Revision: 22043
Author:   [email protected]
Date:     Thu Jun 26 16:03:52 2014 UTC
Log:      Add OnCompileError handler and v8::CompileError debug event.
This event is generated when the parser can not generate code.

[email protected], [email protected], [email protected]

Review URL: https://codereview.chromium.org/264333007

Patch from Alexey Kozyatinskiy <[email protected]>.
http://code.google.com/p/v8/source/detail?r=22043

Modified:
 /branches/bleeding_edge/include/v8-debug.h
 /branches/bleeding_edge/src/debug-debugger.js
 /branches/bleeding_edge/src/debug.cc
 /branches/bleeding_edge/src/debug.h
 /branches/bleeding_edge/src/parser.cc
 /branches/bleeding_edge/test/cctest/test-debug.cc
 /branches/bleeding_edge/test/mjsunit/debug-compile-event.js

=======================================
--- /branches/bleeding_edge/include/v8-debug.h  Wed Jun 11 09:12:35 2014 UTC
+++ /branches/bleeding_edge/include/v8-debug.h  Thu Jun 26 16:03:52 2014 UTC
@@ -20,7 +20,8 @@
   BeforeCompile = 4,
   AfterCompile  = 5,
   ScriptCollected = 6,
-  BreakForCommand = 7
+  CompileError = 7,
+  BreakForCommand = 8
 };


=======================================
--- /branches/bleeding_edge/src/debug-debugger.js Wed Jun 25 09:13:09 2014 UTC +++ /branches/bleeding_edge/src/debug-debugger.js Thu Jun 26 16:03:52 2014 UTC
@@ -19,7 +19,8 @@
                      NewFunction: 3,
                      BeforeCompile: 4,
                      AfterCompile: 5,
-                     ScriptCollected: 6 };
+                     ScriptCollected: 6,
+                     CompileError: 7 };

 // Types of exceptions that can be broken upon.
 Debug.ExceptionBreak = { Caught : 0,
@@ -1143,23 +1144,19 @@
 };


-function MakeCompileEvent(script, before) {
-  return new CompileEvent(script, before);
+function MakeCompileEvent(script, type) {
+  return new CompileEvent(script, type);
 }


-function CompileEvent(script, before) {
+function CompileEvent(script, type) {
   this.script_ = MakeMirror(script);
-  this.before_ = before;
+  this.type_ = type;
 }


 CompileEvent.prototype.eventType = function() {
-  if (this.before_) {
-    return Debug.DebugEvent.BeforeCompile;
-  } else {
-    return Debug.DebugEvent.AfterCompile;
-  }
+  return this.type_;
 };


@@ -1171,10 +1168,13 @@
 CompileEvent.prototype.toJSONProtocol = function() {
   var o = new ProtocolMessage();
   o.running = true;
-  if (this.before_) {
-    o.event = "beforeCompile";
-  } else {
-    o.event = "afterCompile";
+  switch (this.type_) {
+    case Debug.DebugEvent.BeforeCompile:
+      o.event = "beforeCompile";
+    case Debug.DebugEvent.AfterCompile:
+      o.event = "afterCompile";
+    case Debug.DebugEvent.CompileError:
+      o.event = "compileError";
   }
   o.body = {};
   o.body.script = this.script_;
=======================================
--- /branches/bleeding_edge/src/debug.cc        Thu Jun 26 15:12:04 2014 UTC
+++ /branches/bleeding_edge/src/debug.cc        Thu Jun 26 16:03:52 2014 UTC
@@ -2554,11 +2554,11 @@


 MaybeHandle<Object> Debug::MakeCompileEvent(Handle<Script> script,
-                                            bool before) {
+                                            v8::DebugEvent type) {
   // Create the compile event object.
   Handle<Object> script_wrapper = Script::GetWrapper(script);
   Handle<Object> argv[] = { script_wrapper,
-                            isolate_->factory()->ToBoolean(before) };
+                            isolate_->factory()->NewNumberFromInt(type) };
   return MakeJSObject("MakeCompileEvent", ARRAY_SIZE(argv), argv);
 }

@@ -2605,6 +2605,24 @@
ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false);
   // Return to continue execution from where the exception was thrown.
 }
+
+
+void Debug::OnCompileError(Handle<Script> script) {
+  // No more to do if not debugging.
+  if (in_debug_scope() || ignore_events()) return;
+
+  HandleScope scope(isolate_);
+  DebugScope debug_scope(this);
+  if (debug_scope.failed()) return;
+
+  // Create the compile state object.
+  Handle<Object> event_data;
+  // Bail out and don't call debugger if exception.
+ if (!MakeCompileEvent(script, v8::CompileError).ToHandle(&event_data)) return;
+
+  // Process debug event.
+ ProcessDebugEvent(v8::CompileError, Handle<JSObject>::cast(event_data), true);
+}


 void Debug::OnDebugBreak(Handle<Object> break_points_hit,
@@ -2637,7 +2655,8 @@
   // Create the event data object.
   Handle<Object> event_data;
   // Bail out and don't call debugger if exception.
-  if (!MakeCompileEvent(script, true).ToHandle(&event_data)) return;
+  if (!MakeCompileEvent(script, v8::BeforeCompile).ToHandle(&event_data))
+    return;

   // Process debug event.
   ProcessDebugEvent(v8::BeforeCompile,
@@ -2690,7 +2709,7 @@
   // Create the compile state object.
   Handle<Object> event_data;
   // Bail out and don't call debugger if exception.
-  if (!MakeCompileEvent(script, false).ToHandle(&event_data)) return;
+ if (!MakeCompileEvent(script, v8::AfterCompile).ToHandle(&event_data)) return;

   // Process debug event.
ProcessDebugEvent(v8::AfterCompile, Handle<JSObject>::cast(event_data), true);
=======================================
--- /branches/bleeding_edge/src/debug.h Thu Jun 26 15:12:04 2014 UTC
+++ /branches/bleeding_edge/src/debug.h Thu Jun 26 16:03:52 2014 UTC
@@ -367,6 +367,7 @@
   // Debug event triggers.
   void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue);
   void OnException(Handle<Object> exception, bool uncaught);
+  void OnCompileError(Handle<Script> script);
   void OnBeforeCompile(Handle<Script> script);
   void OnAfterCompile(Handle<Script> script);
   void OnScriptCollected(int id);
@@ -542,7 +543,7 @@
       bool uncaught,
       Handle<Object> promise);
   MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent(
-      Handle<Script> script, bool before);
+      Handle<Script> script, v8::DebugEvent type);
   MUST_USE_RESULT MaybeHandle<Object> MakeScriptCollectedEvent(int id);

   // Mirror cache handling.
=======================================
--- /branches/bleeding_edge/src/parser.cc       Thu Jun 26 11:59:42 2014 UTC
+++ /branches/bleeding_edge/src/parser.cc       Thu Jun 26 16:03:52 2014 UTC
@@ -3888,6 +3888,8 @@
           .ToHandleChecked();
       elements->set(0, *arg_string);
     }
+    isolate()->debug()->OnCompileError(script_);
+
     Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
     Handle<Object> result = pending_error_is_reference_error_
         ? factory->NewReferenceError(pending_error_message_, array)
=======================================
--- /branches/bleeding_edge/test/cctest/test-debug.cc Wed Jun 25 12:42:28 2014 UTC +++ /branches/bleeding_edge/test/cctest/test-debug.cc Thu Jun 26 16:03:52 2014 UTC
@@ -6374,6 +6374,60 @@
   // Compilation cache should be disabled when debugger is active.
   CHECK_EQ(2, after_compile_message_count);
 }
+
+
+// Syntax error event handler which counts a number of events.
+int compile_error_event_count = 0;
+
+static void CompileErrorEventCounterClear() {
+  compile_error_event_count = 0;
+}
+
+static void CompileErrorEventCounter(
+    const v8::Debug::EventDetails& event_details) {
+  v8::DebugEvent event = event_details.GetEvent();
+
+  if (event == v8::CompileError) {
+    compile_error_event_count++;
+  }
+}
+
+
+// Tests that syntax error event is sent as many times as there are scripts
+// with syntax error compiled.
+TEST(SyntaxErrorMessageOnSyntaxException) {
+  DebugLocalContext env;
+  v8::HandleScope scope(env->GetIsolate());
+
+  // For this test, we want to break on uncaught exceptions:
+  ChangeBreakOnException(false, true);
+
+  v8::Debug::SetDebugEventListener(CompileErrorEventCounter);
+
+  CompileErrorEventCounterClear();
+
+  // Check initial state.
+  CHECK_EQ(0, compile_error_event_count);
+
+  // Throws SyntaxError: Unexpected end of input
+  v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "+++"));
+  CHECK_EQ(1, compile_error_event_count);
+
+  v8::Script::Compile(
+    v8::String::NewFromUtf8(env->GetIsolate(), "/sel\\/: \\"));
+  CHECK_EQ(2, compile_error_event_count);
+
+  v8::Script::Compile(
+    v8::String::NewFromUtf8(env->GetIsolate(), "JSON.parse('1234:')"));
+  CHECK_EQ(2, compile_error_event_count);
+
+  v8::Script::Compile(
+    v8::String::NewFromUtf8(env->GetIsolate(), "new RegExp('/\\/\\\\');"));
+  CHECK_EQ(2, compile_error_event_count);
+
+ v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "throw 1;"));
+  CHECK_EQ(2, compile_error_event_count);
+}


 // Tests that break event is sent when message handler is reset.
=======================================
--- /branches/bleeding_edge/test/mjsunit/debug-compile-event.js Wed May 29 12:40:21 2013 UTC +++ /branches/bleeding_edge/test/mjsunit/debug-compile-event.js Thu Jun 26 16:03:52 2014 UTC
@@ -32,6 +32,7 @@
 var exception = false;  // Exception in debug event listener.
 var before_compile_count = 0;
 var after_compile_count = 0;
+var compile_error_count = 0;
 var current_source = '';  // Current source being compiled.
 var source_count = 0;  // Total number of scources compiled.
 var host_compilations = 0;  // Number of scources compiled through the API.
@@ -48,11 +49,12 @@
 function listener(event, exec_state, event_data, data) {
   try {
     if (event == Debug.DebugEvent.BeforeCompile ||
-        event == Debug.DebugEvent.AfterCompile) {
+        event == Debug.DebugEvent.AfterCompile ||
+        event == Debug.DebugEvent.CompileError) {
       // Count the events.
       if (event == Debug.DebugEvent.BeforeCompile) {
         before_compile_count++;
-      } else {
+      } else if (event == Debug.DebugEvent.AfterCompile) {
         after_compile_count++;
         switch (event_data.script().compilationType()) {
           case Debug.ScriptCompilationType.Host:
@@ -62,6 +64,8 @@
             eval_compilations++;
             break;
         }
+      } else {
+        compile_error_count++;
       }

// If the compiled source contains 'eval' there will be additional compile
@@ -105,11 +109,17 @@
 // Using JSON.parse does not causes additional compilation events.
 compileSource('x=1; //# sourceURL=myscript.js');

+try {
+  compileSource('}');
+} catch(e) {
+}
+
 // Make sure that the debug event listener was invoked.
 assertFalse(exception, "exception in listener")

-// Number of before and after compile events should be the same.
-assertEquals(before_compile_count, after_compile_count);
+// Number of before and after + error events should be the same.
+assertEquals(before_compile_count, after_compile_count + compile_error_count);
+assertEquals(compile_error_count, 1);

 // Check the actual number of events (no compilation through the API as all
 // source compiled through eval).

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to