我如何在字节码中插入framenode? p>
FRAME FULL [java/lang/String [C java/lang/String T I I [C] []
我的第一次尝试是:
mn.instructions.insertBefore(random, new FrameNode(Opcodes.F_FULL, 1 /**IDK**/,
new Object[]{ "java/lang/String", "[C", "java/lang/String", "T", "I", "I", "[C]" },
1/**IDK**/, new Object[] { "[C]","[]" }));
效果不佳。输出:
FRAME FULL [[java/lang/String] [java/lang/String]
答案 0 :(得分:3)
堆栈帧由许多局部变量和操作数堆栈上的许多值组成。您要重现的内容,显然是将该状态转换为人类可读的字符串形式的结果
FRAME FULL [list of local variables types] [list of operand stack time types]
您要做的第一件事就是从输出格式中识别括号,这需要了解所包含的类型签名,因为以[C
开头括号开头的签名表示数组类型,即一个字符数组。换句话说,一些左括号是类型签名的一部分,其他是输出格式的一部分,而右括号始终是输出格式的一部分,并且永远不会出现在类型签名中。
然后,当您确定了两个组中的类型签名时,请提供适当的局部变量和操作数堆栈项的计数。在你的情况下,你有:
FRAME FULL // frame type
[ // start local variables
java/lang/String
[C
java/lang/String
T
I
I
[C
] // seven local variables specified
[ // start of operand stack
] // empty operand stack
但是你必须开始考虑类型项的含义,遗憾的是它不能从打印输出中导出,只是重现相同的打印输出并不一定意味着正确的代码。
即,项T
和I
可以分别引用具有完全限定名称T
和I
的类,在这种情况下,传递"T"
并且"I"
到FrameNode
是正确的。但是,它们更有可能引用非类堆栈帧类型 int
,它们必须在ASM中使用预定义的Integer
常量引用:
new FrameNode(Opcodes.F_FULL, 7, new Object[] {
"java/lang/String", "[C", "java/lang/String",
Opcodes.TOP, Opcodes.INTEGER, Opcodes.INTEGER, "[C" }, 0, new Object[0]);