]> git.saurik.com Git - apple/javascriptcore.git/blame - inspector/JSJavaScriptCallFrame.cpp
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / inspector / JSJavaScriptCallFrame.cpp
CommitLineData
81345200
A
1/*
2 * Copyright (C) 2014 Apple Inc. All rights reserved.
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#include "config.h"
27#include "JSJavaScriptCallFrame.h"
28
ed1e77d3 29#include "DebuggerScope.h"
81345200
A
30#include "Error.h"
31#include "JSCJSValue.h"
32#include "JSCellInlines.h"
33#include "JSJavaScriptCallFramePrototype.h"
34#include "StructureInlines.h"
35
36using namespace JSC;
37
38namespace Inspector {
39
ed1e77d3 40const ClassInfo JSJavaScriptCallFrame::s_info = { "JavaScriptCallFrame", &Base::s_info, 0, CREATE_METHOD_TABLE(JSJavaScriptCallFrame) };
81345200
A
41
42JSJavaScriptCallFrame::JSJavaScriptCallFrame(VM& vm, Structure* structure, PassRefPtr<JavaScriptCallFrame> impl)
43 : JSDestructibleObject(vm, structure)
44 , m_impl(impl.leakRef())
45{
46}
47
48void JSJavaScriptCallFrame::finishCreation(VM& vm)
49{
50 Base::finishCreation(vm);
51 ASSERT(inherits(info()));
52}
53
54JSObject* JSJavaScriptCallFrame::createPrototype(VM& vm, JSGlobalObject* globalObject)
55{
56 return JSJavaScriptCallFramePrototype::create(vm, globalObject, JSJavaScriptCallFramePrototype::createStructure(vm, globalObject, globalObject->objectPrototype()));
57}
58
59void JSJavaScriptCallFrame::destroy(JSC::JSCell* cell)
60{
61 JSJavaScriptCallFrame* thisObject = static_cast<JSJavaScriptCallFrame*>(cell);
62 thisObject->JSJavaScriptCallFrame::~JSJavaScriptCallFrame();
63}
64
65void JSJavaScriptCallFrame::releaseImpl()
66{
ed1e77d3
A
67 if (auto impl = std::exchange(m_impl, nullptr))
68 impl->deref();
81345200
A
69}
70
71JSJavaScriptCallFrame::~JSJavaScriptCallFrame()
72{
73 releaseImpl();
74}
75
76JSValue JSJavaScriptCallFrame::evaluate(ExecState* exec)
77{
ed1e77d3 78 NakedPtr<Exception> exception;
81345200
A
79 JSValue result = impl().evaluate(exec->argument(0).toString(exec)->value(exec), exception);
80 if (exception)
81 exec->vm().throwException(exec, exception);
82
83 return result;
84}
85
86JSValue JSJavaScriptCallFrame::scopeType(ExecState* exec)
87{
88 if (!impl().scopeChain())
89 return jsUndefined();
90
91 if (!exec->argument(0).isInt32())
92 return jsUndefined();
93 int index = exec->argument(0).asInt32();
94
ed1e77d3
A
95 DebuggerScope* scopeChain = impl().scopeChain();
96 DebuggerScope::iterator end = scopeChain->end();
81345200
A
97
98 bool foundLocalScope = false;
ed1e77d3
A
99 for (DebuggerScope::iterator iter = scopeChain->begin(); iter != end; ++iter) {
100 DebuggerScope* scope = iter.get();
101
102 if (!foundLocalScope && scope->isFunctionOrEvalScope()) {
103 // First function scope is the local scope, each successive one is a closure.
104 if (!index)
105 return jsNumber(JSJavaScriptCallFrame::LOCAL_SCOPE);
106 foundLocalScope = true;
81345200
A
107 }
108
109 if (!index) {
ed1e77d3
A
110 if (scope->isCatchScope())
111 return jsNumber(JSJavaScriptCallFrame::CATCH_SCOPE);
112 if (scope->isFunctionNameScope())
113 return jsNumber(JSJavaScriptCallFrame::FUNCTION_NAME_SCOPE);
114 if (scope->isWithScope())
115 return jsNumber(JSJavaScriptCallFrame::WITH_SCOPE);
116 if (scope->isGlobalScope()) {
117 ASSERT(++iter == end);
81345200 118 return jsNumber(JSJavaScriptCallFrame::GLOBAL_SCOPE);
ed1e77d3
A
119 }
120 ASSERT(scope->isFunctionOrEvalScope());
121 return jsNumber(JSJavaScriptCallFrame::CLOSURE_SCOPE);
81345200
A
122 }
123
124 --index;
125 }
126
127 ASSERT_NOT_REACHED();
128 return jsUndefined();
129}
130
131JSValue JSJavaScriptCallFrame::caller(ExecState* exec) const
132{
133 return toJS(exec, globalObject(), impl().caller());
134}
135
136JSValue JSJavaScriptCallFrame::sourceID(ExecState*) const
137{
138 return jsNumber(impl().sourceID());
139}
140
141JSValue JSJavaScriptCallFrame::line(ExecState*) const
142{
143 return jsNumber(impl().line());
144}
145
146JSValue JSJavaScriptCallFrame::column(ExecState*) const
147{
148 return jsNumber(impl().column());
149}
150
151JSValue JSJavaScriptCallFrame::functionName(ExecState* exec) const
152{
153 return jsString(exec, impl().functionName());
154}
155
156JSValue JSJavaScriptCallFrame::scopeChain(ExecState* exec) const
157{
158 if (!impl().scopeChain())
159 return jsNull();
160
ed1e77d3
A
161 DebuggerScope* scopeChain = impl().scopeChain();
162 DebuggerScope::iterator iter = scopeChain->begin();
163 DebuggerScope::iterator end = scopeChain->end();
81345200
A
164
165 // We must always have something in the scope chain.
166 ASSERT(iter != end);
167
168 MarkedArgumentBuffer list;
169 do {
170 list.append(iter.get());
171 ++iter;
172 } while (iter != end);
173
174 return constructArray(exec, nullptr, globalObject(), list);
175}
176
177JSValue JSJavaScriptCallFrame::thisObject(ExecState*) const
178{
179 return impl().thisValue();
180}
181
182JSValue JSJavaScriptCallFrame::type(ExecState* exec) const
183{
184 switch (impl().type()) {
185 case DebuggerCallFrame::FunctionType:
186 return jsNontrivialString(exec, ASCIILiteral("function"));
187 case DebuggerCallFrame::ProgramType:
188 return jsNontrivialString(exec, ASCIILiteral("program"));
189 }
190
191 ASSERT_NOT_REACHED();
192 return jsNull();
193}
194
195JSValue toJS(ExecState* exec, JSGlobalObject* globalObject, JavaScriptCallFrame* impl)
196{
197 if (!impl)
198 return jsNull();
199
200 JSObject* prototype = JSJavaScriptCallFrame::createPrototype(exec->vm(), globalObject);
201 Structure* structure = JSJavaScriptCallFrame::createStructure(exec->vm(), globalObject, prototype);
202 JSJavaScriptCallFrame* javaScriptCallFrame = JSJavaScriptCallFrame::create(exec->vm(), structure, impl);
203
204 return javaScriptCallFrame;
205}
206
207JSJavaScriptCallFrame* toJSJavaScriptCallFrame(JSValue value)
208{
209 return value.inherits(JSJavaScriptCallFrame::info()) ? jsCast<JSJavaScriptCallFrame*>(value) : nullptr;
210}
211
212} // namespace Inspector
213