rhino CodeGenerator Token.EXPR_RESULT 中的错误?

Bug in rhino CodeGenerator Token.EXPR_RESULT?

我目前正在查看 Rhino 1.7.5 和 1.7.6 的代码。

CodeGenerator.java 中是这个代码 (line 380+):

      case Token.EXPR_VOID:
      case Token.EXPR_RESULT:
        updateLineNumber(node);
        visitExpression(child, 0);
        addIcode((type == Token.EXPR_VOID) ? Icode_POP : Icode_POP_RESULT);
        stackChange(-1);
        break;

child 是 (line 232):

Node child = node.getFirstChild();

ExpressionStatement是触发上面case的节点 但它从不调用 addChildToBack()first 设置为任何值。

所以当上面的代码执行时,child 为 null,我在 CodeGenerator.visitExpression(Node, int)

中得到一个 NullPointerException

我看不出这段代码是如何工作的。但与此同时,它是如此核心的功能,我无法想象人们怎么会错过它 6 年。

[编辑] 我设法创建了一个测试用例:

import static org.junit.Assert.*;
import org.junit.Test;
import org.mozilla.javascript.CompilerEnvirons;
import org.mozilla.javascript.Interpreter;
import org.mozilla.javascript.Parser;
import org.mozilla.javascript.ast.ScriptNode;

public class RhinoTest {

    @Test
    public void testCompileExpression() throws Exception {
        String expression = "row[\"COL_Col1\"]";
        CompilerEnvirons compilerEnv = new CompilerEnvirons();
        Parser p = new Parser( compilerEnv, compilerEnv.getErrorReporter() );
        ScriptNode script = p.parse( expression, null, 0 );

        Interpreter compiler = new Interpreter( );
        Object compiledOb = compiler.compile( compilerEnv, script, null, false );
        assertNotNull( compiledOb );
    }
}

如果我运行这个,我得到这个异常:

java.lang.NullPointerException
    at org.mozilla.javascript.CodeGenerator.visitExpression(CodeGenerator.java:497)
    at org.mozilla.javascript.CodeGenerator.visitStatement(CodeGenerator.java:383)
    at org.mozilla.javascript.CodeGenerator.visitStatement(CodeGenerator.java:276)
    at org.mozilla.javascript.CodeGenerator.generateICodeFromTree(CodeGenerator.java:113)
    at org.mozilla.javascript.CodeGenerator.compile(CodeGenerator.java:83)
    at org.mozilla.javascript.Interpreter.compile(Interpreter.java:194)
    at com.avanon.basic.birt.RhinoTest.testCompileExpression(RhinoTest.java:21)

随着 AST API 的引入,代码生成需要一个额外的步骤来将 "raw" 解析树转换为适合代码生成的东西。

要修复上面的测试用例,请更改行:

    ScriptNode script = p.parse( expression, null, 0 );

进入:

    ScriptNode ast = p.parse( expression, null, 0 );

    IRFactory irf = new IRFactory(compilerEnv, compilerEnv.getErrorReporter());
    ScriptNode tree = irf.transformTree(ast);

您还可以在 Context.compileImpl()

中找到如何准备 codegen 的示例