Index: test/cctest/test-debug.cc |
=================================================================== |
--- test/cctest/test-debug.cc (revision 1851) |
+++ test/cctest/test-debug.cc (working copy) |
@@ -167,11 +167,23 @@ |
(*env)->Global()->Get(v8::String::New(function_name))); |
} |
+ |
+// Compile and run the supplied source and return the requested function. |
+static v8::Local<v8::Function> CompileFunction(const char* source, |
+ const char* function_name) { |
+ |
+ v8::Script::Compile(v8::String::New(source))->Run(); |
+ return v8::Local<v8::Function>::Cast( |
+ v8::Context::GetCurrent()->Global()->Get(v8::String::New(function_name))); |
+} |
+ |
+ |
// Helper function that compiles and runs the source. |
static v8::Local<v8::Value> CompileRun(const char* source) { |
return v8::Script::Compile(v8::String::New(source))->Run(); |
} |
+ |
// Is there any debug info for the function? |
static bool HasDebugInfo(v8::Handle<v8::Function> fun) { |
Handle<v8::internal::JSFunction> f = v8::Utils::OpenHandle(*fun); |
@@ -4588,3 +4600,84 @@ |
CHECK_EQ("new name", last_script_name_hit); |
CHECK_EQ("abc 123", last_script_data_hit); |
} |
+ |
+ |
+static v8::Persistent<v8::Context> expected_context; |
+static v8::Handle<v8::Value> expected_context_data; |
+ |
+ |
+// Check that the expected context is the one generating the debug event. |
+static void ContextCheckMessageHandler(const v8::Debug::Message& message) { |
+ CHECK(message.GetEventContext() == expected_context); |
+ CHECK(message.GetEventContext()->GetData()->StrictEquals( |
+ 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)); |
+ } |
+} |
+ |
+ |
+// Test which creates two contexts and sets different embedder data on each. |
+// Checks that this data is set correctly and that when the debug message |
+// handler is called the expected context is the one active. |
+TEST(ContextData) { |
+ v8::HandleScope scope; |
+ |
+ v8::Debug::SetMessageHandler2(ContextCheckMessageHandler); |
+ |
+ // Create two contexts. |
+ v8::Persistent<v8::Context> context_1; |
+ v8::Persistent<v8::Context> context_2; |
+ v8::Handle<v8::ObjectTemplate> global_template = |
+ v8::Handle<v8::ObjectTemplate>(); |
+ v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>(); |
+ context_1 = v8::Context::New(NULL, global_template, global_object); |
+ context_2 = v8::Context::New(NULL, global_template, global_object); |
+ |
+ // Default data value is undefined. |
+ CHECK(context_1->GetData()->IsUndefined()); |
+ CHECK(context_2->GetData()->IsUndefined()); |
+ |
+ // Set and check different data values. |
+ v8::Handle<v8::Value> data_1 = v8::Number::New(1); |
+ v8::Handle<v8::Value> data_2 = v8::String::New("2"); |
+ context_1->SetData(data_1); |
+ context_2->SetData(data_2); |
+ CHECK(context_1->GetData()->StrictEquals(data_1)); |
+ CHECK(context_2->GetData()->StrictEquals(data_2)); |
+ |
+ // Simple test function which causes a break. |
+ char* source = "function f() { debugger; }"; |
+ |
+ // Enter and run function in the first context. |
+ { |
+ v8::Context::Scope context_scope(context_1); |
+ expected_context = context_1; |
+ expected_context_data = data_1; |
+ v8::Local<v8::Function> f = CompileFunction(source, "f"); |
+ f->Call(context_1->Global(), 0, NULL); |
+ } |
+ |
+ |
+ // Enter and run function in the second context. |
+ { |
+ v8::Context::Scope context_scope(context_2); |
+ expected_context = context_2; |
+ expected_context_data = data_2; |
+ v8::Local<v8::Function> f = CompileFunction(source, "f"); |
+ f->Call(context_2->Global(), 0, NULL); |
+ } |
+ |
+ // Two times compile event and two times break event. |
+ CHECK_GT(message_handler_hit_count, 4); |
+} |