2 * Copyright (C) 2008, 2013, 2015 Apple Inc. All rights reserved.
3 * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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 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.
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.
34 #include "JSCJSValue.h"
38 #include "LLIntData.h"
40 #include "SourceProvider.h"
41 #include "StackAlignment.h"
43 #include <wtf/HashMap.h>
44 #include <wtf/text/StringBuilder.h>
51 class FunctionExecutable
;
55 class LLIntOffsetsExtractor
;
56 class ProgramExecutable
;
60 struct CallFrameClosure
;
63 struct ProtoCallFrame
;
74 enum StackFrameCodeType
{
77 StackFrameFunctionCode
,
82 Strong
<JSObject
> callee
;
83 StackFrameCodeType codeType
;
84 Strong
<ScriptExecutable
> executable
;
85 Strong
<UnlinkedCodeBlock
> codeBlock
;
86 RefPtr
<SourceProvider
> code
;
88 unsigned firstLineColumnOffset
;
89 unsigned characterOffset
;
90 unsigned bytecodeOffset
;
92 JS_EXPORT_PRIVATE String
toString(CallFrame
*);
93 String
friendlySourceURL() const;
94 String
friendlyFunctionName(CallFrame
*) const;
95 JS_EXPORT_PRIVATE
void computeLineAndColumn(unsigned& line
, unsigned& column
);
98 void expressionInfo(int& divot
, int& startOffset
, int& endOffset
, unsigned& line
, unsigned& column
);
101 class SuspendExceptionScope
{
103 SuspendExceptionScope(VM
* vm
)
106 oldException
= vm
->exception();
107 vm
->clearException();
109 ~SuspendExceptionScope()
111 m_vm
->setException(oldException
);
114 Exception
* oldException
;
118 class TopCallFrameSetter
{
120 TopCallFrameSetter(VM
& currentVM
, CallFrame
* callFrame
)
122 , oldCallFrame(currentVM
.topCallFrame
)
124 currentVM
.topCallFrame
= callFrame
;
127 ~TopCallFrameSetter()
129 vm
.topCallFrame
= oldCallFrame
;
133 CallFrame
* oldCallFrame
;
136 class NativeCallFrameTracer
{
138 ALWAYS_INLINE
NativeCallFrameTracer(VM
* vm
, CallFrame
* callFrame
)
142 vm
->topCallFrame
= callFrame
;
146 class NativeCallFrameTracerWithRestore
{
148 ALWAYS_INLINE
NativeCallFrameTracerWithRestore(VM
* vm
, VMEntryFrame
* vmEntryFrame
, CallFrame
* callFrame
)
153 m_savedTopVMEntryFrame
= vm
->topVMEntryFrame
;
154 m_savedTopCallFrame
= vm
->topCallFrame
;
155 vm
->topVMEntryFrame
= vmEntryFrame
;
156 vm
->topCallFrame
= callFrame
;
159 ALWAYS_INLINE
~NativeCallFrameTracerWithRestore()
161 m_vm
->topVMEntryFrame
= m_savedTopVMEntryFrame
;
162 m_vm
->topCallFrame
= m_savedTopCallFrame
;
167 VMEntryFrame
* m_savedTopVMEntryFrame
;
168 CallFrame
* m_savedTopCallFrame
;
172 WTF_MAKE_FAST_ALLOCATED
;
173 friend class CachedCall
;
174 friend class LLIntOffsetsExtractor
;
182 void initialize(bool canUseJIT
);
184 JSStack
& stack() { return m_stack
; }
186 Opcode
getOpcode(OpcodeID id
)
188 ASSERT(m_initialized
);
189 #if ENABLE(COMPUTED_GOTO_OPCODES)
190 return m_opcodeTable
[id
];
196 OpcodeID
getOpcodeID(Opcode opcode
)
198 ASSERT(m_initialized
);
199 #if ENABLE(COMPUTED_GOTO_OPCODES)
200 ASSERT(isOpcode(opcode
));
201 return m_opcodeIDTable
.get(opcode
);
207 bool isOpcode(Opcode
);
209 JSValue
execute(ProgramExecutable
*, CallFrame
*, JSObject
* thisObj
);
210 JSValue
executeCall(CallFrame
*, JSObject
* function
, CallType
, const CallData
&, JSValue thisValue
, const ArgList
&);
211 JSObject
* executeConstruct(CallFrame
*, JSObject
* function
, ConstructType
, const ConstructData
&, const ArgList
&);
212 JSValue
execute(EvalExecutable
*, CallFrame
*, JSValue thisValue
, JSScope
*);
214 void getArgumentsData(CallFrame
*, JSFunction
*&, ptrdiff_t& firstParameterIndex
, Register
*& argv
, int& argc
);
216 SamplingTool
* sampler() { return m_sampler
.get(); }
218 NEVER_INLINE HandlerInfo
* unwind(VMEntryFrame
*&, CallFrame
*&, Exception
*);
219 NEVER_INLINE
void debug(CallFrame
*, DebugHookID
);
220 JSString
* stackTraceAsString(ExecState
*, Vector
<StackFrame
>);
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
*);
227 void dumpSampleData(ExecState
* exec
);
228 void startSampling();
231 JS_EXPORT_PRIVATE
void dumpCallFrame(CallFrame
*);
233 void getStackTrace(Vector
<StackFrame
>& results
, size_t maxStackSize
= std::numeric_limits
<size_t>::max());
236 enum ExecutionFlag
{ Normal
, InitializeAndReturn
};
238 CallFrameClosure
prepareForRepeatCall(FunctionExecutable
*, CallFrame
*, ProtoCallFrame
*, JSFunction
*, int argumentCountIncludingThis
, JSScope
*, JSValue
*);
240 JSValue
execute(CallFrameClosure
&);
244 void dumpRegisters(CallFrame
*);
246 bool isCallBytecode(Opcode opcode
) { return opcode
== getOpcode(op_call
) || opcode
== getOpcode(op_construct
) || opcode
== getOpcode(op_call_eval
); }
248 void enableSampler();
249 int m_sampleEntryDepth
;
250 std::unique_ptr
<SamplingTool
> m_sampler
;
254 int m_errorHandlingModeReentry
;
256 #if ENABLE(COMPUTED_GOTO_OPCODES)
257 Opcode
* m_opcodeTable
; // Maps OpcodeID => Opcode for compiling
258 HashMap
<Opcode
, OpcodeID
> m_opcodeIDTable
; // Maps Opcode => OpcodeID for decompiling
266 JSValue
eval(CallFrame
*);
268 inline CallFrame
* calleeFrameForVarargs(CallFrame
* callFrame
, unsigned numUsedStackSlots
, unsigned argumentCountIncludingThis
)
270 unsigned paddedCalleeFrameOffset
= WTF::roundUpToMultipleOf(
271 stackAlignmentRegisters(),
272 numUsedStackSlots
+ argumentCountIncludingThis
+ JSStack::CallFrameHeaderSize
);
273 return CallFrame::create(callFrame
->registers() - paddedCalleeFrameOffset
);
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
);
285 #endif // Interpreter_h