Home | History | Annotate | Download | only in interpreter
      1 /*
      2  * Copyright (C) 2008 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     14  *     its contributors may be used to endorse or promote products derived
     15  *     from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #ifndef Interpreter_h
     30 #define Interpreter_h
     31 
     32 #include "ArgList.h"
     33 #include "FastAllocBase.h"
     34 #include "JSCell.h"
     35 #include "JSValue.h"
     36 #include "JSObject.h"
     37 #include "Opcode.h"
     38 #include "RegisterFile.h"
     39 
     40 #include <wtf/HashMap.h>
     41 
     42 namespace JSC {
     43 
     44     class CodeBlock;
     45     class EvalExecutable;
     46     class FunctionExecutable;
     47     class InternalFunction;
     48     class JSFunction;
     49     class JSGlobalObject;
     50     class ProgramExecutable;
     51     class Register;
     52     class ScopeChainNode;
     53     class SamplingTool;
     54     struct CallFrameClosure;
     55     struct HandlerInfo;
     56     struct Instruction;
     57 
     58     enum DebugHookID {
     59         WillExecuteProgram,
     60         DidExecuteProgram,
     61         DidEnterCallFrame,
     62         DidReachBreakpoint,
     63         WillLeaveCallFrame,
     64         WillExecuteStatement
     65     };
     66 
     67     enum { MaxMainThreadReentryDepth = 256, MaxSecondaryThreadReentryDepth = 32 };
     68 
     69     class Interpreter : public FastAllocBase {
     70         friend class JIT;
     71         friend class CachedCall;
     72     public:
     73         Interpreter();
     74 
     75         RegisterFile& registerFile() { return m_registerFile; }
     76 
     77         Opcode getOpcode(OpcodeID id)
     78         {
     79             #if HAVE(COMPUTED_GOTO)
     80                 return m_opcodeTable[id];
     81             #else
     82                 return id;
     83             #endif
     84         }
     85 
     86         OpcodeID getOpcodeID(Opcode opcode)
     87         {
     88             #if HAVE(COMPUTED_GOTO)
     89                 ASSERT(isOpcode(opcode));
     90                 return m_opcodeIDTable.get(opcode);
     91             #else
     92                 return opcode;
     93             #endif
     94         }
     95 
     96         bool isOpcode(Opcode);
     97 
     98         JSValue execute(ProgramExecutable*, CallFrame*, ScopeChainNode*, JSObject* thisObj, JSValue* exception);
     99         JSValue execute(FunctionExecutable*, CallFrame*, JSFunction*, JSObject* thisObj, const ArgList& args, ScopeChainNode*, JSValue* exception);
    100         JSValue execute(EvalExecutable* evalNode, CallFrame* exec, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue* exception);
    101 
    102         JSValue retrieveArguments(CallFrame*, JSFunction*) const;
    103         JSValue retrieveCaller(CallFrame*, InternalFunction*) const;
    104         void retrieveLastCaller(CallFrame*, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValue& function) const;
    105 
    106         void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
    107 
    108         SamplingTool* sampler() { return m_sampler.get(); }
    109 
    110         NEVER_INLINE JSValue callEval(CallFrame*, RegisterFile*, Register* argv, int argc, int registerOffset, JSValue& exceptionValue);
    111         NEVER_INLINE HandlerInfo* throwException(CallFrame*&, JSValue&, unsigned bytecodeOffset, bool);
    112         NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine);
    113 
    114         void dumpSampleData(ExecState* exec);
    115         void startSampling();
    116         void stopSampling();
    117     private:
    118         enum ExecutionFlag { Normal, InitializeAndReturn };
    119 
    120         CallFrameClosure prepareForRepeatCall(FunctionExecutable*, CallFrame*, JSFunction*, int argCount, ScopeChainNode*, JSValue* exception);
    121         void endRepeatCall(CallFrameClosure&);
    122         JSValue execute(CallFrameClosure&, JSValue* exception);
    123 
    124         JSValue execute(EvalExecutable*, CallFrame*, JSObject* thisObject, int globalRegisterOffset, ScopeChainNode*, JSValue* exception);
    125 
    126 #if USE(INTERPRETER)
    127         NEVER_INLINE bool resolve(CallFrame*, Instruction*, JSValue& exceptionValue);
    128         NEVER_INLINE bool resolveSkip(CallFrame*, Instruction*, JSValue& exceptionValue);
    129         NEVER_INLINE bool resolveGlobal(CallFrame*, Instruction*, JSValue& exceptionValue);
    130         NEVER_INLINE void resolveBase(CallFrame*, Instruction* vPC);
    131         NEVER_INLINE bool resolveBaseAndProperty(CallFrame*, Instruction*, JSValue& exceptionValue);
    132         NEVER_INLINE ScopeChainNode* createExceptionScope(CallFrame*, const Instruction* vPC);
    133 
    134         void tryCacheGetByID(CallFrame*, CodeBlock*, Instruction*, JSValue baseValue, const Identifier& propertyName, const PropertySlot&);
    135         void uncacheGetByID(CodeBlock*, Instruction* vPC);
    136         void tryCachePutByID(CallFrame*, CodeBlock*, Instruction*, JSValue baseValue, const PutPropertySlot&);
    137         void uncachePutByID(CodeBlock*, Instruction* vPC);
    138 #endif
    139 
    140         NEVER_INLINE bool unwindCallFrame(CallFrame*&, JSValue, unsigned& bytecodeOffset, CodeBlock*&);
    141 
    142         static ALWAYS_INLINE CallFrame* slideRegisterWindowForCall(CodeBlock*, RegisterFile*, CallFrame*, size_t registerOffset, int argc);
    143 
    144         static CallFrame* findFunctionCallFrame(CallFrame*, InternalFunction*);
    145 
    146         JSValue privateExecute(ExecutionFlag, RegisterFile*, CallFrame*, JSValue* exception);
    147 
    148         void dumpCallFrame(CallFrame*);
    149         void dumpRegisters(CallFrame*);
    150 
    151         bool isCallBytecode(Opcode opcode) { return opcode == getOpcode(op_call) || opcode == getOpcode(op_construct) || opcode == getOpcode(op_call_eval); }
    152 
    153         void enableSampler();
    154         int m_sampleEntryDepth;
    155         OwnPtr<SamplingTool> m_sampler;
    156 
    157         int m_reentryDepth;
    158 
    159         RegisterFile m_registerFile;
    160 
    161 #if HAVE(COMPUTED_GOTO)
    162         Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
    163         HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
    164 #endif
    165     };
    166 
    167 } // namespace JSC
    168 
    169 #endif // Interpreter_h
    170