Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / inspector / JavaScriptCallFrame.cpp
index 38032cc..a6948aa 100644 (file)
 #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()
@@ -55,54 +55,65 @@ JavaScriptCallFrame* JavaScriptCallFrame::caller()
         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));
     }
     return m_caller.get();
 }
 
-int JavaScriptCallFrame::sourceID() const
+int JavaScriptCallFrame::callV8FunctionReturnInt(const char* name) const
 {
     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, "sourceID"));
-    if (result->IsInt32())
-        return result->Int32Value();
-    return 0;
+    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.IsEmpty() || !result->IsInt32())
+        return 0;
+    return result->Int32Value();
 }
 
-int JavaScriptCallFrame::line() const
+String JavaScriptCallFrame::callV8FunctionReturnString(const char* name) const
 {
     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, "line"));
-    if (result->IsInt32())
-        return result->Int32Value();
-    return 0;
+    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 toCoreStringWithUndefinedOrNullCheck(result);
+}
+
+int JavaScriptCallFrame::sourceID() const
+{
+    return callV8FunctionReturnInt("sourceID");
+}
+
+int JavaScriptCallFrame::line() const
+{
+    return callV8FunctionReturnInt("line");
 }
 
 int JavaScriptCallFrame::column() const
 {
-    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, "column"));
-    if (result->IsInt32())
-        return result->Int32Value();
-    return 0;
+    return callV8FunctionReturnInt("column");
+}
+
+String JavaScriptCallFrame::scriptName() const
+{
+    return callV8FunctionReturnString("scriptName");
 }
 
 String JavaScriptCallFrame::functionName() const
 {
-    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, "functionName"));
-    return toCoreStringWithUndefinedOrNullCheck(result);
+    return callV8FunctionReturnString("functionName");
 }
 
 v8::Handle<v8::Value> JavaScriptCallFrame::scopeChain() const
 {
-    v8::Handle<v8::Array> scopeChain = v8::Handle<v8::Array>::Cast(m_callFrame.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "scopeChain")));
+    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, "scopeChain")));
+    v8::Handle<v8::Array> scopeChain = v8::Handle<v8::Array>::Cast(func->Call(callFrame, 0, 0));
     v8::Handle<v8::Array> result = v8::Array::New(m_isolate, scopeChain->Length());
     for (uint32_t i = 0; i < scopeChain->Length(); i++)
         result->Set(i, scopeChain->Get(i));
@@ -122,10 +133,7 @@ v8::Handle<v8::Value> JavaScriptCallFrame::thisObject() const
 
 String JavaScriptCallFrame::stepInPositions() const
 {
-    v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate);
-    v8::Handle<v8::Function> stepInPositions = v8::Handle<v8::Function>::Cast(callFrame->Get(v8AtomicString(m_isolate, "stepInPositions")));
-    v8::Handle<v8::Value> result = stepInPositions->Call(callFrame, 0, 0);
-    return toCoreStringWithUndefinedOrNullCheck(result);
+    return callV8FunctionReturnString("stepInPositions");
 }
 
 bool JavaScriptCallFrame::isAtReturn() const
@@ -133,9 +141,9 @@ bool JavaScriptCallFrame::isAtReturn() const
     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
@@ -143,31 +151,38 @@ 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)
+v8::Handle<v8::Value> JavaScriptCallFrame::evaluateWithExceptionDetails(const String& expression)
 {
     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, 1, argv);
+    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 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[] = {
@@ -175,7 +190,26 @@ ScriptValue JavaScriptCallFrame::setVariableValue(int scopeNumber, const String&
         v8String(m_isolate, variableName),
         newValue.v8Value()
     };
-    return ScriptValue(setVariableValueFunction->Call(callFrame, 3, 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, "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