This is the mail archive of the
kawa@sourceware.org
mailing list for the Kawa project.
Re: Ateempt to rewrite a example from bytecode package on scheme
- From: Yaroslav Kavenchuk <kavenchuk at gmail dot com>
- To: Per Bothner <per at bothner dot com>
- Cc: kawa at sourceware dot org
- Date: Wed, 19 Nov 2008 10:53:23 +0200
- Subject: Re: Ateempt to rewrite a example from bytecode package on scheme
- References: <4923C996.3010007@bothner.com>
Per Bothner wrote:
> Yaroslav Kavenchuk wrote:
> The main problem was varargs handling. I think I fixed it so
> that is much better now (in SVN trunk).
>
> A minor bug is that you used null instead of #!null.
Many thanks! A working example is attached.
> I think this might be useful as both an example and
> a test case. Can I use it as such, including checking
> it into the testsuite?
Yes, of cource!
--
WBR, Yaroslav Kavenchuk.
;; import section
(define-alias ClassType gnu.bytecode.ClassType)
(define-alias Access gnu.bytecode.Access)
(define-alias Method gnu.bytecode.Method)
(define-alias CodeAttr gnu.bytecode.CodeAttr)
(define-alias Type gnu.bytecode.Type)
(define-alias Variable gnu.bytecode.Variable)
(define-alias ClassTypeWriter gnu.bytecode.ClassTypeWriter)
(define-alias ArrayClassLoader gnu.bytecode.ArrayClassLoader)
(define-alias System java.lang.System)
(define-alias Class java.lang.Class)
(define-alias Class[] java.lang.Class[])
(define-alias Integer java.lang.Integer)
;; code
;; "public class HelloWorld extends java.lang.Object".
(define c :: ClassType (ClassType "HelloWorld"))
(*:setSuper c "java.lang.Object")
(*:setModifiers c Access:PUBLIC)
;; "public static int add(int, int)".
(define m :: Method
(*:addMethod c "add" "(II)I" (logior Access:PUBLIC Access:STATIC)))
(define code :: CodeAttr (m:startCode))
(code:pushScope)
(code:emitLoad (code:getArg 0))
(code:emitLoad (code:getArg 1))
(code:emitAdd Type:intType)
(define resultVar :: Variable (code:addLocal Type:intType "result"))
(code:emitDup)
(code:emitStore resultVar)
(code:emitReturn)
(code:popScope)
;; Get a byte[] representing the class file.
;; We could write this to disk if we wanted.
(define classFile :: byte[] (*:writeToArray c))
;; Disassemble this class.
;; The output is similar to javap(1).
(ClassTypeWriter:print c System:out 0)
;; Load the generated class into this JVM.
;; gnu.bytecode provides ArrayClassLoader, or you can use your own.
(define cl :: ArrayClassLoader (ArrayClassLoader))
(cl:addClass "HelloWorld" classFile)
;; Actual invocation is just the usual reflection code.
(define helloWorldClass :: Class (cl:loadClass "HelloWorld" #t))
(define argTypes :: Class[]
(Class[] java.lang.Integer:TYPE java.lang.Integer:TYPE))
(define result
(as Integer
(*:invoke (*:getMethod helloWorldClass "add" argTypes)
#!null
(Object[] (Integer 1) (Integer 2)))))
(System:err:println result)