Re: gsoc: first steps, how to do more stuff with LAPs

Charles Zhang <[email protected]> Wed, 16 May 2018 23:05:21 -0400
Newsgroups gmane.lisp.clisp.devel
Message-ID <CAB=SSSk8K7ZBaU4U55vvVwx3Zj3EePCXX3vWgX7ogRP5MT=wJw@mail.gmail.com>
Quick update on the previous example: I cleaned up and added support
for using more of CLISP's call ops, instead of just punting to the
computed funcall routine.

So now the form
(lambda (x y) (if (= x y) (1+ x) (+ x y)))
compiles to
(LOAD 2)
(PUSH)
(LOAD 2)
(PUSH)
(CALLSR 1 47)
(PUSH)
(CONST 0 #S(CONST :VALUE NIL :FORM NIL :LTV-FORM NIL :HORIZON NIL))
(JMPIFEQ G271531)
(JMP G271533)
G271531
(LOAD 2)
(PUSH)
(LOAD 2)
(PUSH)
(CALLSR 2 55)
(JMP G271532)
G271532
(SKIP 3)
(RET)
G271533
(LOAD 2)
(PUSH)
(CALLS2 177)
(JMP G271532)
Compare with CLISP's actual current disassembly. (It's pretty close!
At least pre insert-combined-LAPs)

Charles

On Wed, May 16, 2018 at 12:51 AM, Charles Zhang <[email protected]> wrote:
> Hello clisp,
>
> I managed to get clisp bytecode compiled for forms like (lambda (x y)
> (if (= x y) (1+ x) (+ x y)) correctly with Cleavir. So far the
> bytecode format produced is just a code listing like the following:
>
> ((CONST 0 #S(CONST :VALUE = :FORM NIL :LTV-FORM NIL :HORIZON NIL))
> (PUSH)
> (CALLS1 86)
> (PUSH)
> (LOAD 3)
> (PUSH)
> (LOAD 3)
> (PUSH)
> (FUNCALL 2)
> (PUSH)
> (CONST 1 #S(CONST :VALUE NIL :FORM NIL :LTV-FORM NIL :HORIZON NIL))
> (JMPIFEQ G178973)
> (JMP G178975)
> G178973
> (CONST 2 #S(CONST :VALUE + :FORM NIL :LTV-FORM NIL :HORIZON NIL))
> (PUSH)
> (CALLS1 86)
> (PUSH)
> (LOAD 3)
> (PUSH)
> (LOAD 3)
> (PUSH)
> (FUNCALL 2)
> (JMP G178974)
> G178974
> (SKIP 3)
> (RET)
> G178975
> (LOAD 2)
> (PUSH)
> (CALLS2 177)
> (JMP G178974))
>
> I know I can call insert-combined-LAPs on such a code listing to get
> the abbreviated LAP that disassemble normally produces. However, I
> couldn't figure out a way to actually make this into an executable
> function. It seems that I have to somehow lift the code constants up
> into a constant vector, first of all. Would I have to resort to
> hacking the top level COMPILE function with all the other machinery
> like FNODEs and various special vars bound just to get plug into the
> rest of the compilation pipeline (finishing from
> insert-combined-LAPs)?
>
> In addition, I can compile a nested function into LAP as well while
> compiling the parent function, but it's not clear to me how to combine
> the two into an executable object. For example,
>
> (disassemble (lambda () (lambda ())))
>
> Disassembly of function :LAMBDA
> (CONST 0) = #<COMPILED-FUNCTION :LAMBDA-1>
> 0 required arguments
> 0 optional arguments
> No rest parameter
> No keyword parameters
> 2 byte-code instructions:
> 0     (CONST 0)                           ; #<COMPILED-FUNCTION :LAMBDA-1>
> 1     (SKIP&RET 1)
>
> just skips straight to packaging up the function, already compiled. as
> a CONST.  Is it simply as straightforward as compiling the inner
> function's LAP first, and then saving it to the codevec somehow? it
> didn't seem like function constants were treated the same way in the
> pre insert-combined-LAPs code listings as constants like 2, for
> example, which usually have some form like
>
> (CONST 2 #S(CONST :VALUE 2 :FORM NIL :LTV-FORM NIL :HORIZON NIL))
>
> embedded inside, whereas inner functions (which are referred to as
> CONSTs as well) do not appear in the listing.
>
> Anyway, my main question is how to finish off compiling something like
> the first LAP I gave, into a function with separated bytevec, codevec
> and all, which would also shed light onto the nested functions issue.
>
> Charles

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
clisp-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/clisp-devel