Today, updated tests were committed to the branch which allow it to generate ABCL function classes, load them and execute them. That's exciting news! It basically means that the branch is good enough for anybody to write their own lisp code to create new classes (whether or not they are ABCL functions doesn't really matter).
So, where does that leave us in the bigger picture? Well, even though it's now possible to generate function classes with your own lisp code, the generator hasn't been fully integrated into the compiler. The bit that I did integrate is the use of the CLASS-NAME structure for identification of classes and class references. Next to that, I adjusted the method invoking emitters to use different pool functions for creation of the method refs.
So, what remains to be done?
* A test needs to be created which tests nested use of WITH-CODE-TO-METHOD, making sure that register allocation in the nested function generator is correctly transferred to the outer block (more on that below) * The pool handling needs to be switched over to the new pool functions Possibly, there's a quick-path here by changing the pool-* functions in p2 to forward to the ones in j-c-f (jvm-class-file). * The exception handler creation needs to be adjusted to use the new CODE-ADD-EXCEPTION-HANDLER function * Changing the compiler away from *code* and *static-code* toward WITH-CODE-TO-METHOD * Clean up: removal of unused functions (after integration) [especially those currently conflicting] * Documentation: Not all functions in the j-c-f file are documented. All functions except the internal ones (starting with %) should be documented. * API declaration None of the functions in the file are currently exported or autoloaded (unless by accident). In order to help others to create their own classes, we should probably export (some) of the functions, for runtime-class to build upon.
It'd be my preference to do the integration work on the branch, unless we find a strategy to keep trunk stable while we change its class file generator - one of the most critical components.
When all the above has been completed, I see the following improvements to be made to the code we generate:
* multiple methods to handle &optional processing, instead of fastProcessArgs, if the method has less than 8 parameters in total * moving initialization of static variables to a static {} block, instead of in the (re-runnable) constructor; besides being a nice improvement, this is actually a correctness issue: our current constructors call Lisp.recall(), which can't be called more than once for a given string value * Reduction of the number of function classes generated: non-inlined local functions generated as methods in the function class * Re-introduction of XEPs (External entry points): SBCL uses a paradigm where functions which are hard-linked together, use internal entry points: they flatten keywords, pass the right ([un]boxed) values, etc, skipping the "parameter discovery" checks. XEPs discover the right parameters and call the internal entry point.
Apart from that, we should (finally) be able to implement runtime-class without depending on ASM.
Now, there's the explanation of what should be tested in the test-to-be-written:
WITH-CODE-TO-METHOD catches the output from EMIT. Sometimes, pass2 wants to output a small block of code to the constructor method while in the midst of writing an "execute" method. Even fewer times, but in general quite thinkable, you could see the following nesting with output to two methods, method1 and method2:
(WITH-CODE-TO-METHOD (file method1) .... (WITH-CODE-TO-METHOD (file method2) .... (WITH-CODE-TO-METHOD (file method1) ...)))
The WITH-CODE-TO-METHOD macro provisions for this scenario by saving the values of the compiler-specials to the Code attribute. However, currently, nothing checks if the code works correctly (ie saves enough specials). The test should establish that.
Ok. Sorry for the lengthy e-mail :-)
Bye,
Erik.