Home | History | Annotate | Download | only in cctest
      1 // Copyright 2010 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #ifdef ENABLE_DEBUGGER_SUPPORT
     29 
     30 #include <stdlib.h>
     31 
     32 #include "v8.h"
     33 
     34 #include "api.h"
     35 #include "cctest.h"
     36 #include "compilation-cache.h"
     37 #include "debug.h"
     38 #include "deoptimizer.h"
     39 #include "platform.h"
     40 #include "stub-cache.h"
     41 #include "utils.h"
     42 
     43 
     44 using ::v8::internal::EmbeddedVector;
     45 using ::v8::internal::Object;
     46 using ::v8::internal::OS;
     47 using ::v8::internal::Handle;
     48 using ::v8::internal::Heap;
     49 using ::v8::internal::JSGlobalProxy;
     50 using ::v8::internal::Code;
     51 using ::v8::internal::Debug;
     52 using ::v8::internal::Debugger;
     53 using ::v8::internal::CommandMessage;
     54 using ::v8::internal::CommandMessageQueue;
     55 using ::v8::internal::StepAction;
     56 using ::v8::internal::StepIn;  // From StepAction enum
     57 using ::v8::internal::StepNext;  // From StepAction enum
     58 using ::v8::internal::StepOut;  // From StepAction enum
     59 using ::v8::internal::Vector;
     60 using ::v8::internal::StrLength;
     61 
     62 // Size of temp buffer for formatting small strings.
     63 #define SMALL_STRING_BUFFER_SIZE 80
     64 
     65 // --- A d d i t i o n a l   C h e c k   H e l p e r s
     66 
     67 
     68 // Helper function used by the CHECK_EQ function when given Address
     69 // arguments.  Should not be called directly.
     70 static inline void CheckEqualsHelper(const char* file, int line,
     71                                      const char* expected_source,
     72                                      ::v8::internal::Address expected,
     73                                      const char* value_source,
     74                                      ::v8::internal::Address value) {
     75   if (expected != value) {
     76     V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n#   "
     77                          "Expected: %i\n#   Found: %i",
     78              expected_source, value_source, expected, value);
     79   }
     80 }
     81 
     82 
     83 // Helper function used by the CHECK_NE function when given Address
     84 // arguments.  Should not be called directly.
     85 static inline void CheckNonEqualsHelper(const char* file, int line,
     86                                         const char* unexpected_source,
     87                                         ::v8::internal::Address unexpected,
     88                                         const char* value_source,
     89                                         ::v8::internal::Address value) {
     90   if (unexpected == value) {
     91     V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n#   Value: %i",
     92              unexpected_source, value_source, value);
     93   }
     94 }
     95 
     96 
     97 // Helper function used by the CHECK function when given code
     98 // arguments.  Should not be called directly.
     99 static inline void CheckEqualsHelper(const char* file, int line,
    100                                      const char* expected_source,
    101                                      const Code* expected,
    102                                      const char* value_source,
    103                                      const Code* value) {
    104   if (expected != value) {
    105     V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n#   "
    106                          "Expected: %p\n#   Found: %p",
    107              expected_source, value_source, expected, value);
    108   }
    109 }
    110 
    111 
    112 static inline void CheckNonEqualsHelper(const char* file, int line,
    113                                         const char* expected_source,
    114                                         const Code* expected,
    115                                         const char* value_source,
    116                                         const Code* value) {
    117   if (expected == value) {
    118     V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n#   Value: %p",
    119              expected_source, value_source, value);
    120   }
    121 }
    122 
    123 
    124 // --- H e l p e r   C l a s s e s
    125 
    126 
    127 // Helper class for creating a V8 enviromnent for running tests
    128 class DebugLocalContext {
    129  public:
    130   inline DebugLocalContext(
    131       v8::ExtensionConfiguration* extensions = 0,
    132       v8::Handle<v8::ObjectTemplate> global_template =
    133           v8::Handle<v8::ObjectTemplate>(),
    134       v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>())
    135       : context_(v8::Context::New(extensions, global_template, global_object)) {
    136     context_->Enter();
    137   }
    138   inline ~DebugLocalContext() {
    139     context_->Exit();
    140     context_.Dispose();
    141   }
    142   inline v8::Context* operator->() { return *context_; }
    143   inline v8::Context* operator*() { return *context_; }
    144   inline bool IsReady() { return !context_.IsEmpty(); }
    145   void ExposeDebug() {
    146     v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
    147     // Expose the debug context global object in the global object for testing.
    148     debug->Load();
    149     debug->debug_context()->set_security_token(
    150         v8::Utils::OpenHandle(*context_)->security_token());
    151 
    152     Handle<JSGlobalProxy> global(Handle<JSGlobalProxy>::cast(
    153         v8::Utils::OpenHandle(*context_->Global())));
    154     Handle<v8::internal::String> debug_string =
    155         FACTORY->LookupAsciiSymbol("debug");
    156     SetProperty(global, debug_string,
    157         Handle<Object>(debug->debug_context()->global_proxy()), DONT_ENUM,
    158         ::v8::internal::kNonStrictMode);
    159   }
    160  private:
    161   v8::Persistent<v8::Context> context_;
    162 };
    163 
    164 
    165 // --- H e l p e r   F u n c t i o n s
    166 
    167 
    168 // Compile and run the supplied source and return the fequested function.
    169 static v8::Local<v8::Function> CompileFunction(DebugLocalContext* env,
    170                                                const char* source,
    171                                                const char* function_name) {
    172   v8::Script::Compile(v8::String::New(source))->Run();
    173   return v8::Local<v8::Function>::Cast(
    174       (*env)->Global()->Get(v8::String::New(function_name)));
    175 }
    176 
    177 
    178 // Compile and run the supplied source and return the requested function.
    179 static v8::Local<v8::Function> CompileFunction(const char* source,
    180                                                const char* function_name) {
    181   v8::Script::Compile(v8::String::New(source))->Run();
    182   return v8::Local<v8::Function>::Cast(
    183     v8::Context::GetCurrent()->Global()->Get(v8::String::New(function_name)));
    184 }
    185 
    186 
    187 // Is there any debug info for the function?
    188 static bool HasDebugInfo(v8::Handle<v8::Function> fun) {
    189   Handle<v8::internal::JSFunction> f = v8::Utils::OpenHandle(*fun);
    190   Handle<v8::internal::SharedFunctionInfo> shared(f->shared());
    191   return Debug::HasDebugInfo(shared);
    192 }
    193 
    194 
    195 // Set a break point in a function and return the associated break point
    196 // number.
    197 static int SetBreakPoint(Handle<v8::internal::JSFunction> fun, int position) {
    198   static int break_point = 0;
    199   Handle<v8::internal::SharedFunctionInfo> shared(fun->shared());
    200   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
    201   debug->SetBreakPoint(
    202       shared,
    203       Handle<Object>(v8::internal::Smi::FromInt(++break_point)),
    204       &position);
    205   return break_point;
    206 }
    207 
    208 
    209 // Set a break point in a function and return the associated break point
    210 // number.
    211 static int SetBreakPoint(v8::Handle<v8::Function> fun, int position) {
    212   return SetBreakPoint(v8::Utils::OpenHandle(*fun), position);
    213 }
    214 
    215 
    216 // Set a break point in a function using the Debug object and return the
    217 // associated break point number.
    218 static int SetBreakPointFromJS(const char* function_name,
    219                                int line, int position) {
    220   EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
    221   OS::SNPrintF(buffer,
    222                "debug.Debug.setBreakPoint(%s,%d,%d)",
    223                function_name, line, position);
    224   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
    225   v8::Handle<v8::String> str = v8::String::New(buffer.start());
    226   return v8::Script::Compile(str)->Run()->Int32Value();
    227 }
    228 
    229 
    230 // Set a break point in a script identified by id using the global Debug object.
    231 static int SetScriptBreakPointByIdFromJS(int script_id, int line, int column) {
    232   EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
    233   if (column >= 0) {
    234     // Column specified set script break point on precise location.
    235     OS::SNPrintF(buffer,
    236                  "debug.Debug.setScriptBreakPointById(%d,%d,%d)",
    237                  script_id, line, column);
    238   } else {
    239     // Column not specified set script break point on line.
    240     OS::SNPrintF(buffer,
    241                  "debug.Debug.setScriptBreakPointById(%d,%d)",
    242                  script_id, line);
    243   }
    244   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
    245   {
    246     v8::TryCatch try_catch;
    247     v8::Handle<v8::String> str = v8::String::New(buffer.start());
    248     v8::Handle<v8::Value> value = v8::Script::Compile(str)->Run();
    249     CHECK(!try_catch.HasCaught());
    250     return value->Int32Value();
    251   }
    252 }
    253 
    254 
    255 // Set a break point in a script identified by name using the global Debug
    256 // object.
    257 static int SetScriptBreakPointByNameFromJS(const char* script_name,
    258                                            int line, int column) {
    259   EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
    260   if (column >= 0) {
    261     // Column specified set script break point on precise location.
    262     OS::SNPrintF(buffer,
    263                  "debug.Debug.setScriptBreakPointByName(\"%s\",%d,%d)",
    264                  script_name, line, column);
    265   } else {
    266     // Column not specified set script break point on line.
    267     OS::SNPrintF(buffer,
    268                  "debug.Debug.setScriptBreakPointByName(\"%s\",%d)",
    269                  script_name, line);
    270   }
    271   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
    272   {
    273     v8::TryCatch try_catch;
    274     v8::Handle<v8::String> str = v8::String::New(buffer.start());
    275     v8::Handle<v8::Value> value = v8::Script::Compile(str)->Run();
    276     CHECK(!try_catch.HasCaught());
    277     return value->Int32Value();
    278   }
    279 }
    280 
    281 
    282 // Clear a break point.
    283 static void ClearBreakPoint(int break_point) {
    284   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
    285   debug->ClearBreakPoint(
    286       Handle<Object>(v8::internal::Smi::FromInt(break_point)));
    287 }
    288 
    289 
    290 // Clear a break point using the global Debug object.
    291 static void ClearBreakPointFromJS(int break_point_number) {
    292   EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
    293   OS::SNPrintF(buffer,
    294                "debug.Debug.clearBreakPoint(%d)",
    295                break_point_number);
    296   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
    297   v8::Script::Compile(v8::String::New(buffer.start()))->Run();
    298 }
    299 
    300 
    301 static void EnableScriptBreakPointFromJS(int break_point_number) {
    302   EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
    303   OS::SNPrintF(buffer,
    304                "debug.Debug.enableScriptBreakPoint(%d)",
    305                break_point_number);
    306   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
    307   v8::Script::Compile(v8::String::New(buffer.start()))->Run();
    308 }
    309 
    310 
    311 static void DisableScriptBreakPointFromJS(int break_point_number) {
    312   EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
    313   OS::SNPrintF(buffer,
    314                "debug.Debug.disableScriptBreakPoint(%d)",
    315                break_point_number);
    316   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
    317   v8::Script::Compile(v8::String::New(buffer.start()))->Run();
    318 }
    319 
    320 
    321 static void ChangeScriptBreakPointConditionFromJS(int break_point_number,
    322                                                   const char* condition) {
    323   EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
    324   OS::SNPrintF(buffer,
    325                "debug.Debug.changeScriptBreakPointCondition(%d, \"%s\")",
    326                break_point_number, condition);
    327   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
    328   v8::Script::Compile(v8::String::New(buffer.start()))->Run();
    329 }
    330 
    331 
    332 static void ChangeScriptBreakPointIgnoreCountFromJS(int break_point_number,
    333                                                     int ignoreCount) {
    334   EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
    335   OS::SNPrintF(buffer,
    336                "debug.Debug.changeScriptBreakPointIgnoreCount(%d, %d)",
    337                break_point_number, ignoreCount);
    338   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
    339   v8::Script::Compile(v8::String::New(buffer.start()))->Run();
    340 }
    341 
    342 
    343 // Change break on exception.
    344 static void ChangeBreakOnException(bool caught, bool uncaught) {
    345   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
    346   debug->ChangeBreakOnException(v8::internal::BreakException, caught);
    347   debug->ChangeBreakOnException(v8::internal::BreakUncaughtException, uncaught);
    348 }
    349 
    350 
    351 // Change break on exception using the global Debug object.
    352 static void ChangeBreakOnExceptionFromJS(bool caught, bool uncaught) {
    353   if (caught) {
    354     v8::Script::Compile(
    355         v8::String::New("debug.Debug.setBreakOnException()"))->Run();
    356   } else {
    357     v8::Script::Compile(
    358         v8::String::New("debug.Debug.clearBreakOnException()"))->Run();
    359   }
    360   if (uncaught) {
    361     v8::Script::Compile(
    362         v8::String::New("debug.Debug.setBreakOnUncaughtException()"))->Run();
    363   } else {
    364     v8::Script::Compile(
    365         v8::String::New("debug.Debug.clearBreakOnUncaughtException()"))->Run();
    366   }
    367 }
    368 
    369 
    370 // Prepare to step to next break location.
    371 static void PrepareStep(StepAction step_action) {
    372   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
    373   debug->PrepareStep(step_action, 1);
    374 }
    375 
    376 
    377 // This function is in namespace v8::internal to be friend with class
    378 // v8::internal::Debug.
    379 namespace v8 {
    380 namespace internal {
    381 
    382 // Collect the currently debugged functions.
    383 Handle<FixedArray> GetDebuggedFunctions() {
    384   Debug* debug = Isolate::Current()->debug();
    385 
    386   v8::internal::DebugInfoListNode* node = debug->debug_info_list_;
    387 
    388   // Find the number of debugged functions.
    389   int count = 0;
    390   while (node) {
    391     count++;
    392     node = node->next();
    393   }
    394 
    395   // Allocate array for the debugged functions
    396   Handle<FixedArray> debugged_functions =
    397       FACTORY->NewFixedArray(count);
    398 
    399   // Run through the debug info objects and collect all functions.
    400   count = 0;
    401   while (node) {
    402     debugged_functions->set(count++, *node->debug_info());
    403     node = node->next();
    404   }
    405 
    406   return debugged_functions;
    407 }
    408 
    409 
    410 static Handle<Code> ComputeCallDebugBreak(int argc) {
    411   CALL_HEAP_FUNCTION(
    412       v8::internal::Isolate::Current(),
    413       v8::internal::Isolate::Current()->stub_cache()->ComputeCallDebugBreak(
    414           argc, Code::CALL_IC),
    415       Code);
    416 }
    417 
    418 
    419 // Check that the debugger has been fully unloaded.
    420 void CheckDebuggerUnloaded(bool check_functions) {
    421   // Check that the debugger context is cleared and that there is no debug
    422   // information stored for the debugger.
    423   CHECK(Isolate::Current()->debug()->debug_context().is_null());
    424   CHECK_EQ(NULL, Isolate::Current()->debug()->debug_info_list_);
    425 
    426   // Collect garbage to ensure weak handles are cleared.
    427   HEAP->CollectAllGarbage(false);
    428   HEAP->CollectAllGarbage(false);
    429 
    430   // Iterate the head and check that there are no debugger related objects left.
    431   HeapIterator iterator;
    432   for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
    433     CHECK(!obj->IsDebugInfo());
    434     CHECK(!obj->IsBreakPointInfo());
    435 
    436     // If deep check of functions is requested check that no debug break code
    437     // is left in all functions.
    438     if (check_functions) {
    439       if (obj->IsJSFunction()) {
    440         JSFunction* fun = JSFunction::cast(obj);
    441         for (RelocIterator it(fun->shared()->code()); !it.done(); it.next()) {
    442           RelocInfo::Mode rmode = it.rinfo()->rmode();
    443           if (RelocInfo::IsCodeTarget(rmode)) {
    444             CHECK(!Debug::IsDebugBreak(it.rinfo()->target_address()));
    445           } else if (RelocInfo::IsJSReturn(rmode)) {
    446             CHECK(!Debug::IsDebugBreakAtReturn(it.rinfo()));
    447           }
    448         }
    449       }
    450     }
    451   }
    452 }
    453 
    454 
    455 void ForceUnloadDebugger() {
    456   Isolate::Current()->debugger()->never_unload_debugger_ = false;
    457   Isolate::Current()->debugger()->UnloadDebugger();
    458 }
    459 
    460 
    461 } }  // namespace v8::internal
    462 
    463 
    464 // Check that the debugger has been fully unloaded.
    465 static void CheckDebuggerUnloaded(bool check_functions = false) {
    466   // Let debugger to unload itself synchronously
    467   v8::Debug::ProcessDebugMessages();
    468 
    469   v8::internal::CheckDebuggerUnloaded(check_functions);
    470 }
    471 
    472 
    473 // Inherit from BreakLocationIterator to get access to protected parts for
    474 // testing.
    475 class TestBreakLocationIterator: public v8::internal::BreakLocationIterator {
    476  public:
    477   explicit TestBreakLocationIterator(Handle<v8::internal::DebugInfo> debug_info)
    478     : BreakLocationIterator(debug_info, v8::internal::SOURCE_BREAK_LOCATIONS) {}
    479   v8::internal::RelocIterator* it() { return reloc_iterator_; }
    480   v8::internal::RelocIterator* it_original() {
    481     return reloc_iterator_original_;
    482   }
    483 };
    484 
    485 
    486 // Compile a function, set a break point and check that the call at the break
    487 // location in the code is the expected debug_break function.
    488 void CheckDebugBreakFunction(DebugLocalContext* env,
    489                              const char* source, const char* name,
    490                              int position, v8::internal::RelocInfo::Mode mode,
    491                              Code* debug_break) {
    492   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
    493 
    494   // Create function and set the break point.
    495   Handle<v8::internal::JSFunction> fun = v8::Utils::OpenHandle(
    496       *CompileFunction(env, source, name));
    497   int bp = SetBreakPoint(fun, position);
    498 
    499   // Check that the debug break function is as expected.
    500   Handle<v8::internal::SharedFunctionInfo> shared(fun->shared());
    501   CHECK(Debug::HasDebugInfo(shared));
    502   TestBreakLocationIterator it1(Debug::GetDebugInfo(shared));
    503   it1.FindBreakLocationFromPosition(position);
    504   CHECK_EQ(mode, it1.it()->rinfo()->rmode());
    505   if (mode != v8::internal::RelocInfo::JS_RETURN) {
    506     CHECK_EQ(debug_break,
    507         Code::GetCodeFromTargetAddress(it1.it()->rinfo()->target_address()));
    508   } else {
    509     CHECK(Debug::IsDebugBreakAtReturn(it1.it()->rinfo()));
    510   }
    511 
    512   // Clear the break point and check that the debug break function is no longer
    513   // there
    514   ClearBreakPoint(bp);
    515   CHECK(!debug->HasDebugInfo(shared));
    516   CHECK(debug->EnsureDebugInfo(shared));
    517   TestBreakLocationIterator it2(Debug::GetDebugInfo(shared));
    518   it2.FindBreakLocationFromPosition(position);
    519   CHECK_EQ(mode, it2.it()->rinfo()->rmode());
    520   if (mode == v8::internal::RelocInfo::JS_RETURN) {
    521     CHECK(!Debug::IsDebugBreakAtReturn(it2.it()->rinfo()));
    522   }
    523 }
    524 
    525 
    526 // --- D e b u g   E v e n t   H a n d l e r s
    527 // ---
    528 // --- The different tests uses a number of debug event handlers.
    529 // ---
    530 
    531 
    532 // Source for the JavaScript function which picks out the function
    533 // name of a frame.
    534 const char* frame_function_name_source =
    535     "function frame_function_name(exec_state, frame_number) {"
    536     "  return exec_state.frame(frame_number).func().name();"
    537     "}";
    538 v8::Local<v8::Function> frame_function_name;
    539 
    540 
    541 // Source for the JavaScript function which pick out the name of the
    542 // first argument of a frame.
    543 const char* frame_argument_name_source =
    544     "function frame_argument_name(exec_state, frame_number) {"
    545     "  return exec_state.frame(frame_number).argumentName(0);"
    546     "}";
    547 v8::Local<v8::Function> frame_argument_name;
    548 
    549 
    550 // Source for the JavaScript function which pick out the value of the
    551 // first argument of a frame.
    552 const char* frame_argument_value_source =
    553     "function frame_argument_value(exec_state, frame_number) {"
    554     "  return exec_state.frame(frame_number).argumentValue(0).value_;"
    555     "}";
    556 v8::Local<v8::Function> frame_argument_value;
    557 
    558 
    559 // Source for the JavaScript function which pick out the name of the
    560 // first argument of a frame.
    561 const char* frame_local_name_source =
    562     "function frame_local_name(exec_state, frame_number) {"
    563     "  return exec_state.frame(frame_number).localName(0);"
    564     "}";
    565 v8::Local<v8::Function> frame_local_name;
    566 
    567 
    568 // Source for the JavaScript function which pick out the value of the
    569 // first argument of a frame.
    570 const char* frame_local_value_source =
    571     "function frame_local_value(exec_state, frame_number) {"
    572     "  return exec_state.frame(frame_number).localValue(0).value_;"
    573     "}";
    574 v8::Local<v8::Function> frame_local_value;
    575 
    576 
    577 // Source for the JavaScript function which picks out the source line for the
    578 // top frame.
    579 const char* frame_source_line_source =
    580     "function frame_source_line(exec_state) {"
    581     "  return exec_state.frame(0).sourceLine();"
    582     "}";
    583 v8::Local<v8::Function> frame_source_line;
    584 
    585 
    586 // Source for the JavaScript function which picks out the source column for the
    587 // top frame.
    588 const char* frame_source_column_source =
    589     "function frame_source_column(exec_state) {"
    590     "  return exec_state.frame(0).sourceColumn();"
    591     "}";
    592 v8::Local<v8::Function> frame_source_column;
    593 
    594 
    595 // Source for the JavaScript function which picks out the script name for the
    596 // top frame.
    597 const char* frame_script_name_source =
    598     "function frame_script_name(exec_state) {"
    599     "  return exec_state.frame(0).func().script().name();"
    600     "}";
    601 v8::Local<v8::Function> frame_script_name;
    602 
    603 
    604 // Source for the JavaScript function which picks out the script data for the
    605 // top frame.
    606 const char* frame_script_data_source =
    607     "function frame_script_data(exec_state) {"
    608     "  return exec_state.frame(0).func().script().data();"
    609     "}";
    610 v8::Local<v8::Function> frame_script_data;
    611 
    612 
    613 // Source for the JavaScript function which picks out the script data from
    614 // AfterCompile event
    615 const char* compiled_script_data_source =
    616     "function compiled_script_data(event_data) {"
    617     "  return event_data.script().data();"
    618     "}";
    619 v8::Local<v8::Function> compiled_script_data;
    620 
    621 
    622 // Source for the JavaScript function which returns the number of frames.
    623 static const char* frame_count_source =
    624     "function frame_count(exec_state) {"
    625     "  return exec_state.frameCount();"
    626     "}";
    627 v8::Handle<v8::Function> frame_count;
    628 
    629 
    630 // Global variable to store the last function hit - used by some tests.
    631 char last_function_hit[80];
    632 
    633 // Global variable to store the name and data for last script hit - used by some
    634 // tests.
    635 char last_script_name_hit[80];
    636 char last_script_data_hit[80];
    637 
    638 // Global variables to store the last source position - used by some tests.
    639 int last_source_line = -1;
    640 int last_source_column = -1;
    641 
    642 // Debug event handler which counts the break points which have been hit.
    643 int break_point_hit_count = 0;
    644 static void DebugEventBreakPointHitCount(v8::DebugEvent event,
    645                                          v8::Handle<v8::Object> exec_state,
    646                                          v8::Handle<v8::Object> event_data,
    647                                          v8::Handle<v8::Value> data) {
    648   Debug* debug = v8::internal::Isolate::Current()->debug();
    649   // When hitting a debug event listener there must be a break set.
    650   CHECK_NE(debug->break_id(), 0);
    651 
    652   // Count the number of breaks.
    653   if (event == v8::Break) {
    654     break_point_hit_count++;
    655     if (!frame_function_name.IsEmpty()) {
    656       // Get the name of the function.
    657       const int argc = 2;
    658       v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(0) };
    659       v8::Handle<v8::Value> result = frame_function_name->Call(exec_state,
    660                                                                argc, argv);
    661       if (result->IsUndefined()) {
    662         last_function_hit[0] = '\0';
    663       } else {
    664         CHECK(result->IsString());
    665         v8::Handle<v8::String> function_name(result->ToString());
    666         function_name->WriteAscii(last_function_hit);
    667       }
    668     }
    669 
    670     if (!frame_source_line.IsEmpty()) {
    671       // Get the source line.
    672       const int argc = 1;
    673       v8::Handle<v8::Value> argv[argc] = { exec_state };
    674       v8::Handle<v8::Value> result = frame_source_line->Call(exec_state,
    675                                                              argc, argv);
    676       CHECK(result->IsNumber());
    677       last_source_line = result->Int32Value();
    678     }
    679 
    680     if (!frame_source_column.IsEmpty()) {
    681       // Get the source column.
    682       const int argc = 1;
    683       v8::Handle<v8::Value> argv[argc] = { exec_state };
    684       v8::Handle<v8::Value> result = frame_source_column->Call(exec_state,
    685                                                                argc, argv);
    686       CHECK(result->IsNumber());
    687       last_source_column = result->Int32Value();
    688     }
    689 
    690     if (!frame_script_name.IsEmpty()) {
    691       // Get the script name of the function script.
    692       const int argc = 1;
    693       v8::Handle<v8::Value> argv[argc] = { exec_state };
    694       v8::Handle<v8::Value> result = frame_script_name->Call(exec_state,
    695                                                              argc, argv);
    696       if (result->IsUndefined()) {
    697         last_script_name_hit[0] = '\0';
    698       } else {
    699         CHECK(result->IsString());
    700         v8::Handle<v8::String> script_name(result->ToString());
    701         script_name->WriteAscii(last_script_name_hit);
    702       }
    703     }
    704 
    705     if (!frame_script_data.IsEmpty()) {
    706       // Get the script data of the function script.
    707       const int argc = 1;
    708       v8::Handle<v8::Value> argv[argc] = { exec_state };
    709       v8::Handle<v8::Value> result = frame_script_data->Call(exec_state,
    710                                                              argc, argv);
    711       if (result->IsUndefined()) {
    712         last_script_data_hit[0] = '\0';
    713       } else {
    714         result = result->ToString();
    715         CHECK(result->IsString());
    716         v8::Handle<v8::String> script_data(result->ToString());
    717         script_data->WriteAscii(last_script_data_hit);
    718       }
    719     }
    720   } else if (event == v8::AfterCompile && !compiled_script_data.IsEmpty()) {
    721     const int argc = 1;
    722     v8::Handle<v8::Value> argv[argc] = { event_data };
    723     v8::Handle<v8::Value> result = compiled_script_data->Call(exec_state,
    724                                                               argc, argv);
    725     if (result->IsUndefined()) {
    726       last_script_data_hit[0] = '\0';
    727     } else {
    728       result = result->ToString();
    729       CHECK(result->IsString());
    730       v8::Handle<v8::String> script_data(result->ToString());
    731       script_data->WriteAscii(last_script_data_hit);
    732     }
    733   }
    734 }
    735 
    736 
    737 // Debug event handler which counts a number of events and collects the stack
    738 // height if there is a function compiled for that.
    739 int exception_hit_count = 0;
    740 int uncaught_exception_hit_count = 0;
    741 int last_js_stack_height = -1;
    742 
    743 static void DebugEventCounterClear() {
    744   break_point_hit_count = 0;
    745   exception_hit_count = 0;
    746   uncaught_exception_hit_count = 0;
    747 }
    748 
    749 static void DebugEventCounter(v8::DebugEvent event,
    750                               v8::Handle<v8::Object> exec_state,
    751                               v8::Handle<v8::Object> event_data,
    752                               v8::Handle<v8::Value> data) {
    753   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
    754 
    755   // When hitting a debug event listener there must be a break set.
    756   CHECK_NE(debug->break_id(), 0);
    757 
    758   // Count the number of breaks.
    759   if (event == v8::Break) {
    760     break_point_hit_count++;
    761   } else if (event == v8::Exception) {
    762     exception_hit_count++;
    763 
    764     // Check whether the exception was uncaught.
    765     v8::Local<v8::String> fun_name = v8::String::New("uncaught");
    766     v8::Local<v8::Function> fun =
    767         v8::Function::Cast(*event_data->Get(fun_name));
    768     v8::Local<v8::Value> result = *fun->Call(event_data, 0, NULL);
    769     if (result->IsTrue()) {
    770       uncaught_exception_hit_count++;
    771     }
    772   }
    773 
    774   // Collect the JavsScript stack height if the function frame_count is
    775   // compiled.
    776   if (!frame_count.IsEmpty()) {
    777     static const int kArgc = 1;
    778     v8::Handle<v8::Value> argv[kArgc] = { exec_state };
    779     // Using exec_state as receiver is just to have a receiver.
    780     v8::Handle<v8::Value> result =  frame_count->Call(exec_state, kArgc, argv);
    781     last_js_stack_height = result->Int32Value();
    782   }
    783 }
    784 
    785 
    786 // Debug event handler which evaluates a number of expressions when a break
    787 // point is hit. Each evaluated expression is compared with an expected value.
    788 // For this debug event handler to work the following two global varaibles
    789 // must be initialized.
    790 //   checks: An array of expressions and expected results
    791 //   evaluate_check_function: A JavaScript function (see below)
    792 
    793 // Structure for holding checks to do.
    794 struct EvaluateCheck {
    795   const char* expr;  // An expression to evaluate when a break point is hit.
    796   v8::Handle<v8::Value> expected;  // The expected result.
    797 };
    798 // Array of checks to do.
    799 struct EvaluateCheck* checks = NULL;
    800 // Source for The JavaScript function which can do the evaluation when a break
    801 // point is hit.
    802 const char* evaluate_check_source =
    803     "function evaluate_check(exec_state, expr, expected) {"
    804     "  return exec_state.frame(0).evaluate(expr).value() === expected;"
    805     "}";
    806 v8::Local<v8::Function> evaluate_check_function;
    807 
    808 // The actual debug event described by the longer comment above.
    809 static void DebugEventEvaluate(v8::DebugEvent event,
    810                                v8::Handle<v8::Object> exec_state,
    811                                v8::Handle<v8::Object> event_data,
    812                                v8::Handle<v8::Value> data) {
    813   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
    814   // When hitting a debug event listener there must be a break set.
    815   CHECK_NE(debug->break_id(), 0);
    816 
    817   if (event == v8::Break) {
    818     for (int i = 0; checks[i].expr != NULL; i++) {
    819       const int argc = 3;
    820       v8::Handle<v8::Value> argv[argc] = { exec_state,
    821                                            v8::String::New(checks[i].expr),
    822                                            checks[i].expected };
    823       v8::Handle<v8::Value> result =
    824           evaluate_check_function->Call(exec_state, argc, argv);
    825       if (!result->IsTrue()) {
    826         v8::String::AsciiValue ascii(checks[i].expected->ToString());
    827         V8_Fatal(__FILE__, __LINE__, "%s != %s", checks[i].expr, *ascii);
    828       }
    829     }
    830   }
    831 }
    832 
    833 
    834 // This debug event listener removes a breakpoint in a function
    835 int debug_event_remove_break_point = 0;
    836 static void DebugEventRemoveBreakPoint(v8::DebugEvent event,
    837                                        v8::Handle<v8::Object> exec_state,
    838                                        v8::Handle<v8::Object> event_data,
    839                                        v8::Handle<v8::Value> data) {
    840   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
    841   // When hitting a debug event listener there must be a break set.
    842   CHECK_NE(debug->break_id(), 0);
    843 
    844   if (event == v8::Break) {
    845     break_point_hit_count++;
    846     v8::Handle<v8::Function> fun = v8::Handle<v8::Function>::Cast(data);
    847     ClearBreakPoint(debug_event_remove_break_point);
    848   }
    849 }
    850 
    851 
    852 // Debug event handler which counts break points hit and performs a step
    853 // afterwards.
    854 StepAction step_action = StepIn;  // Step action to perform when stepping.
    855 static void DebugEventStep(v8::DebugEvent event,
    856                            v8::Handle<v8::Object> exec_state,
    857                            v8::Handle<v8::Object> event_data,
    858                            v8::Handle<v8::Value> data) {
    859   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
    860   // When hitting a debug event listener there must be a break set.
    861   CHECK_NE(debug->break_id(), 0);
    862 
    863   if (event == v8::Break) {
    864     break_point_hit_count++;
    865     PrepareStep(step_action);
    866   }
    867 }
    868 
    869 
    870 // Debug event handler which counts break points hit and performs a step
    871 // afterwards. For each call the expected function is checked.
    872 // For this debug event handler to work the following two global varaibles
    873 // must be initialized.
    874 //   expected_step_sequence: An array of the expected function call sequence.
    875 //   frame_function_name: A JavaScript function (see below).
    876 
    877 // String containing the expected function call sequence. Note: this only works
    878 // if functions have name length of one.
    879 const char* expected_step_sequence = NULL;
    880 
    881 // The actual debug event described by the longer comment above.
    882 static void DebugEventStepSequence(v8::DebugEvent event,
    883                                    v8::Handle<v8::Object> exec_state,
    884                                    v8::Handle<v8::Object> event_data,
    885                                    v8::Handle<v8::Value> data) {
    886   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
    887   // When hitting a debug event listener there must be a break set.
    888   CHECK_NE(debug->break_id(), 0);
    889 
    890   if (event == v8::Break || event == v8::Exception) {
    891     // Check that the current function is the expected.
    892     CHECK(break_point_hit_count <
    893           StrLength(expected_step_sequence));
    894     const int argc = 2;
    895     v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(0) };
    896     v8::Handle<v8::Value> result = frame_function_name->Call(exec_state,
    897                                                              argc, argv);
    898     CHECK(result->IsString());
    899     v8::String::AsciiValue function_name(result->ToString());
    900     CHECK_EQ(1, StrLength(*function_name));
    901     CHECK_EQ((*function_name)[0],
    902               expected_step_sequence[break_point_hit_count]);
    903 
    904     // Perform step.
    905     break_point_hit_count++;
    906     PrepareStep(step_action);
    907   }
    908 }
    909 
    910 
    911 // Debug event handler which performs a garbage collection.
    912 static void DebugEventBreakPointCollectGarbage(
    913     v8::DebugEvent event,
    914     v8::Handle<v8::Object> exec_state,
    915     v8::Handle<v8::Object> event_data,
    916     v8::Handle<v8::Value> data) {
    917   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
    918   // When hitting a debug event listener there must be a break set.
    919   CHECK_NE(debug->break_id(), 0);
    920 
    921   // Perform a garbage collection when break point is hit and continue. Based
    922   // on the number of break points hit either scavenge or mark compact
    923   // collector is used.
    924   if (event == v8::Break) {
    925     break_point_hit_count++;
    926     if (break_point_hit_count % 2 == 0) {
    927       // Scavenge.
    928       HEAP->CollectGarbage(v8::internal::NEW_SPACE);
    929     } else {
    930       // Mark sweep compact.
    931       HEAP->CollectAllGarbage(true);
    932     }
    933   }
    934 }
    935 
    936 
    937 // Debug event handler which re-issues a debug break and calls the garbage
    938 // collector to have the heap verified.
    939 static void DebugEventBreak(v8::DebugEvent event,
    940                             v8::Handle<v8::Object> exec_state,
    941                             v8::Handle<v8::Object> event_data,
    942                             v8::Handle<v8::Value> data) {
    943   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
    944   // When hitting a debug event listener there must be a break set.
    945   CHECK_NE(debug->break_id(), 0);
    946 
    947   if (event == v8::Break) {
    948     // Count the number of breaks.
    949     break_point_hit_count++;
    950 
    951     // Run the garbage collector to enforce heap verification if option
    952     // --verify-heap is set.
    953     HEAP->CollectGarbage(v8::internal::NEW_SPACE);
    954 
    955     // Set the break flag again to come back here as soon as possible.
    956     v8::Debug::DebugBreak();
    957   }
    958 }
    959 
    960 
    961 // Debug event handler which re-issues a debug break until a limit has been
    962 // reached.
    963 int max_break_point_hit_count = 0;
    964 bool terminate_after_max_break_point_hit = false;
    965 static void DebugEventBreakMax(v8::DebugEvent event,
    966                                v8::Handle<v8::Object> exec_state,
    967                                v8::Handle<v8::Object> event_data,
    968                                v8::Handle<v8::Value> data) {
    969   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
    970   // When hitting a debug event listener there must be a break set.
    971   CHECK_NE(debug->break_id(), 0);
    972 
    973   if (event == v8::Break) {
    974     if (break_point_hit_count < max_break_point_hit_count) {
    975       // Count the number of breaks.
    976       break_point_hit_count++;
    977 
    978       // Set the break flag again to come back here as soon as possible.
    979       v8::Debug::DebugBreak();
    980     } else if (terminate_after_max_break_point_hit) {
    981       // Terminate execution after the last break if requested.
    982       v8::V8::TerminateExecution();
    983     }
    984   }
    985 }
    986 
    987 
    988 // --- M e s s a g e   C a l l b a c k
    989 
    990 
    991 // Message callback which counts the number of messages.
    992 int message_callback_count = 0;
    993 
    994 static void MessageCallbackCountClear() {
    995   message_callback_count = 0;
    996 }
    997 
    998 static void MessageCallbackCount(v8::Handle<v8::Message> message,
    999                                  v8::Handle<v8::Value> data) {
   1000   message_callback_count++;
   1001 }
   1002 
   1003 
   1004 // --- T h e   A c t u a l   T e s t s
   1005 
   1006 
   1007 // Test that the debug break function is the expected one for different kinds
   1008 // of break locations.
   1009 TEST(DebugStub) {
   1010   using ::v8::internal::Builtins;
   1011   using ::v8::internal::Isolate;
   1012   v8::HandleScope scope;
   1013   DebugLocalContext env;
   1014 
   1015   CheckDebugBreakFunction(&env,
   1016                           "function f1(){}", "f1",
   1017                           0,
   1018                           v8::internal::RelocInfo::JS_RETURN,
   1019                           NULL);
   1020   CheckDebugBreakFunction(&env,
   1021                           "function f2(){x=1;}", "f2",
   1022                           0,
   1023                           v8::internal::RelocInfo::CODE_TARGET_CONTEXT,
   1024                           Isolate::Current()->builtins()->builtin(
   1025                               Builtins::kStoreIC_DebugBreak));
   1026   CheckDebugBreakFunction(&env,
   1027                           "function f3(){var a=x;}", "f3",
   1028                           0,
   1029                           v8::internal::RelocInfo::CODE_TARGET_CONTEXT,
   1030                           Isolate::Current()->builtins()->builtin(
   1031                               Builtins::kLoadIC_DebugBreak));
   1032 
   1033 // TODO(1240753): Make the test architecture independent or split
   1034 // parts of the debugger into architecture dependent files. This
   1035 // part currently disabled as it is not portable between IA32/ARM.
   1036 // Currently on ICs for keyed store/load on ARM.
   1037 #if !defined (__arm__) && !defined(__thumb__)
   1038   CheckDebugBreakFunction(
   1039       &env,
   1040       "function f4(){var index='propertyName'; var a={}; a[index] = 'x';}",
   1041       "f4",
   1042       0,
   1043       v8::internal::RelocInfo::CODE_TARGET,
   1044       Isolate::Current()->builtins()->builtin(
   1045           Builtins::kKeyedStoreIC_DebugBreak));
   1046   CheckDebugBreakFunction(
   1047       &env,
   1048       "function f5(){var index='propertyName'; var a={}; return a[index];}",
   1049       "f5",
   1050       0,
   1051       v8::internal::RelocInfo::CODE_TARGET,
   1052       Isolate::Current()->builtins()->builtin(
   1053           Builtins::kKeyedLoadIC_DebugBreak));
   1054 #endif
   1055 
   1056   // Check the debug break code stubs for call ICs with different number of
   1057   // parameters.
   1058   Handle<Code> debug_break_0 = v8::internal::ComputeCallDebugBreak(0);
   1059   Handle<Code> debug_break_1 = v8::internal::ComputeCallDebugBreak(1);
   1060   Handle<Code> debug_break_4 = v8::internal::ComputeCallDebugBreak(4);
   1061 
   1062   CheckDebugBreakFunction(&env,
   1063                           "function f4_0(){x();}", "f4_0",
   1064                           0,
   1065                           v8::internal::RelocInfo::CODE_TARGET_CONTEXT,
   1066                           *debug_break_0);
   1067 
   1068   CheckDebugBreakFunction(&env,
   1069                           "function f4_1(){x(1);}", "f4_1",
   1070                           0,
   1071                           v8::internal::RelocInfo::CODE_TARGET_CONTEXT,
   1072                           *debug_break_1);
   1073 
   1074   CheckDebugBreakFunction(&env,
   1075                           "function f4_4(){x(1,2,3,4);}", "f4_4",
   1076                           0,
   1077                           v8::internal::RelocInfo::CODE_TARGET_CONTEXT,
   1078                           *debug_break_4);
   1079 }
   1080 
   1081 
   1082 // Test that the debug info in the VM is in sync with the functions being
   1083 // debugged.
   1084 TEST(DebugInfo) {
   1085   v8::HandleScope scope;
   1086   DebugLocalContext env;
   1087   // Create a couple of functions for the test.
   1088   v8::Local<v8::Function> foo =
   1089       CompileFunction(&env, "function foo(){}", "foo");
   1090   v8::Local<v8::Function> bar =
   1091       CompileFunction(&env, "function bar(){}", "bar");
   1092   // Initially no functions are debugged.
   1093   CHECK_EQ(0, v8::internal::GetDebuggedFunctions()->length());
   1094   CHECK(!HasDebugInfo(foo));
   1095   CHECK(!HasDebugInfo(bar));
   1096   // One function (foo) is debugged.
   1097   int bp1 = SetBreakPoint(foo, 0);
   1098   CHECK_EQ(1, v8::internal::GetDebuggedFunctions()->length());
   1099   CHECK(HasDebugInfo(foo));
   1100   CHECK(!HasDebugInfo(bar));
   1101   // Two functions are debugged.
   1102   int bp2 = SetBreakPoint(bar, 0);
   1103   CHECK_EQ(2, v8::internal::GetDebuggedFunctions()->length());
   1104   CHECK(HasDebugInfo(foo));
   1105   CHECK(HasDebugInfo(bar));
   1106   // One function (bar) is debugged.
   1107   ClearBreakPoint(bp1);
   1108   CHECK_EQ(1, v8::internal::GetDebuggedFunctions()->length());
   1109   CHECK(!HasDebugInfo(foo));
   1110   CHECK(HasDebugInfo(bar));
   1111   // No functions are debugged.
   1112   ClearBreakPoint(bp2);
   1113   CHECK_EQ(0, v8::internal::GetDebuggedFunctions()->length());
   1114   CHECK(!HasDebugInfo(foo));
   1115   CHECK(!HasDebugInfo(bar));
   1116 }
   1117 
   1118 
   1119 // Test that a break point can be set at an IC store location.
   1120 TEST(BreakPointICStore) {
   1121   break_point_hit_count = 0;
   1122   v8::HandleScope scope;
   1123   DebugLocalContext env;
   1124 
   1125   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
   1126                                    v8::Undefined());
   1127   v8::Script::Compile(v8::String::New("function foo(){bar=0;}"))->Run();
   1128   v8::Local<v8::Function> foo =
   1129       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
   1130 
   1131   // Run without breakpoints.
   1132   foo->Call(env->Global(), 0, NULL);
   1133   CHECK_EQ(0, break_point_hit_count);
   1134 
   1135   // Run with breakpoint
   1136   int bp = SetBreakPoint(foo, 0);
   1137   foo->Call(env->Global(), 0, NULL);
   1138   CHECK_EQ(1, break_point_hit_count);
   1139   foo->Call(env->Global(), 0, NULL);
   1140   CHECK_EQ(2, break_point_hit_count);
   1141 
   1142   // Run without breakpoints.
   1143   ClearBreakPoint(bp);
   1144   foo->Call(env->Global(), 0, NULL);
   1145   CHECK_EQ(2, break_point_hit_count);
   1146 
   1147   v8::Debug::SetDebugEventListener(NULL);
   1148   CheckDebuggerUnloaded();
   1149 }
   1150 
   1151 
   1152 // Test that a break point can be set at an IC load location.
   1153 TEST(BreakPointICLoad) {
   1154   break_point_hit_count = 0;
   1155   v8::HandleScope scope;
   1156   DebugLocalContext env;
   1157   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
   1158                                    v8::Undefined());
   1159   v8::Script::Compile(v8::String::New("bar=1"))->Run();
   1160   v8::Script::Compile(v8::String::New("function foo(){var x=bar;}"))->Run();
   1161   v8::Local<v8::Function> foo =
   1162       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
   1163 
   1164   // Run without breakpoints.
   1165   foo->Call(env->Global(), 0, NULL);
   1166   CHECK_EQ(0, break_point_hit_count);
   1167 
   1168   // Run with breakpoint.
   1169   int bp = SetBreakPoint(foo, 0);
   1170   foo->Call(env->Global(), 0, NULL);
   1171   CHECK_EQ(1, break_point_hit_count);
   1172   foo->Call(env->Global(), 0, NULL);
   1173   CHECK_EQ(2, break_point_hit_count);
   1174 
   1175   // Run without breakpoints.
   1176   ClearBreakPoint(bp);
   1177   foo->Call(env->Global(), 0, NULL);
   1178   CHECK_EQ(2, break_point_hit_count);
   1179 
   1180   v8::Debug::SetDebugEventListener(NULL);
   1181   CheckDebuggerUnloaded();
   1182 }
   1183 
   1184 
   1185 // Test that a break point can be set at an IC call location.
   1186 TEST(BreakPointICCall) {
   1187   break_point_hit_count = 0;
   1188   v8::HandleScope scope;
   1189   DebugLocalContext env;
   1190   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
   1191                                    v8::Undefined());
   1192   v8::Script::Compile(v8::String::New("function bar(){}"))->Run();
   1193   v8::Script::Compile(v8::String::New("function foo(){bar();}"))->Run();
   1194   v8::Local<v8::Function> foo =
   1195       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
   1196 
   1197   // Run without breakpoints.
   1198   foo->Call(env->Global(), 0, NULL);
   1199   CHECK_EQ(0, break_point_hit_count);
   1200 
   1201   // Run with breakpoint
   1202   int bp = SetBreakPoint(foo, 0);
   1203   foo->Call(env->Global(), 0, NULL);
   1204   CHECK_EQ(1, break_point_hit_count);
   1205   foo->Call(env->Global(), 0, NULL);
   1206   CHECK_EQ(2, break_point_hit_count);
   1207 
   1208   // Run without breakpoints.
   1209   ClearBreakPoint(bp);
   1210   foo->Call(env->Global(), 0, NULL);
   1211   CHECK_EQ(2, break_point_hit_count);
   1212 
   1213   v8::Debug::SetDebugEventListener(NULL);
   1214   CheckDebuggerUnloaded();
   1215 }
   1216 
   1217 
   1218 // Test that a break point can be set at an IC call location and survive a GC.
   1219 TEST(BreakPointICCallWithGC) {
   1220   break_point_hit_count = 0;
   1221   v8::HandleScope scope;
   1222   DebugLocalContext env;
   1223   v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage,
   1224                                    v8::Undefined());
   1225   v8::Script::Compile(v8::String::New("function bar(){return 1;}"))->Run();
   1226   v8::Script::Compile(v8::String::New("function foo(){return bar();}"))->Run();
   1227   v8::Local<v8::Function> foo =
   1228       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
   1229 
   1230   // Run without breakpoints.
   1231   CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value());
   1232   CHECK_EQ(0, break_point_hit_count);
   1233 
   1234   // Run with breakpoint.
   1235   int bp = SetBreakPoint(foo, 0);
   1236   CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value());
   1237   CHECK_EQ(1, break_point_hit_count);
   1238   CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value());
   1239   CHECK_EQ(2, break_point_hit_count);
   1240 
   1241   // Run without breakpoints.
   1242   ClearBreakPoint(bp);
   1243   foo->Call(env->Global(), 0, NULL);
   1244   CHECK_EQ(2, break_point_hit_count);
   1245 
   1246   v8::Debug::SetDebugEventListener(NULL);
   1247   CheckDebuggerUnloaded();
   1248 }
   1249 
   1250 
   1251 // Test that a break point can be set at an IC call location and survive a GC.
   1252 TEST(BreakPointConstructCallWithGC) {
   1253   break_point_hit_count = 0;
   1254   v8::HandleScope scope;
   1255   DebugLocalContext env;
   1256   v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage,
   1257                                    v8::Undefined());
   1258   v8::Script::Compile(v8::String::New("function bar(){ this.x = 1;}"))->Run();
   1259   v8::Script::Compile(v8::String::New(
   1260       "function foo(){return new bar(1).x;}"))->Run();
   1261   v8::Local<v8::Function> foo =
   1262       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
   1263 
   1264   // Run without breakpoints.
   1265   CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value());
   1266   CHECK_EQ(0, break_point_hit_count);
   1267 
   1268   // Run with breakpoint.
   1269   int bp = SetBreakPoint(foo, 0);
   1270   CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value());
   1271   CHECK_EQ(1, break_point_hit_count);
   1272   CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value());
   1273   CHECK_EQ(2, break_point_hit_count);
   1274 
   1275   // Run without breakpoints.
   1276   ClearBreakPoint(bp);
   1277   foo->Call(env->Global(), 0, NULL);
   1278   CHECK_EQ(2, break_point_hit_count);
   1279 
   1280   v8::Debug::SetDebugEventListener(NULL);
   1281   CheckDebuggerUnloaded();
   1282 }
   1283 
   1284 
   1285 // Test that a break point can be set at a return store location.
   1286 TEST(BreakPointReturn) {
   1287   break_point_hit_count = 0;
   1288   v8::HandleScope scope;
   1289   DebugLocalContext env;
   1290 
   1291   // Create a functions for checking the source line and column when hitting
   1292   // a break point.
   1293   frame_source_line = CompileFunction(&env,
   1294                                       frame_source_line_source,
   1295                                       "frame_source_line");
   1296   frame_source_column = CompileFunction(&env,
   1297                                         frame_source_column_source,
   1298                                         "frame_source_column");
   1299 
   1300 
   1301   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
   1302                                    v8::Undefined());
   1303   v8::Script::Compile(v8::String::New("function foo(){}"))->Run();
   1304   v8::Local<v8::Function> foo =
   1305       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
   1306 
   1307   // Run without breakpoints.
   1308   foo->Call(env->Global(), 0, NULL);
   1309   CHECK_EQ(0, break_point_hit_count);
   1310 
   1311   // Run with breakpoint
   1312   int bp = SetBreakPoint(foo, 0);
   1313   foo->Call(env->Global(), 0, NULL);
   1314   CHECK_EQ(1, break_point_hit_count);
   1315   CHECK_EQ(0, last_source_line);
   1316   CHECK_EQ(15, last_source_column);
   1317   foo->Call(env->Global(), 0, NULL);
   1318   CHECK_EQ(2, break_point_hit_count);
   1319   CHECK_EQ(0, last_source_line);
   1320   CHECK_EQ(15, last_source_column);
   1321 
   1322   // Run without breakpoints.
   1323   ClearBreakPoint(bp);
   1324   foo->Call(env->Global(), 0, NULL);
   1325   CHECK_EQ(2, break_point_hit_count);
   1326 
   1327   v8::Debug::SetDebugEventListener(NULL);
   1328   CheckDebuggerUnloaded();
   1329 }
   1330 
   1331 
   1332 static void CallWithBreakPoints(v8::Local<v8::Object> recv,
   1333                                 v8::Local<v8::Function> f,
   1334                                 int break_point_count,
   1335                                 int call_count) {
   1336   break_point_hit_count = 0;
   1337   for (int i = 0; i < call_count; i++) {
   1338     f->Call(recv, 0, NULL);
   1339     CHECK_EQ((i + 1) * break_point_count, break_point_hit_count);
   1340   }
   1341 }
   1342 
   1343 // Test GC during break point processing.
   1344 TEST(GCDuringBreakPointProcessing) {
   1345   break_point_hit_count = 0;
   1346   v8::HandleScope scope;
   1347   DebugLocalContext env;
   1348 
   1349   v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage,
   1350                                    v8::Undefined());
   1351   v8::Local<v8::Function> foo;
   1352 
   1353   // Test IC store break point with garbage collection.
   1354   foo = CompileFunction(&env, "function foo(){bar=0;}", "foo");
   1355   SetBreakPoint(foo, 0);
   1356   CallWithBreakPoints(env->Global(), foo, 1, 10);
   1357 
   1358   // Test IC load break point with garbage collection.
   1359   foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo");
   1360   SetBreakPoint(foo, 0);
   1361   CallWithBreakPoints(env->Global(), foo, 1, 10);
   1362 
   1363   // Test IC call break point with garbage collection.
   1364   foo = CompileFunction(&env, "function bar(){};function foo(){bar();}", "foo");
   1365   SetBreakPoint(foo, 0);
   1366   CallWithBreakPoints(env->Global(), foo, 1, 10);
   1367 
   1368   // Test return break point with garbage collection.
   1369   foo = CompileFunction(&env, "function foo(){}", "foo");
   1370   SetBreakPoint(foo, 0);
   1371   CallWithBreakPoints(env->Global(), foo, 1, 25);
   1372 
   1373   // Test debug break slot break point with garbage collection.
   1374   foo = CompileFunction(&env, "function foo(){var a;}", "foo");
   1375   SetBreakPoint(foo, 0);
   1376   CallWithBreakPoints(env->Global(), foo, 1, 25);
   1377 
   1378   v8::Debug::SetDebugEventListener(NULL);
   1379   CheckDebuggerUnloaded();
   1380 }
   1381 
   1382 
   1383 // Call the function three times with different garbage collections in between
   1384 // and make sure that the break point survives.
   1385 static void CallAndGC(v8::Local<v8::Object> recv,
   1386                       v8::Local<v8::Function> f,
   1387                       bool force_compaction) {
   1388   break_point_hit_count = 0;
   1389 
   1390   for (int i = 0; i < 3; i++) {
   1391     // Call function.
   1392     f->Call(recv, 0, NULL);
   1393     CHECK_EQ(1 + i * 3, break_point_hit_count);
   1394 
   1395     // Scavenge and call function.
   1396     HEAP->CollectGarbage(v8::internal::NEW_SPACE);
   1397     f->Call(recv, 0, NULL);
   1398     CHECK_EQ(2 + i * 3, break_point_hit_count);
   1399 
   1400     // Mark sweep (and perhaps compact) and call function.
   1401     HEAP->CollectAllGarbage(force_compaction);
   1402     f->Call(recv, 0, NULL);
   1403     CHECK_EQ(3 + i * 3, break_point_hit_count);
   1404   }
   1405 }
   1406 
   1407 
   1408 static void TestBreakPointSurviveGC(bool force_compaction) {
   1409   break_point_hit_count = 0;
   1410   v8::HandleScope scope;
   1411   DebugLocalContext env;
   1412 
   1413   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
   1414                                    v8::Undefined());
   1415   v8::Local<v8::Function> foo;
   1416 
   1417   // Test IC store break point with garbage collection.
   1418   {
   1419     v8::Local<v8::Function> bar =
   1420         CompileFunction(&env, "function foo(){}", "foo");
   1421     foo = CompileFunction(&env, "function foo(){bar=0;}", "foo");
   1422     SetBreakPoint(foo, 0);
   1423   }
   1424   CallAndGC(env->Global(), foo, force_compaction);
   1425 
   1426   // Test IC load break point with garbage collection.
   1427   {
   1428     v8::Local<v8::Function> bar =
   1429         CompileFunction(&env, "function foo(){}", "foo");
   1430     foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo");
   1431     SetBreakPoint(foo, 0);
   1432   }
   1433   CallAndGC(env->Global(), foo, force_compaction);
   1434 
   1435   // Test IC call break point with garbage collection.
   1436   {
   1437     v8::Local<v8::Function> bar =
   1438         CompileFunction(&env, "function foo(){}", "foo");
   1439     foo = CompileFunction(&env,
   1440                           "function bar(){};function foo(){bar();}",
   1441                           "foo");
   1442     SetBreakPoint(foo, 0);
   1443   }
   1444   CallAndGC(env->Global(), foo, force_compaction);
   1445 
   1446   // Test return break point with garbage collection.
   1447   {
   1448     v8::Local<v8::Function> bar =
   1449         CompileFunction(&env, "function foo(){}", "foo");
   1450     foo = CompileFunction(&env, "function foo(){}", "foo");
   1451     SetBreakPoint(foo, 0);
   1452   }
   1453   CallAndGC(env->Global(), foo, force_compaction);
   1454 
   1455   // Test non IC break point with garbage collection.
   1456   {
   1457     v8::Local<v8::Function> bar =
   1458         CompileFunction(&env, "function foo(){}", "foo");
   1459     foo = CompileFunction(&env, "function foo(){var bar=0;}", "foo");
   1460     SetBreakPoint(foo, 0);
   1461   }
   1462   CallAndGC(env->Global(), foo, force_compaction);
   1463 
   1464 
   1465   v8::Debug::SetDebugEventListener(NULL);
   1466   CheckDebuggerUnloaded();
   1467 }
   1468 
   1469 
   1470 // Test that a break point can be set at a return store location.
   1471 TEST(BreakPointSurviveGC) {
   1472   TestBreakPointSurviveGC(false);
   1473   TestBreakPointSurviveGC(true);
   1474 }
   1475 
   1476 
   1477 // Test that break points can be set using the global Debug object.
   1478 TEST(BreakPointThroughJavaScript) {
   1479   break_point_hit_count = 0;
   1480   v8::HandleScope scope;
   1481   DebugLocalContext env;
   1482   env.ExposeDebug();
   1483 
   1484   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
   1485                                    v8::Undefined());
   1486   v8::Script::Compile(v8::String::New("function bar(){}"))->Run();
   1487   v8::Script::Compile(v8::String::New("function foo(){bar();bar();}"))->Run();
   1488   //                                               012345678901234567890
   1489   //                                                         1         2
   1490   // Break points are set at position 3 and 9
   1491   v8::Local<v8::Script> foo = v8::Script::Compile(v8::String::New("foo()"));
   1492 
   1493   // Run without breakpoints.
   1494   foo->Run();
   1495   CHECK_EQ(0, break_point_hit_count);
   1496 
   1497   // Run with one breakpoint
   1498   int bp1 = SetBreakPointFromJS("foo", 0, 3);
   1499   foo->Run();
   1500   CHECK_EQ(1, break_point_hit_count);
   1501   foo->Run();
   1502   CHECK_EQ(2, break_point_hit_count);
   1503 
   1504   // Run with two breakpoints
   1505   int bp2 = SetBreakPointFromJS("foo", 0, 9);
   1506   foo->Run();
   1507   CHECK_EQ(4, break_point_hit_count);
   1508   foo->Run();
   1509   CHECK_EQ(6, break_point_hit_count);
   1510 
   1511   // Run with one breakpoint
   1512   ClearBreakPointFromJS(bp2);
   1513   foo->Run();
   1514   CHECK_EQ(7, break_point_hit_count);
   1515   foo->Run();
   1516   CHECK_EQ(8, break_point_hit_count);
   1517 
   1518   // Run without breakpoints.
   1519   ClearBreakPointFromJS(bp1);
   1520   foo->Run();
   1521   CHECK_EQ(8, break_point_hit_count);
   1522 
   1523   v8::Debug::SetDebugEventListener(NULL);
   1524   CheckDebuggerUnloaded();
   1525 
   1526   // Make sure that the break point numbers are consecutive.
   1527   CHECK_EQ(1, bp1);
   1528   CHECK_EQ(2, bp2);
   1529 }
   1530 
   1531 
   1532 // Test that break points on scripts identified by name can be set using the
   1533 // global Debug object.
   1534 TEST(ScriptBreakPointByNameThroughJavaScript) {
   1535   break_point_hit_count = 0;
   1536   v8::HandleScope scope;
   1537   DebugLocalContext env;
   1538   env.ExposeDebug();
   1539 
   1540   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
   1541                                    v8::Undefined());
   1542 
   1543   v8::Local<v8::String> script = v8::String::New(
   1544     "function f() {\n"
   1545     "  function h() {\n"
   1546     "    a = 0;  // line 2\n"
   1547     "  }\n"
   1548     "  b = 1;  // line 4\n"
   1549     "  return h();\n"
   1550     "}\n"
   1551     "\n"
   1552     "function g() {\n"
   1553     "  function h() {\n"
   1554     "    a = 0;\n"
   1555     "  }\n"
   1556     "  b = 2;  // line 12\n"
   1557     "  h();\n"
   1558     "  b = 3;  // line 14\n"
   1559     "  f();    // line 15\n"
   1560     "}");
   1561 
   1562   // Compile the script and get the two functions.
   1563   v8::ScriptOrigin origin =
   1564       v8::ScriptOrigin(v8::String::New("test"));
   1565   v8::Script::Compile(script, &origin)->Run();
   1566   v8::Local<v8::Function> f =
   1567       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   1568   v8::Local<v8::Function> g =
   1569       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("g")));
   1570 
   1571   // Call f and g without break points.
   1572   break_point_hit_count = 0;
   1573   f->Call(env->Global(), 0, NULL);
   1574   CHECK_EQ(0, break_point_hit_count);
   1575   g->Call(env->Global(), 0, NULL);
   1576   CHECK_EQ(0, break_point_hit_count);
   1577 
   1578   // Call f and g with break point on line 12.
   1579   int sbp1 = SetScriptBreakPointByNameFromJS("test", 12, 0);
   1580   break_point_hit_count = 0;
   1581   f->Call(env->Global(), 0, NULL);
   1582   CHECK_EQ(0, break_point_hit_count);
   1583   g->Call(env->Global(), 0, NULL);
   1584   CHECK_EQ(1, break_point_hit_count);
   1585 
   1586   // Remove the break point again.
   1587   break_point_hit_count = 0;
   1588   ClearBreakPointFromJS(sbp1);
   1589   f->Call(env->Global(), 0, NULL);
   1590   CHECK_EQ(0, break_point_hit_count);
   1591   g->Call(env->Global(), 0, NULL);
   1592   CHECK_EQ(0, break_point_hit_count);
   1593 
   1594   // Call f and g with break point on line 2.
   1595   int sbp2 = SetScriptBreakPointByNameFromJS("test", 2, 0);
   1596   break_point_hit_count = 0;
   1597   f->Call(env->Global(), 0, NULL);
   1598   CHECK_EQ(1, break_point_hit_count);
   1599   g->Call(env->Global(), 0, NULL);
   1600   CHECK_EQ(2, break_point_hit_count);
   1601 
   1602   // Call f and g with break point on line 2, 4, 12, 14 and 15.
   1603   int sbp3 = SetScriptBreakPointByNameFromJS("test", 4, 0);
   1604   int sbp4 = SetScriptBreakPointByNameFromJS("test", 12, 0);
   1605   int sbp5 = SetScriptBreakPointByNameFromJS("test", 14, 0);
   1606   int sbp6 = SetScriptBreakPointByNameFromJS("test", 15, 0);
   1607   break_point_hit_count = 0;
   1608   f->Call(env->Global(), 0, NULL);
   1609   CHECK_EQ(2, break_point_hit_count);
   1610   g->Call(env->Global(), 0, NULL);
   1611   CHECK_EQ(7, break_point_hit_count);
   1612 
   1613   // Remove all the break points again.
   1614   break_point_hit_count = 0;
   1615   ClearBreakPointFromJS(sbp2);
   1616   ClearBreakPointFromJS(sbp3);
   1617   ClearBreakPointFromJS(sbp4);
   1618   ClearBreakPointFromJS(sbp5);
   1619   ClearBreakPointFromJS(sbp6);
   1620   f->Call(env->Global(), 0, NULL);
   1621   CHECK_EQ(0, break_point_hit_count);
   1622   g->Call(env->Global(), 0, NULL);
   1623   CHECK_EQ(0, break_point_hit_count);
   1624 
   1625   v8::Debug::SetDebugEventListener(NULL);
   1626   CheckDebuggerUnloaded();
   1627 
   1628   // Make sure that the break point numbers are consecutive.
   1629   CHECK_EQ(1, sbp1);
   1630   CHECK_EQ(2, sbp2);
   1631   CHECK_EQ(3, sbp3);
   1632   CHECK_EQ(4, sbp4);
   1633   CHECK_EQ(5, sbp5);
   1634   CHECK_EQ(6, sbp6);
   1635 }
   1636 
   1637 
   1638 TEST(ScriptBreakPointByIdThroughJavaScript) {
   1639   break_point_hit_count = 0;
   1640   v8::HandleScope scope;
   1641   DebugLocalContext env;
   1642   env.ExposeDebug();
   1643 
   1644   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
   1645                                    v8::Undefined());
   1646 
   1647   v8::Local<v8::String> source = v8::String::New(
   1648     "function f() {\n"
   1649     "  function h() {\n"
   1650     "    a = 0;  // line 2\n"
   1651     "  }\n"
   1652     "  b = 1;  // line 4\n"
   1653     "  return h();\n"
   1654     "}\n"
   1655     "\n"
   1656     "function g() {\n"
   1657     "  function h() {\n"
   1658     "    a = 0;\n"
   1659     "  }\n"
   1660     "  b = 2;  // line 12\n"
   1661     "  h();\n"
   1662     "  b = 3;  // line 14\n"
   1663     "  f();    // line 15\n"
   1664     "}");
   1665 
   1666   // Compile the script and get the two functions.
   1667   v8::ScriptOrigin origin =
   1668       v8::ScriptOrigin(v8::String::New("test"));
   1669   v8::Local<v8::Script> script = v8::Script::Compile(source, &origin);
   1670   script->Run();
   1671   v8::Local<v8::Function> f =
   1672       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   1673   v8::Local<v8::Function> g =
   1674       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("g")));
   1675 
   1676   // Get the script id knowing that internally it is a 32 integer.
   1677   uint32_t script_id = script->Id()->Uint32Value();
   1678 
   1679   // Call f and g without break points.
   1680   break_point_hit_count = 0;
   1681   f->Call(env->Global(), 0, NULL);
   1682   CHECK_EQ(0, break_point_hit_count);
   1683   g->Call(env->Global(), 0, NULL);
   1684   CHECK_EQ(0, break_point_hit_count);
   1685 
   1686   // Call f and g with break point on line 12.
   1687   int sbp1 = SetScriptBreakPointByIdFromJS(script_id, 12, 0);
   1688   break_point_hit_count = 0;
   1689   f->Call(env->Global(), 0, NULL);
   1690   CHECK_EQ(0, break_point_hit_count);
   1691   g->Call(env->Global(), 0, NULL);
   1692   CHECK_EQ(1, break_point_hit_count);
   1693 
   1694   // Remove the break point again.
   1695   break_point_hit_count = 0;
   1696   ClearBreakPointFromJS(sbp1);
   1697   f->Call(env->Global(), 0, NULL);
   1698   CHECK_EQ(0, break_point_hit_count);
   1699   g->Call(env->Global(), 0, NULL);
   1700   CHECK_EQ(0, break_point_hit_count);
   1701 
   1702   // Call f and g with break point on line 2.
   1703   int sbp2 = SetScriptBreakPointByIdFromJS(script_id, 2, 0);
   1704   break_point_hit_count = 0;
   1705   f->Call(env->Global(), 0, NULL);
   1706   CHECK_EQ(1, break_point_hit_count);
   1707   g->Call(env->Global(), 0, NULL);
   1708   CHECK_EQ(2, break_point_hit_count);
   1709 
   1710   // Call f and g with break point on line 2, 4, 12, 14 and 15.
   1711   int sbp3 = SetScriptBreakPointByIdFromJS(script_id, 4, 0);
   1712   int sbp4 = SetScriptBreakPointByIdFromJS(script_id, 12, 0);
   1713   int sbp5 = SetScriptBreakPointByIdFromJS(script_id, 14, 0);
   1714   int sbp6 = SetScriptBreakPointByIdFromJS(script_id, 15, 0);
   1715   break_point_hit_count = 0;
   1716   f->Call(env->Global(), 0, NULL);
   1717   CHECK_EQ(2, break_point_hit_count);
   1718   g->Call(env->Global(), 0, NULL);
   1719   CHECK_EQ(7, break_point_hit_count);
   1720 
   1721   // Remove all the break points again.
   1722   break_point_hit_count = 0;
   1723   ClearBreakPointFromJS(sbp2);
   1724   ClearBreakPointFromJS(sbp3);
   1725   ClearBreakPointFromJS(sbp4);
   1726   ClearBreakPointFromJS(sbp5);
   1727   ClearBreakPointFromJS(sbp6);
   1728   f->Call(env->Global(), 0, NULL);
   1729   CHECK_EQ(0, break_point_hit_count);
   1730   g->Call(env->Global(), 0, NULL);
   1731   CHECK_EQ(0, break_point_hit_count);
   1732 
   1733   v8::Debug::SetDebugEventListener(NULL);
   1734   CheckDebuggerUnloaded();
   1735 
   1736   // Make sure that the break point numbers are consecutive.
   1737   CHECK_EQ(1, sbp1);
   1738   CHECK_EQ(2, sbp2);
   1739   CHECK_EQ(3, sbp3);
   1740   CHECK_EQ(4, sbp4);
   1741   CHECK_EQ(5, sbp5);
   1742   CHECK_EQ(6, sbp6);
   1743 }
   1744 
   1745 
   1746 // Test conditional script break points.
   1747 TEST(EnableDisableScriptBreakPoint) {
   1748   break_point_hit_count = 0;
   1749   v8::HandleScope scope;
   1750   DebugLocalContext env;
   1751   env.ExposeDebug();
   1752 
   1753   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
   1754                                    v8::Undefined());
   1755 
   1756   v8::Local<v8::String> script = v8::String::New(
   1757     "function f() {\n"
   1758     "  a = 0;  // line 1\n"
   1759     "};");
   1760 
   1761   // Compile the script and get function f.
   1762   v8::ScriptOrigin origin =
   1763       v8::ScriptOrigin(v8::String::New("test"));
   1764   v8::Script::Compile(script, &origin)->Run();
   1765   v8::Local<v8::Function> f =
   1766       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   1767 
   1768   // Set script break point on line 1 (in function f).
   1769   int sbp = SetScriptBreakPointByNameFromJS("test", 1, 0);
   1770 
   1771   // Call f while enabeling and disabling the script break point.
   1772   break_point_hit_count = 0;
   1773   f->Call(env->Global(), 0, NULL);
   1774   CHECK_EQ(1, break_point_hit_count);
   1775 
   1776   DisableScriptBreakPointFromJS(sbp);
   1777   f->Call(env->Global(), 0, NULL);
   1778   CHECK_EQ(1, break_point_hit_count);
   1779 
   1780   EnableScriptBreakPointFromJS(sbp);
   1781   f->Call(env->Global(), 0, NULL);
   1782   CHECK_EQ(2, break_point_hit_count);
   1783 
   1784   DisableScriptBreakPointFromJS(sbp);
   1785   f->Call(env->Global(), 0, NULL);
   1786   CHECK_EQ(2, break_point_hit_count);
   1787 
   1788   // Reload the script and get f again checking that the disabeling survives.
   1789   v8::Script::Compile(script, &origin)->Run();
   1790   f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   1791   f->Call(env->Global(), 0, NULL);
   1792   CHECK_EQ(2, break_point_hit_count);
   1793 
   1794   EnableScriptBreakPointFromJS(sbp);
   1795   f->Call(env->Global(), 0, NULL);
   1796   CHECK_EQ(3, break_point_hit_count);
   1797 
   1798   v8::Debug::SetDebugEventListener(NULL);
   1799   CheckDebuggerUnloaded();
   1800 }
   1801 
   1802 
   1803 // Test conditional script break points.
   1804 TEST(ConditionalScriptBreakPoint) {
   1805   break_point_hit_count = 0;
   1806   v8::HandleScope scope;
   1807   DebugLocalContext env;
   1808   env.ExposeDebug();
   1809 
   1810   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
   1811                                    v8::Undefined());
   1812 
   1813   v8::Local<v8::String> script = v8::String::New(
   1814     "count = 0;\n"
   1815     "function f() {\n"
   1816     "  g(count++);  // line 2\n"
   1817     "};\n"
   1818     "function g(x) {\n"
   1819     "  var a=x;  // line 5\n"
   1820     "};");
   1821 
   1822   // Compile the script and get function f.
   1823   v8::ScriptOrigin origin =
   1824       v8::ScriptOrigin(v8::String::New("test"));
   1825   v8::Script::Compile(script, &origin)->Run();
   1826   v8::Local<v8::Function> f =
   1827       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   1828 
   1829   // Set script break point on line 5 (in function g).
   1830   int sbp1 = SetScriptBreakPointByNameFromJS("test", 5, 0);
   1831 
   1832   // Call f with different conditions on the script break point.
   1833   break_point_hit_count = 0;
   1834   ChangeScriptBreakPointConditionFromJS(sbp1, "false");
   1835   f->Call(env->Global(), 0, NULL);
   1836   CHECK_EQ(0, break_point_hit_count);
   1837 
   1838   ChangeScriptBreakPointConditionFromJS(sbp1, "true");
   1839   break_point_hit_count = 0;
   1840   f->Call(env->Global(), 0, NULL);
   1841   CHECK_EQ(1, break_point_hit_count);
   1842 
   1843   ChangeScriptBreakPointConditionFromJS(sbp1, "x % 2 == 0");
   1844   break_point_hit_count = 0;
   1845   for (int i = 0; i < 10; i++) {
   1846     f->Call(env->Global(), 0, NULL);
   1847   }
   1848   CHECK_EQ(5, break_point_hit_count);
   1849 
   1850   // Reload the script and get f again checking that the condition survives.
   1851   v8::Script::Compile(script, &origin)->Run();
   1852   f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   1853 
   1854   break_point_hit_count = 0;
   1855   for (int i = 0; i < 10; i++) {
   1856     f->Call(env->Global(), 0, NULL);
   1857   }
   1858   CHECK_EQ(5, break_point_hit_count);
   1859 
   1860   v8::Debug::SetDebugEventListener(NULL);
   1861   CheckDebuggerUnloaded();
   1862 }
   1863 
   1864 
   1865 // Test ignore count on script break points.
   1866 TEST(ScriptBreakPointIgnoreCount) {
   1867   break_point_hit_count = 0;
   1868   v8::HandleScope scope;
   1869   DebugLocalContext env;
   1870   env.ExposeDebug();
   1871 
   1872   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
   1873                                    v8::Undefined());
   1874 
   1875   v8::Local<v8::String> script = v8::String::New(
   1876     "function f() {\n"
   1877     "  a = 0;  // line 1\n"
   1878     "};");
   1879 
   1880   // Compile the script and get function f.
   1881   v8::ScriptOrigin origin =
   1882       v8::ScriptOrigin(v8::String::New("test"));
   1883   v8::Script::Compile(script, &origin)->Run();
   1884   v8::Local<v8::Function> f =
   1885       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   1886 
   1887   // Set script break point on line 1 (in function f).
   1888   int sbp = SetScriptBreakPointByNameFromJS("test", 1, 0);
   1889 
   1890   // Call f with different ignores on the script break point.
   1891   break_point_hit_count = 0;
   1892   ChangeScriptBreakPointIgnoreCountFromJS(sbp, 1);
   1893   f->Call(env->Global(), 0, NULL);
   1894   CHECK_EQ(0, break_point_hit_count);
   1895   f->Call(env->Global(), 0, NULL);
   1896   CHECK_EQ(1, break_point_hit_count);
   1897 
   1898   ChangeScriptBreakPointIgnoreCountFromJS(sbp, 5);
   1899   break_point_hit_count = 0;
   1900   for (int i = 0; i < 10; i++) {
   1901     f->Call(env->Global(), 0, NULL);
   1902   }
   1903   CHECK_EQ(5, break_point_hit_count);
   1904 
   1905   // Reload the script and get f again checking that the ignore survives.
   1906   v8::Script::Compile(script, &origin)->Run();
   1907   f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   1908 
   1909   break_point_hit_count = 0;
   1910   for (int i = 0; i < 10; i++) {
   1911     f->Call(env->Global(), 0, NULL);
   1912   }
   1913   CHECK_EQ(5, break_point_hit_count);
   1914 
   1915   v8::Debug::SetDebugEventListener(NULL);
   1916   CheckDebuggerUnloaded();
   1917 }
   1918 
   1919 
   1920 // Test that script break points survive when a script is reloaded.
   1921 TEST(ScriptBreakPointReload) {
   1922   break_point_hit_count = 0;
   1923   v8::HandleScope scope;
   1924   DebugLocalContext env;
   1925   env.ExposeDebug();
   1926 
   1927   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
   1928                                    v8::Undefined());
   1929 
   1930   v8::Local<v8::Function> f;
   1931   v8::Local<v8::String> script = v8::String::New(
   1932     "function f() {\n"
   1933     "  function h() {\n"
   1934     "    a = 0;  // line 2\n"
   1935     "  }\n"
   1936     "  b = 1;  // line 4\n"
   1937     "  return h();\n"
   1938     "}");
   1939 
   1940   v8::ScriptOrigin origin_1 = v8::ScriptOrigin(v8::String::New("1"));
   1941   v8::ScriptOrigin origin_2 = v8::ScriptOrigin(v8::String::New("2"));
   1942 
   1943   // Set a script break point before the script is loaded.
   1944   SetScriptBreakPointByNameFromJS("1", 2, 0);
   1945 
   1946   // Compile the script and get the function.
   1947   v8::Script::Compile(script, &origin_1)->Run();
   1948   f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   1949 
   1950   // Call f and check that the script break point is active.
   1951   break_point_hit_count = 0;
   1952   f->Call(env->Global(), 0, NULL);
   1953   CHECK_EQ(1, break_point_hit_count);
   1954 
   1955   // Compile the script again with a different script data and get the
   1956   // function.
   1957   v8::Script::Compile(script, &origin_2)->Run();
   1958   f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   1959 
   1960   // Call f and check that no break points are set.
   1961   break_point_hit_count = 0;
   1962   f->Call(env->Global(), 0, NULL);
   1963   CHECK_EQ(0, break_point_hit_count);
   1964 
   1965   // Compile the script again and get the function.
   1966   v8::Script::Compile(script, &origin_1)->Run();
   1967   f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   1968 
   1969   // Call f and check that the script break point is active.
   1970   break_point_hit_count = 0;
   1971   f->Call(env->Global(), 0, NULL);
   1972   CHECK_EQ(1, break_point_hit_count);
   1973 
   1974   v8::Debug::SetDebugEventListener(NULL);
   1975   CheckDebuggerUnloaded();
   1976 }
   1977 
   1978 
   1979 // Test when several scripts has the same script data
   1980 TEST(ScriptBreakPointMultiple) {
   1981   break_point_hit_count = 0;
   1982   v8::HandleScope scope;
   1983   DebugLocalContext env;
   1984   env.ExposeDebug();
   1985 
   1986   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
   1987                                    v8::Undefined());
   1988 
   1989   v8::Local<v8::Function> f;
   1990   v8::Local<v8::String> script_f = v8::String::New(
   1991     "function f() {\n"
   1992     "  a = 0;  // line 1\n"
   1993     "}");
   1994 
   1995   v8::Local<v8::Function> g;
   1996   v8::Local<v8::String> script_g = v8::String::New(
   1997     "function g() {\n"
   1998     "  b = 0;  // line 1\n"
   1999     "}");
   2000 
   2001   v8::ScriptOrigin origin =
   2002       v8::ScriptOrigin(v8::String::New("test"));
   2003 
   2004   // Set a script break point before the scripts are loaded.
   2005   int sbp = SetScriptBreakPointByNameFromJS("test", 1, 0);
   2006 
   2007   // Compile the scripts with same script data and get the functions.
   2008   v8::Script::Compile(script_f, &origin)->Run();
   2009   f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   2010   v8::Script::Compile(script_g, &origin)->Run();
   2011   g = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("g")));
   2012 
   2013   // Call f and g and check that the script break point is active.
   2014   break_point_hit_count = 0;
   2015   f->Call(env->Global(), 0, NULL);
   2016   CHECK_EQ(1, break_point_hit_count);
   2017   g->Call(env->Global(), 0, NULL);
   2018   CHECK_EQ(2, break_point_hit_count);
   2019 
   2020   // Clear the script break point.
   2021   ClearBreakPointFromJS(sbp);
   2022 
   2023   // Call f and g and check that the script break point is no longer active.
   2024   break_point_hit_count = 0;
   2025   f->Call(env->Global(), 0, NULL);
   2026   CHECK_EQ(0, break_point_hit_count);
   2027   g->Call(env->Global(), 0, NULL);
   2028   CHECK_EQ(0, break_point_hit_count);
   2029 
   2030   // Set script break point with the scripts loaded.
   2031   sbp = SetScriptBreakPointByNameFromJS("test", 1, 0);
   2032 
   2033   // Call f and g and check that the script break point is active.
   2034   break_point_hit_count = 0;
   2035   f->Call(env->Global(), 0, NULL);
   2036   CHECK_EQ(1, break_point_hit_count);
   2037   g->Call(env->Global(), 0, NULL);
   2038   CHECK_EQ(2, break_point_hit_count);
   2039 
   2040   v8::Debug::SetDebugEventListener(NULL);
   2041   CheckDebuggerUnloaded();
   2042 }
   2043 
   2044 
   2045 // Test the script origin which has both name and line offset.
   2046 TEST(ScriptBreakPointLineOffset) {
   2047   break_point_hit_count = 0;
   2048   v8::HandleScope scope;
   2049   DebugLocalContext env;
   2050   env.ExposeDebug();
   2051 
   2052   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
   2053                                    v8::Undefined());
   2054 
   2055   v8::Local<v8::Function> f;
   2056   v8::Local<v8::String> script = v8::String::New(
   2057     "function f() {\n"
   2058     "  a = 0;  // line 8 as this script has line offset 7\n"
   2059     "  b = 0;  // line 9 as this script has line offset 7\n"
   2060     "}");
   2061 
   2062   // Create script origin both name and line offset.
   2063   v8::ScriptOrigin origin(v8::String::New("test.html"),
   2064                           v8::Integer::New(7));
   2065 
   2066   // Set two script break points before the script is loaded.
   2067   int sbp1 = SetScriptBreakPointByNameFromJS("test.html", 8, 0);
   2068   int sbp2 = SetScriptBreakPointByNameFromJS("test.html", 9, 0);
   2069 
   2070   // Compile the script and get the function.
   2071   v8::Script::Compile(script, &origin)->Run();
   2072   f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   2073 
   2074   // Call f and check that the script break point is active.
   2075   break_point_hit_count = 0;
   2076   f->Call(env->Global(), 0, NULL);
   2077   CHECK_EQ(2, break_point_hit_count);
   2078 
   2079   // Clear the script break points.
   2080   ClearBreakPointFromJS(sbp1);
   2081   ClearBreakPointFromJS(sbp2);
   2082 
   2083   // Call f and check that no script break points are active.
   2084   break_point_hit_count = 0;
   2085   f->Call(env->Global(), 0, NULL);
   2086   CHECK_EQ(0, break_point_hit_count);
   2087 
   2088   // Set a script break point with the script loaded.
   2089   sbp1 = SetScriptBreakPointByNameFromJS("test.html", 9, 0);
   2090 
   2091   // Call f and check that the script break point is active.
   2092   break_point_hit_count = 0;
   2093   f->Call(env->Global(), 0, NULL);
   2094   CHECK_EQ(1, break_point_hit_count);
   2095 
   2096   v8::Debug::SetDebugEventListener(NULL);
   2097   CheckDebuggerUnloaded();
   2098 }
   2099 
   2100 
   2101 // Test script break points set on lines.
   2102 TEST(ScriptBreakPointLine) {
   2103   v8::HandleScope scope;
   2104   DebugLocalContext env;
   2105   env.ExposeDebug();
   2106 
   2107   // Create a function for checking the function when hitting a break point.
   2108   frame_function_name = CompileFunction(&env,
   2109                                         frame_function_name_source,
   2110                                         "frame_function_name");
   2111 
   2112   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
   2113                                    v8::Undefined());
   2114 
   2115   v8::Local<v8::Function> f;
   2116   v8::Local<v8::Function> g;
   2117   v8::Local<v8::String> script = v8::String::New(
   2118     "a = 0                      // line 0\n"
   2119     "function f() {\n"
   2120     "  a = 1;                   // line 2\n"
   2121     "}\n"
   2122     " a = 2;                    // line 4\n"
   2123     "  /* xx */ function g() {  // line 5\n"
   2124     "    function h() {         // line 6\n"
   2125     "      a = 3;               // line 7\n"
   2126     "    }\n"
   2127     "    h();                   // line 9\n"
   2128     "    a = 4;                 // line 10\n"
   2129     "  }\n"
   2130     " a=5;                      // line 12");
   2131 
   2132   // Set a couple script break point before the script is loaded.
   2133   int sbp1 = SetScriptBreakPointByNameFromJS("test.html", 0, -1);
   2134   int sbp2 = SetScriptBreakPointByNameFromJS("test.html", 1, -1);
   2135   int sbp3 = SetScriptBreakPointByNameFromJS("test.html", 5, -1);
   2136 
   2137   // Compile the script and get the function.
   2138   break_point_hit_count = 0;
   2139   v8::ScriptOrigin origin(v8::String::New("test.html"), v8::Integer::New(0));
   2140   v8::Script::Compile(script, &origin)->Run();
   2141   f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   2142   g = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("g")));
   2143 
   2144   // Chesk that a break point was hit when the script was run.
   2145   CHECK_EQ(1, break_point_hit_count);
   2146   CHECK_EQ(0, StrLength(last_function_hit));
   2147 
   2148   // Call f and check that the script break point.
   2149   f->Call(env->Global(), 0, NULL);
   2150   CHECK_EQ(2, break_point_hit_count);
   2151   CHECK_EQ("f", last_function_hit);
   2152 
   2153   // Call g and check that the script break point.
   2154   g->Call(env->Global(), 0, NULL);
   2155   CHECK_EQ(3, break_point_hit_count);
   2156   CHECK_EQ("g", last_function_hit);
   2157 
   2158   // Clear the script break point on g and set one on h.
   2159   ClearBreakPointFromJS(sbp3);
   2160   int sbp4 = SetScriptBreakPointByNameFromJS("test.html", 6, -1);
   2161 
   2162   // Call g and check that the script break point in h is hit.
   2163   g->Call(env->Global(), 0, NULL);
   2164   CHECK_EQ(4, break_point_hit_count);
   2165   CHECK_EQ("h", last_function_hit);
   2166 
   2167   // Clear break points in f and h. Set a new one in the script between
   2168   // functions f and g and test that there is no break points in f and g any
   2169   // more.
   2170   ClearBreakPointFromJS(sbp2);
   2171   ClearBreakPointFromJS(sbp4);
   2172   int sbp5 = SetScriptBreakPointByNameFromJS("test.html", 4, -1);
   2173   break_point_hit_count = 0;
   2174   f->Call(env->Global(), 0, NULL);
   2175   g->Call(env->Global(), 0, NULL);
   2176   CHECK_EQ(0, break_point_hit_count);
   2177 
   2178   // Reload the script which should hit two break points.
   2179   break_point_hit_count = 0;
   2180   v8::Script::Compile(script, &origin)->Run();
   2181   CHECK_EQ(2, break_point_hit_count);
   2182   CHECK_EQ(0, StrLength(last_function_hit));
   2183 
   2184   // Set a break point in the code after the last function decleration.
   2185   int sbp6 = SetScriptBreakPointByNameFromJS("test.html", 12, -1);
   2186 
   2187   // Reload the script which should hit three break points.
   2188   break_point_hit_count = 0;
   2189   v8::Script::Compile(script, &origin)->Run();
   2190   CHECK_EQ(3, break_point_hit_count);
   2191   CHECK_EQ(0, StrLength(last_function_hit));
   2192 
   2193   // Clear the last break points, and reload the script which should not hit any
   2194   // break points.
   2195   ClearBreakPointFromJS(sbp1);
   2196   ClearBreakPointFromJS(sbp5);
   2197   ClearBreakPointFromJS(sbp6);
   2198   break_point_hit_count = 0;
   2199   v8::Script::Compile(script, &origin)->Run();
   2200   CHECK_EQ(0, break_point_hit_count);
   2201 
   2202   v8::Debug::SetDebugEventListener(NULL);
   2203   CheckDebuggerUnloaded();
   2204 }
   2205 
   2206 
   2207 // Test top level script break points set on lines.
   2208 TEST(ScriptBreakPointLineTopLevel) {
   2209   v8::HandleScope scope;
   2210   DebugLocalContext env;
   2211   env.ExposeDebug();
   2212 
   2213   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
   2214                                    v8::Undefined());
   2215 
   2216   v8::Local<v8::String> script = v8::String::New(
   2217     "function f() {\n"
   2218     "  a = 1;                   // line 1\n"
   2219     "}\n"
   2220     "a = 2;                     // line 3\n");
   2221   v8::Local<v8::Function> f;
   2222   {
   2223     v8::HandleScope scope;
   2224     v8::Script::Compile(script, v8::String::New("test.html"))->Run();
   2225   }
   2226   f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   2227 
   2228   HEAP->CollectAllGarbage(false);
   2229 
   2230   SetScriptBreakPointByNameFromJS("test.html", 3, -1);
   2231 
   2232   // Call f and check that there was no break points.
   2233   break_point_hit_count = 0;
   2234   f->Call(env->Global(), 0, NULL);
   2235   CHECK_EQ(0, break_point_hit_count);
   2236 
   2237   // Recompile and run script and check that break point was hit.
   2238   break_point_hit_count = 0;
   2239   v8::Script::Compile(script, v8::String::New("test.html"))->Run();
   2240   CHECK_EQ(1, break_point_hit_count);
   2241 
   2242   // Call f and check that there are still no break points.
   2243   break_point_hit_count = 0;
   2244   f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   2245   CHECK_EQ(0, break_point_hit_count);
   2246 
   2247   v8::Debug::SetDebugEventListener(NULL);
   2248   CheckDebuggerUnloaded();
   2249 }
   2250 
   2251 
   2252 // Test that it is possible to add and remove break points in a top level
   2253 // function which has no references but has not been collected yet.
   2254 TEST(ScriptBreakPointTopLevelCrash) {
   2255   v8::HandleScope scope;
   2256   DebugLocalContext env;
   2257   env.ExposeDebug();
   2258 
   2259   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
   2260                                    v8::Undefined());
   2261 
   2262   v8::Local<v8::String> script_source = v8::String::New(
   2263     "function f() {\n"
   2264     "  return 0;\n"
   2265     "}\n"
   2266     "f()");
   2267 
   2268   int sbp1 = SetScriptBreakPointByNameFromJS("test.html", 3, -1);
   2269   {
   2270     v8::HandleScope scope;
   2271     break_point_hit_count = 0;
   2272     v8::Script::Compile(script_source, v8::String::New("test.html"))->Run();
   2273     CHECK_EQ(1, break_point_hit_count);
   2274   }
   2275 
   2276   int sbp2 = SetScriptBreakPointByNameFromJS("test.html", 3, -1);
   2277   ClearBreakPointFromJS(sbp1);
   2278   ClearBreakPointFromJS(sbp2);
   2279 
   2280   v8::Debug::SetDebugEventListener(NULL);
   2281   CheckDebuggerUnloaded();
   2282 }
   2283 
   2284 
   2285 // Test that it is possible to remove the last break point for a function
   2286 // inside the break handling of that break point.
   2287 TEST(RemoveBreakPointInBreak) {
   2288   v8::HandleScope scope;
   2289   DebugLocalContext env;
   2290 
   2291   v8::Local<v8::Function> foo =
   2292       CompileFunction(&env, "function foo(){a=1;}", "foo");
   2293   debug_event_remove_break_point = SetBreakPoint(foo, 0);
   2294 
   2295   // Register the debug event listener pasing the function
   2296   v8::Debug::SetDebugEventListener(DebugEventRemoveBreakPoint, foo);
   2297 
   2298   break_point_hit_count = 0;
   2299   foo->Call(env->Global(), 0, NULL);
   2300   CHECK_EQ(1, break_point_hit_count);
   2301 
   2302   break_point_hit_count = 0;
   2303   foo->Call(env->Global(), 0, NULL);
   2304   CHECK_EQ(0, break_point_hit_count);
   2305 
   2306   v8::Debug::SetDebugEventListener(NULL);
   2307   CheckDebuggerUnloaded();
   2308 }
   2309 
   2310 
   2311 // Test that the debugger statement causes a break.
   2312 TEST(DebuggerStatement) {
   2313   break_point_hit_count = 0;
   2314   v8::HandleScope scope;
   2315   DebugLocalContext env;
   2316   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
   2317                                    v8::Undefined());
   2318   v8::Script::Compile(v8::String::New("function bar(){debugger}"))->Run();
   2319   v8::Script::Compile(v8::String::New(
   2320       "function foo(){debugger;debugger;}"))->Run();
   2321   v8::Local<v8::Function> foo =
   2322       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
   2323   v8::Local<v8::Function> bar =
   2324       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("bar")));
   2325 
   2326   // Run function with debugger statement
   2327   bar->Call(env->Global(), 0, NULL);
   2328   CHECK_EQ(1, break_point_hit_count);
   2329 
   2330   // Run function with two debugger statement
   2331   foo->Call(env->Global(), 0, NULL);
   2332   CHECK_EQ(3, break_point_hit_count);
   2333 
   2334   v8::Debug::SetDebugEventListener(NULL);
   2335   CheckDebuggerUnloaded();
   2336 }
   2337 
   2338 
   2339 // Test setting a breakpoint on the debugger statement.
   2340 TEST(DebuggerStatementBreakpoint) {
   2341     break_point_hit_count = 0;
   2342     v8::HandleScope scope;
   2343     DebugLocalContext env;
   2344     v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
   2345                                      v8::Undefined());
   2346     v8::Script::Compile(v8::String::New("function foo(){debugger;}"))->Run();
   2347     v8::Local<v8::Function> foo =
   2348     v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
   2349 
   2350     // The debugger statement triggers breakpint hit
   2351     foo->Call(env->Global(), 0, NULL);
   2352     CHECK_EQ(1, break_point_hit_count);
   2353 
   2354     int bp = SetBreakPoint(foo, 0);
   2355 
   2356     // Set breakpoint does not duplicate hits
   2357     foo->Call(env->Global(), 0, NULL);
   2358     CHECK_EQ(2, break_point_hit_count);
   2359 
   2360     ClearBreakPoint(bp);
   2361     v8::Debug::SetDebugEventListener(NULL);
   2362     CheckDebuggerUnloaded();
   2363 }
   2364 
   2365 
   2366 // Thest that the evaluation of expressions when a break point is hit generates
   2367 // the correct results.
   2368 TEST(DebugEvaluate) {
   2369   v8::HandleScope scope;
   2370   DebugLocalContext env;
   2371   env.ExposeDebug();
   2372 
   2373   // Create a function for checking the evaluation when hitting a break point.
   2374   evaluate_check_function = CompileFunction(&env,
   2375                                             evaluate_check_source,
   2376                                             "evaluate_check");
   2377   // Register the debug event listener
   2378   v8::Debug::SetDebugEventListener(DebugEventEvaluate);
   2379 
   2380   // Different expected vaules of x and a when in a break point (u = undefined,
   2381   // d = Hello, world!).
   2382   struct EvaluateCheck checks_uu[] = {
   2383     {"x", v8::Undefined()},
   2384     {"a", v8::Undefined()},
   2385     {NULL, v8::Handle<v8::Value>()}
   2386   };
   2387   struct EvaluateCheck checks_hu[] = {
   2388     {"x", v8::String::New("Hello, world!")},
   2389     {"a", v8::Undefined()},
   2390     {NULL, v8::Handle<v8::Value>()}
   2391   };
   2392   struct EvaluateCheck checks_hh[] = {
   2393     {"x", v8::String::New("Hello, world!")},
   2394     {"a", v8::String::New("Hello, world!")},
   2395     {NULL, v8::Handle<v8::Value>()}
   2396   };
   2397 
   2398   // Simple test function. The "y=0" is in the function foo to provide a break
   2399   // location. For "y=0" the "y" is at position 15 in the barbar function
   2400   // therefore setting breakpoint at position 15 will break at "y=0" and
   2401   // setting it higher will break after.
   2402   v8::Local<v8::Function> foo = CompileFunction(&env,
   2403     "function foo(x) {"
   2404     "  var a;"
   2405     "  y=0;"  // To ensure break location 1.
   2406     "  a=x;"
   2407     "  y=0;"  // To ensure break location 2.
   2408     "}",
   2409     "foo");
   2410   const int foo_break_position_1 = 15;
   2411   const int foo_break_position_2 = 29;
   2412 
   2413   // Arguments with one parameter "Hello, world!"
   2414   v8::Handle<v8::Value> argv_foo[1] = { v8::String::New("Hello, world!") };
   2415 
   2416   // Call foo with breakpoint set before a=x and undefined as parameter.
   2417   int bp = SetBreakPoint(foo, foo_break_position_1);
   2418   checks = checks_uu;
   2419   foo->Call(env->Global(), 0, NULL);
   2420 
   2421   // Call foo with breakpoint set before a=x and parameter "Hello, world!".
   2422   checks = checks_hu;
   2423   foo->Call(env->Global(), 1, argv_foo);
   2424 
   2425   // Call foo with breakpoint set after a=x and parameter "Hello, world!".
   2426   ClearBreakPoint(bp);
   2427   SetBreakPoint(foo, foo_break_position_2);
   2428   checks = checks_hh;
   2429   foo->Call(env->Global(), 1, argv_foo);
   2430 
   2431   // Test function with an inner function. The "y=0" is in function barbar
   2432   // to provide a break location. For "y=0" the "y" is at position 8 in the
   2433   // barbar function therefore setting breakpoint at position 8 will break at
   2434   // "y=0" and setting it higher will break after.
   2435   v8::Local<v8::Function> bar = CompileFunction(&env,
   2436     "y = 0;"
   2437     "x = 'Goodbye, world!';"
   2438     "function bar(x, b) {"
   2439     "  var a;"
   2440     "  function barbar() {"
   2441     "    y=0; /* To ensure break location.*/"
   2442     "    a=x;"
   2443     "  };"
   2444     "  debug.Debug.clearAllBreakPoints();"
   2445     "  barbar();"
   2446     "  y=0;a=x;"
   2447     "}",
   2448     "bar");
   2449   const int barbar_break_position = 8;
   2450 
   2451   // Call bar setting breakpoint before a=x in barbar and undefined as
   2452   // parameter.
   2453   checks = checks_uu;
   2454   v8::Handle<v8::Value> argv_bar_1[2] = {
   2455     v8::Undefined(),
   2456     v8::Number::New(barbar_break_position)
   2457   };
   2458   bar->Call(env->Global(), 2, argv_bar_1);
   2459 
   2460   // Call bar setting breakpoint before a=x in barbar and parameter
   2461   // "Hello, world!".
   2462   checks = checks_hu;
   2463   v8::Handle<v8::Value> argv_bar_2[2] = {
   2464     v8::String::New("Hello, world!"),
   2465     v8::Number::New(barbar_break_position)
   2466   };
   2467   bar->Call(env->Global(), 2, argv_bar_2);
   2468 
   2469   // Call bar setting breakpoint after a=x in barbar and parameter
   2470   // "Hello, world!".
   2471   checks = checks_hh;
   2472   v8::Handle<v8::Value> argv_bar_3[2] = {
   2473     v8::String::New("Hello, world!"),
   2474     v8::Number::New(barbar_break_position + 1)
   2475   };
   2476   bar->Call(env->Global(), 2, argv_bar_3);
   2477 
   2478   v8::Debug::SetDebugEventListener(NULL);
   2479   CheckDebuggerUnloaded();
   2480 }
   2481 
   2482 // Copies a C string to a 16-bit string.  Does not check for buffer overflow.
   2483 // Does not use the V8 engine to convert strings, so it can be used
   2484 // in any thread.  Returns the length of the string.
   2485 int AsciiToUtf16(const char* input_buffer, uint16_t* output_buffer) {
   2486   int i;
   2487   for (i = 0; input_buffer[i] != '\0'; ++i) {
   2488     // ASCII does not use chars > 127, but be careful anyway.
   2489     output_buffer[i] = static_cast<unsigned char>(input_buffer[i]);
   2490   }
   2491   output_buffer[i] = 0;
   2492   return i;
   2493 }
   2494 
   2495 // Copies a 16-bit string to a C string by dropping the high byte of
   2496 // each character.  Does not check for buffer overflow.
   2497 // Can be used in any thread.  Requires string length as an input.
   2498 int Utf16ToAscii(const uint16_t* input_buffer, int length,
   2499                  char* output_buffer, int output_len = -1) {
   2500   if (output_len >= 0) {
   2501     if (length > output_len - 1) {
   2502       length = output_len - 1;
   2503     }
   2504   }
   2505 
   2506   for (int i = 0; i < length; ++i) {
   2507     output_buffer[i] = static_cast<char>(input_buffer[i]);
   2508   }
   2509   output_buffer[length] = '\0';
   2510   return length;
   2511 }
   2512 
   2513 
   2514 // We match parts of the message to get evaluate result int value.
   2515 bool GetEvaluateStringResult(char *message, char* buffer, int buffer_size) {
   2516   if (strstr(message, "\"command\":\"evaluate\"") == NULL) {
   2517     return false;
   2518   }
   2519   const char* prefix = "\"text\":\"";
   2520   char* pos1 = strstr(message, prefix);
   2521   if (pos1 == NULL) {
   2522     return false;
   2523   }
   2524   pos1 += strlen(prefix);
   2525   char* pos2 = strchr(pos1, '"');
   2526   if (pos2 == NULL) {
   2527     return false;
   2528   }
   2529   Vector<char> buf(buffer, buffer_size);
   2530   int len = static_cast<int>(pos2 - pos1);
   2531   if (len > buffer_size - 1) {
   2532     len = buffer_size - 1;
   2533   }
   2534   OS::StrNCpy(buf, pos1, len);
   2535   buffer[buffer_size - 1] = '\0';
   2536   return true;
   2537 }
   2538 
   2539 
   2540 struct EvaluateResult {
   2541   static const int kBufferSize = 20;
   2542   char buffer[kBufferSize];
   2543 };
   2544 
   2545 struct DebugProcessDebugMessagesData {
   2546   static const int kArraySize = 5;
   2547   int counter;
   2548   EvaluateResult results[kArraySize];
   2549 
   2550   void reset() {
   2551     counter = 0;
   2552   }
   2553   EvaluateResult* current() {
   2554     return &results[counter % kArraySize];
   2555   }
   2556   void next() {
   2557     counter++;
   2558   }
   2559 };
   2560 
   2561 DebugProcessDebugMessagesData process_debug_messages_data;
   2562 
   2563 static void DebugProcessDebugMessagesHandler(
   2564     const uint16_t* message,
   2565     int length,
   2566     v8::Debug::ClientData* client_data) {
   2567 
   2568   const int kBufferSize = 100000;
   2569   char print_buffer[kBufferSize];
   2570   Utf16ToAscii(message, length, print_buffer, kBufferSize);
   2571 
   2572   EvaluateResult* array_item = process_debug_messages_data.current();
   2573 
   2574   bool res = GetEvaluateStringResult(print_buffer,
   2575                                      array_item->buffer,
   2576                                      EvaluateResult::kBufferSize);
   2577   if (res) {
   2578     process_debug_messages_data.next();
   2579   }
   2580 }
   2581 
   2582 // Test that the evaluation of expressions works even from ProcessDebugMessages
   2583 // i.e. with empty stack.
   2584 TEST(DebugEvaluateWithoutStack) {
   2585   v8::Debug::SetMessageHandler(DebugProcessDebugMessagesHandler);
   2586 
   2587   v8::HandleScope scope;
   2588   DebugLocalContext env;
   2589 
   2590   const char* source =
   2591       "var v1 = 'Pinguin';\n function getAnimal() { return 'Capy' + 'bara'; }";
   2592 
   2593   v8::Script::Compile(v8::String::New(source))->Run();
   2594 
   2595   v8::Debug::ProcessDebugMessages();
   2596 
   2597   const int kBufferSize = 1000;
   2598   uint16_t buffer[kBufferSize];
   2599 
   2600   const char* command_111 = "{\"seq\":111,"
   2601       "\"type\":\"request\","
   2602       "\"command\":\"evaluate\","
   2603       "\"arguments\":{"
   2604       "    \"global\":true,"
   2605       "    \"expression\":\"v1\",\"disable_break\":true"
   2606       "}}";
   2607 
   2608   v8::Debug::SendCommand(buffer, AsciiToUtf16(command_111, buffer));
   2609 
   2610   const char* command_112 = "{\"seq\":112,"
   2611       "\"type\":\"request\","
   2612       "\"command\":\"evaluate\","
   2613       "\"arguments\":{"
   2614       "    \"global\":true,"
   2615       "    \"expression\":\"getAnimal()\",\"disable_break\":true"
   2616       "}}";
   2617 
   2618   v8::Debug::SendCommand(buffer, AsciiToUtf16(command_112, buffer));
   2619 
   2620   const char* command_113 = "{\"seq\":113,"
   2621      "\"type\":\"request\","
   2622      "\"command\":\"evaluate\","
   2623      "\"arguments\":{"
   2624      "    \"global\":true,"
   2625      "    \"expression\":\"239 + 566\",\"disable_break\":true"
   2626      "}}";
   2627 
   2628   v8::Debug::SendCommand(buffer, AsciiToUtf16(command_113, buffer));
   2629 
   2630   v8::Debug::ProcessDebugMessages();
   2631 
   2632   CHECK_EQ(3, process_debug_messages_data.counter);
   2633 
   2634   CHECK_EQ(strcmp("Pinguin", process_debug_messages_data.results[0].buffer), 0);
   2635   CHECK_EQ(strcmp("Capybara", process_debug_messages_data.results[1].buffer),
   2636            0);
   2637   CHECK_EQ(strcmp("805", process_debug_messages_data.results[2].buffer), 0);
   2638 
   2639   v8::Debug::SetMessageHandler(NULL);
   2640   v8::Debug::SetDebugEventListener(NULL);
   2641   CheckDebuggerUnloaded();
   2642 }
   2643 
   2644 
   2645 // Simple test of the stepping mechanism using only store ICs.
   2646 TEST(DebugStepLinear) {
   2647   v8::HandleScope scope;
   2648   DebugLocalContext env;
   2649 
   2650   // Create a function for testing stepping.
   2651   v8::Local<v8::Function> foo = CompileFunction(&env,
   2652                                                 "function foo(){a=1;b=1;c=1;}",
   2653                                                 "foo");
   2654 
   2655   // Run foo to allow it to get optimized.
   2656   CompileRun("a=0; b=0; c=0; foo();");
   2657 
   2658   SetBreakPoint(foo, 3);
   2659 
   2660   // Register a debug event listener which steps and counts.
   2661   v8::Debug::SetDebugEventListener(DebugEventStep);
   2662 
   2663   step_action = StepIn;
   2664   break_point_hit_count = 0;
   2665   foo->Call(env->Global(), 0, NULL);
   2666 
   2667   // With stepping all break locations are hit.
   2668   CHECK_EQ(4, break_point_hit_count);
   2669 
   2670   v8::Debug::SetDebugEventListener(NULL);
   2671   CheckDebuggerUnloaded();
   2672 
   2673   // Register a debug event listener which just counts.
   2674   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
   2675 
   2676   SetBreakPoint(foo, 3);
   2677   break_point_hit_count = 0;
   2678   foo->Call(env->Global(), 0, NULL);
   2679 
   2680   // Without stepping only active break points are hit.
   2681   CHECK_EQ(1, break_point_hit_count);
   2682 
   2683   v8::Debug::SetDebugEventListener(NULL);
   2684   CheckDebuggerUnloaded();
   2685 }
   2686 
   2687 
   2688 // Test of the stepping mechanism for keyed load in a loop.
   2689 TEST(DebugStepKeyedLoadLoop) {
   2690   v8::HandleScope scope;
   2691   DebugLocalContext env;
   2692 
   2693   // Register a debug event listener which steps and counts.
   2694   v8::Debug::SetDebugEventListener(DebugEventStep);
   2695 
   2696   // Create a function for testing stepping of keyed load. The statement 'y=1'
   2697   // is there to have more than one breakable statement in the loop, TODO(315).
   2698   v8::Local<v8::Function> foo = CompileFunction(
   2699       &env,
   2700       "function foo(a) {\n"
   2701       "  var x;\n"
   2702       "  var len = a.length;\n"
   2703       "  for (var i = 0; i < len; i++) {\n"
   2704       "    y = 1;\n"
   2705       "    x = a[i];\n"
   2706       "  }\n"
   2707       "}\n"
   2708       "y=0\n",
   2709       "foo");
   2710 
   2711   // Create array [0,1,2,3,4,5,6,7,8,9]
   2712   v8::Local<v8::Array> a = v8::Array::New(10);
   2713   for (int i = 0; i < 10; i++) {
   2714     a->Set(v8::Number::New(i), v8::Number::New(i));
   2715   }
   2716 
   2717   // Call function without any break points to ensure inlining is in place.
   2718   const int kArgc = 1;
   2719   v8::Handle<v8::Value> args[kArgc] = { a };
   2720   foo->Call(env->Global(), kArgc, args);
   2721 
   2722   // Setup break point and step through the function.
   2723   SetBreakPoint(foo, 3);
   2724   step_action = StepNext;
   2725   break_point_hit_count = 0;
   2726   foo->Call(env->Global(), kArgc, args);
   2727 
   2728   // With stepping all break locations are hit.
   2729   CHECK_EQ(33, break_point_hit_count);
   2730 
   2731   v8::Debug::SetDebugEventListener(NULL);
   2732   CheckDebuggerUnloaded();
   2733 }
   2734 
   2735 
   2736 // Test of the stepping mechanism for keyed store in a loop.
   2737 TEST(DebugStepKeyedStoreLoop) {
   2738   v8::HandleScope scope;
   2739   DebugLocalContext env;
   2740 
   2741   // Register a debug event listener which steps and counts.
   2742   v8::Debug::SetDebugEventListener(DebugEventStep);
   2743 
   2744   // Create a function for testing stepping of keyed store. The statement 'y=1'
   2745   // is there to have more than one breakable statement in the loop, TODO(315).
   2746   v8::Local<v8::Function> foo = CompileFunction(
   2747       &env,
   2748       "function foo(a) {\n"
   2749       "  var len = a.length;\n"
   2750       "  for (var i = 0; i < len; i++) {\n"
   2751       "    y = 1;\n"
   2752       "    a[i] = 42;\n"
   2753       "  }\n"
   2754       "}\n"
   2755       "y=0\n",
   2756       "foo");
   2757 
   2758   // Create array [0,1,2,3,4,5,6,7,8,9]
   2759   v8::Local<v8::Array> a = v8::Array::New(10);
   2760   for (int i = 0; i < 10; i++) {
   2761     a->Set(v8::Number::New(i), v8::Number::New(i));
   2762   }
   2763 
   2764   // Call function without any break points to ensure inlining is in place.
   2765   const int kArgc = 1;
   2766   v8::Handle<v8::Value> args[kArgc] = { a };
   2767   foo->Call(env->Global(), kArgc, args);
   2768 
   2769   // Setup break point and step through the function.
   2770   SetBreakPoint(foo, 3);
   2771   step_action = StepNext;
   2772   break_point_hit_count = 0;
   2773   foo->Call(env->Global(), kArgc, args);
   2774 
   2775   // With stepping all break locations are hit.
   2776   CHECK_EQ(32, break_point_hit_count);
   2777 
   2778   v8::Debug::SetDebugEventListener(NULL);
   2779   CheckDebuggerUnloaded();
   2780 }
   2781 
   2782 
   2783 // Test of the stepping mechanism for named load in a loop.
   2784 TEST(DebugStepNamedLoadLoop) {
   2785   v8::HandleScope scope;
   2786   DebugLocalContext env;
   2787 
   2788   // Register a debug event listener which steps and counts.
   2789   v8::Debug::SetDebugEventListener(DebugEventStep);
   2790 
   2791   // Create a function for testing stepping of named load.
   2792   v8::Local<v8::Function> foo = CompileFunction(
   2793       &env,
   2794       "function foo() {\n"
   2795           "  var a = [];\n"
   2796           "  var s = \"\";\n"
   2797           "  for (var i = 0; i < 10; i++) {\n"
   2798           "    var v = new V(i, i + 1);\n"
   2799           "    v.y;\n"
   2800           "    a.length;\n"  // Special case: array length.
   2801           "    s.length;\n"  // Special case: string length.
   2802           "  }\n"
   2803           "}\n"
   2804           "function V(x, y) {\n"
   2805           "  this.x = x;\n"
   2806           "  this.y = y;\n"
   2807           "}\n",
   2808           "foo");
   2809 
   2810   // Call function without any break points to ensure inlining is in place.
   2811   foo->Call(env->Global(), 0, NULL);
   2812 
   2813   // Setup break point and step through the function.
   2814   SetBreakPoint(foo, 4);
   2815   step_action = StepNext;
   2816   break_point_hit_count = 0;
   2817   foo->Call(env->Global(), 0, NULL);
   2818 
   2819   // With stepping all break locations are hit.
   2820   CHECK_EQ(53, break_point_hit_count);
   2821 
   2822   v8::Debug::SetDebugEventListener(NULL);
   2823   CheckDebuggerUnloaded();
   2824 }
   2825 
   2826 
   2827 static void DoDebugStepNamedStoreLoop(int expected) {
   2828   v8::HandleScope scope;
   2829   DebugLocalContext env;
   2830 
   2831   // Register a debug event listener which steps and counts.
   2832   v8::Debug::SetDebugEventListener(DebugEventStep);
   2833 
   2834   // Create a function for testing stepping of named store.
   2835   v8::Local<v8::Function> foo = CompileFunction(
   2836       &env,
   2837       "function foo() {\n"
   2838           "  var a = {a:1};\n"
   2839           "  for (var i = 0; i < 10; i++) {\n"
   2840           "    a.a = 2\n"
   2841           "  }\n"
   2842           "}\n",
   2843           "foo");
   2844 
   2845   // Call function without any break points to ensure inlining is in place.
   2846   foo->Call(env->Global(), 0, NULL);
   2847 
   2848   // Setup break point and step through the function.
   2849   SetBreakPoint(foo, 3);
   2850   step_action = StepNext;
   2851   break_point_hit_count = 0;
   2852   foo->Call(env->Global(), 0, NULL);
   2853 
   2854   // With stepping all expected break locations are hit.
   2855   CHECK_EQ(expected, break_point_hit_count);
   2856 
   2857   v8::Debug::SetDebugEventListener(NULL);
   2858   CheckDebuggerUnloaded();
   2859 }
   2860 
   2861 
   2862 // Test of the stepping mechanism for named load in a loop.
   2863 TEST(DebugStepNamedStoreLoop) {
   2864   DoDebugStepNamedStoreLoop(22);
   2865 }
   2866 
   2867 
   2868 // Test the stepping mechanism with different ICs.
   2869 TEST(DebugStepLinearMixedICs) {
   2870   v8::HandleScope scope;
   2871   DebugLocalContext env;
   2872 
   2873   // Register a debug event listener which steps and counts.
   2874   v8::Debug::SetDebugEventListener(DebugEventStep);
   2875 
   2876   // Create a function for testing stepping.
   2877   v8::Local<v8::Function> foo = CompileFunction(&env,
   2878       "function bar() {};"
   2879       "function foo() {"
   2880       "  var x;"
   2881       "  var index='name';"
   2882       "  var y = {};"
   2883       "  a=1;b=2;x=a;y[index]=3;x=y[index];bar();}", "foo");
   2884 
   2885   // Run functions to allow them to get optimized.
   2886   CompileRun("a=0; b=0; bar(); foo();");
   2887 
   2888   SetBreakPoint(foo, 0);
   2889 
   2890   step_action = StepIn;
   2891   break_point_hit_count = 0;
   2892   foo->Call(env->Global(), 0, NULL);
   2893 
   2894   // With stepping all break locations are hit.
   2895   CHECK_EQ(11, break_point_hit_count);
   2896 
   2897   v8::Debug::SetDebugEventListener(NULL);
   2898   CheckDebuggerUnloaded();
   2899 
   2900   // Register a debug event listener which just counts.
   2901   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
   2902 
   2903   SetBreakPoint(foo, 0);
   2904   break_point_hit_count = 0;
   2905   foo->Call(env->Global(), 0, NULL);
   2906 
   2907   // Without stepping only active break points are hit.
   2908   CHECK_EQ(1, break_point_hit_count);
   2909 
   2910   v8::Debug::SetDebugEventListener(NULL);
   2911   CheckDebuggerUnloaded();
   2912 }
   2913 
   2914 
   2915 TEST(DebugStepDeclarations) {
   2916   v8::HandleScope scope;
   2917   DebugLocalContext env;
   2918 
   2919   // Register a debug event listener which steps and counts.
   2920   v8::Debug::SetDebugEventListener(DebugEventStep);
   2921 
   2922   // Create a function for testing stepping. Run it to allow it to get
   2923   // optimized.
   2924   const char* src = "function foo() { "
   2925                     "  var a;"
   2926                     "  var b = 1;"
   2927                     "  var c = foo;"
   2928                     "  var d = Math.floor;"
   2929                     "  var e = b + d(1.2);"
   2930                     "}"
   2931                     "foo()";
   2932   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
   2933 
   2934   SetBreakPoint(foo, 0);
   2935 
   2936   // Stepping through the declarations.
   2937   step_action = StepIn;
   2938   break_point_hit_count = 0;
   2939   foo->Call(env->Global(), 0, NULL);
   2940   CHECK_EQ(6, break_point_hit_count);
   2941 
   2942   // Get rid of the debug event listener.
   2943   v8::Debug::SetDebugEventListener(NULL);
   2944   CheckDebuggerUnloaded();
   2945 }
   2946 
   2947 
   2948 TEST(DebugStepLocals) {
   2949   v8::HandleScope scope;
   2950   DebugLocalContext env;
   2951 
   2952   // Register a debug event listener which steps and counts.
   2953   v8::Debug::SetDebugEventListener(DebugEventStep);
   2954 
   2955   // Create a function for testing stepping. Run it to allow it to get
   2956   // optimized.
   2957   const char* src = "function foo() { "
   2958                     "  var a,b;"
   2959                     "  a = 1;"
   2960                     "  b = a + 2;"
   2961                     "  b = 1 + 2 + 3;"
   2962                     "  a = Math.floor(b);"
   2963                     "}"
   2964                     "foo()";
   2965   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
   2966 
   2967   SetBreakPoint(foo, 0);
   2968 
   2969   // Stepping through the declarations.
   2970   step_action = StepIn;
   2971   break_point_hit_count = 0;
   2972   foo->Call(env->Global(), 0, NULL);
   2973   CHECK_EQ(6, break_point_hit_count);
   2974 
   2975   // Get rid of the debug event listener.
   2976   v8::Debug::SetDebugEventListener(NULL);
   2977   CheckDebuggerUnloaded();
   2978 }
   2979 
   2980 
   2981 TEST(DebugStepIf) {
   2982   v8::HandleScope scope;
   2983   DebugLocalContext env;
   2984 
   2985   // Register a debug event listener which steps and counts.
   2986   v8::Debug::SetDebugEventListener(DebugEventStep);
   2987 
   2988   // Create a function for testing stepping. Run it to allow it to get
   2989   // optimized.
   2990   const int argc = 1;
   2991   const char* src = "function foo(x) { "
   2992                     "  a = 1;"
   2993                     "  if (x) {"
   2994                     "    b = 1;"
   2995                     "  } else {"
   2996                     "    c = 1;"
   2997                     "    d = 1;"
   2998                     "  }"
   2999                     "}"
   3000                     "a=0; b=0; c=0; d=0; foo()";
   3001   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
   3002   SetBreakPoint(foo, 0);
   3003 
   3004   // Stepping through the true part.
   3005   step_action = StepIn;
   3006   break_point_hit_count = 0;
   3007   v8::Handle<v8::Value> argv_true[argc] = { v8::True() };
   3008   foo->Call(env->Global(), argc, argv_true);
   3009   CHECK_EQ(4, break_point_hit_count);
   3010 
   3011   // Stepping through the false part.
   3012   step_action = StepIn;
   3013   break_point_hit_count = 0;
   3014   v8::Handle<v8::Value> argv_false[argc] = { v8::False() };
   3015   foo->Call(env->Global(), argc, argv_false);
   3016   CHECK_EQ(5, break_point_hit_count);
   3017 
   3018   // Get rid of the debug event listener.
   3019   v8::Debug::SetDebugEventListener(NULL);
   3020   CheckDebuggerUnloaded();
   3021 }
   3022 
   3023 
   3024 TEST(DebugStepSwitch) {
   3025   v8::HandleScope scope;
   3026   DebugLocalContext env;
   3027 
   3028   // Register a debug event listener which steps and counts.
   3029   v8::Debug::SetDebugEventListener(DebugEventStep);
   3030 
   3031   // Create a function for testing stepping. Run it to allow it to get
   3032   // optimized.
   3033   const int argc = 1;
   3034   const char* src = "function foo(x) { "
   3035                     "  a = 1;"
   3036                     "  switch (x) {"
   3037                     "    case 1:"
   3038                     "      b = 1;"
   3039                     "    case 2:"
   3040                     "      c = 1;"
   3041                     "      break;"
   3042                     "    case 3:"
   3043                     "      d = 1;"
   3044                     "      e = 1;"
   3045                     "      f = 1;"
   3046                     "      break;"
   3047                     "  }"
   3048                     "}"
   3049                     "a=0; b=0; c=0; d=0; e=0; f=0; foo()";
   3050   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
   3051   SetBreakPoint(foo, 0);
   3052 
   3053   // One case with fall-through.
   3054   step_action = StepIn;
   3055   break_point_hit_count = 0;
   3056   v8::Handle<v8::Value> argv_1[argc] = { v8::Number::New(1) };
   3057   foo->Call(env->Global(), argc, argv_1);
   3058   CHECK_EQ(6, break_point_hit_count);
   3059 
   3060   // Another case.
   3061   step_action = StepIn;
   3062   break_point_hit_count = 0;
   3063   v8::Handle<v8::Value> argv_2[argc] = { v8::Number::New(2) };
   3064   foo->Call(env->Global(), argc, argv_2);
   3065   CHECK_EQ(5, break_point_hit_count);
   3066 
   3067   // Last case.
   3068   step_action = StepIn;
   3069   break_point_hit_count = 0;
   3070   v8::Handle<v8::Value> argv_3[argc] = { v8::Number::New(3) };
   3071   foo->Call(env->Global(), argc, argv_3);
   3072   CHECK_EQ(7, break_point_hit_count);
   3073 
   3074   // Get rid of the debug event listener.
   3075   v8::Debug::SetDebugEventListener(NULL);
   3076   CheckDebuggerUnloaded();
   3077 }
   3078 
   3079 
   3080 TEST(DebugStepWhile) {
   3081   v8::HandleScope scope;
   3082   DebugLocalContext env;
   3083 
   3084   // Register a debug event listener which steps and counts.
   3085   v8::Debug::SetDebugEventListener(DebugEventStep);
   3086 
   3087   // Create a function for testing stepping. Run it to allow it to get
   3088   // optimized.
   3089   const int argc = 1;
   3090   const char* src = "function foo(x) { "
   3091                     "  var a = 0;"
   3092                     "  while (a < x) {"
   3093                     "    a++;"
   3094                     "  }"
   3095                     "}"
   3096                     "foo()";
   3097   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
   3098   SetBreakPoint(foo, 8);  // "var a = 0;"
   3099 
   3100   // Looping 10 times.
   3101   step_action = StepIn;
   3102   break_point_hit_count = 0;
   3103   v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) };
   3104   foo->Call(env->Global(), argc, argv_10);
   3105   CHECK_EQ(22, break_point_hit_count);
   3106 
   3107   // Looping 100 times.
   3108   step_action = StepIn;
   3109   break_point_hit_count = 0;
   3110   v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) };
   3111   foo->Call(env->Global(), argc, argv_100);
   3112   CHECK_EQ(202, break_point_hit_count);
   3113 
   3114   // Get rid of the debug event listener.
   3115   v8::Debug::SetDebugEventListener(NULL);
   3116   CheckDebuggerUnloaded();
   3117 }
   3118 
   3119 
   3120 TEST(DebugStepDoWhile) {
   3121   v8::HandleScope scope;
   3122   DebugLocalContext env;
   3123 
   3124   // Register a debug event listener which steps and counts.
   3125   v8::Debug::SetDebugEventListener(DebugEventStep);
   3126 
   3127   // Create a function for testing stepping. Run it to allow it to get
   3128   // optimized.
   3129   const int argc = 1;
   3130   const char* src = "function foo(x) { "
   3131                     "  var a = 0;"
   3132                     "  do {"
   3133                     "    a++;"
   3134                     "  } while (a < x)"
   3135                     "}"
   3136                     "foo()";
   3137   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
   3138   SetBreakPoint(foo, 8);  // "var a = 0;"
   3139 
   3140   // Looping 10 times.
   3141   step_action = StepIn;
   3142   break_point_hit_count = 0;
   3143   v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) };
   3144   foo->Call(env->Global(), argc, argv_10);
   3145   CHECK_EQ(22, break_point_hit_count);
   3146 
   3147   // Looping 100 times.
   3148   step_action = StepIn;
   3149   break_point_hit_count = 0;
   3150   v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) };
   3151   foo->Call(env->Global(), argc, argv_100);
   3152   CHECK_EQ(202, break_point_hit_count);
   3153 
   3154   // Get rid of the debug event listener.
   3155   v8::Debug::SetDebugEventListener(NULL);
   3156   CheckDebuggerUnloaded();
   3157 }
   3158 
   3159 
   3160 TEST(DebugStepFor) {
   3161   v8::HandleScope scope;
   3162   DebugLocalContext env;
   3163 
   3164   // Register a debug event listener which steps and counts.
   3165   v8::Debug::SetDebugEventListener(DebugEventStep);
   3166 
   3167   // Create a function for testing stepping. Run it to allow it to get
   3168   // optimized.
   3169   const int argc = 1;
   3170   const char* src = "function foo(x) { "
   3171                     "  a = 1;"
   3172                     "  for (i = 0; i < x; i++) {"
   3173                     "    b = 1;"
   3174                     "  }"
   3175                     "}"
   3176                     "a=0; b=0; i=0; foo()";
   3177   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
   3178 
   3179   SetBreakPoint(foo, 8);  // "a = 1;"
   3180 
   3181   // Looping 10 times.
   3182   step_action = StepIn;
   3183   break_point_hit_count = 0;
   3184   v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) };
   3185   foo->Call(env->Global(), argc, argv_10);
   3186   CHECK_EQ(23, break_point_hit_count);
   3187 
   3188   // Looping 100 times.
   3189   step_action = StepIn;
   3190   break_point_hit_count = 0;
   3191   v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) };
   3192   foo->Call(env->Global(), argc, argv_100);
   3193   CHECK_EQ(203, break_point_hit_count);
   3194 
   3195   // Get rid of the debug event listener.
   3196   v8::Debug::SetDebugEventListener(NULL);
   3197   CheckDebuggerUnloaded();
   3198 }
   3199 
   3200 
   3201 TEST(DebugStepForContinue) {
   3202   v8::HandleScope scope;
   3203   DebugLocalContext env;
   3204 
   3205   // Register a debug event listener which steps and counts.
   3206   v8::Debug::SetDebugEventListener(DebugEventStep);
   3207 
   3208   // Create a function for testing stepping. Run it to allow it to get
   3209   // optimized.
   3210   const int argc = 1;
   3211   const char* src = "function foo(x) { "
   3212                     "  var a = 0;"
   3213                     "  var b = 0;"
   3214                     "  var c = 0;"
   3215                     "  for (var i = 0; i < x; i++) {"
   3216                     "    a++;"
   3217                     "    if (a % 2 == 0) continue;"
   3218                     "    b++;"
   3219                     "    c++;"
   3220                     "  }"
   3221                     "  return b;"
   3222                     "}"
   3223                     "foo()";
   3224   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
   3225   v8::Handle<v8::Value> result;
   3226   SetBreakPoint(foo, 8);  // "var a = 0;"
   3227 
   3228   // Each loop generates 4 or 5 steps depending on whether a is equal.
   3229 
   3230   // Looping 10 times.
   3231   step_action = StepIn;
   3232   break_point_hit_count = 0;
   3233   v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) };
   3234   result = foo->Call(env->Global(), argc, argv_10);
   3235   CHECK_EQ(5, result->Int32Value());
   3236   CHECK_EQ(50, break_point_hit_count);
   3237 
   3238   // Looping 100 times.
   3239   step_action = StepIn;
   3240   break_point_hit_count = 0;
   3241   v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) };
   3242   result = foo->Call(env->Global(), argc, argv_100);
   3243   CHECK_EQ(50, result->Int32Value());
   3244   CHECK_EQ(455, break_point_hit_count);
   3245 
   3246   // Get rid of the debug event listener.
   3247   v8::Debug::SetDebugEventListener(NULL);
   3248   CheckDebuggerUnloaded();
   3249 }
   3250 
   3251 
   3252 TEST(DebugStepForBreak) {
   3253   v8::HandleScope scope;
   3254   DebugLocalContext env;
   3255 
   3256   // Register a debug event listener which steps and counts.
   3257   v8::Debug::SetDebugEventListener(DebugEventStep);
   3258 
   3259   // Create a function for testing stepping. Run it to allow it to get
   3260   // optimized.
   3261   const int argc = 1;
   3262   const char* src = "function foo(x) { "
   3263                     "  var a = 0;"
   3264                     "  var b = 0;"
   3265                     "  var c = 0;"
   3266                     "  for (var i = 0; i < 1000; i++) {"
   3267                     "    a++;"
   3268                     "    if (a == x) break;"
   3269                     "    b++;"
   3270                     "    c++;"
   3271                     "  }"
   3272                     "  return b;"
   3273                     "}"
   3274                     "foo()";
   3275   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
   3276   v8::Handle<v8::Value> result;
   3277   SetBreakPoint(foo, 8);  // "var a = 0;"
   3278 
   3279   // Each loop generates 5 steps except for the last (when break is executed)
   3280   // which only generates 4.
   3281 
   3282   // Looping 10 times.
   3283   step_action = StepIn;
   3284   break_point_hit_count = 0;
   3285   v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) };
   3286   result = foo->Call(env->Global(), argc, argv_10);
   3287   CHECK_EQ(9, result->Int32Value());
   3288   CHECK_EQ(53, break_point_hit_count);
   3289 
   3290   // Looping 100 times.
   3291   step_action = StepIn;
   3292   break_point_hit_count = 0;
   3293   v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) };
   3294   result = foo->Call(env->Global(), argc, argv_100);
   3295   CHECK_EQ(99, result->Int32Value());
   3296   CHECK_EQ(503, break_point_hit_count);
   3297 
   3298   // Get rid of the debug event listener.
   3299   v8::Debug::SetDebugEventListener(NULL);
   3300   CheckDebuggerUnloaded();
   3301 }
   3302 
   3303 
   3304 TEST(DebugStepForIn) {
   3305   v8::HandleScope scope;
   3306   DebugLocalContext env;
   3307 
   3308   // Register a debug event listener which steps and counts.
   3309   v8::Debug::SetDebugEventListener(DebugEventStep);
   3310 
   3311   // Create a function for testing stepping. Run it to allow it to get
   3312   // optimized.
   3313   v8::Local<v8::Function> foo;
   3314   const char* src_1 = "function foo() { "
   3315                       "  var a = [1, 2];"
   3316                       "  for (x in a) {"
   3317                       "    b = 0;"
   3318                       "  }"
   3319                       "}"
   3320                       "foo()";
   3321   foo = CompileFunction(&env, src_1, "foo");
   3322   SetBreakPoint(foo, 0);  // "var a = ..."
   3323 
   3324   step_action = StepIn;
   3325   break_point_hit_count = 0;
   3326   foo->Call(env->Global(), 0, NULL);
   3327   CHECK_EQ(6, break_point_hit_count);
   3328 
   3329   // Create a function for testing stepping. Run it to allow it to get
   3330   // optimized.
   3331   const char* src_2 = "function foo() { "
   3332                       "  var a = {a:[1, 2, 3]};"
   3333                       "  for (x in a.a) {"
   3334                       "    b = 0;"
   3335                       "  }"
   3336                       "}"
   3337                       "foo()";
   3338   foo = CompileFunction(&env, src_2, "foo");
   3339   SetBreakPoint(foo, 0);  // "var a = ..."
   3340 
   3341   step_action = StepIn;
   3342   break_point_hit_count = 0;
   3343   foo->Call(env->Global(), 0, NULL);
   3344   CHECK_EQ(8, break_point_hit_count);
   3345 
   3346   // Get rid of the debug event listener.
   3347   v8::Debug::SetDebugEventListener(NULL);
   3348   CheckDebuggerUnloaded();
   3349 }
   3350 
   3351 
   3352 TEST(DebugStepWith) {
   3353   v8::HandleScope scope;
   3354   DebugLocalContext env;
   3355 
   3356   // Register a debug event listener which steps and counts.
   3357   v8::Debug::SetDebugEventListener(DebugEventStep);
   3358 
   3359   // Create a function for testing stepping. Run it to allow it to get
   3360   // optimized.
   3361   const char* src = "function foo(x) { "
   3362                     "  var a = {};"
   3363                     "  with (a) {}"
   3364                     "  with (b) {}"
   3365                     "}"
   3366                     "foo()";
   3367   env->Global()->Set(v8::String::New("b"), v8::Object::New());
   3368   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
   3369   v8::Handle<v8::Value> result;
   3370   SetBreakPoint(foo, 8);  // "var a = {};"
   3371 
   3372   step_action = StepIn;
   3373   break_point_hit_count = 0;
   3374   foo->Call(env->Global(), 0, NULL);
   3375   CHECK_EQ(4, break_point_hit_count);
   3376 
   3377   // Get rid of the debug event listener.
   3378   v8::Debug::SetDebugEventListener(NULL);
   3379   CheckDebuggerUnloaded();
   3380 }
   3381 
   3382 
   3383 TEST(DebugConditional) {
   3384   v8::HandleScope scope;
   3385   DebugLocalContext env;
   3386 
   3387   // Register a debug event listener which steps and counts.
   3388   v8::Debug::SetDebugEventListener(DebugEventStep);
   3389 
   3390   // Create a function for testing stepping. Run it to allow it to get
   3391   // optimized.
   3392   const char* src = "function foo(x) { "
   3393                     "  var a;"
   3394                     "  a = x ? 1 : 2;"
   3395                     "  return a;"
   3396                     "}"
   3397                     "foo()";
   3398   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
   3399   SetBreakPoint(foo, 0);  // "var a;"
   3400 
   3401   step_action = StepIn;
   3402   break_point_hit_count = 0;
   3403   foo->Call(env->Global(), 0, NULL);
   3404   CHECK_EQ(5, break_point_hit_count);
   3405 
   3406   step_action = StepIn;
   3407   break_point_hit_count = 0;
   3408   const int argc = 1;
   3409   v8::Handle<v8::Value> argv_true[argc] = { v8::True() };
   3410   foo->Call(env->Global(), argc, argv_true);
   3411   CHECK_EQ(5, break_point_hit_count);
   3412 
   3413   // Get rid of the debug event listener.
   3414   v8::Debug::SetDebugEventListener(NULL);
   3415   CheckDebuggerUnloaded();
   3416 }
   3417 
   3418 
   3419 TEST(StepInOutSimple) {
   3420   v8::HandleScope scope;
   3421   DebugLocalContext env;
   3422 
   3423   // Create a function for checking the function when hitting a break point.
   3424   frame_function_name = CompileFunction(&env,
   3425                                         frame_function_name_source,
   3426                                         "frame_function_name");
   3427 
   3428   // Register a debug event listener which steps and counts.
   3429   v8::Debug::SetDebugEventListener(DebugEventStepSequence);
   3430 
   3431   // Create a function for testing stepping. Run it to allow it to get
   3432   // optimized.
   3433   const char* src = "function a() {b();c();}; "
   3434                     "function b() {c();}; "
   3435                     "function c() {}; "
   3436                     "a(); b(); c()";
   3437   v8::Local<v8::Function> a = CompileFunction(&env, src, "a");
   3438   SetBreakPoint(a, 0);
   3439 
   3440   // Step through invocation of a with step in.
   3441   step_action = StepIn;
   3442   break_point_hit_count = 0;
   3443   expected_step_sequence = "abcbaca";
   3444   a->Call(env->Global(), 0, NULL);
   3445   CHECK_EQ(StrLength(expected_step_sequence),
   3446            break_point_hit_count);
   3447 
   3448   // Step through invocation of a with step next.
   3449   step_action = StepNext;
   3450   break_point_hit_count = 0;
   3451   expected_step_sequence = "aaa";
   3452   a->Call(env->Global(), 0, NULL);
   3453   CHECK_EQ(StrLength(expected_step_sequence),
   3454            break_point_hit_count);
   3455 
   3456   // Step through invocation of a with step out.
   3457   step_action = StepOut;
   3458   break_point_hit_count = 0;
   3459   expected_step_sequence = "a";
   3460   a->Call(env->Global(), 0, NULL);
   3461   CHECK_EQ(StrLength(expected_step_sequence),
   3462            break_point_hit_count);
   3463 
   3464   // Get rid of the debug event listener.
   3465   v8::Debug::SetDebugEventListener(NULL);
   3466   CheckDebuggerUnloaded();
   3467 }
   3468 
   3469 
   3470 TEST(StepInOutTree) {
   3471   v8::HandleScope scope;
   3472   DebugLocalContext env;
   3473 
   3474   // Create a function for checking the function when hitting a break point.
   3475   frame_function_name = CompileFunction(&env,
   3476                                         frame_function_name_source,
   3477                                         "frame_function_name");
   3478 
   3479   // Register a debug event listener which steps and counts.
   3480   v8::Debug::SetDebugEventListener(DebugEventStepSequence);
   3481 
   3482   // Create a function for testing stepping. Run it to allow it to get
   3483   // optimized.
   3484   const char* src = "function a() {b(c(d()),d());c(d());d()}; "
   3485                     "function b(x,y) {c();}; "
   3486                     "function c(x) {}; "
   3487                     "function d() {}; "
   3488                     "a(); b(); c(); d()";
   3489   v8::Local<v8::Function> a = CompileFunction(&env, src, "a");
   3490   SetBreakPoint(a, 0);
   3491 
   3492   // Step through invocation of a with step in.
   3493   step_action = StepIn;
   3494   break_point_hit_count = 0;
   3495   expected_step_sequence = "adacadabcbadacada";
   3496   a->Call(env->Global(), 0, NULL);
   3497   CHECK_EQ(StrLength(expected_step_sequence),
   3498            break_point_hit_count);
   3499 
   3500   // Step through invocation of a with step next.
   3501   step_action = StepNext;
   3502   break_point_hit_count = 0;
   3503   expected_step_sequence = "aaaa";
   3504   a->Call(env->Global(), 0, NULL);
   3505   CHECK_EQ(StrLength(expected_step_sequence),
   3506            break_point_hit_count);
   3507 
   3508   // Step through invocation of a with step out.
   3509   step_action = StepOut;
   3510   break_point_hit_count = 0;
   3511   expected_step_sequence = "a";
   3512   a->Call(env->Global(), 0, NULL);
   3513   CHECK_EQ(StrLength(expected_step_sequence),
   3514            break_point_hit_count);
   3515 
   3516   // Get rid of the debug event listener.
   3517   v8::Debug::SetDebugEventListener(NULL);
   3518   CheckDebuggerUnloaded(true);
   3519 }
   3520 
   3521 
   3522 TEST(StepInOutBranch) {
   3523   v8::HandleScope scope;
   3524   DebugLocalContext env;
   3525 
   3526   // Create a function for checking the function when hitting a break point.
   3527   frame_function_name = CompileFunction(&env,
   3528                                         frame_function_name_source,
   3529                                         "frame_function_name");
   3530 
   3531   // Register a debug event listener which steps and counts.
   3532   v8::Debug::SetDebugEventListener(DebugEventStepSequence);
   3533 
   3534   // Create a function for testing stepping. Run it to allow it to get
   3535   // optimized.
   3536   const char* src = "function a() {b(false);c();}; "
   3537                     "function b(x) {if(x){c();};}; "
   3538                     "function c() {}; "
   3539                     "a(); b(); c()";
   3540   v8::Local<v8::Function> a = CompileFunction(&env, src, "a");
   3541   SetBreakPoint(a, 0);
   3542 
   3543   // Step through invocation of a.
   3544   step_action = StepIn;
   3545   break_point_hit_count = 0;
   3546   expected_step_sequence = "abbaca";
   3547   a->Call(env->Global(), 0, NULL);
   3548   CHECK_EQ(StrLength(expected_step_sequence),
   3549            break_point_hit_count);
   3550 
   3551   // Get rid of the debug event listener.
   3552   v8::Debug::SetDebugEventListener(NULL);
   3553   CheckDebuggerUnloaded();
   3554 }
   3555 
   3556 
   3557 // Test that step in does not step into native functions.
   3558 TEST(DebugStepNatives) {
   3559   v8::HandleScope scope;
   3560   DebugLocalContext env;
   3561 
   3562   // Create a function for testing stepping.
   3563   v8::Local<v8::Function> foo = CompileFunction(
   3564       &env,
   3565       "function foo(){debugger;Math.sin(1);}",
   3566       "foo");
   3567 
   3568   // Register a debug event listener which steps and counts.
   3569   v8::Debug::SetDebugEventListener(DebugEventStep);
   3570 
   3571   step_action = StepIn;
   3572   break_point_hit_count = 0;
   3573   foo->Call(env->Global(), 0, NULL);
   3574 
   3575   // With stepping all break locations are hit.
   3576   CHECK_EQ(3, break_point_hit_count);
   3577 
   3578   v8::Debug::SetDebugEventListener(NULL);
   3579   CheckDebuggerUnloaded();
   3580 
   3581   // Register a debug event listener which just counts.
   3582   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
   3583 
   3584   break_point_hit_count = 0;
   3585   foo->Call(env->Global(), 0, NULL);
   3586 
   3587   // Without stepping only active break points are hit.
   3588   CHECK_EQ(1, break_point_hit_count);
   3589 
   3590   v8::Debug::SetDebugEventListener(NULL);
   3591   CheckDebuggerUnloaded();
   3592 }
   3593 
   3594 
   3595 // Test that step in works with function.apply.
   3596 TEST(DebugStepFunctionApply) {
   3597   v8::HandleScope scope;
   3598   DebugLocalContext env;
   3599 
   3600   // Create a function for testing stepping.
   3601   v8::Local<v8::Function> foo = CompileFunction(
   3602       &env,
   3603       "function bar(x, y, z) { if (x == 1) { a = y; b = z; } }"
   3604       "function foo(){ debugger; bar.apply(this, [1,2,3]); }",
   3605       "foo");
   3606 
   3607   // Register a debug event listener which steps and counts.
   3608   v8::Debug::SetDebugEventListener(DebugEventStep);
   3609 
   3610   step_action = StepIn;
   3611   break_point_hit_count = 0;
   3612   foo->Call(env->Global(), 0, NULL);
   3613 
   3614   // With stepping all break locations are hit.
   3615   CHECK_EQ(7, break_point_hit_count);
   3616 
   3617   v8::Debug::SetDebugEventListener(NULL);
   3618   CheckDebuggerUnloaded();
   3619 
   3620   // Register a debug event listener which just counts.
   3621   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
   3622 
   3623   break_point_hit_count = 0;
   3624   foo->Call(env->Global(), 0, NULL);
   3625 
   3626   // Without stepping only the debugger statement is hit.
   3627   CHECK_EQ(1, break_point_hit_count);
   3628 
   3629   v8::Debug::SetDebugEventListener(NULL);
   3630   CheckDebuggerUnloaded();
   3631 }
   3632 
   3633 
   3634 // Test that step in works with function.call.
   3635 TEST(DebugStepFunctionCall) {
   3636   v8::HandleScope scope;
   3637   DebugLocalContext env;
   3638 
   3639   // Create a function for testing stepping.
   3640   v8::Local<v8::Function> foo = CompileFunction(
   3641       &env,
   3642       "function bar(x, y, z) { if (x == 1) { a = y; b = z; } }"
   3643       "function foo(a){ debugger;"
   3644       "                 if (a) {"
   3645       "                   bar.call(this, 1, 2, 3);"
   3646       "                 } else {"
   3647       "                   bar.call(this, 0);"
   3648       "                 }"
   3649       "}",
   3650       "foo");
   3651 
   3652   // Register a debug event listener which steps and counts.
   3653   v8::Debug::SetDebugEventListener(DebugEventStep);
   3654   step_action = StepIn;
   3655 
   3656   // Check stepping where the if condition in bar is false.
   3657   break_point_hit_count = 0;
   3658   foo->Call(env->Global(), 0, NULL);
   3659   CHECK_EQ(6, break_point_hit_count);
   3660 
   3661   // Check stepping where the if condition in bar is true.
   3662   break_point_hit_count = 0;
   3663   const int argc = 1;
   3664   v8::Handle<v8::Value> argv[argc] = { v8::True() };
   3665   foo->Call(env->Global(), argc, argv);
   3666   CHECK_EQ(8, break_point_hit_count);
   3667 
   3668   v8::Debug::SetDebugEventListener(NULL);
   3669   CheckDebuggerUnloaded();
   3670 
   3671   // Register a debug event listener which just counts.
   3672   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
   3673 
   3674   break_point_hit_count = 0;
   3675   foo->Call(env->Global(), 0, NULL);
   3676 
   3677   // Without stepping only the debugger statement is hit.
   3678   CHECK_EQ(1, break_point_hit_count);
   3679 
   3680   v8::Debug::SetDebugEventListener(NULL);
   3681   CheckDebuggerUnloaded();
   3682 }
   3683 
   3684 
   3685 // Tests that breakpoint will be hit if it's set in script.
   3686 TEST(PauseInScript) {
   3687   v8::HandleScope scope;
   3688   DebugLocalContext env;
   3689   env.ExposeDebug();
   3690 
   3691   // Register a debug event listener which counts.
   3692   v8::Debug::SetDebugEventListener(DebugEventCounter);
   3693 
   3694   // Create a script that returns a function.
   3695   const char* src = "(function (evt) {})";
   3696   const char* script_name = "StepInHandlerTest";
   3697 
   3698   // Set breakpoint in the script.
   3699   SetScriptBreakPointByNameFromJS(script_name, 0, -1);
   3700   break_point_hit_count = 0;
   3701 
   3702   v8::ScriptOrigin origin(v8::String::New(script_name), v8::Integer::New(0));
   3703   v8::Handle<v8::Script> script = v8::Script::Compile(v8::String::New(src),
   3704                                                       &origin);
   3705   v8::Local<v8::Value> r = script->Run();
   3706 
   3707   CHECK(r->IsFunction());
   3708   CHECK_EQ(1, break_point_hit_count);
   3709 
   3710   // Get rid of the debug event listener.
   3711   v8::Debug::SetDebugEventListener(NULL);
   3712   CheckDebuggerUnloaded();
   3713 }
   3714 
   3715 
   3716 // Test break on exceptions. For each exception break combination the number
   3717 // of debug event exception callbacks and message callbacks are collected. The
   3718 // number of debug event exception callbacks are used to check that the
   3719 // debugger is called correctly and the number of message callbacks is used to
   3720 // check that uncaught exceptions are still returned even if there is a break
   3721 // for them.
   3722 TEST(BreakOnException) {
   3723   v8::HandleScope scope;
   3724   DebugLocalContext env;
   3725   env.ExposeDebug();
   3726 
   3727   v8::internal::Isolate::Current()->TraceException(false);
   3728 
   3729   // Create functions for testing break on exception.
   3730   v8::Local<v8::Function> throws =
   3731       CompileFunction(&env, "function throws(){throw 1;}", "throws");
   3732   v8::Local<v8::Function> caught =
   3733       CompileFunction(&env,
   3734                       "function caught(){try {throws();} catch(e) {};}",
   3735                       "caught");
   3736   v8::Local<v8::Function> notCaught =
   3737       CompileFunction(&env, "function notCaught(){throws();}", "notCaught");
   3738 
   3739   v8::V8::AddMessageListener(MessageCallbackCount);
   3740   v8::Debug::SetDebugEventListener(DebugEventCounter);
   3741 
   3742   // Initial state should be no break on exceptions.
   3743   DebugEventCounterClear();
   3744   MessageCallbackCountClear();
   3745   caught->Call(env->Global(), 0, NULL);
   3746   CHECK_EQ(0, exception_hit_count);
   3747   CHECK_EQ(0, uncaught_exception_hit_count);
   3748   CHECK_EQ(0, message_callback_count);
   3749   notCaught->Call(env->Global(), 0, NULL);
   3750   CHECK_EQ(0, exception_hit_count);
   3751   CHECK_EQ(0, uncaught_exception_hit_count);
   3752   CHECK_EQ(1, message_callback_count);
   3753 
   3754   // No break on exception
   3755   DebugEventCounterClear();
   3756   MessageCallbackCountClear();
   3757   ChangeBreakOnException(false, false);
   3758   caught->Call(env->Global(), 0, NULL);
   3759   CHECK_EQ(0, exception_hit_count);
   3760   CHECK_EQ(0, uncaught_exception_hit_count);
   3761   CHECK_EQ(0, message_callback_count);
   3762   notCaught->Call(env->Global(), 0, NULL);
   3763   CHECK_EQ(0, exception_hit_count);
   3764   CHECK_EQ(0, uncaught_exception_hit_count);
   3765   CHECK_EQ(1, message_callback_count);
   3766 
   3767   // Break on uncaught exception
   3768   DebugEventCounterClear();
   3769   MessageCallbackCountClear();
   3770   ChangeBreakOnException(false, true);
   3771   caught->Call(env->Global(), 0, NULL);
   3772   CHECK_EQ(0, exception_hit_count);
   3773   CHECK_EQ(0, uncaught_exception_hit_count);
   3774   CHECK_EQ(0, message_callback_count);
   3775   notCaught->Call(env->Global(), 0, NULL);
   3776   CHECK_EQ(1, exception_hit_count);
   3777   CHECK_EQ(1, uncaught_exception_hit_count);
   3778   CHECK_EQ(1, message_callback_count);
   3779 
   3780   // Break on exception and uncaught exception
   3781   DebugEventCounterClear();
   3782   MessageCallbackCountClear();
   3783   ChangeBreakOnException(true, true);
   3784   caught->Call(env->Global(), 0, NULL);
   3785   CHECK_EQ(1, exception_hit_count);
   3786   CHECK_EQ(0, uncaught_exception_hit_count);
   3787   CHECK_EQ(0, message_callback_count);
   3788   notCaught->Call(env->Global(), 0, NULL);
   3789   CHECK_EQ(2, exception_hit_count);
   3790   CHECK_EQ(1, uncaught_exception_hit_count);
   3791   CHECK_EQ(1, message_callback_count);
   3792 
   3793   // Break on exception
   3794   DebugEventCounterClear();
   3795   MessageCallbackCountClear();
   3796   ChangeBreakOnException(true, false);
   3797   caught->Call(env->Global(), 0, NULL);
   3798   CHECK_EQ(1, exception_hit_count);
   3799   CHECK_EQ(0, uncaught_exception_hit_count);
   3800   CHECK_EQ(0, message_callback_count);
   3801   notCaught->Call(env->Global(), 0, NULL);
   3802   CHECK_EQ(2, exception_hit_count);
   3803   CHECK_EQ(1, uncaught_exception_hit_count);
   3804   CHECK_EQ(1, message_callback_count);
   3805 
   3806   // No break on exception using JavaScript
   3807   DebugEventCounterClear();
   3808   MessageCallbackCountClear();
   3809   ChangeBreakOnExceptionFromJS(false, false);
   3810   caught->Call(env->Global(), 0, NULL);
   3811   CHECK_EQ(0, exception_hit_count);
   3812   CHECK_EQ(0, uncaught_exception_hit_count);
   3813   CHECK_EQ(0, message_callback_count);
   3814   notCaught->Call(env->Global(), 0, NULL);
   3815   CHECK_EQ(0, exception_hit_count);
   3816   CHECK_EQ(0, uncaught_exception_hit_count);
   3817   CHECK_EQ(1, message_callback_count);
   3818 
   3819   // Break on uncaught exception using JavaScript
   3820   DebugEventCounterClear();
   3821   MessageCallbackCountClear();
   3822   ChangeBreakOnExceptionFromJS(false, true);
   3823   caught->Call(env->Global(), 0, NULL);
   3824   CHECK_EQ(0, exception_hit_count);
   3825   CHECK_EQ(0, uncaught_exception_hit_count);
   3826   CHECK_EQ(0, message_callback_count);
   3827   notCaught->Call(env->Global(), 0, NULL);
   3828   CHECK_EQ(1, exception_hit_count);
   3829   CHECK_EQ(1, uncaught_exception_hit_count);
   3830   CHECK_EQ(1, message_callback_count);
   3831 
   3832   // Break on exception and uncaught exception using JavaScript
   3833   DebugEventCounterClear();
   3834   MessageCallbackCountClear();
   3835   ChangeBreakOnExceptionFromJS(true, true);
   3836   caught->Call(env->Global(), 0, NULL);
   3837   CHECK_EQ(1, exception_hit_count);
   3838   CHECK_EQ(0, message_callback_count);
   3839   CHECK_EQ(0, uncaught_exception_hit_count);
   3840   notCaught->Call(env->Global(), 0, NULL);
   3841   CHECK_EQ(2, exception_hit_count);
   3842   CHECK_EQ(1, uncaught_exception_hit_count);
   3843   CHECK_EQ(1, message_callback_count);
   3844 
   3845   // Break on exception using JavaScript
   3846   DebugEventCounterClear();
   3847   MessageCallbackCountClear();
   3848   ChangeBreakOnExceptionFromJS(true, false);
   3849   caught->Call(env->Global(), 0, NULL);
   3850   CHECK_EQ(1, exception_hit_count);
   3851   CHECK_EQ(0, uncaught_exception_hit_count);
   3852   CHECK_EQ(0, message_callback_count);
   3853   notCaught->Call(env->Global(), 0, NULL);
   3854   CHECK_EQ(2, exception_hit_count);
   3855   CHECK_EQ(1, uncaught_exception_hit_count);
   3856   CHECK_EQ(1, message_callback_count);
   3857 
   3858   v8::Debug::SetDebugEventListener(NULL);
   3859   CheckDebuggerUnloaded();
   3860   v8::V8::RemoveMessageListeners(MessageCallbackCount);
   3861 }
   3862 
   3863 
   3864 // Test break on exception from compiler errors. When compiling using
   3865 // v8::Script::Compile there is no JavaScript stack whereas when compiling using
   3866 // eval there are JavaScript frames.
   3867 TEST(BreakOnCompileException) {
   3868   v8::HandleScope scope;
   3869   DebugLocalContext env;
   3870 
   3871   // For this test, we want to break on uncaught exceptions:
   3872   ChangeBreakOnException(false, true);
   3873 
   3874   v8::internal::Isolate::Current()->TraceException(false);
   3875 
   3876   // Create a function for checking the function when hitting a break point.
   3877   frame_count = CompileFunction(&env, frame_count_source, "frame_count");
   3878 
   3879   v8::V8::AddMessageListener(MessageCallbackCount);
   3880   v8::Debug::SetDebugEventListener(DebugEventCounter);
   3881 
   3882   DebugEventCounterClear();
   3883   MessageCallbackCountClear();
   3884 
   3885   // Check initial state.
   3886   CHECK_EQ(0, exception_hit_count);
   3887   CHECK_EQ(0, uncaught_exception_hit_count);
   3888   CHECK_EQ(0, message_callback_count);
   3889   CHECK_EQ(-1, last_js_stack_height);
   3890 
   3891   // Throws SyntaxError: Unexpected end of input
   3892   v8::Script::Compile(v8::String::New("+++"));
   3893   CHECK_EQ(1, exception_hit_count);
   3894   CHECK_EQ(1, uncaught_exception_hit_count);
   3895   CHECK_EQ(1, message_callback_count);
   3896   CHECK_EQ(0, last_js_stack_height);  // No JavaScript stack.
   3897 
   3898   // Throws SyntaxError: Unexpected identifier
   3899   v8::Script::Compile(v8::String::New("x x"));
   3900   CHECK_EQ(2, exception_hit_count);
   3901   CHECK_EQ(2, uncaught_exception_hit_count);
   3902   CHECK_EQ(2, message_callback_count);
   3903   CHECK_EQ(0, last_js_stack_height);  // No JavaScript stack.
   3904 
   3905   // Throws SyntaxError: Unexpected end of input
   3906   v8::Script::Compile(v8::String::New("eval('+++')"))->Run();
   3907   CHECK_EQ(3, exception_hit_count);
   3908   CHECK_EQ(3, uncaught_exception_hit_count);
   3909   CHECK_EQ(3, message_callback_count);
   3910   CHECK_EQ(1, last_js_stack_height);
   3911 
   3912   // Throws SyntaxError: Unexpected identifier
   3913   v8::Script::Compile(v8::String::New("eval('x x')"))->Run();
   3914   CHECK_EQ(4, exception_hit_count);
   3915   CHECK_EQ(4, uncaught_exception_hit_count);
   3916   CHECK_EQ(4, message_callback_count);
   3917   CHECK_EQ(1, last_js_stack_height);
   3918 }
   3919 
   3920 
   3921 TEST(StepWithException) {
   3922   v8::HandleScope scope;
   3923   DebugLocalContext env;
   3924 
   3925   // For this test, we want to break on uncaught exceptions:
   3926   ChangeBreakOnException(false, true);
   3927 
   3928   // Create a function for checking the function when hitting a break point.
   3929   frame_function_name = CompileFunction(&env,
   3930                                         frame_function_name_source,
   3931                                         "frame_function_name");
   3932 
   3933   // Register a debug event listener which steps and counts.
   3934   v8::Debug::SetDebugEventListener(DebugEventStepSequence);
   3935 
   3936   // Create functions for testing stepping.
   3937   const char* src = "function a() { n(); }; "
   3938                     "function b() { c(); }; "
   3939                     "function c() { n(); }; "
   3940                     "function d() { x = 1; try { e(); } catch(x) { x = 2; } }; "
   3941                     "function e() { n(); }; "
   3942                     "function f() { x = 1; try { g(); } catch(x) { x = 2; } }; "
   3943                     "function g() { h(); }; "
   3944                     "function h() { x = 1; throw 1; }; ";
   3945 
   3946   // Step through invocation of a.
   3947   v8::Local<v8::Function> a = CompileFunction(&env, src, "a");
   3948   SetBreakPoint(a, 0);
   3949   step_action = StepIn;
   3950   break_point_hit_count = 0;
   3951   expected_step_sequence = "aa";
   3952   a->Call(env->Global(), 0, NULL);
   3953   CHECK_EQ(StrLength(expected_step_sequence),
   3954            break_point_hit_count);
   3955 
   3956   // Step through invocation of b + c.
   3957   v8::Local<v8::Function> b = CompileFunction(&env, src, "b");
   3958   SetBreakPoint(b, 0);
   3959   step_action = StepIn;
   3960   break_point_hit_count = 0;
   3961   expected_step_sequence = "bcc";
   3962   b->Call(env->Global(), 0, NULL);
   3963   CHECK_EQ(StrLength(expected_step_sequence),
   3964            break_point_hit_count);
   3965   // Step through invocation of d + e.
   3966   v8::Local<v8::Function> d = CompileFunction(&env, src, "d");
   3967   SetBreakPoint(d, 0);
   3968   ChangeBreakOnException(false, true);
   3969   step_action = StepIn;
   3970   break_point_hit_count = 0;
   3971   expected_step_sequence = "ddedd";
   3972   d->Call(env->Global(), 0, NULL);
   3973   CHECK_EQ(StrLength(expected_step_sequence),
   3974            break_point_hit_count);
   3975 
   3976   // Step through invocation of d + e now with break on caught exceptions.
   3977   ChangeBreakOnException(true, true);
   3978   step_action = StepIn;
   3979   break_point_hit_count = 0;
   3980   expected_step_sequence = "ddeedd";
   3981   d->Call(env->Global(), 0, NULL);
   3982   CHECK_EQ(StrLength(expected_step_sequence),
   3983            break_point_hit_count);
   3984 
   3985   // Step through invocation of f + g + h.
   3986   v8::Local<v8::Function> f = CompileFunction(&env, src, "f");
   3987   SetBreakPoint(f, 0);
   3988   ChangeBreakOnException(false, true);
   3989   step_action = StepIn;
   3990   break_point_hit_count = 0;
   3991   expected_step_sequence = "ffghhff";
   3992   f->Call(env->Global(), 0, NULL);
   3993   CHECK_EQ(StrLength(expected_step_sequence),
   3994            break_point_hit_count);
   3995 
   3996   // Step through invocation of f + g + h now with break on caught exceptions.
   3997   ChangeBreakOnException(true, true);
   3998   step_action = StepIn;
   3999   break_point_hit_count = 0;
   4000   expected_step_sequence = "ffghhhff";
   4001   f->Call(env->Global(), 0, NULL);
   4002   CHECK_EQ(StrLength(expected_step_sequence),
   4003            break_point_hit_count);
   4004 
   4005   // Get rid of the debug event listener.
   4006   v8::Debug::SetDebugEventListener(NULL);
   4007   CheckDebuggerUnloaded();
   4008 }
   4009 
   4010 
   4011 TEST(DebugBreak) {
   4012   v8::HandleScope scope;
   4013   DebugLocalContext env;
   4014 
   4015   // This test should be run with option --verify-heap. As --verify-heap is
   4016   // only available in debug mode only check for it in that case.
   4017 #ifdef DEBUG
   4018   CHECK(v8::internal::FLAG_verify_heap);
   4019 #endif
   4020 
   4021   // Register a debug event listener which sets the break flag and counts.
   4022   v8::Debug::SetDebugEventListener(DebugEventBreak);
   4023 
   4024   // Create a function for testing stepping.
   4025   const char* src = "function f0() {}"
   4026                     "function f1(x1) {}"
   4027                     "function f2(x1,x2) {}"
   4028                     "function f3(x1,x2,x3) {}";
   4029   v8::Local<v8::Function> f0 = CompileFunction(&env, src, "f0");
   4030   v8::Local<v8::Function> f1 = CompileFunction(&env, src, "f1");
   4031   v8::Local<v8::Function> f2 = CompileFunction(&env, src, "f2");
   4032   v8::Local<v8::Function> f3 = CompileFunction(&env, src, "f3");
   4033 
   4034   // Call the function to make sure it is compiled.
   4035   v8::Handle<v8::Value> argv[] = { v8::Number::New(1),
   4036                                    v8::Number::New(1),
   4037                                    v8::Number::New(1),
   4038                                    v8::Number::New(1) };
   4039 
   4040   // Call all functions to make sure that they are compiled.
   4041   f0->Call(env->Global(), 0, NULL);
   4042   f1->Call(env->Global(), 0, NULL);
   4043   f2->Call(env->Global(), 0, NULL);
   4044   f3->Call(env->Global(), 0, NULL);
   4045 
   4046   // Set the debug break flag.
   4047   v8::Debug::DebugBreak();
   4048 
   4049   // Call all functions with different argument count.
   4050   break_point_hit_count = 0;
   4051   for (unsigned int i = 0; i < ARRAY_SIZE(argv); i++) {
   4052     f0->Call(env->Global(), i, argv);
   4053     f1->Call(env->Global(), i, argv);
   4054     f2->Call(env->Global(), i, argv);
   4055     f3->Call(env->Global(), i, argv);
   4056   }
   4057 
   4058   // One break for each function called.
   4059   CHECK_EQ(4 * ARRAY_SIZE(argv), break_point_hit_count);
   4060 
   4061   // Get rid of the debug event listener.
   4062   v8::Debug::SetDebugEventListener(NULL);
   4063   CheckDebuggerUnloaded();
   4064 }
   4065 
   4066 
   4067 // Test to ensure that JavaScript code keeps running while the debug break
   4068 // through the stack limit flag is set but breaks are disabled.
   4069 TEST(DisableBreak) {
   4070   v8::HandleScope scope;
   4071   DebugLocalContext env;
   4072 
   4073   // Register a debug event listener which sets the break flag and counts.
   4074   v8::Debug::SetDebugEventListener(DebugEventCounter);
   4075 
   4076   // Create a function for testing stepping.
   4077   const char* src = "function f() {g()};function g(){i=0; while(i<10){i++}}";
   4078   v8::Local<v8::Function> f = CompileFunction(&env, src, "f");
   4079 
   4080   // Set the debug break flag.
   4081   v8::Debug::DebugBreak();
   4082 
   4083   // Call all functions with different argument count.
   4084   break_point_hit_count = 0;
   4085   f->Call(env->Global(), 0, NULL);
   4086   CHECK_EQ(1, break_point_hit_count);
   4087 
   4088   {
   4089     v8::Debug::DebugBreak();
   4090     v8::internal::DisableBreak disable_break(true);
   4091     f->Call(env->Global(), 0, NULL);
   4092     CHECK_EQ(1, break_point_hit_count);
   4093   }
   4094 
   4095   f->Call(env->Global(), 0, NULL);
   4096   CHECK_EQ(2, break_point_hit_count);
   4097 
   4098   // Get rid of the debug event listener.
   4099   v8::Debug::SetDebugEventListener(NULL);
   4100   CheckDebuggerUnloaded();
   4101 }
   4102 
   4103 static const char* kSimpleExtensionSource =
   4104   "(function Foo() {"
   4105   "  return 4;"
   4106   "})() ";
   4107 
   4108 // http://crbug.com/28933
   4109 // Test that debug break is disabled when bootstrapper is active.
   4110 TEST(NoBreakWhenBootstrapping) {
   4111   v8::HandleScope scope;
   4112 
   4113   // Register a debug event listener which sets the break flag and counts.
   4114   v8::Debug::SetDebugEventListener(DebugEventCounter);
   4115 
   4116   // Set the debug break flag.
   4117   v8::Debug::DebugBreak();
   4118   break_point_hit_count = 0;
   4119   {
   4120     // Create a context with an extension to make sure that some JavaScript
   4121     // code is executed during bootstrapping.
   4122     v8::RegisterExtension(new v8::Extension("simpletest",
   4123                                             kSimpleExtensionSource));
   4124     const char* extension_names[] = { "simpletest" };
   4125     v8::ExtensionConfiguration extensions(1, extension_names);
   4126     v8::Persistent<v8::Context> context = v8::Context::New(&extensions);
   4127     context.Dispose();
   4128   }
   4129   // Check that no DebugBreak events occured during the context creation.
   4130   CHECK_EQ(0, break_point_hit_count);
   4131 
   4132   // Get rid of the debug event listener.
   4133   v8::Debug::SetDebugEventListener(NULL);
   4134   CheckDebuggerUnloaded();
   4135 }
   4136 
   4137 static v8::Handle<v8::Array> NamedEnum(const v8::AccessorInfo&) {
   4138   v8::Handle<v8::Array> result = v8::Array::New(3);
   4139   result->Set(v8::Integer::New(0), v8::String::New("a"));
   4140   result->Set(v8::Integer::New(1), v8::String::New("b"));
   4141   result->Set(v8::Integer::New(2), v8::String::New("c"));
   4142   return result;
   4143 }
   4144 
   4145 
   4146 static v8::Handle<v8::Array> IndexedEnum(const v8::AccessorInfo&) {
   4147   v8::Handle<v8::Array> result = v8::Array::New(2);
   4148   result->Set(v8::Integer::New(0), v8::Number::New(1));
   4149   result->Set(v8::Integer::New(1), v8::Number::New(10));
   4150   return result;
   4151 }
   4152 
   4153 
   4154 static v8::Handle<v8::Value> NamedGetter(v8::Local<v8::String> name,
   4155                                          const v8::AccessorInfo& info) {
   4156   v8::String::AsciiValue n(name);
   4157   if (strcmp(*n, "a") == 0) {
   4158     return v8::String::New("AA");
   4159   } else if (strcmp(*n, "b") == 0) {
   4160     return v8::String::New("BB");
   4161   } else if (strcmp(*n, "c") == 0) {
   4162     return v8::String::New("CC");
   4163   } else {
   4164     return v8::Undefined();
   4165   }
   4166 
   4167   return name;
   4168 }
   4169 
   4170 
   4171 static v8::Handle<v8::Value> IndexedGetter(uint32_t index,
   4172                                            const v8::AccessorInfo& info) {
   4173   return v8::Number::New(index + 1);
   4174 }
   4175 
   4176 
   4177 TEST(InterceptorPropertyMirror) {
   4178   // Create a V8 environment with debug access.
   4179   v8::HandleScope scope;
   4180   DebugLocalContext env;
   4181   env.ExposeDebug();
   4182 
   4183   // Create object with named interceptor.
   4184   v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New();
   4185   named->SetNamedPropertyHandler(NamedGetter, NULL, NULL, NULL, NamedEnum);
   4186   env->Global()->Set(v8::String::New("intercepted_named"),
   4187                      named->NewInstance());
   4188 
   4189   // Create object with indexed interceptor.
   4190   v8::Handle<v8::ObjectTemplate> indexed = v8::ObjectTemplate::New();
   4191   indexed->SetIndexedPropertyHandler(IndexedGetter,
   4192                                      NULL,
   4193                                      NULL,
   4194                                      NULL,
   4195                                      IndexedEnum);
   4196   env->Global()->Set(v8::String::New("intercepted_indexed"),
   4197                      indexed->NewInstance());
   4198 
   4199   // Create object with both named and indexed interceptor.
   4200   v8::Handle<v8::ObjectTemplate> both = v8::ObjectTemplate::New();
   4201   both->SetNamedPropertyHandler(NamedGetter, NULL, NULL, NULL, NamedEnum);
   4202   both->SetIndexedPropertyHandler(IndexedGetter, NULL, NULL, NULL, IndexedEnum);
   4203   env->Global()->Set(v8::String::New("intercepted_both"), both->NewInstance());
   4204 
   4205   // Get mirrors for the three objects with interceptor.
   4206   CompileRun(
   4207       "named_mirror = debug.MakeMirror(intercepted_named);"
   4208       "indexed_mirror = debug.MakeMirror(intercepted_indexed);"
   4209       "both_mirror = debug.MakeMirror(intercepted_both)");
   4210   CHECK(CompileRun(
   4211        "named_mirror instanceof debug.ObjectMirror")->BooleanValue());
   4212   CHECK(CompileRun(
   4213         "indexed_mirror instanceof debug.ObjectMirror")->BooleanValue());
   4214   CHECK(CompileRun(
   4215         "both_mirror instanceof debug.ObjectMirror")->BooleanValue());
   4216 
   4217   // Get the property names from the interceptors
   4218   CompileRun(
   4219       "named_names = named_mirror.propertyNames();"
   4220       "indexed_names = indexed_mirror.propertyNames();"
   4221       "both_names = both_mirror.propertyNames()");
   4222   CHECK_EQ(3, CompileRun("named_names.length")->Int32Value());
   4223   CHECK_EQ(2, CompileRun("indexed_names.length")->Int32Value());
   4224   CHECK_EQ(5, CompileRun("both_names.length")->Int32Value());
   4225 
   4226   // Check the expected number of properties.
   4227   const char* source;
   4228   source = "named_mirror.properties().length";
   4229   CHECK_EQ(3, CompileRun(source)->Int32Value());
   4230 
   4231   source = "indexed_mirror.properties().length";
   4232   CHECK_EQ(2, CompileRun(source)->Int32Value());
   4233 
   4234   source = "both_mirror.properties().length";
   4235   CHECK_EQ(5, CompileRun(source)->Int32Value());
   4236 
   4237   // 1 is PropertyKind.Named;
   4238   source = "both_mirror.properties(1).length";
   4239   CHECK_EQ(3, CompileRun(source)->Int32Value());
   4240 
   4241   // 2 is PropertyKind.Indexed;
   4242   source = "both_mirror.properties(2).length";
   4243   CHECK_EQ(2, CompileRun(source)->Int32Value());
   4244 
   4245   // 3 is PropertyKind.Named  | PropertyKind.Indexed;
   4246   source = "both_mirror.properties(3).length";
   4247   CHECK_EQ(5, CompileRun(source)->Int32Value());
   4248 
   4249   // Get the interceptor properties for the object with only named interceptor.
   4250   CompileRun("named_values = named_mirror.properties()");
   4251 
   4252   // Check that the properties are interceptor properties.
   4253   for (int i = 0; i < 3; i++) {
   4254     EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
   4255     OS::SNPrintF(buffer,
   4256                  "named_values[%d] instanceof debug.PropertyMirror", i);
   4257     CHECK(CompileRun(buffer.start())->BooleanValue());
   4258 
   4259     // 4 is PropertyType.Interceptor
   4260     OS::SNPrintF(buffer, "named_values[%d].propertyType()", i);
   4261     CHECK_EQ(4, CompileRun(buffer.start())->Int32Value());
   4262 
   4263     OS::SNPrintF(buffer, "named_values[%d].isNative()", i);
   4264     CHECK(CompileRun(buffer.start())->BooleanValue());
   4265   }
   4266 
   4267   // Get the interceptor properties for the object with only indexed
   4268   // interceptor.
   4269   CompileRun("indexed_values = indexed_mirror.properties()");
   4270 
   4271   // Check that the properties are interceptor properties.
   4272   for (int i = 0; i < 2; i++) {
   4273     EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
   4274     OS::SNPrintF(buffer,
   4275                  "indexed_values[%d] instanceof debug.PropertyMirror", i);
   4276     CHECK(CompileRun(buffer.start())->BooleanValue());
   4277   }
   4278 
   4279   // Get the interceptor properties for the object with both types of
   4280   // interceptors.
   4281   CompileRun("both_values = both_mirror.properties()");
   4282 
   4283   // Check that the properties are interceptor properties.
   4284   for (int i = 0; i < 5; i++) {
   4285     EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
   4286     OS::SNPrintF(buffer, "both_values[%d] instanceof debug.PropertyMirror", i);
   4287     CHECK(CompileRun(buffer.start())->BooleanValue());
   4288   }
   4289 
   4290   // Check the property names.
   4291   source = "both_values[0].name() == 'a'";
   4292   CHECK(CompileRun(source)->BooleanValue());
   4293 
   4294   source = "both_values[1].name() == 'b'";
   4295   CHECK(CompileRun(source)->BooleanValue());
   4296 
   4297   source = "both_values[2].name() == 'c'";
   4298   CHECK(CompileRun(source)->BooleanValue());
   4299 
   4300   source = "both_values[3].name() == 1";
   4301   CHECK(CompileRun(source)->BooleanValue());
   4302 
   4303   source = "both_values[4].name() == 10";
   4304   CHECK(CompileRun(source)->BooleanValue());
   4305 }
   4306 
   4307 
   4308 TEST(HiddenPrototypePropertyMirror) {
   4309   // Create a V8 environment with debug access.
   4310   v8::HandleScope scope;
   4311   DebugLocalContext env;
   4312   env.ExposeDebug();
   4313 
   4314   v8::Handle<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New();
   4315   t0->InstanceTemplate()->Set(v8::String::New("x"), v8::Number::New(0));
   4316   v8::Handle<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New();
   4317   t1->SetHiddenPrototype(true);
   4318   t1->InstanceTemplate()->Set(v8::String::New("y"), v8::Number::New(1));
   4319   v8::Handle<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New();
   4320   t2->SetHiddenPrototype(true);
   4321   t2->InstanceTemplate()->Set(v8::String::New("z"), v8::Number::New(2));
   4322   v8::Handle<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New();
   4323   t3->InstanceTemplate()->Set(v8::String::New("u"), v8::Number::New(3));
   4324 
   4325   // Create object and set them on the global object.
   4326   v8::Handle<v8::Object> o0 = t0->GetFunction()->NewInstance();
   4327   env->Global()->Set(v8::String::New("o0"), o0);
   4328   v8::Handle<v8::Object> o1 = t1->GetFunction()->NewInstance();
   4329   env->Global()->Set(v8::String::New("o1"), o1);
   4330   v8::Handle<v8::Object> o2 = t2->GetFunction()->NewInstance();
   4331   env->Global()->Set(v8::String::New("o2"), o2);
   4332   v8::Handle<v8::Object> o3 = t3->GetFunction()->NewInstance();
   4333   env->Global()->Set(v8::String::New("o3"), o3);
   4334 
   4335   // Get mirrors for the four objects.
   4336   CompileRun(
   4337       "o0_mirror = debug.MakeMirror(o0);"
   4338       "o1_mirror = debug.MakeMirror(o1);"
   4339       "o2_mirror = debug.MakeMirror(o2);"
   4340       "o3_mirror = debug.MakeMirror(o3)");
   4341   CHECK(CompileRun("o0_mirror instanceof debug.ObjectMirror")->BooleanValue());
   4342   CHECK(CompileRun("o1_mirror instanceof debug.ObjectMirror")->BooleanValue());
   4343   CHECK(CompileRun("o2_mirror instanceof debug.ObjectMirror")->BooleanValue());
   4344   CHECK(CompileRun("o3_mirror instanceof debug.ObjectMirror")->BooleanValue());
   4345 
   4346   // Check that each object has one property.
   4347   CHECK_EQ(1, CompileRun(
   4348               "o0_mirror.propertyNames().length")->Int32Value());
   4349   CHECK_EQ(1, CompileRun(
   4350               "o1_mirror.propertyNames().length")->Int32Value());
   4351   CHECK_EQ(1, CompileRun(
   4352               "o2_mirror.propertyNames().length")->Int32Value());
   4353   CHECK_EQ(1, CompileRun(
   4354               "o3_mirror.propertyNames().length")->Int32Value());
   4355 
   4356   // Set o1 as prototype for o0. o1 has the hidden prototype flag so all
   4357   // properties on o1 should be seen on o0.
   4358   o0->Set(v8::String::New("__proto__"), o1);
   4359   CHECK_EQ(2, CompileRun(
   4360               "o0_mirror.propertyNames().length")->Int32Value());
   4361   CHECK_EQ(0, CompileRun(
   4362               "o0_mirror.property('x').value().value()")->Int32Value());
   4363   CHECK_EQ(1, CompileRun(
   4364               "o0_mirror.property('y').value().value()")->Int32Value());
   4365 
   4366   // Set o2 as prototype for o0 (it will end up after o1 as o1 has the hidden
   4367   // prototype flag. o2 also has the hidden prototype flag so all properties
   4368   // on o2 should be seen on o0 as well as properties on o1.
   4369   o0->Set(v8::String::New("__proto__"), o2);
   4370   CHECK_EQ(3, CompileRun(
   4371               "o0_mirror.propertyNames().length")->Int32Value());
   4372   CHECK_EQ(0, CompileRun(
   4373               "o0_mirror.property('x').value().value()")->Int32Value());
   4374   CHECK_EQ(1, CompileRun(
   4375               "o0_mirror.property('y').value().value()")->Int32Value());
   4376   CHECK_EQ(2, CompileRun(
   4377               "o0_mirror.property('z').value().value()")->Int32Value());
   4378 
   4379   // Set o3 as prototype for o0 (it will end up after o1 and o2 as both o1 and
   4380   // o2 has the hidden prototype flag. o3 does not have the hidden prototype
   4381   // flag so properties on o3 should not be seen on o0 whereas the properties
   4382   // from o1 and o2 should still be seen on o0.
   4383   // Final prototype chain: o0 -> o1 -> o2 -> o3
   4384   // Hidden prototypes:           ^^    ^^
   4385   o0->Set(v8::String::New("__proto__"), o3);
   4386   CHECK_EQ(3, CompileRun(
   4387               "o0_mirror.propertyNames().length")->Int32Value());
   4388   CHECK_EQ(1, CompileRun(
   4389               "o3_mirror.propertyNames().length")->Int32Value());
   4390   CHECK_EQ(0, CompileRun(
   4391               "o0_mirror.property('x').value().value()")->Int32Value());
   4392   CHECK_EQ(1, CompileRun(
   4393               "o0_mirror.property('y').value().value()")->Int32Value());
   4394   CHECK_EQ(2, CompileRun(
   4395               "o0_mirror.property('z').value().value()")->Int32Value());
   4396   CHECK(CompileRun("o0_mirror.property('u').isUndefined()")->BooleanValue());
   4397 
   4398   // The prototype (__proto__) for o0 should be o3 as o1 and o2 are hidden.
   4399   CHECK(CompileRun("o0_mirror.protoObject() == o3_mirror")->BooleanValue());
   4400 }
   4401 
   4402 
   4403 static v8::Handle<v8::Value> ProtperyXNativeGetter(
   4404     v8::Local<v8::String> property, const v8::AccessorInfo& info) {
   4405   return v8::Integer::New(10);
   4406 }
   4407 
   4408 
   4409 TEST(NativeGetterPropertyMirror) {
   4410   // Create a V8 environment with debug access.
   4411   v8::HandleScope scope;
   4412   DebugLocalContext env;
   4413   env.ExposeDebug();
   4414 
   4415   v8::Handle<v8::String> name = v8::String::New("x");
   4416   // Create object with named accessor.
   4417   v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New();
   4418   named->SetAccessor(name, &ProtperyXNativeGetter, NULL,
   4419       v8::Handle<v8::Value>(), v8::DEFAULT, v8::None);
   4420 
   4421   // Create object with named property getter.
   4422   env->Global()->Set(v8::String::New("instance"), named->NewInstance());
   4423   CHECK_EQ(10, CompileRun("instance.x")->Int32Value());
   4424 
   4425   // Get mirror for the object with property getter.
   4426   CompileRun("instance_mirror = debug.MakeMirror(instance);");
   4427   CHECK(CompileRun(
   4428       "instance_mirror instanceof debug.ObjectMirror")->BooleanValue());
   4429 
   4430   CompileRun("named_names = instance_mirror.propertyNames();");
   4431   CHECK_EQ(1, CompileRun("named_names.length")->Int32Value());
   4432   CHECK(CompileRun("named_names[0] == 'x'")->BooleanValue());
   4433   CHECK(CompileRun(
   4434       "instance_mirror.property('x').value().isNumber()")->BooleanValue());
   4435   CHECK(CompileRun(
   4436       "instance_mirror.property('x').value().value() == 10")->BooleanValue());
   4437 }
   4438 
   4439 
   4440 static v8::Handle<v8::Value> ProtperyXNativeGetterThrowingError(
   4441     v8::Local<v8::String> property, const v8::AccessorInfo& info) {
   4442   return CompileRun("throw new Error('Error message');");
   4443 }
   4444 
   4445 
   4446 TEST(NativeGetterThrowingErrorPropertyMirror) {
   4447   // Create a V8 environment with debug access.
   4448   v8::HandleScope scope;
   4449   DebugLocalContext env;
   4450   env.ExposeDebug();
   4451 
   4452   v8::Handle<v8::String> name = v8::String::New("x");
   4453   // Create object with named accessor.
   4454   v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New();
   4455   named->SetAccessor(name, &ProtperyXNativeGetterThrowingError, NULL,
   4456       v8::Handle<v8::Value>(), v8::DEFAULT, v8::None);
   4457 
   4458   // Create object with named property getter.
   4459   env->Global()->Set(v8::String::New("instance"), named->NewInstance());
   4460 
   4461   // Get mirror for the object with property getter.
   4462   CompileRun("instance_mirror = debug.MakeMirror(instance);");
   4463   CHECK(CompileRun(
   4464       "instance_mirror instanceof debug.ObjectMirror")->BooleanValue());
   4465   CompileRun("named_names = instance_mirror.propertyNames();");
   4466   CHECK_EQ(1, CompileRun("named_names.length")->Int32Value());
   4467   CHECK(CompileRun("named_names[0] == 'x'")->BooleanValue());
   4468   CHECK(CompileRun(
   4469       "instance_mirror.property('x').value().isError()")->BooleanValue());
   4470 
   4471   // Check that the message is that passed to the Error constructor.
   4472   CHECK(CompileRun(
   4473       "instance_mirror.property('x').value().message() == 'Error message'")->
   4474           BooleanValue());
   4475 }
   4476 
   4477 
   4478 // Test that hidden properties object is not returned as an unnamed property
   4479 // among regular properties.
   4480 // See http://crbug.com/26491
   4481 TEST(NoHiddenProperties) {
   4482   // Create a V8 environment with debug access.
   4483   v8::HandleScope scope;
   4484   DebugLocalContext env;
   4485   env.ExposeDebug();
   4486 
   4487   // Create an object in the global scope.
   4488   const char* source = "var obj = {a: 1};";
   4489   v8::Script::Compile(v8::String::New(source))->Run();
   4490   v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(
   4491       env->Global()->Get(v8::String::New("obj")));
   4492   // Set a hidden property on the object.
   4493   obj->SetHiddenValue(v8::String::New("v8::test-debug::a"),
   4494                       v8::Int32::New(11));
   4495 
   4496   // Get mirror for the object with property getter.
   4497   CompileRun("var obj_mirror = debug.MakeMirror(obj);");
   4498   CHECK(CompileRun(
   4499       "obj_mirror instanceof debug.ObjectMirror")->BooleanValue());
   4500   CompileRun("var named_names = obj_mirror.propertyNames();");
   4501   // There should be exactly one property. But there is also an unnamed
   4502   // property whose value is hidden properties dictionary. The latter
   4503   // property should not be in the list of reguar properties.
   4504   CHECK_EQ(1, CompileRun("named_names.length")->Int32Value());
   4505   CHECK(CompileRun("named_names[0] == 'a'")->BooleanValue());
   4506   CHECK(CompileRun(
   4507       "obj_mirror.property('a').value().value() == 1")->BooleanValue());
   4508 
   4509   // Object created by t0 will become hidden prototype of object 'obj'.
   4510   v8::Handle<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New();
   4511   t0->InstanceTemplate()->Set(v8::String::New("b"), v8::Number::New(2));
   4512   t0->SetHiddenPrototype(true);
   4513   v8::Handle<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New();
   4514   t1->InstanceTemplate()->Set(v8::String::New("c"), v8::Number::New(3));
   4515 
   4516   // Create proto objects, add hidden properties to them and set them on
   4517   // the global object.
   4518   v8::Handle<v8::Object> protoObj = t0->GetFunction()->NewInstance();
   4519   protoObj->SetHiddenValue(v8::String::New("v8::test-debug::b"),
   4520                            v8::Int32::New(12));
   4521   env->Global()->Set(v8::String::New("protoObj"), protoObj);
   4522   v8::Handle<v8::Object> grandProtoObj = t1->GetFunction()->NewInstance();
   4523   grandProtoObj->SetHiddenValue(v8::String::New("v8::test-debug::c"),
   4524                                 v8::Int32::New(13));
   4525   env->Global()->Set(v8::String::New("grandProtoObj"), grandProtoObj);
   4526 
   4527   // Setting prototypes: obj->protoObj->grandProtoObj
   4528   protoObj->Set(v8::String::New("__proto__"), grandProtoObj);
   4529   obj->Set(v8::String::New("__proto__"), protoObj);
   4530 
   4531   // Get mirror for the object with property getter.
   4532   CompileRun("var obj_mirror = debug.MakeMirror(obj);");
   4533   CHECK(CompileRun(
   4534       "obj_mirror instanceof debug.ObjectMirror")->BooleanValue());
   4535   CompileRun("var named_names = obj_mirror.propertyNames();");
   4536   // There should be exactly two properties - one from the object itself and
   4537   // another from its hidden prototype.
   4538   CHECK_EQ(2, CompileRun("named_names.length")->Int32Value());
   4539   CHECK(CompileRun("named_names.sort(); named_names[0] == 'a' &&"
   4540                    "named_names[1] == 'b'")->BooleanValue());
   4541   CHECK(CompileRun(
   4542       "obj_mirror.property('a').value().value() == 1")->BooleanValue());
   4543   CHECK(CompileRun(
   4544       "obj_mirror.property('b').value().value() == 2")->BooleanValue());
   4545 }
   4546 
   4547 
   4548 // Multithreaded tests of JSON debugger protocol
   4549 
   4550 // Support classes
   4551 
   4552 // Provides synchronization between k threads, where k is an input to the
   4553 // constructor.  The Wait() call blocks a thread until it is called for the
   4554 // k'th time, then all calls return.  Each ThreadBarrier object can only
   4555 // be used once.
   4556 class ThreadBarrier {
   4557  public:
   4558   explicit ThreadBarrier(int num_threads);
   4559   ~ThreadBarrier();
   4560   void Wait();
   4561  private:
   4562   int num_threads_;
   4563   int num_blocked_;
   4564   v8::internal::Mutex* lock_;
   4565   v8::internal::Semaphore* sem_;
   4566   bool invalid_;
   4567 };
   4568 
   4569 ThreadBarrier::ThreadBarrier(int num_threads)
   4570     : num_threads_(num_threads), num_blocked_(0) {
   4571   lock_ = OS::CreateMutex();
   4572   sem_ = OS::CreateSemaphore(0);
   4573   invalid_ = false;  // A barrier may only be used once.  Then it is invalid.
   4574 }
   4575 
   4576 // Do not call, due to race condition with Wait().
   4577 // Could be resolved with Pthread condition variables.
   4578 ThreadBarrier::~ThreadBarrier() {
   4579   lock_->Lock();
   4580   delete lock_;
   4581   delete sem_;
   4582 }
   4583 
   4584 void ThreadBarrier::Wait() {
   4585   lock_->Lock();
   4586   CHECK(!invalid_);
   4587   if (num_blocked_ == num_threads_ - 1) {
   4588     // Signal and unblock all waiting threads.
   4589     for (int i = 0; i < num_threads_ - 1; ++i) {
   4590       sem_->Signal();
   4591     }
   4592     invalid_ = true;
   4593     printf("BARRIER\n\n");
   4594     fflush(stdout);
   4595     lock_->Unlock();
   4596   } else {  // Wait for the semaphore.
   4597     ++num_blocked_;
   4598     lock_->Unlock();  // Potential race condition with destructor because
   4599     sem_->Wait();  // these two lines are not atomic.
   4600   }
   4601 }
   4602 
   4603 // A set containing enough barriers and semaphores for any of the tests.
   4604 class Barriers {
   4605  public:
   4606   Barriers();
   4607   void Initialize();
   4608   ThreadBarrier barrier_1;
   4609   ThreadBarrier barrier_2;
   4610   ThreadBarrier barrier_3;
   4611   ThreadBarrier barrier_4;
   4612   ThreadBarrier barrier_5;
   4613   v8::internal::Semaphore* semaphore_1;
   4614   v8::internal::Semaphore* semaphore_2;
   4615 };
   4616 
   4617 Barriers::Barriers() : barrier_1(2), barrier_2(2),
   4618     barrier_3(2), barrier_4(2), barrier_5(2) {}
   4619 
   4620 void Barriers::Initialize() {
   4621   semaphore_1 = OS::CreateSemaphore(0);
   4622   semaphore_2 = OS::CreateSemaphore(0);
   4623 }
   4624 
   4625 
   4626 // We match parts of the message to decide if it is a break message.
   4627 bool IsBreakEventMessage(char *message) {
   4628   const char* type_event = "\"type\":\"event\"";
   4629   const char* event_break = "\"event\":\"break\"";
   4630   // Does the message contain both type:event and event:break?
   4631   return strstr(message, type_event) != NULL &&
   4632          strstr(message, event_break) != NULL;
   4633 }
   4634 
   4635 
   4636 // We match parts of the message to decide if it is a exception message.
   4637 bool IsExceptionEventMessage(char *message) {
   4638   const char* type_event = "\"type\":\"event\"";
   4639   const char* event_exception = "\"event\":\"exception\"";
   4640   // Does the message contain both type:event and event:exception?
   4641   return strstr(message, type_event) != NULL &&
   4642       strstr(message, event_exception) != NULL;
   4643 }
   4644 
   4645 
   4646 // We match the message wether it is an evaluate response message.
   4647 bool IsEvaluateResponseMessage(char* message) {
   4648   const char* type_response = "\"type\":\"response\"";
   4649   const char* command_evaluate = "\"command\":\"evaluate\"";
   4650   // Does the message contain both type:response and command:evaluate?
   4651   return strstr(message, type_response) != NULL &&
   4652          strstr(message, command_evaluate) != NULL;
   4653 }
   4654 
   4655 
   4656 static int StringToInt(const char* s) {
   4657   return atoi(s);  // NOLINT
   4658 }
   4659 
   4660 
   4661 // We match parts of the message to get evaluate result int value.
   4662 int GetEvaluateIntResult(char *message) {
   4663   const char* value = "\"value\":";
   4664   char* pos = strstr(message, value);
   4665   if (pos == NULL) {
   4666     return -1;
   4667   }
   4668   int res = -1;
   4669   res = StringToInt(pos + strlen(value));
   4670   return res;
   4671 }
   4672 
   4673 
   4674 // We match parts of the message to get hit breakpoint id.
   4675 int GetBreakpointIdFromBreakEventMessage(char *message) {
   4676   const char* breakpoints = "\"breakpoints\":[";
   4677   char* pos = strstr(message, breakpoints);
   4678   if (pos == NULL) {
   4679     return -1;
   4680   }
   4681   int res = -1;
   4682   res = StringToInt(pos + strlen(breakpoints));
   4683   return res;
   4684 }
   4685 
   4686 
   4687 // We match parts of the message to get total frames number.
   4688 int GetTotalFramesInt(char *message) {
   4689   const char* prefix = "\"totalFrames\":";
   4690   char* pos = strstr(message, prefix);
   4691   if (pos == NULL) {
   4692     return -1;
   4693   }
   4694   pos += strlen(prefix);
   4695   int res = StringToInt(pos);
   4696   return res;
   4697 }
   4698 
   4699 
   4700 // We match parts of the message to get source line.
   4701 int GetSourceLineFromBreakEventMessage(char *message) {
   4702   const char* source_line = "\"sourceLine\":";
   4703   char* pos = strstr(message, source_line);
   4704   if (pos == NULL) {
   4705     return -1;
   4706   }
   4707   int res = -1;
   4708   res = StringToInt(pos + strlen(source_line));
   4709   return res;
   4710 }
   4711 
   4712 /* Test MessageQueues */
   4713 /* Tests the message queues that hold debugger commands and
   4714  * response messages to the debugger.  Fills queues and makes
   4715  * them grow.
   4716  */
   4717 Barriers message_queue_barriers;
   4718 
   4719 // This is the debugger thread, that executes no v8 calls except
   4720 // placing JSON debugger commands in the queue.
   4721 class MessageQueueDebuggerThread : public v8::internal::Thread {
   4722  public:
   4723   explicit MessageQueueDebuggerThread(v8::internal::Isolate* isolate)
   4724       : Thread(isolate, "MessageQueueDebuggerThread") { }
   4725   void Run();
   4726 };
   4727 
   4728 static void MessageHandler(const uint16_t* message, int length,
   4729                            v8::Debug::ClientData* client_data) {
   4730   static char print_buffer[1000];
   4731   Utf16ToAscii(message, length, print_buffer);
   4732   if (IsBreakEventMessage(print_buffer)) {
   4733     // Lets test script wait until break occurs to send commands.
   4734     // Signals when a break is reported.
   4735     message_queue_barriers.semaphore_2->Signal();
   4736   }
   4737 
   4738   // Allow message handler to block on a semaphore, to test queueing of
   4739   // messages while blocked.
   4740   message_queue_barriers.semaphore_1->Wait();
   4741 }
   4742 
   4743 void MessageQueueDebuggerThread::Run() {
   4744   const int kBufferSize = 1000;
   4745   uint16_t buffer_1[kBufferSize];
   4746   uint16_t buffer_2[kBufferSize];
   4747   const char* command_1 =
   4748       "{\"seq\":117,"
   4749        "\"type\":\"request\","
   4750        "\"command\":\"evaluate\","
   4751        "\"arguments\":{\"expression\":\"1+2\"}}";
   4752   const char* command_2 =
   4753     "{\"seq\":118,"
   4754      "\"type\":\"request\","
   4755      "\"command\":\"evaluate\","
   4756      "\"arguments\":{\"expression\":\"1+a\"}}";
   4757   const char* command_3 =
   4758     "{\"seq\":119,"
   4759      "\"type\":\"request\","
   4760      "\"command\":\"evaluate\","
   4761      "\"arguments\":{\"expression\":\"c.d * b\"}}";
   4762   const char* command_continue =
   4763     "{\"seq\":106,"
   4764      "\"type\":\"request\","
   4765      "\"command\":\"continue\"}";
   4766   const char* command_single_step =
   4767     "{\"seq\":107,"
   4768      "\"type\":\"request\","
   4769      "\"command\":\"continue\","
   4770      "\"arguments\":{\"stepaction\":\"next\"}}";
   4771 
   4772   /* Interleaved sequence of actions by the two threads:*/
   4773   // Main thread compiles and runs source_1
   4774   message_queue_barriers.semaphore_1->Signal();
   4775   message_queue_barriers.barrier_1.Wait();
   4776   // Post 6 commands, filling the command queue and making it expand.
   4777   // These calls return immediately, but the commands stay on the queue
   4778   // until the execution of source_2.
   4779   // Note: AsciiToUtf16 executes before SendCommand, so command is copied
   4780   // to buffer before buffer is sent to SendCommand.
   4781   v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_1, buffer_1));
   4782   v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_2, buffer_2));
   4783   v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2));
   4784   v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2));
   4785   v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2));
   4786   message_queue_barriers.barrier_2.Wait();
   4787   // Main thread compiles and runs source_2.
   4788   // Queued commands are executed at the start of compilation of source_2(
   4789   // beforeCompile event).
   4790   // Free the message handler to process all the messages from the queue. 7
   4791   // messages are expected: 2 afterCompile events and 5 responses.
   4792   // All the commands added so far will fail to execute as long as call stack
   4793   // is empty on beforeCompile event.
   4794   for (int i = 0; i < 6 ; ++i) {
   4795     message_queue_barriers.semaphore_1->Signal();
   4796   }
   4797   message_queue_barriers.barrier_3.Wait();
   4798   // Main thread compiles and runs source_3.
   4799   // Don't stop in the afterCompile handler.
   4800   message_queue_barriers.semaphore_1->Signal();
   4801   // source_3 includes a debugger statement, which causes a break event.
   4802   // Wait on break event from hitting "debugger" statement
   4803   message_queue_barriers.semaphore_2->Wait();
   4804   // These should execute after the "debugger" statement in source_2
   4805   v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_1, buffer_1));
   4806   v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_2, buffer_2));
   4807   v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2));
   4808   v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_single_step, buffer_2));
   4809   // Run after 2 break events, 4 responses.
   4810   for (int i = 0; i < 6 ; ++i) {
   4811     message_queue_barriers.semaphore_1->Signal();
   4812   }
   4813   // Wait on break event after a single step executes.
   4814   message_queue_barriers.semaphore_2->Wait();
   4815   v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_2, buffer_1));
   4816   v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_continue, buffer_2));
   4817   // Run after 2 responses.
   4818   for (int i = 0; i < 2 ; ++i) {
   4819     message_queue_barriers.semaphore_1->Signal();
   4820   }
   4821   // Main thread continues running source_3 to end, waits for this thread.
   4822 }
   4823 
   4824 
   4825 // This thread runs the v8 engine.
   4826 TEST(MessageQueues) {
   4827   MessageQueueDebuggerThread message_queue_debugger_thread(
   4828       i::Isolate::Current());
   4829 
   4830   // Create a V8 environment
   4831   v8::HandleScope scope;
   4832   DebugLocalContext env;
   4833   message_queue_barriers.Initialize();
   4834   v8::Debug::SetMessageHandler(MessageHandler);
   4835   message_queue_debugger_thread.Start();
   4836 
   4837   const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;";
   4838   const char* source_2 = "e = 17;";
   4839   const char* source_3 = "a = 4; debugger; a = 5; a = 6; a = 7;";
   4840 
   4841   // See MessageQueueDebuggerThread::Run for interleaved sequence of
   4842   // API calls and events in the two threads.
   4843   CompileRun(source_1);
   4844   message_queue_barriers.barrier_1.Wait();
   4845   message_queue_barriers.barrier_2.Wait();
   4846   CompileRun(source_2);
   4847   message_queue_barriers.barrier_3.Wait();
   4848   CompileRun(source_3);
   4849   message_queue_debugger_thread.Join();
   4850   fflush(stdout);
   4851 }
   4852 
   4853 
   4854 class TestClientData : public v8::Debug::ClientData {
   4855  public:
   4856   TestClientData() {
   4857     constructor_call_counter++;
   4858   }
   4859   virtual ~TestClientData() {
   4860     destructor_call_counter++;
   4861   }
   4862 
   4863   static void ResetCounters() {
   4864     constructor_call_counter = 0;
   4865     destructor_call_counter = 0;
   4866   }
   4867 
   4868   static int constructor_call_counter;
   4869   static int destructor_call_counter;
   4870 };
   4871 
   4872 int TestClientData::constructor_call_counter = 0;
   4873 int TestClientData::destructor_call_counter = 0;
   4874 
   4875 
   4876 // Tests that MessageQueue doesn't destroy client data when expands and
   4877 // does destroy when it dies.
   4878 TEST(MessageQueueExpandAndDestroy) {
   4879   TestClientData::ResetCounters();
   4880   { // Create a scope for the queue.
   4881     CommandMessageQueue queue(1);
   4882     queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
   4883                                   new TestClientData()));
   4884     queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
   4885                                   new TestClientData()));
   4886     queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
   4887                                   new TestClientData()));
   4888     CHECK_EQ(0, TestClientData::destructor_call_counter);
   4889     queue.Get().Dispose();
   4890     CHECK_EQ(1, TestClientData::destructor_call_counter);
   4891     queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
   4892                                   new TestClientData()));
   4893     queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
   4894                                   new TestClientData()));
   4895     queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
   4896                                   new TestClientData()));
   4897     queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
   4898                                   new TestClientData()));
   4899     queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
   4900                                   new TestClientData()));
   4901     CHECK_EQ(1, TestClientData::destructor_call_counter);
   4902     queue.Get().Dispose();
   4903     CHECK_EQ(2, TestClientData::destructor_call_counter);
   4904   }
   4905   // All the client data should be destroyed when the queue is destroyed.
   4906   CHECK_EQ(TestClientData::destructor_call_counter,
   4907            TestClientData::destructor_call_counter);
   4908 }
   4909 
   4910 
   4911 static int handled_client_data_instances_count = 0;
   4912 static void MessageHandlerCountingClientData(
   4913     const v8::Debug::Message& message) {
   4914   if (message.GetClientData() != NULL) {
   4915     handled_client_data_instances_count++;
   4916   }
   4917 }
   4918 
   4919 
   4920 // Tests that all client data passed to the debugger are sent to the handler.
   4921 TEST(SendClientDataToHandler) {
   4922   // Create a V8 environment
   4923   v8::HandleScope scope;
   4924   DebugLocalContext env;
   4925   TestClientData::ResetCounters();
   4926   handled_client_data_instances_count = 0;
   4927   v8::Debug::SetMessageHandler2(MessageHandlerCountingClientData);
   4928   const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;";
   4929   const int kBufferSize = 1000;
   4930   uint16_t buffer[kBufferSize];
   4931   const char* command_1 =
   4932       "{\"seq\":117,"
   4933        "\"type\":\"request\","
   4934        "\"command\":\"evaluate\","
   4935        "\"arguments\":{\"expression\":\"1+2\"}}";
   4936   const char* command_2 =
   4937     "{\"seq\":118,"
   4938      "\"type\":\"request\","
   4939      "\"command\":\"evaluate\","
   4940      "\"arguments\":{\"expression\":\"1+a\"}}";
   4941   const char* command_continue =
   4942     "{\"seq\":106,"
   4943      "\"type\":\"request\","
   4944      "\"command\":\"continue\"}";
   4945 
   4946   v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer),
   4947                          new TestClientData());
   4948   v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer), NULL);
   4949   v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer),
   4950                          new TestClientData());
   4951   v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer),
   4952                          new TestClientData());
   4953   // All the messages will be processed on beforeCompile event.
   4954   CompileRun(source_1);
   4955   v8::Debug::SendCommand(buffer, AsciiToUtf16(command_continue, buffer));
   4956   CHECK_EQ(3, TestClientData::constructor_call_counter);
   4957   CHECK_EQ(TestClientData::constructor_call_counter,
   4958            handled_client_data_instances_count);
   4959   CHECK_EQ(TestClientData::constructor_call_counter,
   4960            TestClientData::destructor_call_counter);
   4961 }
   4962 
   4963 
   4964 /* Test ThreadedDebugging */
   4965 /* This test interrupts a running infinite loop that is
   4966  * occupying the v8 thread by a break command from the
   4967  * debugger thread.  It then changes the value of a
   4968  * global object, to make the loop terminate.
   4969  */
   4970 
   4971 Barriers threaded_debugging_barriers;
   4972 
   4973 class V8Thread : public v8::internal::Thread {
   4974  public:
   4975   explicit V8Thread(v8::internal::Isolate* isolate)
   4976       : Thread(isolate, "V8Thread") { }
   4977   void Run();
   4978 };
   4979 
   4980 class DebuggerThread : public v8::internal::Thread {
   4981  public:
   4982   explicit DebuggerThread(v8::internal::Isolate* isolate)
   4983       : Thread(isolate, "DebuggerThread") { }
   4984   void Run();
   4985 };
   4986 
   4987 
   4988 static v8::Handle<v8::Value> ThreadedAtBarrier1(const v8::Arguments& args) {
   4989   threaded_debugging_barriers.barrier_1.Wait();
   4990   return v8::Undefined();
   4991 }
   4992 
   4993 
   4994 static void ThreadedMessageHandler(const v8::Debug::Message& message) {
   4995   static char print_buffer[1000];
   4996   v8::String::Value json(message.GetJSON());
   4997   Utf16ToAscii(*json, json.length(), print_buffer);
   4998   if (IsBreakEventMessage(print_buffer)) {
   4999     // Check that we are inside the while loop.
   5000     int source_line = GetSourceLineFromBreakEventMessage(print_buffer);
   5001     CHECK(8 <= source_line && source_line <= 13);
   5002     threaded_debugging_barriers.barrier_2.Wait();
   5003   }
   5004 }
   5005 
   5006 
   5007 void V8Thread::Run() {
   5008   const char* source =
   5009       "flag = true;\n"
   5010       "function bar( new_value ) {\n"
   5011       "  flag = new_value;\n"
   5012       "  return \"Return from bar(\" + new_value + \")\";\n"
   5013       "}\n"
   5014       "\n"
   5015       "function foo() {\n"
   5016       "  var x = 1;\n"
   5017       "  while ( flag == true ) {\n"
   5018       "    if ( x == 1 ) {\n"
   5019       "      ThreadedAtBarrier1();\n"
   5020       "    }\n"
   5021       "    x = x + 1;\n"
   5022       "  }\n"
   5023       "}\n"
   5024       "\n"
   5025       "foo();\n";
   5026 
   5027   v8::HandleScope scope;
   5028   DebugLocalContext env;
   5029   v8::Debug::SetMessageHandler2(&ThreadedMessageHandler);
   5030   v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
   5031   global_template->Set(v8::String::New("ThreadedAtBarrier1"),
   5032                        v8::FunctionTemplate::New(ThreadedAtBarrier1));
   5033   v8::Handle<v8::Context> context = v8::Context::New(NULL, global_template);
   5034   v8::Context::Scope context_scope(context);
   5035 
   5036   CompileRun(source);
   5037 }
   5038 
   5039 void DebuggerThread::Run() {
   5040   const int kBufSize = 1000;
   5041   uint16_t buffer[kBufSize];
   5042 
   5043   const char* command_1 = "{\"seq\":102,"
   5044       "\"type\":\"request\","
   5045       "\"command\":\"evaluate\","
   5046       "\"arguments\":{\"expression\":\"bar(false)\"}}";
   5047   const char* command_2 = "{\"seq\":103,"
   5048       "\"type\":\"request\","
   5049       "\"command\":\"continue\"}";
   5050 
   5051   threaded_debugging_barriers.barrier_1.Wait();
   5052   v8::Debug::DebugBreak();
   5053   threaded_debugging_barriers.barrier_2.Wait();
   5054   v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer));
   5055   v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer));
   5056 }
   5057 
   5058 
   5059 TEST(ThreadedDebugging) {
   5060   DebuggerThread debugger_thread(i::Isolate::Current());
   5061   V8Thread v8_thread(i::Isolate::Current());
   5062 
   5063   // Create a V8 environment
   5064   threaded_debugging_barriers.Initialize();
   5065 
   5066   v8_thread.Start();
   5067   debugger_thread.Start();
   5068 
   5069   v8_thread.Join();
   5070   debugger_thread.Join();
   5071 }
   5072 
   5073 /* Test RecursiveBreakpoints */
   5074 /* In this test, the debugger evaluates a function with a breakpoint, after
   5075  * hitting a breakpoint in another function.  We do this with both values
   5076  * of the flag enabling recursive breakpoints, and verify that the second
   5077  * breakpoint is hit when enabled, and missed when disabled.
   5078  */
   5079 
   5080 class BreakpointsV8Thread : public v8::internal::Thread {
   5081  public:
   5082   explicit BreakpointsV8Thread(v8::internal::Isolate* isolate)
   5083       : Thread(isolate, "BreakpointsV8Thread") { }
   5084   void Run();
   5085 };
   5086 
   5087 class BreakpointsDebuggerThread : public v8::internal::Thread {
   5088  public:
   5089   explicit BreakpointsDebuggerThread(v8::internal::Isolate* isolate,
   5090                                      bool global_evaluate)
   5091       : Thread(isolate, "BreakpointsDebuggerThread"),
   5092         global_evaluate_(global_evaluate) {}
   5093   void Run();
   5094 
   5095  private:
   5096   bool global_evaluate_;
   5097 };
   5098 
   5099 
   5100 Barriers* breakpoints_barriers;
   5101 int break_event_breakpoint_id;
   5102 int evaluate_int_result;
   5103 
   5104 static void BreakpointsMessageHandler(const v8::Debug::Message& message) {
   5105   static char print_buffer[1000];
   5106   v8::String::Value json(message.GetJSON());
   5107   Utf16ToAscii(*json, json.length(), print_buffer);
   5108 
   5109   if (IsBreakEventMessage(print_buffer)) {
   5110     break_event_breakpoint_id =
   5111         GetBreakpointIdFromBreakEventMessage(print_buffer);
   5112     breakpoints_barriers->semaphore_1->Signal();
   5113   } else if (IsEvaluateResponseMessage(print_buffer)) {
   5114     evaluate_int_result = GetEvaluateIntResult(print_buffer);
   5115     breakpoints_barriers->semaphore_1->Signal();
   5116   }
   5117 }
   5118 
   5119 
   5120 void BreakpointsV8Thread::Run() {
   5121   const char* source_1 = "var y_global = 3;\n"
   5122     "function cat( new_value ) {\n"
   5123     "  var x = new_value;\n"
   5124     "  y_global = y_global + 4;\n"
   5125     "  x = 3 * x + 1;\n"
   5126     "  y_global = y_global + 5;\n"
   5127     "  return x;\n"
   5128     "}\n"
   5129     "\n"
   5130     "function dog() {\n"
   5131     "  var x = 1;\n"
   5132     "  x = y_global;"
   5133     "  var z = 3;"
   5134     "  x += 100;\n"
   5135     "  return x;\n"
   5136     "}\n"
   5137     "\n";
   5138   const char* source_2 = "cat(17);\n"
   5139     "cat(19);\n";
   5140 
   5141   v8::HandleScope scope;
   5142   DebugLocalContext env;
   5143   v8::Debug::SetMessageHandler2(&BreakpointsMessageHandler);
   5144 
   5145   CompileRun(source_1);
   5146   breakpoints_barriers->barrier_1.Wait();
   5147   breakpoints_barriers->barrier_2.Wait();
   5148   CompileRun(source_2);
   5149 }
   5150 
   5151 
   5152 void BreakpointsDebuggerThread::Run() {
   5153   const int kBufSize = 1000;
   5154   uint16_t buffer[kBufSize];
   5155 
   5156   const char* command_1 = "{\"seq\":101,"
   5157       "\"type\":\"request\","
   5158       "\"command\":\"setbreakpoint\","
   5159       "\"arguments\":{\"type\":\"function\",\"target\":\"cat\",\"line\":3}}";
   5160   const char* command_2 = "{\"seq\":102,"
   5161       "\"type\":\"request\","
   5162       "\"command\":\"setbreakpoint\","
   5163       "\"arguments\":{\"type\":\"function\",\"target\":\"dog\",\"line\":3}}";
   5164   const char* command_3;
   5165   if (this->global_evaluate_) {
   5166     command_3 = "{\"seq\":103,"
   5167         "\"type\":\"request\","
   5168         "\"command\":\"evaluate\","
   5169         "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":false,"
   5170         "\"global\":true}}";
   5171   } else {
   5172     command_3 = "{\"seq\":103,"
   5173         "\"type\":\"request\","
   5174         "\"command\":\"evaluate\","
   5175         "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":false}}";
   5176   }
   5177   const char* command_4;
   5178   if (this->global_evaluate_) {
   5179     command_4 = "{\"seq\":104,"
   5180         "\"type\":\"request\","
   5181         "\"command\":\"evaluate\","
   5182         "\"arguments\":{\"expression\":\"100 + 8\",\"disable_break\":true,"
   5183         "\"global\":true}}";
   5184   } else {
   5185     command_4 = "{\"seq\":104,"
   5186         "\"type\":\"request\","
   5187         "\"command\":\"evaluate\","
   5188         "\"arguments\":{\"expression\":\"x + 1\",\"disable_break\":true}}";
   5189   }
   5190   const char* command_5 = "{\"seq\":105,"
   5191       "\"type\":\"request\","
   5192       "\"command\":\"continue\"}";
   5193   const char* command_6 = "{\"seq\":106,"
   5194       "\"type\":\"request\","
   5195       "\"command\":\"continue\"}";
   5196   const char* command_7;
   5197   if (this->global_evaluate_) {
   5198     command_7 = "{\"seq\":107,"
   5199         "\"type\":\"request\","
   5200         "\"command\":\"evaluate\","
   5201         "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":true,"
   5202         "\"global\":true}}";
   5203   } else {
   5204     command_7 = "{\"seq\":107,"
   5205         "\"type\":\"request\","
   5206         "\"command\":\"evaluate\","
   5207         "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":true}}";
   5208   }
   5209   const char* command_8 = "{\"seq\":108,"
   5210       "\"type\":\"request\","
   5211       "\"command\":\"continue\"}";
   5212 
   5213 
   5214   // v8 thread initializes, runs source_1
   5215   breakpoints_barriers->barrier_1.Wait();
   5216   // 1:Set breakpoint in cat() (will get id 1).
   5217   v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer));
   5218   // 2:Set breakpoint in dog() (will get id 2).
   5219   v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer));
   5220   breakpoints_barriers->barrier_2.Wait();
   5221   // V8 thread starts compiling source_2.
   5222   // Automatic break happens, to run queued commands
   5223   // breakpoints_barriers->semaphore_1->Wait();
   5224   // Commands 1 through 3 run, thread continues.
   5225   // v8 thread runs source_2 to breakpoint in cat().
   5226   // message callback receives break event.
   5227   breakpoints_barriers->semaphore_1->Wait();
   5228   // Must have hit breakpoint #1.
   5229   CHECK_EQ(1, break_event_breakpoint_id);
   5230   // 4:Evaluate dog() (which has a breakpoint).
   5231   v8::Debug::SendCommand(buffer, AsciiToUtf16(command_3, buffer));
   5232   // V8 thread hits breakpoint in dog().
   5233   breakpoints_barriers->semaphore_1->Wait();  // wait for break event
   5234   // Must have hit breakpoint #2.
   5235   CHECK_EQ(2, break_event_breakpoint_id);
   5236   // 5:Evaluate (x + 1).
   5237   v8::Debug::SendCommand(buffer, AsciiToUtf16(command_4, buffer));
   5238   // Evaluate (x + 1) finishes.
   5239   breakpoints_barriers->semaphore_1->Wait();
   5240   // Must have result 108.
   5241   CHECK_EQ(108, evaluate_int_result);
   5242   // 6:Continue evaluation of dog().
   5243   v8::Debug::SendCommand(buffer, AsciiToUtf16(command_5, buffer));
   5244   // Evaluate dog() finishes.
   5245   breakpoints_barriers->semaphore_1->Wait();
   5246   // Must have result 107.
   5247   CHECK_EQ(107, evaluate_int_result);
   5248   // 7:Continue evaluation of source_2, finish cat(17), hit breakpoint
   5249   // in cat(19).
   5250   v8::Debug::SendCommand(buffer, AsciiToUtf16(command_6, buffer));
   5251   // Message callback gets break event.
   5252   breakpoints_barriers->semaphore_1->Wait();  // wait for break event
   5253   // Must have hit breakpoint #1.
   5254   CHECK_EQ(1, break_event_breakpoint_id);
   5255   // 8: Evaluate dog() with breaks disabled.
   5256   v8::Debug::SendCommand(buffer, AsciiToUtf16(command_7, buffer));
   5257   // Evaluate dog() finishes.
   5258   breakpoints_barriers->semaphore_1->Wait();
   5259   // Must have result 116.
   5260   CHECK_EQ(116, evaluate_int_result);
   5261   // 9: Continue evaluation of source2, reach end.
   5262   v8::Debug::SendCommand(buffer, AsciiToUtf16(command_8, buffer));
   5263 }
   5264 
   5265 void TestRecursiveBreakpointsGeneric(bool global_evaluate) {
   5266   i::FLAG_debugger_auto_break = true;
   5267 
   5268   BreakpointsDebuggerThread breakpoints_debugger_thread(i::Isolate::Current(),
   5269       global_evaluate);
   5270   BreakpointsV8Thread breakpoints_v8_thread(i::Isolate::Current());
   5271 
   5272   // Create a V8 environment
   5273   Barriers stack_allocated_breakpoints_barriers;
   5274   stack_allocated_breakpoints_barriers.Initialize();
   5275   breakpoints_barriers = &stack_allocated_breakpoints_barriers;
   5276 
   5277   breakpoints_v8_thread.Start();
   5278   breakpoints_debugger_thread.Start();
   5279 
   5280   breakpoints_v8_thread.Join();
   5281   breakpoints_debugger_thread.Join();
   5282 }
   5283 
   5284 TEST(RecursiveBreakpoints) {
   5285   TestRecursiveBreakpointsGeneric(false);
   5286 }
   5287 
   5288 TEST(RecursiveBreakpointsGlobal) {
   5289   TestRecursiveBreakpointsGeneric(true);
   5290 }
   5291 
   5292 
   5293 static void DummyDebugEventListener(v8::DebugEvent event,
   5294                                     v8::Handle<v8::Object> exec_state,
   5295                                     v8::Handle<v8::Object> event_data,
   5296                                     v8::Handle<v8::Value> data) {
   5297 }
   5298 
   5299 
   5300 TEST(SetDebugEventListenerOnUninitializedVM) {
   5301   v8::Debug::SetDebugEventListener(DummyDebugEventListener);
   5302 }
   5303 
   5304 
   5305 static void DummyMessageHandler(const v8::Debug::Message& message) {
   5306 }
   5307 
   5308 
   5309 TEST(SetMessageHandlerOnUninitializedVM) {
   5310   v8::Debug::SetMessageHandler2(DummyMessageHandler);
   5311 }
   5312 
   5313 
   5314 TEST(DebugBreakOnUninitializedVM) {
   5315   v8::Debug::DebugBreak();
   5316 }
   5317 
   5318 
   5319 TEST(SendCommandToUninitializedVM) {
   5320   const char* dummy_command = "{}";
   5321   uint16_t dummy_buffer[80];
   5322   int dummy_length = AsciiToUtf16(dummy_command, dummy_buffer);
   5323   v8::Debug::SendCommand(dummy_buffer, dummy_length);
   5324 }
   5325 
   5326 
   5327 // Source for a JavaScript function which returns the data parameter of a
   5328 // function called in the context of the debugger. If no data parameter is
   5329 // passed it throws an exception.
   5330 static const char* debugger_call_with_data_source =
   5331     "function debugger_call_with_data(exec_state, data) {"
   5332     "  if (data) return data;"
   5333     "  throw 'No data!'"
   5334     "}";
   5335 v8::Handle<v8::Function> debugger_call_with_data;
   5336 
   5337 
   5338 // Source for a JavaScript function which returns the data parameter of a
   5339 // function called in the context of the debugger. If no data parameter is
   5340 // passed it throws an exception.
   5341 static const char* debugger_call_with_closure_source =
   5342     "var x = 3;"
   5343     "(function (exec_state) {"
   5344     "  if (exec_state.y) return x - 1;"
   5345     "  exec_state.y = x;"
   5346     "  return exec_state.y"
   5347     "})";
   5348 v8::Handle<v8::Function> debugger_call_with_closure;
   5349 
   5350 // Function to retrieve the number of JavaScript frames by calling a JavaScript
   5351 // in the debugger.
   5352 static v8::Handle<v8::Value> CheckFrameCount(const v8::Arguments& args) {
   5353   CHECK(v8::Debug::Call(frame_count)->IsNumber());
   5354   CHECK_EQ(args[0]->Int32Value(),
   5355            v8::Debug::Call(frame_count)->Int32Value());
   5356   return v8::Undefined();
   5357 }
   5358 
   5359 
   5360 // Function to retrieve the source line of the top JavaScript frame by calling a
   5361 // JavaScript function in the debugger.
   5362 static v8::Handle<v8::Value> CheckSourceLine(const v8::Arguments& args) {
   5363   CHECK(v8::Debug::Call(frame_source_line)->IsNumber());
   5364   CHECK_EQ(args[0]->Int32Value(),
   5365            v8::Debug::Call(frame_source_line)->Int32Value());
   5366   return v8::Undefined();
   5367 }
   5368 
   5369 
   5370 // Function to test passing an additional parameter to a JavaScript function
   5371 // called in the debugger. It also tests that functions called in the debugger
   5372 // can throw exceptions.
   5373 static v8::Handle<v8::Value> CheckDataParameter(const v8::Arguments& args) {
   5374   v8::Handle<v8::String> data = v8::String::New("Test");
   5375   CHECK(v8::Debug::Call(debugger_call_with_data, data)->IsString());
   5376 
   5377   CHECK(v8::Debug::Call(debugger_call_with_data).IsEmpty());
   5378   CHECK(v8::Debug::Call(debugger_call_with_data).IsEmpty());
   5379 
   5380   v8::TryCatch catcher;
   5381   v8::Debug::Call(debugger_call_with_data);
   5382   CHECK(catcher.HasCaught());
   5383   CHECK(catcher.Exception()->IsString());
   5384 
   5385   return v8::Undefined();
   5386 }
   5387 
   5388 
   5389 // Function to test using a JavaScript with closure in the debugger.
   5390 static v8::Handle<v8::Value> CheckClosure(const v8::Arguments& args) {
   5391   CHECK(v8::Debug::Call(debugger_call_with_closure)->IsNumber());
   5392   CHECK_EQ(3, v8::Debug::Call(debugger_call_with_closure)->Int32Value());
   5393   return v8::Undefined();
   5394 }
   5395 
   5396 
   5397 // Test functions called through the debugger.
   5398 TEST(CallFunctionInDebugger) {
   5399   // Create and enter a context with the functions CheckFrameCount,
   5400   // CheckSourceLine and CheckDataParameter installed.
   5401   v8::HandleScope scope;
   5402   v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
   5403   global_template->Set(v8::String::New("CheckFrameCount"),
   5404                        v8::FunctionTemplate::New(CheckFrameCount));
   5405   global_template->Set(v8::String::New("CheckSourceLine"),
   5406                        v8::FunctionTemplate::New(CheckSourceLine));
   5407   global_template->Set(v8::String::New("CheckDataParameter"),
   5408                        v8::FunctionTemplate::New(CheckDataParameter));
   5409   global_template->Set(v8::String::New("CheckClosure"),
   5410                        v8::FunctionTemplate::New(CheckClosure));
   5411   v8::Handle<v8::Context> context = v8::Context::New(NULL, global_template);
   5412   v8::Context::Scope context_scope(context);
   5413 
   5414   // Compile a function for checking the number of JavaScript frames.
   5415   v8::Script::Compile(v8::String::New(frame_count_source))->Run();
   5416   frame_count = v8::Local<v8::Function>::Cast(
   5417       context->Global()->Get(v8::String::New("frame_count")));
   5418 
   5419   // Compile a function for returning the source line for the top frame.
   5420   v8::Script::Compile(v8::String::New(frame_source_line_source))->Run();
   5421   frame_source_line = v8::Local<v8::Function>::Cast(
   5422       context->Global()->Get(v8::String::New("frame_source_line")));
   5423 
   5424   // Compile a function returning the data parameter.
   5425   v8::Script::Compile(v8::String::New(debugger_call_with_data_source))->Run();
   5426   debugger_call_with_data = v8::Local<v8::Function>::Cast(
   5427       context->Global()->Get(v8::String::New("debugger_call_with_data")));
   5428 
   5429   // Compile a function capturing closure.
   5430   debugger_call_with_closure = v8::Local<v8::Function>::Cast(
   5431       v8::Script::Compile(
   5432           v8::String::New(debugger_call_with_closure_source))->Run());
   5433 
   5434   // Calling a function through the debugger returns 0 frames if there are
   5435   // no JavaScript frames.
   5436   CHECK_EQ(v8::Integer::New(0), v8::Debug::Call(frame_count));
   5437 
   5438   // Test that the number of frames can be retrieved.
   5439   v8::Script::Compile(v8::String::New("CheckFrameCount(1)"))->Run();
   5440   v8::Script::Compile(v8::String::New("function f() {"
   5441                                       "  CheckFrameCount(2);"
   5442                                       "}; f()"))->Run();
   5443 
   5444   // Test that the source line can be retrieved.
   5445   v8::Script::Compile(v8::String::New("CheckSourceLine(0)"))->Run();
   5446   v8::Script::Compile(v8::String::New("function f() {\n"
   5447                                       "  CheckSourceLine(1)\n"
   5448                                       "  CheckSourceLine(2)\n"
   5449                                       "  CheckSourceLine(3)\n"
   5450                                       "}; f()"))->Run();
   5451 
   5452   // Test that a parameter can be passed to a function called in the debugger.
   5453   v8::Script::Compile(v8::String::New("CheckDataParameter()"))->Run();
   5454 
   5455   // Test that a function with closure can be run in the debugger.
   5456   v8::Script::Compile(v8::String::New("CheckClosure()"))->Run();
   5457 
   5458 
   5459   // Test that the source line is correct when there is a line offset.
   5460   v8::ScriptOrigin origin(v8::String::New("test"),
   5461                           v8::Integer::New(7));
   5462   v8::Script::Compile(v8::String::New("CheckSourceLine(7)"), &origin)->Run();
   5463   v8::Script::Compile(v8::String::New("function f() {\n"
   5464                                       "  CheckSourceLine(8)\n"
   5465                                       "  CheckSourceLine(9)\n"
   5466                                       "  CheckSourceLine(10)\n"
   5467                                       "}; f()"), &origin)->Run();
   5468 }
   5469 
   5470 
   5471 // Debugger message handler which counts the number of breaks.
   5472 static void SendContinueCommand();
   5473 static void MessageHandlerBreakPointHitCount(
   5474     const v8::Debug::Message& message) {
   5475   if (message.IsEvent() && message.GetEvent() == v8::Break) {
   5476     // Count the number of breaks.
   5477     break_point_hit_count++;
   5478 
   5479     SendContinueCommand();
   5480   }
   5481 }
   5482 
   5483 
   5484 // Test that clearing the debug event listener actually clears all break points
   5485 // and related information.
   5486 TEST(DebuggerUnload) {
   5487   DebugLocalContext env;
   5488 
   5489   // Check debugger is unloaded before it is used.
   5490   CheckDebuggerUnloaded();
   5491 
   5492   // Set a debug event listener.
   5493   break_point_hit_count = 0;
   5494   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
   5495                                    v8::Undefined());
   5496   {
   5497     v8::HandleScope scope;
   5498     // Create a couple of functions for the test.
   5499     v8::Local<v8::Function> foo =
   5500         CompileFunction(&env, "function foo(){x=1}", "foo");
   5501     v8::Local<v8::Function> bar =
   5502         CompileFunction(&env, "function bar(){y=2}", "bar");
   5503 
   5504     // Set some break points.
   5505     SetBreakPoint(foo, 0);
   5506     SetBreakPoint(foo, 4);
   5507     SetBreakPoint(bar, 0);
   5508     SetBreakPoint(bar, 4);
   5509 
   5510     // Make sure that the break points are there.
   5511     break_point_hit_count = 0;
   5512     foo->Call(env->Global(), 0, NULL);
   5513     CHECK_EQ(2, break_point_hit_count);
   5514     bar->Call(env->Global(), 0, NULL);
   5515     CHECK_EQ(4, break_point_hit_count);
   5516   }
   5517 
   5518   // Remove the debug event listener without clearing breakpoints. Do this
   5519   // outside a handle scope.
   5520   v8::Debug::SetDebugEventListener(NULL);
   5521   CheckDebuggerUnloaded(true);
   5522 
   5523   // Now set a debug message handler.
   5524   break_point_hit_count = 0;
   5525   v8::Debug::SetMessageHandler2(MessageHandlerBreakPointHitCount);
   5526   {
   5527     v8::HandleScope scope;
   5528 
   5529     // Get the test functions again.
   5530     v8::Local<v8::Function> foo =
   5531       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
   5532     v8::Local<v8::Function> bar =
   5533       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
   5534 
   5535     foo->Call(env->Global(), 0, NULL);
   5536     CHECK_EQ(0, break_point_hit_count);
   5537 
   5538     // Set break points and run again.
   5539     SetBreakPoint(foo, 0);
   5540     SetBreakPoint(foo, 4);
   5541     foo->Call(env->Global(), 0, NULL);
   5542     CHECK_EQ(2, break_point_hit_count);
   5543   }
   5544 
   5545   // Remove the debug message handler without clearing breakpoints. Do this
   5546   // outside a handle scope.
   5547   v8::Debug::SetMessageHandler2(NULL);
   5548   CheckDebuggerUnloaded(true);
   5549 }
   5550 
   5551 
   5552 // Sends continue command to the debugger.
   5553 static void SendContinueCommand() {
   5554   const int kBufferSize = 1000;
   5555   uint16_t buffer[kBufferSize];
   5556   const char* command_continue =
   5557     "{\"seq\":0,"
   5558      "\"type\":\"request\","
   5559      "\"command\":\"continue\"}";
   5560 
   5561   v8::Debug::SendCommand(buffer, AsciiToUtf16(command_continue, buffer));
   5562 }
   5563 
   5564 
   5565 // Debugger message handler which counts the number of times it is called.
   5566 static int message_handler_hit_count = 0;
   5567 static void MessageHandlerHitCount(const v8::Debug::Message& message) {
   5568   message_handler_hit_count++;
   5569 
   5570   static char print_buffer[1000];
   5571   v8::String::Value json(message.GetJSON());
   5572   Utf16ToAscii(*json, json.length(), print_buffer);
   5573   if (IsExceptionEventMessage(print_buffer)) {
   5574     // Send a continue command for exception events.
   5575     SendContinueCommand();
   5576   }
   5577 }
   5578 
   5579 
   5580 // Test clearing the debug message handler.
   5581 TEST(DebuggerClearMessageHandler) {
   5582   v8::HandleScope scope;
   5583   DebugLocalContext env;
   5584 
   5585   // Check debugger is unloaded before it is used.
   5586   CheckDebuggerUnloaded();
   5587 
   5588   // Set a debug message handler.
   5589   v8::Debug::SetMessageHandler2(MessageHandlerHitCount);
   5590 
   5591   // Run code to throw a unhandled exception. This should end up in the message
   5592   // handler.
   5593   CompileRun("throw 1");
   5594 
   5595   // The message handler should be called.
   5596   CHECK_GT(message_handler_hit_count, 0);
   5597 
   5598   // Clear debug message handler.
   5599   message_handler_hit_count = 0;
   5600   v8::Debug::SetMessageHandler(NULL);
   5601 
   5602   // Run code to throw a unhandled exception. This should end up in the message
   5603   // handler.
   5604   CompileRun("throw 1");
   5605 
   5606   // The message handler should not be called more.
   5607   CHECK_EQ(0, message_handler_hit_count);
   5608 
   5609   CheckDebuggerUnloaded(true);
   5610 }
   5611 
   5612 
   5613 // Debugger message handler which clears the message handler while active.
   5614 static void MessageHandlerClearingMessageHandler(
   5615     const v8::Debug::Message& message) {
   5616   message_handler_hit_count++;
   5617 
   5618   // Clear debug message handler.
   5619   v8::Debug::SetMessageHandler(NULL);
   5620 }
   5621 
   5622 
   5623 // Test clearing the debug message handler while processing a debug event.
   5624 TEST(DebuggerClearMessageHandlerWhileActive) {
   5625   v8::HandleScope scope;
   5626   DebugLocalContext env;
   5627 
   5628   // Check debugger is unloaded before it is used.
   5629   CheckDebuggerUnloaded();
   5630 
   5631   // Set a debug message handler.
   5632   v8::Debug::SetMessageHandler2(MessageHandlerClearingMessageHandler);
   5633 
   5634   // Run code to throw a unhandled exception. This should end up in the message
   5635   // handler.
   5636   CompileRun("throw 1");
   5637 
   5638   // The message handler should be called.
   5639   CHECK_EQ(1, message_handler_hit_count);
   5640 
   5641   CheckDebuggerUnloaded(true);
   5642 }
   5643 
   5644 
   5645 /* Test DebuggerHostDispatch */
   5646 /* In this test, the debugger waits for a command on a breakpoint
   5647  * and is dispatching host commands while in the infinite loop.
   5648  */
   5649 
   5650 class HostDispatchV8Thread : public v8::internal::Thread {
   5651  public:
   5652   explicit HostDispatchV8Thread(v8::internal::Isolate* isolate)
   5653       : Thread(isolate, "HostDispatchV8Thread") { }
   5654   void Run();
   5655 };
   5656 
   5657 class HostDispatchDebuggerThread : public v8::internal::Thread {
   5658  public:
   5659   explicit HostDispatchDebuggerThread(v8::internal::Isolate* isolate)
   5660       : Thread(isolate, "HostDispatchDebuggerThread") { }
   5661   void Run();
   5662 };
   5663 
   5664 Barriers* host_dispatch_barriers;
   5665 
   5666 static void HostDispatchMessageHandler(const v8::Debug::Message& message) {
   5667   static char print_buffer[1000];
   5668   v8::String::Value json(message.GetJSON());
   5669   Utf16ToAscii(*json, json.length(), print_buffer);
   5670 }
   5671 
   5672 
   5673 static void HostDispatchDispatchHandler() {
   5674   host_dispatch_barriers->semaphore_1->Signal();
   5675 }
   5676 
   5677 
   5678 void HostDispatchV8Thread::Run() {
   5679   const char* source_1 = "var y_global = 3;\n"
   5680     "function cat( new_value ) {\n"
   5681     "  var x = new_value;\n"
   5682     "  y_global = 4;\n"
   5683     "  x = 3 * x + 1;\n"
   5684     "  y_global = 5;\n"
   5685     "  return x;\n"
   5686     "}\n"
   5687     "\n";
   5688   const char* source_2 = "cat(17);\n";
   5689 
   5690   v8::HandleScope scope;
   5691   DebugLocalContext env;
   5692 
   5693   // Setup message and host dispatch handlers.
   5694   v8::Debug::SetMessageHandler2(HostDispatchMessageHandler);
   5695   v8::Debug::SetHostDispatchHandler(HostDispatchDispatchHandler, 10 /* ms */);
   5696 
   5697   CompileRun(source_1);
   5698   host_dispatch_barriers->barrier_1.Wait();
   5699   host_dispatch_barriers->barrier_2.Wait();
   5700   CompileRun(source_2);
   5701 }
   5702 
   5703 
   5704 void HostDispatchDebuggerThread::Run() {
   5705   const int kBufSize = 1000;
   5706   uint16_t buffer[kBufSize];
   5707 
   5708   const char* command_1 = "{\"seq\":101,"
   5709       "\"type\":\"request\","
   5710       "\"command\":\"setbreakpoint\","
   5711       "\"arguments\":{\"type\":\"function\",\"target\":\"cat\",\"line\":3}}";
   5712   const char* command_2 = "{\"seq\":102,"
   5713       "\"type\":\"request\","
   5714       "\"command\":\"continue\"}";
   5715 
   5716   // v8 thread initializes, runs source_1
   5717   host_dispatch_barriers->barrier_1.Wait();
   5718   // 1: Set breakpoint in cat().
   5719   v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer));
   5720 
   5721   host_dispatch_barriers->barrier_2.Wait();
   5722   // v8 thread starts compiling source_2.
   5723   // Break happens, to run queued commands and host dispatches.
   5724   // Wait for host dispatch to be processed.
   5725   host_dispatch_barriers->semaphore_1->Wait();
   5726   // 2: Continue evaluation
   5727   v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer));
   5728 }
   5729 
   5730 
   5731 TEST(DebuggerHostDispatch) {
   5732   HostDispatchDebuggerThread host_dispatch_debugger_thread(
   5733       i::Isolate::Current());
   5734   HostDispatchV8Thread host_dispatch_v8_thread(i::Isolate::Current());
   5735   i::FLAG_debugger_auto_break = true;
   5736 
   5737   // Create a V8 environment
   5738   Barriers stack_allocated_host_dispatch_barriers;
   5739   stack_allocated_host_dispatch_barriers.Initialize();
   5740   host_dispatch_barriers = &stack_allocated_host_dispatch_barriers;
   5741 
   5742   host_dispatch_v8_thread.Start();
   5743   host_dispatch_debugger_thread.Start();
   5744 
   5745   host_dispatch_v8_thread.Join();
   5746   host_dispatch_debugger_thread.Join();
   5747 }
   5748 
   5749 
   5750 /* Test DebugMessageDispatch */
   5751 /* In this test, the V8 thread waits for a message from the debug thread.
   5752  * The DebugMessageDispatchHandler is executed from the debugger thread
   5753  * which signals the V8 thread to wake up.
   5754  */
   5755 
   5756 class DebugMessageDispatchV8Thread : public v8::internal::Thread {
   5757  public:
   5758   explicit DebugMessageDispatchV8Thread(v8::internal::Isolate* isolate)
   5759       : Thread(isolate, "DebugMessageDispatchV8Thread") { }
   5760   void Run();
   5761 };
   5762 
   5763 class DebugMessageDispatchDebuggerThread : public v8::internal::Thread {
   5764  public:
   5765   explicit DebugMessageDispatchDebuggerThread(v8::internal::Isolate* isolate)
   5766       : Thread(isolate, "DebugMessageDispatchDebuggerThread") { }
   5767   void Run();
   5768 };
   5769 
   5770 Barriers* debug_message_dispatch_barriers;
   5771 
   5772 
   5773 static void DebugMessageHandler() {
   5774   debug_message_dispatch_barriers->semaphore_1->Signal();
   5775 }
   5776 
   5777 
   5778 void DebugMessageDispatchV8Thread::Run() {
   5779   v8::HandleScope scope;
   5780   DebugLocalContext env;
   5781 
   5782   // Setup debug message dispatch handler.
   5783   v8::Debug::SetDebugMessageDispatchHandler(DebugMessageHandler);
   5784 
   5785   CompileRun("var y = 1 + 2;\n");
   5786   debug_message_dispatch_barriers->barrier_1.Wait();
   5787   debug_message_dispatch_barriers->semaphore_1->Wait();
   5788   debug_message_dispatch_barriers->barrier_2.Wait();
   5789 }
   5790 
   5791 
   5792 void DebugMessageDispatchDebuggerThread::Run() {
   5793   debug_message_dispatch_barriers->barrier_1.Wait();
   5794   SendContinueCommand();
   5795   debug_message_dispatch_barriers->barrier_2.Wait();
   5796 }
   5797 
   5798 
   5799 TEST(DebuggerDebugMessageDispatch) {
   5800   DebugMessageDispatchDebuggerThread debug_message_dispatch_debugger_thread(
   5801       i::Isolate::Current());
   5802   DebugMessageDispatchV8Thread debug_message_dispatch_v8_thread(
   5803       i::Isolate::Current());
   5804 
   5805   i::FLAG_debugger_auto_break = true;
   5806 
   5807   // Create a V8 environment
   5808   Barriers stack_allocated_debug_message_dispatch_barriers;
   5809   stack_allocated_debug_message_dispatch_barriers.Initialize();
   5810   debug_message_dispatch_barriers =
   5811       &stack_allocated_debug_message_dispatch_barriers;
   5812 
   5813   debug_message_dispatch_v8_thread.Start();
   5814   debug_message_dispatch_debugger_thread.Start();
   5815 
   5816   debug_message_dispatch_v8_thread.Join();
   5817   debug_message_dispatch_debugger_thread.Join();
   5818 }
   5819 
   5820 
   5821 TEST(DebuggerAgent) {
   5822   v8::V8::Initialize();
   5823   i::Debugger* debugger = i::Isolate::Current()->debugger();
   5824   // Make sure these ports is not used by other tests to allow tests to run in
   5825   // parallel.
   5826   const int kPort1 = 5858;
   5827   const int kPort2 = 5857;
   5828   const int kPort3 = 5856;
   5829 
   5830   // Make a string with the port2 number.
   5831   const int kPortBufferLen = 6;
   5832   char port2_str[kPortBufferLen];
   5833   OS::SNPrintF(i::Vector<char>(port2_str, kPortBufferLen), "%d", kPort2);
   5834 
   5835   bool ok;
   5836 
   5837   // Initialize the socket library.
   5838   i::Socket::Setup();
   5839 
   5840   // Test starting and stopping the agent without any client connection.
   5841   debugger->StartAgent("test", kPort1);
   5842   debugger->StopAgent();
   5843 
   5844   // Test starting the agent, connecting a client and shutting down the agent
   5845   // with the client connected.
   5846   ok = debugger->StartAgent("test", kPort2);
   5847   CHECK(ok);
   5848   debugger->WaitForAgent();
   5849   i::Socket* client = i::OS::CreateSocket();
   5850   ok = client->Connect("localhost", port2_str);
   5851   CHECK(ok);
   5852   debugger->StopAgent();
   5853   delete client;
   5854 
   5855   // Test starting and stopping the agent with the required port already
   5856   // occoupied.
   5857   i::Socket* server = i::OS::CreateSocket();
   5858   server->Bind(kPort3);
   5859 
   5860   debugger->StartAgent("test", kPort3);
   5861   debugger->StopAgent();
   5862 
   5863   delete server;
   5864 }
   5865 
   5866 
   5867 class DebuggerAgentProtocolServerThread : public i::Thread {
   5868  public:
   5869   explicit DebuggerAgentProtocolServerThread(i::Isolate* isolate, int port)
   5870       : Thread(isolate, "DebuggerAgentProtocolServerThread"),
   5871         port_(port),
   5872         server_(NULL),
   5873         client_(NULL),
   5874         listening_(OS::CreateSemaphore(0)) {
   5875   }
   5876   ~DebuggerAgentProtocolServerThread() {
   5877     // Close both sockets.
   5878     delete client_;
   5879     delete server_;
   5880     delete listening_;
   5881   }
   5882 
   5883   void Run();
   5884   void WaitForListening() { listening_->Wait(); }
   5885   char* body() { return *body_; }
   5886 
   5887  private:
   5888   int port_;
   5889   i::SmartPointer<char> body_;
   5890   i::Socket* server_;  // Server socket used for bind/accept.
   5891   i::Socket* client_;  // Single client connection used by the test.
   5892   i::Semaphore* listening_;  // Signalled when the server is in listen mode.
   5893 };
   5894 
   5895 
   5896 void DebuggerAgentProtocolServerThread::Run() {
   5897   bool ok;
   5898 
   5899   // Create the server socket and bind it to the requested port.
   5900   server_ = i::OS::CreateSocket();
   5901   CHECK(server_ != NULL);
   5902   ok = server_->Bind(port_);
   5903   CHECK(ok);
   5904 
   5905   // Listen for new connections.
   5906   ok = server_->Listen(1);
   5907   CHECK(ok);
   5908   listening_->Signal();
   5909 
   5910   // Accept a connection.
   5911   client_ = server_->Accept();
   5912   CHECK(client_ != NULL);
   5913 
   5914   // Receive a debugger agent protocol message.
   5915   i::DebuggerAgentUtil::ReceiveMessage(client_);
   5916 }
   5917 
   5918 
   5919 TEST(DebuggerAgentProtocolOverflowHeader) {
   5920   // Make sure this port is not used by other tests to allow tests to run in
   5921   // parallel.
   5922   const int kPort = 5860;
   5923   static const char* kLocalhost = "localhost";
   5924 
   5925   // Make a string with the port number.
   5926   const int kPortBufferLen = 6;
   5927   char port_str[kPortBufferLen];
   5928   OS::SNPrintF(i::Vector<char>(port_str, kPortBufferLen), "%d", kPort);
   5929 
   5930   // Initialize the socket library.
   5931   i::Socket::Setup();
   5932 
   5933   // Create a socket server to receive a debugger agent message.
   5934   DebuggerAgentProtocolServerThread* server =
   5935       new DebuggerAgentProtocolServerThread(i::Isolate::Current(), kPort);
   5936   server->Start();
   5937   server->WaitForListening();
   5938 
   5939   // Connect.
   5940   i::Socket* client = i::OS::CreateSocket();
   5941   CHECK(client != NULL);
   5942   bool ok = client->Connect(kLocalhost, port_str);
   5943   CHECK(ok);
   5944 
   5945   // Send headers which overflow the receive buffer.
   5946   static const int kBufferSize = 1000;
   5947   char buffer[kBufferSize];
   5948 
   5949   // Long key and short value: XXXX....XXXX:0\r\n.
   5950   for (int i = 0; i < kBufferSize - 4; i++) {
   5951     buffer[i] = 'X';
   5952   }
   5953   buffer[kBufferSize - 4] = ':';
   5954   buffer[kBufferSize - 3] = '0';
   5955   buffer[kBufferSize - 2] = '\r';
   5956   buffer[kBufferSize - 1] = '\n';
   5957   client->Send(buffer, kBufferSize);
   5958 
   5959   // Short key and long value: X:XXXX....XXXX\r\n.
   5960   buffer[0] = 'X';
   5961   buffer[1] = ':';
   5962   for (int i = 2; i < kBufferSize - 2; i++) {
   5963     buffer[i] = 'X';
   5964   }
   5965   buffer[kBufferSize - 2] = '\r';
   5966   buffer[kBufferSize - 1] = '\n';
   5967   client->Send(buffer, kBufferSize);
   5968 
   5969   // Add empty body to request.
   5970   const char* content_length_zero_header = "Content-Length:0\r\n";
   5971   client->Send(content_length_zero_header,
   5972                StrLength(content_length_zero_header));
   5973   client->Send("\r\n", 2);
   5974 
   5975   // Wait until data is received.
   5976   server->Join();
   5977 
   5978   // Check for empty body.
   5979   CHECK(server->body() == NULL);
   5980 
   5981   // Close the client before the server to avoid TIME_WAIT issues.
   5982   client->Shutdown();
   5983   delete client;
   5984   delete server;
   5985 }
   5986 
   5987 
   5988 // Test for issue http://code.google.com/p/v8/issues/detail?id=289.
   5989 // Make sure that DebugGetLoadedScripts doesn't return scripts
   5990 // with disposed external source.
   5991 class EmptyExternalStringResource : public v8::String::ExternalStringResource {
   5992  public:
   5993   EmptyExternalStringResource() { empty_[0] = 0; }
   5994   virtual ~EmptyExternalStringResource() {}
   5995   virtual size_t length() const { return empty_.length(); }
   5996   virtual const uint16_t* data() const { return empty_.start(); }
   5997  private:
   5998   ::v8::internal::EmbeddedVector<uint16_t, 1> empty_;
   5999 };
   6000 
   6001 
   6002 TEST(DebugGetLoadedScripts) {
   6003   v8::HandleScope scope;
   6004   DebugLocalContext env;
   6005   env.ExposeDebug();
   6006 
   6007   EmptyExternalStringResource source_ext_str;
   6008   v8::Local<v8::String> source = v8::String::NewExternal(&source_ext_str);
   6009   v8::Handle<v8::Script> evil_script = v8::Script::Compile(source);
   6010   Handle<i::ExternalTwoByteString> i_source(
   6011       i::ExternalTwoByteString::cast(*v8::Utils::OpenHandle(*source)));
   6012   // This situation can happen if source was an external string disposed
   6013   // by its owner.
   6014   i_source->set_resource(0);
   6015 
   6016   bool allow_natives_syntax = i::FLAG_allow_natives_syntax;
   6017   i::FLAG_allow_natives_syntax = true;
   6018   CompileRun(
   6019       "var scripts = %DebugGetLoadedScripts();"
   6020       "var count = scripts.length;"
   6021       "for (var i = 0; i < count; ++i) {"
   6022       "  scripts[i].line_ends;"
   6023       "}");
   6024   // Must not crash while accessing line_ends.
   6025   i::FLAG_allow_natives_syntax = allow_natives_syntax;
   6026 
   6027   // Some scripts are retrieved - at least the number of native scripts.
   6028   CHECK_GT((*env)->Global()->Get(v8::String::New("count"))->Int32Value(), 8);
   6029 }
   6030 
   6031 
   6032 // Test script break points set on lines.
   6033 TEST(ScriptNameAndData) {
   6034   v8::HandleScope scope;
   6035   DebugLocalContext env;
   6036   env.ExposeDebug();
   6037 
   6038   // Create functions for retrieving script name and data for the function on
   6039   // the top frame when hitting a break point.
   6040   frame_script_name = CompileFunction(&env,
   6041                                       frame_script_name_source,
   6042                                       "frame_script_name");
   6043   frame_script_data = CompileFunction(&env,
   6044                                       frame_script_data_source,
   6045                                       "frame_script_data");
   6046   compiled_script_data = CompileFunction(&env,
   6047                                          compiled_script_data_source,
   6048                                          "compiled_script_data");
   6049 
   6050   v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
   6051                                    v8::Undefined());
   6052 
   6053   // Test function source.
   6054   v8::Local<v8::String> script = v8::String::New(
   6055     "function f() {\n"
   6056     "  debugger;\n"
   6057     "}\n");
   6058 
   6059   v8::ScriptOrigin origin1 = v8::ScriptOrigin(v8::String::New("name"));
   6060   v8::Handle<v8::Script> script1 = v8::Script::Compile(script, &origin1);
   6061   script1->SetData(v8::String::New("data"));
   6062   script1->Run();
   6063   v8::Local<v8::Function> f;
   6064   f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   6065 
   6066   f->Call(env->Global(), 0, NULL);
   6067   CHECK_EQ(1, break_point_hit_count);
   6068   CHECK_EQ("name", last_script_name_hit);
   6069   CHECK_EQ("data", last_script_data_hit);
   6070 
   6071   // Compile the same script again without setting data. As the compilation
   6072   // cache is disabled when debugging expect the data to be missing.
   6073   v8::Script::Compile(script, &origin1)->Run();
   6074   f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   6075   f->Call(env->Global(), 0, NULL);
   6076   CHECK_EQ(2, break_point_hit_count);
   6077   CHECK_EQ("name", last_script_name_hit);
   6078   CHECK_EQ("", last_script_data_hit);  // Undefined results in empty string.
   6079 
   6080   v8::Local<v8::String> data_obj_source = v8::String::New(
   6081     "({ a: 'abc',\n"
   6082     "  b: 123,\n"
   6083     "  toString: function() { return this.a + ' ' + this.b; }\n"
   6084     "})\n");
   6085   v8::Local<v8::Value> data_obj = v8::Script::Compile(data_obj_source)->Run();
   6086   v8::ScriptOrigin origin2 = v8::ScriptOrigin(v8::String::New("new name"));
   6087   v8::Handle<v8::Script> script2 = v8::Script::Compile(script, &origin2);
   6088   script2->Run();
   6089   script2->SetData(data_obj->ToString());
   6090   f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   6091   f->Call(env->Global(), 0, NULL);
   6092   CHECK_EQ(3, break_point_hit_count);
   6093   CHECK_EQ("new name", last_script_name_hit);
   6094   CHECK_EQ("abc 123", last_script_data_hit);
   6095 
   6096   v8::Handle<v8::Script> script3 =
   6097       v8::Script::Compile(script, &origin2, NULL,
   6098                           v8::String::New("in compile"));
   6099   CHECK_EQ("in compile", last_script_data_hit);
   6100   script3->Run();
   6101   f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   6102   f->Call(env->Global(), 0, NULL);
   6103   CHECK_EQ(4, break_point_hit_count);
   6104   CHECK_EQ("in compile", last_script_data_hit);
   6105 }
   6106 
   6107 
   6108 static v8::Persistent<v8::Context> expected_context;
   6109 static v8::Handle<v8::Value> expected_context_data;
   6110 
   6111 
   6112 // Check that the expected context is the one generating the debug event.
   6113 static void ContextCheckMessageHandler(const v8::Debug::Message& message) {
   6114   CHECK(message.GetEventContext() == expected_context);
   6115   CHECK(message.GetEventContext()->GetData()->StrictEquals(
   6116       expected_context_data));
   6117   message_handler_hit_count++;
   6118 
   6119   static char print_buffer[1000];
   6120   v8::String::Value json(message.GetJSON());
   6121   Utf16ToAscii(*json, json.length(), print_buffer);
   6122 
   6123   // Send a continue command for break events.
   6124   if (IsBreakEventMessage(print_buffer)) {
   6125     SendContinueCommand();
   6126   }
   6127 }
   6128 
   6129 
   6130 // Test which creates two contexts and sets different embedder data on each.
   6131 // Checks that this data is set correctly and that when the debug message
   6132 // handler is called the expected context is the one active.
   6133 TEST(ContextData) {
   6134   v8::HandleScope scope;
   6135 
   6136   v8::Debug::SetMessageHandler2(ContextCheckMessageHandler);
   6137 
   6138   // Create two contexts.
   6139   v8::Persistent<v8::Context> context_1;
   6140   v8::Persistent<v8::Context> context_2;
   6141   v8::Handle<v8::ObjectTemplate> global_template =
   6142       v8::Handle<v8::ObjectTemplate>();
   6143   v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>();
   6144   context_1 = v8::Context::New(NULL, global_template, global_object);
   6145   context_2 = v8::Context::New(NULL, global_template, global_object);
   6146 
   6147   // Default data value is undefined.
   6148   CHECK(context_1->GetData()->IsUndefined());
   6149   CHECK(context_2->GetData()->IsUndefined());
   6150 
   6151   // Set and check different data values.
   6152   v8::Handle<v8::String> data_1 = v8::String::New("1");
   6153   v8::Handle<v8::String> data_2 = v8::String::New("2");
   6154   context_1->SetData(data_1);
   6155   context_2->SetData(data_2);
   6156   CHECK(context_1->GetData()->StrictEquals(data_1));
   6157   CHECK(context_2->GetData()->StrictEquals(data_2));
   6158 
   6159   // Simple test function which causes a break.
   6160   const char* source = "function f() { debugger; }";
   6161 
   6162   // Enter and run function in the first context.
   6163   {
   6164     v8::Context::Scope context_scope(context_1);
   6165     expected_context = context_1;
   6166     expected_context_data = data_1;
   6167     v8::Local<v8::Function> f = CompileFunction(source, "f");
   6168     f->Call(context_1->Global(), 0, NULL);
   6169   }
   6170 
   6171 
   6172   // Enter and run function in the second context.
   6173   {
   6174     v8::Context::Scope context_scope(context_2);
   6175     expected_context = context_2;
   6176     expected_context_data = data_2;
   6177     v8::Local<v8::Function> f = CompileFunction(source, "f");
   6178     f->Call(context_2->Global(), 0, NULL);
   6179   }
   6180 
   6181   // Two times compile event and two times break event.
   6182   CHECK_GT(message_handler_hit_count, 4);
   6183 
   6184   v8::Debug::SetMessageHandler2(NULL);
   6185   CheckDebuggerUnloaded();
   6186 }
   6187 
   6188 
   6189 // Debug message handler which issues a debug break when it hits a break event.
   6190 static int message_handler_break_hit_count = 0;
   6191 static void DebugBreakMessageHandler(const v8::Debug::Message& message) {
   6192   // Schedule a debug break for break events.
   6193   if (message.IsEvent() && message.GetEvent() == v8::Break) {
   6194     message_handler_break_hit_count++;
   6195     if (message_handler_break_hit_count == 1) {
   6196       v8::Debug::DebugBreak();
   6197     }
   6198   }
   6199 
   6200   // Issue a continue command if this event will not cause the VM to start
   6201   // running.
   6202   if (!message.WillStartRunning()) {
   6203     SendContinueCommand();
   6204   }
   6205 }
   6206 
   6207 
   6208 // Test that a debug break can be scheduled while in a message handler.
   6209 TEST(DebugBreakInMessageHandler) {
   6210   v8::HandleScope scope;
   6211   DebugLocalContext env;
   6212 
   6213   v8::Debug::SetMessageHandler2(DebugBreakMessageHandler);
   6214 
   6215   // Test functions.
   6216   const char* script = "function f() { debugger; g(); } function g() { }";
   6217   CompileRun(script);
   6218   v8::Local<v8::Function> f =
   6219       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   6220   v8::Local<v8::Function> g =
   6221       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("g")));
   6222 
   6223   // Call f then g. The debugger statement in f will casue a break which will
   6224   // cause another break.
   6225   f->Call(env->Global(), 0, NULL);
   6226   CHECK_EQ(2, message_handler_break_hit_count);
   6227   // Calling g will not cause any additional breaks.
   6228   g->Call(env->Global(), 0, NULL);
   6229   CHECK_EQ(2, message_handler_break_hit_count);
   6230 }
   6231 
   6232 
   6233 #ifndef V8_INTERPRETED_REGEXP
   6234 // Debug event handler which gets the function on the top frame and schedules a
   6235 // break a number of times.
   6236 static void DebugEventDebugBreak(
   6237     v8::DebugEvent event,
   6238     v8::Handle<v8::Object> exec_state,
   6239     v8::Handle<v8::Object> event_data,
   6240     v8::Handle<v8::Value> data) {
   6241 
   6242   if (event == v8::Break) {
   6243     break_point_hit_count++;
   6244 
   6245     // Get the name of the top frame function.
   6246     if (!frame_function_name.IsEmpty()) {
   6247       // Get the name of the function.
   6248       const int argc = 2;
   6249       v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(0) };
   6250       v8::Handle<v8::Value> result = frame_function_name->Call(exec_state,
   6251                                                                argc, argv);
   6252       if (result->IsUndefined()) {
   6253         last_function_hit[0] = '\0';
   6254       } else {
   6255         CHECK(result->IsString());
   6256         v8::Handle<v8::String> function_name(result->ToString());
   6257         function_name->WriteAscii(last_function_hit);
   6258       }
   6259     }
   6260 
   6261     // Keep forcing breaks.
   6262     if (break_point_hit_count < 20) {
   6263       v8::Debug::DebugBreak();
   6264     }
   6265   }
   6266 }
   6267 
   6268 
   6269 TEST(RegExpDebugBreak) {
   6270   // This test only applies to native regexps.
   6271   v8::HandleScope scope;
   6272   DebugLocalContext env;
   6273 
   6274   // Create a function for checking the function when hitting a break point.
   6275   frame_function_name = CompileFunction(&env,
   6276                                         frame_function_name_source,
   6277                                         "frame_function_name");
   6278 
   6279   // Test RegExp which matches white spaces and comments at the begining of a
   6280   // source line.
   6281   const char* script =
   6282     "var sourceLineBeginningSkip = /^(?:[ \\v\\h]*(?:\\/\\*.*?\\*\\/)*)*/;\n"
   6283     "function f(s) { return s.match(sourceLineBeginningSkip)[0].length; }";
   6284 
   6285   v8::Local<v8::Function> f = CompileFunction(script, "f");
   6286   const int argc = 1;
   6287   v8::Handle<v8::Value> argv[argc] = { v8::String::New("  /* xxx */ a=0;") };
   6288   v8::Local<v8::Value> result = f->Call(env->Global(), argc, argv);
   6289   CHECK_EQ(12, result->Int32Value());
   6290 
   6291   v8::Debug::SetDebugEventListener(DebugEventDebugBreak);
   6292   v8::Debug::DebugBreak();
   6293   result = f->Call(env->Global(), argc, argv);
   6294 
   6295   // Check that there was only one break event. Matching RegExp should not
   6296   // cause Break events.
   6297   CHECK_EQ(1, break_point_hit_count);
   6298   CHECK_EQ("f", last_function_hit);
   6299 }
   6300 #endif  // V8_INTERPRETED_REGEXP
   6301 
   6302 
   6303 // Common part of EvalContextData and NestedBreakEventContextData tests.
   6304 static void ExecuteScriptForContextCheck() {
   6305   // Create a context.
   6306   v8::Persistent<v8::Context> context_1;
   6307   v8::Handle<v8::ObjectTemplate> global_template =
   6308       v8::Handle<v8::ObjectTemplate>();
   6309   v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>();
   6310   context_1 = v8::Context::New(NULL, global_template, global_object);
   6311 
   6312   // Default data value is undefined.
   6313   CHECK(context_1->GetData()->IsUndefined());
   6314 
   6315   // Set and check a data value.
   6316   v8::Handle<v8::String> data_1 = v8::String::New("1");
   6317   context_1->SetData(data_1);
   6318   CHECK(context_1->GetData()->StrictEquals(data_1));
   6319 
   6320   // Simple test function with eval that causes a break.
   6321   const char* source = "function f() { eval('debugger;'); }";
   6322 
   6323   // Enter and run function in the context.
   6324   {
   6325     v8::Context::Scope context_scope(context_1);
   6326     expected_context = context_1;
   6327     expected_context_data = data_1;
   6328     v8::Local<v8::Function> f = CompileFunction(source, "f");
   6329     f->Call(context_1->Global(), 0, NULL);
   6330   }
   6331 }
   6332 
   6333 
   6334 // Test which creates a context and sets embedder data on it. Checks that this
   6335 // data is set correctly and that when the debug message handler is called for
   6336 // break event in an eval statement the expected context is the one returned by
   6337 // Message.GetEventContext.
   6338 TEST(EvalContextData) {
   6339   v8::HandleScope scope;
   6340   v8::Debug::SetMessageHandler2(ContextCheckMessageHandler);
   6341 
   6342   ExecuteScriptForContextCheck();
   6343 
   6344   // One time compile event and one time break event.
   6345   CHECK_GT(message_handler_hit_count, 2);
   6346   v8::Debug::SetMessageHandler2(NULL);
   6347   CheckDebuggerUnloaded();
   6348 }
   6349 
   6350 
   6351 static bool sent_eval = false;
   6352 static int break_count = 0;
   6353 static int continue_command_send_count = 0;
   6354 // Check that the expected context is the one generating the debug event
   6355 // including the case of nested break event.
   6356 static void DebugEvalContextCheckMessageHandler(
   6357     const v8::Debug::Message& message) {
   6358   CHECK(message.GetEventContext() == expected_context);
   6359   CHECK(message.GetEventContext()->GetData()->StrictEquals(
   6360       expected_context_data));
   6361   message_handler_hit_count++;
   6362 
   6363   static char print_buffer[1000];
   6364   v8::String::Value json(message.GetJSON());
   6365   Utf16ToAscii(*json, json.length(), print_buffer);
   6366 
   6367   if (IsBreakEventMessage(print_buffer)) {
   6368     break_count++;
   6369     if (!sent_eval) {
   6370       sent_eval = true;
   6371 
   6372       const int kBufferSize = 1000;
   6373       uint16_t buffer[kBufferSize];
   6374       const char* eval_command =
   6375         "{\"seq\":0,"
   6376          "\"type\":\"request\","
   6377          "\"command\":\"evaluate\","
   6378          "arguments:{\"expression\":\"debugger;\","
   6379          "\"global\":true,\"disable_break\":false}}";
   6380 
   6381       // Send evaluate command.
   6382       v8::Debug::SendCommand(buffer, AsciiToUtf16(eval_command, buffer));
   6383       return;
   6384     } else {
   6385       // It's a break event caused by the evaluation request above.
   6386       SendContinueCommand();
   6387       continue_command_send_count++;
   6388     }
   6389   } else if (IsEvaluateResponseMessage(print_buffer) &&
   6390       continue_command_send_count < 2) {
   6391     // Response to the evaluation request. We're still on the breakpoint so
   6392     // send continue.
   6393     SendContinueCommand();
   6394     continue_command_send_count++;
   6395   }
   6396 }
   6397 
   6398 
   6399 // Tests that context returned for break event is correct when the event occurs
   6400 // in 'evaluate' debugger request.
   6401 TEST(NestedBreakEventContextData) {
   6402   v8::HandleScope scope;
   6403   break_count = 0;
   6404   message_handler_hit_count = 0;
   6405   v8::Debug::SetMessageHandler2(DebugEvalContextCheckMessageHandler);
   6406 
   6407   ExecuteScriptForContextCheck();
   6408 
   6409   // One time compile event and two times break event.
   6410   CHECK_GT(message_handler_hit_count, 3);
   6411 
   6412   // One break from the source and another from the evaluate request.
   6413   CHECK_EQ(break_count, 2);
   6414   v8::Debug::SetMessageHandler2(NULL);
   6415   CheckDebuggerUnloaded();
   6416 }
   6417 
   6418 
   6419 // Debug event listener which counts the script collected events.
   6420 int script_collected_count = 0;
   6421 static void DebugEventScriptCollectedEvent(v8::DebugEvent event,
   6422                                            v8::Handle<v8::Object> exec_state,
   6423                                            v8::Handle<v8::Object> event_data,
   6424                                            v8::Handle<v8::Value> data) {
   6425   // Count the number of breaks.
   6426   if (event == v8::ScriptCollected) {
   6427     script_collected_count++;
   6428   }
   6429 }
   6430 
   6431 
   6432 // Test that scripts collected are reported through the debug event listener.
   6433 TEST(ScriptCollectedEvent) {
   6434   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
   6435   break_point_hit_count = 0;
   6436   script_collected_count = 0;
   6437   v8::HandleScope scope;
   6438   DebugLocalContext env;
   6439 
   6440   // Request the loaded scripts to initialize the debugger script cache.
   6441   debug->GetLoadedScripts();
   6442 
   6443   // Do garbage collection to ensure that only the script in this test will be
   6444   // collected afterwards.
   6445   HEAP->CollectAllGarbage(false);
   6446 
   6447   script_collected_count = 0;
   6448   v8::Debug::SetDebugEventListener(DebugEventScriptCollectedEvent,
   6449                                    v8::Undefined());
   6450   {
   6451     v8::Script::Compile(v8::String::New("eval('a=1')"))->Run();
   6452     v8::Script::Compile(v8::String::New("eval('a=2')"))->Run();
   6453   }
   6454 
   6455   // Do garbage collection to collect the script above which is no longer
   6456   // referenced.
   6457   HEAP->CollectAllGarbage(false);
   6458 
   6459   CHECK_EQ(2, script_collected_count);
   6460 
   6461   v8::Debug::SetDebugEventListener(NULL);
   6462   CheckDebuggerUnloaded();
   6463 }
   6464 
   6465 
   6466 // Debug event listener which counts the script collected events.
   6467 int script_collected_message_count = 0;
   6468 static void ScriptCollectedMessageHandler(const v8::Debug::Message& message) {
   6469   // Count the number of scripts collected.
   6470   if (message.IsEvent() && message.GetEvent() == v8::ScriptCollected) {
   6471     script_collected_message_count++;
   6472     v8::Handle<v8::Context> context = message.GetEventContext();
   6473     CHECK(context.IsEmpty());
   6474   }
   6475 }
   6476 
   6477 
   6478 // Test that GetEventContext doesn't fail and return empty handle for
   6479 // ScriptCollected events.
   6480 TEST(ScriptCollectedEventContext) {
   6481   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
   6482   script_collected_message_count = 0;
   6483   v8::HandleScope scope;
   6484 
   6485   { // Scope for the DebugLocalContext.
   6486     DebugLocalContext env;
   6487 
   6488     // Request the loaded scripts to initialize the debugger script cache.
   6489     debug->GetLoadedScripts();
   6490 
   6491     // Do garbage collection to ensure that only the script in this test will be
   6492     // collected afterwards.
   6493     HEAP->CollectAllGarbage(false);
   6494 
   6495     v8::Debug::SetMessageHandler2(ScriptCollectedMessageHandler);
   6496     {
   6497       v8::Script::Compile(v8::String::New("eval('a=1')"))->Run();
   6498       v8::Script::Compile(v8::String::New("eval('a=2')"))->Run();
   6499     }
   6500   }
   6501 
   6502   // Do garbage collection to collect the script above which is no longer
   6503   // referenced.
   6504   HEAP->CollectAllGarbage(false);
   6505 
   6506   CHECK_EQ(2, script_collected_message_count);
   6507 
   6508   v8::Debug::SetMessageHandler2(NULL);
   6509 }
   6510 
   6511 
   6512 // Debug event listener which counts the after compile events.
   6513 int after_compile_message_count = 0;
   6514 static void AfterCompileMessageHandler(const v8::Debug::Message& message) {
   6515   // Count the number of scripts collected.
   6516   if (message.IsEvent()) {
   6517     if (message.GetEvent() == v8::AfterCompile) {
   6518       after_compile_message_count++;
   6519     } else if (message.GetEvent() == v8::Break) {
   6520       SendContinueCommand();
   6521     }
   6522   }
   6523 }
   6524 
   6525 
   6526 // Tests that after compile event is sent as many times as there are scripts
   6527 // compiled.
   6528 TEST(AfterCompileMessageWhenMessageHandlerIsReset) {
   6529   v8::HandleScope scope;
   6530   DebugLocalContext env;
   6531   after_compile_message_count = 0;
   6532   const char* script = "var a=1";
   6533 
   6534   v8::Debug::SetMessageHandler2(AfterCompileMessageHandler);
   6535   v8::Script::Compile(v8::String::New(script))->Run();
   6536   v8::Debug::SetMessageHandler2(NULL);
   6537 
   6538   v8::Debug::SetMessageHandler2(AfterCompileMessageHandler);
   6539   v8::Debug::DebugBreak();
   6540   v8::Script::Compile(v8::String::New(script))->Run();
   6541 
   6542   // Setting listener to NULL should cause debugger unload.
   6543   v8::Debug::SetMessageHandler2(NULL);
   6544   CheckDebuggerUnloaded();
   6545 
   6546   // Compilation cache should be disabled when debugger is active.
   6547   CHECK_EQ(2, after_compile_message_count);
   6548 }
   6549 
   6550 
   6551 // Tests that break event is sent when message handler is reset.
   6552 TEST(BreakMessageWhenMessageHandlerIsReset) {
   6553   v8::HandleScope scope;
   6554   DebugLocalContext env;
   6555   after_compile_message_count = 0;
   6556   const char* script = "function f() {};";
   6557 
   6558   v8::Debug::SetMessageHandler2(AfterCompileMessageHandler);
   6559   v8::Script::Compile(v8::String::New(script))->Run();
   6560   v8::Debug::SetMessageHandler2(NULL);
   6561 
   6562   v8::Debug::SetMessageHandler2(AfterCompileMessageHandler);
   6563   v8::Debug::DebugBreak();
   6564   v8::Local<v8::Function> f =
   6565       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   6566   f->Call(env->Global(), 0, NULL);
   6567 
   6568   // Setting message handler to NULL should cause debugger unload.
   6569   v8::Debug::SetMessageHandler2(NULL);
   6570   CheckDebuggerUnloaded();
   6571 
   6572   // Compilation cache should be disabled when debugger is active.
   6573   CHECK_EQ(1, after_compile_message_count);
   6574 }
   6575 
   6576 
   6577 static int exception_event_count = 0;
   6578 static void ExceptionMessageHandler(const v8::Debug::Message& message) {
   6579   if (message.IsEvent() && message.GetEvent() == v8::Exception) {
   6580     exception_event_count++;
   6581     SendContinueCommand();
   6582   }
   6583 }
   6584 
   6585 
   6586 // Tests that exception event is sent when message handler is reset.
   6587 TEST(ExceptionMessageWhenMessageHandlerIsReset) {
   6588   v8::HandleScope scope;
   6589   DebugLocalContext env;
   6590 
   6591   // For this test, we want to break on uncaught exceptions:
   6592   ChangeBreakOnException(false, true);
   6593 
   6594   exception_event_count = 0;
   6595   const char* script = "function f() {throw new Error()};";
   6596 
   6597   v8::Debug::SetMessageHandler2(AfterCompileMessageHandler);
   6598   v8::Script::Compile(v8::String::New(script))->Run();
   6599   v8::Debug::SetMessageHandler2(NULL);
   6600 
   6601   v8::Debug::SetMessageHandler2(ExceptionMessageHandler);
   6602   v8::Local<v8::Function> f =
   6603       v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
   6604   f->Call(env->Global(), 0, NULL);
   6605 
   6606   // Setting message handler to NULL should cause debugger unload.
   6607   v8::Debug::SetMessageHandler2(NULL);
   6608   CheckDebuggerUnloaded();
   6609 
   6610   CHECK_EQ(1, exception_event_count);
   6611 }
   6612 
   6613 
   6614 // Tests after compile event is sent when there are some provisional
   6615 // breakpoints out of the scripts lines range.
   6616 TEST(ProvisionalBreakpointOnLineOutOfRange) {
   6617   v8::HandleScope scope;
   6618   DebugLocalContext env;
   6619   env.ExposeDebug();
   6620   const char* script = "function f() {};";
   6621   const char* resource_name = "test_resource";
   6622 
   6623   // Set a couple of provisional breakpoint on lines out of the script lines
   6624   // range.
   6625   int sbp1 = SetScriptBreakPointByNameFromJS(resource_name, 3,
   6626                                              -1 /* no column */);
   6627   int sbp2 = SetScriptBreakPointByNameFromJS(resource_name, 5, 5);
   6628 
   6629   after_compile_message_count = 0;
   6630   v8::Debug::SetMessageHandler2(AfterCompileMessageHandler);
   6631 
   6632   v8::ScriptOrigin origin(
   6633       v8::String::New(resource_name),
   6634       v8::Integer::New(10),
   6635       v8::Integer::New(1));
   6636   // Compile a script whose first line number is greater than the breakpoints'
   6637   // lines.
   6638   v8::Script::Compile(v8::String::New(script), &origin)->Run();
   6639 
   6640   // If the script is compiled successfully there is exactly one after compile
   6641   // event. In case of an exception in debugger code after compile event is not
   6642   // sent.
   6643   CHECK_EQ(1, after_compile_message_count);
   6644 
   6645   ClearBreakPointFromJS(sbp1);
   6646   ClearBreakPointFromJS(sbp2);
   6647   v8::Debug::SetMessageHandler2(NULL);
   6648 }
   6649 
   6650 
   6651 static void BreakMessageHandler(const v8::Debug::Message& message) {
   6652   i::Isolate* isolate = i::Isolate::Current();
   6653   if (message.IsEvent() && message.GetEvent() == v8::Break) {
   6654     // Count the number of breaks.
   6655     break_point_hit_count++;
   6656 
   6657     v8::HandleScope scope;
   6658     v8::Handle<v8::String> json = message.GetJSON();
   6659 
   6660     SendContinueCommand();
   6661   } else if (message.IsEvent() && message.GetEvent() == v8::AfterCompile) {
   6662     v8::HandleScope scope;
   6663 
   6664     bool is_debug_break = isolate->stack_guard()->IsDebugBreak();
   6665     // Force DebugBreak flag while serializer is working.
   6666     isolate->stack_guard()->DebugBreak();
   6667 
   6668     // Force serialization to trigger some internal JS execution.
   6669     v8::Handle<v8::String> json = message.GetJSON();
   6670 
   6671     // Restore previous state.
   6672     if (is_debug_break) {
   6673       isolate->stack_guard()->DebugBreak();
   6674     } else {
   6675       isolate->stack_guard()->Continue(i::DEBUGBREAK);
   6676     }
   6677   }
   6678 }
   6679 
   6680 
   6681 // Test that if DebugBreak is forced it is ignored when code from
   6682 // debug-delay.js is executed.
   6683 TEST(NoDebugBreakInAfterCompileMessageHandler) {
   6684   v8::HandleScope scope;
   6685   DebugLocalContext env;
   6686 
   6687   // Register a debug event listener which sets the break flag and counts.
   6688   v8::Debug::SetMessageHandler2(BreakMessageHandler);
   6689 
   6690   // Set the debug break flag.
   6691   v8::Debug::DebugBreak();
   6692 
   6693   // Create a function for testing stepping.
   6694   const char* src = "function f() { eval('var x = 10;'); } ";
   6695   v8::Local<v8::Function> f = CompileFunction(&env, src, "f");
   6696 
   6697   // There should be only one break event.
   6698   CHECK_EQ(1, break_point_hit_count);
   6699 
   6700   // Set the debug break flag again.
   6701   v8::Debug::DebugBreak();
   6702   f->Call(env->Global(), 0, NULL);
   6703   // There should be one more break event when the script is evaluated in 'f'.
   6704   CHECK_EQ(2, break_point_hit_count);
   6705 
   6706   // Get rid of the debug message handler.
   6707   v8::Debug::SetMessageHandler2(NULL);
   6708   CheckDebuggerUnloaded();
   6709 }
   6710 
   6711 
   6712 static int counting_message_handler_counter;
   6713 
   6714 static void CountingMessageHandler(const v8::Debug::Message& message) {
   6715   counting_message_handler_counter++;
   6716 }
   6717 
   6718 // Test that debug messages get processed when ProcessDebugMessages is called.
   6719 TEST(ProcessDebugMessages) {
   6720   v8::HandleScope scope;
   6721   DebugLocalContext env;
   6722 
   6723   counting_message_handler_counter = 0;
   6724 
   6725   v8::Debug::SetMessageHandler2(CountingMessageHandler);
   6726 
   6727   const int kBufferSize = 1000;
   6728   uint16_t buffer[kBufferSize];
   6729   const char* scripts_command =
   6730     "{\"seq\":0,"
   6731      "\"type\":\"request\","
   6732      "\"command\":\"scripts\"}";
   6733 
   6734   // Send scripts command.
   6735   v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer));
   6736 
   6737   CHECK_EQ(0, counting_message_handler_counter);
   6738   v8::Debug::ProcessDebugMessages();
   6739   // At least one message should come
   6740   CHECK_GE(counting_message_handler_counter, 1);
   6741 
   6742   counting_message_handler_counter = 0;
   6743 
   6744   v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer));
   6745   v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer));
   6746   CHECK_EQ(0, counting_message_handler_counter);
   6747   v8::Debug::ProcessDebugMessages();
   6748   // At least two messages should come
   6749   CHECK_GE(counting_message_handler_counter, 2);
   6750 
   6751   // Get rid of the debug message handler.
   6752   v8::Debug::SetMessageHandler2(NULL);
   6753   CheckDebuggerUnloaded();
   6754 }
   6755 
   6756 
   6757 struct BacktraceData {
   6758   static int frame_counter;
   6759   static void MessageHandler(const v8::Debug::Message& message) {
   6760     char print_buffer[1000];
   6761     v8::String::Value json(message.GetJSON());
   6762     Utf16ToAscii(*json, json.length(), print_buffer, 1000);
   6763 
   6764     if (strstr(print_buffer, "backtrace") == NULL) {
   6765       return;
   6766     }
   6767     frame_counter = GetTotalFramesInt(print_buffer);
   6768   }
   6769 };
   6770 
   6771 int BacktraceData::frame_counter;
   6772 
   6773 
   6774 // Test that debug messages get processed when ProcessDebugMessages is called.
   6775 TEST(Backtrace) {
   6776   v8::HandleScope scope;
   6777   DebugLocalContext env;
   6778 
   6779   v8::Debug::SetMessageHandler2(BacktraceData::MessageHandler);
   6780 
   6781   const int kBufferSize = 1000;
   6782   uint16_t buffer[kBufferSize];
   6783   const char* scripts_command =
   6784     "{\"seq\":0,"
   6785      "\"type\":\"request\","
   6786      "\"command\":\"backtrace\"}";
   6787 
   6788   // Check backtrace from ProcessDebugMessages.
   6789   BacktraceData::frame_counter = -10;
   6790   v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer));
   6791   v8::Debug::ProcessDebugMessages();
   6792   CHECK_EQ(BacktraceData::frame_counter, 0);
   6793 
   6794   v8::Handle<v8::String> void0 = v8::String::New("void(0)");
   6795   v8::Handle<v8::Script> script = v8::Script::Compile(void0, void0);
   6796 
   6797   // Check backtrace from "void(0)" script.
   6798   BacktraceData::frame_counter = -10;
   6799   v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer));
   6800   script->Run();
   6801   CHECK_EQ(BacktraceData::frame_counter, 1);
   6802 
   6803   // Get rid of the debug message handler.
   6804   v8::Debug::SetMessageHandler2(NULL);
   6805   CheckDebuggerUnloaded();
   6806 }
   6807 
   6808 
   6809 TEST(GetMirror) {
   6810   v8::HandleScope scope;
   6811   DebugLocalContext env;
   6812   v8::Handle<v8::Value> obj = v8::Debug::GetMirror(v8::String::New("hodja"));
   6813   v8::Handle<v8::Function> run_test = v8::Handle<v8::Function>::Cast(
   6814       v8::Script::New(
   6815           v8::String::New(
   6816               "function runTest(mirror) {"
   6817               "  return mirror.isString() && (mirror.length() == 5);"
   6818               "}"
   6819               ""
   6820               "runTest;"))->Run());
   6821   v8::Handle<v8::Value> result = run_test->Call(env->Global(), 1, &obj);
   6822   CHECK(result->IsTrue());
   6823 }
   6824 
   6825 
   6826 // Test that the debug break flag works with function.apply.
   6827 TEST(DebugBreakFunctionApply) {
   6828   v8::HandleScope scope;
   6829   DebugLocalContext env;
   6830 
   6831   // Create a function for testing breaking in apply.
   6832   v8::Local<v8::Function> foo = CompileFunction(
   6833       &env,
   6834       "function baz(x) { }"
   6835       "function bar(x) { baz(); }"
   6836       "function foo(){ bar.apply(this, [1]); }",
   6837       "foo");
   6838 
   6839   // Register a debug event listener which steps and counts.
   6840   v8::Debug::SetDebugEventListener(DebugEventBreakMax);
   6841 
   6842   // Set the debug break flag before calling the code using function.apply.
   6843   v8::Debug::DebugBreak();
   6844 
   6845   // Limit the number of debug breaks. This is a regression test for issue 493
   6846   // where this test would enter an infinite loop.
   6847   break_point_hit_count = 0;
   6848   max_break_point_hit_count = 10000;  // 10000 => infinite loop.
   6849   foo->Call(env->Global(), 0, NULL);
   6850 
   6851   // When keeping the debug break several break will happen.
   6852   CHECK_EQ(3, break_point_hit_count);
   6853 
   6854   v8::Debug::SetDebugEventListener(NULL);
   6855   CheckDebuggerUnloaded();
   6856 }
   6857 
   6858 
   6859 v8::Handle<v8::Context> debugee_context;
   6860 v8::Handle<v8::Context> debugger_context;
   6861 
   6862 
   6863 // Property getter that checks that current and calling contexts
   6864 // are both the debugee contexts.
   6865 static v8::Handle<v8::Value> NamedGetterWithCallingContextCheck(
   6866     v8::Local<v8::String> name,
   6867     const v8::AccessorInfo& info) {
   6868   CHECK_EQ(0, strcmp(*v8::String::AsciiValue(name), "a"));
   6869   v8::Handle<v8::Context> current = v8::Context::GetCurrent();
   6870   CHECK(current == debugee_context);
   6871   CHECK(current != debugger_context);
   6872   v8::Handle<v8::Context> calling = v8::Context::GetCalling();
   6873   CHECK(calling == debugee_context);
   6874   CHECK(calling != debugger_context);
   6875   return v8::Int32::New(1);
   6876 }
   6877 
   6878 
   6879 // Debug event listener that checks if the first argument of a function is
   6880 // an object with property 'a' == 1. If the property has custom accessor
   6881 // this handler will eventually invoke it.
   6882 static void DebugEventGetAtgumentPropertyValue(
   6883     v8::DebugEvent event,
   6884     v8::Handle<v8::Object> exec_state,
   6885     v8::Handle<v8::Object> event_data,
   6886     v8::Handle<v8::Value> data) {
   6887   if (event == v8::Break) {
   6888     break_point_hit_count++;
   6889     CHECK(debugger_context == v8::Context::GetCurrent());
   6890     v8::Handle<v8::Function> func(v8::Function::Cast(*CompileRun(
   6891         "(function(exec_state) {\n"
   6892         "    return (exec_state.frame(0).argumentValue(0).property('a').\n"
   6893         "            value().value() == 1);\n"
   6894         "})")));
   6895     const int argc = 1;
   6896     v8::Handle<v8::Value> argv[argc] = { exec_state };
   6897     v8::Handle<v8::Value> result = func->Call(exec_state, argc, argv);
   6898     CHECK(result->IsTrue());
   6899   }
   6900 }
   6901 
   6902 
   6903 TEST(CallingContextIsNotDebugContext) {
   6904   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
   6905   // Create and enter a debugee context.
   6906   v8::HandleScope scope;
   6907   DebugLocalContext env;
   6908   env.ExposeDebug();
   6909 
   6910   // Save handles to the debugger and debugee contexts to be used in
   6911   // NamedGetterWithCallingContextCheck.
   6912   debugee_context = v8::Local<v8::Context>(*env);
   6913   debugger_context = v8::Utils::ToLocal(debug->debug_context());
   6914 
   6915   // Create object with 'a' property accessor.
   6916   v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New();
   6917   named->SetAccessor(v8::String::New("a"),
   6918                      NamedGetterWithCallingContextCheck);
   6919   env->Global()->Set(v8::String::New("obj"),
   6920                      named->NewInstance());
   6921 
   6922   // Register the debug event listener
   6923   v8::Debug::SetDebugEventListener(DebugEventGetAtgumentPropertyValue);
   6924 
   6925   // Create a function that invokes debugger.
   6926   v8::Local<v8::Function> foo = CompileFunction(
   6927       &env,
   6928       "function bar(x) { debugger; }"
   6929       "function foo(){ bar(obj); }",
   6930       "foo");
   6931 
   6932   break_point_hit_count = 0;
   6933   foo->Call(env->Global(), 0, NULL);
   6934   CHECK_EQ(1, break_point_hit_count);
   6935 
   6936   v8::Debug::SetDebugEventListener(NULL);
   6937   debugee_context = v8::Handle<v8::Context>();
   6938   debugger_context = v8::Handle<v8::Context>();
   6939   CheckDebuggerUnloaded();
   6940 }
   6941 
   6942 
   6943 TEST(DebugContextIsPreservedBetweenAccesses) {
   6944   v8::HandleScope scope;
   6945   v8::Local<v8::Context> context1 = v8::Debug::GetDebugContext();
   6946   v8::Local<v8::Context> context2 = v8::Debug::GetDebugContext();
   6947   CHECK_EQ(*context1, *context2);
   6948 }
   6949 
   6950 
   6951 static v8::Handle<v8::Value> expected_callback_data;
   6952 static void DebugEventContextChecker(const v8::Debug::EventDetails& details) {
   6953   CHECK(details.GetEventContext() == expected_context);
   6954   CHECK_EQ(expected_callback_data, details.GetCallbackData());
   6955 }
   6956 
   6957 // Check that event details contain context where debug event occured.
   6958 TEST(DebugEventContext) {
   6959   v8::HandleScope scope;
   6960   expected_callback_data = v8::Int32::New(2010);
   6961   v8::Debug::SetDebugEventListener2(DebugEventContextChecker,
   6962                                     expected_callback_data);
   6963   expected_context = v8::Context::New();
   6964   v8::Context::Scope context_scope(expected_context);
   6965   v8::Script::Compile(v8::String::New("(function(){debugger;})();"))->Run();
   6966   expected_context.Dispose();
   6967   expected_context.Clear();
   6968   v8::Debug::SetDebugEventListener(NULL);
   6969   expected_context_data = v8::Handle<v8::Value>();
   6970   CheckDebuggerUnloaded();
   6971 }
   6972 
   6973 
   6974 static void* expected_break_data;
   6975 static bool was_debug_break_called;
   6976 static bool was_debug_event_called;
   6977 static void DebugEventBreakDataChecker(const v8::Debug::EventDetails& details) {
   6978   if (details.GetEvent() == v8::BreakForCommand) {
   6979     CHECK_EQ(expected_break_data, details.GetClientData());
   6980     was_debug_event_called = true;
   6981   } else if (details.GetEvent() == v8::Break) {
   6982     was_debug_break_called = true;
   6983   }
   6984 }
   6985 
   6986 
   6987 // Check that event details contain context where debug event occured.
   6988 TEST(DebugEventBreakData) {
   6989   v8::HandleScope scope;
   6990   DebugLocalContext env;
   6991   v8::Debug::SetDebugEventListener2(DebugEventBreakDataChecker);
   6992 
   6993   TestClientData::constructor_call_counter = 0;
   6994   TestClientData::destructor_call_counter = 0;
   6995 
   6996   expected_break_data = NULL;
   6997   was_debug_event_called = false;
   6998   was_debug_break_called = false;
   6999   v8::Debug::DebugBreakForCommand();
   7000   v8::Script::Compile(v8::String::New("(function(x){return x;})(1);"))->Run();
   7001   CHECK(was_debug_event_called);
   7002   CHECK(!was_debug_break_called);
   7003 
   7004   TestClientData* data1 = new TestClientData();
   7005   expected_break_data = data1;
   7006   was_debug_event_called = false;
   7007   was_debug_break_called = false;
   7008   v8::Debug::DebugBreakForCommand(data1);
   7009   v8::Script::Compile(v8::String::New("(function(x){return x+1;})(1);"))->Run();
   7010   CHECK(was_debug_event_called);
   7011   CHECK(!was_debug_break_called);
   7012 
   7013   expected_break_data = NULL;
   7014   was_debug_event_called = false;
   7015   was_debug_break_called = false;
   7016   v8::Debug::DebugBreak();
   7017   v8::Script::Compile(v8::String::New("(function(x){return x+2;})(1);"))->Run();
   7018   CHECK(!was_debug_event_called);
   7019   CHECK(was_debug_break_called);
   7020 
   7021   TestClientData* data2 = new TestClientData();
   7022   expected_break_data = data2;
   7023   was_debug_event_called = false;
   7024   was_debug_break_called = false;
   7025   v8::Debug::DebugBreak();
   7026   v8::Debug::DebugBreakForCommand(data2);
   7027   v8::Script::Compile(v8::String::New("(function(x){return x+3;})(1);"))->Run();
   7028   CHECK(was_debug_event_called);
   7029   CHECK(was_debug_break_called);
   7030 
   7031   CHECK_EQ(2, TestClientData::constructor_call_counter);
   7032   CHECK_EQ(TestClientData::constructor_call_counter,
   7033            TestClientData::destructor_call_counter);
   7034 
   7035   v8::Debug::SetDebugEventListener(NULL);
   7036   CheckDebuggerUnloaded();
   7037 }
   7038 
   7039 static bool debug_event_break_deoptimize_done = false;
   7040 
   7041 static void DebugEventBreakDeoptimize(v8::DebugEvent event,
   7042                                       v8::Handle<v8::Object> exec_state,
   7043                                       v8::Handle<v8::Object> event_data,
   7044                                       v8::Handle<v8::Value> data) {
   7045   if (event == v8::Break) {
   7046     if (!frame_function_name.IsEmpty()) {
   7047       // Get the name of the function.
   7048       const int argc = 2;
   7049       v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(0) };
   7050       v8::Handle<v8::Value> result =
   7051           frame_function_name->Call(exec_state, argc, argv);
   7052       if (!result->IsUndefined()) {
   7053         char fn[80];
   7054         CHECK(result->IsString());
   7055         v8::Handle<v8::String> function_name(result->ToString());
   7056         function_name->WriteAscii(fn);
   7057         if (strcmp(fn, "bar") == 0) {
   7058           i::Deoptimizer::DeoptimizeAll();
   7059           debug_event_break_deoptimize_done = true;
   7060         }
   7061       }
   7062     }
   7063 
   7064     v8::Debug::DebugBreak();
   7065   }
   7066 }
   7067 
   7068 
   7069 // Test deoptimization when execution is broken using the debug break stack
   7070 // check interrupt.
   7071 TEST(DeoptimizeDuringDebugBreak) {
   7072   v8::HandleScope scope;
   7073   DebugLocalContext env;
   7074   env.ExposeDebug();
   7075 
   7076   // Create a function for checking the function when hitting a break point.
   7077   frame_function_name = CompileFunction(&env,
   7078                                         frame_function_name_source,
   7079                                         "frame_function_name");
   7080 
   7081 
   7082   // Set a debug event listener which will keep interrupting execution until
   7083   // debug break. When inside function bar it will deoptimize all functions.
   7084   // This tests lazy deoptimization bailout for the stack check, as the first
   7085   // time in function bar when using debug break and no break points will be at
   7086   // the initial stack check.
   7087   v8::Debug::SetDebugEventListener(DebugEventBreakDeoptimize,
   7088                                    v8::Undefined());
   7089 
   7090   // Compile and run function bar which will optimize it for some flag settings.
   7091   v8::Script::Compile(v8::String::New("function bar(){}; bar()"))->Run();
   7092 
   7093   // Set debug break and call bar again.
   7094   v8::Debug::DebugBreak();
   7095   v8::Script::Compile(v8::String::New("bar()"))->Run();
   7096 
   7097   CHECK(debug_event_break_deoptimize_done);
   7098 
   7099   v8::Debug::SetDebugEventListener(NULL);
   7100 }
   7101 
   7102 
   7103 static void DebugEventBreakWithOptimizedStack(v8::DebugEvent event,
   7104                                               v8::Handle<v8::Object> exec_state,
   7105                                               v8::Handle<v8::Object> event_data,
   7106                                               v8::Handle<v8::Value> data) {
   7107   if (event == v8::Break) {
   7108     if (!frame_function_name.IsEmpty()) {
   7109       for (int i = 0; i < 2; i++) {
   7110         const int argc = 2;
   7111         v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(i) };
   7112         // Get the name of the function in frame i.
   7113         v8::Handle<v8::Value> result =
   7114             frame_function_name->Call(exec_state, argc, argv);
   7115         CHECK(result->IsString());
   7116         v8::Handle<v8::String> function_name(result->ToString());
   7117         CHECK(function_name->Equals(v8::String::New("loop")));
   7118         // Get the name of the first argument in frame i.
   7119         result = frame_argument_name->Call(exec_state, argc, argv);
   7120         CHECK(result->IsString());
   7121         v8::Handle<v8::String> argument_name(result->ToString());
   7122         CHECK(argument_name->Equals(v8::String::New("count")));
   7123         // Get the value of the first argument in frame i. If the
   7124         // funtion is optimized the value will be undefined, otherwise
   7125         // the value will be '1 - i'.
   7126         //
   7127         // TODO(3141533): We should be able to get the real value for
   7128         // optimized frames.
   7129         result = frame_argument_value->Call(exec_state, argc, argv);
   7130         CHECK(result->IsUndefined() || (result->Int32Value() == 1 - i));
   7131         // Get the name of the first local variable.
   7132         result = frame_local_name->Call(exec_state, argc, argv);
   7133         CHECK(result->IsString());
   7134         v8::Handle<v8::String> local_name(result->ToString());
   7135         CHECK(local_name->Equals(v8::String::New("local")));
   7136         // Get the value of the first local variable. If the function
   7137         // is optimized the value will be undefined, otherwise it will
   7138         // be 42.
   7139         //
   7140         // TODO(3141533): We should be able to get the real value for
   7141         // optimized frames.
   7142         result = frame_local_value->Call(exec_state, argc, argv);
   7143         CHECK(result->IsUndefined() || (result->Int32Value() == 42));
   7144       }
   7145     }
   7146   }
   7147 }
   7148 
   7149 
   7150 static v8::Handle<v8::Value> ScheduleBreak(const v8::Arguments& args) {
   7151   v8::Debug::SetDebugEventListener(DebugEventBreakWithOptimizedStack,
   7152                                    v8::Undefined());
   7153   v8::Debug::DebugBreak();
   7154   return v8::Undefined();
   7155 }
   7156 
   7157 
   7158 TEST(DebugBreakStackInspection) {
   7159   v8::HandleScope scope;
   7160   DebugLocalContext env;
   7161 
   7162   frame_function_name =
   7163       CompileFunction(&env, frame_function_name_source, "frame_function_name");
   7164   frame_argument_name =
   7165       CompileFunction(&env, frame_argument_name_source, "frame_argument_name");
   7166   frame_argument_value = CompileFunction(&env,
   7167                                          frame_argument_value_source,
   7168                                          "frame_argument_value");
   7169   frame_local_name =
   7170       CompileFunction(&env, frame_local_name_source, "frame_local_name");
   7171   frame_local_value =
   7172       CompileFunction(&env, frame_local_value_source, "frame_local_value");
   7173 
   7174   v8::Handle<v8::FunctionTemplate> schedule_break_template =
   7175       v8::FunctionTemplate::New(ScheduleBreak);
   7176   v8::Handle<v8::Function> schedule_break =
   7177       schedule_break_template->GetFunction();
   7178   env->Global()->Set(v8_str("scheduleBreak"), schedule_break);
   7179 
   7180   const char* src =
   7181       "function loop(count) {"
   7182       "  var local = 42;"
   7183       "  if (count < 1) { scheduleBreak(); loop(count + 1); }"
   7184       "}"
   7185       "loop(0);";
   7186   v8::Script::Compile(v8::String::New(src))->Run();
   7187 }
   7188 
   7189 
   7190 // Test that setting the terminate execution flag during debug break processing.
   7191 static void TestDebugBreakInLoop(const char* loop_head,
   7192                                  const char** loop_bodies,
   7193                                  const char* loop_tail) {
   7194   // Receive 100 breaks for each test and then terminate JavaScript execution.
   7195   static int count = 0;
   7196 
   7197   for (int i = 0; loop_bodies[i] != NULL; i++) {
   7198     count++;
   7199     max_break_point_hit_count = count * 100;
   7200     terminate_after_max_break_point_hit = true;
   7201 
   7202     EmbeddedVector<char, 1024> buffer;
   7203     OS::SNPrintF(buffer,
   7204                  "function f() {%s%s%s}",
   7205                  loop_head, loop_bodies[i], loop_tail);
   7206 
   7207     // Function with infinite loop.
   7208     CompileRun(buffer.start());
   7209 
   7210     // Set the debug break to enter the debugger as soon as possible.
   7211     v8::Debug::DebugBreak();
   7212 
   7213     // Call function with infinite loop.
   7214     CompileRun("f();");
   7215     CHECK_EQ(count * 100, break_point_hit_count);
   7216 
   7217     CHECK(!v8::V8::IsExecutionTerminating());
   7218   }
   7219 }
   7220 
   7221 
   7222 TEST(DebugBreakLoop) {
   7223   v8::HandleScope scope;
   7224   DebugLocalContext env;
   7225 
   7226   // Register a debug event listener which sets the break flag and counts.
   7227   v8::Debug::SetDebugEventListener(DebugEventBreakMax);
   7228 
   7229   CompileRun("var a = 1;");
   7230   CompileRun("function g() { }");
   7231   CompileRun("function h() { }");
   7232 
   7233   const char* loop_bodies[] = {
   7234       "",
   7235       "g()",
   7236       "if (a == 0) { g() }",
   7237       "if (a == 1) { g() }",
   7238       "if (a == 0) { g() } else { h() }",
   7239       "if (a == 0) { continue }",
   7240       "if (a == 1) { continue }",
   7241       "switch (a) { case 1: g(); }",
   7242       "switch (a) { case 1: continue; }",
   7243       "switch (a) { case 1: g(); break; default: h() }",
   7244       "switch (a) { case 1: continue; break; default: h() }",
   7245       NULL
   7246   };
   7247 
   7248   TestDebugBreakInLoop("while (true) {", loop_bodies, "}");
   7249   TestDebugBreakInLoop("while (a == 1) {", loop_bodies, "}");
   7250 
   7251   TestDebugBreakInLoop("do {", loop_bodies, "} while (true)");
   7252   TestDebugBreakInLoop("do {", loop_bodies, "} while (a == 1)");
   7253 
   7254   TestDebugBreakInLoop("for (;;) {", loop_bodies, "}");
   7255   TestDebugBreakInLoop("for (;a == 1;) {", loop_bodies, "}");
   7256 
   7257   // Get rid of the debug event listener.
   7258   v8::Debug::SetDebugEventListener(NULL);
   7259   CheckDebuggerUnloaded();
   7260 }
   7261 
   7262 
   7263 #endif  // ENABLE_DEBUGGER_SUPPORT
   7264