2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #ifndef StackVisitor_h
27 #define StackVisitor_h
29 #include "VMEntryRecord.h"
30 #include <wtf/text/WTFString.h>
35 struct InlineCallFrame
;
42 class ClonedArguments
;
45 typedef ExecState CallFrame
;
58 size_t index() const { return m_index
; }
59 size_t argumentCountIncludingThis() const { return m_argumentCountIncludingThis
; }
60 bool callerIsVMEntryFrame() const { return m_callerIsVMEntryFrame
; }
61 CallFrame
* callerFrame() const { return m_callerFrame
; }
62 JSObject
* callee() const { return m_callee
; }
63 CodeBlock
* codeBlock() const { return m_codeBlock
; }
64 unsigned bytecodeOffset() const { return m_bytecodeOffset
; }
66 InlineCallFrame
* inlineCallFrame() const { return m_inlineCallFrame
; }
69 bool isJSFrame() const { return !!codeBlock(); }
71 bool isInlinedFrame() const { return !!m_inlineCallFrame
; }
74 JS_EXPORT_PRIVATE String
functionName();
75 JS_EXPORT_PRIVATE String
sourceURL();
76 JS_EXPORT_PRIVATE String
toString();
78 CodeType
codeType() const;
79 JS_EXPORT_PRIVATE
void computeLineAndColumn(unsigned& line
, unsigned& column
);
81 ClonedArguments
* createArguments();
82 VMEntryFrame
* vmEntryFrame() const { return m_VMEntryFrame
; }
83 CallFrame
* callFrame() const { return m_callFrame
; }
85 JS_EXPORT_PRIVATE
void print(int indentLevel
);
91 void retrieveExpressionInfo(int& divot
, int& startOffset
, int& endOffset
, unsigned& line
, unsigned& column
);
95 size_t m_argumentCountIncludingThis
;
96 VMEntryFrame
* m_VMEntryFrame
;
97 VMEntryFrame
* m_CallerVMEntryFrame
;
98 CallFrame
* m_callerFrame
;
100 CodeBlock
* m_codeBlock
;
101 unsigned m_bytecodeOffset
;
102 bool m_callerIsVMEntryFrame
;
104 InlineCallFrame
* m_inlineCallFrame
;
106 CallFrame
* m_callFrame
;
108 friend class StackVisitor
;
116 // StackVisitor::visit() expects a Functor that implements the following method:
117 // Status operator()(StackVisitor&);
119 template <typename Functor
>
120 static void visit(CallFrame
* startFrame
, Functor
& functor
)
122 StackVisitor
visitor(startFrame
);
123 while (visitor
->callFrame()) {
124 Status status
= functor(visitor
);
125 if (status
!= Continue
)
127 visitor
.gotoNextFrame();
131 Frame
& operator*() { return m_frame
; }
132 ALWAYS_INLINE Frame
* operator->() { return &m_frame
; }
135 JS_EXPORT_PRIVATE
StackVisitor(CallFrame
* startFrame
);
137 JS_EXPORT_PRIVATE
void gotoNextFrame();
139 void readFrame(CallFrame
*);
140 void readNonInlinedFrame(CallFrame
*, CodeOrigin
* = 0);
142 void readInlinedFrame(CallFrame
*, CodeOrigin
*);
148 class CallerFunctor
{
151 : m_hasSkippedFirstFrame(false)
156 CallFrame
* callerFrame() const { return m_callerFrame
; }
158 StackVisitor::Status
operator()(StackVisitor
& visitor
)
160 if (!m_hasSkippedFirstFrame
) {
161 m_hasSkippedFirstFrame
= true;
162 return StackVisitor::Continue
;
165 m_callerFrame
= visitor
->callFrame();
166 return StackVisitor::Done
;
170 bool m_hasSkippedFirstFrame
;
171 CallFrame
* m_callerFrame
;
176 #endif // StackVisitor_h