New version of v8 from bleeding edge at revision 3649
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index 5b72193..cd0da1b 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -443,6 +443,9 @@
// Check that the debugger has been fully unloaded.
static void CheckDebuggerUnloaded(bool check_functions = false) {
+ // Let debugger to unload itself synchronously
+ v8::Debug::ProcessDebugMessages();
+
v8::internal::CheckDebuggerUnloaded(check_functions);
}
@@ -2160,6 +2163,155 @@
CheckDebuggerUnloaded();
}
+// Copies a C string to a 16-bit string. Does not check for buffer overflow.
+// Does not use the V8 engine to convert strings, so it can be used
+// in any thread. Returns the length of the string.
+int AsciiToUtf16(const char* input_buffer, uint16_t* output_buffer) {
+ int i;
+ for (i = 0; input_buffer[i] != '\0'; ++i) {
+ // ASCII does not use chars > 127, but be careful anyway.
+ output_buffer[i] = static_cast<unsigned char>(input_buffer[i]);
+ }
+ output_buffer[i] = 0;
+ return i;
+}
+
+// Copies a 16-bit string to a C string by dropping the high byte of
+// each character. Does not check for buffer overflow.
+// Can be used in any thread. Requires string length as an input.
+int Utf16ToAscii(const uint16_t* input_buffer, int length,
+ char* output_buffer, int output_len = -1) {
+ if (output_len >= 0) {
+ if (length > output_len - 1) {
+ length = output_len - 1;
+ }
+ }
+
+ for (int i = 0; i < length; ++i) {
+ output_buffer[i] = static_cast<char>(input_buffer[i]);
+ }
+ output_buffer[length] = '\0';
+ return length;
+}
+
+
+// We match parts of the message to get evaluate result int value.
+bool GetEvaluateStringResult(char *message, char* buffer, int buffer_size) {
+ const char* value = "\"value\":";
+ char* pos = strstr(message, value);
+ if (pos == NULL) {
+ return false;
+ }
+ Vector<char> buf(buffer, buffer_size);
+ OS::StrNCpy(buf, pos, buffer_size);
+ buffer[buffer_size - 1] = '\0';
+ return true;
+}
+
+
+struct EvaluateResult {
+ static const int kBufferSize = 20;
+ char buffer[kBufferSize];
+};
+
+struct DebugProcessDebugMessagesData {
+ static const int kArraySize = 5;
+ int counter;
+ EvaluateResult results[kArraySize];
+
+ void reset() {
+ counter = 0;
+ }
+ EvaluateResult* current() {
+ return &results[counter % kArraySize];
+ }
+ void next() {
+ counter++;
+ }
+};
+
+DebugProcessDebugMessagesData process_debug_messages_data;
+
+static void DebugProcessDebugMessagesHandler(
+ const uint16_t* message,
+ int length,
+ v8::Debug::ClientData* client_data) {
+
+ const int kBufferSize = 100000;
+ char print_buffer[kBufferSize];
+ Utf16ToAscii(message, length, print_buffer, kBufferSize);
+
+ EvaluateResult* array_item = process_debug_messages_data.current();
+
+ bool res = GetEvaluateStringResult(print_buffer,
+ array_item->buffer,
+ EvaluateResult::kBufferSize);
+ if (res) {
+ process_debug_messages_data.next();
+ }
+}
+
+// Test that the evaluation of expressions works even from ProcessDebugMessages
+// i.e. with empty stack.
+TEST(DebugEvaluateWithoutStack) {
+ v8::Debug::SetMessageHandler(DebugProcessDebugMessagesHandler);
+
+ v8::HandleScope scope;
+ DebugLocalContext env;
+
+ const char* source =
+ "var v1 = 'Pinguin';\n function getAnimal() { return 'Capy' + 'bara'; }";
+
+ v8::Script::Compile(v8::String::New(source))->Run();
+
+ v8::Debug::ProcessDebugMessages();
+
+ const int kBufferSize = 1000;
+ uint16_t buffer[kBufferSize];
+
+ const char* command_111 = "{\"seq\":111,"
+ "\"type\":\"request\","
+ "\"command\":\"evaluate\","
+ "\"arguments\":{"
+ " \"global\":true,"
+ " \"expression\":\"v1\",\"disable_break\":true"
+ "}}";
+
+ v8::Debug::SendCommand(buffer, AsciiToUtf16(command_111, buffer));
+
+ const char* command_112 = "{\"seq\":112,"
+ "\"type\":\"request\","
+ "\"command\":\"evaluate\","
+ "\"arguments\":{"
+ " \"global\":true,"
+ " \"expression\":\"getAnimal()\",\"disable_break\":true"
+ "}}";
+
+ v8::Debug::SendCommand(buffer, AsciiToUtf16(command_112, buffer));
+
+ const char* command_113 = "{\"seq\":113,"
+ "\"type\":\"request\","
+ "\"command\":\"evaluate\","
+ "\"arguments\":{"
+ " \"global\":true,"
+ " \"expression\":\"239 + 566\",\"disable_break\":true"
+ "}}";
+
+ v8::Debug::SendCommand(buffer, AsciiToUtf16(command_113, buffer));
+
+ v8::Debug::ProcessDebugMessages();
+
+ CHECK_EQ(3, process_debug_messages_data.counter);
+
+ CHECK(strcmp("Pinguin", process_debug_messages_data.results[0].buffer));
+ CHECK(strcmp("Captbara", process_debug_messages_data.results[1].buffer));
+ CHECK(strcmp("805", process_debug_messages_data.results[2].buffer));
+
+ v8::Debug::SetMessageHandler(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
+ CheckDebuggerUnloaded();
+}
+
// Simple test of the stepping mechanism using only store ICs.
TEST(DebugStepLinear) {
@@ -3141,6 +3293,39 @@
CheckDebuggerUnloaded();
}
+static const char* kSimpleExtensionSource =
+ "(function Foo() {"
+ " return 4;"
+ "})() ";
+
+// http://crbug.com/28933
+// Test that debug break is disabled when bootstrapper is active.
+TEST(NoBreakWhenBootstrapping) {
+ v8::HandleScope scope;
+
+ // Register a debug event listener which sets the break flag and counts.
+ v8::Debug::SetDebugEventListener(DebugEventCounter);
+
+ // Set the debug break flag.
+ v8::Debug::DebugBreak();
+ break_point_hit_count = 0;
+ {
+ // Create a context with an extension to make sure that some JavaScript
+ // code is executed during bootstrapping.
+ v8::RegisterExtension(new v8::Extension("simpletest",
+ kSimpleExtensionSource));
+ const char* extension_names[] = { "simpletest" };
+ v8::ExtensionConfiguration extensions(1, extension_names);
+ v8::Persistent<v8::Context> context = v8::Context::New(&extensions);
+ context.Dispose();
+ }
+ // Check that no DebugBreak events occured during the context creation.
+ CHECK_EQ(0, break_point_hit_count);
+
+ // Get rid of the debug event listener.
+ v8::Debug::SetDebugEventListener(NULL);
+ CheckDebuggerUnloaded();
+}
static v8::Handle<v8::Array> NamedEnum(const v8::AccessorInfo&) {
v8::Handle<v8::Array> result = v8::Array::New(3);
@@ -3557,31 +3742,6 @@
// Support classes
-// Copies a C string to a 16-bit string. Does not check for buffer overflow.
-// Does not use the V8 engine to convert strings, so it can be used
-// in any thread. Returns the length of the string.
-int AsciiToUtf16(const char* input_buffer, uint16_t* output_buffer) {
- int i;
- for (i = 0; input_buffer[i] != '\0'; ++i) {
- // ASCII does not use chars > 127, but be careful anyway.
- output_buffer[i] = static_cast<unsigned char>(input_buffer[i]);
- }
- output_buffer[i] = 0;
- return i;
-}
-
-// Copies a 16-bit string to a C string by dropping the high byte of
-// each character. Does not check for buffer overflow.
-// Can be used in any thread. Requires string length as an input.
-int Utf16ToAscii(const uint16_t* input_buffer, int length,
- char* output_buffer) {
- for (int i = 0; i < length; ++i) {
- output_buffer[i] = static_cast<char>(input_buffer[i]);
- }
- output_buffer[length] = '\0';
- return length;
-}
-
// Provides synchronization between k threads, where k is an input to the
// constructor. The Wait() call blocks a thread until it is called for the
// k'th time, then all calls return. Each ThreadBarrier object can only
@@ -5622,6 +5782,51 @@
}
+static int counting_message_handler_counter;
+
+static void CountingMessageHandler(const v8::Debug::Message& message) {
+ counting_message_handler_counter++;
+}
+
+// Test that debug messages get processed when ProcessDebugMessages is called.
+TEST(ProcessDebugMessages) {
+ v8::HandleScope scope;
+ DebugLocalContext env;
+
+ counting_message_handler_counter = 0;
+
+ v8::Debug::SetMessageHandler2(CountingMessageHandler);
+
+ const int kBufferSize = 1000;
+ uint16_t buffer[kBufferSize];
+ const char* scripts_command =
+ "{\"seq\":0,"
+ "\"type\":\"request\","
+ "\"command\":\"scripts\"}";
+
+ // Send scripts command.
+ v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer));
+
+ CHECK_EQ(0, counting_message_handler_counter);
+ v8::Debug::ProcessDebugMessages();
+ // At least one message should come
+ CHECK_GE(counting_message_handler_counter, 1);
+
+ counting_message_handler_counter = 0;
+
+ v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer));
+ v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer));
+ CHECK_EQ(0, counting_message_handler_counter);
+ v8::Debug::ProcessDebugMessages();
+ // At least two messages should come
+ CHECK_GE(counting_message_handler_counter, 2);
+
+ // Get rid of the debug message handler.
+ v8::Debug::SetMessageHandler2(NULL);
+ CheckDebuggerUnloaded();
+}
+
+
TEST(GetMirror) {
v8::HandleScope scope;
DebugLocalContext env;