Index: Source/bindings/dart/DartDebugServer.cpp |
diff --git a/Source/bindings/dart/DartDebugServer.cpp b/Source/bindings/dart/DartDebugServer.cpp |
index 3a44ed13b4c6ef6de5eb2a9b8cdf0a8d2a2e9393..6b39ef3e42aab7f77174f247869e281e0b97c8ff 100644 |
--- a/Source/bindings/dart/DartDebugServer.cpp |
+++ b/Source/bindings/dart/DartDebugServer.cpp |
@@ -215,23 +215,27 @@ v8::Handle<v8::Object> DartDebugServer::createExecutionState(Dart_StackTrace tra |
result = Dart_GetActivationFrame(trace, i, &frame); |
ASSERT(!Dart_IsError(result)); |
Dart_Handle functionName = 0; |
+ Dart_Handle function = 0; |
Dart_Handle scriptURL = 0; |
intptr_t lineNumber = 0; |
intptr_t libraryId = 0; |
- result = Dart_ActivationFrameInfo(frame, &functionName, &scriptURL, &lineNumber, &libraryId); |
+ result = Dart_ActivationFrameInfo(frame, &functionName, &function, &scriptURL, &lineNumber, &libraryId); |
ASSERT(!Dart_IsError(result)); |
Dart_Handle libraryURL = Dart_GetLibraryURL(libraryId); |
ASSERT(!Dart_IsError(libraryURL)); |
Dart_Handle library = Dart_LookupLibrary(libraryURL); |
+ Dart_Handle localVariablesHandle = Dart_GetLocalVariables(frame); |
v8::Local<v8::Object> callFrame = v8::Object::New(); |
callFrame->Set(v8::String::New("functionName"), V8Converter::stringToV8(functionName)); |
+ callFrame->Set(v8::String::New("functionProxy"), DartHandleProxy::create(function)); |
callFrame->Set(v8::String::New("scriptURL"), V8Converter::stringToV8(scriptURL)); |
callFrame->Set(v8::String::New("lineNumber"), v8::Number::New(lineNumber - 1)); |
callFrame->Set(v8::String::New("libraryProxy"), DartHandleProxy::createLibraryProxy(library, libraryId, Dart_Null())); |
callFrame->Set(v8::String::New("localScopeProxy"), DartHandleProxy::createLocalScopeProxy( |
- Dart_GetLocalVariables(frame))); |
+ localVariablesHandle)); |
+ callFrame->Set(v8::String::New("localVariables"), DartHandleProxy::create(localVariablesHandle)); |
callFrame->Set(v8::String::New("isolateHandle"), v8::Number::New(isolateHandle)); |
callFrames->Set(i, callFrame); |
} |
@@ -406,51 +410,56 @@ static void stepOut(const v8::FunctionCallbackInfo<v8::Value>& args) |
static void evaluateInScope(const v8::FunctionCallbackInfo<v8::Value>& args) |
{ |
v8::Handle<v8::String> expression = args[0]->ToString(); |
- v8::Handle<v8::Object> receiver = args[1].As<v8::Object>(); |
- v8::Handle<v8::Value> scopeObjectGlobal = args[2]; |
- v8::Handle<v8::Value> scopeObjectLocal = args[3]; |
- v8::Handle<v8::Value> scopes[] = { scopeObjectGlobal, scopeObjectLocal }; |
+ v8::Handle<v8::Value> receiver = args[1]; |
+ v8::Handle<v8::Object> functionProxy = args[2].As<v8::Object>(); |
+ v8::Handle<v8::Value> localVariablesProxy = args[3]; |
+ DartScopes scopes(functionProxy); |
+ Dart_Handle target = 0; |
if (receiver->IsNull() || receiver->IsUndefined()) { |
- // There is no receiver which indicates we are in a static method |
- // scope in Dart. We should ignore the receiver for this case. |
- // Using null or undefined as the receiver for a function triggers |
- // asserts in V8 while running in Debug mode if an exception occurs. |
- receiver = v8::Object::New(); |
- expression = v8::String::Concat(v8::String::New( |
- "(function($$scopeObjectGlobal, $$scopeObjectLocal) { " |
- "with ($$scopeObjectGlobal) with($$scopeObjectLocal) { " |
- "return "), |
- expression); |
- expression = v8::String::Concat(expression, v8::String::New("} })")); |
+ Dart_Handle functionHandle = scopes.handle; |
+ ASSERT(Dart_IsFunction(functionHandle)); |
+ target = Dart_FunctionOwner(functionHandle); |
} else { |
- expression = v8::String::Concat(v8::String::New( |
- "(function($$scopeObjectGlobal, $$scopeObjectLocal) { " |
- "with ($$scopeObjectGlobal) with (this) with($$scopeObjectLocal) { " |
- "return "), |
- expression); |
- expression = v8::String::Concat(expression, v8::String::New("} })")); |
+ target = DartHandleProxy::unwrapValue(receiver); |
} |
+ ASSERT(!Dart_IsError(target)); |
+ Dart_Handle localVariables = DartHandleProxy::unwrapValue(localVariablesProxy); |
+ ASSERT(Dart_IsList(localVariables)); |
+ intptr_t localVariablesLength = 0; |
+ Dart_ListLength(localVariables, &localVariablesLength); |
+ |
+ Dart_Handle wrapExpressionArgs[2] = { V8Converter::stringToDart(expression), localVariables }; |
+ |
+ Dart_Handle wrappedExpressionTuple = |
+ DartUtilities::invokeUtilsMethod("wrapExpressionAsClosure", 2, wrapExpressionArgs); |
+ ASSERT(Dart_IsList(wrappedExpressionTuple)); |
+ Dart_Handle wrappedExpression = Dart_ListGetAt(wrappedExpressionTuple, 0); |
+ Dart_Handle wrappedExpressionArgs = Dart_ListGetAt(wrappedExpressionTuple, 1); |
+ |
+ ASSERT(Dart_IsString(wrappedExpression)); |
+ Dart_Handle closure = Dart_EvaluateExpr(target, wrappedExpression); |
+ if (Dart_IsError(closure)) { |
+ // There was a parse error. FIXME: consider cleaning up the line |
+ // numbers in the error message. |
+ V8ThrowException::throwError(v8::String::New(Dart_GetError(closure))); |
+ } else { |
+ // Invoke the closure passing in the |
vsm
2013/09/12 00:17:23
Finish the comment. :-)
Jacob
2013/09/17 21:44:43
Done.
|
+ ASSERT(Dart_IsClosure(closure)); |
+ intptr_t length = 0; |
+ Dart_ListLength(wrappedExpressionArgs, &length); |
+ Vector<Dart_Handle> dartFunctionArgs; |
+ for (uint32_t i = 0; i < length; i ++) { |
+ dartFunctionArgs.append(Dart_ListGetAt(wrappedExpressionArgs, i)); |
+ } |
- v8::TryCatch tryCatch; |
- v8::Handle<v8::Function> function = V8ScriptRunner::compileAndRunInternalScript(expression, args.GetIsolate()).As<v8::Function>(); |
- |
- if (tryCatch.HasCaught()) { |
- v8SetReturnValue(args, tryCatch.ReThrow()); |
- return; |
- } |
- |
- v8::Local<v8::Value> result = V8ScriptRunner::callFunction( |
- function, getScriptExecutionContext(), |
- receiver, |
- 2, scopes); |
- |
- if (tryCatch.HasCaught()) { |
- v8SetReturnValue(args, tryCatch.ReThrow()); |
- return; |
+ Dart_Handle result = Dart_InvokeClosure(closure, dartFunctionArgs.size(), dartFunctionArgs.data()); |
+ if (Dart_IsError(result)) { |
+ V8ThrowException::throwError(v8::String::New(Dart_GetError(result))); |
+ } else { |
+ v8SetReturnValue(args, DartHandleProxy::create(result)); |
+ } |
} |
- crashIfV8IsDead(); |
- v8SetReturnValue(args, result); |
} |
void DartDebugServer::ensureHooksInstalled() |
@@ -487,6 +496,15 @@ void DartDebugServer::ensureHooksInstalled() |
nativeCallbacks->Set(v8::String::New("stepOver"), v8::FunctionTemplate::New(&stepOver)->GetFunction()); |
nativeCallbacks->Set(v8::String::New("stepOut"), v8::FunctionTemplate::New(&stepOut)->GetFunction()); |
nativeCallbacks->Set(v8::String::New("evaluateInScope"), evaluateInScopeFunction); |
+ { |
+ // Trampoline script is required to properly set calling context before |
+ // invoking Dart code because of security checks in console.log |
+ // implementation (see InjectedScriptManager::canAccessInspectedWindow). |
+ V8Scope v8scope; |
+ v8::Handle<v8::String> trampolineScript = v8::String::New("(function (func, args) { return func.apply(this, args); })"); |
+ v8::Local<v8::Function> trampoline = v8::Local<v8::Function>::Cast(v8::Script::Compile(trampolineScript)->Run()); |
+ nativeCallbacks->Set(v8::String::New("invocationTrampoline"), trampoline); |
+ } |
dartDebugObject()->Set(v8::String::New("nativeCallbacks"), nativeCallbacks); |
} |