| 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 16 matching lines...) Expand all Loading... |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 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 #include "DebuggerScriptSource.h" | 34 #include "DebuggerScriptSource.h" |
| 35 #include "V8JavaScriptCallFrame.h" | 35 #include "V8JavaScriptCallFrame.h" |
| 36 #include "bindings/v8/ScopedPersistent.h" | 36 #include "bindings/v8/ScopedPersistent.h" |
| 37 #include "bindings/v8/ScriptController.h" |
| 37 #include "bindings/v8/ScriptObject.h" | 38 #include "bindings/v8/ScriptObject.h" |
| 38 #include "bindings/v8/V8Binding.h" | 39 #include "bindings/v8/V8Binding.h" |
| 39 #include "bindings/v8/V8ScriptRunner.h" | 40 #include "bindings/v8/V8ScriptRunner.h" |
| 40 #include "core/inspector/JavaScriptCallFrame.h" | 41 #include "core/inspector/JavaScriptCallFrame.h" |
| 41 #include "core/inspector/ScriptDebugListener.h" | 42 #include "core/inspector/ScriptDebugListener.h" |
| 42 #include "wtf/StdLibExtras.h" | 43 #include "wtf/StdLibExtras.h" |
| 43 #include "wtf/Vector.h" | 44 #include "wtf/Vector.h" |
| 44 #include "wtf/dtoa/utils.h" | 45 #include "wtf/dtoa/utils.h" |
| 45 #include "wtf/text/CString.h" | 46 #include "wtf/text/CString.h" |
| 46 | 47 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 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::Object> debuggerScript = m_debuggerScript.newLocal(m_isolate)
; | 65 v8::Handle<v8::Object> debuggerScript = m_debuggerScript.newLocal(m_isolate)
; |
| 65 v8::Handle<v8::Function> function = v8::Local<v8::Function>::Cast(debuggerSc
ript->Get(v8::String::NewSymbol(functionName))); | 66 v8::Handle<v8::Function> function = v8::Local<v8::Function>::Cast(debuggerSc
ript->Get(v8::String::NewSymbol(functionName))); |
| 66 ASSERT(v8::Context::InContext()); | 67 ASSERT(v8::Context::InContext()); |
| 67 return V8ScriptRunner::callInternalFunction(function, debuggerScript, argc,
argv, m_isolate); | 68 return V8ScriptRunner::callInternalFunction(function, debuggerScript, argc,
argv, m_isolate); |
| 68 } | 69 } |
| 69 | 70 |
| 70 class ScriptDebugServer::ScriptPreprocessor { | |
| 71 WTF_MAKE_NONCOPYABLE(ScriptPreprocessor); | |
| 72 public: | |
| 73 ScriptPreprocessor(const String& preprocessorScript, v8::Isolate* isolate) | |
| 74 : m_isolate(isolate) | |
| 75 { | |
| 76 v8::HandleScope scope(m_isolate); | |
| 77 | |
| 78 v8::Local<v8::Context> context = v8::Context::New(m_isolate); | |
| 79 if (context.IsEmpty()) | |
| 80 return; | |
| 81 v8::Context::Scope contextScope(context); | |
| 82 | |
| 83 String wrappedScript = "(" + preprocessorScript + ")"; | |
| 84 v8::Handle<v8::String> preprocessor = v8::String::New(wrappedScript.utf8
().data(), wrappedScript.utf8().length()); | |
| 85 | |
| 86 v8::Local<v8::Value> preprocessorFunction = V8ScriptRunner::compileAndRu
nInternalScript(preprocessor, m_isolate); | |
| 87 if (preprocessorFunction.IsEmpty() || !preprocessorFunction->IsFunction(
)) | |
| 88 return; | |
| 89 | |
| 90 m_utilityContext.set(isolate, context); | |
| 91 m_preprocessorFunction.set(isolate, v8::Handle<v8::Function>::Cast(prepr
ocessorFunction)); | |
| 92 } | |
| 93 | |
| 94 String preprocessSourceCode(const String& sourceCode, const String& sourceNa
me) | |
| 95 { | |
| 96 v8::HandleScope handleScope(m_isolate); | |
| 97 | |
| 98 if (m_preprocessorFunction.isEmpty()) | |
| 99 return sourceCode; | |
| 100 | |
| 101 v8::Local<v8::Context> context = m_utilityContext.newLocal(m_isolate); | |
| 102 v8::Context::Scope contextScope(context); | |
| 103 | |
| 104 v8::Handle<v8::String> sourceCodeString = v8::String::New(sourceCode.utf
8().data(), sourceCode.utf8().length()); | |
| 105 | |
| 106 v8::Handle<v8::String> sourceNameString = v8::String::New(sourceName.utf
8().data(), sourceName.utf8().length()); | |
| 107 v8::Handle<v8::Value> argv[] = { sourceCodeString, sourceNameString }; | |
| 108 v8::Handle<v8::Value> resultValue = V8ScriptRunner::callInternalFunction
(m_preprocessorFunction.newLocal(m_isolate), context->Global(), WTF_ARRAY_LENGTH
(argv), argv, m_isolate); | |
| 109 | |
| 110 if (!resultValue.IsEmpty() && resultValue->IsString()) { | |
| 111 v8::String::Utf8Value utf8Value(resultValue); | |
| 112 return String::fromUTF8(*utf8Value, utf8Value.length()); | |
| 113 } | |
| 114 return sourceCode; | |
| 115 } | |
| 116 | |
| 117 ~ScriptPreprocessor() | |
| 118 { | |
| 119 } | |
| 120 | |
| 121 private: | |
| 122 ScopedPersistent<v8::Context> m_utilityContext; | |
| 123 String m_preprocessorBody; | |
| 124 ScopedPersistent<v8::Function> m_preprocessorFunction; | |
| 125 v8::Isolate* m_isolate; | |
| 126 }; | |
| 127 | |
| 128 ScriptDebugServer::ScriptDebugServer(v8::Isolate* isolate) | 71 ScriptDebugServer::ScriptDebugServer(v8::Isolate* isolate) |
| 129 : m_pauseOnExceptionsState(DontPauseOnExceptions) | 72 : m_pauseOnExceptionsState(DontPauseOnExceptions) |
| 130 , m_breakpointsActivated(true) | 73 , m_breakpointsActivated(true) |
| 131 , m_runningNestedMessageLoop(false) | 74 , m_runningNestedMessageLoop(false) |
| 132 , m_isolate(isolate) | 75 , m_isolate(isolate) |
| 133 { | 76 { |
| 134 } | 77 } |
| 135 | 78 |
| 136 ScriptDebugServer::~ScriptDebugServer() | 79 ScriptDebugServer::~ScriptDebugServer() |
| 137 { | 80 { |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 return false; | 303 return false; |
| 361 } | 304 } |
| 362 | 305 |
| 363 | 306 |
| 364 void ScriptDebugServer::updateCallStack(ScriptValue* callFrame) | 307 void ScriptDebugServer::updateCallStack(ScriptValue* callFrame) |
| 365 { | 308 { |
| 366 if (isPaused()) | 309 if (isPaused()) |
| 367 *callFrame = currentCallFrame(); | 310 *callFrame = currentCallFrame(); |
| 368 } | 311 } |
| 369 | 312 |
| 370 | 313 ScriptController* ScriptDebugServer::scriptController(v8::Handle<v8::Context> co
ntext) |
| 371 void ScriptDebugServer::setScriptPreprocessor(const String& preprocessorBody) | |
| 372 { | 314 { |
| 373 m_scriptPreprocessor.clear(); | 315 return 0; |
| 374 if (!preprocessorBody.isEmpty()) | |
| 375 m_scriptPreprocessor = adoptPtr(new ScriptPreprocessor(preprocessorBody,
m_isolate)); | |
| 376 } | 316 } |
| 377 | 317 |
| 378 PassRefPtr<JavaScriptCallFrame> ScriptDebugServer::wrapCallFrames(v8::Handle<v8:
:Object> executionState, int maximumLimit) | 318 PassRefPtr<JavaScriptCallFrame> ScriptDebugServer::wrapCallFrames(v8::Handle<v8:
:Object> executionState, int maximumLimit) |
| 379 { | 319 { |
| 380 v8::Handle<v8::Value> argv[] = { executionState, v8::Integer::New(maximumLim
it) }; | 320 v8::Handle<v8::Value> argv[] = { executionState, v8::Integer::New(maximumLim
it) }; |
| 381 v8::Handle<v8::Value> currentCallFrameV8 = callDebuggerMethod("currentCallFr
ame", 2, argv); | 321 v8::Handle<v8::Value> currentCallFrameV8 = callDebuggerMethod("currentCallFr
ame", 2, argv); |
| 382 | 322 |
| 383 ASSERT(!currentCallFrameV8.IsEmpty()); | 323 ASSERT(!currentCallFrameV8.IsEmpty()); |
| 384 if (!currentCallFrameV8->IsObject()) | 324 if (!currentCallFrameV8->IsObject()) |
| 385 return PassRefPtr<JavaScriptCallFrame>(); | 325 return PassRefPtr<JavaScriptCallFrame>(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 409 | 349 |
| 410 static ScriptDebugServer* toScriptDebugServer(v8::Handle<v8::Value> data) | 350 static ScriptDebugServer* toScriptDebugServer(v8::Handle<v8::Value> data) |
| 411 { | 351 { |
| 412 void* p = v8::Handle<v8::External>::Cast(data)->Value(); | 352 void* p = v8::Handle<v8::External>::Cast(data)->Value(); |
| 413 return static_cast<ScriptDebugServer*>(p); | 353 return static_cast<ScriptDebugServer*>(p); |
| 414 } | 354 } |
| 415 | 355 |
| 416 void ScriptDebugServer::breakProgramCallback(const v8::FunctionCallbackInfo<v8::
Value>& args) | 356 void ScriptDebugServer::breakProgramCallback(const v8::FunctionCallbackInfo<v8::
Value>& args) |
| 417 { | 357 { |
| 418 ASSERT(2 == args.Length()); | 358 ASSERT(2 == args.Length()); |
| 419 | |
| 420 ScriptDebugServer* thisPtr = toScriptDebugServer(args.Data()); | 359 ScriptDebugServer* thisPtr = toScriptDebugServer(args.Data()); |
| 421 v8::Handle<v8::Value> exception; | 360 v8::Handle<v8::Value> exception; |
| 422 v8::Handle<v8::Array> hitBreakpoints; | 361 v8::Handle<v8::Array> hitBreakpoints; |
| 423 thisPtr->handleProgramBreak(v8::Handle<v8::Object>::Cast(args[0]), exception
, hitBreakpoints); | 362 thisPtr->handleProgramBreak(v8::Handle<v8::Object>::Cast(args[0]), exception
, hitBreakpoints); |
| 424 } | 363 } |
| 425 | 364 |
| 426 void ScriptDebugServer::handleProgramBreak(v8::Handle<v8::Object> executionState
, v8::Handle<v8::Value> exception, v8::Handle<v8::Array> hitBreakpointNumbers) | 365 void ScriptDebugServer::handleProgramBreak(v8::Handle<v8::Object> executionState
, v8::Handle<v8::Value> exception, v8::Handle<v8::Array> hitBreakpointNumbers) |
| 427 { | 366 { |
| 428 // Don't allow nested breaks. | 367 // Don't allow nested breaks. |
| 429 if (isPaused()) | 368 if (isPaused()) |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 | 413 |
| 475 if (event != v8::Break && event != v8::Exception && event != v8::AfterCompil
e && event != v8::BeforeCompile) | 414 if (event != v8::Break && event != v8::Exception && event != v8::AfterCompil
e && event != v8::BeforeCompile) |
| 476 return; | 415 return; |
| 477 | 416 |
| 478 v8::Handle<v8::Context> eventContext = eventDetails.GetEventContext(); | 417 v8::Handle<v8::Context> eventContext = eventDetails.GetEventContext(); |
| 479 ASSERT(!eventContext.IsEmpty()); | 418 ASSERT(!eventContext.IsEmpty()); |
| 480 | 419 |
| 481 ScriptDebugListener* listener = getDebugListenerForContext(eventContext); | 420 ScriptDebugListener* listener = getDebugListenerForContext(eventContext); |
| 482 if (listener) { | 421 if (listener) { |
| 483 v8::HandleScope scope(m_isolate); | 422 v8::HandleScope scope(m_isolate); |
| 484 v8::Local<v8::Context> debugContext = v8::Debug::GetDebugContext(); | |
| 485 v8::Handle<v8::Object> debuggerScript = m_debuggerScript.newLocal(m_isol
ate); | 423 v8::Handle<v8::Object> debuggerScript = m_debuggerScript.newLocal(m_isol
ate); |
| 486 if (event == v8::BeforeCompile) { | 424 if (event == v8::BeforeCompile) { |
| 487 | 425 ScriptController* controller = scriptController(eventContext); |
| 488 if (!m_scriptPreprocessor) | 426 if (controller) |
| 489 return; | 427 controller->preprocessEval(this, eventDetails.GetEventData()); |
| 490 | |
| 491 OwnPtr<ScriptPreprocessor> preprocessor(m_scriptPreprocessor.release
()); | |
| 492 v8::Context::Scope contextScope(debugContext); | |
| 493 v8::Handle<v8::Function> getScriptSourceFunction = v8::Local<v8::Fun
ction>::Cast(debuggerScript->Get(v8::String::New("getScriptSource"))); | |
| 494 v8::Handle<v8::Value> argv[] = { eventDetails.GetEventData() }; | |
| 495 v8::Handle<v8::Value> script = V8ScriptRunner::callInternalFunction(
getScriptSourceFunction, debuggerScript, WTF_ARRAY_LENGTH(argv), argv, m_isolate
); | |
| 496 | |
| 497 v8::Handle<v8::Function> getScriptNameFunction = v8::Local<v8::Funct
ion>::Cast(debuggerScript->Get(v8::String::New("getScriptName"))); | |
| 498 v8::Handle<v8::Value> argv1[] = { eventDetails.GetEventData() }; | |
| 499 v8::Handle<v8::Value> scriptName = V8ScriptRunner::callInternalFunct
ion(getScriptNameFunction, debuggerScript, WTF_ARRAY_LENGTH(argv1), argv1, m_iso
late); | |
| 500 v8::Handle<v8::Function> setScriptSourceFunction = v8::Local<v8::Fun
ction>::Cast(debuggerScript->Get(v8::String::New("setScriptSource"))); | |
| 501 String patchedScript = preprocessor->preprocessSourceCode(toWebCoreS
tringWithUndefinedOrNullCheck(script), toWebCoreStringWithUndefinedOrNullCheck(s
criptName)); | |
| 502 | |
| 503 v8::Handle<v8::Value> argv2[] = { eventDetails.GetEventData(), v8Str
ing(patchedScript, m_isolate) }; | |
| 504 V8ScriptRunner::callInternalFunction(setScriptSourceFunction, debugg
erScript, WTF_ARRAY_LENGTH(argv2), argv2, m_isolate); | |
| 505 m_scriptPreprocessor = preprocessor.release(); | |
| 506 } else if (event == v8::AfterCompile) { | 428 } else if (event == v8::AfterCompile) { |
| 507 v8::Context::Scope contextScope(v8::Debug::GetDebugContext()); | 429 v8::Context::Scope contextScope(v8::Debug::GetDebugContext()); |
| 508 v8::Handle<v8::Function> getAfterCompileScript = v8::Local<v8::Funct
ion>::Cast(debuggerScript->Get(v8::String::NewSymbol("getAfterCompileScript"))); | 430 v8::Handle<v8::Function> getAfterCompileScript = v8::Local<v8::Funct
ion>::Cast(debuggerScript->Get(v8::String::NewSymbol("getAfterCompileScript"))); |
| 509 v8::Handle<v8::Value> argv[] = { eventDetails.GetEventData() }; | 431 v8::Handle<v8::Value> argv[] = { eventDetails.GetEventData() }; |
| 510 v8::Handle<v8::Value> value = V8ScriptRunner::callInternalFunction(g
etAfterCompileScript, debuggerScript, WTF_ARRAY_LENGTH(argv), argv, m_isolate); | 432 v8::Handle<v8::Value> value = V8ScriptRunner::callInternalFunction(g
etAfterCompileScript, debuggerScript, WTF_ARRAY_LENGTH(argv), argv, m_isolate); |
| 511 ASSERT(value->IsObject()); | 433 ASSERT(value->IsObject()); |
| 512 v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value); | 434 v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value); |
| 513 dispatchDidParseSource(listener, object); | 435 dispatchDidParseSource(listener, object); |
| 514 } else if (event == v8::Exception) { | 436 } else if (event == v8::Exception) { |
| 515 v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackT
race(1); | 437 v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackT
race(1); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 657 *wasThrown = true; | 579 *wasThrown = true; |
| 658 *result = ScriptValue(tryCatch.Exception()); | 580 *result = ScriptValue(tryCatch.Exception()); |
| 659 v8::Local<v8::Message> message = tryCatch.Message(); | 581 v8::Local<v8::Message> message = tryCatch.Message(); |
| 660 if (!message.IsEmpty()) | 582 if (!message.IsEmpty()) |
| 661 *exceptionMessage = toWebCoreStringWithUndefinedOrNullCheck(message-
>Get()); | 583 *exceptionMessage = toWebCoreStringWithUndefinedOrNullCheck(message-
>Get()); |
| 662 } else | 584 } else |
| 663 *result = ScriptValue(value); | 585 *result = ScriptValue(value); |
| 664 } | 586 } |
| 665 | 587 |
| 666 } // namespace WebCore | 588 } // namespace WebCore |
| OLD | NEW |