blob: 490a6105579c41ba464138aeea9d1fb9248eab41 [file] [log] [blame]
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +00001/*
mark.lam@apple.comd7c391d2016-06-08 20:59:49 +00002 * Copyright (C) 2008, 2013, 2015-2016 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.
mjs@apple.com92047332014-03-15 04:08:27 +000014 * 3. Neither the name of Apple Inc. ("Apple") nor the names of
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000015 * 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
ryanhaddad@apple.com22104f52016-09-28 17:08:17 +000030#pragma once
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000031
weinig@apple.com49b32502008-07-06 00:10:04 +000032#include "ArgList.h"
mark.lam@apple.com451de992016-09-07 22:10:50 +000033#include "CatchScope.h"
utatane.tea@gmail.com4f2f2b22016-10-18 08:13:26 +000034#include "FrameTracers.h"
mhahnenberg@apple.comc1bc9d32013-01-24 21:39:55 +000035#include "JSCJSValue.h"
ggaren@apple.com1d72f772008-07-03 00:47:00 +000036#include "JSCell.h"
ggaren@apple.combb639262009-02-20 06:04:21 +000037#include "JSObject.h"
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000038#include "Opcode.h"
fpizlo@apple.combcfd39e2015-02-10 23:16:36 +000039#include "StackAlignment.h"
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +000040#include "StackFrame.h"
hausmann@webkit.orgf71db052009-07-15 15:14:15 +000041#include <wtf/HashMap.h>
42
mark.lam@apple.com504b1cc2016-07-11 20:48:15 +000043#if !ENABLE(JIT)
44#include "CLoopStack.h"
45#endif
46
47
cwzwarich@webkit.org3f782f62008-09-08 01:28:33 +000048namespace JSC {
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000049
50 class CodeBlock;
barraclough@apple.com836511562009-08-15 01:14:00 +000051 class EvalExecutable;
barraclough@apple.com306bb122009-08-18 05:34:52 +000052 class FunctionExecutable;
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000053 class VM;
fpizlo@apple.com3a2fa4c2015-04-13 22:13:12 +000054 class JSFunction;
oliver@apple.comc8f3a752008-06-28 04:02:03 +000055 class JSGlobalObject;
utatane.tea@gmail.com6c389582015-09-04 04:29:04 +000056 class JSModuleEnvironment;
utatane.tea@gmail.coma8309d92015-09-01 02:05:30 +000057 class JSModuleRecord;
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +000058 class LLIntOffsetsExtractor;
barraclough@apple.com836511562009-08-15 01:14:00 +000059 class ProgramExecutable;
utatane.tea@gmail.coma8309d92015-09-01 02:05:30 +000060 class ModuleProgramExecutable;
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000061 class Register;
ggaren@apple.comb11e7872012-08-30 22:50:00 +000062 class JSScope;
oliver@apple.comef1f5ce2009-04-15 07:31:48 +000063 struct CallFrameClosure;
weinig@apple.com18064e72008-12-10 00:26:13 +000064 struct HandlerInfo;
levin@chromium.org93604aa2009-07-29 08:04:19 +000065 struct Instruction;
msaboff@apple.com6f0b31a2013-12-04 16:40:17 +000066 struct ProtoCallFrame;
utatane.tea@gmail.comc2585192016-08-25 22:55:10 +000067 struct UnlinkedInstruction;
msaboff@apple.com6f0b31a2013-12-04 16:40:17 +000068
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +000069 enum UnwindStart : uint8_t { UnwindFromCurrentFrame, UnwindFromCallerFrame };
mark.lam@apple.com4348a432015-09-07 05:19:28 +000070
commit-queue@webkit.orgfbca3052016-10-01 15:32:59 +000071 enum DebugHookType {
ggaren@apple.comd0740c82008-05-28 20:47:13 +000072 WillExecuteProgram,
73 DidExecuteProgram,
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000074 DidEnterCallFrame,
oliver@apple.com139b5292008-06-03 22:48:52 +000075 DidReachBreakpoint,
ggaren@apple.comd0740c82008-05-28 20:47:13 +000076 WillLeaveCallFrame,
joepeck@webkit.orgbb70ac62016-09-30 19:22:37 +000077 WillExecuteStatement,
78 WillExecuteExpression,
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000079 };
80
oliver@apple.comddf4b482012-02-17 21:17:59 +000081 enum StackFrameCodeType {
82 StackFrameGlobalCode,
83 StackFrameEvalCode,
utatane.tea@gmail.coma8309d92015-09-01 02:05:30 +000084 StackFrameModuleCode,
oliver@apple.comddf4b482012-02-17 21:17:59 +000085 StackFrameFunctionCode,
86 StackFrameNativeCode
87 };
88
ossy@webkit.org95c1bc42011-01-20 16:30:54 +000089 class Interpreter {
90 WTF_MAKE_FAST_ALLOCATED;
aroben@apple.come089d622012-02-21 16:26:12 +000091 friend class CachedCall;
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +000092 friend class LLIntOffsetsExtractor;
93 friend class JIT;
commit-queue@webkit.org3f922f92013-08-29 00:28:42 +000094 friend class VM;
mark.lam@apple.com8b97fde2012-10-22 22:09:58 +000095
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000096 public:
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000097 Interpreter(VM &);
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +000098 ~Interpreter();
fpizlo@apple.com0afe9662011-12-20 02:42:06 +000099
mark.lam@apple.coma6f900b2015-08-18 17:37:21 +0000100 void initialize();
barraclough@apple.com7c876fc2008-11-11 05:09:46 +0000101
mark.lam@apple.com504b1cc2016-07-11 20:48:15 +0000102#if !ENABLE(JIT)
103 CLoopStack& cloopStack() { return m_cloopStack; }
104#endif
ggaren@apple.com82a62d02008-06-27 22:35:33 +0000105
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000106 Opcode getOpcode(OpcodeID id)
ggaren@apple.come5af6d52008-09-26 22:43:16 +0000107 {
fpizlo@apple.com0afe9662011-12-20 02:42:06 +0000108 ASSERT(m_initialized);
commit-queue@webkit.orgb8419482012-08-30 22:21:48 +0000109#if ENABLE(COMPUTED_GOTO_OPCODES)
fpizlo@apple.com0afe9662011-12-20 02:42:06 +0000110 return m_opcodeTable[id];
111#else
112 return id;
113#endif
ggaren@apple.come5af6d52008-09-26 22:43:16 +0000114 }
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000115
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000116 OpcodeID getOpcodeID(Opcode opcode)
weinig@apple.coma963b962008-06-05 05:36:55 +0000117 {
fpizlo@apple.com0afe9662011-12-20 02:42:06 +0000118 ASSERT(m_initialized);
dbatyai.u-szeged@partner.samsung.com46f07e52014-06-19 16:32:31 +0000119#if ENABLE(COMPUTED_GOTO_OPCODES)
fpizlo@apple.com0afe9662011-12-20 02:42:06 +0000120 ASSERT(isOpcode(opcode));
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +0000121 return m_opcodeIDTable.get(opcode);
mark.lam@apple.com74a9e832012-09-25 04:30:20 +0000122#else
fpizlo@apple.com0afe9662011-12-20 02:42:06 +0000123 return opcode;
mark.lam@apple.com74a9e832012-09-25 04:30:20 +0000124#endif
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000125 }
utatane.tea@gmail.comc2585192016-08-25 22:55:10 +0000126
127 OpcodeID getOpcodeID(const Instruction&);
128 OpcodeID getOpcodeID(const UnlinkedInstruction&);
129
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000130 bool isOpcode(Opcode);
barraclough@apple.com2607dd02010-10-27 20:46:09 +0000131
ggaren@apple.comb11e7872012-08-30 22:50:00 +0000132 JSValue execute(ProgramExecutable*, CallFrame*, JSObject* thisObj);
barraclough@apple.com2607dd02010-10-27 20:46:09 +0000133 JSValue executeCall(CallFrame*, JSObject* function, CallType, const CallData&, JSValue thisValue, const ArgList&);
utatane.tea@gmail.com221fbc42015-07-22 00:29:39 +0000134 JSObject* executeConstruct(CallFrame*, JSObject* function, ConstructType, const ConstructData&, const ArgList&, JSValue newTarget);
ggaren@apple.comb11e7872012-08-30 22:50:00 +0000135 JSValue execute(EvalExecutable*, CallFrame*, JSValue thisValue, JSScope*);
utatane.tea@gmail.com6c389582015-09-04 04:29:04 +0000136 JSValue execute(ModuleProgramExecutable*, CallFrame*, JSModuleEnvironment*);
weinig@apple.coma963b962008-06-05 05:36:55 +0000137
darin@apple.com8c2bac02008-10-09 00:40:43 +0000138 void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
oliver@apple.comc8f3a752008-06-28 04:02:03 +0000139
mark.lam@apple.com4348a432015-09-07 05:19:28 +0000140 NEVER_INLINE HandlerInfo* unwind(VM&, CallFrame*&, Exception*, UnwindStart);
saambarati1@gmail.com284319e2015-09-17 18:30:04 +0000141 void notifyDebuggerOfExceptionToBeThrown(CallFrame*, Exception*);
commit-queue@webkit.orgfbca3052016-10-01 15:32:59 +0000142 NEVER_INLINE void debug(CallFrame*, DebugHookType);
mark.lam@apple.com9f6a2c72016-06-11 19:58:07 +0000143 static JSString* stackTraceAsString(VM&, const Vector<StackFrame>&);
barraclough@apple.com5b374fc2009-06-02 05:36:18 +0000144
mark.lam@apple.comb07f4c42013-08-08 16:38:31 +0000145 static EncodedJSValue JSC_HOST_CALL constructWithErrorConstructor(ExecState*);
146 static EncodedJSValue JSC_HOST_CALL callErrorConstructor(ExecState*);
147 static EncodedJSValue JSC_HOST_CALL constructWithNativeErrorConstructor(ExecState*);
148 static EncodedJSValue JSC_HOST_CALL callNativeErrorConstructor(ExecState*);
149
oliver@apple.coma08210b2012-07-18 23:26:06 +0000150 JS_EXPORT_PRIVATE void dumpCallFrame(CallFrame*);
151
mark.lam@apple.com9f6a2c72016-06-11 19:58:07 +0000152 void getStackTrace(Vector<StackFrame>& results, size_t framesToSkip = 0, size_t maxStackSize = std::numeric_limits<size_t>::max());
mmirman@apple.comc35dac92015-04-07 21:34:05 +0000153
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000154 private:
weinig@apple.coma963b962008-06-05 05:36:55 +0000155 enum ExecutionFlag { Normal, InitializeAndReturn };
oliver@apple.com9a4dea52009-04-15 07:13:25 +0000156
msaboff@apple.com6f0b31a2013-12-04 16:40:17 +0000157 CallFrameClosure prepareForRepeatCall(FunctionExecutable*, CallFrame*, ProtoCallFrame*, JSFunction*, int argumentCountIncludingThis, JSScope*, JSValue*);
mark.lam@apple.comafeead12013-12-05 20:33:35 +0000158
barraclough@apple.com2607dd02010-10-27 20:46:09 +0000159 JSValue execute(CallFrameClosure&);
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000160
mmirman@apple.comc35dac92015-04-07 21:34:05 +0000161
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000162
ggaren@apple.com68313b02008-11-13 00:48:23 +0000163 void dumpRegisters(CallFrame*);
ggaren@apple.com4b8c0fb2008-10-20 16:48:30 +0000164
msaboff@apple.comc15ae7e2015-09-16 23:40:35 +0000165 bool isCallBytecode(Opcode opcode) { return opcode == getOpcode(op_call) || opcode == getOpcode(op_construct) || opcode == getOpcode(op_call_eval) || opcode == getOpcode(op_tail_call); }
mrowe@apple.comf88a4632008-09-07 05:44:58 +0000166
oliver@apple.come0b15ee2013-07-25 04:01:06 +0000167 VM& m_vm;
mark.lam@apple.com504b1cc2016-07-11 20:48:15 +0000168#if !ENABLE(JIT)
169 CLoopStack m_cloopStack;
170#endif
mark.lam@apple.com8b97fde2012-10-22 22:09:58 +0000171 int m_errorHandlingModeReentry;
ggaren@apple.com1d72f772008-07-03 00:47:00 +0000172
dbatyai.u-szeged@partner.samsung.com46f07e52014-06-19 16:32:31 +0000173#if ENABLE(COMPUTED_GOTO_OPCODES)
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +0000174 Opcode* m_opcodeTable; // Maps OpcodeID => Opcode for compiling
175 HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000176#endif
fpizlo@apple.com0afe9662011-12-20 02:42:06 +0000177
178#if !ASSERT_DISABLED
179 bool m_initialized;
180#endif
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000181 };
barraclough@apple.com19afece2011-07-15 19:51:49 +0000182
ggaren@apple.com539d1bb2011-11-14 19:21:40 +0000183 JSValue eval(CallFrame*);
fpizlo@apple.combcfd39e2015-02-10 23:16:36 +0000184
185 inline CallFrame* calleeFrameForVarargs(CallFrame* callFrame, unsigned numUsedStackSlots, unsigned argumentCountIncludingThis)
186 {
msaboff@apple.comc15ae7e2015-09-16 23:40:35 +0000187 // We want the new frame to be allocated on a stack aligned offset with a stack
188 // aligned size. Align the size here.
189 argumentCountIncludingThis = WTF::roundUpToMultipleOf(
190 stackAlignmentRegisters(),
mark.lam@apple.com2bd89342016-07-08 22:58:15 +0000191 argumentCountIncludingThis + CallFrame::headerSizeInRegisters) - CallFrame::headerSizeInRegisters;
msaboff@apple.comc15ae7e2015-09-16 23:40:35 +0000192
193 // Align the frame offset here.
fpizlo@apple.combcfd39e2015-02-10 23:16:36 +0000194 unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(
195 stackAlignmentRegisters(),
mark.lam@apple.com2bd89342016-07-08 22:58:15 +0000196 numUsedStackSlots + argumentCountIncludingThis + CallFrame::headerSizeInRegisters);
fpizlo@apple.combcfd39e2015-02-10 23:16:36 +0000197 return CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
198 }
199
fpizlo@apple.com8fefdd32015-02-18 19:55:47 +0000200 unsigned sizeOfVarargs(CallFrame* exec, JSValue arguments, uint32_t firstVarArgOffset);
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000201 static const unsigned maxArguments = 0x10000;
mark.lam@apple.com504b1cc2016-07-11 20:48:15 +0000202 unsigned sizeFrameForVarargs(CallFrame* exec, VM&, JSValue arguments, unsigned numUsedStackSlots, uint32_t firstVarArgOffset);
203 unsigned sizeFrameForForwardArguments(CallFrame* exec, VM&, unsigned numUsedStackSlots);
fpizlo@apple.combcfd39e2015-02-10 23:16:36 +0000204 void loadVarargs(CallFrame* execCaller, VirtualRegister firstElementDest, JSValue source, uint32_t offset, uint32_t length);
205 void setupVarargsFrame(CallFrame* execCaller, CallFrame* execCallee, JSValue arguments, uint32_t firstVarArgOffset, uint32_t length);
206 void setupVarargsFrameAndSetThis(CallFrame* execCaller, CallFrame* execCallee, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset, uint32_t length);
keith_miller@apple.come497e202016-06-13 21:05:36 +0000207 void setupForwardArgumentsFrame(CallFrame* execCaller, CallFrame* execCallee, uint32_t length);
208 void setupForwardArgumentsFrameAndSetThis(CallFrame* execCaller, CallFrame* execCallee, JSValue thisValue, uint32_t length);
fpizlo@apple.com74485fb2015-02-10 03:27:43 +0000209
cwzwarich@webkit.org3f782f62008-09-08 01:28:33 +0000210} // namespace JSC