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