blob: fd7f624e4237d15beb97145313a201a3c9ca0e6b [file] [log] [blame]
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +00001/*
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 */
weinig@apple.coma963b962008-06-05 05:36:55 +000028
ggaren@apple.com901a8a22008-11-17 20:57:18 +000029#ifndef Interpreter_h
30#define Interpreter_h
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000031
weinig@apple.com49b32502008-07-06 00:10:04 +000032#include "ArgList.h"
ggaren@apple.com1d72f772008-07-03 00:47:00 +000033#include "JSCell.h"
34#include "JSValue.h"
ggaren@apple.combb639262009-02-20 06:04:21 +000035#include "JSObject.h"
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000036#include "Opcode.h"
ggaren@apple.com82a62d02008-06-27 22:35:33 +000037#include "RegisterFile.h"
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000038
hausmann@webkit.orgf71db052009-07-15 15:14:15 +000039#include <wtf/HashMap.h>
40
cwzwarich@webkit.org3f782f62008-09-08 01:28:33 +000041namespace JSC {
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000042
43 class CodeBlock;
barraclough@apple.com836511562009-08-15 01:14:00 +000044 class EvalExecutable;
barraclough@apple.com306bb122009-08-18 05:34:52 +000045 class FunctionExecutable;
ggaren@apple.com82a62d02008-06-27 22:35:33 +000046 class JSFunction;
oliver@apple.comc8f3a752008-06-28 04:02:03 +000047 class JSGlobalObject;
barraclough@apple.com836511562009-08-15 01:14:00 +000048 class ProgramExecutable;
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000049 class Register;
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000050 class ScopeChainNode;
barraclough@apple.comeb51bd92008-07-30 17:38:35 +000051 class SamplingTool;
oliver@apple.comef1f5ce2009-04-15 07:31:48 +000052 struct CallFrameClosure;
weinig@apple.com18064e72008-12-10 00:26:13 +000053 struct HandlerInfo;
levin@chromium.org93604aa2009-07-29 08:04:19 +000054 struct Instruction;
55
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000056 enum DebugHookID {
ggaren@apple.comd0740c82008-05-28 20:47:13 +000057 WillExecuteProgram,
58 DidExecuteProgram,
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000059 DidEnterCallFrame,
oliver@apple.com139b5292008-06-03 22:48:52 +000060 DidReachBreakpoint,
ggaren@apple.comd0740c82008-05-28 20:47:13 +000061 WillLeaveCallFrame,
62 WillExecuteStatement
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000063 };
64
commit-queue@webkit.org84814622011-08-25 01:25:38 +000065 class TopCallFrameSetter {
66 public:
67 TopCallFrameSetter(JSGlobalData& global, CallFrame* callFrame)
68 : globalData(global)
69 , oldCallFrame(global.topCallFrame)
70 {
71 global.topCallFrame = callFrame;
72 }
73
74 ~TopCallFrameSetter()
75 {
76 globalData.topCallFrame = oldCallFrame;
77 }
78 private:
79 JSGlobalData& globalData;
80 CallFrame* oldCallFrame;
81 };
82
weinig@apple.com1d6ce272010-04-21 20:59:14 +000083 enum { MaxLargeThreadReentryDepth = 256, MaxSmallThreadReentryDepth = 32 };
ggaren@apple.com4668b2f2008-06-02 16:36:01 +000084
ossy@webkit.org95c1bc42011-01-20 16:30:54 +000085 class Interpreter {
86 WTF_MAKE_FAST_ALLOCATED;
ggaren@apple.com4f7d7a92008-11-17 03:34:05 +000087 friend class JIT;
oliver@apple.com9a4dea52009-04-15 07:13:25 +000088 friend class CachedCall;
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000089 public:
ggaren@apple.com99e9f3f2011-06-22 20:07:37 +000090 Interpreter();
barraclough@apple.com7c876fc2008-11-11 05:09:46 +000091
ggaren@apple.com82a62d02008-06-27 22:35:33 +000092 RegisterFile& registerFile() { return m_registerFile; }
93
ggaren@apple.com47d3f052008-11-15 21:37:49 +000094 Opcode getOpcode(OpcodeID id)
ggaren@apple.come5af6d52008-09-26 22:43:16 +000095 {
oliver@apple.com563fc0a2010-07-11 01:14:47 +000096 #if ENABLE(COMPUTED_GOTO_INTERPRETER)
ggaren@apple.com47d3f052008-11-15 21:37:49 +000097 return m_opcodeTable[id];
ggaren@apple.come5af6d52008-09-26 22:43:16 +000098 #else
99 return id;
100 #endif
101 }
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000102
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000103 OpcodeID getOpcodeID(Opcode opcode)
weinig@apple.coma963b962008-06-05 05:36:55 +0000104 {
oliver@apple.com563fc0a2010-07-11 01:14:47 +0000105 #if ENABLE(COMPUTED_GOTO_INTERPRETER)
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000106 ASSERT(isOpcode(opcode));
107 return m_opcodeIDTable.get(opcode);
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000108 #else
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000109 return opcode;
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000110 #endif
111 }
112
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000113 bool isOpcode(Opcode);
barraclough@apple.com2607dd02010-10-27 20:46:09 +0000114
115 JSValue execute(ProgramExecutable*, CallFrame*, ScopeChainNode*, JSObject* thisObj);
116 JSValue executeCall(CallFrame*, JSObject* function, CallType, const CallData&, JSValue thisValue, const ArgList&);
117 JSObject* executeConstruct(CallFrame*, JSObject* function, ConstructType, const ConstructData&, const ArgList&);
barraclough@apple.com19afece2011-07-15 19:51:49 +0000118 JSValue execute(EvalExecutable* evalNode, CallFrame*, JSValue thisValue, ScopeChainNode*);
weinig@apple.coma963b962008-06-05 05:36:55 +0000119
ggaren@apple.comdc067b62009-05-01 22:43:39 +0000120 JSValue retrieveArguments(CallFrame*, JSFunction*) const;
kevino@webkit.org627fde72011-06-08 19:45:37 +0000121 JS_EXPORT_PRIVATE JSValue retrieveCaller(CallFrame*, JSFunction*) const;
122 JS_EXPORT_PRIVATE void retrieveLastCaller(CallFrame*, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValue& function) const;
ggaren@apple.com0c677732008-09-30 00:46:25 +0000123
darin@apple.com8c2bac02008-10-09 00:40:43 +0000124 void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
oliver@apple.comc8f3a752008-06-28 04:02:03 +0000125
oliver@apple.comebd0b4c2009-09-29 21:48:52 +0000126 SamplingTool* sampler() { return m_sampler.get(); }
ggaren@apple.com82a62d02008-06-27 22:35:33 +0000127
barraclough@apple.com2607dd02010-10-27 20:46:09 +0000128 NEVER_INLINE JSValue callEval(CallFrame*, RegisterFile*, Register* argv, int argc, int registerOffset);
barraclough@apple.com87dbd5e2010-11-19 02:35:25 +0000129 NEVER_INLINE HandlerInfo* throwException(CallFrame*&, JSValue&, unsigned bytecodeOffset);
barraclough@apple.com5b374fc2009-06-02 05:36:18 +0000130 NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine);
131
oliver@apple.comebd0b4c2009-09-29 21:48:52 +0000132 void dumpSampleData(ExecState* exec);
133 void startSampling();
134 void stopSampling();
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000135 private:
weinig@apple.coma963b962008-06-05 05:36:55 +0000136 enum ExecutionFlag { Normal, InitializeAndReturn };
oliver@apple.com9a4dea52009-04-15 07:13:25 +0000137
barraclough@apple.com2607dd02010-10-27 20:46:09 +0000138 CallFrameClosure prepareForRepeatCall(FunctionExecutable*, CallFrame*, JSFunction*, int argCount, ScopeChainNode*);
oliver@apple.com9a4dea52009-04-15 07:13:25 +0000139 void endRepeatCall(CallFrameClosure&);
barraclough@apple.com2607dd02010-10-27 20:46:09 +0000140 JSValue execute(CallFrameClosure&);
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000141
barraclough@apple.com19afece2011-07-15 19:51:49 +0000142 JSValue execute(EvalExecutable*, CallFrame*, JSValue thisValue, int globalRegisterOffset, ScopeChainNode*);
ggaren@apple.com82a62d02008-06-27 22:35:33 +0000143
oliver@apple.com942e37d2010-07-07 01:35:56 +0000144#if ENABLE(INTERPRETER)
ggaren@apple.comdc067b62009-05-01 22:43:39 +0000145 NEVER_INLINE bool resolve(CallFrame*, Instruction*, JSValue& exceptionValue);
146 NEVER_INLINE bool resolveSkip(CallFrame*, Instruction*, JSValue& exceptionValue);
147 NEVER_INLINE bool resolveGlobal(CallFrame*, Instruction*, JSValue& exceptionValue);
oliver@apple.come9af1242010-05-08 00:05:00 +0000148 NEVER_INLINE bool resolveGlobalDynamic(CallFrame*, Instruction*, JSValue& exceptionValue);
darin@apple.com8c2bac02008-10-09 00:40:43 +0000149 NEVER_INLINE void resolveBase(CallFrame*, Instruction* vPC);
ggaren@apple.comdc067b62009-05-01 22:43:39 +0000150 NEVER_INLINE bool resolveBaseAndProperty(CallFrame*, Instruction*, JSValue& exceptionValue);
barraclough@apple.com19afece2011-07-15 19:51:49 +0000151 NEVER_INLINE bool resolveThisAndProperty(CallFrame*, Instruction*, JSValue& exceptionValue);
darin@apple.com8c2bac02008-10-09 00:40:43 +0000152 NEVER_INLINE ScopeChainNode* createExceptionScope(CallFrame*, const Instruction* vPC);
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000153
oliver@apple.com49bbd292009-05-23 11:08:58 +0000154 void tryCacheGetByID(CallFrame*, CodeBlock*, Instruction*, JSValue baseValue, const Identifier& propertyName, const PropertySlot&);
155 void uncacheGetByID(CodeBlock*, Instruction* vPC);
156 void tryCachePutByID(CallFrame*, CodeBlock*, Instruction*, JSValue baseValue, const PutPropertySlot&);
157 void uncachePutByID(CodeBlock*, Instruction* vPC);
oliver@apple.com942e37d2010-07-07 01:35:56 +0000158#endif // ENABLE(INTERPRETER)
oliver@apple.com49bbd292009-05-23 11:08:58 +0000159
ggaren@apple.comdc067b62009-05-01 22:43:39 +0000160 NEVER_INLINE bool unwindCallFrame(CallFrame*&, JSValue, unsigned& bytecodeOffset, CodeBlock*&);
weinig@apple.coma963b962008-06-05 05:36:55 +0000161
darin@apple.com8c2bac02008-10-09 00:40:43 +0000162 static ALWAYS_INLINE CallFrame* slideRegisterWindowForCall(CodeBlock*, RegisterFile*, CallFrame*, size_t registerOffset, int argc);
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000163
barraclough@apple.com4be541c2010-05-20 02:38:01 +0000164 static CallFrame* findFunctionCallFrame(CallFrame*, JSFunction*);
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000165
barraclough@apple.com2607dd02010-10-27 20:46:09 +0000166 JSValue privateExecute(ExecutionFlag, RegisterFile*, CallFrame*);
darin@apple.com8c2bac02008-10-09 00:40:43 +0000167
ggaren@apple.com68313b02008-11-13 00:48:23 +0000168 void dumpCallFrame(CallFrame*);
169 void dumpRegisters(CallFrame*);
ggaren@apple.com4b8c0fb2008-10-20 16:48:30 +0000170
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000171 bool isCallBytecode(Opcode opcode) { return opcode == getOpcode(op_call) || opcode == getOpcode(op_construct) || opcode == getOpcode(op_call_eval); }
mrowe@apple.comf88a4632008-09-07 05:44:58 +0000172
oliver@apple.comebd0b4c2009-09-29 21:48:52 +0000173 void enableSampler();
174 int m_sampleEntryDepth;
175 OwnPtr<SamplingTool> m_sampler;
ggaren@apple.combe95ccf2008-10-25 19:59:47 +0000176
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000177 int m_reentryDepth;
oliver@apple.comc8f3a752008-06-28 04:02:03 +0000178
ggaren@apple.com82a62d02008-06-27 22:35:33 +0000179 RegisterFile m_registerFile;
ggaren@apple.com1d72f772008-07-03 00:47:00 +0000180
oliver@apple.com563fc0a2010-07-11 01:14:47 +0000181#if ENABLE(COMPUTED_GOTO_INTERPRETER)
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000182 Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
183 HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000184#endif
185 };
barraclough@apple.com19afece2011-07-15 19:51:49 +0000186
187 // This value must not be an object that would require this conversion (WebCore's global object).
188 inline bool isValidThisObject(JSValue thisValue, ExecState* exec)
189 {
190 return !thisValue.isObject() || thisValue.toThisObject(exec) == thisValue;
191 }
192
cwzwarich@webkit.org3f782f62008-09-08 01:28:33 +0000193} // namespace JSC
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000194
ggaren@apple.com901a8a22008-11-17 20:57:18 +0000195#endif // Interpreter_h