?? interpreter.java
字號:
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape 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/NPL/ * * 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 Netscape are * Copyright (C) 1997-2000 Netscape Communications Corporation. 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 Public License (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 NPL, indicate your decision by * deleting the provisions above and replace 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 NPL or the GPL. */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"; case Icode_INTNUMBER: return "INTNUMBER"; case Icode_LITERAL_NEW: return "LITERAL_NEW"; case Icode_LITERAL_SET: return "LITERAL_SET"; case Icode_SPARE_ARRAYLIT: return "SPARE_ARRAYLIT";
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -