jmc.scm 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. ;; The example in gnu/bytecode/package.html
  2. ;; converted to Scheme by Yaroslav Kavenchuk
  3. (define-alias ClassType gnu.bytecode.ClassType)
  4. (define-alias Access gnu.bytecode.Access)
  5. (define-alias Method gnu.bytecode.Method)
  6. (define-alias CodeAttr gnu.bytecode.CodeAttr)
  7. (define-alias Type gnu.bytecode.Type)
  8. (define-alias Variable gnu.bytecode.Variable)
  9. (define-alias ClassTypeWriter gnu.bytecode.ClassTypeWriter)
  10. (define-alias ArrayClassLoader gnu.bytecode.ArrayClassLoader)
  11. (define-alias System java.lang.System)
  12. (define-alias Class java.lang.Class)
  13. (define-alias Integer java.lang.Integer)
  14. ;; code
  15. ;; "public class HelloWorld extends java.lang.Object".
  16. (define c :: ClassType (ClassType "HelloWorld"))
  17. (*:setSuper c "java.lang.Object")
  18. (*:setModifiers c Access:PUBLIC)
  19. ;; "public static int add(int, int)".
  20. (define m :: Method
  21. (*:addMethod c "add" "(II)I" (logior Access:PUBLIC Access:STATIC)))
  22. (define code :: CodeAttr (m:startCode))
  23. (code:pushScope)
  24. (code:emitLoad (code:getArg 0))
  25. (code:emitLoad (code:getArg 1))
  26. (code:emitAdd Type:intType)
  27. (define resultVar :: Variable (code:addLocal Type:intType "result"))
  28. (code:emitDup)
  29. (code:emitStore resultVar)
  30. (code:emitReturn)
  31. (code:popScope)
  32. ;; Get a byte[] representing the class file.
  33. ;; We could write this to disk if we wanted.
  34. (define classFile :: byte[] (*:writeToArray c))
  35. ;; Disassemble this class.
  36. ;; The output is similar to javap(1).
  37. (ClassTypeWriter:print c System:out 0)
  38. ;; Load the generated class into this JVM.
  39. ;; gnu.bytecode provides ArrayClassLoader, or you can use your own.
  40. (define cl :: ArrayClassLoader (ArrayClassLoader))
  41. (cl:addClass "HelloWorld" classFile)
  42. ;; Actual invocation is just the usual reflection code.
  43. (define helloWorldClass :: Class (cl:loadClass "HelloWorld" #t))
  44. (define argTypes :: Class[]
  45. (Class[] java.lang.Integer:TYPE java.lang.Integer:TYPE))
  46. (define result
  47. (as Integer
  48. (*:invoke (*:getMethod helloWorldClass "add" @argTypes)
  49. #!null
  50. @(Object[] (Integer 1) (Integer 2)))))
  51. (format #t "Result of HelloWorld.add(1,2) is ~s~%" result)