ASMでHello World
はじめに
ASM という frameworkに興味がり、それを使った サンプルプログラムを書いてみました
ASM とは Java byte code を、操作、分析、あるいは動的に生成できる framework です
これを使って何が出来るかといえば、例えばJVM向けのコンパイラを作れたりします
実際にASMを使ったプロダクトが下の一覧に紹介されています
見てみると Groovy, Jython など有名なものが一覧にありますね
これを使えばあなたの独自プログラミング言語でWeb アプリケーションを作れますね!
Hello World
こちらを使って Hello World プログラムを動的に生成するプログラムを書いてみました
https://github.com/quwahara/HelloAsm/blob/master/src/main/java/com/e2info/helloasm/HelloAsmApp.java
このプログラムを実行すると2つのファイルができます
HellAsm.txt
HellAsm.class
HellAsm.txt はjava byte code の アセンブリ言語のような形式のファイルで出力されます
HellAsm.class は java のクラスファイルそのもので、実行すると下のような具合になります
$ java HelloAsm hello ASM
ビルド、実行するには、
ASMのライブラリの他に
Apache Commons IO
http://commons.apache.org/
のライブラリも必要です
はまりポイントが2カ所ありました
ClassWriter.COMPUTE_MAXS が効かない
スタックサイズを自動で計算してくれるフラグですが、
単純に指定しただけでは計算してもらえませんでした
mv.visitMaxs(0, 0);
を呼び出す事で、計算してもらえるようです
それについて下の様な記述がありました
ASM 4.0 A Java bytecode engineering library.
http://download.forge.objectweb.org/asm/asm4-guide.pdf
ClassWriter options (p. 44)
• with new ClassWriter(ClassWriter.COMPUTE_MAXS) the sizes of the local variables and operand stack parts are computed for you. You must still call visitMaxs, but you can use any arguments: they will be ignored and recomputed. With this option you still have to compute the frames yourself.
アセンブリ言語の出力させ方がわからない
試行錯誤して下のような書き方でいいのではと思います
// build binary byte[] bin = cw.toByteArray(); // save asm trace for human readable { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); new ClassReader(bin).accept(new TraceClassVisitor(pw), 0); File f = new File(name + ".txt"); FileUtils.writeStringToFile(f, sw.toString()); }
これであなたもバイナリアン!