LCOV - code coverage report
Current view: top level - src/runtime - runtime-debug.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 685 860 79.7 %
Date: 2017-04-26 Functions: 60 140 42.9 %

          Line data    Source code
       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/compiler.h"
       9             : #include "src/debug/debug-coverage.h"
      10             : #include "src/debug/debug-evaluate.h"
      11             : #include "src/debug/debug-frames.h"
      12             : #include "src/debug/debug-scopes.h"
      13             : #include "src/debug/debug.h"
      14             : #include "src/debug/liveedit.h"
      15             : #include "src/frames-inl.h"
      16             : #include "src/globals.h"
      17             : #include "src/interpreter/bytecodes.h"
      18             : #include "src/interpreter/interpreter.h"
      19             : #include "src/isolate-inl.h"
      20             : #include "src/runtime/runtime.h"
      21             : #include "src/wasm/wasm-module.h"
      22             : #include "src/wasm/wasm-objects.h"
      23             : 
      24             : namespace v8 {
      25             : namespace internal {
      26             : 
      27      151614 : RUNTIME_FUNCTION(Runtime_DebugBreak) {
      28             :   SealHandleScope shs(isolate);
      29             :   DCHECK_EQ(1, args.length());
      30       25269 :   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
      31       50538 :   HandleScope scope(isolate);
      32       50538 :   ReturnValueScope result_scope(isolate->debug());
      33       25269 :   isolate->debug()->set_return_value(*value);
      34             : 
      35             :   // Get the top-most JavaScript frame.
      36       50538 :   JavaScriptFrameIterator it(isolate);
      37       50538 :   isolate->debug()->Break(it.frame());
      38       25269 :   return isolate->debug()->return_value();
      39             : }
      40             : 
      41      393318 : RUNTIME_FUNCTION(Runtime_DebugBreakOnBytecode) {
      42             :   SealHandleScope shs(isolate);
      43             :   DCHECK_EQ(1, args.length());
      44       65553 :   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
      45      131106 :   HandleScope scope(isolate);
      46      131106 :   ReturnValueScope result_scope(isolate->debug());
      47       65553 :   isolate->debug()->set_return_value(*value);
      48             : 
      49             :   // Get the top-most JavaScript frame.
      50      131106 :   JavaScriptFrameIterator it(isolate);
      51      131106 :   isolate->debug()->Break(it.frame());
      52             : 
      53             :   // Return the handler from the original bytecode array.
      54             :   DCHECK(it.frame()->is_interpreted());
      55             :   InterpretedFrame* interpreted_frame =
      56       65553 :       reinterpret_cast<InterpretedFrame*>(it.frame());
      57       65553 :   SharedFunctionInfo* shared = interpreted_frame->function()->shared();
      58       65553 :   BytecodeArray* bytecode_array = shared->bytecode_array();
      59       65553 :   int bytecode_offset = interpreted_frame->GetBytecodeOffset();
      60             :   interpreter::Bytecode bytecode =
      61       65553 :       interpreter::Bytecodes::FromByte(bytecode_array->get(bytecode_offset));
      62             :   return isolate->interpreter()->GetBytecodeHandler(
      63       65553 :       bytecode, interpreter::OperandScale::kSingle);
      64             : }
      65             : 
      66             : 
      67       24068 : RUNTIME_FUNCTION(Runtime_HandleDebuggerStatement) {
      68             :   SealHandleScope shs(isolate);
      69             :   DCHECK_EQ(0, args.length());
      70       12034 :   if (isolate->debug()->break_points_active()) {
      71       12028 :     isolate->debug()->HandleDebugBreak(kIgnoreIfTopFrameBlackboxed);
      72             :   }
      73       12034 :   return isolate->heap()->undefined_value();
      74             : }
      75             : 
      76             : 
      77             : // Adds a JavaScript function as a debug event listener.
      78             : // args[0]: debug event listener function to set or null or undefined for
      79             : //          clearing the event listener function
      80             : // args[1]: object supplied during callback
      81         483 : RUNTIME_FUNCTION(Runtime_SetDebugEventListener) {
      82             :   SealHandleScope shs(isolate);
      83             :   DCHECK_EQ(2, args.length());
      84         378 :   CHECK(args[0]->IsJSFunction() || args[0]->IsNullOrUndefined(isolate));
      85         161 :   CONVERT_ARG_HANDLE_CHECKED(Object, callback, 0);
      86         161 :   CONVERT_ARG_HANDLE_CHECKED(Object, data, 1);
      87         161 :   if (callback->IsJSFunction()) {
      88             :     JavaScriptDebugDelegate* delegate = new JavaScriptDebugDelegate(
      89         105 :         isolate, Handle<JSFunction>::cast(callback), data);
      90         105 :     isolate->debug()->SetDebugDelegate(delegate, true);
      91             :   } else {
      92          56 :     isolate->debug()->SetDebugDelegate(nullptr, false);
      93             :   }
      94         161 :   return isolate->heap()->undefined_value();
      95             : }
      96             : 
      97             : 
      98         394 : RUNTIME_FUNCTION(Runtime_ScheduleBreak) {
      99             :   SealHandleScope shs(isolate);
     100             :   DCHECK_EQ(0, args.length());
     101         197 :   isolate->stack_guard()->RequestDebugBreak();
     102         197 :   return isolate->heap()->undefined_value();
     103             : }
     104             : 
     105             : 
     106    10752064 : static Handle<Object> DebugGetProperty(LookupIterator* it,
     107             :                                        bool* has_caught = NULL) {
     108    10751962 :   for (; it->IsFound(); it->Next()) {
     109     5375975 :     switch (it->state()) {
     110             :       case LookupIterator::NOT_FOUND:
     111             :       case LookupIterator::TRANSITION:
     112           0 :         UNREACHABLE();
     113             :       case LookupIterator::ACCESS_CHECK:
     114             :         // Ignore access checks.
     115             :         break;
     116             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
     117             :       case LookupIterator::INTERCEPTOR:
     118             :       case LookupIterator::JSPROXY:
     119          72 :         return it->isolate()->factory()->undefined_value();
     120             :       case LookupIterator::ACCESSOR: {
     121          30 :         Handle<Object> accessors = it->GetAccessors();
     122          30 :         if (!accessors->IsAccessorInfo()) {
     123           0 :           return it->isolate()->factory()->undefined_value();
     124             :         }
     125             :         MaybeHandle<Object> maybe_result =
     126          30 :             JSObject::GetPropertyWithAccessor(it);
     127             :         Handle<Object> result;
     128          30 :         if (!maybe_result.ToHandle(&result)) {
     129          12 :           result = handle(it->isolate()->pending_exception(), it->isolate());
     130             :           it->isolate()->clear_pending_exception();
     131          12 :           if (has_caught != NULL) *has_caught = true;
     132             :         }
     133          30 :         return result;
     134             :       }
     135             : 
     136             :       case LookupIterator::DATA:
     137     5375873 :         return it->GetDataValue();
     138             :     }
     139             :   }
     140             : 
     141           6 :   return it->isolate()->factory()->undefined_value();
     142             : }
     143             : 
     144             : template <class IteratorType>
     145         126 : static MaybeHandle<JSArray> GetIteratorInternalProperties(
     146             :     Isolate* isolate, Handle<IteratorType> object) {
     147             :   Factory* factory = isolate->factory();
     148             :   Handle<IteratorType> iterator = Handle<IteratorType>::cast(object);
     149         126 :   CHECK(iterator->kind()->IsSmi());
     150             :   const char* kind = NULL;
     151         126 :   switch (Smi::cast(iterator->kind())->value()) {
     152             :     case IteratorType::kKindKeys:
     153             :       kind = "keys";
     154             :       break;
     155             :     case IteratorType::kKindValues:
     156             :       kind = "values";
     157          44 :       break;
     158             :     case IteratorType::kKindEntries:
     159             :       kind = "entries";
     160          62 :       break;
     161             :     default:
     162           0 :       UNREACHABLE();
     163             :   }
     164             : 
     165         126 :   Handle<FixedArray> result = factory->NewFixedArray(2 * 3);
     166             :   Handle<String> has_more =
     167         126 :       factory->NewStringFromAsciiChecked("[[IteratorHasMore]]");
     168         126 :   result->set(0, *has_more);
     169         252 :   result->set(1, isolate->heap()->ToBoolean(iterator->HasMore()));
     170             : 
     171             :   Handle<String> index =
     172         126 :       factory->NewStringFromAsciiChecked("[[IteratorIndex]]");
     173         126 :   result->set(2, *index);
     174         126 :   result->set(3, iterator->index());
     175             : 
     176             :   Handle<String> iterator_kind =
     177         126 :       factory->NewStringFromAsciiChecked("[[IteratorKind]]");
     178         126 :   result->set(4, *iterator_kind);
     179         126 :   Handle<String> kind_str = factory->NewStringFromAsciiChecked(kind);
     180         126 :   result->set(5, *kind_str);
     181         126 :   return factory->NewJSArrayWithElements(result);
     182             : }
     183             : 
     184             : 
     185      106344 : MaybeHandle<JSArray> Runtime::GetInternalProperties(Isolate* isolate,
     186             :                                                     Handle<Object> object) {
     187             :   Factory* factory = isolate->factory();
     188      106344 :   if (object->IsJSBoundFunction()) {
     189             :     Handle<JSBoundFunction> function = Handle<JSBoundFunction>::cast(object);
     190             : 
     191           6 :     Handle<FixedArray> result = factory->NewFixedArray(2 * 3);
     192             :     Handle<String> target =
     193           6 :         factory->NewStringFromAsciiChecked("[[TargetFunction]]");
     194           6 :     result->set(0, *target);
     195           6 :     result->set(1, function->bound_target_function());
     196             : 
     197             :     Handle<String> bound_this =
     198           6 :         factory->NewStringFromAsciiChecked("[[BoundThis]]");
     199           6 :     result->set(2, *bound_this);
     200           6 :     result->set(3, function->bound_this());
     201             : 
     202             :     Handle<String> bound_args =
     203           6 :         factory->NewStringFromAsciiChecked("[[BoundArgs]]");
     204           6 :     result->set(4, *bound_args);
     205             :     Handle<FixedArray> bound_arguments =
     206           6 :         factory->CopyFixedArray(handle(function->bound_arguments(), isolate));
     207             :     Handle<JSArray> arguments_array =
     208             :         factory->NewJSArrayWithElements(bound_arguments);
     209           6 :     result->set(5, *arguments_array);
     210             :     return factory->NewJSArrayWithElements(result);
     211      106338 :   } else if (object->IsJSMapIterator()) {
     212          84 :     Handle<JSMapIterator> iterator = Handle<JSMapIterator>::cast(object);
     213          84 :     return GetIteratorInternalProperties(isolate, iterator);
     214      106254 :   } else if (object->IsJSSetIterator()) {
     215          42 :     Handle<JSSetIterator> iterator = Handle<JSSetIterator>::cast(object);
     216          42 :     return GetIteratorInternalProperties(isolate, iterator);
     217      106212 :   } else if (object->IsJSGeneratorObject()) {
     218             :     Handle<JSGeneratorObject> generator =
     219             :         Handle<JSGeneratorObject>::cast(object);
     220             : 
     221             :     const char* status = "suspended";
     222          54 :     if (generator->is_closed()) {
     223             :       status = "closed";
     224          42 :     } else if (generator->is_executing()) {
     225             :       status = "running";
     226             :     } else {
     227             :       DCHECK(generator->is_suspended());
     228             :     }
     229             : 
     230          54 :     Handle<FixedArray> result = factory->NewFixedArray(2 * 3);
     231             :     Handle<String> generator_status =
     232          54 :         factory->NewStringFromAsciiChecked("[[GeneratorStatus]]");
     233          54 :     result->set(0, *generator_status);
     234          54 :     Handle<String> status_str = factory->NewStringFromAsciiChecked(status);
     235          54 :     result->set(1, *status_str);
     236             : 
     237             :     Handle<String> function =
     238          54 :         factory->NewStringFromAsciiChecked("[[GeneratorFunction]]");
     239          54 :     result->set(2, *function);
     240          54 :     result->set(3, generator->function());
     241             : 
     242             :     Handle<String> receiver =
     243          54 :         factory->NewStringFromAsciiChecked("[[GeneratorReceiver]]");
     244          54 :     result->set(4, *receiver);
     245          54 :     result->set(5, generator->receiver());
     246             :     return factory->NewJSArrayWithElements(result);
     247      106158 :   } else if (object->IsJSPromise()) {
     248             :     Handle<JSPromise> promise = Handle<JSPromise>::cast(object);
     249          30 :     const char* status = JSPromise::Status(promise->status());
     250          30 :     Handle<FixedArray> result = factory->NewFixedArray(2 * 2);
     251             :     Handle<String> promise_status =
     252          30 :         factory->NewStringFromAsciiChecked("[[PromiseStatus]]");
     253          30 :     result->set(0, *promise_status);
     254          30 :     Handle<String> status_str = factory->NewStringFromAsciiChecked(status);
     255          30 :     result->set(1, *status_str);
     256             : 
     257             :     Handle<Object> value_obj(promise->result(), isolate);
     258             :     Handle<String> promise_value =
     259          30 :         factory->NewStringFromAsciiChecked("[[PromiseValue]]");
     260          30 :     result->set(2, *promise_value);
     261          30 :     result->set(3, *value_obj);
     262             :     return factory->NewJSArrayWithElements(result);
     263      106128 :   } else if (object->IsJSProxy()) {
     264             :     Handle<JSProxy> js_proxy = Handle<JSProxy>::cast(object);
     265           0 :     Handle<FixedArray> result = factory->NewFixedArray(3 * 2);
     266             : 
     267             :     Handle<String> handler_str =
     268           0 :         factory->NewStringFromAsciiChecked("[[Handler]]");
     269           0 :     result->set(0, *handler_str);
     270           0 :     result->set(1, js_proxy->handler());
     271             : 
     272             :     Handle<String> target_str =
     273           0 :         factory->NewStringFromAsciiChecked("[[Target]]");
     274           0 :     result->set(2, *target_str);
     275           0 :     result->set(3, js_proxy->target());
     276             : 
     277             :     Handle<String> is_revoked_str =
     278           0 :         factory->NewStringFromAsciiChecked("[[IsRevoked]]");
     279           0 :     result->set(4, *is_revoked_str);
     280           0 :     result->set(5, isolate->heap()->ToBoolean(js_proxy->IsRevoked()));
     281             :     return factory->NewJSArrayWithElements(result);
     282      106128 :   } else if (object->IsJSValue()) {
     283             :     Handle<JSValue> js_value = Handle<JSValue>::cast(object);
     284             : 
     285         152 :     Handle<FixedArray> result = factory->NewFixedArray(2);
     286             :     Handle<String> primitive_value =
     287         152 :         factory->NewStringFromAsciiChecked("[[PrimitiveValue]]");
     288         152 :     result->set(0, *primitive_value);
     289         152 :     result->set(1, js_value->value());
     290             :     return factory->NewJSArrayWithElements(result);
     291             :   }
     292      105976 :   return factory->NewJSArray(0);
     293             : }
     294             : 
     295             : 
     296           0 : RUNTIME_FUNCTION(Runtime_DebugGetInternalProperties) {
     297           0 :   HandleScope scope(isolate);
     298             :   DCHECK_EQ(1, args.length());
     299           0 :   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
     300           0 :   RETURN_RESULT_OR_FAILURE(isolate,
     301           0 :                            Runtime::GetInternalProperties(isolate, obj));
     302             : }
     303             : 
     304             : 
     305             : // Get debugger related details for an object property, in the following format:
     306             : // 0: Property value
     307             : // 1: Property details
     308             : // 2: Property value is exception
     309             : // 3: Getter function if defined
     310             : // 4: Setter function if defined
     311             : // Items 2-4 are only filled if the property has either a getter or a setter.
     312    21503888 : RUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) {
     313     5376029 :   HandleScope scope(isolate);
     314             :   DCHECK_EQ(2, args.length());
     315    10752058 :   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
     316     5376029 :   CONVERT_ARG_HANDLE_CHECKED(Object, name_obj, 1);
     317             : 
     318             :   // Convert the {name_obj} to a Name.
     319             :   Handle<Name> name;
     320    10752058 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
     321             :                                      Object::ToName(isolate, name_obj));
     322             : 
     323             :   // Make sure to set the current context to the context before the debugger was
     324             :   // entered (if the debugger is entered). The reason for switching context here
     325             :   // is that for some property lookups (accessors and interceptors) callbacks
     326             :   // into the embedding application can occour, and the embedding application
     327             :   // could have the assumption that its own native context is the current
     328             :   // context and not some internal debugger context.
     329    10752058 :   SaveContext save(isolate);
     330     5376029 :   if (isolate->debug()->in_debug_scope()) {
     331    10751602 :     isolate->set_context(*isolate->debug()->debugger_entry()->GetContext());
     332             :   }
     333             : 
     334             :   // Check if the name is trivially convertible to an index and get the element
     335             :   // if so.
     336             :   uint32_t index;
     337             :   // TODO(verwaest): Make sure DebugGetProperty can handle arrays, and remove
     338             :   // this special case.
     339     5376029 :   if (name->AsArrayIndex(&index)) {
     340          48 :     Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
     341             :     Handle<Object> element_or_char;
     342         144 :     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
     343             :         isolate, element_or_char, JSReceiver::GetElement(isolate, obj, index));
     344          48 :     details->set(0, *element_or_char);
     345          96 :     details->set(1, PropertyDetails::Empty().AsSmi());
     346          96 :     return *isolate->factory()->NewJSArrayWithElements(details);
     347             :   }
     348             : 
     349     5375981 :   LookupIterator it(obj, name, LookupIterator::OWN);
     350     5375981 :   bool has_caught = false;
     351     5375981 :   Handle<Object> value = DebugGetProperty(&it, &has_caught);
     352     5375981 :   if (!it.IsFound()) return isolate->heap()->undefined_value();
     353             : 
     354             :   Handle<Object> maybe_pair;
     355     5375975 :   if (it.state() == LookupIterator::ACCESSOR) {
     356          30 :     maybe_pair = it.GetAccessors();
     357             :   }
     358             : 
     359             :   // If the callback object is a fixed array then it contains JavaScript
     360             :   // getter and/or setter.
     361     5376005 :   bool has_js_accessors = !maybe_pair.is_null() && maybe_pair->IsAccessorPair();
     362             :   Handle<FixedArray> details =
     363     5375975 :       isolate->factory()->NewFixedArray(has_js_accessors ? 6 : 3);
     364     5375975 :   details->set(0, *value);
     365             :   // TODO(verwaest): Get rid of this random way of handling interceptors.
     366     5375975 :   PropertyDetails d = it.state() == LookupIterator::INTERCEPTOR
     367             :                           ? PropertyDetails::Empty()
     368     5375975 :                           : it.property_details();
     369    10751950 :   details->set(1, d.AsSmi());
     370             :   details->set(
     371    10751950 :       2, isolate->heap()->ToBoolean(it.state() == LookupIterator::INTERCEPTOR));
     372     5375975 :   if (has_js_accessors) {
     373           0 :     Handle<AccessorPair> accessors = Handle<AccessorPair>::cast(maybe_pair);
     374           0 :     details->set(3, isolate->heap()->ToBoolean(has_caught));
     375             :     Handle<Object> getter =
     376           0 :         AccessorPair::GetComponent(accessors, ACCESSOR_GETTER);
     377             :     Handle<Object> setter =
     378           0 :         AccessorPair::GetComponent(accessors, ACCESSOR_SETTER);
     379           0 :     details->set(4, *getter);
     380           0 :     details->set(5, *setter);
     381             :   }
     382             : 
     383    16127979 :   return *isolate->factory()->NewJSArrayWithElements(details);
     384             : }
     385             : 
     386             : 
     387           0 : RUNTIME_FUNCTION(Runtime_DebugGetProperty) {
     388           0 :   HandleScope scope(isolate);
     389             : 
     390             :   DCHECK_EQ(2, args.length());
     391             : 
     392           0 :   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
     393           0 :   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
     394             : 
     395           0 :   LookupIterator it(obj, name);
     396           0 :   return *DebugGetProperty(&it);
     397             : }
     398             : 
     399             : // Return the property kind calculated from the property details.
     400             : // args[0]: smi with property details.
     401           0 : RUNTIME_FUNCTION(Runtime_DebugPropertyKindFromDetails) {
     402             :   SealHandleScope shs(isolate);
     403             :   DCHECK_EQ(1, args.length());
     404           0 :   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
     405           0 :   return Smi::FromInt(static_cast<int>(details.kind()));
     406             : }
     407             : 
     408             : 
     409             : // Return the property attribute calculated from the property details.
     410             : // args[0]: smi with property details.
     411           0 : RUNTIME_FUNCTION(Runtime_DebugPropertyAttributesFromDetails) {
     412             :   SealHandleScope shs(isolate);
     413             :   DCHECK_EQ(1, args.length());
     414           0 :   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
     415           0 :   return Smi::FromInt(static_cast<int>(details.attributes()));
     416             : }
     417             : 
     418             : 
     419    16520943 : RUNTIME_FUNCTION(Runtime_CheckExecutionState) {
     420             :   SealHandleScope shs(isolate);
     421             :   DCHECK_EQ(1, args.length());
     422    11013962 :   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
     423     5506981 :   CHECK(isolate->debug()->CheckExecutionState(break_id));
     424     5506981 :   return isolate->heap()->true_value();
     425             : }
     426             : 
     427             : 
     428     1853056 : RUNTIME_FUNCTION(Runtime_GetFrameCount) {
     429      463264 :   HandleScope scope(isolate);
     430             :   DCHECK_EQ(1, args.length());
     431      926528 :   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
     432      463264 :   CHECK(isolate->debug()->CheckExecutionState(break_id));
     433             : 
     434             :   // Count all frames which are relevant to debugging stack trace.
     435             :   int n = 0;
     436      463264 :   StackFrame::Id id = isolate->debug()->break_frame_id();
     437      463264 :   if (id == StackFrame::NO_ID) {
     438             :     // If there is no JavaScript stack frame count is 0.
     439             :     return Smi::kZero;
     440             :   }
     441             : 
     442      463234 :   List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
     443     5384654 :   for (StackTraceFrameIterator it(isolate, id); !it.done(); it.Advance()) {
     444             :     frames.Clear();
     445     4921420 :     it.frame()->Summarize(&frames);
     446     9851013 :     for (int i = frames.length() - 1; i >= 0; i--) {
     447             :       // Omit functions from native and extension scripts.
     448     4929593 :       if (frames[i].is_subject_to_debugging()) n++;
     449             :     }
     450      463234 :   }
     451      926498 :   return Smi::FromInt(n);
     452             : }
     453             : 
     454             : static const int kFrameDetailsFrameIdIndex = 0;
     455             : static const int kFrameDetailsReceiverIndex = 1;
     456             : static const int kFrameDetailsFunctionIndex = 2;
     457             : static const int kFrameDetailsScriptIndex = 3;
     458             : static const int kFrameDetailsArgumentCountIndex = 4;
     459             : static const int kFrameDetailsLocalCountIndex = 5;
     460             : static const int kFrameDetailsSourcePositionIndex = 6;
     461             : static const int kFrameDetailsConstructCallIndex = 7;
     462             : static const int kFrameDetailsAtReturnIndex = 8;
     463             : static const int kFrameDetailsFlagsIndex = 9;
     464             : static const int kFrameDetailsFirstDynamicIndex = 10;
     465             : 
     466             : // Return an array with frame details
     467             : // args[0]: number: break id
     468             : // args[1]: number: frame index
     469             : //
     470             : // The array returned contains the following information:
     471             : // 0: Frame id
     472             : // 1: Receiver
     473             : // 2: Function
     474             : // 3: Script
     475             : // 4: Argument count
     476             : // 5: Local count
     477             : // 6: Source position
     478             : // 7: Constructor call
     479             : // 8: Is at return
     480             : // 9: Flags
     481             : // Arguments name, value
     482             : // Locals name, value
     483             : // Return value if any
     484     1257201 : RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
     485      229547 :   HandleScope scope(isolate);
     486             :   DCHECK_EQ(2, args.length());
     487      459094 :   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
     488      229547 :   CHECK(isolate->debug()->CheckExecutionState(break_id));
     489             : 
     490      459094 :   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
     491      250801 :   Heap* heap = isolate->heap();
     492             : 
     493             :   // Find the relevant frame with the requested index.
     494      229547 :   StackFrame::Id id = isolate->debug()->break_frame_id();
     495      229547 :   if (id == StackFrame::NO_ID) {
     496             :     // If there are no JavaScript stack frames return undefined.
     497           0 :     return heap->undefined_value();
     498             :   }
     499             : 
     500      459094 :   StackTraceFrameIterator it(isolate, id);
     501             :   // Inlined frame index in optimized frame, starting from outer function.
     502             :   int inlined_frame_index =
     503      229547 :       DebugFrameHelper::FindIndexedNonNativeFrame(&it, index);
     504      229547 :   if (inlined_frame_index == -1) return heap->undefined_value();
     505             : 
     506      459094 :   FrameInspector frame_inspector(it.frame(), inlined_frame_index, isolate);
     507             : 
     508             :   // Traverse the saved contexts chain to find the active context for the
     509             :   // selected frame.
     510             :   SaveContext* save =
     511      229547 :       DebugFrameHelper::FindSavedContextForFrame(isolate, it.frame());
     512             : 
     513             :   // Get the frame id.
     514      229547 :   Handle<Object> frame_id(DebugFrameHelper::WrapFrameId(it.frame()->id()),
     515             :                           isolate);
     516             : 
     517      229547 :   if (frame_inspector.summary().IsWasm()) {
     518             :     // Create the details array (no dynamic information for wasm).
     519             :     Handle<FixedArray> details =
     520         374 :         isolate->factory()->NewFixedArray(kFrameDetailsFirstDynamicIndex);
     521             : 
     522             :     // Add the frame id.
     523         374 :     details->set(kFrameDetailsFrameIdIndex, *frame_id);
     524             : 
     525             :     // Add the function name.
     526         374 :     Handle<String> func_name = frame_inspector.summary().FunctionName();
     527         374 :     details->set(kFrameDetailsFunctionIndex, *func_name);
     528             : 
     529             :     // Add the script wrapper
     530             :     Handle<Object> script_wrapper =
     531         374 :         Script::GetWrapper(frame_inspector.GetScript());
     532         374 :     details->set(kFrameDetailsScriptIndex, *script_wrapper);
     533             : 
     534             :     // Add the arguments count.
     535         374 :     details->set(kFrameDetailsArgumentCountIndex, Smi::kZero);
     536             : 
     537             :     // Add the locals count
     538         374 :     details->set(kFrameDetailsLocalCountIndex, Smi::kZero);
     539             : 
     540             :     // Add the source position.
     541         374 :     int position = frame_inspector.summary().SourcePosition();
     542         748 :     details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
     543             : 
     544             :     // Add the constructor information.
     545         748 :     details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(false));
     546             : 
     547             :     // Add the at return information.
     548         748 :     details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(false));
     549             : 
     550             :     // Add flags to indicate information on whether this frame is
     551             :     //   bit 0: invoked in the debugger context.
     552             :     //   bit 1: optimized frame.
     553             :     //   bit 2: inlined in optimized frame
     554         374 :     int flags = inlined_frame_index << 2;
     555        1122 :     if (*save->context() == *isolate->debug()->debug_context()) {
     556           0 :       flags |= 1 << 0;
     557             :     }
     558         748 :     details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
     559             : 
     560         748 :     return *isolate->factory()->NewJSArrayWithElements(details);
     561             :   }
     562             : 
     563             :   // Find source position in unoptimized code.
     564      229173 :   int position = frame_inspector.GetSourcePosition();
     565             : 
     566             :   // Handle JavaScript frames.
     567      229173 :   bool is_optimized = it.frame()->is_optimized();
     568             : 
     569             :   // Check for constructor frame.
     570      229173 :   bool constructor = frame_inspector.IsConstructor();
     571             : 
     572             :   // Get scope info and read from it for local variable information.
     573             :   Handle<JSFunction> function =
     574      229173 :       Handle<JSFunction>::cast(frame_inspector.GetFunction());
     575      229173 :   CHECK(function->shared()->IsSubjectToDebugging());
     576      229173 :   Handle<SharedFunctionInfo> shared(function->shared());
     577      229173 :   Handle<ScopeInfo> scope_info(shared->scope_info());
     578             :   DCHECK(*scope_info != ScopeInfo::Empty(isolate));
     579             : 
     580             :   // Get the locals names and values into a temporary array.
     581      229173 :   Handle<Object> maybe_context = frame_inspector.GetContext();
     582             :   const int local_count_with_synthetic = maybe_context->IsContext()
     583             :                                              ? scope_info->LocalCount()
     584      458346 :                                              : scope_info->StackLocalCount();
     585             :   int local_count = local_count_with_synthetic;
     586     5214620 :   for (int slot = 0; slot < local_count_with_synthetic; ++slot) {
     587             :     // Hide compiler-introduced temporary variables, whether on the stack or on
     588             :     // the context.
     589     5214620 :     if (ScopeInfo::VariableIsSynthetic(scope_info->LocalName(slot))) {
     590      229024 :       local_count--;
     591             :     }
     592             :   }
     593             : 
     594      229173 :   List<Handle<Object>> locals;
     595             :   // Fill in the values of the locals.
     596             :   int i = 0;
     597    10412011 :   for (; i < scope_info->StackLocalCount(); ++i) {
     598             :     // Use the value from the stack.
     599     5278551 :     if (ScopeInfo::VariableIsSynthetic(scope_info->LocalName(i))) continue;
     600     9808574 :     locals.Add(Handle<String>(scope_info->LocalName(i), isolate));
     601             :     Handle<Object> value =
     602     4904287 :         frame_inspector.GetExpression(scope_info->StackLocalIndex(i));
     603             :     // TODO(yangguo): We convert optimized out values to {undefined} when they
     604             :     // are passed to the debugger. Eventually we should handle them somehow.
     605     4904287 :     if (value->IsOptimizedOut(isolate)) {
     606        4217 :       value = isolate->factory()->undefined_value();
     607             :     }
     608     4904287 :     locals.Add(value);
     609             :   }
     610      229173 :   if (locals.length() < local_count * 2) {
     611             :     // Get the context containing declarations.
     612             :     DCHECK(maybe_context->IsContext());
     613       18918 :     Handle<Context> context(Context::cast(*maybe_context)->closure_context());
     614             : 
     615      250224 :     for (; i < scope_info->LocalCount(); ++i) {
     616      115653 :       Handle<String> name(scope_info->LocalName(i));
     617      149997 :       if (ScopeInfo::VariableIsSynthetic(*name)) continue;
     618             :       VariableMode mode;
     619             :       InitializationFlag init_flag;
     620             :       MaybeAssignedFlag maybe_assigned_flag;
     621       81309 :       locals.Add(name);
     622             :       int context_slot_index = ScopeInfo::ContextSlotIndex(
     623       81309 :           scope_info, name, &mode, &init_flag, &maybe_assigned_flag);
     624       81309 :       Object* value = context->get(context_slot_index);
     625       81309 :       locals.Add(Handle<Object>(value, isolate));
     626             :     }
     627             :   }
     628             : 
     629             :   // Check whether this frame is positioned at return. If not top
     630             :   // frame or if the frame is optimized it cannot be at a return.
     631             :   bool at_return = false;
     632      229173 :   if (!is_optimized && index == 0) {
     633      198364 :     at_return = isolate->debug()->IsBreakAtReturn(it.javascript_frame());
     634             :   }
     635             : 
     636             :   // If positioned just before return find the value to be returned and add it
     637             :   // to the frame information.
     638      229173 :   Handle<Object> return_value = isolate->factory()->undefined_value();
     639      229173 :   if (at_return) {
     640       10284 :     return_value = handle(isolate->debug()->return_value(), isolate);
     641             :   }
     642             : 
     643             :   // Now advance to the arguments adapter frame (if any). It contains all
     644             :   // the provided parameters whereas the function frame always have the number
     645             :   // of arguments matching the functions parameters. The rest of the
     646             :   // information (except for what is collected above) is the same.
     647      457570 :   if ((inlined_frame_index == 0) &&
     648      228397 :       it.javascript_frame()->has_adapted_arguments()) {
     649       16015 :     it.AdvanceToArgumentsFrame();
     650       16015 :     frame_inspector.SetArgumentsFrame(it.frame());
     651             :   }
     652             : 
     653             :   // Find the number of arguments to fill. At least fill the number of
     654             :   // parameters for the function and fill more if more parameters are provided.
     655      229173 :   int argument_count = scope_info->ParameterCount();
     656      229173 :   if (argument_count < frame_inspector.GetParametersCount()) {
     657       13640 :     argument_count = frame_inspector.GetParametersCount();
     658             :   }
     659             : 
     660             :   // Calculate the size of the result.
     661      229173 :   int details_size = kFrameDetailsFirstDynamicIndex +
     662      458346 :                      2 * (argument_count + local_count) + (at_return ? 1 : 0);
     663      229173 :   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
     664             : 
     665             :   // Add the frame id.
     666      229173 :   details->set(kFrameDetailsFrameIdIndex, *frame_id);
     667             : 
     668             :   // Add the function (same as in function frame).
     669      458346 :   details->set(kFrameDetailsFunctionIndex, *(frame_inspector.GetFunction()));
     670             : 
     671             :   // Add the script wrapper
     672             :   Handle<Object> script_wrapper =
     673      229173 :       Script::GetWrapper(frame_inspector.GetScript());
     674      229173 :   details->set(kFrameDetailsScriptIndex, *script_wrapper);
     675             : 
     676             :   // Add the arguments count.
     677      458346 :   details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
     678             : 
     679             :   // Add the locals count
     680      458346 :   details->set(kFrameDetailsLocalCountIndex, Smi::FromInt(local_count));
     681             : 
     682             :   // Add the source position.
     683      229173 :   if (position != kNoSourcePosition) {
     684      458346 :     details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
     685             :   } else {
     686           0 :     details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value());
     687             :   }
     688             : 
     689             :   // Add the constructor information.
     690      458346 :   details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor));
     691             : 
     692             :   // Add the at return information.
     693      458346 :   details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
     694             : 
     695             :   // Add flags to indicate information on whether this frame is
     696             :   //   bit 0: invoked in the debugger context.
     697             :   //   bit 1: optimized frame.
     698             :   //   bit 2: inlined in optimized frame
     699             :   int flags = 0;
     700      687519 :   if (*save->context() == *isolate->debug()->debug_context()) {
     701             :     flags |= 1 << 0;
     702             :   }
     703      229173 :   if (is_optimized) {
     704       24888 :     flags |= 1 << 1;
     705       24888 :     flags |= inlined_frame_index << 2;
     706             :   }
     707      458346 :   details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
     708             : 
     709             :   // Fill the dynamic part.
     710             :   int details_index = kFrameDetailsFirstDynamicIndex;
     711             : 
     712             :   // Add arguments name and value.
     713       62544 :   for (int i = 0; i < argument_count; i++) {
     714             :     // Name of the argument.
     715       62544 :     if (i < scope_info->ParameterCount()) {
     716       89076 :       details->set(details_index++, scope_info->ParameterName(i));
     717             :     } else {
     718       36012 :       details->set(details_index++, heap->undefined_value());
     719             :     }
     720             : 
     721             :     // Parameter value.
     722       62544 :     if (i < frame_inspector.GetParametersCount()) {
     723             :       // Get the value from the stack.
     724      177888 :       details->set(details_index++, *(frame_inspector.GetParameter(i)));
     725             :     } else {
     726        6496 :       details->set(details_index++, heap->undefined_value());
     727             :     }
     728             :   }
     729             : 
     730             :   // Add locals name and value from the temporary copy from the function frame.
     731    20171557 :   for (const auto& local : locals) details->set(details_index++, *local);
     732             : 
     733             :   // Add the value being returned.
     734      229173 :   if (at_return) {
     735       10284 :     details->set(details_index++, *return_value);
     736             :   }
     737             : 
     738             :   // Add the receiver (same as in function frame).
     739      229173 :   Handle<Object> receiver = frame_inspector.summary().receiver();
     740             :   DCHECK(function->shared()->IsUserJavaScript());
     741             :   // Optimized frames only restore the receiver as best-effort (see
     742             :   // OptimizedFrame::Summarize).
     743             :   DCHECK_IMPLIES(!is_optimized && is_sloppy(shared->language_mode()),
     744             :                  receiver->IsJSReceiver());
     745      229173 :   details->set(kFrameDetailsReceiverIndex, *receiver);
     746             : 
     747             :   DCHECK_EQ(details_size, details_index);
     748      687893 :   return *isolate->factory()->NewJSArrayWithElements(details);
     749             : }
     750             : 
     751             : 
     752           0 : RUNTIME_FUNCTION(Runtime_GetScopeCount) {
     753           0 :   HandleScope scope(isolate);
     754             :   DCHECK_EQ(2, args.length());
     755           0 :   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
     756           0 :   CHECK(isolate->debug()->CheckExecutionState(break_id));
     757             : 
     758           0 :   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
     759             : 
     760             :   // Get the frame where the debugging is performed.
     761           0 :   StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id);
     762           0 :   StackTraceFrameIterator it(isolate, id);
     763           0 :   StandardFrame* frame = it.frame();
     764           0 :   if (it.frame()->is_wasm()) return 0;
     765             : 
     766           0 :   FrameInspector frame_inspector(frame, 0, isolate);
     767             : 
     768             :   // Count the visible scopes.
     769             :   int n = 0;
     770           0 :   for (ScopeIterator it(isolate, &frame_inspector); !it.Done(); it.Next()) {
     771           0 :     n++;
     772           0 :   }
     773             : 
     774           0 :   return Smi::FromInt(n);
     775             : }
     776             : 
     777             : 
     778             : // Return an array with scope details
     779             : // args[0]: number: break id
     780             : // args[1]: number: frame index
     781             : // args[2]: number: inlined frame index
     782             : // args[3]: number: scope index
     783             : //
     784             : // The array returned contains the following information:
     785             : // 0: Scope type
     786             : // 1: Scope object
     787         510 : RUNTIME_FUNCTION(Runtime_GetScopeDetails) {
     788         170 :   HandleScope scope(isolate);
     789             :   DCHECK_EQ(4, args.length());
     790         340 :   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
     791         170 :   CHECK(isolate->debug()->CheckExecutionState(break_id));
     792             : 
     793         340 :   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
     794         340 :   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
     795         340 :   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
     796             : 
     797             :   // Get the frame where the debugging is performed.
     798         170 :   StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id);
     799         340 :   StackTraceFrameIterator frame_it(isolate, id);
     800             :   // Wasm has no scopes, this must be javascript.
     801         170 :   JavaScriptFrame* frame = JavaScriptFrame::cast(frame_it.frame());
     802         340 :   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
     803             : 
     804             :   // Find the requested scope.
     805             :   int n = 0;
     806         340 :   ScopeIterator it(isolate, &frame_inspector);
     807          60 :   for (; !it.Done() && n < index; it.Next()) {
     808          60 :     n++;
     809             :   }
     810         170 :   if (it.Done()) {
     811           0 :     return isolate->heap()->undefined_value();
     812             :   }
     813         510 :   RETURN_RESULT_OR_FAILURE(isolate, it.MaterializeScopeDetails());
     814             : }
     815             : 
     816             : 
     817             : // Return an array of scope details
     818             : // args[0]: number: break id
     819             : // args[1]: number: frame index
     820             : // args[2]: number: inlined frame index
     821             : // args[3]: boolean: ignore nested scopes
     822             : //
     823             : // The array returned contains arrays with the following information:
     824             : // 0: Scope type
     825             : // 1: Scope object
     826      575694 : RUNTIME_FUNCTION(Runtime_GetAllScopesDetails) {
     827      191898 :   HandleScope scope(isolate);
     828             :   DCHECK(args.length() == 3 || args.length() == 4);
     829      383796 :   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
     830      191898 :   CHECK(isolate->debug()->CheckExecutionState(break_id));
     831             : 
     832      383796 :   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
     833      383796 :   CONVERT_NUMBER_CHECKED(int, inlined_frame_index, Int32, args[2]);
     834             : 
     835             :   ScopeIterator::Option option = ScopeIterator::DEFAULT;
     836      191898 :   if (args.length() == 4) {
     837      383796 :     CONVERT_BOOLEAN_ARG_CHECKED(flag, 3);
     838      191898 :     if (flag) option = ScopeIterator::IGNORE_NESTED_SCOPES;
     839             :   }
     840             : 
     841             :   // Get the frame where the debugging is performed.
     842      191898 :   StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id);
     843      383796 :   StackTraceFrameIterator frame_it(isolate, id);
     844      191898 :   StandardFrame* frame = frame_it.frame();
     845             : 
     846             :   // Handle wasm frames specially. They provide exactly two scopes (global /
     847             :   // local).
     848      192174 :   if (frame->is_wasm_interpreter_entry()) {
     849             :     Handle<WasmDebugInfo> debug_info(
     850             :         WasmInterpreterEntryFrame::cast(frame)->wasm_instance()->debug_info(),
     851         276 :         isolate);
     852             :     return *WasmDebugInfo::GetScopeDetails(debug_info, frame->fp(),
     853         552 :                                            inlined_frame_index);
     854             :   }
     855             : 
     856      383244 :   FrameInspector frame_inspector(frame, inlined_frame_index, isolate);
     857             :   List<Handle<JSObject>> result(4);
     858      383244 :   ScopeIterator it(isolate, &frame_inspector, option);
     859      512512 :   for (; !it.Done(); it.Next()) {
     860             :     Handle<JSObject> details;
     861     1025024 :     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, details,
     862             :                                        it.MaterializeScopeDetails());
     863      512512 :     result.Add(details);
     864             :   }
     865             : 
     866      191622 :   Handle<FixedArray> array = isolate->factory()->NewFixedArray(result.length());
     867      512512 :   for (int i = 0; i < result.length(); ++i) {
     868     1025024 :     array->set(i, *result[i]);
     869             :   }
     870      575142 :   return *isolate->factory()->NewJSArrayWithElements(array);
     871             : }
     872             : 
     873             : 
     874          48 : RUNTIME_FUNCTION(Runtime_GetFunctionScopeCount) {
     875          24 :   HandleScope scope(isolate);
     876             :   DCHECK_EQ(1, args.length());
     877             : 
     878             :   // Check arguments.
     879          48 :   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
     880             : 
     881             :   // Count the visible scopes.
     882             :   int n = 0;
     883          24 :   if (function->IsJSFunction()) {
     884          96 :     for (ScopeIterator it(isolate, Handle<JSFunction>::cast(function));
     885          48 :          !it.Done(); it.Next()) {
     886          48 :       n++;
     887          24 :     }
     888             :   }
     889             : 
     890          24 :   return Smi::FromInt(n);
     891             : }
     892             : 
     893             : 
     894          96 : RUNTIME_FUNCTION(Runtime_GetFunctionScopeDetails) {
     895          48 :   HandleScope scope(isolate);
     896             :   DCHECK_EQ(2, args.length());
     897             : 
     898             :   // Check arguments.
     899          96 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
     900          96 :   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
     901             : 
     902             :   // Find the requested scope.
     903             :   int n = 0;
     904          96 :   ScopeIterator it(isolate, fun);
     905          24 :   for (; !it.Done() && n < index; it.Next()) {
     906          24 :     n++;
     907             :   }
     908          48 :   if (it.Done()) {
     909           0 :     return isolate->heap()->undefined_value();
     910             :   }
     911             : 
     912         144 :   RETURN_RESULT_OR_FAILURE(isolate, it.MaterializeScopeDetails());
     913             : }
     914             : 
     915         968 : RUNTIME_FUNCTION(Runtime_GetGeneratorScopeCount) {
     916         484 :   HandleScope scope(isolate);
     917             :   DCHECK_EQ(1, args.length());
     918             : 
     919         968 :   if (!args[0]->IsJSGeneratorObject()) return Smi::kZero;
     920             : 
     921             :   // Check arguments.
     922         968 :   CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, gen, 0);
     923             : 
     924             :   // Count the visible scopes.
     925             :   int n = 0;
     926        2300 :   for (ScopeIterator it(isolate, gen); !it.Done(); it.Next()) {
     927        1816 :     n++;
     928         484 :   }
     929             : 
     930         484 :   return Smi::FromInt(n);
     931             : }
     932             : 
     933        3212 : RUNTIME_FUNCTION(Runtime_GetGeneratorScopeDetails) {
     934        1606 :   HandleScope scope(isolate);
     935             :   DCHECK_EQ(2, args.length());
     936             : 
     937        3212 :   if (!args[0]->IsJSGeneratorObject()) {
     938           0 :     return isolate->heap()->undefined_value();
     939             :   }
     940             : 
     941             :   // Check arguments.
     942        3212 :   CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, gen, 0);
     943        3212 :   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
     944             : 
     945             :   // Find the requested scope.
     946             :   int n = 0;
     947        3212 :   ScopeIterator it(isolate, gen);
     948        1620 :   for (; !it.Done() && n < index; it.Next()) {
     949        1620 :     n++;
     950             :   }
     951        1606 :   if (it.Done()) {
     952           0 :     return isolate->heap()->undefined_value();
     953             :   }
     954             : 
     955        4818 :   RETURN_RESULT_OR_FAILURE(isolate, it.MaterializeScopeDetails());
     956             : }
     957             : 
     958         376 : static bool SetScopeVariableValue(ScopeIterator* it, int index,
     959             :                                   Handle<String> variable_name,
     960             :                                   Handle<Object> new_value) {
     961        1096 :   for (int n = 0; !it->Done() && n < index; it->Next()) {
     962         172 :     n++;
     963             :   }
     964         376 :   if (it->Done()) {
     965             :     return false;
     966             :   }
     967         376 :   return it->SetVariableValue(variable_name, new_value);
     968             : }
     969             : 
     970             : 
     971             : // Change variable value in closure or local scope
     972             : // args[0]: number or JsFunction: break id or function
     973             : // args[1]: number: frame index (when arg[0] is break id)
     974             : // args[2]: number: inlined frame index (when arg[0] is break id)
     975             : // args[3]: number: scope index
     976             : // args[4]: string: variable name
     977             : // args[5]: object: new value
     978             : //
     979             : // Return true if success and false otherwise
     980         946 : RUNTIME_FUNCTION(Runtime_SetScopeVariableValue) {
     981         376 :   HandleScope scope(isolate);
     982             :   DCHECK_EQ(6, args.length());
     983             : 
     984             :   // Check arguments.
     985         752 :   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
     986         752 :   CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4);
     987         376 :   CONVERT_ARG_HANDLE_CHECKED(Object, new_value, 5);
     988             : 
     989             :   bool res;
     990         752 :   if (args[0]->IsNumber()) {
     991         388 :     CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
     992         194 :     CHECK(isolate->debug()->CheckExecutionState(break_id));
     993             : 
     994         388 :     CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
     995         388 :     CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
     996             : 
     997             :     // Get the frame where the debugging is performed.
     998         194 :     StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id);
     999         194 :     StackTraceFrameIterator frame_it(isolate, id);
    1000             :     // Wasm has no scopes, this must be javascript.
    1001         194 :     JavaScriptFrame* frame = JavaScriptFrame::cast(frame_it.frame());
    1002         388 :     FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
    1003             : 
    1004         388 :     ScopeIterator it(isolate, &frame_inspector);
    1005         388 :     res = SetScopeVariableValue(&it, index, variable_name, new_value);
    1006         364 :   } else if (args[0]->IsJSFunction()) {
    1007           0 :     CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
    1008           0 :     ScopeIterator it(isolate, fun);
    1009           0 :     res = SetScopeVariableValue(&it, index, variable_name, new_value);
    1010             :   } else {
    1011         364 :     CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, gen, 0);
    1012         182 :     ScopeIterator it(isolate, gen);
    1013         182 :     res = SetScopeVariableValue(&it, index, variable_name, new_value);
    1014             :   }
    1015             : 
    1016         376 :   return isolate->heap()->ToBoolean(res);
    1017             : }
    1018             : 
    1019             : 
    1020           0 : RUNTIME_FUNCTION(Runtime_DebugPrintScopes) {
    1021           0 :   HandleScope scope(isolate);
    1022             :   DCHECK_EQ(0, args.length());
    1023             : 
    1024             : #ifdef DEBUG
    1025             :   // Print the scopes for the top frame.
    1026             :   StackFrameLocator locator(isolate);
    1027             :   JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
    1028             :   FrameInspector frame_inspector(frame, 0, isolate);
    1029             : 
    1030             :   for (ScopeIterator it(isolate, &frame_inspector); !it.Done(); it.Next()) {
    1031             :     it.DebugPrint();
    1032             :   }
    1033             : #endif
    1034           0 :   return isolate->heap()->undefined_value();
    1035             : }
    1036             : 
    1037             : 
    1038             : // Sets the disable break state
    1039             : // args[0]: disable break state
    1040           0 : RUNTIME_FUNCTION(Runtime_SetBreakPointsActive) {
    1041           0 :   HandleScope scope(isolate);
    1042             :   DCHECK_EQ(1, args.length());
    1043           0 :   CONVERT_BOOLEAN_ARG_CHECKED(active, 0);
    1044           0 :   isolate->debug()->set_break_points_active(active);
    1045           0 :   return isolate->heap()->undefined_value();
    1046             : }
    1047             : 
    1048             : 
    1049        3111 : static bool IsPositionAlignmentCodeCorrect(int alignment) {
    1050        3111 :   return alignment == STATEMENT_ALIGNED || alignment == BREAK_POSITION_ALIGNED;
    1051             : }
    1052             : 
    1053             : 
    1054        1176 : RUNTIME_FUNCTION(Runtime_GetBreakLocations) {
    1055         392 :   HandleScope scope(isolate);
    1056             :   DCHECK_EQ(2, args.length());
    1057         392 :   CHECK(isolate->debug()->is_active());
    1058         784 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
    1059         784 :   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[1]);
    1060             : 
    1061         392 :   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
    1062           0 :     return isolate->ThrowIllegalOperation();
    1063             :   }
    1064             :   BreakPositionAlignment alignment =
    1065         392 :       static_cast<BreakPositionAlignment>(statement_aligned_code);
    1066             : 
    1067         392 :   Handle<SharedFunctionInfo> shared(fun->shared());
    1068             :   // Find the number of break points
    1069             :   Handle<Object> break_locations =
    1070         392 :       Debug::GetSourceBreakLocations(shared, alignment);
    1071         392 :   if (break_locations->IsUndefined(isolate)) {
    1072          56 :     return isolate->heap()->undefined_value();
    1073             :   }
    1074             :   // Return array as JS array
    1075             :   return *isolate->factory()->NewJSArrayWithElements(
    1076        1008 :       Handle<FixedArray>::cast(break_locations));
    1077             : }
    1078             : 
    1079             : 
    1080             : // Set a break point in a function.
    1081             : // args[0]: function
    1082             : // args[1]: number: break source position (within the function source)
    1083             : // args[2]: number: break point object
    1084           0 : RUNTIME_FUNCTION(Runtime_SetFunctionBreakPoint) {
    1085           0 :   HandleScope scope(isolate);
    1086             :   DCHECK_EQ(3, args.length());
    1087           0 :   CHECK(isolate->debug()->is_active());
    1088           0 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
    1089           0 :   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
    1090           0 :   CHECK(source_position >= function->shared()->start_position() &&
    1091             :         source_position <= function->shared()->end_position());
    1092           0 :   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 2);
    1093             : 
    1094             :   // Set break point.
    1095           0 :   CHECK(isolate->debug()->SetBreakPoint(function, break_point_object_arg,
    1096             :                                         &source_position));
    1097             : 
    1098           0 :   return Smi::FromInt(source_position);
    1099             : }
    1100             : 
    1101             : 
    1102             : // Changes the state of a break point in a script and returns source position
    1103             : // where break point was set. NOTE: Regarding performance see the NOTE for
    1104             : // GetScriptFromScriptData.
    1105             : // args[0]: script to set break point in
    1106             : // args[1]: number: break source position (within the script source)
    1107             : // args[2]: number, breakpoint position alignment
    1108             : // args[3]: number: break point object
    1109       10876 : RUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) {
    1110        2719 :   HandleScope scope(isolate);
    1111             :   DCHECK_EQ(4, args.length());
    1112        2719 :   CHECK(isolate->debug()->is_active());
    1113        5438 :   CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
    1114        5438 :   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
    1115        2719 :   CHECK(source_position >= 0);
    1116        5438 :   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[2]);
    1117        2719 :   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 3);
    1118             : 
    1119        2719 :   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
    1120           0 :     return isolate->ThrowIllegalOperation();
    1121             :   }
    1122             :   BreakPositionAlignment alignment =
    1123        2719 :       static_cast<BreakPositionAlignment>(statement_aligned_code);
    1124             : 
    1125             :   // Get the script from the script wrapper.
    1126        5438 :   CHECK(wrapper->value()->IsScript());
    1127        2719 :   Handle<Script> script(Script::cast(wrapper->value()));
    1128             : 
    1129             :   // Set break point.
    1130        2719 :   if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg,
    1131        2719 :                                                 &source_position, alignment)) {
    1132           6 :     return isolate->heap()->undefined_value();
    1133             :   }
    1134             : 
    1135        2713 :   return Smi::FromInt(source_position);
    1136             : }
    1137             : 
    1138             : 
    1139             : // Clear a break point
    1140             : // args[0]: number: break point object
    1141        5552 : RUNTIME_FUNCTION(Runtime_ClearBreakPoint) {
    1142        2776 :   HandleScope scope(isolate);
    1143             :   DCHECK_EQ(1, args.length());
    1144        2776 :   CHECK(isolate->debug()->is_active());
    1145        2776 :   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 0);
    1146             : 
    1147             :   // Clear break point.
    1148        2776 :   isolate->debug()->ClearBreakPoint(break_point_object_arg);
    1149             : 
    1150        2776 :   return isolate->heap()->undefined_value();
    1151             : }
    1152             : 
    1153             : 
    1154             : // Change the state of break on exceptions.
    1155             : // args[0]: Enum value indicating whether to affect caught/uncaught exceptions.
    1156             : // args[1]: Boolean indicating on/off.
    1157         144 : RUNTIME_FUNCTION(Runtime_ChangeBreakOnException) {
    1158          48 :   HandleScope scope(isolate);
    1159             :   DCHECK_EQ(2, args.length());
    1160          96 :   CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
    1161          96 :   CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
    1162             : 
    1163             :   // If the number doesn't match an enum value, the ChangeBreakOnException
    1164             :   // function will default to affecting caught exceptions.
    1165             :   ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
    1166             :   // Update break point state.
    1167          96 :   isolate->debug()->ChangeBreakOnException(type, enable);
    1168          48 :   return isolate->heap()->undefined_value();
    1169             : }
    1170             : 
    1171             : 
    1172             : // Returns the state of break on exceptions
    1173             : // args[0]: boolean indicating uncaught exceptions
    1174       15372 : RUNTIME_FUNCTION(Runtime_IsBreakOnException) {
    1175        5124 :   HandleScope scope(isolate);
    1176             :   DCHECK_EQ(1, args.length());
    1177       10248 :   CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
    1178             : 
    1179             :   ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
    1180        5124 :   bool result = isolate->debug()->IsBreakOnException(type);
    1181        5124 :   return Smi::FromInt(result);
    1182             : }
    1183             : 
    1184             : 
    1185             : // Prepare for stepping
    1186             : // args[0]: break id for checking execution state
    1187             : // args[1]: step action from the enumeration StepAction
    1188             : // args[2]: number of times to perform the step, for step out it is the number
    1189             : //          of frames to step down.
    1190         390 : RUNTIME_FUNCTION(Runtime_PrepareStep) {
    1191          78 :   HandleScope scope(isolate);
    1192             :   DCHECK_EQ(2, args.length());
    1193         156 :   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
    1194          78 :   CHECK(isolate->debug()->CheckExecutionState(break_id));
    1195             : 
    1196         156 :   if (!args[1]->IsNumber()) {
    1197           0 :     return isolate->Throw(isolate->heap()->illegal_argument_string());
    1198             :   }
    1199             : 
    1200             :   // Get the step action and check validity.
    1201          78 :   StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1]));
    1202          78 :   if (step_action != StepIn && step_action != StepNext &&
    1203             :       step_action != StepOut) {
    1204           0 :     return isolate->Throw(isolate->heap()->illegal_argument_string());
    1205             :   }
    1206             : 
    1207             :   // Clear all current stepping setup.
    1208          78 :   isolate->debug()->ClearStepping();
    1209             : 
    1210             :   // Prepare step.
    1211         156 :   isolate->debug()->PrepareStep(static_cast<StepAction>(step_action));
    1212          78 :   return isolate->heap()->undefined_value();
    1213             : }
    1214             : 
    1215             : // Clear all stepping set by PrepareStep.
    1216          56 : RUNTIME_FUNCTION(Runtime_ClearStepping) {
    1217          28 :   HandleScope scope(isolate);
    1218             :   DCHECK_EQ(0, args.length());
    1219          28 :   CHECK(isolate->debug()->is_active());
    1220          28 :   isolate->debug()->ClearStepping();
    1221          28 :   return isolate->heap()->undefined_value();
    1222             : }
    1223             : 
    1224             : 
    1225       46737 : RUNTIME_FUNCTION(Runtime_DebugEvaluate) {
    1226       15579 :   HandleScope scope(isolate);
    1227             : 
    1228             :   // Check the execution state and decode arguments frame and source to be
    1229             :   // evaluated.
    1230             :   DCHECK_EQ(5, args.length());
    1231       31158 :   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
    1232       15579 :   CHECK(isolate->debug()->CheckExecutionState(break_id));
    1233             : 
    1234       31158 :   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
    1235       31158 :   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
    1236       31158 :   CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
    1237       31158 :   CONVERT_BOOLEAN_ARG_CHECKED(throw_on_side_effect, 4);
    1238             : 
    1239       15579 :   StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id);
    1240             : 
    1241       31158 :   RETURN_RESULT_OR_FAILURE(
    1242             :       isolate, DebugEvaluate::Local(isolate, id, inlined_jsframe_index, source,
    1243       15579 :                                     throw_on_side_effect));
    1244             : }
    1245             : 
    1246             : 
    1247          18 : RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) {
    1248           6 :   HandleScope scope(isolate);
    1249             : 
    1250             :   // Check the execution state and decode arguments frame and source to be
    1251             :   // evaluated.
    1252             :   DCHECK_EQ(2, args.length());
    1253          12 :   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
    1254           6 :   CHECK(isolate->debug()->CheckExecutionState(break_id));
    1255             : 
    1256          12 :   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
    1257             : 
    1258          18 :   RETURN_RESULT_OR_FAILURE(isolate, DebugEvaluate::Global(isolate, source));
    1259             : }
    1260             : 
    1261             : 
    1262       11580 : RUNTIME_FUNCTION(Runtime_DebugGetLoadedScripts) {
    1263        2920 :   HandleScope scope(isolate);
    1264             :   DCHECK_EQ(0, args.length());
    1265             : 
    1266             :   Handle<FixedArray> instances;
    1267             :   {
    1268        2920 :     DebugScope debug_scope(isolate->debug());
    1269        2920 :     if (debug_scope.failed()) {
    1270             :       DCHECK(isolate->has_pending_exception());
    1271         100 :       return isolate->heap()->exception();
    1272             :     }
    1273             :     // Fill the script objects.
    1274        2820 :     instances = isolate->debug()->GetLoadedScripts();
    1275             :   }
    1276             : 
    1277             :   // Convert the script objects to proper JS objects.
    1278      153796 :   for (int i = 0; i < instances->length(); i++) {
    1279       75488 :     Handle<Script> script = Handle<Script>(Script::cast(instances->get(i)));
    1280             :     // Get the script wrapper in a local handle before calling GetScriptWrapper,
    1281             :     // because using
    1282             :     //   instances->set(i, *GetScriptWrapper(script))
    1283             :     // is unsafe as GetScriptWrapper might call GC and the C++ compiler might
    1284             :     // already have dereferenced the instances handle.
    1285       75488 :     Handle<JSObject> wrapper = Script::GetWrapper(script);
    1286       75488 :     instances->set(i, *wrapper);
    1287             :   }
    1288             : 
    1289             :   // Return result as a JS array.
    1290        5640 :   return *isolate->factory()->NewJSArrayWithElements(instances);
    1291             : }
    1292             : 
    1293           0 : static bool HasInPrototypeChainIgnoringProxies(Isolate* isolate,
    1294             :                                                JSObject* object,
    1295             :                                                Object* proto) {
    1296             :   PrototypeIterator iter(isolate, object, kStartAtReceiver);
    1297             :   while (true) {
    1298           0 :     iter.AdvanceIgnoringProxies();
    1299           0 :     if (iter.IsAtEnd()) return false;
    1300           0 :     if (iter.GetCurrent() == proto) return true;
    1301             :   }
    1302             : }
    1303             : 
    1304             : 
    1305             : // Scan the heap for objects with direct references to an object
    1306             : // args[0]: the object to find references to
    1307             : // args[1]: constructor function for instances to exclude (Mirror)
    1308             : // args[2]: the the maximum number of objects to return
    1309           0 : RUNTIME_FUNCTION(Runtime_DebugReferencedBy) {
    1310           0 :   HandleScope scope(isolate);
    1311             :   DCHECK_EQ(3, args.length());
    1312           0 :   CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
    1313           0 :   CONVERT_ARG_HANDLE_CHECKED(Object, filter, 1);
    1314           0 :   CHECK(filter->IsUndefined(isolate) || filter->IsJSObject());
    1315           0 :   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
    1316           0 :   CHECK(max_references >= 0);
    1317             : 
    1318           0 :   List<Handle<JSObject> > instances;
    1319           0 :   Heap* heap = isolate->heap();
    1320             :   {
    1321           0 :     HeapIterator iterator(heap, HeapIterator::kFilterUnreachable);
    1322             :     // Get the constructor function for context extension and arguments array.
    1323           0 :     Object* arguments_fun = isolate->sloppy_arguments_map()->GetConstructor();
    1324             :     HeapObject* heap_obj;
    1325           0 :     while ((heap_obj = iterator.next()) != nullptr) {
    1326           0 :       if (!heap_obj->IsJSObject()) continue;
    1327             :       JSObject* obj = JSObject::cast(heap_obj);
    1328           0 :       if (obj->IsJSContextExtensionObject()) continue;
    1329           0 :       if (obj->map()->GetConstructor() == arguments_fun) continue;
    1330           0 :       if (!obj->ReferencesObject(*target)) continue;
    1331             :       // Check filter if supplied. This is normally used to avoid
    1332             :       // references from mirror objects.
    1333           0 :       if (!filter->IsUndefined(isolate) &&
    1334           0 :           HasInPrototypeChainIgnoringProxies(isolate, obj, *filter)) {
    1335             :         continue;
    1336             :       }
    1337           0 :       if (obj->IsJSGlobalObject()) {
    1338           0 :         obj = JSGlobalObject::cast(obj)->global_proxy();
    1339             :       }
    1340           0 :       instances.Add(Handle<JSObject>(obj));
    1341           0 :       if (instances.length() == max_references) break;
    1342             :     }
    1343             :     // Iterate the rest of the heap to satisfy HeapIterator constraints.
    1344           0 :     while (iterator.next()) {
    1345           0 :     }
    1346             :   }
    1347             : 
    1348             :   Handle<FixedArray> result;
    1349           0 :   if (instances.length() == 1 && instances.last().is_identical_to(target)) {
    1350             :     // Check for circular reference only. This can happen when the object is
    1351             :     // only referenced from mirrors and has a circular reference in which case
    1352             :     // the object is not really alive and would have been garbage collected if
    1353             :     // not referenced from the mirror.
    1354           0 :     result = isolate->factory()->empty_fixed_array();
    1355             :   } else {
    1356           0 :     result = isolate->factory()->NewFixedArray(instances.length());
    1357           0 :     for (int i = 0; i < instances.length(); ++i) result->set(i, *instances[i]);
    1358             :   }
    1359           0 :   return *isolate->factory()->NewJSArrayWithElements(result);
    1360             : }
    1361             : 
    1362             : 
    1363             : // Scan the heap for objects constructed by a specific function.
    1364             : // args[0]: the constructor to find instances of
    1365             : // args[1]: the the maximum number of objects to return
    1366           0 : RUNTIME_FUNCTION(Runtime_DebugConstructedBy) {
    1367           0 :   HandleScope scope(isolate);
    1368             :   DCHECK_EQ(2, args.length());
    1369           0 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
    1370           0 :   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
    1371           0 :   CHECK(max_references >= 0);
    1372             : 
    1373           0 :   List<Handle<JSObject> > instances;
    1374           0 :   Heap* heap = isolate->heap();
    1375             :   {
    1376           0 :     HeapIterator iterator(heap, HeapIterator::kFilterUnreachable);
    1377             :     HeapObject* heap_obj;
    1378           0 :     while ((heap_obj = iterator.next()) != nullptr) {
    1379           0 :       if (!heap_obj->IsJSObject()) continue;
    1380             :       JSObject* obj = JSObject::cast(heap_obj);
    1381           0 :       if (obj->map()->GetConstructor() != *constructor) continue;
    1382           0 :       instances.Add(Handle<JSObject>(obj));
    1383           0 :       if (instances.length() == max_references) break;
    1384             :     }
    1385             :     // Iterate the rest of the heap to satisfy HeapIterator constraints.
    1386           0 :     while (iterator.next()) {
    1387           0 :     }
    1388             :   }
    1389             : 
    1390             :   Handle<FixedArray> result =
    1391           0 :       isolate->factory()->NewFixedArray(instances.length());
    1392           0 :   for (int i = 0; i < instances.length(); ++i) result->set(i, *instances[i]);
    1393           0 :   return *isolate->factory()->NewJSArrayWithElements(result);
    1394             : }
    1395             : 
    1396             : 
    1397             : // Find the effective prototype object as returned by __proto__.
    1398             : // args[0]: the object to find the prototype for.
    1399          12 : RUNTIME_FUNCTION(Runtime_DebugGetPrototype) {
    1400           6 :   HandleScope shs(isolate);
    1401             :   DCHECK_EQ(1, args.length());
    1402          12 :   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
    1403             :   // TODO(1543): Come up with a solution for clients to handle potential errors
    1404             :   // thrown by an intermediate proxy.
    1405          18 :   RETURN_RESULT_OR_FAILURE(isolate, JSReceiver::GetPrototype(isolate, obj));
    1406             : }
    1407             : 
    1408             : 
    1409             : // Patches script source (should be called upon BeforeCompile event).
    1410             : // TODO(5530): Remove once uses in debug.js are gone.
    1411           0 : RUNTIME_FUNCTION(Runtime_DebugSetScriptSource) {
    1412           0 :   HandleScope scope(isolate);
    1413             :   DCHECK_EQ(2, args.length());
    1414             : 
    1415           0 :   CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0);
    1416           0 :   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
    1417             : 
    1418           0 :   CHECK(script_wrapper->value()->IsScript());
    1419           0 :   Handle<Script> script(Script::cast(script_wrapper->value()));
    1420             : 
    1421             :   // The following condition is not guaranteed to hold and a failure is also
    1422             :   // propagated to callers. Hence we fail gracefully here and don't crash.
    1423           0 :   if (script->compilation_state() != Script::COMPILATION_STATE_INITIAL) {
    1424           0 :     return isolate->ThrowIllegalOperation();
    1425             :   }
    1426             : 
    1427           0 :   script->set_source(*source);
    1428             : 
    1429           0 :   return isolate->heap()->undefined_value();
    1430             : }
    1431             : 
    1432             : 
    1433         174 : RUNTIME_FUNCTION(Runtime_FunctionGetInferredName) {
    1434             :   SealHandleScope shs(isolate);
    1435             :   DCHECK_EQ(1, args.length());
    1436             : 
    1437          87 :   CONVERT_ARG_CHECKED(Object, f, 0);
    1438          87 :   if (f->IsJSFunction()) {
    1439          72 :     return JSFunction::cast(f)->shared()->inferred_name();
    1440             :   }
    1441          15 :   return isolate->heap()->empty_string();
    1442             : }
    1443             : 
    1444             : 
    1445      382088 : RUNTIME_FUNCTION(Runtime_FunctionGetDebugName) {
    1446      191044 :   HandleScope scope(isolate);
    1447             :   DCHECK_EQ(1, args.length());
    1448             : 
    1449      382088 :   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
    1450             : 
    1451      191044 :   if (function->IsJSBoundFunction()) {
    1452           0 :     RETURN_RESULT_OR_FAILURE(
    1453             :         isolate, JSBoundFunction::GetName(
    1454             :                      isolate, Handle<JSBoundFunction>::cast(function)));
    1455             :   } else {
    1456      382088 :     return *JSFunction::GetDebugName(Handle<JSFunction>::cast(function));
    1457      191044 :   }
    1458             : }
    1459             : 
    1460             : 
    1461       11176 : RUNTIME_FUNCTION(Runtime_GetDebugContext) {
    1462        3169 :   HandleScope scope(isolate);
    1463             :   DCHECK_EQ(0, args.length());
    1464             :   Handle<Context> context;
    1465             :   {
    1466        3169 :     DebugScope debug_scope(isolate->debug());
    1467        3169 :     if (debug_scope.failed()) {
    1468             :       DCHECK(isolate->has_pending_exception());
    1469        1500 :       return isolate->heap()->exception();
    1470             :     }
    1471        1669 :     context = isolate->debug()->GetDebugContext();
    1472             :   }
    1473        1669 :   if (context.is_null()) return isolate->heap()->undefined_value();
    1474        5007 :   context->set_security_token(isolate->native_context()->security_token());
    1475        1669 :   return context->global_proxy();
    1476             : }
    1477             : 
    1478             : 
    1479             : // Performs a GC.
    1480             : // Presently, it only does a full GC.
    1481          56 : RUNTIME_FUNCTION(Runtime_CollectGarbage) {
    1482             :   SealHandleScope shs(isolate);
    1483             :   DCHECK_EQ(1, args.length());
    1484             :   isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
    1485          28 :                                      GarbageCollectionReason::kRuntime);
    1486          28 :   return isolate->heap()->undefined_value();
    1487             : }
    1488             : 
    1489             : 
    1490             : // Gets the current heap usage.
    1491           0 : RUNTIME_FUNCTION(Runtime_GetHeapUsage) {
    1492             :   SealHandleScope shs(isolate);
    1493             :   DCHECK_EQ(0, args.length());
    1494           0 :   int usage = static_cast<int>(isolate->heap()->SizeOfObjects());
    1495           0 :   if (!Smi::IsValid(usage)) {
    1496           0 :     return *isolate->factory()->NewNumberFromInt(usage);
    1497             :   }
    1498           0 :   return Smi::FromInt(usage);
    1499             : }
    1500             : 
    1501             : 
    1502             : // Finds the script object from the script data. NOTE: This operation uses
    1503             : // heap traversal to find the function generated for the source position
    1504             : // for the requested break point. For lazily compiled functions several heap
    1505             : // traversals might be required rendering this operation as a rather slow
    1506             : // operation. However for setting break points which is normally done through
    1507             : // some kind of user interaction the performance is not crucial.
    1508         108 : RUNTIME_FUNCTION(Runtime_GetScript) {
    1509          54 :   HandleScope scope(isolate);
    1510             :   DCHECK_EQ(1, args.length());
    1511         108 :   CONVERT_ARG_HANDLE_CHECKED(String, script_name, 0);
    1512             : 
    1513             :   Handle<Script> found;
    1514             :   {
    1515          54 :     Script::Iterator iterator(isolate);
    1516             :     Script* script = NULL;
    1517        1056 :     while ((script = iterator.Next()) != NULL) {
    1518        2070 :       if (!script->name()->IsString()) continue;
    1519         921 :       String* name = String::cast(script->name());
    1520         921 :       if (name->Equals(*script_name)) {
    1521             :         found = Handle<Script>(script, isolate);
    1522             :         break;
    1523             :       }
    1524             :     }
    1525             :   }
    1526             : 
    1527          54 :   if (found.is_null()) return isolate->heap()->undefined_value();
    1528          66 :   return *Script::GetWrapper(found);
    1529             : }
    1530             : 
    1531             : // TODO(5530): Remove once uses in debug.js are gone.
    1532        7716 : RUNTIME_FUNCTION(Runtime_ScriptLineCount) {
    1533        3858 :   HandleScope scope(isolate);
    1534             :   DCHECK_EQ(1, args.length());
    1535        7716 :   CONVERT_ARG_CHECKED(JSValue, script, 0);
    1536             : 
    1537        7716 :   CHECK(script->value()->IsScript());
    1538        3858 :   Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
    1539             : 
    1540        3858 :   if (script_handle->type() == Script::TYPE_WASM) {
    1541             :     // Return 0 for now; this function will disappear soon anyway.
    1542           0 :     return Smi::FromInt(0);
    1543             :   }
    1544             : 
    1545        3858 :   Script::InitLineEnds(script_handle);
    1546             : 
    1547        3858 :   FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends());
    1548        3858 :   return Smi::FromInt(line_ends_array->length());
    1549             : }
    1550             : 
    1551             : namespace {
    1552             : 
    1553      208314 : int ScriptLinePosition(Handle<Script> script, int line) {
    1554      208314 :   if (line < 0) return -1;
    1555             : 
    1556      208314 :   if (script->type() == Script::TYPE_WASM) {
    1557             :     return WasmCompiledModule::cast(script->wasm_compiled_module())
    1558         212 :         ->GetFunctionOffset(line);
    1559             :   }
    1560             : 
    1561      208208 :   Script::InitLineEnds(script);
    1562             : 
    1563             :   FixedArray* line_ends_array = FixedArray::cast(script->line_ends());
    1564             :   const int line_count = line_ends_array->length();
    1565             :   DCHECK_LT(0, line_count);
    1566             : 
    1567      208208 :   if (line == 0) return 0;
    1568             :   // If line == line_count, we return the first position beyond the last line.
    1569      172909 :   if (line > line_count) return -1;
    1570      345818 :   return Smi::cast(line_ends_array->get(line - 1))->value() + 1;
    1571             : }
    1572             : 
    1573             : }  // namespace
    1574             : 
    1575             : // TODO(5530): Remove once uses in debug.js are gone.
    1576           0 : RUNTIME_FUNCTION(Runtime_ScriptLineStartPosition) {
    1577           0 :   HandleScope scope(isolate);
    1578             :   DCHECK_EQ(2, args.length());
    1579           0 :   CONVERT_ARG_CHECKED(JSValue, script, 0);
    1580           0 :   CONVERT_NUMBER_CHECKED(int32_t, line, Int32, args[1]);
    1581             : 
    1582           0 :   CHECK(script->value()->IsScript());
    1583           0 :   Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
    1584             : 
    1585           0 :   return Smi::FromInt(ScriptLinePosition(script_handle, line));
    1586             : }
    1587             : 
    1588             : // TODO(5530): Remove once uses in debug.js are gone.
    1589           0 : RUNTIME_FUNCTION(Runtime_ScriptLineEndPosition) {
    1590           0 :   HandleScope scope(isolate);
    1591             :   DCHECK_EQ(2, args.length());
    1592           0 :   CONVERT_ARG_CHECKED(JSValue, script, 0);
    1593           0 :   CONVERT_NUMBER_CHECKED(int32_t, line, Int32, args[1]);
    1594             : 
    1595           0 :   CHECK(script->value()->IsScript());
    1596           0 :   Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
    1597             : 
    1598           0 :   if (script_handle->type() == Script::TYPE_WASM) {
    1599             :     // Return zero for now; this function will disappear soon anyway.
    1600           0 :     return Smi::FromInt(0);
    1601             :   }
    1602             : 
    1603           0 :   Script::InitLineEnds(script_handle);
    1604             : 
    1605           0 :   FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends());
    1606           0 :   const int line_count = line_ends_array->length();
    1607             : 
    1608           0 :   if (line < 0 || line >= line_count) {
    1609           0 :     return Smi::FromInt(-1);
    1610             :   } else {
    1611           0 :     return Smi::cast(line_ends_array->get(line));
    1612           0 :   }
    1613             : }
    1614             : 
    1615      857290 : static Handle<Object> GetJSPositionInfo(Handle<Script> script, int position,
    1616             :                                         Script::OffsetFlag offset_flag,
    1617             :                                         Isolate* isolate) {
    1618             :   Script::PositionInfo info;
    1619      857290 :   if (!Script::GetPositionInfo(script, position, &info, offset_flag)) {
    1620          14 :     return isolate->factory()->null_value();
    1621             :   }
    1622             : 
    1623      857276 :   Handle<String> source = handle(String::cast(script->source()), isolate);
    1624             :   Handle<String> sourceText = script->type() == Script::TYPE_WASM
    1625             :                                   ? isolate->factory()->empty_string()
    1626             :                                   : isolate->factory()->NewSubString(
    1627     1714034 :                                         source, info.line_start, info.line_end);
    1628             : 
    1629             :   Handle<JSObject> jsinfo =
    1630      857276 :       isolate->factory()->NewJSObject(isolate->object_function());
    1631             : 
    1632             :   JSObject::AddProperty(jsinfo, isolate->factory()->script_string(), script,
    1633      857276 :                         NONE);
    1634             :   JSObject::AddProperty(jsinfo, isolate->factory()->position_string(),
    1635      857276 :                         handle(Smi::FromInt(position), isolate), NONE);
    1636             :   JSObject::AddProperty(jsinfo, isolate->factory()->line_string(),
    1637     1714552 :                         handle(Smi::FromInt(info.line), isolate), NONE);
    1638             :   JSObject::AddProperty(jsinfo, isolate->factory()->column_string(),
    1639     1714552 :                         handle(Smi::FromInt(info.column), isolate), NONE);
    1640             :   JSObject::AddProperty(jsinfo, isolate->factory()->sourceText_string(),
    1641      857276 :                         sourceText, NONE);
    1642             : 
    1643      857276 :   return jsinfo;
    1644             : }
    1645             : 
    1646             : namespace {
    1647             : 
    1648      208314 : int ScriptLinePositionWithOffset(Handle<Script> script, int line, int offset) {
    1649      208314 :   if (line < 0 || offset < 0) return -1;
    1650             : 
    1651      208314 :   if (line == 0 || offset == 0)
    1652      207110 :     return ScriptLinePosition(script, line) + offset;
    1653             : 
    1654             :   Script::PositionInfo info;
    1655        1204 :   if (!Script::GetPositionInfo(script, offset, &info, Script::NO_OFFSET)) {
    1656             :     return -1;
    1657             :   }
    1658             : 
    1659        1204 :   const int total_line = info.line + line;
    1660        1204 :   return ScriptLinePosition(script, total_line);
    1661             : }
    1662             : 
    1663      208314 : Handle<Object> ScriptLocationFromLine(Isolate* isolate, Handle<Script> script,
    1664             :                                       Handle<Object> opt_line,
    1665             :                                       Handle<Object> opt_column,
    1666             :                                       int32_t offset) {
    1667             :   // Line and column are possibly undefined and we need to handle these cases,
    1668             :   // additionally subtracting corresponding offsets.
    1669             : 
    1670             :   int32_t line = 0;
    1671      208314 :   if (!opt_line->IsNullOrUndefined(isolate)) {
    1672      208034 :     CHECK(opt_line->IsNumber());
    1673      416068 :     line = NumberToInt32(*opt_line) - script->line_offset();
    1674             :   }
    1675             : 
    1676             :   int32_t column = 0;
    1677      208314 :   if (!opt_column->IsNullOrUndefined(isolate)) {
    1678      207346 :     CHECK(opt_column->IsNumber());
    1679      207346 :     column = NumberToInt32(*opt_column);
    1680      242269 :     if (line == 0) column -= script->column_offset();
    1681             :   }
    1682             : 
    1683      208314 :   int line_position = ScriptLinePositionWithOffset(script, line, offset);
    1684      208314 :   if (line_position < 0 || column < 0) return isolate->factory()->null_value();
    1685             : 
    1686             :   return GetJSPositionInfo(script, line_position + column, Script::NO_OFFSET,
    1687      208314 :                            isolate);
    1688             : }
    1689             : 
    1690             : // Slow traversal over all scripts on the heap.
    1691      205044 : bool GetScriptById(Isolate* isolate, int needle, Handle<Script>* result) {
    1692      205044 :   Script::Iterator iterator(isolate);
    1693             :   Script* script = NULL;
    1694      205044 :   while ((script = iterator.Next()) != NULL) {
    1695     5536910 :     if (script->id() == needle) {
    1696      205044 :       *result = handle(script);
    1697      205044 :       return true;
    1698             :     }
    1699             :   }
    1700             : 
    1701             :   return false;
    1702             : }
    1703             : 
    1704             : }  // namespace
    1705             : 
    1706             : // Get information on a specific source line and column possibly offset by a
    1707             : // fixed source position. This function is used to find a source position from
    1708             : // a line and column position. The fixed source position offset is typically
    1709             : // used to find a source position in a function based on a line and column in
    1710             : // the source for the function alone. The offset passed will then be the
    1711             : // start position of the source for the function within the full script source.
    1712             : // Note that incoming line and column parameters may be undefined, and are
    1713             : // assumed to be passed *with* offsets.
    1714             : // TODO(5530): Remove once uses in debug.js are gone.
    1715        6596 : RUNTIME_FUNCTION(Runtime_ScriptLocationFromLine) {
    1716        3298 :   HandleScope scope(isolate);
    1717             :   DCHECK_EQ(4, args.length());
    1718        6596 :   CONVERT_ARG_HANDLE_CHECKED(JSValue, script, 0);
    1719        3298 :   CONVERT_ARG_HANDLE_CHECKED(Object, opt_line, 1);
    1720        3298 :   CONVERT_ARG_HANDLE_CHECKED(Object, opt_column, 2);
    1721        6596 :   CONVERT_NUMBER_CHECKED(int32_t, offset, Int32, args[3]);
    1722             : 
    1723        6596 :   CHECK(script->value()->IsScript());
    1724        3298 :   Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
    1725             : 
    1726             :   return *ScriptLocationFromLine(isolate, script_handle, opt_line, opt_column,
    1727        6596 :                                  offset);
    1728             : }
    1729             : 
    1730             : // TODO(5530): Rename once conflicting function has been deleted.
    1731      410032 : RUNTIME_FUNCTION(Runtime_ScriptLocationFromLine2) {
    1732      205016 :   HandleScope scope(isolate);
    1733             :   DCHECK_EQ(4, args.length());
    1734      410032 :   CONVERT_NUMBER_CHECKED(int32_t, scriptid, Int32, args[0]);
    1735      205016 :   CONVERT_ARG_HANDLE_CHECKED(Object, opt_line, 1);
    1736      205016 :   CONVERT_ARG_HANDLE_CHECKED(Object, opt_column, 2);
    1737      410032 :   CONVERT_NUMBER_CHECKED(int32_t, offset, Int32, args[3]);
    1738             : 
    1739             :   Handle<Script> script;
    1740      205016 :   CHECK(GetScriptById(isolate, scriptid, &script));
    1741             : 
    1742      410032 :   return *ScriptLocationFromLine(isolate, script, opt_line, opt_column, offset);
    1743             : }
    1744             : 
    1745             : // TODO(5530): Remove once uses in debug.js are gone.
    1746     1297896 : RUNTIME_FUNCTION(Runtime_ScriptPositionInfo) {
    1747      648948 :   HandleScope scope(isolate);
    1748             :   DCHECK_EQ(3, args.length());
    1749     1297896 :   CONVERT_ARG_CHECKED(JSValue, script, 0);
    1750     1297896 :   CONVERT_NUMBER_CHECKED(int32_t, position, Int32, args[1]);
    1751     1297896 :   CONVERT_BOOLEAN_ARG_CHECKED(with_offset, 2);
    1752             : 
    1753     1297896 :   CHECK(script->value()->IsScript());
    1754      648948 :   Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
    1755             : 
    1756             :   const Script::OffsetFlag offset_flag =
    1757      648948 :       with_offset ? Script::WITH_OFFSET : Script::NO_OFFSET;
    1758     1297896 :   return *GetJSPositionInfo(script_handle, position, offset_flag, isolate);
    1759             : }
    1760             : 
    1761             : // TODO(5530): Rename once conflicting function has been deleted.
    1762          56 : RUNTIME_FUNCTION(Runtime_ScriptPositionInfo2) {
    1763          28 :   HandleScope scope(isolate);
    1764             :   DCHECK_EQ(3, args.length());
    1765          56 :   CONVERT_NUMBER_CHECKED(int32_t, scriptid, Int32, args[0]);
    1766          56 :   CONVERT_NUMBER_CHECKED(int32_t, position, Int32, args[1]);
    1767          56 :   CONVERT_BOOLEAN_ARG_CHECKED(with_offset, 2);
    1768             : 
    1769             :   Handle<Script> script;
    1770          28 :   CHECK(GetScriptById(isolate, scriptid, &script));
    1771             : 
    1772             :   const Script::OffsetFlag offset_flag =
    1773          28 :       with_offset ? Script::WITH_OFFSET : Script::NO_OFFSET;
    1774          56 :   return *GetJSPositionInfo(script, position, offset_flag, isolate);
    1775             : }
    1776             : 
    1777             : // Returns the given line as a string, or null if line is out of bounds.
    1778             : // The parameter line is expected to include the script's line offset.
    1779             : // TODO(5530): Remove once uses in debug.js are gone.
    1780         120 : RUNTIME_FUNCTION(Runtime_ScriptSourceLine) {
    1781          60 :   HandleScope scope(isolate);
    1782             :   DCHECK_EQ(2, args.length());
    1783         120 :   CONVERT_ARG_CHECKED(JSValue, script, 0);
    1784         120 :   CONVERT_NUMBER_CHECKED(int32_t, line, Int32, args[1]);
    1785             : 
    1786         120 :   CHECK(script->value()->IsScript());
    1787          60 :   Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
    1788             : 
    1789          60 :   if (script_handle->type() == Script::TYPE_WASM) {
    1790             :     // Return null for now; this function will disappear soon anyway.
    1791           0 :     return isolate->heap()->null_value();
    1792             :   }
    1793             : 
    1794          60 :   Script::InitLineEnds(script_handle);
    1795             : 
    1796          60 :   FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends());
    1797          60 :   const int line_count = line_ends_array->length();
    1798             : 
    1799          60 :   line -= script_handle->line_offset();
    1800          60 :   if (line < 0 || line_count <= line) {
    1801           0 :     return isolate->heap()->null_value();
    1802             :   }
    1803             : 
    1804             :   const int start =
    1805          60 :       (line == 0) ? 0 : Smi::cast(line_ends_array->get(line - 1))->value() + 1;
    1806          60 :   const int end = Smi::cast(line_ends_array->get(line))->value();
    1807             : 
    1808             :   Handle<String> source =
    1809         120 :       handle(String::cast(script_handle->source()), isolate);
    1810          60 :   Handle<String> str = isolate->factory()->NewSubString(source, start, end);
    1811             : 
    1812          60 :   return *str;
    1813             : }
    1814             : 
    1815             : // On function call, depending on circumstances, prepare for stepping in,
    1816             : // or perform a side effect check.
    1817     6888300 : RUNTIME_FUNCTION(Runtime_DebugOnFunctionCall) {
    1818     1377660 :   HandleScope scope(isolate);
    1819             :   DCHECK_EQ(1, args.length());
    1820     2755320 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
    1821     1377660 :   if (isolate->debug()->last_step_action() >= StepIn) {
    1822     1368204 :     isolate->debug()->PrepareStepIn(fun);
    1823             :   }
    1824     1387116 :   if (isolate->needs_side_effect_check() &&
    1825        9456 :       !isolate->debug()->PerformSideEffectCheck(fun)) {
    1826        1110 :     return isolate->heap()->exception();
    1827             :   }
    1828     1376550 :   return isolate->heap()->undefined_value();
    1829             : }
    1830             : 
    1831             : // Set one shot breakpoints for the suspended generator object.
    1832         432 : RUNTIME_FUNCTION(Runtime_DebugPrepareStepInSuspendedGenerator) {
    1833         216 :   HandleScope scope(isolate);
    1834             :   DCHECK_EQ(0, args.length());
    1835         216 :   isolate->debug()->PrepareStepInSuspendedGenerator();
    1836         216 :   return isolate->heap()->undefined_value();
    1837             : }
    1838             : 
    1839        1000 : RUNTIME_FUNCTION(Runtime_DebugRecordGenerator) {
    1840         250 :   HandleScope scope(isolate);
    1841             :   DCHECK_EQ(1, args.length());
    1842         500 :   CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
    1843         250 :   CHECK(isolate->debug()->last_step_action() >= StepNext);
    1844         250 :   isolate->debug()->RecordGenerator(generator);
    1845         250 :   return isolate->heap()->undefined_value();
    1846             : }
    1847             : 
    1848       42324 : RUNTIME_FUNCTION(Runtime_DebugPushPromise) {
    1849             :   DCHECK_EQ(1, args.length());
    1850       21162 :   HandleScope scope(isolate);
    1851       42324 :   CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
    1852       21162 :   isolate->PushPromise(promise);
    1853       21162 :   return isolate->heap()->undefined_value();
    1854             : }
    1855             : 
    1856             : 
    1857       56916 : RUNTIME_FUNCTION(Runtime_DebugPopPromise) {
    1858             :   DCHECK_EQ(0, args.length());
    1859             :   SealHandleScope shs(isolate);
    1860       28458 :   isolate->PopPromise();
    1861       28458 :   return isolate->heap()->undefined_value();
    1862             : }
    1863             : 
    1864       29296 : RUNTIME_FUNCTION(Runtime_DebugAsyncFunctionPromiseCreated) {
    1865             :   DCHECK_EQ(1, args.length());
    1866        7324 :   HandleScope scope(isolate);
    1867       14648 :   CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
    1868        7324 :   isolate->PushPromise(promise);
    1869        7324 :   int id = isolate->debug()->NextAsyncTaskId(promise);
    1870             :   Handle<Symbol> async_stack_id_symbol =
    1871        7324 :       isolate->factory()->promise_async_stack_id_symbol();
    1872             :   JSObject::SetProperty(promise, async_stack_id_symbol,
    1873             :                         handle(Smi::FromInt(id), isolate), STRICT)
    1874       14648 :       .Assert();
    1875        7324 :   isolate->debug()->OnAsyncTaskEvent(debug::kDebugEnqueueAsyncFunction, id, 0);
    1876        7324 :   return isolate->heap()->undefined_value();
    1877             : }
    1878             : 
    1879        2304 : RUNTIME_FUNCTION(Runtime_DebugPromiseReject) {
    1880         768 :   HandleScope scope(isolate);
    1881             :   DCHECK_EQ(2, args.length());
    1882        1536 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, rejected_promise, 0);
    1883         768 :   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
    1884             : 
    1885         768 :   isolate->debug()->OnPromiseReject(rejected_promise, value);
    1886         768 :   return isolate->heap()->undefined_value();
    1887             : }
    1888             : 
    1889      184660 : RUNTIME_FUNCTION(Runtime_DebugAsyncEventEnqueueRecurring) {
    1890       36932 :   HandleScope scope(isolate);
    1891             :   DCHECK_EQ(2, args.length());
    1892       73864 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
    1893       73864 :   CONVERT_SMI_ARG_CHECKED(status, 1);
    1894       36932 :   if (isolate->debug()->is_active()) {
    1895             :     isolate->debug()->OnAsyncTaskEvent(
    1896             :         status == v8::Promise::kFulfilled ? debug::kDebugEnqueuePromiseResolve
    1897             :                                           : debug::kDebugEnqueuePromiseReject,
    1898       73864 :         isolate->debug()->NextAsyncTaskId(promise), 0);
    1899             :   }
    1900       36932 :   return isolate->heap()->undefined_value();
    1901             : }
    1902             : 
    1903        1644 : RUNTIME_FUNCTION(Runtime_DebugIsActive) {
    1904             :   SealHandleScope shs(isolate);
    1905         822 :   return Smi::FromInt(isolate->debug()->is_active());
    1906             : }
    1907             : 
    1908           0 : RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) {
    1909           0 :   UNIMPLEMENTED();
    1910             :   return NULL;
    1911             : }
    1912             : 
    1913         112 : RUNTIME_FUNCTION(Runtime_DebugCollectCoverage) {
    1914          56 :   HandleScope scope(isolate);
    1915             :   DCHECK_EQ(0, args.length());
    1916             :   // Collect coverage data.
    1917         112 :   std::unique_ptr<Coverage> coverage;
    1918          56 :   if (isolate->is_best_effort_code_coverage()) {
    1919          42 :     coverage.reset(Coverage::CollectBestEffort(isolate));
    1920             :   } else {
    1921          14 :     coverage.reset(Coverage::CollectPrecise(isolate));
    1922             :   }
    1923          56 :   Factory* factory = isolate->factory();
    1924             :   // Turn the returned data structure into JavaScript.
    1925             :   // Create an array of scripts.
    1926          56 :   int num_scripts = static_cast<int>(coverage->size());
    1927             :   // Prepare property keys.
    1928          56 :   Handle<FixedArray> scripts_array = factory->NewFixedArray(num_scripts);
    1929          56 :   Handle<String> script_string = factory->NewStringFromStaticChars("script");
    1930          56 :   Handle<String> start_string = factory->NewStringFromStaticChars("start");
    1931          56 :   Handle<String> end_string = factory->NewStringFromStaticChars("end");
    1932          56 :   Handle<String> count_string = factory->NewStringFromStaticChars("count");
    1933         196 :   for (int i = 0; i < num_scripts; i++) {
    1934         196 :     const auto& script_data = coverage->at(i);
    1935         196 :     HandleScope inner_scope(isolate);
    1936         196 :     int num_functions = static_cast<int>(script_data.functions.size());
    1937         196 :     Handle<FixedArray> functions_array = factory->NewFixedArray(num_functions);
    1938        2205 :     for (int j = 0; j < num_functions; j++) {
    1939        2205 :       const auto& function_data = script_data.functions[j];
    1940        2205 :       Handle<JSObject> range_obj = factory->NewJSObjectWithNullProto();
    1941             :       JSObject::AddProperty(range_obj, start_string,
    1942             :                             factory->NewNumberFromInt(function_data.start),
    1943        4410 :                             NONE);
    1944             :       JSObject::AddProperty(range_obj, end_string,
    1945        4410 :                             factory->NewNumberFromInt(function_data.end), NONE);
    1946             :       JSObject::AddProperty(range_obj, count_string,
    1947             :                             factory->NewNumberFromUint(function_data.count),
    1948        4410 :                             NONE);
    1949        2205 :       functions_array->set(j, *range_obj);
    1950             :     }
    1951             :     Handle<JSArray> script_obj =
    1952         196 :         factory->NewJSArrayWithElements(functions_array, FAST_ELEMENTS);
    1953         196 :     Handle<JSObject> wrapper = Script::GetWrapper(script_data.script);
    1954         196 :     JSObject::AddProperty(script_obj, script_string, wrapper, NONE);
    1955         196 :     scripts_array->set(i, *script_obj);
    1956         196 :   }
    1957         168 :   return *factory->NewJSArrayWithElements(scripts_array, FAST_ELEMENTS);
    1958             : }
    1959             : 
    1960          28 : RUNTIME_FUNCTION(Runtime_DebugTogglePreciseCoverage) {
    1961             :   SealHandleScope shs(isolate);
    1962          28 :   CONVERT_BOOLEAN_ARG_CHECKED(enable, 0);
    1963             :   Coverage::SelectMode(isolate, enable ? debug::Coverage::kPreciseCount
    1964          14 :                                        : debug::Coverage::kBestEffort);
    1965          14 :   return isolate->heap()->undefined_value();
    1966             : }
    1967             : 
    1968             : }  // namespace internal
    1969             : }  // namespace v8

Generated by: LCOV version 1.10