From 897ecefe1e36074f2ad59f7d4f18e987bd034b30 Mon Sep 17 00:00:00 2001 From: "yurys@chromium.org" Date: Wed, 20 May 2009 07:28:42 +0000 Subject: [PATCH] Exposed method for finding global context by traversing context chain to API. Review URL: http://codereview.chromium.org/112035 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2005 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/debug.cc | 4 +- test/cctest/test-debug.cc | 127 ++++++++++++++++++++++++++++++++++---- 2 files changed, 117 insertions(+), 14 deletions(-) diff --git a/src/debug.cc b/src/debug.cc index 82772f4072..224b100a74 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -2384,7 +2384,9 @@ v8::Handle MessageImpl::GetJSON() const { v8::Handle MessageImpl::GetEventContext() const { - return v8::Utils::ToLocal(Debug::debugger_entry()->GetContext()); + Handle context = Debug::debugger_entry()->GetContext(); + Handle global_context(context->global_context()); + return v8::Utils::ToLocal(global_context); } diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc index 03eb0c951d..a075113fc2 100644 --- a/test/cctest/test-debug.cc +++ b/test/cctest/test-debug.cc @@ -4172,11 +4172,8 @@ TEST(DebuggerUnload) { } -// Debugger message handler which counts the number of times it is called. -static int message_handler_hit_count = 0; -static void MessageHandlerHitCount(const v8::Debug::Message& message) { - message_handler_hit_count++; - +// Sends continue command to the debugger. +static void SendContinueCommand() { const int kBufferSize = 1000; uint16_t buffer[kBufferSize]; const char* command_continue = @@ -4188,6 +4185,15 @@ static void MessageHandlerHitCount(const v8::Debug::Message& message) { } +// Debugger message handler which counts the number of times it is called. +static int message_handler_hit_count = 0; +static void MessageHandlerHitCount(const v8::Debug::Message& message) { + message_handler_hit_count++; + + SendContinueCommand(); +} + + // Test clearing the debug message handler. TEST(DebuggerClearMessageHandler) { v8::HandleScope scope; @@ -4624,16 +4630,9 @@ static void ContextCheckMessageHandler(const v8::Debug::Message& message) { expected_context_data)); message_handler_hit_count++; - const int kBufferSize = 1000; - uint16_t buffer[kBufferSize]; - const char* command_continue = - "{\"seq\":0," - "\"type\":\"request\"," - "\"command\":\"continue\"}"; - // Send a continue command for break events. if (message.GetEvent() == v8::Break) { - v8::Debug::SendCommand(buffer, AsciiToUtf16(command_continue, buffer)); + SendContinueCommand(); } } @@ -4694,6 +4693,108 @@ TEST(ContextData) { } +// Common part of EvalContextData and NestedBreakEventContextData tests. +static void ExecuteScriptForContextCheck() { + // Create a context. + v8::Persistent context_1; + v8::Handle global_template = + v8::Handle(); + v8::Handle global_object = v8::Handle(); + context_1 = v8::Context::New(NULL, global_template, global_object); + + // Default data value is undefined. + CHECK(context_1->GetData()->IsUndefined()); + + // Set and check a data value. + v8::Handle data_1 = v8::Number::New(1); + context_1->SetData(data_1); + CHECK(context_1->GetData()->StrictEquals(data_1)); + + // Simple test function with eval that causes a break. + const char* source = "function f() { eval('debugger;'); }"; + + // Enter and run function in the context. + { + v8::Context::Scope context_scope(context_1); + expected_context = context_1; + expected_context_data = data_1; + v8::Local f = CompileFunction(source, "f"); + f->Call(context_1->Global(), 0, NULL); + } +} + + +// Test which creates a context and sets embedder data on it. Checks that this +// data is set correctly and that when the debug message handler is called for +// break event in an eval statement the expected context is the one returned by +// Message.GetEventContext. +TEST(EvalContextData) { + v8::HandleScope scope; + v8::Debug::SetMessageHandler2(ContextCheckMessageHandler); + + ExecuteScriptForContextCheck(); + + // One time compile event and one time break event. + CHECK_GT(message_handler_hit_count, 2); +} + + +static bool sent_eval = false; +static int break_count = 0; +// Check that the expected context is the one generating the debug event +// including the case of nested break event. +static void DebugEvalContextCheckMessageHandler( + const v8::Debug::Message& message) { + CHECK(message.GetEventContext() == expected_context); + CHECK(message.GetEventContext()->GetData()->StrictEquals( + expected_context_data)); + message_handler_hit_count++; + + if (message.IsEvent() && message.GetEvent() == v8::Break) { + break_count++; + if (!sent_eval) { + sent_eval = true; + + const int kBufferSize = 1000; + uint16_t buffer[kBufferSize]; + const char* eval_command = + "{\"seq\":0," + "\"type\":\"request\"," + "\"command\":\"evaluate\"," + "arguments:{\"expression\":\"debugger;\"," + "\"global\":true,\"disable_break\":false}}"; + + // Send evaluate command. + v8::Debug::SendCommand(buffer, AsciiToUtf16(eval_command, buffer)); + return; + } else { + // It's a break event caused by the evaluation request above. + SendContinueCommand(); + } + } else if (message.IsResponse()) { + // Response to the evaluation request. We're still on the breakpoint so + // send continue. + SendContinueCommand(); + } +} + + +// Tests that context returned for break event is correct when the event occurs +// in 'evaluate' debugger request. +TEST(NestedBreakEventContextData) { + v8::HandleScope scope; + v8::Debug::SetMessageHandler2(DebugEvalContextCheckMessageHandler); + + ExecuteScriptForContextCheck(); + + // One time compile event and two times break event. + CHECK_GT(message_handler_hit_count, 3); + + // One break from the source and another from the evaluate request. + CHECK_EQ(break_count, 2); +} + + // Debug event listener which counts the script collected events. int script_collected_count = 0; static void DebugEventScriptCollectedEvent(v8::DebugEvent event,