]> git.saurik.com Git - apple/javascriptcore.git/blame - interpreter/Interpreter.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / interpreter / Interpreter.h
CommitLineData
9dae56ea 1/*
ed1e77d3 2 * Copyright (C) 2008, 2013, 2015 Apple Inc. All rights reserved.
93a37866 3 * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
9dae56ea
A
4 *
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.
81345200 14 * 3. Neither the name of Apple Inc. ("Apple") nor the names of
9dae56ea
A
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 */
29
30#ifndef Interpreter_h
31#define Interpreter_h
32
33#include "ArgList.h"
93a37866 34#include "JSCJSValue.h"
9dae56ea 35#include "JSCell.h"
ba379fdc 36#include "JSObject.h"
93a37866 37#include "JSStack.h"
6fe7ccc8 38#include "LLIntData.h"
9dae56ea 39#include "Opcode.h"
81345200 40#include "SourceProvider.h"
ed1e77d3 41#include "StackAlignment.h"
9dae56ea 42
f9bf01c6 43#include <wtf/HashMap.h>
93a37866 44#include <wtf/text/StringBuilder.h>
f9bf01c6 45
9dae56ea
A
46namespace JSC {
47
48 class CodeBlock;
f9bf01c6 49 class EvalExecutable;
6fe7ccc8 50 class ExecutableBase;
f9bf01c6 51 class FunctionExecutable;
93a37866 52 class VM;
ed1e77d3 53 class JSFunction;
9dae56ea 54 class JSGlobalObject;
6fe7ccc8 55 class LLIntOffsetsExtractor;
f9bf01c6 56 class ProgramExecutable;
9dae56ea 57 class Register;
93a37866 58 class JSScope;
9dae56ea 59 class SamplingTool;
ba379fdc 60 struct CallFrameClosure;
9dae56ea 61 struct HandlerInfo;
f9bf01c6 62 struct Instruction;
81345200
A
63 struct ProtoCallFrame;
64
9dae56ea
A
65 enum DebugHookID {
66 WillExecuteProgram,
67 DidExecuteProgram,
68 DidEnterCallFrame,
69 DidReachBreakpoint,
70 WillLeaveCallFrame,
71 WillExecuteStatement
72 };
73
6fe7ccc8
A
74 enum StackFrameCodeType {
75 StackFrameGlobalCode,
76 StackFrameEvalCode,
77 StackFrameFunctionCode,
78 StackFrameNativeCode
79 };
80
81 struct StackFrame {
82 Strong<JSObject> callee;
83 StackFrameCodeType codeType;
ed1e77d3 84 Strong<ScriptExecutable> executable;
93a37866
A
85 Strong<UnlinkedCodeBlock> codeBlock;
86 RefPtr<SourceProvider> code;
87 int lineOffset;
88 unsigned firstLineColumnOffset;
89 unsigned characterOffset;
90 unsigned bytecodeOffset;
91 String sourceURL;
92 JS_EXPORT_PRIVATE String toString(CallFrame*);
ed1e77d3
A
93 String friendlySourceURL() const;
94 String friendlyFunctionName(CallFrame*) const;
93a37866
A
95 JS_EXPORT_PRIVATE void computeLineAndColumn(unsigned& line, unsigned& column);
96
97 private:
98 void expressionInfo(int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column);
6fe7ccc8
A
99 };
100
ed1e77d3 101 class SuspendExceptionScope {
81345200 102 public:
ed1e77d3
A
103 SuspendExceptionScope(VM* vm)
104 : m_vm(vm)
81345200 105 {
ed1e77d3 106 oldException = vm->exception();
81345200
A
107 vm->clearException();
108 }
ed1e77d3 109 ~SuspendExceptionScope()
81345200 110 {
ed1e77d3 111 m_vm->setException(oldException);
81345200
A
112 }
113 private:
ed1e77d3 114 Exception* oldException;
81345200
A
115 VM* m_vm;
116 };
117
6fe7ccc8
A
118 class TopCallFrameSetter {
119 public:
81345200
A
120 TopCallFrameSetter(VM& currentVM, CallFrame* callFrame)
121 : vm(currentVM)
122 , oldCallFrame(currentVM.topCallFrame)
6fe7ccc8 123 {
81345200 124 currentVM.topCallFrame = callFrame;
6fe7ccc8
A
125 }
126
127 ~TopCallFrameSetter()
128 {
93a37866 129 vm.topCallFrame = oldCallFrame;
6fe7ccc8
A
130 }
131 private:
93a37866 132 VM& vm;
6fe7ccc8
A
133 CallFrame* oldCallFrame;
134 };
135
136 class NativeCallFrameTracer {
137 public:
81345200 138 ALWAYS_INLINE NativeCallFrameTracer(VM* vm, CallFrame* callFrame)
6fe7ccc8 139 {
81345200 140 ASSERT(vm);
6fe7ccc8 141 ASSERT(callFrame);
81345200
A
142 vm->topCallFrame = callFrame;
143 }
ed1e77d3
A
144 };
145
146 class NativeCallFrameTracerWithRestore {
147 public:
148 ALWAYS_INLINE NativeCallFrameTracerWithRestore(VM* vm, VMEntryFrame* vmEntryFrame, CallFrame* callFrame)
149 : m_vm(vm)
81345200
A
150 {
151 ASSERT(vm);
152 ASSERT(callFrame);
ed1e77d3
A
153 m_savedTopVMEntryFrame = vm->topVMEntryFrame;
154 m_savedTopCallFrame = vm->topCallFrame;
155 vm->topVMEntryFrame = vmEntryFrame;
156 vm->topCallFrame = callFrame;
6fe7ccc8 157 }
ed1e77d3
A
158
159 ALWAYS_INLINE ~NativeCallFrameTracerWithRestore()
160 {
161 m_vm->topVMEntryFrame = m_savedTopVMEntryFrame;
162 m_vm->topCallFrame = m_savedTopCallFrame;
163 }
164
165 private:
166 VM* m_vm;
167 VMEntryFrame* m_savedTopVMEntryFrame;
168 CallFrame* m_savedTopCallFrame;
6fe7ccc8
A
169 };
170
14957cd0
A
171 class Interpreter {
172 WTF_MAKE_FAST_ALLOCATED;
ba379fdc 173 friend class CachedCall;
6fe7ccc8
A
174 friend class LLIntOffsetsExtractor;
175 friend class JIT;
81345200 176 friend class VM;
93a37866 177
9dae56ea 178 public:
93a37866 179 Interpreter(VM &);
6fe7ccc8
A
180 ~Interpreter();
181
93a37866 182 void initialize(bool canUseJIT);
9dae56ea 183
93a37866 184 JSStack& stack() { return m_stack; }
9dae56ea
A
185
186 Opcode getOpcode(OpcodeID id)
187 {
6fe7ccc8 188 ASSERT(m_initialized);
93a37866 189#if ENABLE(COMPUTED_GOTO_OPCODES)
6fe7ccc8
A
190 return m_opcodeTable[id];
191#else
192 return id;
193#endif
9dae56ea
A
194 }
195
196 OpcodeID getOpcodeID(Opcode opcode)
197 {
6fe7ccc8 198 ASSERT(m_initialized);
81345200 199#if ENABLE(COMPUTED_GOTO_OPCODES)
6fe7ccc8 200 ASSERT(isOpcode(opcode));
6fe7ccc8
A
201 return m_opcodeIDTable.get(opcode);
202#else
203 return opcode;
204#endif
205 }
206
9dae56ea 207 bool isOpcode(Opcode);
14957cd0 208
93a37866 209 JSValue execute(ProgramExecutable*, CallFrame*, JSObject* thisObj);
14957cd0
A
210 JSValue executeCall(CallFrame*, JSObject* function, CallType, const CallData&, JSValue thisValue, const ArgList&);
211 JSObject* executeConstruct(CallFrame*, JSObject* function, ConstructType, const ConstructData&, const ArgList&);
93a37866 212 JSValue execute(EvalExecutable*, CallFrame*, JSValue thisValue, JSScope*);
9dae56ea 213
9dae56ea 214 void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
9dae56ea 215
f9bf01c6 216 SamplingTool* sampler() { return m_sampler.get(); }
9dae56ea 217
ed1e77d3 218 NEVER_INLINE HandlerInfo* unwind(VMEntryFrame*&, CallFrame*&, Exception*);
81345200
A
219 NEVER_INLINE void debug(CallFrame*, DebugHookID);
220 JSString* stackTraceAsString(ExecState*, Vector<StackFrame>);
221
222 static EncodedJSValue JSC_HOST_CALL constructWithErrorConstructor(ExecState*);
223 static EncodedJSValue JSC_HOST_CALL callErrorConstructor(ExecState*);
224 static EncodedJSValue JSC_HOST_CALL constructWithNativeErrorConstructor(ExecState*);
225 static EncodedJSValue JSC_HOST_CALL callNativeErrorConstructor(ExecState*);
9dae56ea 226
f9bf01c6
A
227 void dumpSampleData(ExecState* exec);
228 void startSampling();
229 void stopSampling();
93a37866
A
230
231 JS_EXPORT_PRIVATE void dumpCallFrame(CallFrame*);
232
ed1e77d3
A
233 void getStackTrace(Vector<StackFrame>& results, size_t maxStackSize = std::numeric_limits<size_t>::max());
234
9dae56ea
A
235 private:
236 enum ExecutionFlag { Normal, InitializeAndReturn };
237
81345200 238 CallFrameClosure prepareForRepeatCall(FunctionExecutable*, CallFrame*, ProtoCallFrame*, JSFunction*, int argumentCountIncludingThis, JSScope*, JSValue*);
9dae56ea 239
81345200 240 JSValue execute(CallFrameClosure&);
9dae56ea 241
ed1e77d3 242
9dae56ea 243
9dae56ea 244 void dumpRegisters(CallFrame*);
9dae56ea
A
245
246 bool isCallBytecode(Opcode opcode) { return opcode == getOpcode(op_call) || opcode == getOpcode(op_construct) || opcode == getOpcode(op_call_eval); }
247
f9bf01c6
A
248 void enableSampler();
249 int m_sampleEntryDepth;
ed1e77d3 250 std::unique_ptr<SamplingTool> m_sampler;
9dae56ea 251
81345200 252 VM& m_vm;
93a37866
A
253 JSStack m_stack;
254 int m_errorHandlingModeReentry;
9dae56ea 255
81345200 256#if ENABLE(COMPUTED_GOTO_OPCODES)
6fe7ccc8
A
257 Opcode* m_opcodeTable; // Maps OpcodeID => Opcode for compiling
258 HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
9dae56ea 259#endif
6fe7ccc8
A
260
261#if !ASSERT_DISABLED
262 bool m_initialized;
263#endif
9dae56ea 264 };
6fe7ccc8 265
6fe7ccc8 266 JSValue eval(CallFrame*);
ed1e77d3
A
267
268 inline CallFrame* calleeFrameForVarargs(CallFrame* callFrame, unsigned numUsedStackSlots, unsigned argumentCountIncludingThis)
269 {
270 unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(
271 stackAlignmentRegisters(),
272 numUsedStackSlots + argumentCountIncludingThis + JSStack::CallFrameHeaderSize);
273 return CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
274 }
275
276 unsigned sizeOfVarargs(CallFrame* exec, JSValue arguments, uint32_t firstVarArgOffset);
277 static const unsigned maxArguments = 0x10000;
278 unsigned sizeFrameForVarargs(CallFrame* exec, JSStack*, JSValue arguments, unsigned numUsedStackSlots, uint32_t firstVarArgOffset);
279 void loadVarargs(CallFrame* execCaller, VirtualRegister firstElementDest, JSValue source, uint32_t offset, uint32_t length);
280 void setupVarargsFrame(CallFrame* execCaller, CallFrame* execCallee, JSValue arguments, uint32_t firstVarArgOffset, uint32_t length);
281 void setupVarargsFrameAndSetThis(CallFrame* execCaller, CallFrame* execCallee, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset, uint32_t length);
282
9dae56ea
A
283} // namespace JSC
284
285#endif // Interpreter_h