2017-11-23 19 views
1

メソッド内のすべてのラベルのオフセットを取得しようとしています。Javaバイトコード - ASM - ラベルオフセットの取得

私は、次のコードを使用してみました:getOffset()方法はExceptionをスローしかし

private static ArrayList<Integer> GetLabelOffsets(MethodNode methodNode) { 
    ArrayList<Integer> labelOffsets = new ArrayList<>(); 

    for (AbstractInsnNode instruction : methodNode.instructions.toArray()) { 
     if (instruction instanceof JumpInsnNode) { 
      JumpInsnNode jumpInsnNode = (JumpInsnNode) instruction; 
      labelOffsets.add(jumpInsnNode.label.getLabel().getOffset());. 
     } 
    } 

    return labelOffsets; 
} 

を:

java.lang.IllegalStateException: Label offset position has not been resolved yet 

どのように私はこれらのオフセット位置を解決することができますか?またはこれを達成するための適切な方法は何ですか? documentation of getOffset()から

public static HashMap<String, ClassNode> ParseJar(JarFile jar) { 
    HashMap<String, ClassNode> classes = new HashMap<>(); 

    try { 
     Enumeration<?> enumeration = jar.entries(); 
     while (enumeration.hasMoreElements()) { 
      JarEntry entry = (JarEntry) enumeration.nextElement(); 

      if (entry.getName().endsWith(".class")) { 
       ClassReader classReader = new ClassReader(jar.getInputStream(entry)); 
       ClassNode classNode = new ClassNode(); 
       classReader.accept(classNode, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); 
       classes.put(classNode.name, classNode); 
      } 

     } 
     jar.close(); 
     return classes; 
    } catch (Exception ex) { 
     return null; 
    } 
} 

public static void main(String[] args) { 
    JarFile jar = new JarFile(fileName); 
    HashMap<String, ClassNode> classes = JarUtils.ParseJar(jar); 
    for (ClassNode classNode : classes.values()) { 
     for (MethodNode methodNode : classNode.methods) { 
      ArrayList<Integer> offsets = GetLabelOffsets(methodNode); 
      // do more stuff with offsets 
     } 
    } 
} 
+0

[最小、完全、および検証可能な例](https://stackoverflow.com/help/mcve)を提供(投稿)できますか? –

+0

更新いただきありがとうございます!問題を再現するために、プログラム入力としてどのjarファイルを使用すべきですか? –

+0

jarファイルで実行する必要があります。バイトコードに(条件なし)ジャンプが含まれている限り。 – eKKiM

答えて

4

この方法

編集

MethodNode

は、要求に応じてより多くのコードを追加しましたJavaのASMライブラリからorg.objectweb.asm.tree.MethodNodeオブジェクトであります属性サブclを対象としています通常、クラスジェネレータやアダプタでは必要ありません。

このオフセットは、バイトで定義されているので命令のリストを処理するとき、それはASMは、異なる長さを有することができる命令の異なる形態を抽象化し、特にとして、非常に有用ではないであろうがバイトコード。

この命令リストは変更可能であるため、Labelは論理位置を表し、オフセットはメソッドの結果のバイトコードを書き込むときに計算され、実際の数値は既知です。

命令リスト内には、命令と同じLabelを参照する対応するLabelNodeが存在する必要があります。

+0

ありがとう!私はこれを過度に複雑化しているように見えます。このようにして動作し、はるかに簡単/クリーナーです。 – eKKiM