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