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

📄 interpreter.java

📁 這是一個javascript 的 interpreter是了解 web browser的好材料
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                     caseNode = (Node.Jump)caseNode.getNext())                {                    if (caseNode.getType() != Token.CASE)                        throw badTree(caseNode);                    Node test = caseNode.getFirstChild();                    addIcode(Icode_DUP);                    stackChange(1);                    visitExpression(test, 0);                    addToken(Token.SHEQ);                    stackChange(-1);                    // If true, Icode_IFEQ_POP will jump and remove case                    // value from stack                    addGoto(caseNode.target, Icode_IFEQ_POP);                    stackChange(-1);                }                addIcode(Icode_POP);                stackChange(-1);            }            break;          case Token.TARGET:            markTargetLabel(node);            break;          case Token.IFEQ :          case Token.IFNE :            {                Node target = ((Node.Jump)node).target;                visitExpression(child, 0);                addGoto(target, type);                stackChange(-1);            }            break;          case Token.GOTO:            {                Node target = ((Node.Jump)node).target;                addGoto(target, type);            }            break;          case Token.JSR:            {                Node target = ((Node.Jump)node).target;                addGoto(target, Icode_GOSUB);            }            break;          case Token.FINALLY:            {                // Account for incomming GOTOSUB address                stackChange(1);                int finallyRegister = getLocalBlockRef(node);                addIndexOp(Icode_STARTSUB, finallyRegister);                stackChange(-1);                while (child != null) {                    visitStatement(child, initialStackDepth);                    child = child.getNext();                }                addIndexOp(Icode_RETSUB, finallyRegister);            }            break;          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;          case Token.TRY:            {                Node.Jump tryNode = (Node.Jump)node;                int exceptionObjectLocal = getLocalBlockRef(tryNode);                int scopeLocal = allocLocal();                addIndexOp(Icode_SCOPE_SAVE, scopeLocal);                int tryStart = itsICodeTop;                boolean savedFlag = itsInTryFlag;                itsInTryFlag = true;                while (child != null) {                    visitStatement(child, initialStackDepth);                    child = child.getNext();                }                itsInTryFlag = savedFlag;                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 (node.getIntProp(Node.GENERATOR_END_PROP, 0) != 0) {                // We're in a generator, so change RETURN to GENERATOR_END                addIcode(Icode_GENERATOR_END);                addUint16(itsLineNumber & 0xFFFF);            } else 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:          case Token.ENUM_INIT_ARRAY:            visitExpression(child, 0);            addIndexOp(type, getLocalBlockRef(node));            stackChange(-1);            break;          case Icode_GENERATOR:            break;          default:            throw badTree(node);        }        if (itsStackDepth != initialStackDepth) {            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 {                    // Only use the tail call optimization if we're not in a try                    // or we're not generating debug info (since the                    // optimization will confuse the debugger)                    if (type == Token.CALL && (contextFlags & ECF_TAIL) != 0 &&                        !compilerEnv.isGenerateDebugInfo() && !itsInTryFlag)                    {                        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:          case Token.GETPROPNOWARN:            visitExpression(child, 0);            child = child.getNext();            addStringOp(type, 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

⌨️ 快捷键说明

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