我继续研究方法仿真,并在传递指令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);
}但这似乎写得不正确。我可以尝试不同的逻辑变量返回什么,但如果不理解,在什么情况下值可以合并,我找不到。我在javadoc和asm-4教程中找不到有用的信息。因此,在以下情况下,我需要返回的是:
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);
}
}发布于 2018-02-16 16:51:48
当一条指令可以通过不同的代码路径到达时,例如当你有条件、循环或异常处理程序时,需要合并这些值。
因此,当值相同时,无论采用了哪条代码路径,都可以保留它,否则该值将不再是可预测的常量。因此,在我的代码中,null被用来表示未知值,当这些值不同时,它总是返回null。
所以当你有像这样的代码时
void foo(int arg) {
int i = 1;
int j = arg%2==0? i: arg;
}arg、i的值和操作数堆栈上的值在向j赋值之前合并。arg已经有了一个不可预知的值,i在每个代码路径中都有值1,但是要分配给j的操作数堆栈上的值有不同的值,1或“unknown”,具体取决于所采用的代码路径。
如果您愿意,您可以决定维护一组可能的值,但是当其中一个可能的值是“未知”时,合并的结果可能是任何值,因此是“未知的”。
https://stackoverflow.com/questions/48816547
复制相似问题