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