rhino CodeGenerator Token.EXPR_RESULT中的错误?

时间:2015-05-27 13:39:50

标签: javascript rhino

我目前正在查看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

因此,当执行上述代码时,NullPointerException为空,我在CodeGenerator.visitExpression(Node, int)

中获得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 ); } }

我无法看到这段代码是如何工作的。但与此同时,它是一个核心功能,我无法想象人们如何能够错过它6年。

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

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)

如果我运行这个,我会遇到这个例外:

<?php namespace App;

use Artisaninweb\SoapWrapper\Facades\SoapWrapper;
use Illuminate\Http\RedirectResponse;

class SoapController {

private $auth_response;
private $cookie;
private $search_client;
private $search_response;

public function soapExchange() {

    // create SOAP client and add service details
    SoapWrapper::add(function ($service) {

        $service
            ->name('WoSAuthenticate')
            ->wsdl('http://search.webofknowledge.com/esti/wokmws/ws/WOKMWSAuthenticate?wsdl')
            ->trace(true)
            ->cache(WSDL_CACHE_NONE);
    });

    SoapWrapper::service('WoSAuthenticate', function($service) {
        // call authenticate() method to get SID cookie
        $auth_response = $service->call('authenticate', []);
        $cookie = $auth_response->return;
        // test for cookie return
        // print($cookie);
    });

    // create SOAP client and add service details
    $search_client = new SoapWrapper;
    $search_client::add(function ($service) {

        $service
            ->name('WoSSearch')
            ->wsdl('http://search.webofknowledge.com/esti/wokmws/ws/WokSearch?wsdl')
            ->trace(true)
            ->cache(WSDL_CACHE_NONE);
    });

    if (isset($auth_response->return)) {

        // if there is an SID returned then add it to the cookie attribute of the search client
        $search_client->__setCookie('SID', $cookie);
    } else {
        // route to relevant view to display throttle error
        return redirect('throttle');
    }
}
}

1 个答案:

答案 0 :(得分:1)

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

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

    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的示例