guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Is it possible to get ijp's js branch working anymore?


From: Christine Lemmer-Webber
Subject: Is it possible to get ijp's js branch working anymore?
Date: Mon, 11 Oct 2021 21:21:36 -0400
User-agent: mu4e 1.6.6; emacs 27.2

I've moved this thread from guile-user to guile-devel.

"Dr. Arne Babenhauserheide" <arne_bab@web.de> writes:

> Christine Lemmer-Webber <cwebber@dustycloud.org> writes:
>
>> I have pushed one more merge with master to the compile-to-js-merge
>> branch.  I've taken the bold move of pushing this to origin... I think
>> it's a good idea to try to get this in, so it's worth it not just
>> sitting in my own personal repo.
>
> wow — thank you!
>
> Is there a short example on how to use this branch for the features that
> already work?
>
> Best wishes,
> Arne

ijp's email, at the start of this thread (see 2017-08-28 in the
guile-user mail archive) explains everything better than I could.
However, the branch does not really work.  I'm worried it might not be
able to, see below.

I've actually made it past the last hurdle I mentioned in my thread;
turns out I was closer on track when I last tried to merge this than in
the efforts I made within the last week.  And so I'm now at the point
where I think I'm dealing with the real merge issues.  Wingo, I've cc'ed
you... I think you're our main hope here.

Here's the problem: CPS changed a lot since ijp wrote this... and it may
have gotten advanced enough that merging has become very difficult.
The problem started out with records that look like so:

  #<cps (primcall allocate-words/immediate (pair . 2))>

There are two weird things here:

 - $primcall used to only have args that were a list; now there are some
   weird ones with cons cells, like 'allocate-words/immediate.  I see
   that compile-bytecode.scm has grown to pattern match against a
   significant number of these.  So, ok, we have to do the same in
   compile-js.scm.

 - Except that wait a minute... 'allocate-words/immediate ?!
   This sounds *really* low-level.  Wait, it *is* really low-level!
   Right now ijp's branch had a runtime.js branch which translated
   a bunch of these primitives, and that could be done quasi-reasonably,
   but allocate-words/immediate.... what the heck do we do with that
   in javascript?!

The commit where things seem to have gotten low-level in CPS land is
9f98b4a5b1067b177c700d27abf4ed477f013951.  Here's the big relevant
change:

#+BEGIN_SRC diff
diff --git a/module/language/cps/closure-conversion.scm 
b/module/language/cps/closure-conversion.scm
index 4f9296397..746e5cebe 100644
--- a/module/language/cps/closure-conversion.scm
+++ b/module/language/cps/closure-conversion.scm
@@ -19,9 +19,8 @@
 ;;; Commentary:
 ;;;
 ;;; This pass converts a CPS term in such a way that no function has any
-;;; free variables.  Instead, closures are built explicitly with
-;;; make-closure primcalls, and free variables are referenced through
-;;; the closure.
+;;; free variables.  Instead, closures are built explicitly as heap
+;;; objects, and free variables are referenced through the closure.
 ;;;
 ;;; Closure conversion also removes any $rec expressions that
 ;;; contification did not handle.  See (language cps) for a further
@@ -520,10 +519,36 @@ term."
     (define (allocate-closure cps k src label known? nfree)
       "Allocate a new closure, and pass it to $var{k}."
       (match (vector known? nfree)
+        (#(#f 0)
+         ;; The call sites cannot be enumerated, but the closure has no
+         ;; identity; statically allocate it.
+         (with-cps cps
+           (build-term ($continue k src ($closure label 0)))))
         (#(#f nfree)
          ;; The call sites cannot be enumerated; allocate a closure.
          (with-cps cps
-           (build-term ($continue k src ($closure label nfree)))))
+           (letv closure tag code)
+           (letk k* ($kargs () ()
+                      ($continue k src ($values (closure)))))
+           (letk kinit ($kargs ('code) (code)
+                         ($continue k* src
+                           ($primcall 'word-set!/immediate '(closure . 1)
+                                      (closure code)))))
+           (letk kcode ($kargs () ()
+                         ($continue kinit src ($code label))))
+           (letk ktag1
+                 ($kargs ('tag) (tag)
+                   ($continue kcode src
+                     ($primcall 'word-set!/immediate '(closure . 0)
+                                (closure tag)))))
+           (letk ktag0
+                 ($kargs ('closure) (closure)
+                   ($continue ktag1 src
+                     ($primcall 'load-u64 (+ %tc7-program (ash nfree 16)) 
()))))
+           (build-term
+             ($continue ktag0 src
+               ($primcall 'allocate-words/immediate `(closure . ,(+ nfree 2))
+                          ())))))
         (#(#t 2)
          ;; Well-known closure with two free variables; the closure is a
          ;; pair.
#+END_SRC

I'm not really sure what to do.  I don't mean to complain; I, along with
everyone here, has benefitted from Wingo's constant tweaking of this
stuff, making it all more and more efficient.  But can it still be
compatible with ijp's vision of javascript emerging the cps layer?

Here's my gut sense though: I wonder if CPS can be broken into phases,
one that does these smarter low-level memory tweaks, and one that
doesn't, so that ijp's lovely branch has a chance of being merged.

Or maybe there's a more obvious path?

What to do?!  Wingo, we need your help!

 - Christine



reply via email to

[Prev in Thread] Current Thread [Next in Thread]