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