Chromium Code Reviews| 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); |
| } |