2 * Copyright (C) 2008, 2013 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"
36 #include "JSFunction.h"
39 #include "LLIntData.h"
41 #include "SourceProvider.h"
43 #include <wtf/HashMap.h>
44 #include <wtf/text/StringBuilder.h>
51 class FunctionExecutable
;
54 class LLIntOffsetsExtractor
;
55 class ProgramExecutable
;
59 struct CallFrameClosure
;
62 struct ProtoCallFrame
;
73 enum StackFrameCodeType
{
76 StackFrameFunctionCode
,
81 Strong
<JSObject
> callee
;
82 StackFrameCodeType codeType
;
83 Strong
<ExecutableBase
> executable
;
84 Strong
<UnlinkedCodeBlock
> codeBlock
;
85 RefPtr
<SourceProvider
> code
;
87 unsigned firstLineColumnOffset
;
88 unsigned characterOffset
;
89 unsigned bytecodeOffset
;
91 JS_EXPORT_PRIVATE String
toString(CallFrame
*);
92 String
friendlySourceURL() const
97 case StackFrameEvalCode
:
98 case StackFrameFunctionCode
:
99 case StackFrameGlobalCode
:
100 if (!sourceURL
.isEmpty())
101 traceLine
= sourceURL
.impl();
103 case StackFrameNativeCode
:
104 traceLine
= "[native code]";
107 return traceLine
.isNull() ? emptyString() : traceLine
;
109 String
friendlyFunctionName(CallFrame
* callFrame
) const
112 JSObject
* stackFrameCallee
= callee
.get();
115 case StackFrameEvalCode
:
116 traceLine
= "eval code";
118 case StackFrameNativeCode
:
120 traceLine
= getCalculatedDisplayName(callFrame
, stackFrameCallee
).impl();
122 case StackFrameFunctionCode
:
123 traceLine
= getCalculatedDisplayName(callFrame
, stackFrameCallee
).impl();
125 case StackFrameGlobalCode
:
126 traceLine
= "global code";
129 return traceLine
.isNull() ? emptyString() : traceLine
;
131 JS_EXPORT_PRIVATE
void computeLineAndColumn(unsigned& line
, unsigned& column
);
134 void expressionInfo(int& divot
, int& startOffset
, int& endOffset
, unsigned& line
, unsigned& column
);
137 class ClearExceptionScope
{
139 ClearExceptionScope(VM
* vm
): m_vm(vm
)
141 vm
->getExceptionInfo(oldException
, oldExceptionStack
);
142 vm
->clearException();
144 ~ClearExceptionScope()
146 m_vm
->setExceptionInfo(oldException
, oldExceptionStack
);
149 JSC::JSValue oldException
;
150 RefCountedArray
<JSC::StackFrame
> oldExceptionStack
;
154 class TopCallFrameSetter
{
156 TopCallFrameSetter(VM
& currentVM
, CallFrame
* callFrame
)
158 , oldCallFrame(currentVM
.topCallFrame
)
160 ASSERT(!callFrame
->isVMEntrySentinel());
161 currentVM
.topCallFrame
= callFrame
;
164 ~TopCallFrameSetter()
166 ASSERT(!oldCallFrame
->isVMEntrySentinel());
167 vm
.topCallFrame
= oldCallFrame
;
171 CallFrame
* oldCallFrame
;
174 class NativeCallFrameTracer
{
176 ALWAYS_INLINE
NativeCallFrameTracer(VM
* vm
, CallFrame
* callFrame
)
180 ASSERT(!callFrame
->isVMEntrySentinel());
181 vm
->topCallFrame
= callFrame
;
184 enum VMEntrySentinelOKTag
{ VMEntrySentinelOK
};
185 ALWAYS_INLINE
NativeCallFrameTracer(VM
* vm
, CallFrame
* callFrame
, VMEntrySentinelOKTag
)
189 if (!callFrame
->isVMEntrySentinel())
190 vm
->topCallFrame
= callFrame
;
195 WTF_MAKE_FAST_ALLOCATED
;
196 friend class CachedCall
;
197 friend class LLIntOffsetsExtractor
;
205 void initialize(bool canUseJIT
);
207 JSStack
& stack() { return m_stack
; }
209 Opcode
getOpcode(OpcodeID id
)
211 ASSERT(m_initialized
);
212 #if ENABLE(COMPUTED_GOTO_OPCODES)
213 return m_opcodeTable
[id
];
219 OpcodeID
getOpcodeID(Opcode opcode
)
221 ASSERT(m_initialized
);
222 #if ENABLE(COMPUTED_GOTO_OPCODES)
223 ASSERT(isOpcode(opcode
));
224 return m_opcodeIDTable
.get(opcode
);
230 bool isOpcode(Opcode
);
232 JSValue
execute(ProgramExecutable
*, CallFrame
*, JSObject
* thisObj
);
233 JSValue
executeCall(CallFrame
*, JSObject
* function
, CallType
, const CallData
&, JSValue thisValue
, const ArgList
&);
234 JSObject
* executeConstruct(CallFrame
*, JSObject
* function
, ConstructType
, const ConstructData
&, const ArgList
&);
235 JSValue
execute(EvalExecutable
*, CallFrame
*, JSValue thisValue
, JSScope
*);
237 void getArgumentsData(CallFrame
*, JSFunction
*&, ptrdiff_t& firstParameterIndex
, Register
*& argv
, int& argc
);
239 SamplingTool
* sampler() { return m_sampler
.get(); }
241 NEVER_INLINE HandlerInfo
* unwind(CallFrame
*&, JSValue
&);
242 NEVER_INLINE
void debug(CallFrame
*, DebugHookID
);
243 JSString
* stackTraceAsString(ExecState
*, Vector
<StackFrame
>);
245 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
*);
250 void dumpSampleData(ExecState
* exec
);
251 void startSampling();
254 JS_EXPORT_PRIVATE
void dumpCallFrame(CallFrame
*);
257 enum ExecutionFlag
{ Normal
, InitializeAndReturn
};
259 CallFrameClosure
prepareForRepeatCall(FunctionExecutable
*, CallFrame
*, ProtoCallFrame
*, JSFunction
*, int argumentCountIncludingThis
, JSScope
*, JSValue
*);
261 JSValue
execute(CallFrameClosure
&);
263 void getStackTrace(Vector
<StackFrame
>& results
, size_t maxStackSize
= std::numeric_limits
<size_t>::max());
265 void dumpRegisters(CallFrame
*);
267 bool isCallBytecode(Opcode opcode
) { return opcode
== getOpcode(op_call
) || opcode
== getOpcode(op_construct
) || opcode
== getOpcode(op_call_eval
); }
269 void enableSampler();
270 int m_sampleEntryDepth
;
271 OwnPtr
<SamplingTool
> m_sampler
;
275 int m_errorHandlingModeReentry
;
277 #if ENABLE(COMPUTED_GOTO_OPCODES)
278 Opcode
* m_opcodeTable
; // Maps OpcodeID => Opcode for compiling
279 HashMap
<Opcode
, OpcodeID
> m_opcodeIDTable
; // Maps Opcode => OpcodeID for decompiling
287 JSValue
eval(CallFrame
*);
288 CallFrame
* sizeFrameForVarargs(CallFrame
*, JSStack
*, JSValue
, int, uint32_t firstVarArgOffset
);
289 void loadVarargs(CallFrame
*, CallFrame
*, JSValue
, JSValue
, uint32_t firstVarArgOffset
);
292 #endif // Interpreter_h