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 "JSCell.h"
     34 #include "JSValue.h"
     35 #include "JSObject.h"
     36 #include "Opcode.h"
     37 #include "RegisterFile.h"
     38 
     39 #include <wtf/HashMap.h>
     40 
     41 namespace JSC {
     42 
     43     class CodeBlock;
     44     class EvalExecutable;
     45     class FunctionExecutable;
     46     class JSFunction;
     47     class JSGlobalObject;
     48     class ProgramExecutable;
     49     class Register;
     50     class ScopeChainNode;
     51     class SamplingTool;
     52     struct CallFrameClosure;
     53     struct HandlerInfo;
     54     struct Instruction;
     55 
     56     enum DebugHookID {
     57         WillExecuteProgram,
     58         DidExecuteProgram,
     59         DidEnterCallFrame,
     60         DidReachBreakpoint,
     61         WillLeaveCallFrame,
     62         WillExecuteStatement
     63     };
     64 
     65     enum { MaxLargeThreadReentryDepth = 256, MaxSmallThreadReentryDepth = 32 };
     66 
     67     class Interpreter {
     68         WTF_MAKE_FAST_ALLOCATED;
     69         friend class JIT;
     70         friend class CachedCall;
     71     public:
     72         Interpreter(JSGlobalData&);
     73 
     74         RegisterFile& registerFile() { return m_registerFile; }
     75 
     76         Opcode getOpcode(OpcodeID id)
     77         {
     78             #if ENABLE(COMPUTED_GOTO_INTERPRETER)
     79                 return m_opcodeTable[id];
     80             #else
     81                 return id;
     82             #endif
     83         }
     84 
     85         OpcodeID getOpcodeID(Opcode opcode)
     86         {
     87             #if ENABLE(COMPUTED_GOTO_INTERPRETER)
     88                 ASSERT(isOpcode(opcode));
     89                 return m_opcodeIDTable.get(opcode);
     90             #else
     91                 return opcode;
     92             #endif
     93         }
     94 
     95         bool isOpcode(Opcode);
     96 
     97         JSValue execute(ProgramExecutable*, CallFrame*, ScopeChainNode*, JSObject* thisObj);
     98         JSValue executeCall(CallFrame*, JSObject* function, CallType, const CallData&, JSValue thisValue, const ArgList&);
     99         JSObject* executeConstruct(CallFrame*, JSObject* function, ConstructType, const ConstructData&, const ArgList&);
    100         JSValue execute(EvalExecutable* evalNode, CallFrame* exec, JSObject* thisObj, ScopeChainNode* scopeChain);
    101 
    102         JSValue retrieveArguments(CallFrame*, JSFunction*) const;
    103         JSValue retrieveCaller(CallFrame*, JSFunction*) 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);
    111         NEVER_INLINE HandlerInfo* throwException(CallFrame*&, JSValue&, unsigned bytecodeOffset);
    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*);
    121         void endRepeatCall(CallFrameClosure&);
    122         JSValue execute(CallFrameClosure&);
    123 
    124         JSValue execute(EvalExecutable*, CallFrame*, JSObject* thisObject, int globalRegisterOffset, ScopeChainNode*);
    125 
    126 #if ENABLE(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 bool resolveGlobalDynamic(CallFrame*, Instruction*, JSValue& exceptionValue);
    131         NEVER_INLINE void resolveBase(CallFrame*, Instruction* vPC);
    132         NEVER_INLINE bool resolveBaseAndProperty(CallFrame*, Instruction*, JSValue& exceptionValue);
    133         NEVER_INLINE ScopeChainNode* createExceptionScope(CallFrame*, const Instruction* vPC);
    134 
    135         void tryCacheGetByID(CallFrame*, CodeBlock*, Instruction*, JSValue baseValue, const Identifier& propertyName, const PropertySlot&);
    136         void uncacheGetByID(CodeBlock*, Instruction* vPC);
    137         void tryCachePutByID(CallFrame*, CodeBlock*, Instruction*, JSValue baseValue, const PutPropertySlot&);
    138         void uncachePutByID(CodeBlock*, Instruction* vPC);
    139 #endif // ENABLE(INTERPRETER)
    140 
    141         NEVER_INLINE bool unwindCallFrame(CallFrame*&, JSValue, unsigned& bytecodeOffset, CodeBlock*&);
    142 
    143         static ALWAYS_INLINE CallFrame* slideRegisterWindowForCall(CodeBlock*, RegisterFile*, CallFrame*, size_t registerOffset, int argc);
    144 
    145         static CallFrame* findFunctionCallFrame(CallFrame*, JSFunction*);
    146 
    147         JSValue privateExecute(ExecutionFlag, RegisterFile*, CallFrame*);
    148 
    149         void dumpCallFrame(CallFrame*);
    150         void dumpRegisters(CallFrame*);
    151 
    152         bool isCallBytecode(Opcode opcode) { return opcode == getOpcode(op_call) || opcode == getOpcode(op_construct) || opcode == getOpcode(op_call_eval); }
    153 
    154         void enableSampler();
    155         int m_sampleEntryDepth;
    156         OwnPtr<SamplingTool> m_sampler;
    157 
    158         int m_reentryDepth;
    159 
    160         RegisterFile m_registerFile;
    161 
    162 #if ENABLE(COMPUTED_GOTO_INTERPRETER)
    163         Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
    164         HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
    165 #endif
    166     };
    167 
    168 } // namespace JSC
    169 
    170 #endif // Interpreter_h
    171