2015年11月16日月曜日

ASMのドキュメントを読む(Core API - Methods - Interfaces and components前半)

前回の続き。今回からASMについて。

ASMではVisitorパターンを使って、バイトコードを生成したり変更したりする。コンパイル後のクラスファイル群は、クラスがあったりメソッドがあったりアノテーションが付いていたりと複雑なツリー状の構造をしているので、ツリーの中のどの要素をどう操作するかを記述していくことになる。

Visitorパターンでは複数の要素を巡って処理するものだが、ASMではVisitorクラスのコンストラクタに別のVisitorオブジェクトを登録するところがポイント。インスタンスを作る時にVisitor1→Visitor2→Visitor3のようにVisitor同士を一方向に繋げるようになっている。ClassReaderやClassWriterのような入出力もVisitorでできているので、既存のクラスファイルを読み込んで、複数箇所を変換して、出力するという一連のバイトコード操作の処理フローを作ることができる。

MethodVisitorの場合、プログラマーの責任において次の順番で呼びだすことが定められている。
visitAnnotationDefault?
( visitAnnotation | visitParameterAnnotation | visitAttribute )* ( visitCode
( visitTryCatchBlock | visitLabel | visitFrame | visitXxxInsn | visitLocalVariable | visitLineNumber )*
visitMaxs )? visitEnd 

ややこしいことに、ClassWriterで出力するためには、フレームとローカル変数、オペランドスタックのサイズを計算する必要がある。ASMに自動計算させることもできるが10%〜2倍程度遅くなる。new ClassWriter(ClassWriter.COMPUTE_FRAMES)を指定してもvisitMaxs()メソッドの呼び出しは省略できないことに注意。引数は無視されるのでvisitMaxs(0,0)でOK

0 件のコメント:

コメントを投稿

DockerでMQ環境を作る

DockerHubの ibmcom/mq を使う。ファイルシステムとしてtmpfsは使えないので これ を参考に/mnt/sda1に置き換える。 brew install docker docker-machine docker-machine create --drive...