| 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 |