#include "config.h"
#include "core/inspector/JavaScriptCallFrame.h"
-#include "bindings/v8/ScriptValue.h"
-#include "bindings/v8/V8Binding.h"
+#include "bindings/core/v8/ScriptValue.h"
+#include "bindings/core/v8/V8Binding.h"
+#include <v8-debug.h>
-namespace WebCore {
+namespace blink {
JavaScriptCallFrame::JavaScriptCallFrame(v8::Handle<v8::Context> debuggerContext, v8::Handle<v8::Object> callFrame)
: m_isolate(v8::Isolate::GetCurrent())
, m_debuggerContext(m_isolate, debuggerContext)
, m_callFrame(m_isolate, callFrame)
{
- ScriptWrappable::init(this);
}
JavaScriptCallFrame::~JavaScriptCallFrame()
v8::Handle<v8::Context> debuggerContext = m_debuggerContext.newLocal(m_isolate);
v8::Context::Scope contextScope(debuggerContext);
v8::Handle<v8::Value> callerFrame = m_callFrame.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "caller"));
- if (!callerFrame->IsObject())
+ if (callerFrame.IsEmpty() || !callerFrame->IsObject())
return 0;
m_caller = JavaScriptCallFrame::create(debuggerContext, v8::Handle<v8::Object>::Cast(callerFrame));
}
int JavaScriptCallFrame::callV8FunctionReturnInt(const char* name) const
{
v8::HandleScope handleScope(m_isolate);
+ v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate));
v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate);
v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(callFrame->Get(v8AtomicString(m_isolate, name)));
v8::Handle<v8::Value> result = func->Call(callFrame, 0, 0);
- if (result->IsInt32())
- return result->Int32Value();
- return 0;
+ if (result.IsEmpty() || !result->IsInt32())
+ return 0;
+ return result->Int32Value();
}
String JavaScriptCallFrame::callV8FunctionReturnString(const char* name) const
{
v8::HandleScope handleScope(m_isolate);
+ v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate));
v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate);
v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(callFrame->Get(v8AtomicString(m_isolate, name)));
v8::Handle<v8::Value> result = func->Call(callFrame, 0, 0);
return callV8FunctionReturnInt("column");
}
+String JavaScriptCallFrame::scriptName() const
+{
+ return callV8FunctionReturnString("scriptName");
+}
+
String JavaScriptCallFrame::functionName() const
{
return callV8FunctionReturnString("functionName");
v8::HandleScope handleScope(m_isolate);
v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate));
v8::Handle<v8::Value> result = m_callFrame.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "isAtReturn"));
- if (result->IsBoolean())
- return result->BooleanValue();
- return false;
+ if (result.IsEmpty() || !result->IsBoolean())
+ return false;
+ return result->BooleanValue();
}
v8::Handle<v8::Value> JavaScriptCallFrame::returnValue() const
return m_callFrame.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "returnValue"));
}
-v8::Handle<v8::Value> JavaScriptCallFrame::evaluate(const String& expression)
+ScriptValue JavaScriptCallFrame::evaluateWithExceptionDetails(ScriptState* scriptState, const String& expression, const ScriptValue& scopeExtension)
{
+ ScriptState::Scope scriptScope(scriptState);
v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate);
v8::Handle<v8::Function> evalFunction = v8::Handle<v8::Function>::Cast(callFrame->Get(v8AtomicString(m_isolate, "evaluate")));
- v8::Handle<v8::Value> argv[] = { v8String(m_debuggerContext.newLocal(m_isolate)->GetIsolate(), expression) };
- return evalFunction->Call(callFrame, WTF_ARRAY_LENGTH(argv), argv);
+ v8::Handle<v8::Value> argv[] = {
+ v8String(m_debuggerContext.newLocal(m_isolate)->GetIsolate(), expression),
+ scopeExtension.isEmpty() ? v8::Handle<v8::Value>::Cast(v8::Undefined(m_isolate)) : scopeExtension.v8Value()
+ };
+ v8::TryCatch tryCatch;
+ v8::Handle<v8::Value> result = evalFunction->Call(callFrame, WTF_ARRAY_LENGTH(argv), argv);
+
+ v8::Handle<v8::Object> wrappedResult = v8::Object::New(m_isolate);
+ if (tryCatch.HasCaught()) {
+ wrappedResult->Set(v8::String::NewFromUtf8(m_isolate, "result"), tryCatch.Exception());
+ wrappedResult->Set(v8::String::NewFromUtf8(m_isolate, "exceptionDetails"), createExceptionDetails(tryCatch.Message(), m_isolate));
+ } else {
+ wrappedResult->Set(v8::String::NewFromUtf8(m_isolate, "result"), result);
+ wrappedResult->Set(v8::String::NewFromUtf8(m_isolate, "exceptionDetails"), v8::Undefined(m_isolate));
+ }
+ return ScriptValue(scriptState, wrappedResult);
}
v8::Handle<v8::Value> JavaScriptCallFrame::restart()
{
v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate);
v8::Handle<v8::Function> restartFunction = v8::Handle<v8::Function>::Cast(callFrame->Get(v8AtomicString(m_isolate, "restart")));
- v8::Debug::SetLiveEditEnabled(true);
+ v8::Debug::SetLiveEditEnabled(m_isolate, true);
v8::Handle<v8::Value> result = restartFunction->Call(callFrame, 0, 0);
- v8::Debug::SetLiveEditEnabled(false);
+ v8::Debug::SetLiveEditEnabled(m_isolate, false);
return result;
}
-v8::Handle<v8::Object> JavaScriptCallFrame::innerCallFrame()
-{
- return m_callFrame.newLocal(m_isolate);
-}
-
-ScriptValue JavaScriptCallFrame::setVariableValue(int scopeNumber, const String& variableName, const ScriptValue& newValue)
+ScriptValue JavaScriptCallFrame::setVariableValue(ScriptState* scriptState, int scopeNumber, const String& variableName, const ScriptValue& newValue)
{
+ ScriptState::Scope scriptScope(scriptState);
v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate);
v8::Handle<v8::Function> setVariableValueFunction = v8::Handle<v8::Function>::Cast(callFrame->Get(v8AtomicString(m_isolate, "setVariableValue")));
v8::Handle<v8::Value> argv[] = {
v8String(m_isolate, variableName),
newValue.v8Value()
};
- return ScriptValue(setVariableValueFunction->Call(callFrame, WTF_ARRAY_LENGTH(argv), argv), m_isolate);
+ return ScriptValue(scriptState, setVariableValueFunction->Call(callFrame, WTF_ARRAY_LENGTH(argv), argv));
+}
+
+v8::Handle<v8::Object> JavaScriptCallFrame::createExceptionDetails(v8::Handle<v8::Message> message, v8::Isolate* isolate)
+{
+ v8::Handle<v8::Object> exceptionDetails = v8::Object::New(isolate);
+ exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "text"), message->Get());
+ exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "url"), message->GetScriptOrigin().ResourceName());
+ exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "scriptId"), v8::Integer::New(isolate, message->GetScriptOrigin().ScriptID()->Value()));
+ exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "line"), v8::Integer::New(isolate, message->GetLineNumber()));
+ exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "column"), v8::Integer::New(isolate, message->GetStartColumn()));
+ if (!message->GetStackTrace().IsEmpty())
+ exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "stackTrace"), message->GetStackTrace()->AsArray());
+ else
+ exceptionDetails->Set(v8::String::NewFromUtf8(isolate, "stackTrace"), v8::Undefined(isolate));
+ return exceptionDetails;
+}
+
+void JavaScriptCallFrame::trace(Visitor* visitor)
+{
+ visitor->trace(m_caller);
}
-} // namespace WebCore
+} // namespace blink