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

📄 interpreter.java

📁 java中比较著名的js引擎当属mozilla开源的rhino
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): *   Patrick Beard *   Norris Boyd *   Igor Bukanov *   Ethan Hugg *   Terry Lucas *   Roger Lawrence *   Milen Nankov * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */package org.mozilla.javascript;import java.io.PrintStream;import java.io.Serializable;import org.mozilla.javascript.continuations.Continuation;import org.mozilla.javascript.debug.DebugFrame;public class Interpreter{// Additional interpreter-specific codes    private static final int    // Stack: ... value1 -> ... value1 value1        Icode_DUP                       = -1,    // Stack: ... value2 value1 -> ... value2 value1 value2 value1        Icode_DUP2                      = -2,    // Stack: ... value2 value1 -> ... value1 value2        Icode_SWAP                      = -3,    // Stack: ... value1 -> ...        Icode_POP                       = -4,    // Store stack top into return register and then pop it        Icode_POP_RESULT                = -5,    // To jump conditionally and pop additional stack value        Icode_IFEQ_POP                  = -6,    // various types of ++/--        Icode_VAR_INC_DEC               = -7,        Icode_NAME_INC_DEC              = -8,        Icode_PROP_INC_DEC              = -9,        Icode_ELEM_INC_DEC              = -10,        Icode_REF_INC_DEC               = -11,    // load/save scope from/to local        Icode_SCOPE_LOAD                = -12,        Icode_SCOPE_SAVE                = -13,        Icode_TYPEOFNAME                = -14,    // helper for function calls        Icode_NAME_AND_THIS             = -15,        Icode_PROP_AND_THIS             = -16,        Icode_ELEM_AND_THIS             = -17,        Icode_VALUE_AND_THIS            = -18,    // Create closure object for nested functions        Icode_CLOSURE_EXPR              = -19,        Icode_CLOSURE_STMT              = -20,    // Special calls        Icode_CALLSPECIAL               = -21,    // To return undefined value        Icode_RETUNDEF                  = -22,    // Exception handling implementation        Icode_GOSUB                     = -23,        Icode_STARTSUB                  = -24,        Icode_RETSUB                    = -25,    // To indicating a line number change in icodes.        Icode_LINE                      = -26,    // To store shorts and ints inline        Icode_SHORTNUMBER               = -27,        Icode_INTNUMBER                 = -28,    // To create and populate array to hold values for [] and {} literals        Icode_LITERAL_NEW               = -29,        Icode_LITERAL_SET               = -30,    // Array literal with skipped index like [1,,2]        Icode_SPARE_ARRAYLIT            = -31,    // Load index register to prepare for the following index operation        Icode_REG_IND_C0                = -32,        Icode_REG_IND_C1                = -33,        Icode_REG_IND_C2                = -34,        Icode_REG_IND_C3                = -35,        Icode_REG_IND_C4                = -36,        Icode_REG_IND_C5                = -37,        Icode_REG_IND1                  = -38,        Icode_REG_IND2                  = -39,        Icode_REG_IND4                  = -40,    // Load string register to prepare for the following string operation        Icode_REG_STR_C0                = -41,        Icode_REG_STR_C1                = -42,        Icode_REG_STR_C2                = -43,        Icode_REG_STR_C3                = -44,        Icode_REG_STR1                  = -45,        Icode_REG_STR2                  = -46,        Icode_REG_STR4                  = -47,    // Version of getvar/setvar that read var index directly from bytecode        Icode_GETVAR1                   = -48,        Icode_SETVAR1                   = -49,    // Load unefined        Icode_UNDEF                     = -50,        Icode_ZERO                      = -51,        Icode_ONE                       = -52,    // entrance and exit from .()       Icode_ENTERDQ                    = -53,       Icode_LEAVEDQ                    = -54,       Icode_TAIL_CALL                  = -55,       // Clear local to allow GC its context       Icode_LOCAL_CLEAR                = -56,    // Last icode        MIN_ICODE                       = -56;    // data for parsing    private CompilerEnvirons compilerEnv;    private boolean itsInFunctionFlag;    private InterpreterData itsData;    private ScriptOrFnNode scriptOrFn;    private int itsICodeTop;    private int itsStackDepth;    private int itsLineNumber;    private int itsDoubleTableTop;    private ObjToIntMap itsStrings = new ObjToIntMap(20);    private int itsLocalTop;    private static final int MIN_LABEL_TABLE_SIZE = 32;    private static final int MIN_FIXUP_TABLE_SIZE = 40;    private int[] itsLabelTable;    private int itsLabelTableTop;// itsFixupTable[i] = (label_index << 32) | fixup_site    private long[] itsFixupTable;    private int itsFixupTableTop;    private ObjArray itsLiteralIds = new ObjArray();    private int itsExceptionTableTop;    private static final int EXCEPTION_TRY_START_SLOT  = 0;    private static final int EXCEPTION_TRY_END_SLOT    = 1;    private static final int EXCEPTION_HANDLER_SLOT    = 2;    private static final int EXCEPTION_TYPE_SLOT       = 3;    private static final int EXCEPTION_LOCAL_SLOT      = 4;    private static final int EXCEPTION_SCOPE_SLOT      = 5;    // SLOT_SIZE: space for try start/end, handler, start, handler type,    //            exception local and scope local    private static final int EXCEPTION_SLOT_SIZE       = 6;// ECF_ or Expression Context Flags constants: for now only TAIL is available    private static final int ECF_TAIL = 1 << 0;    /**     * Class to hold data corresponding to one interpreted call stack frame.     */    private static class CallFrame implements Cloneable, Serializable    {        static final long serialVersionUID = -2843792508994958978L;        CallFrame parentFrame;        // amount of stack frames before this one on the interpretation stack        int frameIndex;        // If true indicates read-only frame that is a part of continuation        boolean frozen;        InterpretedFunction fnOrScript;        InterpreterData idata;// Stack structure// stack[0 <= i < localShift]: arguments and local variables// stack[localShift <= i <= emptyStackTop]: used for local temporaries// stack[emptyStackTop < i < stack.length]: stack data// sDbl[i]: if stack[i] is UniqueTag.DOUBLE_MARK, sDbl[i] holds the number value        Object[] stack;        double[] sDbl;        CallFrame varSource; // defaults to this unless continuation frame        int localShift;        int emptyStackTop;        DebugFrame debuggerFrame;        boolean useActivation;        Scriptable thisObj;        Scriptable[] scriptRegExps;// The values that change during interpretation        Object result;        double resultDbl;        int pc;        int pcPrevBranch;        int pcSourceLineStart;        Scriptable scope;        int savedStackTop;        int savedCallOp;        CallFrame cloneFrozen()        {            if (!frozen) Kit.codeBug();            CallFrame copy;            try {                copy = (CallFrame)clone();            } catch (CloneNotSupportedException ex) {                throw new IllegalStateException();            }            // clone stack but keep varSource to point to values            // from this frame to share variables.            copy.stack = (Object[])stack.clone();            copy.sDbl = (double[])sDbl.clone();            copy.frozen = false;            return copy;        }    }    private static final class ContinuationJump implements Serializable    {        static final long serialVersionUID = 7687739156004308247L;        CallFrame capturedFrame;        CallFrame branchFrame;        Object result;        double resultDbl;        ContinuationJump(Continuation c, CallFrame current)        {            this.capturedFrame = (CallFrame)c.getImplementation();            if (this.capturedFrame == null || current == null) {                // Continuation and current execution does not share                // any frames if there is nothing to capture or                // if there is no currently executed frames                this.branchFrame = null;            } else {                // Search for branch frame where parent frame chains starting                // from captured and current meet.                CallFrame chain1 = this.capturedFrame;                CallFrame chain2 = current;                // First work parents of chain1 or chain2 until the same                // frame depth.                int diff = chain1.frameIndex - chain2.frameIndex;                if (diff != 0) {                    if (diff < 0) {                        // swap to make sure that                        // chain1.frameIndex > chain2.frameIndex and diff > 0                        chain1 = current;                        chain2 = this.capturedFrame;                        diff = -diff;                    }                    do {                        chain1 = chain1.parentFrame;                    } while (--diff != 0);                    if (chain1.frameIndex != chain2.frameIndex) Kit.codeBug();                }                // Now walk parents in parallel until a shared frame is found                // or until the root is reached.                while (chain1 != chain2 && chain1 != null) {                    chain1 = chain1.parentFrame;                    chain2 = chain2.parentFrame;                }                this.branchFrame = chain1;                if (this.branchFrame != null && !this.branchFrame.frozen)                    Kit.codeBug();            }        }    }    static {        // Checks for byte code consistencies, good compiler can eliminate them        if (Token.LAST_BYTECODE_TOKEN > 127) {            String str = "Violation of Token.LAST_BYTECODE_TOKEN <= 127";            System.err.println(str);            throw new IllegalStateException(str);        }        if (MIN_ICODE < -128) {            String str = "Violation of Interpreter.MIN_ICODE >= -128";            System.err.println(str);            throw new IllegalStateException(str);        }    }    private static String bytecodeName(int bytecode)    {        if (!validBytecode(bytecode)) {            throw new IllegalArgumentException(String.valueOf(bytecode));        }        if (!Token.printICode) {            return String.valueOf(bytecode);        }        if (validTokenCode(bytecode)) {            return Token.name(bytecode);        }        switch (bytecode) {          case Icode_DUP:              return "DUP";          case Icode_DUP2:             return "DUP2";          case Icode_SWAP:             return "SWAP";          case Icode_POP:              return "POP";          case Icode_POP_RESULT:       return "POP_RESULT";          case Icode_IFEQ_POP:         return "IFEQ_POP";          case Icode_VAR_INC_DEC:      return "VAR_INC_DEC";          case Icode_NAME_INC_DEC:     return "NAME_INC_DEC";          case Icode_PROP_INC_DEC:     return "PROP_INC_DEC";          case Icode_ELEM_INC_DEC:     return "ELEM_INC_DEC";          case Icode_REF_INC_DEC:      return "REF_INC_DEC";          case Icode_SCOPE_LOAD:       return "SCOPE_LOAD";          case Icode_SCOPE_SAVE:       return "SCOPE_SAVE";          case Icode_TYPEOFNAME:       return "TYPEOFNAME";          case Icode_NAME_AND_THIS:    return "NAME_AND_THIS";          case Icode_PROP_AND_THIS:    return "PROP_AND_THIS";          case Icode_ELEM_AND_THIS:    return "ELEM_AND_THIS";          case Icode_VALUE_AND_THIS:   return "VALUE_AND_THIS";          case Icode_CLOSURE_EXPR:     return "CLOSURE_EXPR";          case Icode_CLOSURE_STMT:     return "CLOSURE_STMT";          case Icode_CALLSPECIAL:      return "CALLSPECIAL";          case Icode_RETUNDEF:         return "RETUNDEF";          case Icode_GOSUB:            return "GOSUB";          case Icode_STARTSUB:         return "STARTSUB";          case Icode_RETSUB:           return "RETSUB";          case Icode_LINE:             return "LINE";          case Icode_SHORTNUMBER:      return "SHORTNUMBER";

⌨️ 快捷键说明

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