which assembler

15 views
Skip to first unread message

René Jansen

unread,
Oct 10, 2008, 7:45:47 PM10/10/08
to jvm-la...@googlegroups.com
Just a quick question: which assembler are you guys using for experimentation? I find myself wanting to try out some things, but I am in a bind between ooLong and Jasmin or maybe ASM. Is there an unofficial official assembler, preferably something with macros (old s/370 bal programmer that I am) and its own disassembler.

I noticed there is a class called Assembler in the tools sources, is this only usable from javac or is it addressable in any other way?

If no disassembler goes with the package, I would prefer something that is close enough to javap that I can write a small thingy to rearrange its output into something that I can assemble - something that ASM can but in a very verbose way.

Please let me know what you use.

best regards,

René Vincent Jansen.

Charles Oliver Nutter

unread,
Oct 10, 2008, 7:58:44 PM10/10/08
to jvm-la...@googlegroups.com

I'm using ASM exclusively, but usually wrapped behind one of my own shims.

Either this super-trivial shim that just exposes a method-per-opcode:

http://is.gd/3RsP

Or my unreleased Ruby DSL for ASM, "JVMScript":

http://kenai.com/projects/jvmscript

The latter is probably more interesting to you, but obviously has a
dependency on JRuby. Perhaps that's not a problem for your toolchain.

Here's a short sample:

builder = Compiler::FileBuilder.build("somefile.source") do
package "org.awesome", "stuff" do
public_class "MyClass", object do
public_field "list", ArrayList

public_constructor string, ArrayList do
aload 0
invokespecial object, "<init>", [void]
aload 0
aload 1
aload 2
invokevirtual this, "bar", [ArrayList, string, ArrayList]
aload 0
swap
putfield this, "list", ArrayList
returnvoid
end

public_static_method "foo", this, string do
new this
dup
aload 0
new ArrayList
dup
invokespecial ArrayList, "<init>", [void]
invokespecial this, "<init>", [void, string, ArrayList]
areturn
end

public_method "bar", ArrayList, string, ArrayList do
aload 1
invokevirtual(string, "toLowerCase", string)
aload 2
swap
invokevirtual(ArrayList, "add", [boolean, object])
aload 2
areturn
end

public_method("getList", ArrayList) do
aload 0
getfield this, "list", ArrayList
areturn
end

public_static_method("main", void, string[]) do
aload 0
ldc_int 0
aaload
invokestatic this, "foo", [this, string]
invokevirtual this, "getList", ArrayList
aprintln
returnvoid
end
end
end
end

- Charlie

Jochen Theodorou

unread,
Oct 10, 2008, 7:59:35 PM10/10/08
to jvm-la...@googlegroups.com
René Jansen schrieb:

> Just a quick question: which assembler are you guys using for
> experimentation? I find myself wanting to try out some things, but I am
> in a bind between ooLong and Jasmin or maybe ASM. Is there an unofficial
> official assembler, preferably something with macros (old s/370 bal
> programmer that I am) and its own disassembler.

I gave up on Jasmin a long time ago... don't remember why anymore.
ooLong... hear of this the first time. I use ASM very much and I think
many do.

[...]


> If no disassembler goes with the package, I would prefer something that
> is close enough to javap that I can write a small thingy to rearrange
> its output into something that I can assemble - something that ASM can
> but in a very verbose way.

ASM has a bytecode disassembler, you can let it even print the
disassembler in a form that you can almost directly use as code to
create that bytecode. ASM has also a verifier you can use to check your
bytecode and let ASM point to the position where the bytecode is no
longer ok... I wrote a small tool with a gui that is a bit more
comfortable, but it is based on ASM... I really should finish it one day
and release it :( Anyway, ASM can not give you Macros, but since it is a
library you use your Java program that controls ASM becomes the part the
part with the makro if you want to.

bye blackdrag

--
Jochen "blackdrag" Theodorou
The Groovy Project Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
http://www.g2one.com/

René Jansen

unread,
Oct 14, 2008, 11:36:36 AM10/14/08
to jvm-la...@googlegroups.com
Hi Charlie,

thanks for sharing this, it looks most useful. I downloaded and ran it; the testcases run ok. I cannot figure out how to make it write MyClass.class; please forgive me my Ruby-ignorance here. I removed the things I though to be for the testcase only, and have it execute outside of a method. It executes ok, but Erik Meijer would be very happy: there are no side-effects. That I know of.

best regards and thanks in advance.

René.

Charles Oliver Nutter

unread,
Oct 14, 2008, 1:19:26 PM10/14/08
to jvm-la...@googlegroups.com
I need to provide some better examples, but the missing bit of code is
generating the class files after you've done the building process:

builder.generate do |filename, class_builder|
File.open(filename, 'w') {|f| f.write(class_builder.generate)}
end

The generate method on the main builder passes the .class filename and
the ClassBuilder for each class. ClassBuilder#generate produces the
bytes for the class.

Note that I've never released JVMScript officially, but I want to; if
you start playing around with it, keep in mind the following:

1. I'm interested in input and willing to make changes before doing a
release
2. The Compiler namespace will probably become JVMScript

So a shorter, more complete example:

~/projects/duby ➔ cat simple.rb
require 'jvmscript'

builder = Compiler::FileBuilder.build('simple.source') do
public_class 'simple', object do
public_static_method 'main', void, string[] do
aload 0
ldc_int 0
aaload
aprintln
end
end
end

builder.generate do |file, cls|
File.open(file, 'w') {|f| f.write(cls.generate)}
end

~/projects/duby ➔ jruby -I ../jvmscript/lib simple.rb

~/projects/duby ➔ javap -c simple
Compiled from "simple.source"
public class simple extends java.lang.Object{
public static void main(java.lang.String[]);
Code:
0: aload_0
1: ldc #8; //int 0
3: aaload
4: dup
5: getstatic #14; //Field java/lang/System.out:Ljava/io/PrintStream;
8: swap
9: invokevirtual #20; //Method
java/io/PrintStream.println:(Ljava/lang/Object;)V

}

- Charlie

René Jansen

unread,
Oct 15, 2008, 5:06:55 PM10/15/08
to jvm-la...@googlegroups.com
Hi Charlie,

I see; it works. What is the best forum for feedback?

For starters, it took me a minute to understand that void is used as a method return type, but is left out as a method argument. This is no problem as long as it is stated somewhere in block letters (avoiding the words large type here).

Let me know if it is this forum or somewhere else.

Thanks for the tool and your help,
 
best regards,

René. 

Charles Oliver Nutter

unread,
Oct 15, 2008, 5:52:45 PM10/15/08
to jvm-la...@googlegroups.com
Just join the mailing lists on the kenai project page. I've been the
only consumer up to now, so I appreciate your input. We can look at
cleaning it up, building out more tests, and putting out a release version.

http://kenai.com/projects/jvmscript

- Charlie

René Jansen wrote:
> Hi Charlie,
>

dmi...@users.sourceforge.net

unread,
Oct 27, 2008, 6:17:10 AM10/27/08
to jvm-la...@googlegroups.com
I just made a fascinating discovery about defineClass(...);

It is theoretical thus far. .. but when applied to my code it ideed makes my code over 4 times faster.
Someone give me a sanity check

I have this class layout

LispObject
-> LispProc
-> Dynamically defined classes
-> LispInt
-> LispString
-> LispChar
-> LispFloat
-> LispEtc...

I run code.. and the JIT is caching very well and being smart.
I add a new "-> Dynamically defined classes"Some of the JIT caches get blown away
My code suddenly goes very slow .. but warms up.
I add a new "-> Dynamically defined classes"
Some of the JIT caches get blown away
My code suddenly goes very slow .. but warms up.

I did this for over 700 seconds


So here was what I did:

LispObject
-> LispProc
-> Dynamically defined classes
-> LispJITShim
-> LispInt
-> LispString
-> LispChar
-> LispFloat
-> LispEtc...


I copied the code verbatum from LispObject to LispJITShim and made the existing classes subclass the shim.


Now when a dynamic defined class happens.. it blows out LispObject cached JIT
But the pre-existing classes keep all their JIT intact.. because LispJITShim never calls its 'super'
the work done in 700seconds is now all done in 160seconds!!!!!!

Rastislav Kassak

unread,
Oct 27, 2008, 7:13:27 AM10/27/08
to jvm-la...@googlegroups.com
Jamaica from Judoscript is a bit similar but with more java-like
syntax: http://www.judoscript.org/articles/jamaica.html.

It's build on top of ASM or BCEL, but I guess it's outdated as the
last release is from 2005.

However, JVMScript looks much better. It's Ruby after all. :)
Thanks Charlie, I'll try it.

Charles Oliver Nutter

unread,
Oct 27, 2008, 2:12:21 PM10/27/08
to jvm-la...@googlegroups.com
Jamaica looks interesting...probably a lot JVMScript could steal from
it. Largely the reason I wrote JVMScript the way I did was to allow
using it as an API (which I do in Duby) and because as an internal DSL
you have all Ruby constructs to use as well. So defining a new macro is
as simple as defining a Ruby method that calls the same opcode methods.
Indeed, the "println" method I provide is just a sequence of calls to
opcodes to do a println.

Looking forward to getting feedback from JVMScript users. I'm pushing
for an initial release of both JVMScript and Duby soon.
Reply all
Reply to author
Forward
0 new messages