2 * Copyright (C) 2014 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.
27 #include "JSJavaScriptCallFrame.h"
29 #include "DebuggerScope.h"
31 #include "JSCJSValue.h"
32 #include "JSCellInlines.h"
33 #include "JSJavaScriptCallFramePrototype.h"
34 #include "StructureInlines.h"
40 const ClassInfo
JSJavaScriptCallFrame::s_info
= { "JavaScriptCallFrame", &Base::s_info
, 0, CREATE_METHOD_TABLE(JSJavaScriptCallFrame
) };
42 JSJavaScriptCallFrame::JSJavaScriptCallFrame(VM
& vm
, Structure
* structure
, PassRefPtr
<JavaScriptCallFrame
> impl
)
43 : JSDestructibleObject(vm
, structure
)
44 , m_impl(impl
.leakRef())
48 void JSJavaScriptCallFrame::finishCreation(VM
& vm
)
50 Base::finishCreation(vm
);
51 ASSERT(inherits(info()));
54 JSObject
* JSJavaScriptCallFrame::createPrototype(VM
& vm
, JSGlobalObject
* globalObject
)
56 return JSJavaScriptCallFramePrototype::create(vm
, globalObject
, JSJavaScriptCallFramePrototype::createStructure(vm
, globalObject
, globalObject
->objectPrototype()));
59 void JSJavaScriptCallFrame::destroy(JSC::JSCell
* cell
)
61 JSJavaScriptCallFrame
* thisObject
= static_cast<JSJavaScriptCallFrame
*>(cell
);
62 thisObject
->JSJavaScriptCallFrame::~JSJavaScriptCallFrame();
65 void JSJavaScriptCallFrame::releaseImpl()
67 if (auto impl
= std::exchange(m_impl
, nullptr))
71 JSJavaScriptCallFrame::~JSJavaScriptCallFrame()
76 JSValue
JSJavaScriptCallFrame::evaluate(ExecState
* exec
)
78 NakedPtr
<Exception
> exception
;
79 JSValue result
= impl().evaluate(exec
->argument(0).toString(exec
)->value(exec
), exception
);
81 exec
->vm().throwException(exec
, exception
);
86 JSValue
JSJavaScriptCallFrame::scopeType(ExecState
* exec
)
88 if (!impl().scopeChain())
91 if (!exec
->argument(0).isInt32())
93 int index
= exec
->argument(0).asInt32();
95 DebuggerScope
* scopeChain
= impl().scopeChain();
96 DebuggerScope::iterator end
= scopeChain
->end();
98 bool foundLocalScope
= false;
99 for (DebuggerScope::iterator iter
= scopeChain
->begin(); iter
!= end
; ++iter
) {
100 DebuggerScope
* scope
= iter
.get();
102 if (!foundLocalScope
&& scope
->isFunctionOrEvalScope()) {
103 // First function scope is the local scope, each successive one is a closure.
105 return jsNumber(JSJavaScriptCallFrame::LOCAL_SCOPE
);
106 foundLocalScope
= true;
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
);
118 return jsNumber(JSJavaScriptCallFrame::GLOBAL_SCOPE
);
120 ASSERT(scope
->isFunctionOrEvalScope());
121 return jsNumber(JSJavaScriptCallFrame::CLOSURE_SCOPE
);
127 ASSERT_NOT_REACHED();
128 return jsUndefined();
131 JSValue
JSJavaScriptCallFrame::caller(ExecState
* exec
) const
133 return toJS(exec
, globalObject(), impl().caller());
136 JSValue
JSJavaScriptCallFrame::sourceID(ExecState
*) const
138 return jsNumber(impl().sourceID());
141 JSValue
JSJavaScriptCallFrame::line(ExecState
*) const
143 return jsNumber(impl().line());
146 JSValue
JSJavaScriptCallFrame::column(ExecState
*) const
148 return jsNumber(impl().column());
151 JSValue
JSJavaScriptCallFrame::functionName(ExecState
* exec
) const
153 return jsString(exec
, impl().functionName());
156 JSValue
JSJavaScriptCallFrame::scopeChain(ExecState
* exec
) const
158 if (!impl().scopeChain())
161 DebuggerScope
* scopeChain
= impl().scopeChain();
162 DebuggerScope::iterator iter
= scopeChain
->begin();
163 DebuggerScope::iterator end
= scopeChain
->end();
165 // We must always have something in the scope chain.
168 MarkedArgumentBuffer list
;
170 list
.append(iter
.get());
172 } while (iter
!= end
);
174 return constructArray(exec
, nullptr, globalObject(), list
);
177 JSValue
JSJavaScriptCallFrame::thisObject(ExecState
*) const
179 return impl().thisValue();
182 JSValue
JSJavaScriptCallFrame::type(ExecState
* exec
) const
184 switch (impl().type()) {
185 case DebuggerCallFrame::FunctionType
:
186 return jsNontrivialString(exec
, ASCIILiteral("function"));
187 case DebuggerCallFrame::ProgramType
:
188 return jsNontrivialString(exec
, ASCIILiteral("program"));
191 ASSERT_NOT_REACHED();
195 JSValue
toJS(ExecState
* exec
, JSGlobalObject
* globalObject
, JavaScriptCallFrame
* impl
)
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
);
204 return javaScriptCallFrame
;
207 JSJavaScriptCallFrame
* toJSJavaScriptCallFrame(JSValue value
)
209 return value
.inherits(JSJavaScriptCallFrame::info()) ? jsCast
<JSJavaScriptCallFrame
*>(value
) : nullptr;
212 } // namespace Inspector