From: Charles Z. <ka...@be...> - 2018-05-17 03:05:32
|
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 <ka...@be...> 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 |