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

此代码(line 380+)在CodeGenerator.java中:

      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为空,我在NullPointerException中得到一个CodeGenerator.visitExpression(Node, int)

我看不到这段代码如何工作。但与此同时,它是一个核心功能,我无法想象人们会错过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的引入,代码生成需要一个额外的步骤才能将“原始”解析树转换为适合代码生成的东西。

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

    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()中找到有关如何准备代码生成的示例。

关于javascript - Rhino CodeGenerator Token.EXPR_RESULT中的错误?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30484231/

10-11 12:56