blob: 61589e69fe0e6ce84f611391f4f1491a71565155 [file] [log] [blame]
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +00001/*
mark.lam@apple.comfaa53932013-03-20 09:09:38 +00002 * Copyright (C) 2008, 2013 Apple Inc. All rights reserved.
commit-queue@webkit.orgd106bf22012-07-04 21:36:52 +00003 * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +00004 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
weinig@apple.coma963b962008-06-05 05:36:55 +000029
ggaren@apple.com901a8a22008-11-17 20:57:18 +000030#ifndef Interpreter_h
31#define Interpreter_h
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000032
weinig@apple.com49b32502008-07-06 00:10:04 +000033#include "ArgList.h"
mhahnenberg@apple.comc1bc9d32013-01-24 21:39:55 +000034#include "JSCJSValue.h"
ggaren@apple.com1d72f772008-07-03 00:47:00 +000035#include "JSCell.h"
oliver@apple.comddf4b482012-02-17 21:17:59 +000036#include "JSFunction.h"
ggaren@apple.combb639262009-02-20 06:04:21 +000037#include "JSObject.h"
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +000038#include "JSStack.h"
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +000039#include "LLIntData.h"
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000040#include "Opcode.h"
commit-queue@webkit.org3f922f92013-08-29 00:28:42 +000041#include "SourceProvider.h"
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000042
hausmann@webkit.orgf71db052009-07-15 15:14:15 +000043#include <wtf/HashMap.h>
commit-queue@webkit.orgd106bf22012-07-04 21:36:52 +000044#include <wtf/text/StringBuilder.h>
hausmann@webkit.orgf71db052009-07-15 15:14:15 +000045
cwzwarich@webkit.org3f782f62008-09-08 01:28:33 +000046namespace JSC {
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000047
48 class CodeBlock;
barraclough@apple.com836511562009-08-15 01:14:00 +000049 class EvalExecutable;
oliver@apple.comddf4b482012-02-17 21:17:59 +000050 class ExecutableBase;
barraclough@apple.com306bb122009-08-18 05:34:52 +000051 class FunctionExecutable;
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000052 class VM;
oliver@apple.comc8f3a752008-06-28 04:02:03 +000053 class JSGlobalObject;
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +000054 class LLIntOffsetsExtractor;
barraclough@apple.com836511562009-08-15 01:14:00 +000055 class ProgramExecutable;
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000056 class Register;
ggaren@apple.comb11e7872012-08-30 22:50:00 +000057 class JSScope;
barraclough@apple.comeb51bd92008-07-30 17:38:35 +000058 class SamplingTool;
oliver@apple.comef1f5ce2009-04-15 07:31:48 +000059 struct CallFrameClosure;
weinig@apple.com18064e72008-12-10 00:26:13 +000060 struct HandlerInfo;
levin@chromium.org93604aa2009-07-29 08:04:19 +000061 struct Instruction;
62
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000063 enum DebugHookID {
ggaren@apple.comd0740c82008-05-28 20:47:13 +000064 WillExecuteProgram,
65 DidExecuteProgram,
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000066 DidEnterCallFrame,
oliver@apple.com139b5292008-06-03 22:48:52 +000067 DidReachBreakpoint,
ggaren@apple.comd0740c82008-05-28 20:47:13 +000068 WillLeaveCallFrame,
69 WillExecuteStatement
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000070 };
71
oliver@apple.comddf4b482012-02-17 21:17:59 +000072 enum StackFrameCodeType {
73 StackFrameGlobalCode,
74 StackFrameEvalCode,
75 StackFrameFunctionCode,
76 StackFrameNativeCode
77 };
78
79 struct StackFrame {
80 Strong<JSObject> callee;
81 StackFrameCodeType codeType;
82 Strong<ExecutableBase> executable;
oliver@apple.come47f99d2013-04-06 22:47:56 +000083 Strong<UnlinkedCodeBlock> codeBlock;
84 RefPtr<SourceProvider> code;
85 int lineOffset;
mark.lam@apple.com5b45f902013-07-09 16:15:12 +000086 unsigned firstLineColumnOffset;
oliver@apple.come47f99d2013-04-06 22:47:56 +000087 unsigned characterOffset;
88 unsigned bytecodeOffset;
benjamin@webkit.orgcff06e42012-08-30 21:23:51 +000089 String sourceURL;
oliver@apple.come47f99d2013-04-06 22:47:56 +000090 JS_EXPORT_PRIVATE String toString(CallFrame*);
commit-queue@webkit.orgd106bf22012-07-04 21:36:52 +000091 String friendlySourceURL() const
92 {
93 String traceLine;
94
95 switch (codeType) {
96 case StackFrameEvalCode:
97 case StackFrameFunctionCode:
98 case StackFrameGlobalCode:
99 if (!sourceURL.isEmpty())
100 traceLine = sourceURL.impl();
101 break;
102 case StackFrameNativeCode:
103 traceLine = "[native code]";
104 break;
105 }
106 return traceLine.isNull() ? emptyString() : traceLine;
107 }
108 String friendlyFunctionName(CallFrame* callFrame) const
109 {
oliver@apple.comddf4b482012-02-17 21:17:59 +0000110 String traceLine;
111 JSObject* stackFrameCallee = callee.get();
112
113 switch (codeType) {
114 case StackFrameEvalCode:
commit-queue@webkit.orgd106bf22012-07-04 21:36:52 +0000115 traceLine = "eval code";
oliver@apple.comddf4b482012-02-17 21:17:59 +0000116 break;
commit-queue@webkit.orgd106bf22012-07-04 21:36:52 +0000117 case StackFrameNativeCode:
118 if (callee)
119 traceLine = getCalculatedDisplayName(callFrame, stackFrameCallee).impl();
commit-queue@webkit.org50c978a2012-06-27 19:54:48 +0000120 break;
commit-queue@webkit.orgd106bf22012-07-04 21:36:52 +0000121 case StackFrameFunctionCode:
122 traceLine = getCalculatedDisplayName(callFrame, stackFrameCallee).impl();
commit-queue@webkit.orge12e2f32012-06-28 01:09:22 +0000123 break;
commit-queue@webkit.orge12e2f32012-06-28 01:09:22 +0000124 case StackFrameGlobalCode:
commit-queue@webkit.orgd106bf22012-07-04 21:36:52 +0000125 traceLine = "global code";
126 break;
commit-queue@webkit.orge12e2f32012-06-28 01:09:22 +0000127 }
commit-queue@webkit.orgd106bf22012-07-04 21:36:52 +0000128 return traceLine.isNull() ? emptyString() : traceLine;
129 }
mark.lam@apple.com5b45f902013-07-09 16:15:12 +0000130 JS_EXPORT_PRIVATE void computeLineAndColumn(unsigned& line, unsigned& column);
131
132 private:
133 void expressionInfo(int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column);
oliver@apple.comddf4b482012-02-17 21:17:59 +0000134 };
135
commit-queue@webkit.org3f922f92013-08-29 00:28:42 +0000136 class ClearExceptionScope {
137 public:
138 ClearExceptionScope(VM* vm): m_vm(vm)
139 {
140 vm->getExceptionInfo(oldException, oldExceptionStack);
141 vm->clearException();
142 }
143 ~ClearExceptionScope()
144 {
145 m_vm->setExceptionInfo(oldException, oldExceptionStack);
146 }
147 private:
148 JSC::JSValue oldException;
149 RefCountedArray<JSC::StackFrame> oldExceptionStack;
150 VM* m_vm;
151 };
152
commit-queue@webkit.org84814622011-08-25 01:25:38 +0000153 class TopCallFrameSetter {
154 public:
mark.lam@apple.com315b9822013-08-16 01:47:41 +0000155 TopCallFrameSetter(VM& currentVM, CallFrame* callFrame)
156 : vm(currentVM)
157 , oldCallFrame(currentVM.topCallFrame)
commit-queue@webkit.org84814622011-08-25 01:25:38 +0000158 {
mark.lam@apple.com315b9822013-08-16 01:47:41 +0000159 ASSERT(!callFrame->hasHostCallFrameFlag());
160 currentVM.topCallFrame = callFrame;
commit-queue@webkit.org84814622011-08-25 01:25:38 +0000161 }
162
163 ~TopCallFrameSetter()
164 {
mark.lam@apple.com315b9822013-08-16 01:47:41 +0000165 ASSERT(!oldCallFrame->hasHostCallFrameFlag());
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000166 vm.topCallFrame = oldCallFrame;
commit-queue@webkit.org84814622011-08-25 01:25:38 +0000167 }
168 private:
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000169 VM& vm;
commit-queue@webkit.org84814622011-08-25 01:25:38 +0000170 CallFrame* oldCallFrame;
171 };
oliver@apple.come07a4592012-01-25 19:43:06 +0000172
173 class NativeCallFrameTracer {
174 public:
mark.lam@apple.com315b9822013-08-16 01:47:41 +0000175 ALWAYS_INLINE NativeCallFrameTracer(VM* vm, CallFrame* callFrame)
oliver@apple.come07a4592012-01-25 19:43:06 +0000176 {
mark.lam@apple.com315b9822013-08-16 01:47:41 +0000177 ASSERT(vm);
oliver@apple.come07a4592012-01-25 19:43:06 +0000178 ASSERT(callFrame);
mark.lam@apple.com315b9822013-08-16 01:47:41 +0000179 ASSERT(!callFrame->hasHostCallFrameFlag());
180 vm->topCallFrame = callFrame;
oliver@apple.come07a4592012-01-25 19:43:06 +0000181 }
182 };
commit-queue@webkit.org84814622011-08-25 01:25:38 +0000183
ossy@webkit.org95c1bc42011-01-20 16:30:54 +0000184 class Interpreter {
185 WTF_MAKE_FAST_ALLOCATED;
aroben@apple.come089d622012-02-21 16:26:12 +0000186 friend class CachedCall;
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +0000187 friend class LLIntOffsetsExtractor;
188 friend class JIT;
commit-queue@webkit.org3f922f92013-08-29 00:28:42 +0000189 friend class VM;
mark.lam@apple.com8b97fde2012-10-22 22:09:58 +0000190
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000191 public:
mark.lam@apple.com8b97fde2012-10-22 22:09:58 +0000192 class ErrorHandlingMode {
193 public:
194 JS_EXPORT_PRIVATE ErrorHandlingMode(ExecState*);
195 JS_EXPORT_PRIVATE ~ErrorHandlingMode();
196 private:
197 Interpreter& m_interpreter;
198 };
199
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000200 Interpreter(VM &);
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +0000201 ~Interpreter();
fpizlo@apple.com0afe9662011-12-20 02:42:06 +0000202
barraclough@apple.com25d57822012-08-30 00:27:19 +0000203 void initialize(bool canUseJIT);
barraclough@apple.com7c876fc2008-11-11 05:09:46 +0000204
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +0000205 JSStack& stack() { return m_stack; }
ggaren@apple.com82a62d02008-06-27 22:35:33 +0000206
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000207 Opcode getOpcode(OpcodeID id)
ggaren@apple.come5af6d52008-09-26 22:43:16 +0000208 {
fpizlo@apple.com0afe9662011-12-20 02:42:06 +0000209 ASSERT(m_initialized);
commit-queue@webkit.orgb8419482012-08-30 22:21:48 +0000210#if ENABLE(COMPUTED_GOTO_OPCODES)
fpizlo@apple.com0afe9662011-12-20 02:42:06 +0000211 return m_opcodeTable[id];
212#else
213 return id;
214#endif
ggaren@apple.come5af6d52008-09-26 22:43:16 +0000215 }
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000216
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000217 OpcodeID getOpcodeID(Opcode opcode)
weinig@apple.coma963b962008-06-05 05:36:55 +0000218 {
fpizlo@apple.com0afe9662011-12-20 02:42:06 +0000219 ASSERT(m_initialized);
mark.lam@apple.com74a9e832012-09-25 04:30:20 +0000220#if ENABLE(COMPUTED_GOTO_OPCODES) && ENABLE(LLINT)
fpizlo@apple.com0afe9662011-12-20 02:42:06 +0000221 ASSERT(isOpcode(opcode));
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +0000222 return m_opcodeIDTable.get(opcode);
mark.lam@apple.com74a9e832012-09-25 04:30:20 +0000223#else
fpizlo@apple.com0afe9662011-12-20 02:42:06 +0000224 return opcode;
mark.lam@apple.com74a9e832012-09-25 04:30:20 +0000225#endif
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000226 }
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +0000227
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000228 bool isOpcode(Opcode);
barraclough@apple.com2607dd02010-10-27 20:46:09 +0000229
ggaren@apple.comb11e7872012-08-30 22:50:00 +0000230 JSValue execute(ProgramExecutable*, CallFrame*, JSObject* thisObj);
barraclough@apple.com2607dd02010-10-27 20:46:09 +0000231 JSValue executeCall(CallFrame*, JSObject* function, CallType, const CallData&, JSValue thisValue, const ArgList&);
232 JSObject* executeConstruct(CallFrame*, JSObject* function, ConstructType, const ConstructData&, const ArgList&);
ggaren@apple.comb11e7872012-08-30 22:50:00 +0000233 JSValue execute(EvalExecutable*, CallFrame*, JSValue thisValue, JSScope*);
weinig@apple.coma963b962008-06-05 05:36:55 +0000234
darin@apple.com8c2bac02008-10-09 00:40:43 +0000235 void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
oliver@apple.comc8f3a752008-06-28 04:02:03 +0000236
oliver@apple.comebd0b4c2009-09-29 21:48:52 +0000237 SamplingTool* sampler() { return m_sampler.get(); }
ggaren@apple.com82a62d02008-06-27 22:35:33 +0000238
mark.lam@apple.combd1385d2013-06-21 23:58:52 +0000239 bool isInErrorHandlingMode() { return m_errorHandlingModeReentry; }
240
fpizlo@apple.comf825bf62013-09-22 05:00:45 +0000241 NEVER_INLINE HandlerInfo* unwind(CallFrame*&, JSValue&);
mark.lam@apple.come72693d2013-09-24 23:52:57 +0000242 NEVER_INLINE void debug(CallFrame*, DebugHookID);
commit-queue@webkit.org0fc0afa2013-07-30 04:33:35 +0000243 JSString* stackTraceAsString(ExecState*, Vector<StackFrame>);
barraclough@apple.com5b374fc2009-06-02 05:36:18 +0000244
mark.lam@apple.comb07f4c42013-08-08 16:38:31 +0000245 static EncodedJSValue JSC_HOST_CALL constructWithErrorConstructor(ExecState*);
246 static EncodedJSValue JSC_HOST_CALL callErrorConstructor(ExecState*);
247 static EncodedJSValue JSC_HOST_CALL constructWithNativeErrorConstructor(ExecState*);
248 static EncodedJSValue JSC_HOST_CALL callNativeErrorConstructor(ExecState*);
249
oliver@apple.comebd0b4c2009-09-29 21:48:52 +0000250 void dumpSampleData(ExecState* exec);
251 void startSampling();
252 void stopSampling();
oliver@apple.coma08210b2012-07-18 23:26:06 +0000253
254 JS_EXPORT_PRIVATE void dumpCallFrame(CallFrame*);
255
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000256 private:
weinig@apple.coma963b962008-06-05 05:36:55 +0000257 enum ExecutionFlag { Normal, InitializeAndReturn };
oliver@apple.com9a4dea52009-04-15 07:13:25 +0000258
ggaren@apple.comb11e7872012-08-30 22:50:00 +0000259 CallFrameClosure prepareForRepeatCall(FunctionExecutable*, CallFrame*, JSFunction*, int argumentCountIncludingThis, JSScope*);
oliver@apple.com9a4dea52009-04-15 07:13:25 +0000260 void endRepeatCall(CallFrameClosure&);
barraclough@apple.com2607dd02010-10-27 20:46:09 +0000261 JSValue execute(CallFrameClosure&);
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000262
mark.lam@apple.com304d5972013-08-08 16:57:07 +0000263 void getStackTrace(Vector<StackFrame>& results, size_t maxStackSize = std::numeric_limits<size_t>::max());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000264
ggaren@apple.com68313b02008-11-13 00:48:23 +0000265 void dumpRegisters(CallFrame*);
ggaren@apple.com4b8c0fb2008-10-20 16:48:30 +0000266
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000267 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 +0000268
oliver@apple.comebd0b4c2009-09-29 21:48:52 +0000269 void enableSampler();
270 int m_sampleEntryDepth;
271 OwnPtr<SamplingTool> m_sampler;
ggaren@apple.combe95ccf2008-10-25 19:59:47 +0000272
oliver@apple.come0b15ee2013-07-25 04:01:06 +0000273 VM& m_vm;
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +0000274 JSStack m_stack;
mark.lam@apple.com8b97fde2012-10-22 22:09:58 +0000275 int m_errorHandlingModeReentry;
ggaren@apple.com1d72f772008-07-03 00:47:00 +0000276
mark.lam@apple.com74a9e832012-09-25 04:30:20 +0000277#if ENABLE(COMPUTED_GOTO_OPCODES) && ENABLE(LLINT)
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +0000278 Opcode* m_opcodeTable; // Maps OpcodeID => Opcode for compiling
279 HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000280#endif
fpizlo@apple.com0afe9662011-12-20 02:42:06 +0000281
282#if !ASSERT_DISABLED
283 bool m_initialized;
284#endif
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000285 };
barraclough@apple.com19afece2011-07-15 19:51:49 +0000286
ggaren@apple.com539d1bb2011-11-14 19:21:40 +0000287 JSValue eval(CallFrame*);
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +0000288 CallFrame* loadVarargs(CallFrame*, JSStack*, JSValue thisValue, JSValue arguments, int firstFreeRegister);
ggaren@apple.com539d1bb2011-11-14 19:21:40 +0000289
cwzwarich@webkit.org3f782f62008-09-08 01:28:33 +0000290} // namespace JSC
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000291
ggaren@apple.com901a8a22008-11-17 20:57:18 +0000292#endif // Interpreter_h