Saturday, March 28, 2009

BiteScript 0.0.1 - A Ruby DSL for JVM Bytecode

I have finally released the first version of BiteScript, my little DSL for generating JVM bytecode. Install it as a gem with "gem install bitescript".

require 'bitescript'

include BiteScript

fb = do
public_class "SimpleLoop" do
public_static_method "main", void, string[] do
aload 0
push_int 0
label :top
goto :top

fb.generate do |filename, class_builder|, 'w') do |file|

BiteScript grew out of my work on Duby. I did not want to call directly into a Java bytecode API like ASM, so I wrapped it with a nice Ruby-like layer. I also wanted the option of having blocks of bytecode look like raw assembly, but also callable as an API.

Currently only two projects I know of make use of BiteScript: Duby and the upcoming Ruby-to-Java "compiler2" in JRuby, which will also be released as a gem.

For a longer example, you can look at tool/compiler2.rb in JRuby, lib/duby/jvm/jvm_compiler.rb in Duby, or an example implementation of Fibonacci in BiteScript.

I'm open to suggestions for how to improve the API, and I'd also like to add the missing Java 5 features. The better BiteScript works, the better Duby and "compiler2" will work.

For folks interested in using BiteScript, the JVM Specification is an easy-to-read complete reference for targeting the JVM, and here is my favorite JVM opcode quickref.


Stephen Bannasch said...

Thanks for releasing this.

I'm following your work on compiler2 with interest also.

Some misc questions/comments:

What does line 68 in mixed_bag.rb do:

loader = JRuby.runtime.jruby_class_loader

The local variable: loader isn't referred to later.

Is there rdoc online anywhere -- I didn't see any rdoc link at the Kenai site.

When I was looking at mixed_bag.rb in Kenai I wondered about loader and clicked the "raw" link to display just the source in the browser so I could easily search for other references to 'loader' but Kenai generate headers which cause the raw file to be downloaded instead of displayed.

Stephen Bannasch said...

I don't know why I missed the subsequent reference to loader ?? -- it was three lines after the first reference:

cls = loader.define_class(name[0..-7].gsub('/', '.'), bytes.to_java_bytes)

Austin Seipp said...

So, I installed jruby using macports, giving me:

$ jruby -v
jruby 1.1.6 (ruby 1.8.6 patchlevel 114) (2009-03-29 rev 6586) [i386-java]

I then installed bitescript using the command 'sudo jgem install bitescript'

When I try to run the 'mixed_bag.rb' test though, I get:

$ jruby mixed_bag.rb
/Users/austinseipp/share/java/jruby/lib/ruby/site_ruby/1.8/builtin/java/ast.rb:49:in `const_missing': uninitialized constant BiteScript (NameError)
from bitescript.rb:3
from bitescript.rb:3:in `require'
from mixed_bag.rb:3

Any way to fix this?

Robert Fischer said...

What are the missing Java 5 features?

Charles Oliver Nutter said...

Robert Fischer: There's no support in BiteScript at the moment for defining things like enums, annotations, or generic signatures.

Austin: You probably need to add -rubygems to the JRuby command line or to the script you're testing (which would be the example scripts, so perhaps I should add them there myself).

Unknown said...

Isn't JRuby itself just a DSL for generating bytecode? And java itself for that matter? haha