Cha*_*the 8 java bytecode bytecode-manipulation
我正在研究计算StackFrameMap(SFM)中条目的代码.目标是能够生成(SFM)条目,使Java 7字节码验证器满意.遵循TDD方法,我开始为验证者创建伪造的SMF条目以进行投诉; 我会用我正确计算的条目替换它们,看看我是否正确地做了.
问题是:我不能让字节码验证器抱怨.这是一个示例,从原始Java代码开始(此代码不应该做任何有用的事情):
public int stackFrameTest(int x) {
if (x > 0) {
System.out.println("positive x");
}
return -x;
}
Run Code Online (Sandbox Code Playgroud)
这会生成以下字节码(使用SFM):
public int stackFrameTest(int);
flags: ACC_PUBLIC
Code:
stack=2, locals=2, args_size=2
0: iload_1
1: ifle 12
4: getstatic #47 // Field java/lang/System.out:Ljava/io/PrintStream;
7: ldc #85 // String positive x
9: invokevirtual #55 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
12: iload_1
13: ineg
14: ireturn
StackMapTable: number_of_entries = 1
frame_type = 12 /* same */
Run Code Online (Sandbox Code Playgroud)
现在,我将SFM更改为包含以下内容:
StackMapTable: number_of_entries = 1
frame_type = 255 /* full_frame */
offset_delta = 12
locals = [ double, float ]
stack = [ double ]
Run Code Online (Sandbox Code Playgroud)
正如您所看到的那样,这完全是假的,但加载时没有错误.我阅读了JVM规范,但我看不出有什么理由可以解决这个问题.我没有使用该SplitBytecodeVerifier选项.
编辑:根据下面接受的答案,Eclipse已设置为发出Java 6类文件(版本50.0).此版本的类文件将悄悄地忽略StackFrameMap的问题.更改设置以使用默认的Java 7类文件格式(51.0)后,它按预期工作.
我无法重现您的结果.我尝试修改堆栈帧,但无法按预期加载.如果你愿意,我可以发布我修改过的类文件.
目前尚不清楚发生了什么,但你几乎肯定在某个地方犯了错误.最可能的解释是您的类文件具有版本50.0,在这种情况下,当stackmap无效时,JVM将回退到正常验证.您需要将版本设置为51.0以强制进行堆栈映射验证.另一种可能性是你只是搞砸了编辑文件,并没有实际保存更改或没有做出你认为你做过的更改.
这是我修改过的类文件的程序集.
.version 51 0
.class super public StackFrameTest4
.super java/lang/Object
.method public <init> : ()V
.limit stack 1
.limit locals 1
aload_0
invokespecial java/lang/Object <init> ()V
return
.end method
.method static public main : ([Ljava/lang/String;)V
.limit stack 2
.limit locals 1
new StackFrameTest
dup
invokespecial StackFrameTest <init> ()V
bipush 42
invokevirtual StackFrameTest stackFrameTest (I)I
pop
return
.end method
.method public stackFrameTest : (I)I
.limit stack 2
.limit locals 2
iload_1
ifle L12
getstatic java/lang/System out Ljava/io/PrintStream;
ldc 'positive x'
invokevirtual java/io/PrintStream println (Ljava/lang/String;)V
L12:
.stack full
locals Double Float
stack Double
.end stack
iload_1
ineg
ireturn
.end method
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
163 次 |
| 最近记录: |