I've been playing with Parrot some more recently, and thinking about converting Java bytecode to Parrot bytecode. My thoughts went something like this: Parrot is a register machine. The Java virtual machine is a stack machine. Parrot is also a stack machine (it's only a register machine for speed, there is still a stack). Instead of converting Java bytecode to Parrot bytecode, I can make Parrot into a JVM. I can achieve this by adding new JVM-like opcodes to Parrot (really quite trivial, all I coded up was a new jvm.ops file and reconfigured and typed "make". The 14 new opcodes where generated, added to Parrot, and the assembler automagically supported them.)
Have I confused you already? Well, let me explain it. Here is a piece of Java source code:
public static void spin() { int i; for(i = 0, i < 12345678; i++); System.out.print(i); }
javac turns that into the following bytecode:
0 iconst_0 1 istore_0 2 goto 8 5 iinc 0 1 8 iload_0 9 sipush 1000 12 if_icmplt 5 15 getstatic #318 iload_0 19 invokevirtual #4 22 return
Now, after I've added my jvm.ops file to Parrot, I can code this in Parrot assembler as the following code:
# This is Parrot assembler: iconst_0 istore_0 goto IN REDO: iinc 0, 1 IN: iload_0 sipush 12345678 if_icmplt REDO iload_0 jvm_print end
... and the usual ./assemble.pl jvm.pasm > jvm.pbc; ./parrot jvm.pbc will compile and run the JVM-like Parrot opcodes.
That is, I've implemented "iconst_0" (a JVM bytecode which pushes zero onto the stack) and so on in Parrot, and Parrot is running JVM-like bytecode as well as Parrot bytecode (of course, I've only implemented a couple of JVM opcodes). This shows how flexible Parrot is, and is the method that will be used when multiple language target Parrot I imagine.
So I posted the code to perl6-internals and got little response back, apart from the "you're crazy" and "wow". It's a cute idea and it leads on to issues raised by Dan such as sharing objects between Java and other languages hosted on Parrot, or maybe doing wild JNI stuff. [Note: we can't go much further at the moment as Parrot doesn't have a symbol table, objects, methods, or method calls yet - but it will ;-]
This is all research for my Targeting Parrot talk at OSCON. Is there anything you'd like to know about targeting languages at Parrot? Ask away!
Anyway, off to a London.pm social meeting. I'm wearing my Parrot tshirt today...
What actually converts the JBC into PBC? Are you doing this by hand atm (i.e. converting JBC to parrot assembler, then assembling it,) or is there some form of automated system?
As I understand it you're adding new op codes to the pvm so that you have a one to one translation for JBC and PBC. Doesn't this add more operations to the VM? Don't adding more operations slow down the VM implementation (because each operation takes longer to look things up?)
Re:op code bloat
acme on 2002-05-03T12:03:04
Yes, there is a lot of handwaving;-)
It was just weekend project, so I converted the JBC into PBC by hand. As I work on this more, I'll be using Java::JVM::Classfile to do it automatically.
This does indeed mean adding more opcodes to Parrot. Parrot has around 600 opcodes already and I added 14. If I added all ~255 JVM opcodes, it would indeed increase the total number of Parrot opcodes, but the slowdown is pretty small. In fact, Parrot will have dynamically loadable opcode libraries, so in future this slowdown would be even less of a problem.
Hope this help! LeonRe:op code bloat
2shortplanks on 2002-05-03T12:54:32
Does this mean that you can have numerous different Parrot Byte Codes and a PBC file will have to say what encoding scheme (what opcodes mean what) it is?
/me waves hands too Re:op code bloat
acme on 2002-05-03T12:58:17
Possibly. I think we're actually concentrating on getting Parrot working before doing all the magic clever stuff;-)