7 #include "src/arguments-inl.h" 8 #include "src/compiler.h" 9 #include "src/counters.h" 10 #include "src/debug/debug-coverage.h" 11 #include "src/debug/debug-evaluate.h" 12 #include "src/debug/debug-frames.h" 13 #include "src/debug/debug-scopes.h" 14 #include "src/debug/debug.h" 15 #include "src/debug/liveedit.h" 16 #include "src/frames-inl.h" 17 #include "src/globals.h" 18 #include "src/interpreter/bytecode-array-accessor.h" 19 #include "src/interpreter/bytecodes.h" 20 #include "src/interpreter/interpreter.h" 21 #include "src/isolate-inl.h" 22 #include "src/objects/debug-objects-inl.h" 23 #include "src/objects/heap-object-inl.h" 24 #include "src/objects/js-collection-inl.h" 25 #include "src/objects/js-generator-inl.h" 26 #include "src/objects/js-promise-inl.h" 27 #include "src/runtime/runtime-utils.h" 28 #include "src/runtime/runtime.h" 29 #include "src/snapshot/snapshot.h" 30 #include "src/wasm/wasm-objects-inl.h" 35 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_DebugBreakOnBytecode) {
36 using interpreter::Bytecode;
37 using interpreter::Bytecodes;
38 using interpreter::OperandScale;
40 SealHandleScope shs(isolate);
41 DCHECK_EQ(1, args.length());
42 CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
43 HandleScope scope(isolate);
47 ReturnValueScope result_scope(isolate->debug());
48 isolate->debug()->set_return_value(*value);
51 JavaScriptFrameIterator it(isolate);
52 if (isolate->debug_execution_mode() == DebugInfo::kBreakpoints) {
53 isolate->debug()->Break(it.frame(),
54 handle(it.frame()->function(), isolate));
59 if (isolate->debug()->will_restart()) {
60 return MakePair(ReadOnlyRoots(isolate).undefined_value(),
61 Smi::FromInt(static_cast<uint8_t>(Bytecode::kIllegal)));
65 DCHECK(it.frame()->is_interpreted());
66 InterpretedFrame* interpreted_frame =
67 reinterpret_cast<InterpretedFrame*
>(it.frame());
68 SharedFunctionInfo* shared = interpreted_frame->function()->shared();
69 BytecodeArray bytecode_array = shared->GetBytecodeArray();
70 int bytecode_offset = interpreted_frame->GetBytecodeOffset();
71 Bytecode bytecode = Bytecodes::FromByte(bytecode_array->get(bytecode_offset));
73 bool side_effect_check_failed =
false;
74 if (isolate->debug_execution_mode() == DebugInfo::kSideEffects) {
75 side_effect_check_failed =
76 !isolate->debug()->PerformSideEffectCheckAtBytecode(interpreted_frame);
79 if (Bytecodes::Returns(bytecode)) {
84 interpreted_frame->PatchBytecodeArray(bytecode_array);
92 OperandScale operand_scale = OperandScale::kSingle;
93 isolate->interpreter()->GetBytecodeHandler(bytecode, operand_scale);
95 if (side_effect_check_failed) {
96 return MakePair(ReadOnlyRoots(isolate).exception(),
97 Smi::FromInt(static_cast<uint8_t>(bytecode)));
99 Object* interrupt_object = isolate->stack_guard()->HandleInterrupts();
100 if (interrupt_object->IsException(isolate)) {
101 return MakePair(interrupt_object,
102 Smi::FromInt(static_cast<uint8_t>(bytecode)));
104 return MakePair(isolate->debug()->return_value(),
105 Smi::FromInt(static_cast<uint8_t>(bytecode)));
108 RUNTIME_FUNCTION(Runtime_DebugBreakAtEntry) {
109 HandleScope scope(isolate);
110 DCHECK_EQ(1, args.length());
111 CONVERT_ARG_HANDLE_CHECKED(JSFunction,
function, 0);
114 DCHECK(function->shared()->HasDebugInfo());
115 DCHECK(function->shared()->GetDebugInfo()->BreakAtEntry());
118 JavaScriptFrameIterator it(isolate);
119 DCHECK_EQ(*
function, it.frame()->function());
120 isolate->debug()->Break(it.frame(),
function);
122 return ReadOnlyRoots(isolate).undefined_value();
125 RUNTIME_FUNCTION(Runtime_HandleDebuggerStatement) {
126 SealHandleScope shs(isolate);
127 DCHECK_EQ(0, args.length());
128 if (isolate->debug()->break_points_active()) {
129 isolate->debug()->HandleDebugBreak(kIgnoreIfTopFrameBlackboxed);
131 return isolate->stack_guard()->HandleInterrupts();
134 RUNTIME_FUNCTION(Runtime_ScheduleBreak) {
135 SealHandleScope shs(isolate);
136 DCHECK_EQ(0, args.length());
137 isolate->RequestInterrupt(
138 [](v8::Isolate* isolate,
void*) { v8::debug::BreakRightNow(isolate); },
140 return ReadOnlyRoots(isolate).undefined_value();
143 template <
class IteratorType>
144 static MaybeHandle<JSArray> GetIteratorInternalProperties(
145 Isolate* isolate, Handle<IteratorType>
object) {
146 Factory* factory = isolate->factory();
147 Handle<IteratorType> iterator = Handle<IteratorType>::cast(
object);
148 const char* kind =
nullptr;
149 switch (iterator->map()->instance_type()) {
150 case JS_MAP_KEY_ITERATOR_TYPE:
153 case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
154 case JS_SET_KEY_VALUE_ITERATOR_TYPE:
157 case JS_MAP_VALUE_ITERATOR_TYPE:
158 case JS_SET_VALUE_ITERATOR_TYPE:
165 Handle<FixedArray> result = factory->NewFixedArray(2 * 3);
166 Handle<String> has_more =
167 factory->NewStringFromAsciiChecked(
"[[IteratorHasMore]]");
168 result->set(0, *has_more);
169 result->set(1, isolate->heap()->ToBoolean(iterator->HasMore()));
171 Handle<String> index =
172 factory->NewStringFromAsciiChecked(
"[[IteratorIndex]]");
173 result->set(2, *index);
174 result->set(3, iterator->index());
176 Handle<String> iterator_kind =
177 factory->NewStringFromAsciiChecked(
"[[IteratorKind]]");
178 result->set(4, *iterator_kind);
179 Handle<String> kind_str = factory->NewStringFromAsciiChecked(kind);
180 result->set(5, *kind_str);
181 return factory->NewJSArrayWithElements(result);
185 MaybeHandle<JSArray> Runtime::GetInternalProperties(Isolate* isolate,
186 Handle<Object>
object) {
187 Factory* factory = isolate->factory();
188 if (object->IsJSBoundFunction()) {
189 Handle<JSBoundFunction>
function = Handle<JSBoundFunction>::cast(
object);
191 Handle<FixedArray> result = factory->NewFixedArray(2 * 3);
192 Handle<String> target =
193 factory->NewStringFromAsciiChecked(
"[[TargetFunction]]");
194 result->set(0, *target);
195 result->set(1, function->bound_target_function());
197 Handle<String> bound_this =
198 factory->NewStringFromAsciiChecked(
"[[BoundThis]]");
199 result->set(2, *bound_this);
200 result->set(3, function->bound_this());
202 Handle<String> bound_args =
203 factory->NewStringFromAsciiChecked(
"[[BoundArgs]]");
204 result->set(4, *bound_args);
205 Handle<FixedArray> bound_arguments =
206 factory->CopyFixedArray(handle(function->bound_arguments(), isolate));
207 Handle<JSArray> arguments_array =
208 factory->NewJSArrayWithElements(bound_arguments);
209 result->set(5, *arguments_array);
210 return factory->NewJSArrayWithElements(result);
211 }
else if (object->IsJSMapIterator()) {
212 Handle<JSMapIterator> iterator = Handle<JSMapIterator>::cast(
object);
213 return GetIteratorInternalProperties(isolate, iterator);
214 }
else if (object->IsJSSetIterator()) {
215 Handle<JSSetIterator> iterator = Handle<JSSetIterator>::cast(
object);
216 return GetIteratorInternalProperties(isolate, iterator);
217 }
else if (object->IsJSGeneratorObject()) {
218 Handle<JSGeneratorObject> generator =
219 Handle<JSGeneratorObject>::cast(
object);
221 const char* status =
"suspended";
222 if (generator->is_closed()) {
224 }
else if (generator->is_executing()) {
227 DCHECK(generator->is_suspended());
230 Handle<FixedArray> result = factory->NewFixedArray(2 * 3);
231 Handle<String> generator_status =
232 factory->NewStringFromAsciiChecked(
"[[GeneratorStatus]]");
233 result->set(0, *generator_status);
234 Handle<String> status_str = factory->NewStringFromAsciiChecked(status);
235 result->set(1, *status_str);
237 Handle<String>
function =
238 factory->NewStringFromAsciiChecked(
"[[GeneratorFunction]]");
239 result->set(2, *
function);
240 result->set(3, generator->function());
242 Handle<String> receiver =
243 factory->NewStringFromAsciiChecked(
"[[GeneratorReceiver]]");
244 result->set(4, *receiver);
245 result->set(5, generator->receiver());
246 return factory->NewJSArrayWithElements(result);
247 }
else if (object->IsJSPromise()) {
248 Handle<JSPromise> promise = Handle<JSPromise>::cast(
object);
249 const char* status = JSPromise::Status(promise->status());
250 Handle<FixedArray> result = factory->NewFixedArray(2 * 2);
251 Handle<String> promise_status =
252 factory->NewStringFromAsciiChecked(
"[[PromiseStatus]]");
253 result->set(0, *promise_status);
254 Handle<String> status_str = factory->NewStringFromAsciiChecked(status);
255 result->set(1, *status_str);
257 Handle<Object> value_obj(promise->status() == Promise::kPending
258 ? ReadOnlyRoots(isolate).undefined_value()
261 Handle<String> promise_value =
262 factory->NewStringFromAsciiChecked(
"[[PromiseValue]]");
263 result->set(2, *promise_value);
264 result->set(3, *value_obj);
265 return factory->NewJSArrayWithElements(result);
266 }
else if (object->IsJSProxy()) {
267 Handle<JSProxy> js_proxy = Handle<JSProxy>::cast(
object);
268 Handle<FixedArray> result = factory->NewFixedArray(3 * 2);
270 Handle<String> handler_str =
271 factory->NewStringFromAsciiChecked(
"[[Handler]]");
272 result->set(0, *handler_str);
273 result->set(1, js_proxy->handler());
275 Handle<String> target_str =
276 factory->NewStringFromAsciiChecked(
"[[Target]]");
277 result->set(2, *target_str);
278 result->set(3, js_proxy->target());
280 Handle<String> is_revoked_str =
281 factory->NewStringFromAsciiChecked(
"[[IsRevoked]]");
282 result->set(4, *is_revoked_str);
283 result->set(5, isolate->heap()->ToBoolean(js_proxy->IsRevoked()));
284 return factory->NewJSArrayWithElements(result);
285 }
else if (object->IsJSValue()) {
286 Handle<JSValue> js_value = Handle<JSValue>::cast(
object);
288 Handle<FixedArray> result = factory->NewFixedArray(2);
289 Handle<String> primitive_value =
290 factory->NewStringFromAsciiChecked(
"[[PrimitiveValue]]");
291 result->set(0, *primitive_value);
292 result->set(1, js_value->value());
293 return factory->NewJSArrayWithElements(result);
295 return factory->NewJSArray(0);
298 RUNTIME_FUNCTION(Runtime_GetGeneratorScopeCount) {
299 HandleScope scope(isolate);
300 DCHECK_EQ(1, args.length());
302 if (!args[0]->IsJSGeneratorObject())
return Smi::kZero;
305 CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, gen, 0);
308 if (!gen->is_suspended()) {
314 for (ScopeIterator it(isolate, gen); !it.Done(); it.Next()) {
318 return Smi::FromInt(n);
321 RUNTIME_FUNCTION(Runtime_GetGeneratorScopeDetails) {
322 HandleScope scope(isolate);
323 DCHECK_EQ(2, args.length());
325 if (!args[0]->IsJSGeneratorObject()) {
326 return ReadOnlyRoots(isolate).undefined_value();
330 CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, gen, 0);
331 CONVERT_NUMBER_CHECKED(
int, index, Int32, args[1]);
334 if (!gen->is_suspended()) {
335 return ReadOnlyRoots(isolate).undefined_value();
340 ScopeIterator it(isolate, gen);
341 for (; !it.Done() && n < index; it.Next()) {
345 return ReadOnlyRoots(isolate).undefined_value();
348 return *it.MaterializeScopeDetails();
351 static bool SetScopeVariableValue(ScopeIterator* it,
int index,
352 Handle<String> variable_name,
353 Handle<Object> new_value) {
354 for (
int n = 0; !it->Done() && n < index; it->Next()) {
360 return it->SetVariableValue(variable_name, new_value);
370 RUNTIME_FUNCTION(Runtime_SetGeneratorScopeVariableValue) {
371 HandleScope scope(isolate);
372 DCHECK_EQ(4, args.length());
373 CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, gen, 0);
374 CONVERT_NUMBER_CHECKED(
int, index, Int32, args[1]);
375 CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 2);
376 CONVERT_ARG_HANDLE_CHECKED(Object, new_value, 3);
377 ScopeIterator it(isolate, gen);
378 bool res = SetScopeVariableValue(&it, index, variable_name, new_value);
379 return isolate->heap()->ToBoolean(res);
383 RUNTIME_FUNCTION(Runtime_GetBreakLocations) {
384 HandleScope scope(isolate);
385 DCHECK_EQ(1, args.length());
386 CHECK(isolate->debug()->is_active());
387 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
389 Handle<SharedFunctionInfo> shared(fun->shared(), isolate);
391 Handle<Object> break_locations =
392 Debug::GetSourceBreakLocations(isolate, shared);
393 if (break_locations->IsUndefined(isolate)) {
394 return ReadOnlyRoots(isolate).undefined_value();
397 return *isolate->factory()->NewJSArrayWithElements(
398 Handle<FixedArray>::cast(break_locations));
404 RUNTIME_FUNCTION(Runtime_IsBreakOnException) {
405 HandleScope scope(isolate);
406 DCHECK_EQ(1, args.length());
407 CONVERT_NUMBER_CHECKED(
uint32_t, type_arg, Uint32, args[0]);
409 ExceptionBreakType type =
static_cast<ExceptionBreakType
>(type_arg);
410 bool result = isolate->debug()->IsBreakOnException(type);
411 return Smi::FromInt(result);
415 RUNTIME_FUNCTION(Runtime_ClearStepping) {
416 HandleScope scope(isolate);
417 DCHECK_EQ(0, args.length());
418 CHECK(isolate->debug()->is_active());
419 isolate->debug()->ClearStepping();
420 return ReadOnlyRoots(isolate).undefined_value();
423 RUNTIME_FUNCTION(Runtime_DebugGetLoadedScriptIds) {
424 HandleScope scope(isolate);
425 DCHECK_EQ(0, args.length());
427 Handle<FixedArray> instances;
429 DebugScope debug_scope(isolate->debug());
431 instances = isolate->debug()->GetLoadedScripts();
435 for (
int i = 0;
i < instances->length();
i++) {
436 Handle<Script> script(Script::cast(instances->get(
i)), isolate);
437 instances->set(
i, Smi::FromInt(script->id()));
441 return *isolate->factory()->NewJSArrayWithElements(instances);
445 RUNTIME_FUNCTION(Runtime_FunctionGetInferredName) {
446 SealHandleScope shs(isolate);
447 DCHECK_EQ(1, args.length());
449 CONVERT_ARG_CHECKED(Object, f, 0);
450 if (f->IsJSFunction()) {
451 return JSFunction::cast(f)->shared()->inferred_name();
453 return ReadOnlyRoots(isolate).empty_string();
459 RUNTIME_FUNCTION(Runtime_CollectGarbage) {
460 SealHandleScope shs(isolate);
461 DCHECK_EQ(1, args.length());
462 isolate->heap()->PreciseCollectAllGarbage(Heap::kNoGCFlags,
463 GarbageCollectionReason::kRuntime);
464 return ReadOnlyRoots(isolate).undefined_value();
469 RUNTIME_FUNCTION(Runtime_GetHeapUsage) {
470 SealHandleScope shs(isolate);
471 DCHECK_EQ(0, args.length());
472 int usage =
static_cast<int>(isolate->heap()->SizeOfObjects());
473 if (!Smi::IsValid(usage)) {
474 return *isolate->factory()->NewNumberFromInt(usage);
476 return Smi::FromInt(usage);
481 int ScriptLinePosition(Handle<Script> script,
int line) {
482 if (line < 0)
return -1;
484 if (script->type() == Script::TYPE_WASM) {
485 return WasmModuleObject::cast(script->wasm_module_object())
486 ->GetFunctionOffset(line);
489 Script::InitLineEnds(script);
491 FixedArray line_ends_array = FixedArray::cast(script->line_ends());
492 const int line_count = line_ends_array->length();
493 DCHECK_LT(0, line_count);
495 if (line == 0)
return 0;
497 if (line > line_count)
return -1;
498 return Smi::ToInt(line_ends_array->get(line - 1)) + 1;
501 int ScriptLinePositionWithOffset(Handle<Script> script,
int line,
int offset) {
502 if (line < 0 || offset < 0)
return -1;
504 if (line == 0 || offset == 0)
505 return ScriptLinePosition(script, line) + offset;
507 Script::PositionInfo info;
508 if (!Script::GetPositionInfo(script, offset, &info, Script::NO_OFFSET)) {
512 const int total_line = info.line + line;
513 return ScriptLinePosition(script, total_line);
516 Handle<Object> GetJSPositionInfo(Handle<Script> script,
int position,
517 Script::OffsetFlag offset_flag,
519 Script::PositionInfo info;
520 if (!Script::GetPositionInfo(script, position, &info, offset_flag)) {
521 return isolate->factory()->null_value();
524 Handle<String> source = handle(String::cast(script->source()), isolate);
525 Handle<String> sourceText = script->type() == Script::TYPE_WASM
526 ? isolate->factory()->empty_string()
527 : isolate->factory()->NewSubString(
528 source, info.line_start, info.line_end);
530 Handle<JSObject> jsinfo =
531 isolate->factory()->NewJSObject(isolate->object_function());
533 JSObject::AddProperty(isolate, jsinfo, isolate->factory()->script_string(),
535 JSObject::AddProperty(isolate, jsinfo, isolate->factory()->position_string(),
536 handle(Smi::FromInt(position), isolate), NONE);
537 JSObject::AddProperty(isolate, jsinfo, isolate->factory()->line_string(),
538 handle(Smi::FromInt(info.line), isolate), NONE);
539 JSObject::AddProperty(isolate, jsinfo, isolate->factory()->column_string(),
540 handle(Smi::FromInt(info.column), isolate), NONE);
541 JSObject::AddProperty(isolate, jsinfo,
542 isolate->factory()->sourceText_string(), sourceText,
548 Handle<Object> ScriptLocationFromLine(Isolate* isolate, Handle<Script> script,
549 Handle<Object> opt_line,
550 Handle<Object> opt_column,
556 if (!opt_line->IsNullOrUndefined(isolate)) {
557 CHECK(opt_line->IsNumber());
558 line = NumberToInt32(*opt_line) - script->line_offset();
562 if (!opt_column->IsNullOrUndefined(isolate)) {
563 CHECK(opt_column->IsNumber());
564 column = NumberToInt32(*opt_column);
565 if (line == 0) column -= script->column_offset();
568 int line_position = ScriptLinePositionWithOffset(script, line, offset);
569 if (line_position < 0 || column < 0)
return isolate->factory()->null_value();
571 return GetJSPositionInfo(script, line_position + column, Script::NO_OFFSET,
576 bool GetScriptById(Isolate* isolate,
int needle, Handle<Script>* result) {
577 Script::Iterator iterator(isolate);
578 Script* script =
nullptr;
579 while ((script = iterator.Next()) !=
nullptr) {
580 if (script->id() == needle) {
581 *result = handle(script, isolate);
592 RUNTIME_FUNCTION(Runtime_ScriptLocationFromLine2) {
593 HandleScope scope(isolate);
594 DCHECK_EQ(4, args.length());
595 CONVERT_NUMBER_CHECKED(int32_t, scriptid, Int32, args[0]);
596 CONVERT_ARG_HANDLE_CHECKED(Object, opt_line, 1);
597 CONVERT_ARG_HANDLE_CHECKED(Object, opt_column, 2);
598 CONVERT_NUMBER_CHECKED(int32_t, offset, Int32, args[3]);
600 Handle<Script> script;
601 CHECK(GetScriptById(isolate, scriptid, &script));
603 return *ScriptLocationFromLine(isolate, script, opt_line, opt_column, offset);
608 RUNTIME_FUNCTION(Runtime_DebugOnFunctionCall) {
609 HandleScope scope(isolate);
610 DCHECK_EQ(2, args.length());
611 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
612 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
613 if (isolate->debug()->needs_check_on_function_call()) {
615 Deoptimizer::DeoptimizeFunction(*fun);
616 if (isolate->debug()->last_step_action() >= StepIn ||
617 isolate->debug()->break_on_next_function_call()) {
618 DCHECK_EQ(isolate->debug_execution_mode(), DebugInfo::kBreakpoints);
619 isolate->debug()->PrepareStepIn(fun);
621 if (isolate->debug_execution_mode() == DebugInfo::kSideEffects &&
622 !isolate->debug()->PerformSideEffectCheck(fun, receiver)) {
623 return ReadOnlyRoots(isolate).exception();
626 return ReadOnlyRoots(isolate).undefined_value();
630 RUNTIME_FUNCTION(Runtime_DebugPrepareStepInSuspendedGenerator) {
631 HandleScope scope(isolate);
632 DCHECK_EQ(0, args.length());
633 isolate->debug()->PrepareStepInSuspendedGenerator();
634 return ReadOnlyRoots(isolate).undefined_value();
637 RUNTIME_FUNCTION(Runtime_DebugPushPromise) {
638 DCHECK_EQ(1, args.length());
639 HandleScope scope(isolate);
640 CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
641 isolate->PushPromise(promise);
642 return ReadOnlyRoots(isolate).undefined_value();
646 RUNTIME_FUNCTION(Runtime_DebugPopPromise) {
647 DCHECK_EQ(0, args.length());
648 SealHandleScope shs(isolate);
649 isolate->PopPromise();
650 return ReadOnlyRoots(isolate).undefined_value();
654 Handle<JSObject> MakeRangeObject(Isolate* isolate,
const CoverageBlock& range) {
655 Factory* factory = isolate->factory();
657 Handle<String> start_string = factory->InternalizeUtf8String(
"start");
658 Handle<String> end_string = factory->InternalizeUtf8String(
"end");
659 Handle<String> count_string = factory->InternalizeUtf8String(
"count");
661 Handle<JSObject> range_obj = factory->NewJSObjectWithNullProto();
662 JSObject::AddProperty(isolate, range_obj, start_string,
663 factory->NewNumberFromInt(range.start), NONE);
664 JSObject::AddProperty(isolate, range_obj, end_string,
665 factory->NewNumberFromInt(range.end), NONE);
666 JSObject::AddProperty(isolate, range_obj, count_string,
667 factory->NewNumberFromUint(range.count), NONE);
673 RUNTIME_FUNCTION(Runtime_DebugCollectCoverage) {
674 HandleScope scope(isolate);
675 DCHECK_EQ(0, args.length());
677 std::unique_ptr<Coverage> coverage;
678 if (isolate->is_best_effort_code_coverage()) {
679 coverage = Coverage::CollectBestEffort(isolate);
681 coverage = Coverage::CollectPrecise(isolate);
683 Factory* factory = isolate->factory();
686 int num_scripts =
static_cast<int>(coverage->size());
688 Handle<FixedArray> scripts_array = factory->NewFixedArray(num_scripts);
689 Handle<String> script_string = factory->NewStringFromStaticChars(
"script");
690 for (
int i = 0;
i < num_scripts;
i++) {
691 const auto& script_data = coverage->at(
i);
692 HandleScope inner_scope(isolate);
694 std::vector<CoverageBlock> ranges;
695 int num_functions =
static_cast<int>(script_data.functions.size());
696 for (
int j = 0; j < num_functions; j++) {
697 const auto& function_data = script_data.functions[j];
698 ranges.emplace_back(function_data.start, function_data.end,
699 function_data.count);
700 for (
size_t k = 0; k < function_data.blocks.size(); k++) {
701 const auto& block_data = function_data.blocks[k];
702 ranges.emplace_back(block_data.start, block_data.end, block_data.count);
706 int num_ranges =
static_cast<int>(ranges.size());
707 Handle<FixedArray> ranges_array = factory->NewFixedArray(num_ranges);
708 for (
int j = 0; j < num_ranges; j++) {
709 Handle<JSObject> range_object = MakeRangeObject(isolate, ranges[j]);
710 ranges_array->set(j, *range_object);
713 Handle<JSArray> script_obj =
714 factory->NewJSArrayWithElements(ranges_array, PACKED_ELEMENTS);
715 JSObject::AddProperty(isolate, script_obj, script_string,
716 handle(script_data.script->source(), isolate), NONE);
717 scripts_array->set(
i, *script_obj);
719 return *factory->NewJSArrayWithElements(scripts_array, PACKED_ELEMENTS);
722 RUNTIME_FUNCTION(Runtime_DebugTogglePreciseCoverage) {
723 SealHandleScope shs(isolate);
724 CONVERT_BOOLEAN_ARG_CHECKED(enable, 0);
725 Coverage::SelectMode(isolate, enable ? debug::Coverage::kPreciseCount
726 : debug::Coverage::kBestEffort);
727 return ReadOnlyRoots(isolate).undefined_value();
730 RUNTIME_FUNCTION(Runtime_DebugToggleBlockCoverage) {
731 SealHandleScope shs(isolate);
732 CONVERT_BOOLEAN_ARG_CHECKED(enable, 0);
733 Coverage::SelectMode(isolate, enable ? debug::Coverage::kBlockCount
734 : debug::Coverage::kBestEffort);
735 return ReadOnlyRoots(isolate).undefined_value();
738 RUNTIME_FUNCTION(Runtime_IncBlockCounter) {
739 SealHandleScope scope(isolate);
740 DCHECK_EQ(2, args.length());
741 CONVERT_ARG_CHECKED(JSFunction,
function, 0);
742 CONVERT_SMI_ARG_CHECKED(coverage_array_slot_index, 1);
749 SharedFunctionInfo* shared =
function->shared();
750 if (shared->HasCoverageInfo()) {
751 CoverageInfo coverage_info = shared->GetCoverageInfo();
752 coverage_info->IncrementBlockCount(coverage_array_slot_index);
755 return ReadOnlyRoots(isolate).undefined_value();
758 RUNTIME_FUNCTION(Runtime_DebugAsyncFunctionEntered) {
759 DCHECK_EQ(1, args.length());
760 HandleScope scope(isolate);
761 CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
762 isolate->RunPromiseHook(PromiseHookType::kInit, promise,
763 isolate->factory()->undefined_value());
764 if (isolate->debug()->is_active()) isolate->PushPromise(promise);
765 return ReadOnlyRoots(isolate).undefined_value();
768 RUNTIME_FUNCTION(Runtime_DebugAsyncFunctionFinished) {
769 DCHECK_EQ(2, args.length());
770 HandleScope scope(isolate);
771 CONVERT_BOOLEAN_ARG_CHECKED(has_suspend, 0);
772 CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 1);
773 isolate->PopPromise();
775 isolate->OnAsyncFunctionStateChanged(promise,
776 debug::kAsyncFunctionFinished);
781 RUNTIME_FUNCTION(Runtime_DebugAsyncFunctionSuspended) {
782 DCHECK_EQ(1, args.length());
783 HandleScope scope(isolate);
784 CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
785 isolate->OnAsyncFunctionStateChanged(promise, debug::kAsyncFunctionSuspended);
786 return ReadOnlyRoots(isolate).undefined_value();
789 RUNTIME_FUNCTION(Runtime_LiveEditPatchScript) {
790 HandleScope scope(isolate);
791 DCHECK_EQ(2, args.length());
792 CONVERT_ARG_HANDLE_CHECKED(JSFunction, script_function, 0);
793 CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1);
795 Handle<Script> script(Script::cast(script_function->shared()->script()),
798 LiveEdit::PatchScript(isolate, script, new_source,
false, &result);
799 switch (result.status) {
800 case v8::debug::LiveEditResult::COMPILE_ERROR:
801 return isolate->Throw(*isolate->factory()->NewStringFromAsciiChecked(
802 "LiveEdit failed: COMPILE_ERROR"));
803 case v8::debug::LiveEditResult::BLOCKED_BY_RUNNING_GENERATOR:
804 return isolate->Throw(*isolate->factory()->NewStringFromAsciiChecked(
805 "LiveEdit failed: BLOCKED_BY_RUNNING_GENERATOR"));
806 case v8::debug::LiveEditResult::BLOCKED_BY_FUNCTION_ABOVE_BREAK_FRAME:
807 return isolate->Throw(*isolate->factory()->NewStringFromAsciiChecked(
808 "LiveEdit failed: BLOCKED_BY_FUNCTION_ABOVE_BREAK_FRAME"));
809 case v8::debug::LiveEditResult::
810 BLOCKED_BY_FUNCTION_BELOW_NON_DROPPABLE_FRAME:
811 return isolate->Throw(*isolate->factory()->NewStringFromAsciiChecked(
812 "LiveEdit failed: BLOCKED_BY_FUNCTION_BELOW_NON_DROPPABLE_FRAME"));
813 case v8::debug::LiveEditResult::BLOCKED_BY_ACTIVE_FUNCTION:
814 return isolate->Throw(*isolate->factory()->NewStringFromAsciiChecked(
815 "LiveEdit failed: BLOCKED_BY_ACTIVE_FUNCTION"));
816 case v8::debug::LiveEditResult::BLOCKED_BY_NEW_TARGET_IN_RESTART_FRAME:
817 return isolate->Throw(*isolate->factory()->NewStringFromAsciiChecked(
818 "LiveEdit failed: BLOCKED_BY_NEW_TARGET_IN_RESTART_FRAME"));
819 case v8::debug::LiveEditResult::FRAME_RESTART_IS_NOT_SUPPORTED:
820 return isolate->Throw(*isolate->factory()->NewStringFromAsciiChecked(
821 "LiveEdit failed: FRAME_RESTART_IS_NOT_SUPPORTED"));
822 case v8::debug::LiveEditResult::OK:
823 return ReadOnlyRoots(isolate).undefined_value();
825 return ReadOnlyRoots(isolate).undefined_value();
828 RUNTIME_FUNCTION(Runtime_PerformSideEffectCheckForObject) {
829 HandleScope scope(isolate);
830 DCHECK_EQ(1, args.length());
831 CONVERT_ARG_HANDLE_CHECKED(JSReceiver,
object, 0);
833 DCHECK_EQ(isolate->debug_execution_mode(), DebugInfo::kSideEffects);
834 if (!isolate->debug()->PerformSideEffectCheckForObject(
object)) {
835 DCHECK(isolate->has_pending_exception());
836 return ReadOnlyRoots(isolate).exception();
838 return ReadOnlyRoots(isolate).undefined_value();