Dissregared the last email there was a Hypelink that I misspelled as well as rewrote my last post to make clearer
----- Original Message ----- From: "Ville Voutilainen" ville.voutilainen@gmail.com To: dmiles@users.sourceforge.net Cc: "Armed Bear" armedbear-devel@common-lisp.net Sent: Thursday, November 05, 2009 9:57 PM Subject: Re: [armedbear-devel] 0.18 and beyond
2009/11/6 logicmoo@gmail.com:
Other java lisps define each Primitive execute as a single static function in a trampolines file. The Primitive itself just calls the static function in the trampolines (
This is a useful technique to speed up compiled code. It could also speed up startup times as long as you don't invoke such primitives
Indeed
The translation looks like there's no longer a Primitive that extends LispObject.
No longer a "requirement" for the compiler to *have to* use a Primitive
Do we generate wrappers on the fly?
Correct As you foresee, for cases like #'APPLY/#'FUNCALL etc and from the interpreter it is done on the fly.
Previous code that read: declareFunction(myName,"primitive_CHAR_LESS_THAN_execute_1_0_false","CHAR<",1,0,false); declareFunction(myName,"primitive_CHAR_LESS_THAN_execute_2_0_false","CHAR<",2,0,false); declareFunction(myName,"primitive_CHAR_LESS_THAN_execute_0_0_true","CHAR<",0,0,true);
Does actually create 5 objects:
One Symbol: Symbol s = intern("CHAR<",pkg);
One Primtive subclass called a FunctorIndexer
FunctorIndexer p = new FunctorIndexer(s);
One Primtive is placed inside the symbol-function: s.setSymbolFunction(p);
Three Functors: p.Add( new ForwardFunctor(s,myName,"primitive_CHAR_LESS_THAN_execute_1_0_false","CHAR<",1,0,false)); p.Add ( new ForwardFunctor(s,myName,"primitive_CHAR_LESS_THAN_execute_2_0_false","CHAR<",2,0,false)); p.Add( new ForwardFunctor(s,myName,"primitive_CHAR_LESS_THAN_execute_0_0_true","CHAR<",0,0,true));
This will later be used to index the call sigs to the best ForwardFunctor.
So far we have made 5 objects: s,p,f0,f1,f2 ------------------------------------------------------------------------------------------ On first use: lets say:
(funcall 'char< #\a #\b #\c)
thats 3 args ins .. the best match is f2 -
This transistion is handled in here: http://larkc.svn.sourceforge.net/viewvc/larkc/trunk/platform/src/com/cyc/too...
It creates one class that implments processArgs(LispObject r0,LispObject r1,LispObject r2) And loads the arity3Cache of the FunctorIndexer which physically calls the static function:
return primitive_CHAR_LESS_THAN_execute_0_0_true(new LispObject[]{r0,r1,r2});
----------------------- So far we have made 6 objects -----------------------
Note though this machinery is only used in FUNCALL and interpreted code
When hitting the functor generator .. it should be considered "worse case"
But serves a better way case than hitting the reflection on line 62 of http://larkc.svn.sourceforge.net/viewvc/larkc/trunk/platform/src/com/cyc/too... (But this 2ndary wrapper technique still isn't that bad. )
How do you then pass the primitive as one? Like passing EQ/EQUAL/EQUALP to FIND/POSITION family of functions?
You find-or-create the Symbol like findSymbol("EQ",pgk).getSymbolFunction().execue(a0,a1,etc); like before.
".getSymbolFunction()" is where the new magic takes place
Or user-defined functions that take functions, and you don't know the type and must box it (aka pass it as a LispObject)?
Currently all execute(..,.,.,.) signatures take LispObject as before.
However with not much more work it is possible to make a cache of unboxed versions like...
public final static LispObject primitive_CHAR_LESS_THAN_execute_2_0_false_nobox(char req0, char req1) { return req0 < req1? T : NIL; }
Registered the same way to the interpreter and compiler:
declareFunction(myName,"primitive_CHAR_LESS_THAN_execute_2_0_false_unboxed","CHAR<",2,0,false);
Actually if you want, is even simplier to not go thru the explicit "registration process" but using Annotations
@InlineCompiler(symbolname="CHAR<", package="COMMON-LISP"); public final static LispObject primitive_CHAR_LESS_THAN_execute_2_0_false_nobox(char req0, char req1) { return req0 < req1? T : NIL; }
armedbear-devel@common-lisp.net