Home | History | Annotate | Download | only in runtime
      1 // Copyright 2014 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/runtime/runtime-utils.h"
      6 
      7 #include "src/arguments.h"
      8 #include "src/debug/debug.h"
      9 #include "src/debug/debug-evaluate.h"
     10 #include "src/debug/debug-frames.h"
     11 #include "src/debug/debug-scopes.h"
     12 #include "src/frames-inl.h"
     13 #include "src/isolate-inl.h"
     14 #include "src/runtime/runtime.h"
     15 
     16 namespace v8 {
     17 namespace internal {
     18 
     19 RUNTIME_FUNCTION(Runtime_DebugBreak) {
     20   SealHandleScope shs(isolate);
     21   DCHECK(args.length() == 0);
     22   // Get the top-most JavaScript frame.
     23   JavaScriptFrameIterator it(isolate);
     24   isolate->debug()->Break(args, it.frame());
     25   isolate->debug()->SetAfterBreakTarget(it.frame());
     26   return isolate->heap()->undefined_value();
     27 }
     28 
     29 
     30 RUNTIME_FUNCTION(Runtime_HandleDebuggerStatement) {
     31   SealHandleScope shs(isolate);
     32   DCHECK(args.length() == 0);
     33   if (isolate->debug()->break_points_active()) {
     34     isolate->debug()->HandleDebugBreak();
     35   }
     36   return isolate->heap()->undefined_value();
     37 }
     38 
     39 
     40 // Adds a JavaScript function as a debug event listener.
     41 // args[0]: debug event listener function to set or null or undefined for
     42 //          clearing the event listener function
     43 // args[1]: object supplied during callback
     44 RUNTIME_FUNCTION(Runtime_SetDebugEventListener) {
     45   SealHandleScope shs(isolate);
     46   DCHECK(args.length() == 2);
     47   RUNTIME_ASSERT(args[0]->IsJSFunction() || args[0]->IsUndefined() ||
     48                  args[0]->IsNull());
     49   CONVERT_ARG_HANDLE_CHECKED(Object, callback, 0);
     50   CONVERT_ARG_HANDLE_CHECKED(Object, data, 1);
     51   isolate->debug()->SetEventListener(callback, data);
     52 
     53   return isolate->heap()->undefined_value();
     54 }
     55 
     56 
     57 RUNTIME_FUNCTION(Runtime_ScheduleBreak) {
     58   SealHandleScope shs(isolate);
     59   DCHECK(args.length() == 0);
     60   isolate->stack_guard()->RequestDebugBreak();
     61   return isolate->heap()->undefined_value();
     62 }
     63 
     64 
     65 static Handle<Object> DebugGetProperty(LookupIterator* it,
     66                                        bool* has_caught = NULL) {
     67   for (; it->IsFound(); it->Next()) {
     68     switch (it->state()) {
     69       case LookupIterator::NOT_FOUND:
     70       case LookupIterator::TRANSITION:
     71         UNREACHABLE();
     72       case LookupIterator::ACCESS_CHECK:
     73         // Ignore access checks.
     74         break;
     75       case LookupIterator::INTEGER_INDEXED_EXOTIC:
     76       case LookupIterator::INTERCEPTOR:
     77       case LookupIterator::JSPROXY:
     78         return it->isolate()->factory()->undefined_value();
     79       case LookupIterator::ACCESSOR: {
     80         Handle<Object> accessors = it->GetAccessors();
     81         if (!accessors->IsAccessorInfo()) {
     82           return it->isolate()->factory()->undefined_value();
     83         }
     84         MaybeHandle<Object> maybe_result =
     85             JSObject::GetPropertyWithAccessor(it, SLOPPY);
     86         Handle<Object> result;
     87         if (!maybe_result.ToHandle(&result)) {
     88           result = handle(it->isolate()->pending_exception(), it->isolate());
     89           it->isolate()->clear_pending_exception();
     90           if (has_caught != NULL) *has_caught = true;
     91         }
     92         return result;
     93       }
     94 
     95       case LookupIterator::DATA:
     96         return it->GetDataValue();
     97     }
     98   }
     99 
    100   return it->isolate()->factory()->undefined_value();
    101 }
    102 
    103 
    104 static Handle<Object> DebugGetProperty(Handle<Object> object,
    105                                        Handle<Name> name) {
    106   LookupIterator it(object, name);
    107   return DebugGetProperty(&it);
    108 }
    109 
    110 
    111 template <class IteratorType>
    112 static MaybeHandle<JSArray> GetIteratorInternalProperties(
    113     Isolate* isolate, Handle<IteratorType> object) {
    114   Factory* factory = isolate->factory();
    115   Handle<IteratorType> iterator = Handle<IteratorType>::cast(object);
    116   RUNTIME_ASSERT_HANDLIFIED(iterator->kind()->IsSmi(), JSArray);
    117   const char* kind = NULL;
    118   switch (Smi::cast(iterator->kind())->value()) {
    119     case IteratorType::kKindKeys:
    120       kind = "keys";
    121       break;
    122     case IteratorType::kKindValues:
    123       kind = "values";
    124       break;
    125     case IteratorType::kKindEntries:
    126       kind = "entries";
    127       break;
    128     default:
    129       RUNTIME_ASSERT_HANDLIFIED(false, JSArray);
    130   }
    131 
    132   Handle<FixedArray> result = factory->NewFixedArray(2 * 3);
    133   Handle<String> has_more =
    134       factory->NewStringFromAsciiChecked("[[IteratorHasMore]]");
    135   result->set(0, *has_more);
    136   result->set(1, isolate->heap()->ToBoolean(iterator->HasMore()));
    137 
    138   Handle<String> index =
    139       factory->NewStringFromAsciiChecked("[[IteratorIndex]]");
    140   result->set(2, *index);
    141   result->set(3, iterator->index());
    142 
    143   Handle<String> iterator_kind =
    144       factory->NewStringFromAsciiChecked("[[IteratorKind]]");
    145   result->set(4, *iterator_kind);
    146   Handle<String> kind_str = factory->NewStringFromAsciiChecked(kind);
    147   result->set(5, *kind_str);
    148   return factory->NewJSArrayWithElements(result);
    149 }
    150 
    151 
    152 MaybeHandle<JSArray> Runtime::GetInternalProperties(Isolate* isolate,
    153                                                     Handle<Object> object) {
    154   Factory* factory = isolate->factory();
    155   if (object->IsJSBoundFunction()) {
    156     Handle<JSBoundFunction> function = Handle<JSBoundFunction>::cast(object);
    157 
    158     Handle<FixedArray> result = factory->NewFixedArray(2 * 3);
    159     Handle<String> target =
    160         factory->NewStringFromAsciiChecked("[[TargetFunction]]");
    161     result->set(0, *target);
    162     result->set(1, function->bound_target_function());
    163 
    164     Handle<String> bound_this =
    165         factory->NewStringFromAsciiChecked("[[BoundThis]]");
    166     result->set(2, *bound_this);
    167     result->set(3, function->bound_this());
    168 
    169     Handle<String> bound_args =
    170         factory->NewStringFromAsciiChecked("[[BoundArgs]]");
    171     result->set(4, *bound_args);
    172     Handle<FixedArray> bound_arguments =
    173         factory->CopyFixedArray(handle(function->bound_arguments(), isolate));
    174     Handle<JSArray> arguments_array =
    175         factory->NewJSArrayWithElements(bound_arguments);
    176     result->set(5, *arguments_array);
    177     return factory->NewJSArrayWithElements(result);
    178   } else if (object->IsJSMapIterator()) {
    179     Handle<JSMapIterator> iterator = Handle<JSMapIterator>::cast(object);
    180     return GetIteratorInternalProperties(isolate, iterator);
    181   } else if (object->IsJSSetIterator()) {
    182     Handle<JSSetIterator> iterator = Handle<JSSetIterator>::cast(object);
    183     return GetIteratorInternalProperties(isolate, iterator);
    184   } else if (object->IsJSGeneratorObject()) {
    185     Handle<JSGeneratorObject> generator =
    186         Handle<JSGeneratorObject>::cast(object);
    187 
    188     const char* status = "suspended";
    189     if (generator->is_closed()) {
    190       status = "closed";
    191     } else if (generator->is_executing()) {
    192       status = "running";
    193     } else {
    194       DCHECK(generator->is_suspended());
    195     }
    196 
    197     Handle<FixedArray> result = factory->NewFixedArray(2 * 3);
    198     Handle<String> generator_status =
    199         factory->NewStringFromAsciiChecked("[[GeneratorStatus]]");
    200     result->set(0, *generator_status);
    201     Handle<String> status_str = factory->NewStringFromAsciiChecked(status);
    202     result->set(1, *status_str);
    203 
    204     Handle<String> function =
    205         factory->NewStringFromAsciiChecked("[[GeneratorFunction]]");
    206     result->set(2, *function);
    207     result->set(3, generator->function());
    208 
    209     Handle<String> receiver =
    210         factory->NewStringFromAsciiChecked("[[GeneratorReceiver]]");
    211     result->set(4, *receiver);
    212     result->set(5, generator->receiver());
    213     return factory->NewJSArrayWithElements(result);
    214   } else if (Object::IsPromise(object)) {
    215     Handle<JSObject> promise = Handle<JSObject>::cast(object);
    216 
    217     Handle<Object> status_obj =
    218         DebugGetProperty(promise, isolate->factory()->promise_status_symbol());
    219     RUNTIME_ASSERT_HANDLIFIED(status_obj->IsSmi(), JSArray);
    220     const char* status = "rejected";
    221     int status_val = Handle<Smi>::cast(status_obj)->value();
    222     switch (status_val) {
    223       case +1:
    224         status = "resolved";
    225         break;
    226       case 0:
    227         status = "pending";
    228         break;
    229       default:
    230         DCHECK_EQ(-1, status_val);
    231     }
    232 
    233     Handle<FixedArray> result = factory->NewFixedArray(2 * 2);
    234     Handle<String> promise_status =
    235         factory->NewStringFromAsciiChecked("[[PromiseStatus]]");
    236     result->set(0, *promise_status);
    237     Handle<String> status_str = factory->NewStringFromAsciiChecked(status);
    238     result->set(1, *status_str);
    239 
    240     Handle<Object> value_obj =
    241         DebugGetProperty(promise, isolate->factory()->promise_value_symbol());
    242     Handle<String> promise_value =
    243         factory->NewStringFromAsciiChecked("[[PromiseValue]]");
    244     result->set(2, *promise_value);
    245     result->set(3, *value_obj);
    246     return factory->NewJSArrayWithElements(result);
    247   } else if (object->IsJSValue()) {
    248     Handle<JSValue> js_value = Handle<JSValue>::cast(object);
    249 
    250     Handle<FixedArray> result = factory->NewFixedArray(2);
    251     Handle<String> primitive_value =
    252         factory->NewStringFromAsciiChecked("[[PrimitiveValue]]");
    253     result->set(0, *primitive_value);
    254     result->set(1, js_value->value());
    255     return factory->NewJSArrayWithElements(result);
    256   }
    257   return factory->NewJSArray(0);
    258 }
    259 
    260 
    261 RUNTIME_FUNCTION(Runtime_DebugGetInternalProperties) {
    262   HandleScope scope(isolate);
    263   DCHECK(args.length() == 1);
    264   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
    265   Handle<JSArray> result;
    266   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    267       isolate, result, Runtime::GetInternalProperties(isolate, obj));
    268   return *result;
    269 }
    270 
    271 
    272 // Get debugger related details for an object property, in the following format:
    273 // 0: Property value
    274 // 1: Property details
    275 // 2: Property value is exception
    276 // 3: Getter function if defined
    277 // 4: Setter function if defined
    278 // Items 2-4 are only filled if the property has either a getter or a setter.
    279 RUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) {
    280   HandleScope scope(isolate);
    281 
    282   DCHECK(args.length() == 2);
    283 
    284   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
    285   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
    286 
    287   // Make sure to set the current context to the context before the debugger was
    288   // entered (if the debugger is entered). The reason for switching context here
    289   // is that for some property lookups (accessors and interceptors) callbacks
    290   // into the embedding application can occour, and the embedding application
    291   // could have the assumption that its own native context is the current
    292   // context and not some internal debugger context.
    293   SaveContext save(isolate);
    294   if (isolate->debug()->in_debug_scope()) {
    295     isolate->set_context(*isolate->debug()->debugger_entry()->GetContext());
    296   }
    297 
    298   // Check if the name is trivially convertible to an index and get the element
    299   // if so.
    300   uint32_t index;
    301   // TODO(verwaest): Make sure DebugGetProperty can handle arrays, and remove
    302   // this special case.
    303   if (name->AsArrayIndex(&index)) {
    304     Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
    305     Handle<Object> element_or_char;
    306     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, element_or_char,
    307                                        Object::GetElement(isolate, obj, index));
    308     details->set(0, *element_or_char);
    309     details->set(1, PropertyDetails::Empty().AsSmi());
    310     return *isolate->factory()->NewJSArrayWithElements(details);
    311   }
    312 
    313   LookupIterator it(obj, name, LookupIterator::HIDDEN);
    314   bool has_caught = false;
    315   Handle<Object> value = DebugGetProperty(&it, &has_caught);
    316   if (!it.IsFound()) return isolate->heap()->undefined_value();
    317 
    318   Handle<Object> maybe_pair;
    319   if (it.state() == LookupIterator::ACCESSOR) {
    320     maybe_pair = it.GetAccessors();
    321   }
    322 
    323   // If the callback object is a fixed array then it contains JavaScript
    324   // getter and/or setter.
    325   bool has_js_accessors = !maybe_pair.is_null() && maybe_pair->IsAccessorPair();
    326   Handle<FixedArray> details =
    327       isolate->factory()->NewFixedArray(has_js_accessors ? 6 : 3);
    328   details->set(0, *value);
    329   // TODO(verwaest): Get rid of this random way of handling interceptors.
    330   PropertyDetails d = it.state() == LookupIterator::INTERCEPTOR
    331                           ? PropertyDetails::Empty()
    332                           : it.property_details();
    333   details->set(1, d.AsSmi());
    334   details->set(
    335       2, isolate->heap()->ToBoolean(it.state() == LookupIterator::INTERCEPTOR));
    336   if (has_js_accessors) {
    337     AccessorPair* accessors = AccessorPair::cast(*maybe_pair);
    338     details->set(3, isolate->heap()->ToBoolean(has_caught));
    339     details->set(4, accessors->GetComponent(ACCESSOR_GETTER));
    340     details->set(5, accessors->GetComponent(ACCESSOR_SETTER));
    341   }
    342 
    343   return *isolate->factory()->NewJSArrayWithElements(details);
    344 }
    345 
    346 
    347 RUNTIME_FUNCTION(Runtime_DebugGetProperty) {
    348   HandleScope scope(isolate);
    349 
    350   DCHECK(args.length() == 2);
    351 
    352   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
    353   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
    354 
    355   LookupIterator it(obj, name);
    356   return *DebugGetProperty(&it);
    357 }
    358 
    359 
    360 // Return the property type calculated from the property details.
    361 // args[0]: smi with property details.
    362 RUNTIME_FUNCTION(Runtime_DebugPropertyTypeFromDetails) {
    363   SealHandleScope shs(isolate);
    364   DCHECK(args.length() == 1);
    365   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
    366   return Smi::FromInt(static_cast<int>(details.type()));
    367 }
    368 
    369 
    370 // Return the property attribute calculated from the property details.
    371 // args[0]: smi with property details.
    372 RUNTIME_FUNCTION(Runtime_DebugPropertyAttributesFromDetails) {
    373   SealHandleScope shs(isolate);
    374   DCHECK(args.length() == 1);
    375   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
    376   return Smi::FromInt(static_cast<int>(details.attributes()));
    377 }
    378 
    379 
    380 // Return the property insertion index calculated from the property details.
    381 // args[0]: smi with property details.
    382 RUNTIME_FUNCTION(Runtime_DebugPropertyIndexFromDetails) {
    383   SealHandleScope shs(isolate);
    384   DCHECK(args.length() == 1);
    385   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
    386   // TODO(verwaest): Works only for dictionary mode holders.
    387   return Smi::FromInt(details.dictionary_index());
    388 }
    389 
    390 
    391 // Return property value from named interceptor.
    392 // args[0]: object
    393 // args[1]: property name
    394 RUNTIME_FUNCTION(Runtime_DebugNamedInterceptorPropertyValue) {
    395   HandleScope scope(isolate);
    396   DCHECK(args.length() == 2);
    397   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
    398   RUNTIME_ASSERT(obj->HasNamedInterceptor());
    399   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
    400 
    401   Handle<Object> result;
    402   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
    403                                      JSObject::GetProperty(obj, name));
    404   return *result;
    405 }
    406 
    407 
    408 // Return element value from indexed interceptor.
    409 // args[0]: object
    410 // args[1]: index
    411 RUNTIME_FUNCTION(Runtime_DebugIndexedInterceptorElementValue) {
    412   HandleScope scope(isolate);
    413   DCHECK(args.length() == 2);
    414   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
    415   RUNTIME_ASSERT(obj->HasIndexedInterceptor());
    416   CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
    417   Handle<Object> result;
    418   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
    419                                      Object::GetElement(isolate, obj, index));
    420   return *result;
    421 }
    422 
    423 
    424 RUNTIME_FUNCTION(Runtime_CheckExecutionState) {
    425   SealHandleScope shs(isolate);
    426   DCHECK(args.length() == 1);
    427   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
    428   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
    429   return isolate->heap()->true_value();
    430 }
    431 
    432 
    433 RUNTIME_FUNCTION(Runtime_GetFrameCount) {
    434   HandleScope scope(isolate);
    435   DCHECK(args.length() == 1);
    436   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
    437   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
    438 
    439   // Count all frames which are relevant to debugging stack trace.
    440   int n = 0;
    441   StackFrame::Id id = isolate->debug()->break_frame_id();
    442   if (id == StackFrame::NO_ID) {
    443     // If there is no JavaScript stack frame count is 0.
    444     return Smi::FromInt(0);
    445   }
    446 
    447   for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
    448     List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
    449     it.frame()->Summarize(&frames);
    450     for (int i = frames.length() - 1; i >= 0; i--) {
    451       // Omit functions from native and extension scripts.
    452       if (frames[i].function()->shared()->IsSubjectToDebugging()) n++;
    453     }
    454   }
    455   return Smi::FromInt(n);
    456 }
    457 
    458 
    459 static const int kFrameDetailsFrameIdIndex = 0;
    460 static const int kFrameDetailsReceiverIndex = 1;
    461 static const int kFrameDetailsFunctionIndex = 2;
    462 static const int kFrameDetailsArgumentCountIndex = 3;
    463 static const int kFrameDetailsLocalCountIndex = 4;
    464 static const int kFrameDetailsSourcePositionIndex = 5;
    465 static const int kFrameDetailsConstructCallIndex = 6;
    466 static const int kFrameDetailsAtReturnIndex = 7;
    467 static const int kFrameDetailsFlagsIndex = 8;
    468 static const int kFrameDetailsFirstDynamicIndex = 9;
    469 
    470 
    471 // Return an array with frame details
    472 // args[0]: number: break id
    473 // args[1]: number: frame index
    474 //
    475 // The array returned contains the following information:
    476 // 0: Frame id
    477 // 1: Receiver
    478 // 2: Function
    479 // 3: Argument count
    480 // 4: Local count
    481 // 5: Source position
    482 // 6: Constructor call
    483 // 7: Is at return
    484 // 8: Flags
    485 // Arguments name, value
    486 // Locals name, value
    487 // Return value if any
    488 RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
    489   HandleScope scope(isolate);
    490   DCHECK(args.length() == 2);
    491   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
    492   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
    493 
    494   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
    495   Heap* heap = isolate->heap();
    496 
    497   // Find the relevant frame with the requested index.
    498   StackFrame::Id id = isolate->debug()->break_frame_id();
    499   if (id == StackFrame::NO_ID) {
    500     // If there are no JavaScript stack frames return undefined.
    501     return heap->undefined_value();
    502   }
    503 
    504   JavaScriptFrameIterator it(isolate, id);
    505   // Inlined frame index in optimized frame, starting from outer function.
    506   int inlined_jsframe_index =
    507       DebugFrameHelper::FindIndexedNonNativeFrame(&it, index);
    508   if (inlined_jsframe_index == -1) return heap->undefined_value();
    509 
    510   FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate);
    511   bool is_optimized = it.frame()->is_optimized();
    512 
    513   // Traverse the saved contexts chain to find the active context for the
    514   // selected frame.
    515   SaveContext* save =
    516       DebugFrameHelper::FindSavedContextForFrame(isolate, it.frame());
    517 
    518   // Get the frame id.
    519   Handle<Object> frame_id(DebugFrameHelper::WrapFrameId(it.frame()->id()),
    520                           isolate);
    521 
    522   // Find source position in unoptimized code.
    523   int position = frame_inspector.GetSourcePosition();
    524 
    525   // Check for constructor frame.
    526   bool constructor = frame_inspector.IsConstructor();
    527 
    528   // Get scope info and read from it for local variable information.
    529   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
    530   RUNTIME_ASSERT(function->shared()->IsSubjectToDebugging());
    531   Handle<SharedFunctionInfo> shared(function->shared());
    532   Handle<ScopeInfo> scope_info(shared->scope_info());
    533   DCHECK(*scope_info != ScopeInfo::Empty(isolate));
    534 
    535   // Get the locals names and values into a temporary array.
    536   int local_count = scope_info->LocalCount();
    537   for (int slot = 0; slot < scope_info->LocalCount(); ++slot) {
    538     // Hide compiler-introduced temporary variables, whether on the stack or on
    539     // the context.
    540     if (scope_info->LocalIsSynthetic(slot)) local_count--;
    541   }
    542 
    543   Handle<FixedArray> locals =
    544       isolate->factory()->NewFixedArray(local_count * 2);
    545 
    546   // Fill in the values of the locals.
    547   int local = 0;
    548   int i = 0;
    549   for (; i < scope_info->StackLocalCount(); ++i) {
    550     // Use the value from the stack.
    551     if (scope_info->LocalIsSynthetic(i)) continue;
    552     locals->set(local * 2, scope_info->LocalName(i));
    553     locals->set(local * 2 + 1, frame_inspector.GetExpression(i));
    554     local++;
    555   }
    556   if (local < local_count) {
    557     // Get the context containing declarations.
    558     Handle<Context> context(
    559         Context::cast(frame_inspector.GetContext())->declaration_context());
    560     for (; i < scope_info->LocalCount(); ++i) {
    561       if (scope_info->LocalIsSynthetic(i)) continue;
    562       Handle<String> name(scope_info->LocalName(i));
    563       VariableMode mode;
    564       InitializationFlag init_flag;
    565       MaybeAssignedFlag maybe_assigned_flag;
    566       locals->set(local * 2, *name);
    567       int context_slot_index = ScopeInfo::ContextSlotIndex(
    568           scope_info, name, &mode, &init_flag, &maybe_assigned_flag);
    569       Object* value = context->get(context_slot_index);
    570       locals->set(local * 2 + 1, value);
    571       local++;
    572     }
    573   }
    574 
    575   // Check whether this frame is positioned at return. If not top
    576   // frame or if the frame is optimized it cannot be at a return.
    577   bool at_return = false;
    578   if (!is_optimized && index == 0) {
    579     at_return = isolate->debug()->IsBreakAtReturn(it.frame());
    580   }
    581 
    582   // If positioned just before return find the value to be returned and add it
    583   // to the frame information.
    584   Handle<Object> return_value = isolate->factory()->undefined_value();
    585   if (at_return) {
    586     StackFrameIterator it2(isolate);
    587     Address internal_frame_sp = NULL;
    588     while (!it2.done()) {
    589       if (it2.frame()->is_internal()) {
    590         internal_frame_sp = it2.frame()->sp();
    591       } else {
    592         if (it2.frame()->is_java_script()) {
    593           if (it2.frame()->id() == it.frame()->id()) {
    594             // The internal frame just before the JavaScript frame contains the
    595             // value to return on top. A debug break at return will create an
    596             // internal frame to store the return value (eax/rax/r0) before
    597             // entering the debug break exit frame.
    598             if (internal_frame_sp != NULL) {
    599               return_value =
    600                   Handle<Object>(Memory::Object_at(internal_frame_sp), isolate);
    601               break;
    602             }
    603           }
    604         }
    605 
    606         // Indicate that the previous frame was not an internal frame.
    607         internal_frame_sp = NULL;
    608       }
    609       it2.Advance();
    610     }
    611   }
    612 
    613   // Now advance to the arguments adapter frame (if any). It contains all
    614   // the provided parameters whereas the function frame always have the number
    615   // of arguments matching the functions parameters. The rest of the
    616   // information (except for what is collected above) is the same.
    617   if ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) {
    618     it.AdvanceToArgumentsFrame();
    619     frame_inspector.SetArgumentsFrame(it.frame());
    620   }
    621 
    622   // Find the number of arguments to fill. At least fill the number of
    623   // parameters for the function and fill more if more parameters are provided.
    624   int argument_count = scope_info->ParameterCount();
    625   if (argument_count < frame_inspector.GetParametersCount()) {
    626     argument_count = frame_inspector.GetParametersCount();
    627   }
    628 
    629   // Calculate the size of the result.
    630   int details_size = kFrameDetailsFirstDynamicIndex +
    631                      2 * (argument_count + local_count) + (at_return ? 1 : 0);
    632   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
    633 
    634   // Add the frame id.
    635   details->set(kFrameDetailsFrameIdIndex, *frame_id);
    636 
    637   // Add the function (same as in function frame).
    638   details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction());
    639 
    640   // Add the arguments count.
    641   details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
    642 
    643   // Add the locals count
    644   details->set(kFrameDetailsLocalCountIndex, Smi::FromInt(local_count));
    645 
    646   // Add the source position.
    647   if (position != RelocInfo::kNoPosition) {
    648     details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
    649   } else {
    650     details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value());
    651   }
    652 
    653   // Add the constructor information.
    654   details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor));
    655 
    656   // Add the at return information.
    657   details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
    658 
    659   // Add flags to indicate information on whether this frame is
    660   //   bit 0: invoked in the debugger context.
    661   //   bit 1: optimized frame.
    662   //   bit 2: inlined in optimized frame
    663   int flags = 0;
    664   if (*save->context() == *isolate->debug()->debug_context()) {
    665     flags |= 1 << 0;
    666   }
    667   if (is_optimized) {
    668     flags |= 1 << 1;
    669     flags |= inlined_jsframe_index << 2;
    670   }
    671   details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
    672 
    673   // Fill the dynamic part.
    674   int details_index = kFrameDetailsFirstDynamicIndex;
    675 
    676   // Add arguments name and value.
    677   for (int i = 0; i < argument_count; i++) {
    678     // Name of the argument.
    679     if (i < scope_info->ParameterCount()) {
    680       details->set(details_index++, scope_info->ParameterName(i));
    681     } else {
    682       details->set(details_index++, heap->undefined_value());
    683     }
    684 
    685     // Parameter value.
    686     if (i < frame_inspector.GetParametersCount()) {
    687       // Get the value from the stack.
    688       details->set(details_index++, frame_inspector.GetParameter(i));
    689     } else {
    690       details->set(details_index++, heap->undefined_value());
    691     }
    692   }
    693 
    694   // Add locals name and value from the temporary copy from the function frame.
    695   for (int i = 0; i < local_count * 2; i++) {
    696     details->set(details_index++, locals->get(i));
    697   }
    698 
    699   // Add the value being returned.
    700   if (at_return) {
    701     details->set(details_index++, *return_value);
    702   }
    703 
    704   // Add the receiver (same as in function frame).
    705   Handle<Object> receiver(it.frame()->receiver(), isolate);
    706   DCHECK(!function->shared()->IsBuiltin());
    707   if (!receiver->IsJSObject() && is_sloppy(shared->language_mode())) {
    708     // If the receiver is not a JSObject and the function is not a builtin or
    709     // strict-mode we have hit an optimization where a value object is not
    710     // converted into a wrapped JS objects. To hide this optimization from the
    711     // debugger, we wrap the receiver by creating correct wrapper object based
    712     // on the function's native context.
    713     // See ECMA-262 6.0, 9.2.1.2, 6 b iii.
    714     if (receiver->IsUndefined()) {
    715       receiver = handle(function->global_proxy());
    716     } else {
    717       Context* context = function->context();
    718       Handle<Context> native_context(Context::cast(context->native_context()));
    719       if (!Object::ToObject(isolate, receiver, native_context)
    720                .ToHandle(&receiver)) {
    721         // This only happens if the receiver is forcibly set in %_CallFunction.
    722         return heap->undefined_value();
    723       }
    724     }
    725   }
    726   details->set(kFrameDetailsReceiverIndex, *receiver);
    727 
    728   DCHECK_EQ(details_size, details_index);
    729   return *isolate->factory()->NewJSArrayWithElements(details);
    730 }
    731 
    732 
    733 RUNTIME_FUNCTION(Runtime_GetScopeCount) {
    734   HandleScope scope(isolate);
    735   DCHECK(args.length() == 2);
    736   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
    737   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
    738 
    739   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
    740 
    741   // Get the frame where the debugging is performed.
    742   StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id);
    743   JavaScriptFrameIterator it(isolate, id);
    744   JavaScriptFrame* frame = it.frame();
    745   FrameInspector frame_inspector(frame, 0, isolate);
    746 
    747   // Count the visible scopes.
    748   int n = 0;
    749   for (ScopeIterator it(isolate, &frame_inspector); !it.Done(); it.Next()) {
    750     n++;
    751   }
    752 
    753   return Smi::FromInt(n);
    754 }
    755 
    756 
    757 // Returns the list of step-in positions (text offset) in a function of the
    758 // stack frame in a range from the current debug break position to the end
    759 // of the corresponding statement.
    760 RUNTIME_FUNCTION(Runtime_GetStepInPositions) {
    761   HandleScope scope(isolate);
    762   DCHECK(args.length() == 2);
    763   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
    764   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
    765 
    766   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
    767 
    768   // Get the frame where the debugging is performed.
    769   StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id);
    770   JavaScriptFrameIterator frame_it(isolate, id);
    771   RUNTIME_ASSERT(!frame_it.done());
    772 
    773   List<int> positions;
    774   isolate->debug()->GetStepinPositions(frame_it.frame(), id, &positions);
    775   Factory* factory = isolate->factory();
    776   Handle<FixedArray> array = factory->NewFixedArray(positions.length());
    777   for (int i = 0; i < positions.length(); ++i) {
    778     array->set(i, Smi::FromInt(positions[i]));
    779   }
    780   return *factory->NewJSArrayWithElements(array, FAST_SMI_ELEMENTS);
    781 }
    782 
    783 
    784 // Return an array with scope details
    785 // args[0]: number: break id
    786 // args[1]: number: frame index
    787 // args[2]: number: inlined frame index
    788 // args[3]: number: scope index
    789 //
    790 // The array returned contains the following information:
    791 // 0: Scope type
    792 // 1: Scope object
    793 RUNTIME_FUNCTION(Runtime_GetScopeDetails) {
    794   HandleScope scope(isolate);
    795   DCHECK(args.length() == 4);
    796   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
    797   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
    798 
    799   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
    800   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
    801   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
    802 
    803   // Get the frame where the debugging is performed.
    804   StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id);
    805   JavaScriptFrameIterator frame_it(isolate, id);
    806   JavaScriptFrame* frame = frame_it.frame();
    807   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
    808 
    809   // Find the requested scope.
    810   int n = 0;
    811   ScopeIterator it(isolate, &frame_inspector);
    812   for (; !it.Done() && n < index; it.Next()) {
    813     n++;
    814   }
    815   if (it.Done()) {
    816     return isolate->heap()->undefined_value();
    817   }
    818   Handle<JSObject> details;
    819   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, details,
    820                                      it.MaterializeScopeDetails());
    821   return *details;
    822 }
    823 
    824 
    825 // Return an array of scope details
    826 // args[0]: number: break id
    827 // args[1]: number: frame index
    828 // args[2]: number: inlined frame index
    829 // args[3]: boolean: ignore nested scopes
    830 //
    831 // The array returned contains arrays with the following information:
    832 // 0: Scope type
    833 // 1: Scope object
    834 RUNTIME_FUNCTION(Runtime_GetAllScopesDetails) {
    835   HandleScope scope(isolate);
    836   DCHECK(args.length() == 3 || args.length() == 4);
    837   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
    838   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
    839 
    840   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
    841   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
    842 
    843   ScopeIterator::Option option = ScopeIterator::DEFAULT;
    844   if (args.length() == 4) {
    845     CONVERT_BOOLEAN_ARG_CHECKED(flag, 3);
    846     if (flag) option = ScopeIterator::IGNORE_NESTED_SCOPES;
    847   }
    848 
    849   // Get the frame where the debugging is performed.
    850   StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id);
    851   JavaScriptFrameIterator frame_it(isolate, id);
    852   JavaScriptFrame* frame = frame_it.frame();
    853   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
    854 
    855   List<Handle<JSObject> > result(4);
    856   ScopeIterator it(isolate, &frame_inspector, option);
    857   for (; !it.Done(); it.Next()) {
    858     Handle<JSObject> details;
    859     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, details,
    860                                        it.MaterializeScopeDetails());
    861     result.Add(details);
    862   }
    863 
    864   Handle<FixedArray> array = isolate->factory()->NewFixedArray(result.length());
    865   for (int i = 0; i < result.length(); ++i) {
    866     array->set(i, *result[i]);
    867   }
    868   return *isolate->factory()->NewJSArrayWithElements(array);
    869 }
    870 
    871 
    872 RUNTIME_FUNCTION(Runtime_GetFunctionScopeCount) {
    873   HandleScope scope(isolate);
    874   DCHECK_EQ(1, args.length());
    875 
    876   // Check arguments.
    877   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
    878 
    879   // Count the visible scopes.
    880   int n = 0;
    881   if (function->IsJSFunction()) {
    882     for (ScopeIterator it(isolate, Handle<JSFunction>::cast(function));
    883          !it.Done(); it.Next()) {
    884       n++;
    885     }
    886   }
    887 
    888   return Smi::FromInt(n);
    889 }
    890 
    891 
    892 RUNTIME_FUNCTION(Runtime_GetFunctionScopeDetails) {
    893   HandleScope scope(isolate);
    894   DCHECK(args.length() == 2);
    895 
    896   // Check arguments.
    897   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
    898   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
    899 
    900   // Find the requested scope.
    901   int n = 0;
    902   ScopeIterator it(isolate, fun);
    903   for (; !it.Done() && n < index; it.Next()) {
    904     n++;
    905   }
    906   if (it.Done()) {
    907     return isolate->heap()->undefined_value();
    908   }
    909 
    910   Handle<JSObject> details;
    911   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, details,
    912                                      it.MaterializeScopeDetails());
    913   return *details;
    914 }
    915 
    916 
    917 static bool SetScopeVariableValue(ScopeIterator* it, int index,
    918                                   Handle<String> variable_name,
    919                                   Handle<Object> new_value) {
    920   for (int n = 0; !it->Done() && n < index; it->Next()) {
    921     n++;
    922   }
    923   if (it->Done()) {
    924     return false;
    925   }
    926   return it->SetVariableValue(variable_name, new_value);
    927 }
    928 
    929 
    930 // Change variable value in closure or local scope
    931 // args[0]: number or JsFunction: break id or function
    932 // args[1]: number: frame index (when arg[0] is break id)
    933 // args[2]: number: inlined frame index (when arg[0] is break id)
    934 // args[3]: number: scope index
    935 // args[4]: string: variable name
    936 // args[5]: object: new value
    937 //
    938 // Return true if success and false otherwise
    939 RUNTIME_FUNCTION(Runtime_SetScopeVariableValue) {
    940   HandleScope scope(isolate);
    941   DCHECK(args.length() == 6);
    942 
    943   // Check arguments.
    944   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
    945   CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4);
    946   CONVERT_ARG_HANDLE_CHECKED(Object, new_value, 5);
    947 
    948   bool res;
    949   if (args[0]->IsNumber()) {
    950     CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
    951     RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
    952 
    953     CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
    954     CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
    955 
    956     // Get the frame where the debugging is performed.
    957     StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id);
    958     JavaScriptFrameIterator frame_it(isolate, id);
    959     JavaScriptFrame* frame = frame_it.frame();
    960     FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
    961 
    962     ScopeIterator it(isolate, &frame_inspector);
    963     res = SetScopeVariableValue(&it, index, variable_name, new_value);
    964   } else {
    965     CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
    966     ScopeIterator it(isolate, fun);
    967     res = SetScopeVariableValue(&it, index, variable_name, new_value);
    968   }
    969 
    970   return isolate->heap()->ToBoolean(res);
    971 }
    972 
    973 
    974 RUNTIME_FUNCTION(Runtime_DebugPrintScopes) {
    975   HandleScope scope(isolate);
    976   DCHECK(args.length() == 0);
    977 
    978 #ifdef DEBUG
    979   // Print the scopes for the top frame.
    980   StackFrameLocator locator(isolate);
    981   JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
    982   FrameInspector frame_inspector(frame, 0, isolate);
    983 
    984   for (ScopeIterator it(isolate, &frame_inspector); !it.Done(); it.Next()) {
    985     it.DebugPrint();
    986   }
    987 #endif
    988   return isolate->heap()->undefined_value();
    989 }
    990 
    991 
    992 RUNTIME_FUNCTION(Runtime_GetThreadCount) {
    993   HandleScope scope(isolate);
    994   DCHECK(args.length() == 1);
    995   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
    996   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
    997 
    998   // Count all archived V8 threads.
    999   int n = 0;
   1000   for (ThreadState* thread = isolate->thread_manager()->FirstThreadStateInUse();
   1001        thread != NULL; thread = thread->Next()) {
   1002     n++;
   1003   }
   1004 
   1005   // Total number of threads is current thread and archived threads.
   1006   return Smi::FromInt(n + 1);
   1007 }
   1008 
   1009 
   1010 static const int kThreadDetailsCurrentThreadIndex = 0;
   1011 static const int kThreadDetailsThreadIdIndex = 1;
   1012 static const int kThreadDetailsSize = 2;
   1013 
   1014 // Return an array with thread details
   1015 // args[0]: number: break id
   1016 // args[1]: number: thread index
   1017 //
   1018 // The array returned contains the following information:
   1019 // 0: Is current thread?
   1020 // 1: Thread id
   1021 RUNTIME_FUNCTION(Runtime_GetThreadDetails) {
   1022   HandleScope scope(isolate);
   1023   DCHECK(args.length() == 2);
   1024   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   1025   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
   1026 
   1027   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
   1028 
   1029   // Allocate array for result.
   1030   Handle<FixedArray> details =
   1031       isolate->factory()->NewFixedArray(kThreadDetailsSize);
   1032 
   1033   // Thread index 0 is current thread.
   1034   if (index == 0) {
   1035     // Fill the details.
   1036     details->set(kThreadDetailsCurrentThreadIndex,
   1037                  isolate->heap()->true_value());
   1038     details->set(kThreadDetailsThreadIdIndex,
   1039                  Smi::FromInt(ThreadId::Current().ToInteger()));
   1040   } else {
   1041     // Find the thread with the requested index.
   1042     int n = 1;
   1043     ThreadState* thread = isolate->thread_manager()->FirstThreadStateInUse();
   1044     while (index != n && thread != NULL) {
   1045       thread = thread->Next();
   1046       n++;
   1047     }
   1048     if (thread == NULL) {
   1049       return isolate->heap()->undefined_value();
   1050     }
   1051 
   1052     // Fill the details.
   1053     details->set(kThreadDetailsCurrentThreadIndex,
   1054                  isolate->heap()->false_value());
   1055     details->set(kThreadDetailsThreadIdIndex,
   1056                  Smi::FromInt(thread->id().ToInteger()));
   1057   }
   1058 
   1059   // Convert to JS array and return.
   1060   return *isolate->factory()->NewJSArrayWithElements(details);
   1061 }
   1062 
   1063 
   1064 // Sets the disable break state
   1065 // args[0]: disable break state
   1066 RUNTIME_FUNCTION(Runtime_SetBreakPointsActive) {
   1067   HandleScope scope(isolate);
   1068   DCHECK(args.length() == 1);
   1069   CONVERT_BOOLEAN_ARG_CHECKED(active, 0);
   1070   isolate->debug()->set_break_points_active(active);
   1071   return isolate->heap()->undefined_value();
   1072 }
   1073 
   1074 
   1075 static bool IsPositionAlignmentCodeCorrect(int alignment) {
   1076   return alignment == STATEMENT_ALIGNED || alignment == BREAK_POSITION_ALIGNED;
   1077 }
   1078 
   1079 
   1080 RUNTIME_FUNCTION(Runtime_GetBreakLocations) {
   1081   HandleScope scope(isolate);
   1082   DCHECK(args.length() == 2);
   1083   RUNTIME_ASSERT(isolate->debug()->is_active());
   1084   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
   1085   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[1]);
   1086 
   1087   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
   1088     return isolate->ThrowIllegalOperation();
   1089   }
   1090   BreakPositionAlignment alignment =
   1091       static_cast<BreakPositionAlignment>(statement_aligned_code);
   1092 
   1093   Handle<SharedFunctionInfo> shared(fun->shared());
   1094   // Find the number of break points
   1095   Handle<Object> break_locations =
   1096       Debug::GetSourceBreakLocations(shared, alignment);
   1097   if (break_locations->IsUndefined()) return isolate->heap()->undefined_value();
   1098   // Return array as JS array
   1099   return *isolate->factory()->NewJSArrayWithElements(
   1100       Handle<FixedArray>::cast(break_locations));
   1101 }
   1102 
   1103 
   1104 // Set a break point in a function.
   1105 // args[0]: function
   1106 // args[1]: number: break source position (within the function source)
   1107 // args[2]: number: break point object
   1108 RUNTIME_FUNCTION(Runtime_SetFunctionBreakPoint) {
   1109   HandleScope scope(isolate);
   1110   DCHECK(args.length() == 3);
   1111   RUNTIME_ASSERT(isolate->debug()->is_active());
   1112   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   1113   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
   1114   RUNTIME_ASSERT(source_position >= function->shared()->start_position() &&
   1115                  source_position <= function->shared()->end_position());
   1116   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 2);
   1117 
   1118   // Set break point.
   1119   RUNTIME_ASSERT(isolate->debug()->SetBreakPoint(
   1120       function, break_point_object_arg, &source_position));
   1121 
   1122   return Smi::FromInt(source_position);
   1123 }
   1124 
   1125 
   1126 // Changes the state of a break point in a script and returns source position
   1127 // where break point was set. NOTE: Regarding performance see the NOTE for
   1128 // GetScriptFromScriptData.
   1129 // args[0]: script to set break point in
   1130 // args[1]: number: break source position (within the script source)
   1131 // args[2]: number, breakpoint position alignment
   1132 // args[3]: number: break point object
   1133 RUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) {
   1134   HandleScope scope(isolate);
   1135   DCHECK(args.length() == 4);
   1136   RUNTIME_ASSERT(isolate->debug()->is_active());
   1137   CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
   1138   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
   1139   RUNTIME_ASSERT(source_position >= 0);
   1140   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[2]);
   1141   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 3);
   1142 
   1143   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
   1144     return isolate->ThrowIllegalOperation();
   1145   }
   1146   BreakPositionAlignment alignment =
   1147       static_cast<BreakPositionAlignment>(statement_aligned_code);
   1148 
   1149   // Get the script from the script wrapper.
   1150   RUNTIME_ASSERT(wrapper->value()->IsScript());
   1151   Handle<Script> script(Script::cast(wrapper->value()));
   1152 
   1153   // Set break point.
   1154   if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg,
   1155                                                 &source_position, alignment)) {
   1156     return isolate->heap()->undefined_value();
   1157   }
   1158 
   1159   return Smi::FromInt(source_position);
   1160 }
   1161 
   1162 
   1163 // Clear a break point
   1164 // args[0]: number: break point object
   1165 RUNTIME_FUNCTION(Runtime_ClearBreakPoint) {
   1166   HandleScope scope(isolate);
   1167   DCHECK(args.length() == 1);
   1168   RUNTIME_ASSERT(isolate->debug()->is_active());
   1169   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 0);
   1170 
   1171   // Clear break point.
   1172   isolate->debug()->ClearBreakPoint(break_point_object_arg);
   1173 
   1174   return isolate->heap()->undefined_value();
   1175 }
   1176 
   1177 
   1178 // Change the state of break on exceptions.
   1179 // args[0]: Enum value indicating whether to affect caught/uncaught exceptions.
   1180 // args[1]: Boolean indicating on/off.
   1181 RUNTIME_FUNCTION(Runtime_ChangeBreakOnException) {
   1182   HandleScope scope(isolate);
   1183   DCHECK(args.length() == 2);
   1184   CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
   1185   CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
   1186 
   1187   // If the number doesn't match an enum value, the ChangeBreakOnException
   1188   // function will default to affecting caught exceptions.
   1189   ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
   1190   // Update break point state.
   1191   isolate->debug()->ChangeBreakOnException(type, enable);
   1192   return isolate->heap()->undefined_value();
   1193 }
   1194 
   1195 
   1196 // Returns the state of break on exceptions
   1197 // args[0]: boolean indicating uncaught exceptions
   1198 RUNTIME_FUNCTION(Runtime_IsBreakOnException) {
   1199   HandleScope scope(isolate);
   1200   DCHECK(args.length() == 1);
   1201   CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
   1202 
   1203   ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
   1204   bool result = isolate->debug()->IsBreakOnException(type);
   1205   return Smi::FromInt(result);
   1206 }
   1207 
   1208 
   1209 // Prepare for stepping
   1210 // args[0]: break id for checking execution state
   1211 // args[1]: step action from the enumeration StepAction
   1212 // args[2]: number of times to perform the step, for step out it is the number
   1213 //          of frames to step down.
   1214 RUNTIME_FUNCTION(Runtime_PrepareStep) {
   1215   HandleScope scope(isolate);
   1216   DCHECK(args.length() == 2);
   1217   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   1218   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
   1219 
   1220   if (!args[1]->IsNumber()) {
   1221     return isolate->Throw(isolate->heap()->illegal_argument_string());
   1222   }
   1223 
   1224   // Get the step action and check validity.
   1225   StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1]));
   1226   if (step_action != StepIn && step_action != StepNext &&
   1227       step_action != StepOut && step_action != StepFrame) {
   1228     return isolate->Throw(isolate->heap()->illegal_argument_string());
   1229   }
   1230 
   1231   // Clear all current stepping setup.
   1232   isolate->debug()->ClearStepping();
   1233 
   1234   // Prepare step.
   1235   isolate->debug()->PrepareStep(static_cast<StepAction>(step_action));
   1236   return isolate->heap()->undefined_value();
   1237 }
   1238 
   1239 
   1240 // Clear all stepping set by PrepareStep.
   1241 RUNTIME_FUNCTION(Runtime_ClearStepping) {
   1242   HandleScope scope(isolate);
   1243   DCHECK(args.length() == 0);
   1244   RUNTIME_ASSERT(isolate->debug()->is_active());
   1245   isolate->debug()->ClearStepping();
   1246   return isolate->heap()->undefined_value();
   1247 }
   1248 
   1249 
   1250 RUNTIME_FUNCTION(Runtime_DebugEvaluate) {
   1251   HandleScope scope(isolate);
   1252 
   1253   // Check the execution state and decode arguments frame and source to be
   1254   // evaluated.
   1255   DCHECK(args.length() == 6);
   1256   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   1257   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
   1258 
   1259   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
   1260   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
   1261   CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
   1262   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4);
   1263   CONVERT_ARG_HANDLE_CHECKED(HeapObject, context_extension, 5);
   1264 
   1265   StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id);
   1266 
   1267   Handle<Object> result;
   1268   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1269       isolate, result,
   1270       DebugEvaluate::Local(isolate, id, inlined_jsframe_index, source,
   1271                            disable_break, context_extension));
   1272   return *result;
   1273 }
   1274 
   1275 
   1276 RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) {
   1277   HandleScope scope(isolate);
   1278 
   1279   // Check the execution state and decode arguments frame and source to be
   1280   // evaluated.
   1281   DCHECK(args.length() == 4);
   1282   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
   1283   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
   1284 
   1285   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
   1286   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 2);
   1287   CONVERT_ARG_HANDLE_CHECKED(HeapObject, context_extension, 3);
   1288 
   1289   Handle<Object> result;
   1290   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1291       isolate, result,
   1292       DebugEvaluate::Global(isolate, source, disable_break, context_extension));
   1293   return *result;
   1294 }
   1295 
   1296 
   1297 RUNTIME_FUNCTION(Runtime_DebugGetLoadedScripts) {
   1298   HandleScope scope(isolate);
   1299   DCHECK(args.length() == 0);
   1300   RUNTIME_ASSERT(isolate->debug()->is_active());
   1301 
   1302   Handle<FixedArray> instances;
   1303   {
   1304     DebugScope debug_scope(isolate->debug());
   1305     if (debug_scope.failed()) {
   1306       DCHECK(isolate->has_pending_exception());
   1307       return isolate->heap()->exception();
   1308     }
   1309     // Fill the script objects.
   1310     instances = isolate->debug()->GetLoadedScripts();
   1311   }
   1312 
   1313   // Convert the script objects to proper JS objects.
   1314   for (int i = 0; i < instances->length(); i++) {
   1315     Handle<Script> script = Handle<Script>(Script::cast(instances->get(i)));
   1316     // Get the script wrapper in a local handle before calling GetScriptWrapper,
   1317     // because using
   1318     //   instances->set(i, *GetScriptWrapper(script))
   1319     // is unsafe as GetScriptWrapper might call GC and the C++ compiler might
   1320     // already have dereferenced the instances handle.
   1321     Handle<JSObject> wrapper = Script::GetWrapper(script);
   1322     instances->set(i, *wrapper);
   1323   }
   1324 
   1325   // Return result as a JS array.
   1326   Handle<JSObject> result =
   1327       isolate->factory()->NewJSObject(isolate->array_function());
   1328   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
   1329   return *result;
   1330 }
   1331 
   1332 
   1333 static bool HasInPrototypeChainIgnoringProxies(Isolate* isolate, Object* object,
   1334                                                Object* proto) {
   1335   PrototypeIterator iter(isolate, object, PrototypeIterator::START_AT_RECEIVER);
   1336   while (true) {
   1337     iter.AdvanceIgnoringProxies();
   1338     if (iter.IsAtEnd()) return false;
   1339     if (iter.IsAtEnd(proto)) return true;
   1340   }
   1341 }
   1342 
   1343 
   1344 // Scan the heap for objects with direct references to an object
   1345 // args[0]: the object to find references to
   1346 // args[1]: constructor function for instances to exclude (Mirror)
   1347 // args[2]: the the maximum number of objects to return
   1348 RUNTIME_FUNCTION(Runtime_DebugReferencedBy) {
   1349   HandleScope scope(isolate);
   1350   DCHECK(args.length() == 3);
   1351   CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
   1352   CONVERT_ARG_HANDLE_CHECKED(Object, filter, 1);
   1353   RUNTIME_ASSERT(filter->IsUndefined() || filter->IsJSObject());
   1354   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
   1355   RUNTIME_ASSERT(max_references >= 0);
   1356 
   1357   List<Handle<JSObject> > instances;
   1358   Heap* heap = isolate->heap();
   1359   {
   1360     HeapIterator iterator(heap, HeapIterator::kFilterUnreachable);
   1361     // Get the constructor function for context extension and arguments array.
   1362     Object* arguments_fun = isolate->sloppy_arguments_map()->GetConstructor();
   1363     HeapObject* heap_obj;
   1364     while ((heap_obj = iterator.next())) {
   1365       if (!heap_obj->IsJSObject()) continue;
   1366       JSObject* obj = JSObject::cast(heap_obj);
   1367       if (obj->IsJSContextExtensionObject()) continue;
   1368       if (obj->map()->GetConstructor() == arguments_fun) continue;
   1369       if (!obj->ReferencesObject(*target)) continue;
   1370       // Check filter if supplied. This is normally used to avoid
   1371       // references from mirror objects.
   1372       if (!filter->IsUndefined() &&
   1373           HasInPrototypeChainIgnoringProxies(isolate, obj, *filter)) {
   1374         continue;
   1375       }
   1376       if (obj->IsJSGlobalObject()) {
   1377         obj = JSGlobalObject::cast(obj)->global_proxy();
   1378       }
   1379       instances.Add(Handle<JSObject>(obj));
   1380       if (instances.length() == max_references) break;
   1381     }
   1382     // Iterate the rest of the heap to satisfy HeapIterator constraints.
   1383     while (iterator.next()) {
   1384     }
   1385   }
   1386 
   1387   Handle<FixedArray> result;
   1388   if (instances.length() == 1 && instances.last().is_identical_to(target)) {
   1389     // Check for circular reference only. This can happen when the object is
   1390     // only referenced from mirrors and has a circular reference in which case
   1391     // the object is not really alive and would have been garbage collected if
   1392     // not referenced from the mirror.
   1393     result = isolate->factory()->empty_fixed_array();
   1394   } else {
   1395     result = isolate->factory()->NewFixedArray(instances.length());
   1396     for (int i = 0; i < instances.length(); ++i) result->set(i, *instances[i]);
   1397   }
   1398   return *isolate->factory()->NewJSArrayWithElements(result);
   1399 }
   1400 
   1401 
   1402 // Scan the heap for objects constructed by a specific function.
   1403 // args[0]: the constructor to find instances of
   1404 // args[1]: the the maximum number of objects to return
   1405 RUNTIME_FUNCTION(Runtime_DebugConstructedBy) {
   1406   HandleScope scope(isolate);
   1407   DCHECK(args.length() == 2);
   1408   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
   1409   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
   1410   RUNTIME_ASSERT(max_references >= 0);
   1411 
   1412   List<Handle<JSObject> > instances;
   1413   Heap* heap = isolate->heap();
   1414   {
   1415     HeapIterator iterator(heap, HeapIterator::kFilterUnreachable);
   1416     HeapObject* heap_obj;
   1417     while ((heap_obj = iterator.next())) {
   1418       if (!heap_obj->IsJSObject()) continue;
   1419       JSObject* obj = JSObject::cast(heap_obj);
   1420       if (obj->map()->GetConstructor() != *constructor) continue;
   1421       instances.Add(Handle<JSObject>(obj));
   1422       if (instances.length() == max_references) break;
   1423     }
   1424     // Iterate the rest of the heap to satisfy HeapIterator constraints.
   1425     while (iterator.next()) {
   1426     }
   1427   }
   1428 
   1429   Handle<FixedArray> result =
   1430       isolate->factory()->NewFixedArray(instances.length());
   1431   for (int i = 0; i < instances.length(); ++i) result->set(i, *instances[i]);
   1432   return *isolate->factory()->NewJSArrayWithElements(result);
   1433 }
   1434 
   1435 
   1436 // Find the effective prototype object as returned by __proto__.
   1437 // args[0]: the object to find the prototype for.
   1438 RUNTIME_FUNCTION(Runtime_DebugGetPrototype) {
   1439   HandleScope shs(isolate);
   1440   DCHECK(args.length() == 1);
   1441   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   1442   Handle<Object> prototype;
   1443   // TODO(1543): Come up with a solution for clients to handle potential errors
   1444   // thrown by an intermediate proxy.
   1445   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, prototype,
   1446                                      Object::GetPrototype(isolate, obj));
   1447   return *prototype;
   1448 }
   1449 
   1450 
   1451 // Patches script source (should be called upon BeforeCompile event).
   1452 RUNTIME_FUNCTION(Runtime_DebugSetScriptSource) {
   1453   HandleScope scope(isolate);
   1454   DCHECK(args.length() == 2);
   1455 
   1456   CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0);
   1457   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
   1458 
   1459   RUNTIME_ASSERT(script_wrapper->value()->IsScript());
   1460   Handle<Script> script(Script::cast(script_wrapper->value()));
   1461 
   1462   int compilation_state = script->compilation_state();
   1463   RUNTIME_ASSERT(compilation_state == Script::COMPILATION_STATE_INITIAL);
   1464   script->set_source(*source);
   1465 
   1466   return isolate->heap()->undefined_value();
   1467 }
   1468 
   1469 
   1470 RUNTIME_FUNCTION(Runtime_FunctionGetInferredName) {
   1471   SealHandleScope shs(isolate);
   1472   DCHECK_EQ(1, args.length());
   1473 
   1474   CONVERT_ARG_CHECKED(Object, f, 0);
   1475   if (f->IsJSFunction()) {
   1476     return JSFunction::cast(f)->shared()->inferred_name();
   1477   }
   1478   return isolate->heap()->empty_string();
   1479 }
   1480 
   1481 
   1482 RUNTIME_FUNCTION(Runtime_FunctionGetDebugName) {
   1483   HandleScope scope(isolate);
   1484   DCHECK_EQ(1, args.length());
   1485 
   1486   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
   1487 
   1488   if (function->IsJSBoundFunction()) {
   1489     return Handle<JSBoundFunction>::cast(function)->name();
   1490   }
   1491   Handle<Object> name =
   1492       JSFunction::GetDebugName(Handle<JSFunction>::cast(function));
   1493   return *name;
   1494 }
   1495 
   1496 
   1497 // A testing entry. Returns statement position which is the closest to
   1498 // source_position.
   1499 RUNTIME_FUNCTION(Runtime_GetFunctionCodePositionFromSource) {
   1500   HandleScope scope(isolate);
   1501   CHECK(isolate->debug()->live_edit_enabled());
   1502   DCHECK(args.length() == 2);
   1503   RUNTIME_ASSERT(isolate->debug()->is_active());
   1504   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   1505   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
   1506 
   1507   Handle<Code> code(function->code(), isolate);
   1508 
   1509   if (code->kind() != Code::FUNCTION &&
   1510       code->kind() != Code::OPTIMIZED_FUNCTION) {
   1511     return isolate->heap()->undefined_value();
   1512   }
   1513 
   1514   RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION));
   1515   int closest_pc = 0;
   1516   int distance = kMaxInt;
   1517   while (!it.done()) {
   1518     int statement_position = static_cast<int>(it.rinfo()->data());
   1519     // Check if this break point is closer that what was previously found.
   1520     if (source_position <= statement_position &&
   1521         statement_position - source_position < distance) {
   1522       closest_pc =
   1523           static_cast<int>(it.rinfo()->pc() - code->instruction_start());
   1524       distance = statement_position - source_position;
   1525       // Check whether we can't get any closer.
   1526       if (distance == 0) break;
   1527     }
   1528     it.next();
   1529   }
   1530 
   1531   return Smi::FromInt(closest_pc);
   1532 }
   1533 
   1534 
   1535 // Calls specified function with or without entering the debugger.
   1536 // This is used in unit tests to run code as if debugger is entered or simply
   1537 // to have a stack with C++ frame in the middle.
   1538 RUNTIME_FUNCTION(Runtime_ExecuteInDebugContext) {
   1539   HandleScope scope(isolate);
   1540   DCHECK(args.length() == 1);
   1541   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   1542 
   1543   DebugScope debug_scope(isolate->debug());
   1544   if (debug_scope.failed()) {
   1545     DCHECK(isolate->has_pending_exception());
   1546     return isolate->heap()->exception();
   1547   }
   1548 
   1549   Handle<Object> result;
   1550   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   1551       isolate, result,
   1552       Execution::Call(isolate, function, handle(function->global_proxy()), 0,
   1553                       NULL));
   1554   return *result;
   1555 }
   1556 
   1557 
   1558 RUNTIME_FUNCTION(Runtime_GetDebugContext) {
   1559   HandleScope scope(isolate);
   1560   DCHECK(args.length() == 0);
   1561   Handle<Context> context;
   1562   {
   1563     DebugScope debug_scope(isolate->debug());
   1564     if (debug_scope.failed()) {
   1565       DCHECK(isolate->has_pending_exception());
   1566       return isolate->heap()->exception();
   1567     }
   1568     context = isolate->debug()->GetDebugContext();
   1569   }
   1570   if (context.is_null()) return isolate->heap()->undefined_value();
   1571   context->set_security_token(isolate->native_context()->security_token());
   1572   return context->global_proxy();
   1573 }
   1574 
   1575 
   1576 // Performs a GC.
   1577 // Presently, it only does a full GC.
   1578 RUNTIME_FUNCTION(Runtime_CollectGarbage) {
   1579   SealHandleScope shs(isolate);
   1580   DCHECK(args.length() == 1);
   1581   isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "%CollectGarbage");
   1582   return isolate->heap()->undefined_value();
   1583 }
   1584 
   1585 
   1586 // Gets the current heap usage.
   1587 RUNTIME_FUNCTION(Runtime_GetHeapUsage) {
   1588   SealHandleScope shs(isolate);
   1589   DCHECK(args.length() == 0);
   1590   int usage = static_cast<int>(isolate->heap()->SizeOfObjects());
   1591   if (!Smi::IsValid(usage)) {
   1592     return *isolate->factory()->NewNumberFromInt(usage);
   1593   }
   1594   return Smi::FromInt(usage);
   1595 }
   1596 
   1597 
   1598 // Finds the script object from the script data. NOTE: This operation uses
   1599 // heap traversal to find the function generated for the source position
   1600 // for the requested break point. For lazily compiled functions several heap
   1601 // traversals might be required rendering this operation as a rather slow
   1602 // operation. However for setting break points which is normally done through
   1603 // some kind of user interaction the performance is not crucial.
   1604 RUNTIME_FUNCTION(Runtime_GetScript) {
   1605   HandleScope scope(isolate);
   1606   DCHECK(args.length() == 1);
   1607   CONVERT_ARG_HANDLE_CHECKED(String, script_name, 0);
   1608 
   1609   Handle<Script> found;
   1610   {
   1611     Script::Iterator iterator(isolate);
   1612     Script* script = NULL;
   1613     while ((script = iterator.Next()) != NULL) {
   1614       if (!script->name()->IsString()) continue;
   1615       String* name = String::cast(script->name());
   1616       if (name->Equals(*script_name)) {
   1617         found = Handle<Script>(script, isolate);
   1618         break;
   1619       }
   1620     }
   1621   }
   1622 
   1623   if (found.is_null()) return isolate->heap()->undefined_value();
   1624   return *Script::GetWrapper(found);
   1625 }
   1626 
   1627 
   1628 // Set one shot breakpoints for the callback function that is passed to a
   1629 // built-in function such as Array.forEach to enable stepping into the callback,
   1630 // if we are indeed stepping and the callback is subject to debugging.
   1631 RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) {
   1632   DCHECK(args.length() == 1);
   1633   HandleScope scope(isolate);
   1634   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
   1635   RUNTIME_ASSERT(object->IsJSFunction() || object->IsJSGeneratorObject());
   1636   Handle<JSFunction> fun;
   1637   if (object->IsJSFunction()) {
   1638     fun = Handle<JSFunction>::cast(object);
   1639   } else {
   1640     fun = Handle<JSFunction>(
   1641         Handle<JSGeneratorObject>::cast(object)->function(), isolate);
   1642   }
   1643 
   1644   isolate->debug()->PrepareStepIn(fun);
   1645   return isolate->heap()->undefined_value();
   1646 }
   1647 
   1648 
   1649 RUNTIME_FUNCTION(Runtime_DebugPushPromise) {
   1650   DCHECK(args.length() == 2);
   1651   HandleScope scope(isolate);
   1652   CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
   1653   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 1);
   1654   isolate->PushPromise(promise, function);
   1655   // If we are in step-in mode, flood the handler.
   1656   isolate->debug()->EnableStepIn();
   1657   return isolate->heap()->undefined_value();
   1658 }
   1659 
   1660 
   1661 RUNTIME_FUNCTION(Runtime_DebugPopPromise) {
   1662   DCHECK(args.length() == 0);
   1663   SealHandleScope shs(isolate);
   1664   isolate->PopPromise();
   1665   return isolate->heap()->undefined_value();
   1666 }
   1667 
   1668 
   1669 RUNTIME_FUNCTION(Runtime_DebugPromiseEvent) {
   1670   DCHECK(args.length() == 1);
   1671   HandleScope scope(isolate);
   1672   CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
   1673   isolate->debug()->OnPromiseEvent(data);
   1674   return isolate->heap()->undefined_value();
   1675 }
   1676 
   1677 
   1678 RUNTIME_FUNCTION(Runtime_DebugAsyncTaskEvent) {
   1679   DCHECK(args.length() == 1);
   1680   HandleScope scope(isolate);
   1681   CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
   1682   isolate->debug()->OnAsyncTaskEvent(data);
   1683   return isolate->heap()->undefined_value();
   1684 }
   1685 
   1686 
   1687 RUNTIME_FUNCTION(Runtime_DebugIsActive) {
   1688   SealHandleScope shs(isolate);
   1689   return Smi::FromInt(isolate->debug()->is_active());
   1690 }
   1691 
   1692 
   1693 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) {
   1694   UNIMPLEMENTED();
   1695   return NULL;
   1696 }
   1697 }  // namespace internal
   1698 }  // namespace v8
   1699