我继续研究方法仿真并在传递指令ILOAD时获得实际值。在Holger's help with Interpreter之后
在使用main()
方法添加局部变量的新操作后,我坚持使用merge(V a, V b)
方法,在扩展Interpreter
时必须覆盖该方法。
@Override
public LocalValue merge(LocalValue valueA, LocalValue valueB) {
if (Objects.equals(valueA, valueB)) return valueA;
else return new LocalValue(basicInterpreter.merge(valueA.type, valueB.type), null);
}
但似乎写得不正确。我可以尝试不同的逻辑变量返回但不理解,在什么情况下值可以合并,我找不到。我试过在javadocs和asm-4教程中找不到有用的信息。那么,我需要返回什么时候:
- 一个值为null,另一个值不为
- 两个值都不是null,相同类型,但不同的对象(例如0和5)
- 两个值都不为空,不同类型为
basicInterpreter:
private BasicInterpreter basicInterpreter = new BasicInterpreter();
LocalValue:
public static class LocalValue implements Value {
Object value;
BasicValue type;
public LocalValue(BasicValue type, Object value) {
this.value = value;
this.type = type;
}
@Override public int getSize() {return type.getSize();}
@Override public String toString() {return value == null ? "null" : value.toString();}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof LocalValue)) return false;
LocalValue otherV = (LocalValue) obj;
return Objects.equals(otherV.type, type) && Objects.equals(otherV.value, value);
}
}
答案 0 :(得分:0)
当可以通过不同的代码路径访问指令时,需要合并值,例如,当您有条件,循环或异常处理程序时。
因此,当值相同时,无论采用哪种代码路径,都可以保留它,否则该值不再是可预测的常量。因此,在我的代码中,null
用于表示未知值,当值不同时,它始终返回null
。
所以当你有像
这样的代码时void foo(int arg) {
int i = 1;
int j = arg%2==0? i: arg;
}
arg
,i
的值以及操作数堆栈上的值在分配到j
之前合并。 arg
已经有一个不可预测的值,i
在每个代码路径中都有值1
,但是要分配给j
的操作数堆栈上的值具有不同的值,1
或“未知”,具体取决于采用的代码路径。
如果您愿意,您可以决定保留一组可能的值,但是当其中一个可能值为“未知”时,合并冷的结果为任何值,因此,“未知”。