15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (c) 2010-2011 Google Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions in binary form must reproduce the above 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission. 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/ScriptDebugServer.h" 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "DebuggerScriptSource.h" 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "V8JavaScriptCallFrame.h" 3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/ScopedPersistent.h" 3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/ScriptObject.h" 3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/V8Binding.h" 3993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "bindings/v8/V8ScriptRunner.h" 4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/JavaScriptCallFrame.h" 4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/ScriptDebugListener.h" 4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/StdLibExtras.h" 4353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/Vector.h" 445267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "wtf/dtoa/utils.h" 450019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch#include "wtf/text/CString.h" 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace { 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class ClientDataImpl : public v8::Debug::ClientData { 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ClientDataImpl(PassOwnPtr<ScriptDebugServer::Task> task) : m_task(task) { } 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual ~ClientDataImpl() { } 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ScriptDebugServer::Task* task() const { return m_task.get(); } 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OwnPtr<ScriptDebugServer::Task> m_task; 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 60f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)const char stepIntoV8MethodName[] = "stepIntoStatement"; 61f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)const char stepOutV8MethodName[] = "stepOutOfFunction"; 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)v8::Local<v8::Value> ScriptDebugServer::callDebuggerMethod(const char* functionName, int argc, v8::Handle<v8::Value> argv[]) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 66591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::Handle<v8::Object> debuggerScript = m_debuggerScript.newLocal(m_isolate); 67591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::Handle<v8::Function> function = v8::Local<v8::Function>::Cast(debuggerScript->Get(v8::String::NewSymbol(functionName))); 6893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) ASSERT(v8::Context::InContext()); 69591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return V8ScriptRunner::callInternalFunction(function, debuggerScript, argc, argv, m_isolate); 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7283750176c3ee2cea66c8a9751271026a5901be3aBen Murdochclass ScriptDebugServer::ScriptPreprocessor { 7383750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch WTF_MAKE_NONCOPYABLE(ScriptPreprocessor); 7483750176c3ee2cea66c8a9751271026a5901be3aBen Murdochpublic: 7583750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch ScriptPreprocessor(const String& preprocessorScript, v8::Isolate* isolate) 7683750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch : m_isolate(isolate) 7783750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch { 7883750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::HandleScope scope(m_isolate); 7983750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 8083750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::Local<v8::Context> context = v8::Context::New(m_isolate); 8183750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch if (context.IsEmpty()) 8283750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch return; 8383750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::Context::Scope contextScope(context); 8483750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 8583750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch String wrappedScript = "(" + preprocessorScript + ")"; 8683750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::Handle<v8::String> preprocessor = v8::String::New(wrappedScript.utf8().data(), wrappedScript.utf8().length()); 8783750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 8883750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::Local<v8::Value> preprocessorFunction = V8ScriptRunner::compileAndRunInternalScript(preprocessor, m_isolate); 8983750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch if (preprocessorFunction.IsEmpty() || !preprocessorFunction->IsFunction()) 9083750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch return; 9183750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 9283750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch m_utilityContext.set(isolate, context); 9383750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch m_preprocessorFunction.set(isolate, v8::Handle<v8::Function>::Cast(preprocessorFunction)); 9483750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch } 9583750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 9683750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch String preprocessSourceCode(const String& sourceCode, const String& sourceName) 9783750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch { 9883750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::HandleScope handleScope(m_isolate); 9983750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 10083750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch if (m_preprocessorFunction.isEmpty()) 10183750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch return sourceCode; 10283750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 10383750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::Local<v8::Context> context = m_utilityContext.newLocal(m_isolate); 10483750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::Context::Scope contextScope(context); 10583750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 10683750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::Handle<v8::String> sourceCodeString = v8::String::New(sourceCode.utf8().data(), sourceCode.utf8().length()); 10783750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 10883750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::Handle<v8::String> sourceNameString = v8::String::New(sourceName.utf8().data(), sourceName.utf8().length()); 10983750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::Handle<v8::Value> argv[] = { sourceCodeString, sourceNameString }; 11083750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::Handle<v8::Value> resultValue = V8ScriptRunner::callInternalFunction(m_preprocessorFunction.newLocal(m_isolate), context->Global(), WTF_ARRAY_LENGTH(argv), argv, m_isolate); 11183750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 11283750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch if (!resultValue.IsEmpty() && resultValue->IsString()) { 11383750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::String::Utf8Value utf8Value(resultValue); 11483750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch return String::fromUTF8(*utf8Value, utf8Value.length()); 11583750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch } 11683750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch return sourceCode; 11783750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch } 11883750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 11983750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch ~ScriptPreprocessor() 12083750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch { 12183750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch } 12283750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 12383750176c3ee2cea66c8a9751271026a5901be3aBen Murdochprivate: 12483750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch ScopedPersistent<v8::Context> m_utilityContext; 12583750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch String m_preprocessorBody; 12683750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch ScopedPersistent<v8::Function> m_preprocessorFunction; 12783750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::Isolate* m_isolate; 12883750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch}; 12983750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 13053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)ScriptDebugServer::ScriptDebugServer(v8::Isolate* isolate) 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_pauseOnExceptionsState(DontPauseOnExceptions) 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_breakpointsActivated(true) 133926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_runningNestedMessageLoop(false) 13453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) , m_isolate(isolate) 135926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 136926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 137926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 138926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)ScriptDebugServer::~ScriptDebugServer() 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 142e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben MurdochString ScriptDebugServer::setBreakpoint(const String& sourceID, const ScriptBreakpoint& scriptBreakpoint, int* actualLineNumber, int* actualColumnNumber, bool interstatementLocation) 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1443464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch v8::HandleScope scope(m_isolate); 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext(); 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Context::Scope contextScope(debuggerContext); 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Object> args = v8::Object::New(); 149926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) args->Set(v8::String::NewSymbol("sourceID"), v8String(sourceID, debuggerContext->GetIsolate())); 150591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch args->Set(v8::String::NewSymbol("lineNumber"), v8::Integer::New(scriptBreakpoint.lineNumber, debuggerContext->GetIsolate())); 151591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch args->Set(v8::String::NewSymbol("columnNumber"), v8::Integer::New(scriptBreakpoint.columnNumber, debuggerContext->GetIsolate())); 152e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch args->Set(v8::String::NewSymbol("interstatementLocation"), v8Boolean(interstatementLocation, debuggerContext->GetIsolate())); 153926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) args->Set(v8::String::NewSymbol("condition"), v8String(scriptBreakpoint.condition, debuggerContext->GetIsolate())); 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 155521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8::Handle<v8::Function> setBreakpointFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.newLocal(m_isolate)->Get(v8::String::NewSymbol("setBreakpoint"))); 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Value> breakpointId = v8::Debug::Call(setBreakpointFunction, args); 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!breakpointId->IsString()) 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ""; 159926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *actualLineNumber = args->Get(v8::String::NewSymbol("lineNumber"))->Int32Value(); 160926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *actualColumnNumber = args->Get(v8::String::NewSymbol("columnNumber"))->Int32Value(); 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return toWebCoreString(breakpointId->ToString()); 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptDebugServer::removeBreakpoint(const String& breakpointId) 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 166521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8::HandleScope scope(m_isolate); 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext(); 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Context::Scope contextScope(debuggerContext); 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Object> args = v8::Object::New(); 171926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) args->Set(v8::String::NewSymbol("breakpointId"), v8String(breakpointId, debuggerContext->GetIsolate())); 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 173521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8::Handle<v8::Function> removeBreakpointFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.newLocal(m_isolate)->Get(v8::String::NewSymbol("removeBreakpoint"))); 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Debug::Call(removeBreakpointFunction, args); 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptDebugServer::clearBreakpoints() 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ensureDebuggerScriptCompiled(); 180521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8::HandleScope scope(m_isolate); 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext(); 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Context::Scope contextScope(debuggerContext); 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 184521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8::Handle<v8::Function> clearBreakpoints = v8::Local<v8::Function>::Cast(m_debuggerScript.newLocal(m_isolate)->Get(v8::String::NewSymbol("clearBreakpoints"))); 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Debug::Call(clearBreakpoints); 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptDebugServer::setBreakpointsActivated(bool activated) 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ensureDebuggerScriptCompiled(); 191521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8::HandleScope scope(m_isolate); 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext(); 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Context::Scope contextScope(debuggerContext); 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Object> args = v8::Object::New(); 196926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) args->Set(v8::String::NewSymbol("enabled"), v8::Boolean::New(activated)); 197521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8::Handle<v8::Function> setBreakpointsActivated = v8::Local<v8::Function>::Cast(m_debuggerScript.newLocal(m_isolate)->Get(v8::String::NewSymbol("setBreakpointsActivated"))); 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Debug::Call(setBreakpointsActivated, args); 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_breakpointsActivated = activated; 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ScriptDebugServer::PauseOnExceptionsState ScriptDebugServer::pauseOnExceptionsState() 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ensureDebuggerScriptCompiled(); 206521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8::HandleScope scope(m_isolate); 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Context::Scope contextScope(v8::Debug::GetDebugContext()); 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Value> argv[] = { v8Undefined() }; 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Value> result = callDebuggerMethod("pauseOnExceptionsState", 0, argv); 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return static_cast<ScriptDebugServer::PauseOnExceptionsState>(result->Int32Value()); 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptDebugServer::setPauseOnExceptionsState(PauseOnExceptionsState pauseOnExceptionsState) 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ensureDebuggerScriptCompiled(); 217521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8::HandleScope scope(m_isolate); 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Context::Scope contextScope(v8::Debug::GetDebugContext()); 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Value> argv[] = { v8::Int32::New(pauseOnExceptionsState) }; 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) callDebuggerMethod("setPauseOnExceptionsState", 1, argv); 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptDebugServer::setPauseOnNextStatement(bool pause) 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isPaused()) 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (pause) 22993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) v8::Debug::DebugBreak(m_isolate); 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 23193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) v8::Debug::CancelDebugBreak(m_isolate); 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 234521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)bool ScriptDebugServer::canBreakProgram() 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_breakpointsActivated) 237521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return false; 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 239521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // FIXME: Remove this check once m_isolate->GetCurrentContext() does not crash. 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!v8::Context::InContext()) 241521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return false; 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 243521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8::HandleScope scope(m_isolate); 244521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return !m_isolate->GetCurrentContext().IsEmpty(); 245521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 247521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void ScriptDebugServer::breakProgram() 248521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 249521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (!canBreakProgram()) 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 252521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8::HandleScope scope(m_isolate); 253521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (m_breakProgramCallbackTemplate.isEmpty()) { 254521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); 255521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) templ->SetCallHandler(&ScriptDebugServer::breakProgramCallback, v8::External::New(this)); 256521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) m_breakProgramCallbackTemplate.set(m_isolate, templ); 257521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) } 258521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 259521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) m_pausedContext = m_isolate->GetCurrentContext(); 260521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8::Handle<v8::Function> breakProgramFunction = m_breakProgramCallbackTemplate.newLocal(m_isolate)->GetFunction(); 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Debug::Call(breakProgramFunction); 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_pausedContext.Clear(); 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptDebugServer::continueProgram() 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isPaused()) 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) quitMessageLoopOnPause(); 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_executionState.clear(); 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptDebugServer::stepIntoStatement() 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isPaused()); 275591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::HandleScope handleScope(m_isolate); 276591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::Handle<v8::Value> argv[] = { m_executionState.newLocal(m_isolate) }; 277f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) callDebuggerMethod(stepIntoV8MethodName, 1, argv); 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continueProgram(); 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptDebugServer::stepOverStatement() 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isPaused()); 284591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::HandleScope handleScope(m_isolate); 285591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::Handle<v8::Value> argv[] = { m_executionState.newLocal(m_isolate) }; 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) callDebuggerMethod("stepOverStatement", 1, argv); 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continueProgram(); 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptDebugServer::stepOutOfFunction() 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isPaused()); 293591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::HandleScope handleScope(m_isolate); 294591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::Handle<v8::Value> argv[] = { m_executionState.newLocal(m_isolate) }; 295f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) callDebuggerMethod(stepOutV8MethodName, 1, argv); 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continueProgram(); 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 299591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochbool ScriptDebugServer::setScriptSource(const String& sourceID, const String& newContent, bool preview, String* error, RefPtr<TypeBuilder::Debugger::SetScriptSourceError>& errorData, ScriptValue* newCallFrames, ScriptObject* result) 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 301926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) class EnableLiveEditScope { 302926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) public: 303926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) EnableLiveEditScope() { v8::Debug::SetLiveEditEnabled(true); } 304926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ~EnableLiveEditScope() { v8::Debug::SetLiveEditEnabled(false); } 305926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) }; 306926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ensureDebuggerScriptCompiled(); 308591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::HandleScope scope(m_isolate); 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OwnPtr<v8::Context::Scope> contextScope; 311926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) v8::Handle<v8::Context> debuggerContext = v8::Debug::GetDebugContext(); 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isPaused()) 313926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) contextScope = adoptPtr(new v8::Context::Scope(debuggerContext)); 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) v8::Handle<v8::Value> argv[] = { v8String(sourceID, debuggerContext->GetIsolate()), v8String(newContent, debuggerContext->GetIsolate()), v8Boolean(preview) }; 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 317926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) v8::Local<v8::Value> v8result; 318926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) { 319926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) EnableLiveEditScope enableLiveEditScope; 320926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) v8::TryCatch tryCatch; 321926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) tryCatch.SetVerbose(false); 322926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) v8result = callDebuggerMethod("liveEditScriptSource", 3, argv); 323926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (tryCatch.HasCaught()) { 324926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) v8::Local<v8::Message> message = tryCatch.Message(); 325926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!message.IsEmpty()) 326926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *error = toWebCoreStringWithUndefinedOrNullCheck(message->Get()); 327926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) else 328926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *error = "Unknown error."; 329926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return false; 330926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!v8result.IsEmpty()); 333591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::Local<v8::Object> resultTuple = v8result->ToObject(); 334591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch int code = static_cast<int>(resultTuple->Get(0)->ToInteger()->Value()); 335591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch switch (code) { 336591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch case 0: 337591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch { 338591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::Local<v8::Value> normalResult = resultTuple->Get(1); 339591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (normalResult->IsObject()) 340591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch *result = ScriptObject(ScriptState::current(), normalResult->ToObject()); 341591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // Call stack may have changed after if the edited function was on the stack. 342591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (!preview && isPaused()) 343591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch *newCallFrames = currentCallFrame(); 344591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return true; 345591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 346591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // Compile error. 347591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch case 1: 348591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch { 349591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<TypeBuilder::Debugger::SetScriptSourceError::CompileError> compileError = 350591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch TypeBuilder::Debugger::SetScriptSourceError::CompileError::create() 351591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch .setMessage(toWebCoreStringWithUndefinedOrNullCheck(resultTuple->Get(2))) 352591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch .setLineNumber(resultTuple->Get(3)->ToInteger()->Value()) 353591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch .setColumnNumber(resultTuple->Get(4)->ToInteger()->Value()); 354591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 355591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch *error = toWebCoreStringWithUndefinedOrNullCheck(resultTuple->Get(1)); 356591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch errorData = TypeBuilder::Debugger::SetScriptSourceError::create(); 357591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch errorData->setCompileError(compileError); 358591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return false; 359591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 360591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 361591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch *error = "Unknown error."; 362591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return false; 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptDebugServer::updateCallStack(ScriptValue* callFrame) 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isPaused()) 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *callFrame = currentCallFrame(); 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 37283750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 37383750176c3ee2cea66c8a9751271026a5901be3aBen Murdochvoid ScriptDebugServer::setScriptPreprocessor(const String& preprocessorBody) 374926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 37583750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch m_scriptPreprocessor.clear(); 37683750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch if (!preprocessorBody.isEmpty()) 37783750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch m_scriptPreprocessor = adoptPtr(new ScriptPreprocessor(preprocessorBody, m_isolate)); 378926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 379926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 380e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben MurdochPassRefPtr<JavaScriptCallFrame> ScriptDebugServer::wrapCallFrames(v8::Handle<v8::Object> executionState, int maximumLimit) 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 382e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch v8::Handle<v8::Value> argv[] = { executionState, v8::Integer::New(maximumLimit) }; 383e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch v8::Handle<v8::Value> currentCallFrameV8 = callDebuggerMethod("currentCallFrame", 2, argv); 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!currentCallFrameV8.IsEmpty()); 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!currentCallFrameV8->IsObject()) 387e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return PassRefPtr<JavaScriptCallFrame>(); 388e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return JavaScriptCallFrame::create(v8::Debug::GetDebugContext(), v8::Handle<v8::Object>::Cast(currentCallFrameV8)); 389e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch} 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 391e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben MurdochScriptValue ScriptDebugServer::currentCallFrame() 392e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{ 393e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch ASSERT(isPaused()); 394e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch v8::HandleScope handleScope(m_isolate); 395e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch RefPtr<JavaScriptCallFrame> currentCallFrame = wrapCallFrames(m_executionState.newLocal(m_isolate), -1); 396e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (!currentCallFrame) 397e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return ScriptValue(v8::Null()); 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Context::Scope contextScope(m_pausedContext); 399926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return ScriptValue(toV8(currentCallFrame.release(), v8::Handle<v8::Object>(), m_pausedContext->GetIsolate())); 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptDebugServer::interruptAndRun(PassOwnPtr<Task> task, v8::Isolate* isolate) 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Debug::DebugBreakForCommand(new ClientDataImpl(task), isolate); 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptDebugServer::runPendingTasks() 4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Debug::ProcessDebugMessages(); 4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static ScriptDebugServer* toScriptDebugServer(v8::Handle<v8::Value> data) 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void* p = v8::Handle<v8::External>::Cast(data)->Value(); 4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return static_cast<ScriptDebugServer*>(p); 4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4185267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void ScriptDebugServer::breakProgramCallback(const v8::FunctionCallbackInfo<v8::Value>& args) 4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(2 == args.Length()); 42102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ScriptDebugServer* thisPtr = toScriptDebugServer(args.Data()); 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Value> exception; 4245267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) v8::Handle<v8::Array> hitBreakpoints; 425e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch thisPtr->handleProgramBreak(v8::Handle<v8::Object>::Cast(args[0]), exception, hitBreakpoints); 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 428e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochvoid ScriptDebugServer::handleProgramBreak(v8::Handle<v8::Object> executionState, v8::Handle<v8::Value> exception, v8::Handle<v8::Array> hitBreakpointNumbers) 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Don't allow nested breaks. 4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isPaused()) 4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ScriptDebugListener* listener = getDebugListenerForContext(m_pausedContext); 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!listener) 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4385267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) Vector<String> breakpointIds; 4395267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (!hitBreakpointNumbers.IsEmpty()) { 4405267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) breakpointIds.resize(hitBreakpointNumbers->Length()); 4415267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) for (size_t i = 0; i < hitBreakpointNumbers->Length(); i++) 4425267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) breakpointIds[i] = toWebCoreStringWithUndefinedOrNullCheck(hitBreakpointNumbers->Get(i)); 4435267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) } 4445267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 44593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) m_executionState.set(m_isolate, executionState); 4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ScriptState* currentCallFrameState = ScriptState::forContext(m_pausedContext); 4475267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) listener->didPause(currentCallFrameState, currentCallFrame(), ScriptValue(exception), breakpointIds); 4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 449926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_runningNestedMessageLoop = true; 4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) runMessageLoopOnPause(m_pausedContext); 451926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_runningNestedMessageLoop = false; 4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 454e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochvoid ScriptDebugServer::handleProgramBreak(const v8::Debug::EventDetails& eventDetails, v8::Handle<v8::Value> exception, v8::Handle<v8::Array> hitBreakpointNumbers) 4555267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles){ 4565267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) m_pausedContext = eventDetails.GetEventContext(); 457e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch handleProgramBreak(eventDetails.GetExecutionState(), exception, hitBreakpointNumbers); 4585267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) m_pausedContext.Clear(); 4595267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)} 4605267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptDebugServer::v8DebugEventCallback(const v8::Debug::EventDetails& eventDetails) 4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ScriptDebugServer* thisPtr = toScriptDebugServer(eventDetails.GetCallbackData()); 4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) thisPtr->handleV8DebugEvent(eventDetails); 4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 467f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)bool ScriptDebugServer::executeSkipPauseRequest(ScriptDebugListener::SkipPauseRequest request, v8::Handle<v8::Object> executionState) 468f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles){ 469f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) const char* v8MethodName; 470f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) switch (request) { 471f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) case ScriptDebugListener::NoSkip: 472f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return false; 473f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) case ScriptDebugListener::Continue: 474f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return true; 475f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) case ScriptDebugListener::StepInto: 476f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) v8MethodName = stepIntoV8MethodName; 477f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) case ScriptDebugListener::StepOut: 478f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) v8MethodName = stepOutV8MethodName; 479f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) } 480f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) v8::Handle<v8::Value> argv[] = { executionState }; 481f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) callDebuggerMethod(stepIntoV8MethodName, 1, argv); 482f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return true; 483f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)} 484f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptDebugServer::handleV8DebugEvent(const v8::Debug::EventDetails& eventDetails) 4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::DebugEvent event = eventDetails.GetEvent(); 4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (event == v8::BreakForCommand) { 4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ClientDataImpl* data = static_cast<ClientDataImpl*>(eventDetails.GetClientData()); 4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data->task()->run(); 4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 495926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (event != v8::Break && event != v8::Exception && event != v8::AfterCompile && event != v8::BeforeCompile) 4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Context> eventContext = eventDetails.GetEventContext(); 4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!eventContext.IsEmpty()); 5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ScriptDebugListener* listener = getDebugListenerForContext(eventContext); 5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (listener) { 503591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::HandleScope scope(m_isolate); 50483750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::Local<v8::Context> debugContext = v8::Debug::GetDebugContext(); 505591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::Handle<v8::Object> debuggerScript = m_debuggerScript.newLocal(m_isolate); 506926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (event == v8::BeforeCompile) { 50783750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 50883750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch if (!m_scriptPreprocessor) 50983750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch return; 51083750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 51183750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch OwnPtr<ScriptPreprocessor> preprocessor(m_scriptPreprocessor.release()); 51283750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::Context::Scope contextScope(debugContext); 51383750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::Handle<v8::Function> getScriptSourceFunction = v8::Local<v8::Function>::Cast(debuggerScript->Get(v8::String::New("getScriptSource"))); 51483750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::Handle<v8::Value> argv[] = { eventDetails.GetEventData() }; 51583750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::Handle<v8::Value> script = V8ScriptRunner::callInternalFunction(getScriptSourceFunction, debuggerScript, WTF_ARRAY_LENGTH(argv), argv, m_isolate); 51683750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 51783750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::Handle<v8::Function> getScriptNameFunction = v8::Local<v8::Function>::Cast(debuggerScript->Get(v8::String::New("getScriptName"))); 51883750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::Handle<v8::Value> argv1[] = { eventDetails.GetEventData() }; 51983750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::Handle<v8::Value> scriptName = V8ScriptRunner::callInternalFunction(getScriptNameFunction, debuggerScript, WTF_ARRAY_LENGTH(argv1), argv1, m_isolate); 52083750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::Handle<v8::Function> setScriptSourceFunction = v8::Local<v8::Function>::Cast(debuggerScript->Get(v8::String::New("setScriptSource"))); 52183750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch String patchedScript = preprocessor->preprocessSourceCode(toWebCoreStringWithUndefinedOrNullCheck(script), toWebCoreStringWithUndefinedOrNullCheck(scriptName)); 52283750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 52383750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch v8::Handle<v8::Value> argv2[] = { eventDetails.GetEventData(), v8String(patchedScript, m_isolate) }; 52483750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch V8ScriptRunner::callInternalFunction(setScriptSourceFunction, debuggerScript, WTF_ARRAY_LENGTH(argv2), argv2, m_isolate); 52583750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch m_scriptPreprocessor = preprocessor.release(); 526926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } else if (event == v8::AfterCompile) { 5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Context::Scope contextScope(v8::Debug::GetDebugContext()); 528591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::Handle<v8::Function> getAfterCompileScript = v8::Local<v8::Function>::Cast(debuggerScript->Get(v8::String::NewSymbol("getAfterCompileScript"))); 5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Value> argv[] = { eventDetails.GetEventData() }; 530591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::Handle<v8::Value> value = V8ScriptRunner::callInternalFunction(getAfterCompileScript, debuggerScript, WTF_ARRAY_LENGTH(argv), argv, m_isolate); 5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(value->IsObject()); 5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value); 5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dispatchDidParseSource(listener, object); 5345267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) } else if (event == v8::Exception) { 5355267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(1); 5365267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) // Stack trace is empty in case of syntax error. Silently continue execution in such cases. 5375267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (!stackTrace->GetFrameCount()) 5385267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return; 539e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch RefPtr<JavaScriptCallFrame> topFrame = wrapCallFrames(eventDetails.GetExecutionState(), 1); 540f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) if (topFrame && executeSkipPauseRequest(listener->shouldSkipExceptionPause(topFrame), eventDetails.GetExecutionState())) { 541e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return; 542e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } 5435267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) v8::Handle<v8::Object> eventData = eventDetails.GetEventData(); 5445267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) v8::Handle<v8::Value> exceptionGetterValue = eventData->Get(v8::String::NewSymbol("exception")); 5455267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) ASSERT(!exceptionGetterValue.IsEmpty() && exceptionGetterValue->IsFunction()); 546591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::Handle<v8::Value> exception = V8ScriptRunner::callInternalFunction(v8::Handle<v8::Function>::Cast(exceptionGetterValue), eventData, 0, 0, m_isolate); 547e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch handleProgramBreak(eventDetails, exception, v8::Handle<v8::Array>()); 5485267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) } else if (event == v8::Break) { 549591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::Handle<v8::Function> getBreakpointNumbersFunction = v8::Local<v8::Function>::Cast(debuggerScript->Get(v8::String::NewSymbol("getBreakpointNumbers"))); 5505267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) v8::Handle<v8::Value> argv[] = { eventDetails.GetEventData() }; 551591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::Handle<v8::Value> hitBreakpoints = V8ScriptRunner::callInternalFunction(getBreakpointNumbersFunction, debuggerScript, WTF_ARRAY_LENGTH(argv), argv, m_isolate); 5525267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) ASSERT(hitBreakpoints->IsArray()); 5535267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 554f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) RefPtr<JavaScriptCallFrame> topFrame = wrapCallFrames(eventDetails.GetExecutionState(), 1); 555f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) if (topFrame) { 556f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) ScriptDebugListener::SkipPauseRequest skipRequest; 557f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) if (v8::Handle<v8::Array>::Cast(hitBreakpoints)->Length()) 558f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) skipRequest = listener->shouldSkipBreakpointPause(topFrame); 559f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) else 560f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) skipRequest = listener->shouldSkipStepPause(topFrame); 561f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) if (executeSkipPauseRequest(skipRequest, eventDetails.GetExecutionState())) 562f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return; 563f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) } 564f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 565e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch handleProgramBreak(eventDetails, v8::Handle<v8::Value>(), hitBreakpoints.As<v8::Array>()); 5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptDebugServer::dispatchDidParseSource(ScriptDebugListener* listener, v8::Handle<v8::Object> object) 5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 572926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) String sourceID = toWebCoreStringWithUndefinedOrNullCheck(object->Get(v8::String::NewSymbol("id"))); 5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ScriptDebugListener::Script script; 575926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) script.url = toWebCoreStringWithUndefinedOrNullCheck(object->Get(v8::String::NewSymbol("name"))); 576926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) script.source = toWebCoreStringWithUndefinedOrNullCheck(object->Get(v8::String::NewSymbol("source"))); 577926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) script.sourceMappingURL = toWebCoreStringWithUndefinedOrNullCheck(object->Get(v8::String::NewSymbol("sourceMappingURL"))); 578926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) script.startLine = object->Get(v8::String::NewSymbol("startLine"))->ToInteger()->Value(); 579926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) script.startColumn = object->Get(v8::String::NewSymbol("startColumn"))->ToInteger()->Value(); 580926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) script.endLine = object->Get(v8::String::NewSymbol("endLine"))->ToInteger()->Value(); 581926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) script.endColumn = object->Get(v8::String::NewSymbol("endColumn"))->ToInteger()->Value(); 582926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) script.isContentScript = object->Get(v8::String::NewSymbol("isContentScript"))->ToBoolean()->Value(); 5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) listener->didParseSource(sourceID, script); 5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptDebugServer::ensureDebuggerScriptCompiled() 5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 589591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (!m_debuggerScript.isEmpty()) 59093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return; 59193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 59293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) v8::HandleScope scope(m_isolate); 5935267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) v8::Context::Scope contextScope(v8::Debug::GetDebugContext()); 59493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) v8::Handle<v8::String> source = v8String(String(reinterpret_cast<const char*>(DebuggerScriptSource_js), sizeof(DebuggerScriptSource_js)), m_isolate); 5955267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) v8::Local<v8::Value> value = V8ScriptRunner::compileAndRunInternalScript(source, m_isolate); 59693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) ASSERT(!value.IsEmpty()); 59793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) ASSERT(value->IsObject()); 59893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) m_debuggerScript.set(m_isolate, v8::Handle<v8::Object>::Cast(value)); 5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)v8::Local<v8::Value> ScriptDebugServer::functionScopes(v8::Handle<v8::Function> function) 6025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ensureDebuggerScriptCompiled(); 6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Value> argv[] = { function }; 6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return callDebuggerMethod("getFunctionScopes", 1, argv); 6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)v8::Local<v8::Value> ScriptDebugServer::getInternalProperties(v8::Handle<v8::Object>& object) 6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 611591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (m_debuggerScript.isEmpty()) 6125267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return v8::Local<v8::Value>::New(m_isolate, v8::Undefined()); 6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Value> argv[] = { object }; 6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return callDebuggerMethod("getInternalProperties", 1, argv); 6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6185267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)v8::Handle<v8::Value> ScriptDebugServer::setFunctionVariableValue(v8::Handle<v8::Value> functionValue, int scopeNumber, const String& variableName, v8::Handle<v8::Value> newValue) 619926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 620926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext(); 621591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (m_debuggerScript.isEmpty()) 6225267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return v8::ThrowException(v8::String::New("Debugging is not enabled.")); 623926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 624926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) v8::Handle<v8::Value> argv[] = { 625926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) functionValue, 626926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) v8::Handle<v8::Value>(v8::Integer::New(scopeNumber)), 627926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) v8String(variableName, debuggerContext->GetIsolate()), 628926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) newValue 629926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) }; 630926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return callDebuggerMethod("setFunctionVariableValue", 4, argv); 631926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 632926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 6335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool ScriptDebugServer::isPaused() 6355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 636591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return !m_executionState.isEmpty(); 6375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptDebugServer::compileScript(ScriptState* state, const String& expression, const String& sourceURL, String* scriptId, String* exceptionMessage) 6405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 641591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::HandleScope handleScope(m_isolate); 6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Context> context = state->context(); 6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (context.IsEmpty()) 6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Context::Scope contextScope(context); 6465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 647591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::Handle<v8::String> source = v8String(expression, m_isolate); 6485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::TryCatch tryCatch; 649591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::Local<v8::Script> script = V8ScriptRunner::compileScript(source, sourceURL, TextPosition(), 0, m_isolate); 6505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (tryCatch.HasCaught()) { 6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Message> message = tryCatch.Message(); 6525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!message.IsEmpty()) 653926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *exceptionMessage = toWebCoreStringWithUndefinedOrNullCheck(message->Get()); 6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 6555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (script.IsEmpty()) 6575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 6585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 659926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *scriptId = toWebCoreStringWithUndefinedOrNullCheck(script->Id()); 6605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_compiledScripts.set(*scriptId, adoptPtr(new ScopedPersistent<v8::Script>(script))); 6615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptDebugServer::clearCompiledScripts() 6645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_compiledScripts.clear(); 6665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptDebugServer::runScript(ScriptState* state, const String& scriptId, ScriptValue* result, bool* wasThrown, String* exceptionMessage) 6695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_compiledScripts.contains(scriptId)) 6715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 672591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::HandleScope handleScope(m_isolate); 6735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ScopedPersistent<v8::Script>* scriptHandle = m_compiledScripts.get(scriptId); 674591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch v8::Local<v8::Script> script = scriptHandle->newLocal(m_isolate); 6755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_compiledScripts.remove(scriptId); 6765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (script.IsEmpty()) 6775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 6785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Context> context = state->context(); 6805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (context.IsEmpty()) 6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 6825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Context::Scope contextScope(context); 6835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::TryCatch tryCatch; 68493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) v8::Local<v8::Value> value = V8ScriptRunner::runCompiledScript(script, state->scriptExecutionContext()); 6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *wasThrown = false; 6865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (tryCatch.HasCaught()) { 6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *wasThrown = true; 6885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *result = ScriptValue(tryCatch.Exception()); 6895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Message> message = tryCatch.Message(); 6905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!message.IsEmpty()) 691926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *exceptionMessage = toWebCoreStringWithUndefinedOrNullCheck(message->Get()); 6925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 6935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *result = ScriptValue(value); 6945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore 697