Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(340)

Unified Diff: Source/bindings/dart/DartDebugServer.cpp

Issue 23710032: Switch the DevTools to support a true Dart REPL (Closed) Base URL: svn://svn.chromium.org/multivm/trunk/webkit
Patch Set: PTAL Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/bindings/dart/DartDebugHooks.js ('k') | Source/bindings/dart/DartHandleProxy.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/bindings/dart/DartDebugServer.cpp
diff --git a/Source/bindings/dart/DartDebugServer.cpp b/Source/bindings/dart/DartDebugServer.cpp
index 3a44ed13b4c6ef6de5eb2a9b8cdf0a8d2a2e9393..8136fe259d4865bd382c649504bdede38a9e6350 100644
--- a/Source/bindings/dart/DartDebugServer.cpp
+++ b/Source/bindings/dart/DartDebugServer.cpp
@@ -199,6 +199,45 @@ void DartDebugServer::disable()
disable->Call(dartDebugObject(), 0, 0);
}
+bool lookupTokenLineNumber(const Dart_CodeLocation& location, int* lineNumber, int* columnNumber)
+{
+ Dart_Handle info = Dart_ScriptGetTokenInfo(location.library_id, location.script_url);
+ ASSERT(Dart_IsList(info));
+ intptr_t infoLength = 0;
+ Dart_Handle res = Dart_ListLength(info, &infoLength);
+ ASSERT(!Dart_IsError(res));
+ Dart_Handle elem;
+ bool lineStart = true;
+ int currentLineNumber = 0;
+ for (intptr_t i = 0; i < infoLength; i++) {
+ elem = Dart_ListGetAt(info, i);
+ if (Dart_IsNull(elem)) {
+ lineStart = true;
+ } else {
+ ASSERT(Dart_IsInteger(elem));
+ Dart_Handle exception = 0;
+ int64_t value = DartUtilities::toInteger(elem, exception);
+ ASSERT(!exception);
+ if (lineStart) {
+ // Line number.
+ currentLineNumber = value;
+ lineStart = false;
+ } else {
+ // Token offset.
+ if (value == location.token_pos) {
+ *lineNumber = currentLineNumber;
+ ASSERT(i + 1 < infoLength);
+ *columnNumber = DartUtilities::toInteger(Dart_ListGetAt(info, i + 1), exception);
+ ASSERT(!exception);
+ return true;
+ }
+ i++; // skip columnNumber.
+ }
+ }
+ }
+ return false;
+}
+
v8::Handle<v8::Object> DartDebugServer::createExecutionState(Dart_StackTrace trace)
{
intptr_t length = 0;
@@ -210,28 +249,34 @@ v8::Handle<v8::Object> DartDebugServer::createExecutionState(Dart_StackTrace tra
int isolateHandle = isolateMap().getByValue(Dart_CurrentIsolate());
v8::Local<v8::Array> callFrames = v8::Array::New(length);
- for (int i = length - 1; i >=0; --i) {
+ for (int i = length - 1; i >= 0; --i) {
Dart_ActivationFrame frame = 0;
result = Dart_GetActivationFrame(trace, i, &frame);
ASSERT(!Dart_IsError(result));
Dart_Handle functionName = 0;
- Dart_Handle scriptURL = 0;
- intptr_t lineNumber = 0;
- intptr_t libraryId = 0;
+ Dart_Handle function = 0;
- result = Dart_ActivationFrameInfo(frame, &functionName, &scriptURL, &lineNumber, &libraryId);
+ Dart_CodeLocation location;
+ result = Dart_ActivationFrameGetLocation(frame, &functionName, &function, &location);
+ int lineNumber = 0;
+ int columnNumber = 0;
+ lookupTokenLineNumber(location, &lineNumber, &columnNumber);
ASSERT(!Dart_IsError(result));
- Dart_Handle libraryURL = Dart_GetLibraryURL(libraryId);
+ Dart_Handle libraryURL = Dart_GetLibraryURL(location.library_id);
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("scriptURL"), V8Converter::stringToV8(scriptURL));
+ callFrame->Set(v8::String::New("functionProxy"), DartHandleProxy::create(function));
+ callFrame->Set(v8::String::New("scriptURL"), V8Converter::stringToV8(location.script_url));
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("columnNumber"), v8::Number::New(columnNumber - 1));
+ callFrame->Set(v8::String::New("libraryProxy"), DartHandleProxy::createLibraryProxy(library, location.library_id, 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 +451,57 @@ 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 expression arguments specified by
+ // wrappedExpressionTuple.
+ 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 +538,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);
}
« no previous file with comments | « Source/bindings/dart/DartDebugHooks.js ('k') | Source/bindings/dart/DartHandleProxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698