| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2010-2011 Google Inc. All rights reserved. | 2 * Copyright (c) 2010-2011 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "config.h" | 31 #include "config.h" |
| 32 #include "bindings/v8/ScriptDebugServer.h" | 32 #include "bindings/v8/ScriptDebugServer.h" |
| 33 | 33 |
| 34 | 34 |
| 35 #include "DebuggerScriptSource.h" | 35 #include "DebuggerScriptSource.h" |
| 36 #include "V8JavaScriptCallFrame.h" | 36 #include "V8JavaScriptCallFrame.h" |
| 37 #include "bindings/v8/ScopedPersistent.h" | 37 #include "bindings/v8/ScopedPersistent.h" |
| 38 #include "bindings/v8/ScriptController.h" |
| 38 #include "bindings/v8/ScriptObject.h" | 39 #include "bindings/v8/ScriptObject.h" |
| 39 #include "bindings/v8/V8Binding.h" | 40 #include "bindings/v8/V8Binding.h" |
| 40 #include "bindings/v8/V8RecursionScope.h" | 41 #include "bindings/v8/V8RecursionScope.h" |
| 41 #include "bindings/v8/V8ScriptRunner.h" | 42 #include "bindings/v8/V8ScriptRunner.h" |
| 42 #include "core/inspector/JavaScriptCallFrame.h" | 43 #include "core/inspector/JavaScriptCallFrame.h" |
| 43 #include "core/inspector/ScriptDebugListener.h" | 44 #include "core/inspector/ScriptDebugListener.h" |
| 44 #include "wtf/StdLibExtras.h" | 45 #include "wtf/StdLibExtras.h" |
| 45 #include "wtf/Vector.h" | 46 #include "wtf/Vector.h" |
| 46 | 47 |
| 47 namespace WebCore { | 48 namespace WebCore { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 59 | 60 |
| 60 } | 61 } |
| 61 | 62 |
| 62 v8::Local<v8::Value> ScriptDebugServer::callDebuggerMethod(const char* functionN
ame, int argc, v8::Handle<v8::Value> argv[]) | 63 v8::Local<v8::Value> ScriptDebugServer::callDebuggerMethod(const char* functionN
ame, int argc, v8::Handle<v8::Value> argv[]) |
| 63 { | 64 { |
| 64 v8::Handle<v8::Function> function = v8::Local<v8::Function>::Cast(m_debugger
Script.get()->Get(v8::String::NewSymbol(functionName))); | 65 v8::Handle<v8::Function> function = v8::Local<v8::Function>::Cast(m_debugger
Script.get()->Get(v8::String::NewSymbol(functionName))); |
| 65 ASSERT(v8::Context::InContext()); | 66 ASSERT(v8::Context::InContext()); |
| 66 return V8ScriptRunner::callInternalFunction(function, v8::Context::GetCurren
t(), m_debuggerScript.get(), argc, argv, m_isolate); | 67 return V8ScriptRunner::callInternalFunction(function, v8::Context::GetCurren
t(), m_debuggerScript.get(), argc, argv, m_isolate); |
| 67 } | 68 } |
| 68 | 69 |
| 69 class ScriptDebugServer::ScriptPreprocessor { | |
| 70 WTF_MAKE_NONCOPYABLE(ScriptPreprocessor); | |
| 71 public: | |
| 72 ScriptPreprocessor(const String& preprocessorScript, v8::Isolate* isolate) | |
| 73 : m_isolate(isolate) | |
| 74 { | |
| 75 v8::HandleScope scope(m_isolate); | |
| 76 | |
| 77 v8::Local<v8::Context> context = v8::Context::New(m_isolate); | |
| 78 if (context.IsEmpty()) | |
| 79 return; | |
| 80 | |
| 81 String wrappedScript = "(" + preprocessorScript + ")"; | |
| 82 v8::Handle<v8::String> preprocessor = v8::String::New(wrappedScript.utf8
().data(), wrappedScript.utf8().length()); | |
| 83 | |
| 84 v8::Local<v8::Value> preprocessorFunction = V8ScriptRunner::compileAndRu
nInternalScript(preprocessor, m_isolate, context); | |
| 85 if (preprocessorFunction.IsEmpty() || !preprocessorFunction->IsFunction(
)) | |
| 86 return; | |
| 87 | |
| 88 m_utilityContext.set(isolate, context); | |
| 89 m_preprocessorFunction.set(isolate, v8::Handle<v8::Function>::Cast(prepr
ocessorFunction)); | |
| 90 } | |
| 91 | |
| 92 String preprocessSourceCode(const String& sourceCode, const String& sourceNa
me) | |
| 93 { | |
| 94 v8::HandleScope handleScope(m_isolate); | |
| 95 | |
| 96 if (m_preprocessorFunction.isEmpty()) | |
| 97 return sourceCode; | |
| 98 | |
| 99 v8::Local<v8::Context> context = v8::Local<v8::Context>::New(m_utilityCo
ntext.get()); | |
| 100 v8::Context::Scope contextScope(context); | |
| 101 | |
| 102 v8::Handle<v8::String> sourceCodeString = v8::String::New(sourceCode.utf
8().data(), sourceCode.utf8().length()); | |
| 103 | |
| 104 v8::Handle<v8::String> sourceNameString = v8::String::New(sourceName.utf
8().data(), sourceName.utf8().length()); | |
| 105 v8::Handle<v8::Value> argv[] = { sourceCodeString, sourceNameString }; | |
| 106 | |
| 107 v8::TryCatch tryCatch; | |
| 108 V8RecursionScope::MicrotaskSuppression recursionScope; | |
| 109 v8::Handle<v8::Value> resultValue = m_preprocessorFunction.newLocal(m_is
olate)->Call(context->Global(), 2, argv); | |
| 110 | |
| 111 if (tryCatch.HasCaught()) | |
| 112 return sourceCode; | |
| 113 | |
| 114 if (resultValue->IsString()) { | |
| 115 v8::String::Utf8Value utf8Value(resultValue); | |
| 116 return String::fromUTF8(*utf8Value, utf8Value.length()); | |
| 117 } | |
| 118 | |
| 119 return sourceCode; | |
| 120 } | |
| 121 | |
| 122 ~ScriptPreprocessor() | |
| 123 { | |
| 124 } | |
| 125 | |
| 126 private: | |
| 127 ScopedPersistent<v8::Context> m_utilityContext; | |
| 128 String m_preprocessorBody; | |
| 129 ScopedPersistent<v8::Function> m_preprocessorFunction; | |
| 130 v8::Isolate* m_isolate; | |
| 131 }; | |
| 132 | |
| 133 ScriptDebugServer::ScriptDebugServer(v8::Isolate* isolate) | 70 ScriptDebugServer::ScriptDebugServer(v8::Isolate* isolate) |
| 134 : m_pauseOnExceptionsState(DontPauseOnExceptions) | 71 : m_pauseOnExceptionsState(DontPauseOnExceptions) |
| 135 , m_breakpointsActivated(true) | 72 , m_breakpointsActivated(true) |
| 136 , m_runningNestedMessageLoop(false) | 73 , m_runningNestedMessageLoop(false) |
| 137 , m_isolate(isolate) | 74 , m_isolate(isolate) |
| 138 { | 75 { |
| 139 } | 76 } |
| 140 | 77 |
| 141 ScriptDebugServer::~ScriptDebugServer() | 78 ScriptDebugServer::~ScriptDebugServer() |
| 142 { | 79 { |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 return true; | 267 return true; |
| 331 } | 268 } |
| 332 | 269 |
| 333 | 270 |
| 334 void ScriptDebugServer::updateCallStack(ScriptValue* callFrame) | 271 void ScriptDebugServer::updateCallStack(ScriptValue* callFrame) |
| 335 { | 272 { |
| 336 if (isPaused()) | 273 if (isPaused()) |
| 337 *callFrame = currentCallFrame(); | 274 *callFrame = currentCallFrame(); |
| 338 } | 275 } |
| 339 | 276 |
| 277 ScriptController* ScriptDebugServer::scriptController(v8::Handle<v8::Context> co
ntext) |
| 278 { |
| 279 return 0; |
| 280 } |
| 340 | 281 |
| 341 void ScriptDebugServer::setScriptPreprocessor(const String& preprocessorBody) | 282 void ScriptDebugServer::preprocess(v8::Handle<v8::Context> eventContext, v8::Han
dle<v8::Object> eventData) |
| 342 { | 283 { |
| 343 m_scriptPreprocessor.clear(); | 284 v8::Local<v8::Context> debugContext = v8::Debug::GetDebugContext(); |
| 344 if (!preprocessorBody.isEmpty()) | 285 v8::Context::Scope contextScope(debugContext); |
| 345 m_scriptPreprocessor = adoptPtr(new ScriptPreprocessor(preprocessorBody,
m_isolate)); | 286 |
| 287 v8::Handle<v8::Value> argvEventData[] = { eventData }; |
| 288 String typeInfo = toWebCoreStringWithUndefinedOrNullCheck(callDebuggerMethod
("getScriptCompilationTypeInfo", 1, argvEventData)); |
| 289 if (!typeInfo.startsWith("eval")) |
| 290 return; |
| 291 |
| 292 String scriptName = toWebCoreStringWithUndefinedOrNullCheck(callDebuggerMeth
od("getScriptName", 1, argvEventData)); |
| 293 String script = toWebCoreStringWithUndefinedOrNullCheck(callDebuggerMethod("
getScriptSource", 1, argvEventData)); |
| 294 ScriptController* controller = scriptController(eventContext); |
| 295 if (!controller) |
| 296 return; |
| 297 |
| 298 String patchedScript = controller->preprocess(script, scriptName); |
| 299 |
| 300 v8::Handle<v8::Value> argv2[] = { eventData, v8String(patchedScript, debugCo
ntext->GetIsolate()) }; |
| 301 callDebuggerMethod("setScriptSource", 2, argv2); |
| 346 } | 302 } |
| 347 | 303 |
| 348 ScriptValue ScriptDebugServer::currentCallFrame() | 304 ScriptValue ScriptDebugServer::currentCallFrame() |
| 349 { | 305 { |
| 350 ASSERT(isPaused()); | 306 ASSERT(isPaused()); |
| 351 v8::Handle<v8::Value> argv[] = { m_executionState.get() }; | 307 v8::Handle<v8::Value> argv[] = { m_executionState.get() }; |
| 352 v8::Handle<v8::Value> currentCallFrameV8 = callDebuggerMethod("currentCallFr
ame", 1, argv); | 308 v8::Handle<v8::Value> currentCallFrameV8 = callDebuggerMethod("currentCallFr
ame", 1, argv); |
| 353 | 309 |
| 354 ASSERT(!currentCallFrameV8.IsEmpty()); | 310 ASSERT(!currentCallFrameV8.IsEmpty()); |
| 355 if (!currentCallFrameV8->IsObject()) | 311 if (!currentCallFrameV8->IsObject()) |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 424 if (event != v8::Break && event != v8::Exception && event != v8::AfterCompil
e && event != v8::BeforeCompile) | 380 if (event != v8::Break && event != v8::Exception && event != v8::AfterCompil
e && event != v8::BeforeCompile) |
| 425 return; | 381 return; |
| 426 | 382 |
| 427 v8::Handle<v8::Context> eventContext = eventDetails.GetEventContext(); | 383 v8::Handle<v8::Context> eventContext = eventDetails.GetEventContext(); |
| 428 ASSERT(!eventContext.IsEmpty()); | 384 ASSERT(!eventContext.IsEmpty()); |
| 429 | 385 |
| 430 ScriptDebugListener* listener = getDebugListenerForContext(eventContext); | 386 ScriptDebugListener* listener = getDebugListenerForContext(eventContext); |
| 431 if (listener) { | 387 if (listener) { |
| 432 v8::HandleScope scope; | 388 v8::HandleScope scope; |
| 433 if (event == v8::BeforeCompile) { | 389 if (event == v8::BeforeCompile) { |
| 434 | 390 preprocess(eventContext, eventDetails.GetEventData()); |
| 435 if (!m_scriptPreprocessor) | |
| 436 return; | |
| 437 | |
| 438 OwnPtr<ScriptPreprocessor> preprocessor(m_scriptPreprocessor.release
()); | |
| 439 v8::Local<v8::Context> debugContext = v8::Debug::GetDebugContext(); | |
| 440 v8::Context::Scope contextScope(debugContext); | |
| 441 v8::Handle<v8::Function> getScriptSourceFunction = v8::Local<v8::Fun
ction>::Cast(m_debuggerScript.get()->Get(v8::String::New("getScriptSource"))); | |
| 442 v8::Handle<v8::Value> argv[] = { eventDetails.GetEventData() }; | |
| 443 v8::Handle<v8::Value> script = getScriptSourceFunction->Call(m_debug
gerScript.get(), 1, argv); | |
| 444 | |
| 445 v8::Handle<v8::Function> getScriptNameFunction = v8::Local<v8::Funct
ion>::Cast(m_debuggerScript.get()->Get(v8::String::New("getScriptName"))); | |
| 446 v8::Handle<v8::Value> argv1[] = { eventDetails.GetEventData() }; | |
| 447 v8::Handle<v8::Value> scriptName = getScriptNameFunction->Call(m_deb
uggerScript.get(), 1, argv1); | |
| 448 | |
| 449 v8::Handle<v8::Function> setScriptSourceFunction = v8::Local<v8::Fun
ction>::Cast(m_debuggerScript.get()->Get(v8::String::New("setScriptSource"))); | |
| 450 String patchedScript = preprocessor->preprocessSourceCode(toWebCoreS
tringWithUndefinedOrNullCheck(script), toWebCoreStringWithUndefinedOrNullCheck(s
criptName)); | |
| 451 | |
| 452 v8::Handle<v8::Value> argv2[] = { eventDetails.GetEventData(), v8Str
ing(patchedScript, debugContext->GetIsolate()) }; | |
| 453 setScriptSourceFunction->Call(m_debuggerScript.get(), 2, argv2); | |
| 454 m_scriptPreprocessor = preprocessor.release(); | |
| 455 } else if (event == v8::AfterCompile) { | 391 } else if (event == v8::AfterCompile) { |
| 456 v8::Context::Scope contextScope(v8::Debug::GetDebugContext()); | 392 v8::Context::Scope contextScope(v8::Debug::GetDebugContext()); |
| 457 v8::Handle<v8::Function> onAfterCompileFunction = v8::Local<v8::Func
tion>::Cast(m_debuggerScript.get()->Get(v8::String::NewSymbol("getAfterCompileSc
ript"))); | 393 v8::Handle<v8::Function> onAfterCompileFunction = v8::Local<v8::Func
tion>::Cast(m_debuggerScript.get()->Get(v8::String::NewSymbol("getAfterCompileSc
ript"))); |
| 458 v8::Handle<v8::Value> argv[] = { eventDetails.GetEventData() }; | 394 v8::Handle<v8::Value> argv[] = { eventDetails.GetEventData() }; |
| 459 v8::Handle<v8::Value> value = onAfterCompileFunction->Call(m_debugge
rScript.get(), 1, argv); | 395 v8::Handle<v8::Value> value = onAfterCompileFunction->Call(m_debugge
rScript.get(), 1, argv); |
| 460 ASSERT(value->IsObject()); | 396 ASSERT(value->IsObject()); |
| 461 v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value); | 397 v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value); |
| 462 dispatchDidParseSource(listener, object); | 398 dispatchDidParseSource(listener, object); |
| 463 } else if (event == v8::Break || event == v8::Exception) { | 399 } else if (event == v8::Break || event == v8::Exception) { |
| 464 v8::Handle<v8::Value> exception; | 400 v8::Handle<v8::Value> exception; |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 *wasThrown = true; | 538 *wasThrown = true; |
| 603 *result = ScriptValue(tryCatch.Exception()); | 539 *result = ScriptValue(tryCatch.Exception()); |
| 604 v8::Local<v8::Message> message = tryCatch.Message(); | 540 v8::Local<v8::Message> message = tryCatch.Message(); |
| 605 if (!message.IsEmpty()) | 541 if (!message.IsEmpty()) |
| 606 *exceptionMessage = toWebCoreStringWithUndefinedOrNullCheck(message-
>Get()); | 542 *exceptionMessage = toWebCoreStringWithUndefinedOrNullCheck(message-
>Get()); |
| 607 } else | 543 } else |
| 608 *result = ScriptValue(value); | 544 *result = ScriptValue(value); |
| 609 } | 545 } |
| 610 | 546 |
| 611 } // namespace WebCore | 547 } // namespace WebCore |
| OLD | NEW |