⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codegen.java

📁 java中比较著名的js引擎当属mozilla开源的rhino
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
        for (int i = 0; i != functionCount; i++) {            OptFunctionNode ofn = OptFunctionNode.get(scriptOrFn, i);            if (ofn.fnode.getFunctionType()                    == FunctionNode.FUNCTION_STATEMENT)            {                visitFunction(ofn, FunctionNode.FUNCTION_STATEMENT);            }        }        // default is to generate debug info        if (compilerEnv.isGenerateDebugInfo()) {            cfw.addVariableDescriptor(debugVariableName, "Lorg/mozilla/javascript/Scriptable;", cfw.getCurrentCodeOffset(), variableObjectLocal);        }        if (fnCurrent == null) {            // OPT: use dataflow to prove that this assignment is dead            popvLocal = getNewWordLocal();            Codegen.pushUndefined(cfw);            cfw.addAStore(popvLocal);            int linenum = scriptOrFn.getEndLineno();            if (linenum != -1)              cfw.addLineNumberEntry((short)linenum);        } else {            if (fnCurrent.itsContainsCalls0) {                itsZeroArgArray = getNewWordLocal();                cfw.add(ByteCode.GETSTATIC,                        "org/mozilla/javascript/ScriptRuntime",                        "emptyArgs", "[Ljava/lang/Object;");                cfw.addAStore(itsZeroArgArray);            }            if (fnCurrent.itsContainsCalls1) {                itsOneArgArray = getNewWordLocal();                cfw.addPush(1);                cfw.add(ByteCode.ANEWARRAY, "java/lang/Object");                cfw.addAStore(itsOneArgArray);            }        }    }    private void generateEpilogue()    {        if (hasVarsInRegs) {            if (epilogueLabel != -1) {                cfw.markLabel(epilogueLabel);            }            cfw.add(ByteCode.ARETURN);            return;        }        cfw.markLabel(epilogueLabel);        if (fnCurrent == null) {            cfw.addALoad(popvLocal);            cfw.add(ByteCode.ARETURN);        } else {            generateActivationExit();            cfw.add(ByteCode.ARETURN);            // Generate catch block to catch all and rethrow to call exit code            // under exception propagation as well.            int finallyHandler = cfw.acquireLabel();            cfw.markHandler(finallyHandler);            short exceptionObject = getNewWordLocal();            cfw.addAStore(exceptionObject);            // Duplicate generateActivationExit() in the catch block since it            // takes less space then full-fetured ByteCode.JSR/ByteCode.RET            generateActivationExit();            cfw.addALoad(exceptionObject);            releaseWordLocal(exceptionObject);            // rethrow            cfw.add(ByteCode.ATHROW);            // mark the handler            cfw.addExceptionHandler(enterAreaStartLabel, epilogueLabel,                                    finallyHandler, null); // catch any        }    }    private void generateActivationExit()    {        if (fnCurrent == null || hasVarsInRegs) throw Kit.codeBug();        cfw.addALoad(contextLocal);        addScriptRuntimeInvoke("exitActivationFunction",                               "(Lorg/mozilla/javascript/Context;)V");    }    private void generateStatement(Node node, Node parent)    {        // System.out.println("gen code for " + node.toString());        updateLineNumber(node);        int type = node.getType();        Node child = node.getFirstChild();        switch (type) {              case Token.LOOP:              case Token.LABEL:              case Token.WITH:              case Token.SCRIPT:              case Token.BLOCK:              case Token.EMPTY:                // no-ops.                while (child != null) {                    generateStatement(child, node);                    child = child.getNext();                }                break;              case Token.LOCAL_BLOCK: {                int local = getNewWordLocal();                node.putIntProp(Node.LOCAL_PROP, local);                while (child != null) {                    generateStatement(child, node);                    child = child.getNext();                }                releaseWordLocal((short)local);                node.removeProp(Node.LOCAL_PROP);                break;              }              case Token.FUNCTION: {                int fnIndex = node.getExistingIntProp(Node.FUNCTION_PROP);                OptFunctionNode ofn = OptFunctionNode.get(scriptOrFn, fnIndex);                int t = ofn.fnode.getFunctionType();                if (t == FunctionNode.FUNCTION_EXPRESSION_STATEMENT) {                    visitFunction(ofn, t);                } else {                    if (t != FunctionNode.FUNCTION_STATEMENT) {                        throw Codegen.badTree();                    }                }                break;              }              case Token.TRY:                visitTryCatchFinally((Node.Jump)node, child);                break;              case Token.CATCH_SCOPE:                {                    int local = getLocalBlockRegister(node);                    int scopeIndex                        = node.getExistingIntProp(Node.CATCH_SCOPE_PROP);                    String name = child.getString(); // name of exception                    child = child.getNext();                    generateExpression(child, node); // load expression object                    if (scopeIndex == 0) {                        cfw.add(ByteCode.ACONST_NULL);                    } else {                        // Load previous catch scope object                        cfw.addALoad(local);                    }                    cfw.addPush(name);                    cfw.addALoad(contextLocal);                    cfw.addALoad(variableObjectLocal);                    addScriptRuntimeInvoke(                        "newCatchScope",                        "(Ljava/lang/Throwable;"                        +"Lorg/mozilla/javascript/Scriptable;"                        +"Ljava/lang/String;"                        +"Lorg/mozilla/javascript/Context;"                        +"Lorg/mozilla/javascript/Scriptable;"                        +")Lorg/mozilla/javascript/Scriptable;");                    cfw.addAStore(local);                }                break;              case Token.THROW:                generateExpression(child, node);                cfw.add(ByteCode.NEW,                        "org/mozilla/javascript/JavaScriptException");                cfw.add(ByteCode.DUP_X1);                cfw.add(ByteCode.SWAP);                cfw.addPush(scriptOrFn.getSourceName());                cfw.addPush(itsLineNumber);                cfw.addInvoke(                    ByteCode.INVOKESPECIAL,                    "org/mozilla/javascript/JavaScriptException",                    "<init>",                    "(Ljava/lang/Object;Ljava/lang/String;I)V");                cfw.add(ByteCode.ATHROW);                break;              case Token.RETHROW:                cfw.addALoad(getLocalBlockRegister(node));                cfw.add(ByteCode.ATHROW);                break;              case Token.RETURN_RESULT:              case Token.RETURN:                if (child != null) {                    generateExpression(child, node);                } else if (type == Token.RETURN) {                    Codegen.pushUndefined(cfw);                } else {                    if (popvLocal < 0) throw Codegen.badTree();                    cfw.addALoad(popvLocal);                }                if (epilogueLabel == -1) {                    if (!hasVarsInRegs) throw Codegen.badTree();                    epilogueLabel = cfw.acquireLabel();                }                cfw.add(ByteCode.GOTO, epilogueLabel);                break;              case Token.SWITCH:                visitSwitch((Node.Jump)node, child);                break;              case Token.ENTERWITH:                generateExpression(child, node);                cfw.addALoad(contextLocal);                cfw.addALoad(variableObjectLocal);                addScriptRuntimeInvoke(                    "enterWith",                    "(Ljava/lang/Object;"                    +"Lorg/mozilla/javascript/Context;"                    +"Lorg/mozilla/javascript/Scriptable;"                    +")Lorg/mozilla/javascript/Scriptable;");                cfw.addAStore(variableObjectLocal);                break;              case Token.LEAVEWITH:                cfw.addALoad(variableObjectLocal);                addScriptRuntimeInvoke(                    "leaveWith",                    "(Lorg/mozilla/javascript/Scriptable;"                    +")Lorg/mozilla/javascript/Scriptable;");                cfw.addAStore(variableObjectLocal);                break;              case Token.ENUM_INIT_KEYS:              case Token.ENUM_INIT_VALUES:                generateExpression(child, node);                cfw.addALoad(contextLocal);                cfw.addPush(type == Token.ENUM_INIT_VALUES);                addScriptRuntimeInvoke("enumInit",                                       "(Ljava/lang/Object;"                                       +"Lorg/mozilla/javascript/Context;"                                       +"Z"                                       +")Ljava/lang/Object;");                cfw.addAStore(getLocalBlockRegister(node));                break;              case Token.EXPR_VOID:                if (child.getType() == Token.SETVAR) {                    /* special case this so as to avoid unnecessary                    load's & pop's */                    visitSetVar(child, child.getFirstChild(), false);                }                else {                    generateExpression(child, node);                    if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1)                        cfw.add(ByteCode.POP2);                    else                        cfw.add(ByteCode.POP);                }                break;              case Token.EXPR_RESULT:                generateExpression(child, node);                if (popvLocal < 0) {                    popvLocal = getNewWordLocal();                }                cfw.addAStore(popvLocal);                break;              case Token.TARGET:                {                    int label = getTargetLabel(node);                    cfw.markLabel(label);                }                break;              case Token.JSR:              case Token.GOTO:              case Token.IFEQ:              case Token.IFNE:                visitGOTO((Node.Jump)node, type, child);                break;              case Token.FINALLY:                {                    //Save return address in a new local where                    int finallyRegister = getNewWordLocal();                    cfw.addAStore(finallyRegister);                    while (child != null) {                        generateStatement(child, node);                        child = child.getNext();                    }                    cfw.add(ByteCode.RET, finallyRegister);                    releaseWordLocal((short)finallyRegister);                }                break;              default:                throw Codegen.badTree();        }    }    private void generateExpression(Node node, Node parent)    {        int type = node.getType();        Node child = node.getFirstChild();        switch (type) {              case Token.USE_STACK:                break;              case Token.FUNCTION:                if (fnCurrent != null || parent.getType() != Token.SCRIPT) {                    int fnIndex = node.getExistingIntProp(Node.FUNCTION_PROP);                    OptFunctionNode ofn = OptFunctionNode.get(scriptOrFn,                                                             fnIndex);                    int t = ofn.fnode.getFunctionType();                    if (t != FunctionNode.FUNCTION_EXPRESSION) {                        throw Codegen.badTree();                    }                    visitFunction(ofn, t);                }                break;              case Token.NAME:                {                    cfw.addALoad(contextLocal);                    cfw.addALoad(variableObjectLocal);                    cfw.addPush(node.getString());                    addScriptRuntimeInvoke(                        "name",                        "(Lorg/mozilla/javascript/Context;"                        +"Lorg/mozilla/javascript/Scriptable;"                        +"Ljava/lang/String;"                        +")Ljava/lang/Object;");                }                break;              case Token.CALL:              case Token.NEW:                {                    int specialType = node.getIntProp(Node.SPECIALCALL_PROP,                                                      Node.NON_SPECIALCALL);        

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -