Author: [email protected]
Date: Thu Feb 19 03:42:34 2009
New Revision: 1313

Modified:
    branches/experimental/toiger/   (props changed)
    branches/experimental/toiger/ChangeLog
    branches/experimental/toiger/src/api.cc
    branches/experimental/toiger/src/d8.js
    branches/experimental/toiger/src/debug-arm.cc
    branches/experimental/toiger/src/debug-delay.js
    branches/experimental/toiger/src/debug-ia32.cc
    branches/experimental/toiger/src/debug.cc
    branches/experimental/toiger/src/debug.h
    branches/experimental/toiger/src/jsregexp.cc
    branches/experimental/toiger/src/jsregexp.h
    branches/experimental/toiger/src/objects-debug.cc
    branches/experimental/toiger/src/objects.cc
    branches/experimental/toiger/src/regexp-macro-assembler-irregexp-inl.h    
(props changed)
    branches/experimental/toiger/test/cctest/test-debug.cc
    branches/experimental/toiger/test/mjsunit/debug-evaluate-recursive.js

Log:
Experimental: merge from the bleeding_edge branch.  Merge
bleeding_edge revisions 1261-1275.

Modified: branches/experimental/toiger/ChangeLog
==============================================================================
--- branches/experimental/toiger/ChangeLog      (original)
+++ branches/experimental/toiger/ChangeLog      Thu Feb 19 03:42:34 2009
@@ -1,16 +1,28 @@
+2009-02-13: Version 1.0.1
+
+        Fixed two crash-bugs in irregexp (issue 231 and 233).
+
+        Fixed a number of minor bugs (issue 87, 227 and 228).
+
+        Added support for morphing strings to external strings on demand
+        to avoid having to create copies in the embedding code.
+
+        Removed experimental support for external symbol callbacks.
+
+
  2009-02-09: Version 1.0.0

          Fixed crash-bug in the code generation for case independent 16 bit
          backreferences.
-
+
          Made shells more robust in the presence of string conversion
          failures (issue 224).
-
+
          Fixed a potential infinite loop when attempting to resolve
          eval (issue 221).
-
+
          Miscellaneous fixes to the new regular expression engine.
-
+
          Reduced binary by stripping unneeded text from JavaScript library  
and
          minifying some JavaScript files.


Modified: branches/experimental/toiger/src/api.cc
==============================================================================
--- branches/experimental/toiger/src/api.cc     (original)
+++ branches/experimental/toiger/src/api.cc     Thu Feb 19 03:42:34 2009
@@ -2184,7 +2184,7 @@


  const char* v8::V8::GetVersion() {
-  return "1.0.1 (candidate)";
+  return "1.0.2 (candidate)";
  }


@@ -2888,8 +2888,11 @@
    EnsureInitialized("v8::Debug::SetDebugEventListener()");
    ON_BAILOUT("v8::Debug::SetDebugEventListener()", return false);
    HandleScope scope;
-  i::Debugger::SetEventListener(i::Factory::NewProxy(FUNCTION_ADDR(that)),
-                                Utils::OpenHandle(*data));
+  i::Handle<i::Object> proxy = i::Factory::undefined_value();
+  if (that != NULL) {
+    proxy = i::Factory::NewProxy(FUNCTION_ADDR(that));
+  }
+  i::Debugger::SetEventListener(proxy, Utils::OpenHandle(*data));
    return true;
  }


Modified: branches/experimental/toiger/src/d8.js
==============================================================================
--- branches/experimental/toiger/src/d8.js      (original)
+++ branches/experimental/toiger/src/d8.js      Thu Feb 19 03:42:34 2009
@@ -381,6 +381,10 @@
      var request = this.createRequest('evaluate');
      request.arguments = {};
      request.arguments.expression = expression;
+    // Request a global evaluation if there is no current frame.
+    if (Debug.State.currentFrame == kNoFrame) {
+      request.arguments.global = true;
+    }
      return request.toJSONProtocol();
    }
  };
@@ -795,7 +799,7 @@
        case 'evaluate':
        case 'lookup':
          if (last_cmd == 'p' || last_cmd == 'print') {
-          details.text =  body.text;
+          result = body.text;
          } else {
            var value = response.bodyValue();
            if (value.isObject()) {
@@ -984,10 +988,10 @@


  ProtocolPackage.prototype.bodyValue = function(index) {
-  if (IS_UNDEFINED(index)) {
-    return new ProtocolValue(this.packet_.body, this);
-  } else {
+  if (index) {
      return new ProtocolValue(this.packet_.body[index], this);
+  } else {
+    return new ProtocolValue(this.packet_.body, this);
    }
  }


Modified: branches/experimental/toiger/src/debug-arm.cc
==============================================================================
--- branches/experimental/toiger/src/debug-arm.cc       (original)
+++ branches/experimental/toiger/src/debug-arm.cc       Thu Feb 19 03:42:34 2009
@@ -51,6 +51,13 @@
  }


+bool Debug::IsDebugBreakAtReturn(RelocInfo* rinfo) {
+  ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()));
+  // Currently debug break is not supported in frame exit code on ARM.
+  return false;
+}
+
+
  #define __ masm->



Modified: branches/experimental/toiger/src/debug-delay.js
==============================================================================
--- branches/experimental/toiger/src/debug-delay.js     (original)
+++ branches/experimental/toiger/src/debug-delay.js     Thu Feb 19 03:42:34 2009
@@ -1421,6 +1421,11 @@
      disable_break = true;
    }

+  // No frames no evaluate in frame.
+  if (this.exec_state_.frameCount() == 0) {
+    return response.failed('No frames');
+  }
+
    // Check whether a frame was specified.
    if (!IS_UNDEFINED(frame)) {
      var frame_number = %ToNumber(frame);

Modified: branches/experimental/toiger/src/debug-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/debug-ia32.cc      (original)
+++ branches/experimental/toiger/src/debug-ia32.cc      Thu Feb 19 03:42:34 2009
@@ -37,7 +37,7 @@
  // A debug break in the frame exit code is identified by a call  
instruction.
  bool BreakLocationIterator::IsDebugBreakAtReturn() {
    // Opcode E8 is call.
-  return (*(rinfo()->pc()) == 0xE8);
+  return Debug::IsDebugBreakAtReturn(rinfo());
  }


@@ -56,6 +56,14 @@
  void BreakLocationIterator::ClearDebugBreakAtReturn() {
    rinfo()->PatchCode(original_rinfo()->pc(),
                       Debug::kIa32JSReturnSequenceLength);
+}
+
+
+// Check whether the JS frame exit code has been patched with a debug  
break.
+bool Debug::IsDebugBreakAtReturn(RelocInfo* rinfo) {
+  ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()));
+  // Opcode E8 is call.
+  return (*(rinfo->pc()) == 0xE8);
  }



Modified: branches/experimental/toiger/src/debug.cc
==============================================================================
--- branches/experimental/toiger/src/debug.cc   (original)
+++ branches/experimental/toiger/src/debug.cc   Thu Feb 19 03:42:34 2009
@@ -314,6 +314,8 @@


  void BreakLocationIterator::PrepareStepIn() {
+  HandleScope scope;
+
    // Step in can only be prepared if currently positioned on an IC call or
    // construct call.
    Address target = rinfo()->target_address();
@@ -363,6 +365,17 @@
  }


+// Clear out all the debug break code. This is ONLY supposed to be used  
when
+// shutting down the debugger as it will leave the break point information  
in
+// DebugInfo even though the code is patched back to the non break point  
state.
+void BreakLocationIterator::ClearAllDebugBreak() {
+  while (!Done()) {
+    ClearDebugBreak();
+    Next();
+  }
+}
+
+
  bool BreakLocationIterator::RinfoDone() const {
    ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done());
    return reloc_iterator_->done();
@@ -589,6 +602,9 @@
      return;
    }

+  // Get rid of all break points and related information.
+  ClearAllBreakPoints();
+
    // Clear debugger context global handle.
     
GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_context_.location()));
    debug_context_ = Handle<Context>();
@@ -715,6 +731,8 @@

  // Check whether a single break point object is triggered.
  bool Debug::CheckBreakPoint(Handle<Object> break_point_object) {
+  HandleScope scope;
+
    // Ignore check if break point object is not a JSObject.
    if (!break_point_object->IsJSObject()) return true;

@@ -765,6 +783,8 @@
  void Debug::SetBreakPoint(Handle<SharedFunctionInfo> shared,
                            int source_position,
                            Handle<Object> break_point_object) {
+  HandleScope scope;
+
    if (!EnsureDebugInfo(shared)) {
      // Return if retrieving debug info failed.
      return;
@@ -785,6 +805,8 @@


  void Debug::ClearBreakPoint(Handle<Object> break_point_object) {
+  HandleScope scope;
+
    DebugInfoListNode* node = debug_info_list_;
    while (node != NULL) {
      Object* result = DebugInfo::FindBreakPointInfo(node->debug_info(),
@@ -817,6 +839,22 @@
  }


+void Debug::ClearAllBreakPoints() {
+  DebugInfoListNode* node = debug_info_list_;
+  while (node != NULL) {
+    // Remove all debug break code.
+    BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
+    it.ClearAllDebugBreak();
+    node = node->next();
+  }
+
+  // Remove all debug info.
+  while (debug_info_list_ != NULL) {
+    RemoveDebugInfo(debug_info_list_->debug_info());
+  }
+}
+
+
  void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) {
    // Make sure the function has setup the debug info.
    if (!EnsureDebugInfo(shared)) {
@@ -1214,6 +1252,8 @@


  void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
+  HandleScope scope;
+
    // Get the executing function in which the debug break occurred.
    Handle<SharedFunctionInfo> shared =
         
Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared());
@@ -1297,6 +1337,7 @@


  void Debug::ClearMirrorCache() {
+  HandleScope scope;
    ASSERT(Top::context() == *Debug::debug_context());

    // Clear the mirror cache.
@@ -1596,6 +1637,8 @@

  void Debugger::ProcessDebugEvent(v8::DebugEvent event,
                                   Handle<Object> event_data) {
+  HandleScope scope;
+
    // Create the execution state.
    bool caught_exception = false;
    Handle<Object> exec_state = MakeExecutionState(&caught_exception);
@@ -1712,6 +1755,9 @@
    if (!debugger_active() && message_thread_) {
      message_thread_->OnDebuggerInactive();
    }
+  if (!debugger_active()) {
+    Debug::Unload();
+  }
  }


@@ -1816,6 +1862,8 @@
  void DebugMessageThread::DebugEvent(v8::DebugEvent event,
                                      Handle<Object> exec_state,
                                      Handle<Object> event_data) {
+  HandleScope scope;
+
    if (!Debug::Load()) return;

    // Process the individual events.

Modified: branches/experimental/toiger/src/debug.h
==============================================================================
--- branches/experimental/toiger/src/debug.h    (original)
+++ branches/experimental/toiger/src/debug.h    Thu Feb 19 03:42:34 2009
@@ -89,6 +89,7 @@
    bool HasBreakPoint();
    bool IsDebugBreak();
    Object* BreakPointObjects();
+  void ClearAllDebugBreak();


    inline int code_position() { return pc() - debug_info_->code()->entry();  
}
@@ -172,6 +173,7 @@
                              int source_position,
                              Handle<Object> break_point_object);
    static void ClearBreakPoint(Handle<Object> break_point_object);
+  static void ClearAllBreakPoints();
    static void FloodWithOneShot(Handle<SharedFunctionInfo> shared);
    static void FloodHandlerWithOneShot();
    static void ChangeBreakOnException(ExceptionBreakType type, bool enable);
@@ -186,6 +188,7 @@
    static bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared);

    static bool IsDebugBreak(Address addr);
+  static bool IsDebugBreakAtReturn(RelocInfo* rinfo);

    // Check whether a code stub with the specified major key is a possible  
break
    // point location.
@@ -257,7 +260,8 @@
    static void HandleWeakDebugInfo(v8::Persistent<v8::Value> obj, void*  
data);

    friend class Debugger;
-  friend Handle<FixedArray> GetDebuggedFunctions();  // Found in  
test-debug.cc
+  friend Handle<FixedArray> GetDebuggedFunctions();  // In test-debug.cc
+  friend void CheckDebuggerUnloaded(bool check_functions);  // In  
test-debug.cc

    // Threading support.
    static char* ArchiveDebug(char* to);

Modified: branches/experimental/toiger/src/jsregexp.cc
==============================================================================
--- branches/experimental/toiger/src/jsregexp.cc        (original)
+++ branches/experimental/toiger/src/jsregexp.cc        Thu Feb 19 03:42:34 2009
@@ -298,7 +298,7 @@
        return AtomExec(regexp, subject, index);
      case JSRegExp::IRREGEXP: {
        Handle<Object> result = IrregexpExec(regexp, subject, index);
-      if (result.is_null()) ASSERT(Top::has_pending_exception());
+      ASSERT(!result.is_null() || Top::has_pending_exception());
        return result;
      }
      case JSRegExp::JSCRE:
@@ -317,7 +317,7 @@
        return AtomExecGlobal(regexp, subject);
      case JSRegExp::IRREGEXP: {
        Handle<Object> result = IrregexpExecGlobal(regexp, subject);
-      if (result.is_null()) ASSERT(Top::has_pending_exception());
+      ASSERT(!result.is_null() || Top::has_pending_exception());
        return result;
      }
      case JSRegExp::JSCRE:
@@ -823,6 +823,11 @@
                                   offsets.vector(),
                                   offsets.length());

+      if (matches.is_null()) {
+        ASSERT(Top::has_pending_exception());
+        return matches;
+      }
+
        if (matches->IsJSArray()) {
          SetElement(result, i, matches);
          i++;
@@ -830,10 +835,9 @@
          if (offsets.vector()[0] == offsets.vector()[1]) {
            previous_index++;
          }
-      } else if (matches->IsNull()) {
-        return result;
        } else {
-        return matches;
+        ASSERT(matches->IsNull());
+        return result;
        }
      }
    }

Modified: branches/experimental/toiger/src/jsregexp.h
==============================================================================
--- branches/experimental/toiger/src/jsregexp.h (original)
+++ branches/experimental/toiger/src/jsregexp.h Thu Feb 19 03:42:34 2009
@@ -55,7 +55,6 @@
                                  Handle<String> pattern,
                                  Handle<String> flags);

-  // Implements RegExp.prototype.exec(string) function.
    // See ECMA-262 section 15.10.6.2.
    // This function calls the garbage collector if necessary.
    static Handle<Object> Exec(Handle<JSRegExp> regexp,
@@ -155,6 +154,9 @@
                                        int* ovector,
                                        int ovector_length);

+  // On a successful match, the result is a JSArray containing
+  // captured positions. On a failure, the result is the null value.
+  // Returns an empty handle in case of an exception.
    static Handle<Object> IrregexpExecOnce(Handle<FixedArray> regexp,
                                           int num_captures,
                                           Handle<String> subject16,

Modified: branches/experimental/toiger/src/objects-debug.cc
==============================================================================
--- branches/experimental/toiger/src/objects-debug.cc   (original)
+++ branches/experimental/toiger/src/objects-debug.cc   Thu Feb 19 03:42:34  
2009
@@ -552,11 +552,11 @@
    PrintF(" - name: ");
    name()->ShortPrint();
    PrintF("\n - expected_nof_properties: %d", expected_nof_properties());
-  PrintF("\n - instance class name =");
+  PrintF("\n - instance class name = ");
    instance_class_name()->Print();
-  PrintF("\n - code =");
+  PrintF("\n - code = ");
    code()->ShortPrint();
-  PrintF("\n - source code =");
+  PrintF("\n - source code = ");
    GetSourceCode()->ShortPrint();
    PrintF("\n - lazy load: %s",
           lazy_load_data() == Heap::undefined_value() ? "no" : "yes");
@@ -568,7 +568,7 @@
    PrintF("\n - end position = %d", end_position());
    PrintF("\n - is expression = %d", is_expression());
    PrintF("\n - debug info = ");
-  debug_info()->Print();
+  debug_info()->ShortPrint();
    PrintF("\n - length = %d", length());
    PrintF("\n");
  }
@@ -752,7 +752,7 @@
  }

  void AccessorInfo::AccessorInfoPrint() {
-  PrintF("AccessorInfo");
+  HeapObject::PrintHeader("AccessorInfo");
    PrintF("\n - getter: ");
    getter()->ShortPrint();
    PrintF("\n - setter: ");
@@ -773,7 +773,7 @@
  }

  void AccessCheckInfo::AccessCheckInfoPrint() {
-  PrintF("AccessCheckInfo");
+  HeapObject::PrintHeader("AccessCheckInfo");
    PrintF("\n - named_callback: ");
    named_callback()->ShortPrint();
    PrintF("\n - indexed_callback: ");
@@ -793,7 +793,7 @@
  }

  void InterceptorInfo::InterceptorInfoPrint() {
-  PrintF("InterceptorInfo");
+  HeapObject::PrintHeader("InterceptorInfo");
    PrintF("\n - getter: ");
    getter()->ShortPrint();
    PrintF("\n - setter: ");
@@ -815,7 +815,7 @@
  }

  void CallHandlerInfo::CallHandlerInfoPrint() {
-  PrintF("CallHandlerInfo");
+  HeapObject::PrintHeader("CallHandlerInfo");
    PrintF("\n - callback: ");
    callback()->ShortPrint();
    PrintF("\n - data: ");
@@ -843,7 +843,7 @@
  }

  void FunctionTemplateInfo::FunctionTemplateInfoPrint() {
-  PrintF("FunctionTemplateInfo");
+  HeapObject::PrintHeader("FunctionTemplateInfo");
    PrintF("\n - tag: ");
    tag()->ShortPrint();
    PrintF("\n - property_list: ");
@@ -881,7 +881,7 @@
  }

  void ObjectTemplateInfo::ObjectTemplateInfoPrint() {
-  PrintF("ObjectTemplateInfo");
+  HeapObject::PrintHeader("ObjectTemplateInfo");
    PrintF("\n - constructor: ");
    constructor()->ShortPrint();
    PrintF("\n - internal_field_count: ");
@@ -895,7 +895,7 @@
  }

  void SignatureInfo::SignatureInfoPrint() {
-  PrintF("SignatureInfo");
+  HeapObject::PrintHeader("SignatureInfo");
    PrintF("\n - receiver: ");
    receiver()->ShortPrint();
    PrintF("\n - args: ");
@@ -908,7 +908,7 @@
  }

  void TypeSwitchInfo::TypeSwitchInfoPrint() {
-  PrintF("TypeSwitchInfo");
+  HeapObject::PrintHeader("TypeSwitchInfo");
    PrintF("\n - types: ");
    types()->ShortPrint();
  }
@@ -950,15 +950,15 @@


  void DebugInfo::DebugInfoPrint() {
-  PrintF("DebugInfo");
-  PrintF("\n - shared");
+  HeapObject::PrintHeader("DebugInfo");
+  PrintF("\n - shared: ");
    shared()->ShortPrint();
-  PrintF("\n - original_code");
+  PrintF("\n - original_code: ");
    original_code()->ShortPrint();
-  PrintF("\n - code");
+  PrintF("\n - code: ");
    code()->ShortPrint();
-  PrintF("\n - break_points");
-  break_points()->ShortPrint();
+  PrintF("\n - break_points: ");
+  break_points()->Print();
  }


@@ -972,11 +972,11 @@


  void BreakPointInfo::BreakPointInfoPrint() {
-  PrintF("BreakPointInfo");
-  PrintF("\n - code_position %d", code_position());
-  PrintF("\n - source_position %d", source_position());
-  PrintF("\n - statement_position %d", statement_position());
-  PrintF("\n - break_point_objects ");
+  HeapObject::PrintHeader("BreakPointInfo");
+  PrintF("\n - code_position: %d", code_position());
+  PrintF("\n - source_position: %d", source_position());
+  PrintF("\n - statement_position: %d", statement_position());
+  PrintF("\n - break_point_objects: ");
    break_point_objects()->ShortPrint();
  }


Modified: branches/experimental/toiger/src/objects.cc
==============================================================================
--- branches/experimental/toiger/src/objects.cc (original)
+++ branches/experimental/toiger/src/objects.cc Thu Feb 19 03:42:34 2009
@@ -926,7 +926,9 @@
        break;
  #define MAKE_STRUCT_CASE(NAME, Name, name) \
    case NAME##_TYPE:                        \
+    accumulator->Put('<');                 \
      accumulator->Add(#Name);               \
+    accumulator->Put('>');                 \
      break;
    STRUCT_LIST(MAKE_STRUCT_CASE)
  #undef MAKE_STRUCT_CASE

Modified: branches/experimental/toiger/test/cctest/test-debug.cc
==============================================================================
--- branches/experimental/toiger/test/cctest/test-debug.cc      (original)
+++ branches/experimental/toiger/test/cctest/test-debug.cc      Thu Feb 19  
03:42:34 2009
@@ -363,8 +363,66 @@
                       Code);
  }

+
+// Check that the debugger is loaded.
+static void CheckDebuggerLoaded() {
+  CHECK(Debug::debug_context().is_null());
+}
+
+
+// Check that the debugger has been fully unloaded.
+void CheckDebuggerUnloaded(bool check_functions) {
+  // Check that the debugger context is cleared and that there is no debug
+  // information stored for the debugger.
+  CHECK(Debug::debug_context().is_null());
+  CHECK_EQ(NULL, Debug::debug_info_list_);
+
+  // Collect garbage to ensure weak handles are cleared.
+  Heap::CollectAllGarbage();
+  Heap::CollectAllGarbage();
+
+  // Iterate the head and check that there are no debugger related objects  
left.
+  HeapIterator iterator;
+  while (iterator.has_next()) {
+    HeapObject* obj = iterator.next();
+    CHECK(obj != NULL);
+    CHECK(!obj->IsDebugInfo());
+    CHECK(!obj->IsBreakPointInfo());
+
+    // If deep check of functions is requested check that no debug break  
code
+    // is left in all functions.
+    if (check_functions) {
+      if (obj->IsJSFunction()) {
+        JSFunction* fun = JSFunction::cast(obj);
+        for (RelocIterator it(fun->shared()->code()); !it.done();  
it.next()) {
+          RelocInfo::Mode rmode = it.rinfo()->rmode();
+          if (RelocInfo::IsCodeTarget(rmode)) {
+            CHECK(!Debug::IsDebugBreak(it.rinfo()->target_address()));
+          } else if (RelocInfo::IsJSReturn(rmode)) {
+            CHECK(!Debug::IsDebugBreakAtReturn(it.rinfo()));
+          }
+        }
+      }
+    }
+  }
+}
+
+
  } }  // namespace v8::internal

+
+// Check that the debugger is loaded.
+static void CheckDebuggerLoaded() {
+  v8::internal::CheckDebuggerLoaded();
+}
+
+
+// Check that the debugger has been fully unloaded.
+static void CheckDebuggerUnloaded(bool check_functions = false) {
+  v8::internal::CheckDebuggerUnloaded(check_functions);
+}
+
+
  // Inherit from BreakLocationIterator to get access to protected parts for
  // testing.
  class TestBreakLocationIterator: public  
v8::internal::BreakLocationIterator {
@@ -823,6 +881,7 @@
    break_point_hit_count = 0;
    v8::HandleScope scope;
    DebugLocalContext env;
+
    v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
                                     v8::Undefined());
    v8::Script::Compile(v8::String::New("function foo(){bar=0;}"))->Run();
@@ -846,6 +905,7 @@
    CHECK_EQ(2, break_point_hit_count);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -878,6 +938,7 @@
    CHECK_EQ(2, break_point_hit_count);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -910,6 +971,7 @@
    CHECK_EQ(2, break_point_hit_count);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -941,6 +1003,7 @@
    CHECK_EQ(2, break_point_hit_count);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -986,6 +1049,7 @@
    CallWithBreakPoints(env->Global(), foo, 1, 25);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -1043,6 +1107,7 @@
    CallAndGC(env->Global(), foo);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -1093,6 +1158,7 @@
    CHECK_EQ(8, break_point_hit_count);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();

    // Make sure that the break point numbers are consecutive.
    CHECK_EQ(1, bp1);
@@ -1207,6 +1273,7 @@
    CHECK_EQ(2, break_point_hit_count);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();

    // Make sure that the break point numbers are consecutive.
    CHECK_EQ(1, sbp1);
@@ -1272,6 +1339,7 @@
    CHECK_EQ(3, break_point_hit_count);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -1333,6 +1401,7 @@
    CHECK_EQ(5, break_point_hit_count);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -1387,6 +1456,7 @@
    CHECK_EQ(5, break_point_hit_count);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -1445,6 +1515,7 @@
    CHECK_EQ(1, break_point_hit_count);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -1510,6 +1581,7 @@
    CHECK_EQ(2, break_point_hit_count);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -1565,6 +1637,7 @@
    CHECK_EQ(1, break_point_hit_count);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -1670,6 +1743,7 @@
    CHECK_EQ(0, break_point_hit_count);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -1695,6 +1769,7 @@
    CHECK_EQ(0, break_point_hit_count);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -1722,6 +1797,7 @@
    CHECK_EQ(3, break_point_hit_count);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -1836,6 +1912,7 @@
    bar->Call(env->Global(), 2, argv_bar_3);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -1861,10 +1938,12 @@
    CHECK_EQ(4, break_point_hit_count);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();

    // Register a debug event listener which just counts.
    v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);

+  SetBreakPoint(foo, 3);
    break_point_hit_count = 0;
    foo->Call(env->Global(), 0, NULL);

@@ -1872,6 +1951,7 @@
    CHECK_EQ(1, break_point_hit_count);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -1906,10 +1986,12 @@
  #endif

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();

    // Register a debug event listener which just counts.
    v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);

+  SetBreakPoint(foo, 0);
    break_point_hit_count = 0;
    foo->Call(env->Global(), 0, NULL);

@@ -1917,6 +1999,7 @@
    CHECK_EQ(1, break_point_hit_count);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -1957,6 +2040,7 @@

    // Get rid of the debug event listener.
    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -2009,6 +2093,7 @@

    // Get rid of the debug event listener.
    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -2046,6 +2131,7 @@

    // Get rid of the debug event listener.
    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -2091,6 +2177,7 @@

    // Get rid of the debug event listener.
    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -2137,6 +2224,7 @@

    // Get rid of the debug event listener.
    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded(true);
  }


@@ -2168,6 +2256,7 @@

    // Get rid of the debug event listener.
    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -2193,6 +2282,7 @@
    CHECK_EQ(3, break_point_hit_count);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();

    // Register a debug event listener which just counts.
    v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
@@ -2204,6 +2294,7 @@
    CHECK_EQ(1, break_point_hit_count);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -2350,6 +2441,7 @@
    CHECK_EQ(1, message_callback_count);

    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
    v8::V8::RemoveMessageListeners(MessageCallbackCount);
  }

@@ -2486,6 +2578,7 @@

    // Get rid of the debug event listener.
    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -2539,6 +2632,7 @@

    // Get rid of the debug event listener.
    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -2575,6 +2669,7 @@

    // Get rid of the debug event listener.
    v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
  }


@@ -3505,4 +3600,63 @@

    // Test that a function with closure can be run in the debugger.
    v8::Script::Compile(v8::String::New("CheckClosure()"))->Run();
+}
+
+
+// Test that clearing the debug event listener actually clears all break  
points
+// and related information.
+TEST(DebuggerUnload) {
+  v8::HandleScope scope;
+  DebugLocalContext env;
+
+  // Check debugger is unloaded before it is used.
+  CheckDebuggerUnloaded();
+
+  // Add debug event listener.
+  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
+                                   v8::Undefined());
+  CheckDebuggerLoaded();
+
+  // Create a couple of functions for the test.
+  v8::Local<v8::Function> foo =
+      CompileFunction(&env, "function foo(){x=1}", "foo");
+  v8::Local<v8::Function> bar =
+      CompileFunction(&env, "function bar(){y=2}", "bar");
+
+  // Set some break points.
+  SetBreakPoint(foo, 0);
+  SetBreakPoint(foo, 4);
+  SetBreakPoint(bar, 0);
+  SetBreakPoint(bar, 4);
+
+  // Make sure that the break points are there.
+  break_point_hit_count = 0;
+  foo->Call(env->Global(), 0, NULL);
+  CHECK_EQ(2, break_point_hit_count);
+  bar->Call(env->Global(), 0, NULL);
+  CHECK_EQ(4, break_point_hit_count);
+
+  // Remove the debug event listener without clearing breakpoints.
+  v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded(true);
+
+  // Set a new debug event listener.
+  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
+                                   v8::Undefined());
+  CheckDebuggerLoaded();
+
+  // Check that the break points was actually cleared.
+  break_point_hit_count = 0;
+  foo->Call(env->Global(), 0, NULL);
+  CHECK_EQ(0, break_point_hit_count);
+
+  // Set break points and run again.
+  SetBreakPoint(foo, 0);
+  SetBreakPoint(foo, 4);
+  foo->Call(env->Global(), 0, NULL);
+  CHECK_EQ(2, break_point_hit_count);
+
+  // Remove the debug event listener without clearing breakpoints again.
+  v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded(true);
  }

Modified:  
branches/experimental/toiger/test/mjsunit/debug-evaluate-recursive.js
==============================================================================
--- branches/experimental/toiger/test/mjsunit/debug-evaluate-recursive.js       
 
(original)
+++ branches/experimental/toiger/test/mjsunit/debug-evaluate-recursive.js       
 
Thu Feb 19 03:42:34 2009
@@ -153,9 +153,11 @@
  // Remove the debug event listener.
  Debug.setListener(null);

-// Add debug event listener wich uses recursive breaks.
-listenerComplete = false;
+// Set debug event listener wich uses recursive breaks.
  Debug.setListener(listener_recurse);
+listenerComplete = false;
+
+Debug.setBreakPoint(f, 2, 0);

  debugger;


--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to