java - ASM 在解释器上合并两个值对象

标签 java bytecode java-bytecode-asm

我继续研究方法仿真并在传递指令 ILOAD 时获得实际值(value)。之后Holger's help with Interpretermain() 方法中添加带有局部变量的新操作后,我坚持使用 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)
- 两个值都不为 null,不同类型

基本解释器:

private BasicInterpreter basicInterpreter = new BasicInterpreter();

本地值:

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);
    }
}

最佳答案

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

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

所以当你有这样的代码时

void foo(int arg) {
    int i = 1;
    int j = arg%2==0? i: arg;
}

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

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

关于java - ASM 在解释器上合并两个值对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48816547/

相关文章:

java - Vert.x事件循环与单线程

java - 为一个字段中的多个值构建 Lucene 查询

java - 应为 STRING,但实际为 BEGIN_OBJECT

java - 如何获取 IBM Java 8 的调试信息包

java - 在 Java 字节码/类格式中,什么决定一个方法是否覆盖另一个方法?

java - ASM 和 Javaagent 字节码检测 : ClassFormatError: StackMapTable format error: bad offset for Uninitialized

java - 为什么 null 不是编译时常量?

java - 为什么 lambda 翻译需要生成静态方法?

java - 如何调试内部错误?

java - ASM 字节码库中用于确定操作码性质的实用方法?