ASM在Interpreter上合并两个值对象

时间:2018-02-15 21:25:19

标签: java bytecode java-bytecode-asm

我继续研究方法仿真并在传递指令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);
    }
}

1 个答案:

答案 0 :(得分:0)

当可以通过不同的代码路径访问指令时,需要合并值,例如,当您有条件,循环或异常处理程序时。

因此,当值相同时,无论采用哪种代码路径,都可以保留它,否则该值不再是可预测的常量。因此,在我的代码中,null用于表示未知值,当值不同时,它始终返回null

所以当你有像

这样的代码时
void foo(int arg) {
    int i = 1;
    int j = arg%2==0? i: arg;
}

argi的值以及操作数堆栈上的值在分配到j之前合并。 arg已经有一个不可预测的值,i在每个代码路径中都有值1,但是要分配给j的操作数堆栈上的值具有不同的值,1或“未知”,具体取决于采用的代码路径。

如果您愿意,您可以决定保留一组可能的值,但是当其中一个可能值为“未知”时,合并冷的结果为任何值,因此,“未知”。

相关问题