]> git.saurik.com Git - apple/javascriptcore.git/blame - interpreter/StackVisitor.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / interpreter / StackVisitor.h
CommitLineData
81345200 1/*
ed1e77d3 2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
81345200
A
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
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.
12 *
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.
24 */
25
26#ifndef StackVisitor_h
27#define StackVisitor_h
28
ed1e77d3 29#include "VMEntryRecord.h"
81345200
A
30#include <wtf/text/WTFString.h>
31
32namespace JSC {
33
34struct CodeOrigin;
35struct InlineCallFrame;
36
81345200
A
37class CodeBlock;
38class ExecState;
39class JSFunction;
40class JSObject;
41class JSScope;
ed1e77d3 42class ClonedArguments;
81345200
A
43class Register;
44
45typedef ExecState CallFrame;
46
47class StackVisitor {
48public:
49 class Frame {
50 public:
51 enum CodeType {
52 Global,
53 Eval,
54 Function,
55 Native
56 };
57
58 size_t index() const { return m_index; }
59 size_t argumentCountIncludingThis() const { return m_argumentCountIncludingThis; }
ed1e77d3 60 bool callerIsVMEntryFrame() const { return m_callerIsVMEntryFrame; }
81345200
A
61 CallFrame* callerFrame() const { return m_callerFrame; }
62 JSObject* callee() const { return m_callee; }
81345200
A
63 CodeBlock* codeBlock() const { return m_codeBlock; }
64 unsigned bytecodeOffset() const { return m_bytecodeOffset; }
65#if ENABLE(DFG_JIT)
66 InlineCallFrame* inlineCallFrame() const { return m_inlineCallFrame; }
67#endif
68
69 bool isJSFrame() const { return !!codeBlock(); }
70#if ENABLE(DFG_JIT)
71 bool isInlinedFrame() const { return !!m_inlineCallFrame; }
72#endif
73
74 JS_EXPORT_PRIVATE String functionName();
75 JS_EXPORT_PRIVATE String sourceURL();
76 JS_EXPORT_PRIVATE String toString();
77
78 CodeType codeType() const;
79 JS_EXPORT_PRIVATE void computeLineAndColumn(unsigned& line, unsigned& column);
80
ed1e77d3
A
81 ClonedArguments* createArguments();
82 VMEntryFrame* vmEntryFrame() const { return m_VMEntryFrame; }
81345200
A
83 CallFrame* callFrame() const { return m_callFrame; }
84
81345200 85 JS_EXPORT_PRIVATE void print(int indentLevel);
81345200
A
86
87 private:
88 Frame() { }
89 ~Frame() { }
90
91 void retrieveExpressionInfo(int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column);
92 void setToEnd();
93
94 size_t m_index;
95 size_t m_argumentCountIncludingThis;
ed1e77d3
A
96 VMEntryFrame* m_VMEntryFrame;
97 VMEntryFrame* m_CallerVMEntryFrame;
81345200
A
98 CallFrame* m_callerFrame;
99 JSObject* m_callee;
81345200
A
100 CodeBlock* m_codeBlock;
101 unsigned m_bytecodeOffset;
ed1e77d3 102 bool m_callerIsVMEntryFrame;
81345200
A
103#if ENABLE(DFG_JIT)
104 InlineCallFrame* m_inlineCallFrame;
105#endif
106 CallFrame* m_callFrame;
107
108 friend class StackVisitor;
109 };
110
111 enum Status {
112 Continue = 0,
113 Done = 1
114 };
115
116 // StackVisitor::visit() expects a Functor that implements the following method:
117 // Status operator()(StackVisitor&);
118
119 template <typename Functor>
120 static void visit(CallFrame* startFrame, Functor& functor)
121 {
122 StackVisitor visitor(startFrame);
123 while (visitor->callFrame()) {
124 Status status = functor(visitor);
125 if (status != Continue)
126 break;
127 visitor.gotoNextFrame();
128 }
129 }
130
131 Frame& operator*() { return m_frame; }
132 ALWAYS_INLINE Frame* operator->() { return &m_frame; }
133
134private:
135 JS_EXPORT_PRIVATE StackVisitor(CallFrame* startFrame);
136
137 JS_EXPORT_PRIVATE void gotoNextFrame();
138
139 void readFrame(CallFrame*);
140 void readNonInlinedFrame(CallFrame*, CodeOrigin* = 0);
141#if ENABLE(DFG_JIT)
142 void readInlinedFrame(CallFrame*, CodeOrigin*);
143#endif
144
145 Frame m_frame;
146};
147
ed1e77d3
A
148class CallerFunctor {
149public:
150 CallerFunctor()
151 : m_hasSkippedFirstFrame(false)
152 , m_callerFrame(0)
153 {
154 }
155
156 CallFrame* callerFrame() const { return m_callerFrame; }
157
158 StackVisitor::Status operator()(StackVisitor& visitor)
159 {
160 if (!m_hasSkippedFirstFrame) {
161 m_hasSkippedFirstFrame = true;
162 return StackVisitor::Continue;
163 }
164
165 m_callerFrame = visitor->callFrame();
166 return StackVisitor::Done;
167 }
168
169private:
170 bool m_hasSkippedFirstFrame;
171 CallFrame* m_callerFrame;
172};
173
81345200
A
174} // namespace JSC
175
176#endif // StackVisitor_h
177