OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (c) 2010, Google 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 are | |
6 * met: | |
7 * | |
8 * * Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * * Redistributions in binary form must reproduce the above | |
11 * copyright notice, this list of conditions and the following disclaimer | |
12 * in the documentation and/or other materials provided with the | |
13 * distribution. | |
14 * * Neither the name of Google Inc. nor the names of its | |
15 * contributors may be used to endorse or promote products derived from | |
16 * this software without specific prior written permission. | |
17 * | |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 */ | |
30 | |
31 #include "sky/engine/config.h" | |
32 #include "sky/engine/core/inspector/JavaScriptCallFrame.h" | |
33 | |
34 #include "sky/engine/bindings/core/v8/ScriptValue.h" | |
35 #include "sky/engine/bindings/core/v8/V8Binding.h" | |
36 #include "v8/include/v8-debug.h" | |
37 | |
38 namespace blink { | |
39 | |
40 JavaScriptCallFrame::JavaScriptCallFrame(v8::Handle<v8::Context> debuggerContext
, v8::Handle<v8::Object> callFrame) | |
41 : m_isolate(v8::Isolate::GetCurrent()) | |
42 , m_debuggerContext(m_isolate, debuggerContext) | |
43 , m_callFrame(m_isolate, callFrame) | |
44 { | |
45 } | |
46 | |
47 JavaScriptCallFrame::~JavaScriptCallFrame() | |
48 { | |
49 } | |
50 | |
51 JavaScriptCallFrame* JavaScriptCallFrame::caller() | |
52 { | |
53 if (!m_caller) { | |
54 v8::HandleScope handleScope(m_isolate); | |
55 v8::Handle<v8::Context> debuggerContext = m_debuggerContext.newLocal(m_i
solate); | |
56 v8::Context::Scope contextScope(debuggerContext); | |
57 v8::Handle<v8::Value> callerFrame = m_callFrame.newLocal(m_isolate)->Get
(v8AtomicString(m_isolate, "caller")); | |
58 if (callerFrame.IsEmpty() || !callerFrame->IsObject()) | |
59 return 0; | |
60 m_caller = JavaScriptCallFrame::create(debuggerContext, v8::Handle<v8::O
bject>::Cast(callerFrame)); | |
61 } | |
62 return m_caller.get(); | |
63 } | |
64 | |
65 int JavaScriptCallFrame::callV8FunctionReturnInt(const char* name) const | |
66 { | |
67 v8::HandleScope handleScope(m_isolate); | |
68 v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate)); | |
69 v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate); | |
70 v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(callFrame->Ge
t(v8AtomicString(m_isolate, name))); | |
71 v8::Handle<v8::Value> result = func->Call(callFrame, 0, 0); | |
72 if (result.IsEmpty() || !result->IsInt32()) | |
73 return 0; | |
74 return result->Int32Value(); | |
75 } | |
76 | |
77 String JavaScriptCallFrame::callV8FunctionReturnString(const char* name) const | |
78 { | |
79 v8::HandleScope handleScope(m_isolate); | |
80 v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate)); | |
81 v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate); | |
82 v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(callFrame->Ge
t(v8AtomicString(m_isolate, name))); | |
83 v8::Handle<v8::Value> result = func->Call(callFrame, 0, 0); | |
84 return toCoreStringWithUndefinedOrNullCheck(result); | |
85 } | |
86 | |
87 int JavaScriptCallFrame::sourceID() const | |
88 { | |
89 return callV8FunctionReturnInt("sourceID"); | |
90 } | |
91 | |
92 int JavaScriptCallFrame::line() const | |
93 { | |
94 return callV8FunctionReturnInt("line"); | |
95 } | |
96 | |
97 int JavaScriptCallFrame::column() const | |
98 { | |
99 return callV8FunctionReturnInt("column"); | |
100 } | |
101 | |
102 String JavaScriptCallFrame::scriptName() const | |
103 { | |
104 return callV8FunctionReturnString("scriptName"); | |
105 } | |
106 | |
107 String JavaScriptCallFrame::functionName() const | |
108 { | |
109 return callV8FunctionReturnString("functionName"); | |
110 } | |
111 | |
112 v8::Handle<v8::Value> JavaScriptCallFrame::scopeChain() const | |
113 { | |
114 v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate); | |
115 v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(callFrame->Ge
t(v8AtomicString(m_isolate, "scopeChain"))); | |
116 v8::Handle<v8::Array> scopeChain = v8::Handle<v8::Array>::Cast(func->Call(ca
llFrame, 0, 0)); | |
117 v8::Handle<v8::Array> result = v8::Array::New(m_isolate, scopeChain->Length(
)); | |
118 for (uint32_t i = 0; i < scopeChain->Length(); i++) | |
119 result->Set(i, scopeChain->Get(i)); | |
120 return result; | |
121 } | |
122 | |
123 int JavaScriptCallFrame::scopeType(int scopeIndex) const | |
124 { | |
125 v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate); | |
126 v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(callFrame->Ge
t(v8AtomicString(m_isolate, "scopeType"))); | |
127 v8::Handle<v8::Array> scopeType = v8::Handle<v8::Array>::Cast(func->Call(cal
lFrame, 0, 0)); | |
128 return scopeType->Get(scopeIndex)->Int32Value(); | |
129 } | |
130 | |
131 v8::Handle<v8::Value> JavaScriptCallFrame::thisObject() const | |
132 { | |
133 return m_callFrame.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "thisO
bject")); | |
134 } | |
135 | |
136 String JavaScriptCallFrame::stepInPositions() const | |
137 { | |
138 return callV8FunctionReturnString("stepInPositions"); | |
139 } | |
140 | |
141 bool JavaScriptCallFrame::isAtReturn() const | |
142 { | |
143 v8::HandleScope handleScope(m_isolate); | |
144 v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate)); | |
145 v8::Handle<v8::Value> result = m_callFrame.newLocal(m_isolate)->Get(v8Atomic
String(m_isolate, "isAtReturn")); | |
146 if (result.IsEmpty() || !result->IsBoolean()) | |
147 return false; | |
148 return result->BooleanValue(); | |
149 } | |
150 | |
151 v8::Handle<v8::Value> JavaScriptCallFrame::returnValue() const | |
152 { | |
153 return m_callFrame.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "retur
nValue")); | |
154 } | |
155 | |
156 v8::Handle<v8::Value> JavaScriptCallFrame::evaluateWithExceptionDetails(const St
ring& expression) | |
157 { | |
158 v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate); | |
159 v8::Handle<v8::Function> evalFunction = v8::Handle<v8::Function>::Cast(callF
rame->Get(v8AtomicString(m_isolate, "evaluate"))); | |
160 v8::Handle<v8::Value> argv[] = { v8String(m_debuggerContext.newLocal(m_isola
te)->GetIsolate(), expression) }; | |
161 v8::TryCatch tryCatch; | |
162 v8::Handle<v8::Value> result = evalFunction->Call(callFrame, WTF_ARRAY_LENGT
H(argv), argv); | |
163 | |
164 v8::Handle<v8::Object> wrappedResult = v8::Object::New(m_isolate); | |
165 if (tryCatch.HasCaught()) { | |
166 wrappedResult->Set(v8::String::NewFromUtf8(m_isolate, "result"), tryCatc
h.Exception()); | |
167 wrappedResult->Set(v8::String::NewFromUtf8(m_isolate, "exceptionDetails"
), createExceptionDetails(tryCatch.Message(), m_isolate)); | |
168 } else { | |
169 wrappedResult->Set(v8::String::NewFromUtf8(m_isolate, "result"), result)
; | |
170 wrappedResult->Set(v8::String::NewFromUtf8(m_isolate, "exceptionDetails"
), v8::Undefined(m_isolate)); | |
171 } | |
172 return wrappedResult; | |
173 } | |
174 | |
175 v8::Handle<v8::Value> JavaScriptCallFrame::restart() | |
176 { | |
177 v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate); | |
178 v8::Handle<v8::Function> restartFunction = v8::Handle<v8::Function>::Cast(ca
llFrame->Get(v8AtomicString(m_isolate, "restart"))); | |
179 v8::Debug::SetLiveEditEnabled(m_isolate, true); | |
180 v8::Handle<v8::Value> result = restartFunction->Call(callFrame, 0, 0); | |
181 v8::Debug::SetLiveEditEnabled(m_isolate, false); | |
182 return result; | |
183 } | |
184 | |
185 ScriptValue JavaScriptCallFrame::setVariableValue(ScriptState* scriptState, int
scopeNumber, const String& variableName, const ScriptValue& newValue) | |
186 { | |
187 ScriptState::Scope scriptScope(scriptState); | |
188 v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate); | |
189 v8::Handle<v8::Function> setVariableValueFunction = v8::Handle<v8::Function>
::Cast(callFrame->Get(v8AtomicString(m_isolate, "setVariableValue"))); | |
190 v8::Handle<v8::Value> argv[] = { | |
191 v8::Handle<v8::Value>(v8::Integer::New(m_isolate, scopeNumber)), | |
192 v8String(m_isolate, variableName), | |
193 newValue.v8Value() | |
194 }; | |
195 return ScriptValue(scriptState, setVariableValueFunction->Call(callFrame, WT
F_ARRAY_LENGTH(argv), argv)); | |
196 } | |
197 | |
198 v8::Handle<v8::Object> JavaScriptCallFrame::createExceptionDetails(v8::Handle<v8
::Message> message, v8::Isolate* isolate) | |
199 { | |
200 v8::Handle<v8::Object> exceptionDetails = v8::Object::New(isolate); | |
201 exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "text"), message->Get
()); | |
202 exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "url"), message->GetS
criptOrigin().ResourceName()); | |
203 exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "line"), v8::Integer:
:New(isolate, message->GetLineNumber())); | |
204 exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "column"), v8::Intege
r::New(isolate, message->GetStartColumn())); | |
205 if (!message->GetStackTrace().IsEmpty()) | |
206 exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "stackTrace"), me
ssage->GetStackTrace()->AsArray()); | |
207 else | |
208 exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "stackTrace"), v8
::Undefined(isolate)); | |
209 return exceptionDetails; | |
210 } | |
211 | |
212 } // namespace blink | |
OLD | NEW |