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 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.
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"
42 #include <wtf/HashMap.h>
43 #include <wtf/text/StringBuilder.h>
50 class FunctionExecutable
;
53 class LLIntOffsetsExtractor
;
54 class ProgramExecutable
;
58 struct CallFrameClosure
;
71 enum StackFrameCodeType
{
74 StackFrameFunctionCode
,
79 Strong
<JSObject
> callee
;
80 StackFrameCodeType codeType
;
81 Strong
<ExecutableBase
> executable
;
82 Strong
<UnlinkedCodeBlock
> codeBlock
;
83 RefPtr
<SourceProvider
> code
;
85 unsigned firstLineColumnOffset
;
86 unsigned characterOffset
;
87 unsigned bytecodeOffset
;
89 JS_EXPORT_PRIVATE String
toString(CallFrame
*);
90 String
friendlySourceURL() const
95 case StackFrameEvalCode
:
96 case StackFrameFunctionCode
:
97 case StackFrameGlobalCode
:
98 if (!sourceURL
.isEmpty())
99 traceLine
= sourceURL
.impl();
101 case StackFrameNativeCode
:
102 traceLine
= "[native code]";
105 return traceLine
.isNull() ? emptyString() : traceLine
;
107 String
friendlyFunctionName(CallFrame
* callFrame
) const
110 JSObject
* stackFrameCallee
= callee
.get();
113 case StackFrameEvalCode
:
114 traceLine
= "eval code";
116 case StackFrameNativeCode
:
118 traceLine
= getCalculatedDisplayName(callFrame
, stackFrameCallee
).impl();
120 case StackFrameFunctionCode
:
121 traceLine
= getCalculatedDisplayName(callFrame
, stackFrameCallee
).impl();
123 case StackFrameGlobalCode
:
124 traceLine
= "global code";
127 return traceLine
.isNull() ? emptyString() : traceLine
;
129 JS_EXPORT_PRIVATE
void computeLineAndColumn(unsigned& line
, unsigned& column
);
132 void expressionInfo(int& divot
, int& startOffset
, int& endOffset
, unsigned& line
, unsigned& column
);
135 class TopCallFrameSetter
{
137 TopCallFrameSetter(VM
& global
, CallFrame
* callFrame
)
139 , oldCallFrame(global
.topCallFrame
)
141 global
.topCallFrame
= callFrame
;
144 ~TopCallFrameSetter()
146 vm
.topCallFrame
= oldCallFrame
;
150 CallFrame
* oldCallFrame
;
153 class NativeCallFrameTracer
{
155 ALWAYS_INLINE
NativeCallFrameTracer(VM
* global
, CallFrame
* callFrame
)
159 global
->topCallFrame
= callFrame
;
164 WTF_MAKE_FAST_ALLOCATED
;
165 friend class CachedCall
;
166 friend class LLIntOffsetsExtractor
;
170 class ErrorHandlingMode
{
172 JS_EXPORT_PRIVATE
ErrorHandlingMode(ExecState
*);
173 JS_EXPORT_PRIVATE
~ErrorHandlingMode();
175 Interpreter
& m_interpreter
;
181 void initialize(bool canUseJIT
);
183 JSStack
& stack() { return m_stack
; }
185 Opcode
getOpcode(OpcodeID id
)
187 ASSERT(m_initialized
);
188 #if ENABLE(COMPUTED_GOTO_OPCODES)
189 return m_opcodeTable
[id
];
195 OpcodeID
getOpcodeID(Opcode opcode
)
197 ASSERT(m_initialized
);
198 #if ENABLE(COMPUTED_GOTO_OPCODES) && ENABLE(LLINT)
199 ASSERT(isOpcode(opcode
));
200 return m_opcodeIDTable
.get(opcode
);
206 bool isOpcode(Opcode
);
208 JSValue
execute(ProgramExecutable
*, CallFrame
*, JSObject
* thisObj
);
209 JSValue
executeCall(CallFrame
*, JSObject
* function
, CallType
, const CallData
&, JSValue thisValue
, const ArgList
&);
210 JSObject
* executeConstruct(CallFrame
*, JSObject
* function
, ConstructType
, const ConstructData
&, const ArgList
&);
211 JSValue
execute(EvalExecutable
*, CallFrame
*, JSValue thisValue
, JSScope
*);
213 JSValue
retrieveArgumentsFromVMCode(CallFrame
*, JSFunction
*) const;
214 JSValue
retrieveCallerFromVMCode(CallFrame
*, JSFunction
*) const;
215 JS_EXPORT_PRIVATE
void retrieveLastCaller(CallFrame
*, int& lineNumber
, intptr_t& sourceID
, String
& sourceURL
, JSValue
& function
) const;
217 void getArgumentsData(CallFrame
*, JSFunction
*&, ptrdiff_t& firstParameterIndex
, Register
*& argv
, int& argc
);
219 SamplingTool
* sampler() { return m_sampler
.get(); }
221 NEVER_INLINE HandlerInfo
* throwException(CallFrame
*&, JSValue
&, unsigned bytecodeOffset
);
222 NEVER_INLINE
void debug(CallFrame
*, DebugHookID
, int firstLine
, int lastLine
, int column
);
223 static const String
getTraceLine(CallFrame
*, StackFrameCodeType
, const String
&, int);
224 JS_EXPORT_PRIVATE
static void getStackTrace(VM
*, Vector
<StackFrame
>& results
, size_t maxStackSize
= std::numeric_limits
<size_t>::max());
225 static void addStackTraceIfNecessary(CallFrame
*, JSValue error
);
227 void dumpSampleData(ExecState
* exec
);
228 void startSampling();
231 JS_EXPORT_PRIVATE
void dumpCallFrame(CallFrame
*);
236 StackPolicy(Interpreter
&, const StackBounds
&);
237 inline size_t requiredCapacity() { return m_requiredCapacity
; }
240 Interpreter
& m_interpreter
;
241 size_t m_requiredCapacity
;
244 enum ExecutionFlag
{ Normal
, InitializeAndReturn
};
246 CallFrameClosure
prepareForRepeatCall(FunctionExecutable
*, CallFrame
*, JSFunction
*, int argumentCountIncludingThis
, JSScope
*);
247 void endRepeatCall(CallFrameClosure
&);
248 JSValue
execute(CallFrameClosure
&);
250 NEVER_INLINE
bool unwindCallFrame(CallFrame
*&, JSValue
, unsigned& bytecodeOffset
, CodeBlock
*&);
252 static CallFrame
* findFunctionCallFrameFromVMCode(CallFrame
*, JSFunction
*);
254 void dumpRegisters(CallFrame
*);
256 bool isCallBytecode(Opcode opcode
) { return opcode
== getOpcode(op_call
) || opcode
== getOpcode(op_construct
) || opcode
== getOpcode(op_call_eval
); }
258 void enableSampler();
259 int m_sampleEntryDepth
;
260 OwnPtr
<SamplingTool
> m_sampler
;
263 int m_errorHandlingModeReentry
;
265 #if ENABLE(COMPUTED_GOTO_OPCODES) && ENABLE(LLINT)
266 Opcode
* m_opcodeTable
; // Maps OpcodeID => Opcode for compiling
267 HashMap
<Opcode
, OpcodeID
> m_opcodeIDTable
; // Maps Opcode => OpcodeID for decompiling
275 // This value must not be an object that would require this conversion (WebCore's global object).
276 inline bool isValidThisObject(JSValue thisValue
, ExecState
* exec
)
278 return !thisValue
.isObject() || thisValue
.toThisObject(exec
) == thisValue
;
281 JSValue
eval(CallFrame
*);
282 CallFrame
* loadVarargs(CallFrame
*, JSStack
*, JSValue thisValue
, JSValue arguments
, int firstFreeRegister
);
286 #endif // Interpreter_h