| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2010, Google Inc. All rights reserved. | 2 * Copyright (c) 2010, Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 | 30 |
| 31 #include "config.h" | 31 #include "config.h" |
| 32 #include "core/inspector/JavaScriptCallFrame.h" | 32 #include "core/inspector/JavaScriptCallFrame.h" |
| 33 | 33 |
| 34 #include "bindings/core/v8/ScriptValue.h" | 34 #include "bindings/core/v8/ScriptValue.h" |
| 35 #include "bindings/core/v8/V8Binding.h" | 35 #include "bindings/core/v8/V8Binding.h" |
| 36 #include <v8-debug.h> | 36 #include <v8-debug.h> |
| 37 | 37 |
| 38 namespace blink { | 38 namespace blink { |
| 39 | 39 |
| 40 JavaScriptCallFrame::JavaScriptCallFrame(v8::Handle<v8::Context> debuggerContext
, v8::Handle<v8::Object> callFrame) | 40 JavaScriptCallFrame::JavaScriptCallFrame(v8::Local<v8::Context> debuggerContext,
v8::Local<v8::Object> callFrame) |
| 41 : m_isolate(v8::Isolate::GetCurrent()) | 41 : m_isolate(v8::Isolate::GetCurrent()) |
| 42 , m_debuggerContext(m_isolate, debuggerContext) | 42 , m_debuggerContext(m_isolate, debuggerContext) |
| 43 , m_callFrame(m_isolate, callFrame) | 43 , m_callFrame(m_isolate, callFrame) |
| 44 { | 44 { |
| 45 } | 45 } |
| 46 | 46 |
| 47 JavaScriptCallFrame::~JavaScriptCallFrame() | 47 JavaScriptCallFrame::~JavaScriptCallFrame() |
| 48 { | 48 { |
| 49 } | 49 } |
| 50 | 50 |
| 51 JavaScriptCallFrame* JavaScriptCallFrame::caller() | 51 JavaScriptCallFrame* JavaScriptCallFrame::caller() |
| 52 { | 52 { |
| 53 if (!m_caller) { | 53 if (!m_caller) { |
| 54 v8::HandleScope handleScope(m_isolate); | 54 v8::HandleScope handleScope(m_isolate); |
| 55 v8::Handle<v8::Context> debuggerContext = m_debuggerContext.newLocal(m_i
solate); | 55 v8::Local<v8::Context> debuggerContext = m_debuggerContext.newLocal(m_is
olate); |
| 56 v8::Context::Scope contextScope(debuggerContext); | 56 v8::Context::Scope contextScope(debuggerContext); |
| 57 v8::Handle<v8::Value> callerFrame = m_callFrame.newLocal(m_isolate)->Get
(v8AtomicString(m_isolate, "caller")); | 57 v8::Local<v8::Value> callerFrame = m_callFrame.newLocal(m_isolate)->Get(
v8AtomicString(m_isolate, "caller")); |
| 58 if (callerFrame.IsEmpty() || !callerFrame->IsObject()) | 58 if (callerFrame.IsEmpty() || !callerFrame->IsObject()) |
| 59 return 0; | 59 return 0; |
| 60 m_caller = JavaScriptCallFrame::create(debuggerContext, v8::Handle<v8::O
bject>::Cast(callerFrame)); | 60 m_caller = JavaScriptCallFrame::create(debuggerContext, v8::Local<v8::Ob
ject>::Cast(callerFrame)); |
| 61 } | 61 } |
| 62 return m_caller.get(); | 62 return m_caller.get(); |
| 63 } | 63 } |
| 64 | 64 |
| 65 int JavaScriptCallFrame::callV8FunctionReturnInt(const char* name) const | 65 int JavaScriptCallFrame::callV8FunctionReturnInt(const char* name) const |
| 66 { | 66 { |
| 67 v8::HandleScope handleScope(m_isolate); | 67 v8::HandleScope handleScope(m_isolate); |
| 68 v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate)); | 68 v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate)); |
| 69 v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate); | 69 v8::Local<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))); | 70 v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(callFrame->Get(
v8AtomicString(m_isolate, name))); |
| 71 v8::Handle<v8::Value> result = func->Call(callFrame, 0, 0); | 71 v8::Local<v8::Value> result = func->Call(callFrame, 0, 0); |
| 72 if (result.IsEmpty() || !result->IsInt32()) | 72 if (result.IsEmpty() || !result->IsInt32()) |
| 73 return 0; | 73 return 0; |
| 74 return result->Int32Value(); | 74 return result->Int32Value(); |
| 75 } | 75 } |
| 76 | 76 |
| 77 String JavaScriptCallFrame::callV8FunctionReturnString(const char* name) const | 77 String JavaScriptCallFrame::callV8FunctionReturnString(const char* name) const |
| 78 { | 78 { |
| 79 v8::HandleScope handleScope(m_isolate); | 79 v8::HandleScope handleScope(m_isolate); |
| 80 v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate)); | 80 v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate)); |
| 81 v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate); | 81 v8::Local<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))); | 82 v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(callFrame->Get(
v8AtomicString(m_isolate, name))); |
| 83 v8::Handle<v8::Value> result = func->Call(callFrame, 0, 0); | 83 v8::Local<v8::Value> result = func->Call(callFrame, 0, 0); |
| 84 return toCoreStringWithUndefinedOrNullCheck(result); | 84 return toCoreStringWithUndefinedOrNullCheck(result); |
| 85 } | 85 } |
| 86 | 86 |
| 87 int JavaScriptCallFrame::sourceID() const | 87 int JavaScriptCallFrame::sourceID() const |
| 88 { | 88 { |
| 89 return callV8FunctionReturnInt("sourceID"); | 89 return callV8FunctionReturnInt("sourceID"); |
| 90 } | 90 } |
| 91 | 91 |
| 92 int JavaScriptCallFrame::line() const | 92 int JavaScriptCallFrame::line() const |
| 93 { | 93 { |
| 94 return callV8FunctionReturnInt("line"); | 94 return callV8FunctionReturnInt("line"); |
| 95 } | 95 } |
| 96 | 96 |
| 97 int JavaScriptCallFrame::column() const | 97 int JavaScriptCallFrame::column() const |
| 98 { | 98 { |
| 99 return callV8FunctionReturnInt("column"); | 99 return callV8FunctionReturnInt("column"); |
| 100 } | 100 } |
| 101 | 101 |
| 102 String JavaScriptCallFrame::scriptName() const | 102 String JavaScriptCallFrame::scriptName() const |
| 103 { | 103 { |
| 104 return callV8FunctionReturnString("scriptName"); | 104 return callV8FunctionReturnString("scriptName"); |
| 105 } | 105 } |
| 106 | 106 |
| 107 String JavaScriptCallFrame::functionName() const | 107 String JavaScriptCallFrame::functionName() const |
| 108 { | 108 { |
| 109 return callV8FunctionReturnString("functionName"); | 109 return callV8FunctionReturnString("functionName"); |
| 110 } | 110 } |
| 111 | 111 |
| 112 v8::Handle<v8::Value> JavaScriptCallFrame::scopeChain() const | 112 v8::Local<v8::Value> JavaScriptCallFrame::scopeChain() const |
| 113 { | 113 { |
| 114 v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate); | 114 v8::Local<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"))); | 115 v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(callFrame->Get(
v8AtomicString(m_isolate, "scopeChain"))); |
| 116 v8::Handle<v8::Array> scopeChain = v8::Handle<v8::Array>::Cast(func->Call(ca
llFrame, 0, 0)); | 116 v8::Local<v8::Array> scopeChain = v8::Local<v8::Array>::Cast(func->Call(call
Frame, 0, 0)); |
| 117 v8::Handle<v8::Array> result = v8::Array::New(m_isolate, scopeChain->Length(
)); | 117 v8::Local<v8::Array> result = v8::Array::New(m_isolate, scopeChain->Length()
); |
| 118 for (uint32_t i = 0; i < scopeChain->Length(); i++) | 118 for (uint32_t i = 0; i < scopeChain->Length(); i++) |
| 119 result->Set(i, scopeChain->Get(i)); | 119 result->Set(i, scopeChain->Get(i)); |
| 120 return result; | 120 return result; |
| 121 } | 121 } |
| 122 | 122 |
| 123 int JavaScriptCallFrame::scopeType(int scopeIndex) const | 123 int JavaScriptCallFrame::scopeType(int scopeIndex) const |
| 124 { | 124 { |
| 125 v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate); | 125 v8::Local<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"))); | 126 v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(callFrame->Get(
v8AtomicString(m_isolate, "scopeType"))); |
| 127 v8::Handle<v8::Array> scopeType = v8::Handle<v8::Array>::Cast(func->Call(cal
lFrame, 0, 0)); | 127 v8::Local<v8::Array> scopeType = v8::Local<v8::Array>::Cast(func->Call(callF
rame, 0, 0)); |
| 128 return scopeType->Get(scopeIndex)->Int32Value(); | 128 return scopeType->Get(scopeIndex)->Int32Value(); |
| 129 } | 129 } |
| 130 | 130 |
| 131 v8::Handle<v8::Value> JavaScriptCallFrame::thisObject() const | 131 v8::Local<v8::Value> JavaScriptCallFrame::thisObject() const |
| 132 { | 132 { |
| 133 return m_callFrame.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "thisO
bject")); | 133 return m_callFrame.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "thisO
bject")); |
| 134 } | 134 } |
| 135 | 135 |
| 136 String JavaScriptCallFrame::stepInPositions() const | 136 String JavaScriptCallFrame::stepInPositions() const |
| 137 { | 137 { |
| 138 return callV8FunctionReturnString("stepInPositions"); | 138 return callV8FunctionReturnString("stepInPositions"); |
| 139 } | 139 } |
| 140 | 140 |
| 141 bool JavaScriptCallFrame::isAtReturn() const | 141 bool JavaScriptCallFrame::isAtReturn() const |
| 142 { | 142 { |
| 143 v8::HandleScope handleScope(m_isolate); | 143 v8::HandleScope handleScope(m_isolate); |
| 144 v8::Context::Scope contextScope(m_debuggerContext.newLocal(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")); | 145 v8::Local<v8::Value> result = m_callFrame.newLocal(m_isolate)->Get(v8AtomicS
tring(m_isolate, "isAtReturn")); |
| 146 if (result.IsEmpty() || !result->IsBoolean()) | 146 if (result.IsEmpty() || !result->IsBoolean()) |
| 147 return false; | 147 return false; |
| 148 return result->BooleanValue(); | 148 return result->BooleanValue(); |
| 149 } | 149 } |
| 150 | 150 |
| 151 v8::Handle<v8::Value> JavaScriptCallFrame::returnValue() const | 151 v8::Local<v8::Value> JavaScriptCallFrame::returnValue() const |
| 152 { | 152 { |
| 153 return m_callFrame.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "retur
nValue")); | 153 return m_callFrame.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "retur
nValue")); |
| 154 } | 154 } |
| 155 | 155 |
| 156 ScriptValue JavaScriptCallFrame::evaluateWithExceptionDetails(ScriptState* scrip
tState, const String& expression, const ScriptValue& scopeExtension) | 156 ScriptValue JavaScriptCallFrame::evaluateWithExceptionDetails(ScriptState* scrip
tState, const String& expression, const ScriptValue& scopeExtension) |
| 157 { | 157 { |
| 158 ScriptState::Scope scriptScope(scriptState); | 158 ScriptState::Scope scriptScope(scriptState); |
| 159 v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate); | 159 v8::Local<v8::Object> callFrame = m_callFrame.newLocal(m_isolate); |
| 160 v8::Handle<v8::Function> evalFunction = v8::Handle<v8::Function>::Cast(callF
rame->Get(v8AtomicString(m_isolate, "evaluate"))); | 160 v8::Local<v8::Function> evalFunction = v8::Local<v8::Function>::Cast(callFra
me->Get(v8AtomicString(m_isolate, "evaluate"))); |
| 161 v8::Handle<v8::Value> argv[] = { | 161 v8::Local<v8::Value> argv[] = { |
| 162 v8String(m_debuggerContext.newLocal(m_isolate)->GetIsolate(), expression
), | 162 v8String(m_debuggerContext.newLocal(m_isolate)->GetIsolate(), expression
), |
| 163 scopeExtension.isEmpty() ? v8::Handle<v8::Value>::Cast(v8::Undefined(m_i
solate)) : scopeExtension.v8Value() | 163 scopeExtension.isEmpty() ? v8::Handle<v8::Value>::Cast(v8::Undefined(m_i
solate)) : scopeExtension.v8Value() |
| 164 }; | 164 }; |
| 165 v8::TryCatch tryCatch; | 165 v8::TryCatch tryCatch; |
| 166 v8::Handle<v8::Value> result = evalFunction->Call(callFrame, WTF_ARRAY_LENGT
H(argv), argv); | 166 v8::Local<v8::Value> result = evalFunction->Call(callFrame, WTF_ARRAY_LENGTH
(argv), argv); |
| 167 | 167 |
| 168 v8::Handle<v8::Object> wrappedResult = v8::Object::New(m_isolate); | 168 v8::Local<v8::Object> wrappedResult = v8::Object::New(m_isolate); |
| 169 if (tryCatch.HasCaught()) { | 169 if (tryCatch.HasCaught()) { |
| 170 wrappedResult->Set(v8::String::NewFromUtf8(m_isolate, "result"), tryCatc
h.Exception()); | 170 wrappedResult->Set(v8::String::NewFromUtf8(m_isolate, "result"), tryCatc
h.Exception()); |
| 171 wrappedResult->Set(v8::String::NewFromUtf8(m_isolate, "exceptionDetails"
), createExceptionDetails(m_isolate, tryCatch.Message())); | 171 wrappedResult->Set(v8::String::NewFromUtf8(m_isolate, "exceptionDetails"
), createExceptionDetails(m_isolate, tryCatch.Message())); |
| 172 } else { | 172 } else { |
| 173 wrappedResult->Set(v8::String::NewFromUtf8(m_isolate, "result"), result)
; | 173 wrappedResult->Set(v8::String::NewFromUtf8(m_isolate, "result"), result)
; |
| 174 wrappedResult->Set(v8::String::NewFromUtf8(m_isolate, "exceptionDetails"
), v8::Undefined(m_isolate)); | 174 wrappedResult->Set(v8::String::NewFromUtf8(m_isolate, "exceptionDetails"
), v8::Undefined(m_isolate)); |
| 175 } | 175 } |
| 176 return ScriptValue(scriptState, wrappedResult); | 176 return ScriptValue(scriptState, wrappedResult); |
| 177 } | 177 } |
| 178 | 178 |
| 179 v8::Handle<v8::Value> JavaScriptCallFrame::restart() | 179 v8::Local<v8::Value> JavaScriptCallFrame::restart() |
| 180 { | 180 { |
| 181 v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate); | 181 v8::Local<v8::Object> callFrame = m_callFrame.newLocal(m_isolate); |
| 182 v8::Handle<v8::Function> restartFunction = v8::Handle<v8::Function>::Cast(ca
llFrame->Get(v8AtomicString(m_isolate, "restart"))); | 182 v8::Local<v8::Function> restartFunction = v8::Local<v8::Function>::Cast(call
Frame->Get(v8AtomicString(m_isolate, "restart"))); |
| 183 v8::Debug::SetLiveEditEnabled(m_isolate, true); | 183 v8::Debug::SetLiveEditEnabled(m_isolate, true); |
| 184 v8::Handle<v8::Value> result = restartFunction->Call(callFrame, 0, 0); | 184 v8::Local<v8::Value> result = restartFunction->Call(callFrame, 0, 0); |
| 185 v8::Debug::SetLiveEditEnabled(m_isolate, false); | 185 v8::Debug::SetLiveEditEnabled(m_isolate, false); |
| 186 return result; | 186 return result; |
| 187 } | 187 } |
| 188 | 188 |
| 189 ScriptValue JavaScriptCallFrame::setVariableValue(ScriptState* scriptState, int
scopeNumber, const String& variableName, const ScriptValue& newValue) | 189 ScriptValue JavaScriptCallFrame::setVariableValue(ScriptState* scriptState, int
scopeNumber, const String& variableName, const ScriptValue& newValue) |
| 190 { | 190 { |
| 191 ScriptState::Scope scriptScope(scriptState); | 191 ScriptState::Scope scriptScope(scriptState); |
| 192 v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate); | 192 v8::Local<v8::Object> callFrame = m_callFrame.newLocal(m_isolate); |
| 193 v8::Handle<v8::Function> setVariableValueFunction = v8::Handle<v8::Function>
::Cast(callFrame->Get(v8AtomicString(m_isolate, "setVariableValue"))); | 193 v8::Local<v8::Function> setVariableValueFunction = v8::Local<v8::Function>::
Cast(callFrame->Get(v8AtomicString(m_isolate, "setVariableValue"))); |
| 194 v8::Handle<v8::Value> argv[] = { | 194 v8::Local<v8::Value> argv[] = { |
| 195 v8::Handle<v8::Value>(v8::Integer::New(m_isolate, scopeNumber)), | 195 v8::Local<v8::Value>(v8::Integer::New(m_isolate, scopeNumber)), |
| 196 v8String(m_isolate, variableName), | 196 v8String(m_isolate, variableName), |
| 197 newValue.v8Value() | 197 newValue.v8Value() |
| 198 }; | 198 }; |
| 199 return ScriptValue(scriptState, setVariableValueFunction->Call(callFrame, WT
F_ARRAY_LENGTH(argv), argv)); | 199 return ScriptValue(scriptState, setVariableValueFunction->Call(callFrame, WT
F_ARRAY_LENGTH(argv), argv)); |
| 200 } | 200 } |
| 201 | 201 |
| 202 v8::Handle<v8::Object> JavaScriptCallFrame::createExceptionDetails(v8::Isolate*
isolate, v8::Handle<v8::Message> message) | 202 v8::Local<v8::Object> JavaScriptCallFrame::createExceptionDetails(v8::Isolate* i
solate, v8::Local<v8::Message> message) |
| 203 { | 203 { |
| 204 v8::Handle<v8::Object> exceptionDetails = v8::Object::New(isolate); | 204 v8::Local<v8::Object> exceptionDetails = v8::Object::New(isolate); |
| 205 exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "text"), message->Get
()); | 205 exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "text"), message->Get
()); |
| 206 exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "url"), message->GetS
criptOrigin().ResourceName()); | 206 exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "url"), message->GetS
criptOrigin().ResourceName()); |
| 207 exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "scriptId"), v8::Inte
ger::New(isolate, message->GetScriptOrigin().ScriptID()->Value())); | 207 exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "scriptId"), v8::Inte
ger::New(isolate, message->GetScriptOrigin().ScriptID()->Value())); |
| 208 exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "line"), v8::Integer:
:New(isolate, message->GetLineNumber())); | 208 exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "line"), v8::Integer:
:New(isolate, message->GetLineNumber())); |
| 209 exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "column"), v8::Intege
r::New(isolate, message->GetStartColumn())); | 209 exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "column"), v8::Intege
r::New(isolate, message->GetStartColumn())); |
| 210 if (!message->GetStackTrace().IsEmpty()) | 210 if (!message->GetStackTrace().IsEmpty()) |
| 211 exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "stackTrace"), me
ssage->GetStackTrace()->AsArray()); | 211 exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "stackTrace"), me
ssage->GetStackTrace()->AsArray()); |
| 212 else | 212 else |
| 213 exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "stackTrace"), v8
::Undefined(isolate)); | 213 exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "stackTrace"), v8
::Undefined(isolate)); |
| 214 return exceptionDetails; | 214 return exceptionDetails; |
| 215 } | 215 } |
| 216 | 216 |
| 217 void JavaScriptCallFrame::trace(Visitor* visitor) | 217 void JavaScriptCallFrame::trace(Visitor* visitor) |
| 218 { | 218 { |
| 219 visitor->trace(m_caller); | 219 visitor->trace(m_caller); |
| 220 } | 220 } |
| 221 | 221 |
| 222 } // namespace blink | 222 } // namespace blink |
| OLD | NEW |