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

📄 interpreter.java

📁 java中比较著名的js引擎当属mozilla开源的rhino
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                Node.Jump tryNode = (Node.Jump)node;                int exceptionObjectLocal = getLocalBlockRef(tryNode);                int scopeLocal = allocLocal();                addIndexOp(Icode_SCOPE_SAVE, scopeLocal);                int tryStart = itsICodeTop;                while (child != null) {                    visitStatement(child);                    child = child.getNext();                }                Node catchTarget = tryNode.target;                if (catchTarget != null) {                    int catchStartPC                        = itsLabelTable[getTargetLabel(catchTarget)];                    addExceptionHandler(                        tryStart, catchStartPC, catchStartPC,                        false, exceptionObjectLocal, scopeLocal);                }                Node finallyTarget = tryNode.getFinally();                if (finallyTarget != null) {                    int finallyStartPC                        = itsLabelTable[getTargetLabel(finallyTarget)];                    addExceptionHandler(                        tryStart, finallyStartPC, finallyStartPC,                        true, exceptionObjectLocal, scopeLocal);                }                addIndexOp(Icode_LOCAL_CLEAR, scopeLocal);                releaseLocal(scopeLocal);            }            break;          case Token.CATCH_SCOPE:            {                int localIndex = getLocalBlockRef(node);                int scopeIndex = node.getExistingIntProp(Node.CATCH_SCOPE_PROP);                String name = child.getString();                child = child.getNext();                visitExpression(child, 0); // load expression object                addStringPrefix(name);                addIndexPrefix(localIndex);                addToken(Token.CATCH_SCOPE);                addUint8(scopeIndex != 0 ? 1 : 0);                stackChange(-1);            }            break;          case Token.THROW:            updateLineNumber(node);            visitExpression(child, 0);            addToken(Token.THROW);            addUint16(itsLineNumber & 0xFFFF);            stackChange(-1);            break;          case Token.RETHROW:            updateLineNumber(node);            addIndexOp(Token.RETHROW, getLocalBlockRef(node));            break;          case Token.RETURN:            updateLineNumber(node);            if (child != null) {                visitExpression(child, ECF_TAIL);                addToken(Token.RETURN);                stackChange(-1);            } else {                addIcode(Icode_RETUNDEF);            }            break;          case Token.RETURN_RESULT:            updateLineNumber(node);            addToken(Token.RETURN_RESULT);            break;          case Token.ENUM_INIT_KEYS:          case Token.ENUM_INIT_VALUES :            visitExpression(child, 0);            addIndexOp(type, getLocalBlockRef(node));            stackChange(-1);            break;          default:            throw badTree(node);        }        if (itsStackDepth != 0) {            throw Kit.codeBug();        }    }    private void visitExpression(Node node, int contextFlags)    {        int type = node.getType();        Node child = node.getFirstChild();        int savedStackDepth = itsStackDepth;        switch (type) {          case Token.FUNCTION:            {                int fnIndex = node.getExistingIntProp(Node.FUNCTION_PROP);                FunctionNode fn = scriptOrFn.getFunctionNode(fnIndex);                // See comments in visitStatement for Token.FUNCTION case                if (fn.getFunctionType() != FunctionNode.FUNCTION_EXPRESSION) {                    throw Kit.codeBug();                }                addIndexOp(Icode_CLOSURE_EXPR, fnIndex);                stackChange(1);            }            break;          case Token.LOCAL_LOAD:            {                int localIndex = getLocalBlockRef(node);                addIndexOp(Token.LOCAL_LOAD, localIndex);                stackChange(1);            }            break;          case Token.COMMA:            {                Node lastChild = node.getLastChild();                while (child != lastChild) {                    visitExpression(child, 0);                    addIcode(Icode_POP);                    stackChange(-1);                    child = child.getNext();                }                // Preserve tail context flag if any                visitExpression(child, contextFlags & ECF_TAIL);            }            break;          case Token.USE_STACK:            // Indicates that stack was modified externally,            // like placed catch object            stackChange(1);            break;          case Token.REF_CALL:          case Token.CALL:          case Token.NEW:            {                if (type == Token.NEW) {                    visitExpression(child, 0);                } else {                    generateCallFunAndThis(child);                }                int argCount = 0;                while ((child = child.getNext()) != null) {                    visitExpression(child, 0);                    ++argCount;                }                int callType = node.getIntProp(Node.SPECIALCALL_PROP,                                               Node.NON_SPECIALCALL);                if (callType != Node.NON_SPECIALCALL) {                    // embed line number and source filename                    addIndexOp(Icode_CALLSPECIAL, argCount);                    addUint8(callType);                    addUint8(type == Token.NEW ? 1 : 0);                    addUint16(itsLineNumber & 0xFFFF);                } else {                    if (type == Token.CALL) {                        if ((contextFlags & ECF_TAIL) != 0) {                            type = Icode_TAIL_CALL;                        }                    }                    addIndexOp(type, argCount);                }                // adjust stack                if (type == Token.NEW) {                    // new: f, args -> result                    stackChange(-argCount);                } else {                    // call: f, thisObj, args -> result                    // ref_call: f, thisObj, args -> ref                    stackChange(-1 - argCount);                }                if (argCount > itsData.itsMaxCalleeArgs) {                    itsData.itsMaxCalleeArgs = argCount;                }            }            break;          case Token.AND:          case Token.OR:            {                visitExpression(child, 0);                addIcode(Icode_DUP);                stackChange(1);                int afterSecondJumpStart = itsICodeTop;                int jump = (type == Token.AND) ? Token.IFNE : Token.IFEQ;                addGotoOp(jump);                stackChange(-1);                addIcode(Icode_POP);                stackChange(-1);                child = child.getNext();                // Preserve tail context flag if any                visitExpression(child, contextFlags & ECF_TAIL);                resolveForwardGoto(afterSecondJumpStart);            }            break;          case Token.HOOK:            {                Node ifThen = child.getNext();                Node ifElse = ifThen.getNext();                visitExpression(child, 0);                int elseJumpStart = itsICodeTop;                addGotoOp(Token.IFNE);                stackChange(-1);                // Preserve tail context flag if any                visitExpression(ifThen, contextFlags & ECF_TAIL);                int afterElseJumpStart = itsICodeTop;                addGotoOp(Token.GOTO);                resolveForwardGoto(elseJumpStart);                itsStackDepth = savedStackDepth;                // Preserve tail context flag if any                visitExpression(ifElse, contextFlags & ECF_TAIL);                resolveForwardGoto(afterElseJumpStart);            }            break;          case Token.GETPROP:            visitExpression(child, 0);            child = child.getNext();            addStringOp(Token.GETPROP, child.getString());            break;          case Token.GETELEM:          case Token.DELPROP:          case Token.BITAND:          case Token.BITOR:          case Token.BITXOR:          case Token.LSH:          case Token.RSH:          case Token.URSH:          case Token.ADD:          case Token.SUB:          case Token.MOD:          case Token.DIV:          case Token.MUL:          case Token.EQ:          case Token.NE:          case Token.SHEQ:          case Token.SHNE:          case Token.IN:          case Token.INSTANCEOF:          case Token.LE:          case Token.LT:          case Token.GE:          case Token.GT:            visitExpression(child, 0);            child = child.getNext();            visitExpression(child, 0);            addToken(type);            stackChange(-1);            break;          case Token.POS:          case Token.NEG:          case Token.NOT:          case Token.BITNOT:          case Token.TYPEOF:          case Token.VOID:            visitExpression(child, 0);            if (type == Token.VOID) {                addIcode(Icode_POP);                addIcode(Icode_UNDEF);            } else {                addToken(type);            }            break;          case Token.GET_REF:          case Token.DEL_REF:            visitExpression(child, 0);            addToken(type);            break;          case Token.SETPROP:          case Token.SETPROP_OP:            {                visitExpression(child, 0);                child = child.getNext();                String property = child.getString();                child = child.getNext();                if (type == Token.SETPROP_OP) {                    addIcode(Icode_DUP);                    stackChange(1);                    addStringOp(Token.GETPROP, property);                    // Compensate for the following USE_STACK                    stackChange(-1);                }                visitExpression(child, 0);                addStringOp(Token.SETPROP, property);                stackChange(-1);            }            break;          case Token.SETELEM:          case Token.SETELEM_OP:            visitExpression(child, 0);            child = child.getNext();            visitExpression(child, 0);            child = child.getNext();            if (type == Token.SETELEM_OP) {                addIcode(Icode_DUP2);                stackChange(2);                addToken(Token.GETELEM);                stackChange(-1);                // Compensate for the following USE_STACK                stackChange(-1);            }            visitExpression(child, 0);            addToken(Token.SETELEM);            stackChange(-2);            break;          case Token.SET_REF:          case Token.SET_REF_OP:            visitExpression(child, 0);            child = child.getNext();            if (type == Token.SET_REF_OP) {                addIcode(Icode_DUP);                stackChange(1);                addToken(Token.GET_REF);                // Compensate for the following USE_STACK                stackChange(-1);            }            visitExpression(child, 0);            addToken(Token.SET_REF);            stackChange(-1);            break;          case Token.SETNAME:            {                String name = child.getString();                visitExpression(child, 0);                child = child.getNext();                visitExpression(child, 0);                addStringOp(Token.SETNAME, name);                stackChange(-1);            }            break;          case Token.TYPEOFNAME:            {                String name = node.getString();                int index = -1;                // use typeofname if an activation frame exists                // since the vars all exist there instead of in jregs                if (itsInFunctionFlag && !itsData.itsNeedsActivation)                    index = scriptOrFn.getParamOrVarIndex(name);                if (index == -1) {                    addStringOp(Icode_TYPEOFNAME, name);                    stackChange(1);                } else {                    addVarOp(Token.GETVAR, index);                    stackChange(1);                    addToken(Token.TYPEOF);                }            }            break;          case Token.BINDNAME:          case Token.NAME:          case Token.STRING:            addStringOp(type, node.getString());            stackChange(1);            break;          case Token.INC:          case Token.DEC:            visitIncDec(node, child);            break;          case Token.NUMBER:            {                double num = node.getDouble();                int inum = (int)num;

⌨️ 快捷键说明

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