5 #include <unordered_map> 7 #include "src/assembler-inl.h" 8 #include "src/assert-scope.h" 9 #include "src/base/optional.h" 10 #include "src/compiler/wasm-compiler.h" 11 #include "src/debug/debug-scopes.h" 12 #include "src/debug/debug.h" 13 #include "src/frames-inl.h" 14 #include "src/heap/factory.h" 15 #include "src/identity-map.h" 16 #include "src/isolate.h" 17 #include "src/wasm/module-decoder.h" 18 #include "src/wasm/wasm-code-manager.h" 19 #include "src/wasm/wasm-interpreter.h" 20 #include "src/wasm/wasm-limits.h" 21 #include "src/wasm/wasm-module.h" 22 #include "src/wasm/wasm-objects-inl.h" 23 #include "src/zone/accounting-allocator.h" 31 template <
bool internal,
typename... Args>
32 Handle<String> PrintFToOneByteString(Isolate* isolate,
const char* format,
36 constexpr
int kMaxStrLen = 18;
37 EmbeddedVector<char, kMaxStrLen> value;
38 int len = SNPrintF(value, format, args...);
39 CHECK(len > 0 && len < value.length());
40 Vector<uint8_t> name = Vector<uint8_t>::cast(value.SubVector(0, len));
42 ? isolate->factory()->InternalizeOneByteString(name)
43 : isolate->factory()->NewStringFromOneByte(name).ToHandleChecked();
46 Handle<Object> WasmValueToValueObject(Isolate* isolate, WasmValue value) {
47 switch (value.type()) {
49 if (Smi::IsValid(value.to<int32_t>()))
50 return handle(Smi::FromInt(value.to<int32_t>()), isolate);
51 return PrintFToOneByteString<false>(isolate,
"%d", value.to<int32_t>());
53 if (Smi::IsValid(value.to<
int64_t>()))
54 return handle(Smi::FromIntptr(value.to<
int64_t>()), isolate);
55 return PrintFToOneByteString<false>(isolate,
"%" PRId64,
58 return isolate->factory()->NewNumber(value.to<
float>());
60 return isolate->factory()->NewNumber(value.to<
double>());
63 return isolate->factory()->undefined_value();
67 MaybeHandle<String> GetLocalName(Isolate* isolate,
68 Handle<WasmDebugInfo> debug_info,
69 int func_index,
int local_index) {
70 DCHECK_LE(0, func_index);
71 DCHECK_LE(0, local_index);
72 if (!debug_info->has_locals_names()) {
73 Handle<WasmModuleObject> module_object(
74 debug_info->wasm_instance()->module_object(), isolate);
75 Handle<FixedArray> locals_names = DecodeLocalNames(isolate, module_object);
76 debug_info->set_locals_names(*locals_names);
79 Handle<FixedArray> locals_names(debug_info->locals_names(), isolate);
80 if (func_index >= locals_names->length() ||
81 locals_names->get(func_index)->IsUndefined(isolate)) {
85 Handle<FixedArray> func_locals_names(
86 FixedArray::cast(locals_names->get(func_index)), isolate);
87 if (local_index >= func_locals_names->length() ||
88 func_locals_names->get(local_index)->IsUndefined(isolate)) {
91 return handle(String::cast(func_locals_names->get(local_index)), isolate);
94 class InterpreterHandle {
95 MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(InterpreterHandle);
97 const WasmModule* module_;
98 WasmInterpreter interpreter_;
99 StepAction next_step_action_ = StepNone;
100 int last_step_stack_depth_ = 0;
101 std::unordered_map<Address, uint32_t> activations_;
103 uint32_t StartActivation(Address frame_pointer) {
104 WasmInterpreter::Thread* thread = interpreter_.GetThread(0);
105 uint32_t activation_id = thread->StartActivation();
106 DCHECK_EQ(0, activations_.count(frame_pointer));
107 activations_.insert(std::make_pair(frame_pointer, activation_id));
108 return activation_id;
111 void FinishActivation(Address frame_pointer,
uint32_t activation_id) {
112 WasmInterpreter::Thread* thread = interpreter_.GetThread(0);
113 thread->FinishActivation(activation_id);
114 DCHECK_EQ(1, activations_.count(frame_pointer));
115 activations_.erase(frame_pointer);
118 std::pair<uint32_t, uint32_t> GetActivationFrameRange(
119 WasmInterpreter::Thread* thread, Address frame_pointer) {
120 DCHECK_EQ(1, activations_.count(frame_pointer));
121 uint32_t activation_id = activations_.find(frame_pointer)->second;
123 uint32_t frame_base = thread->ActivationFrameBase(activation_id);
124 uint32_t frame_limit = activation_id == num_activations
125 ? thread->GetFrameCount()
126 : thread->ActivationFrameBase(activation_id + 1);
127 DCHECK_LE(frame_base, frame_limit);
128 DCHECK_LE(frame_limit, thread->GetFrameCount());
129 return {frame_base, frame_limit};
132 static Vector<const byte> GetBytes(WasmDebugInfo* debug_info) {
135 NativeModule* native_module =
136 debug_info->wasm_instance()->module_object()->native_module();
137 return native_module->wire_bytes();
141 InterpreterHandle(Isolate* isolate, Handle<WasmDebugInfo> debug_info)
143 module_(debug_info->wasm_instance()->module_object()->module()),
144 interpreter_(isolate, module_, GetBytes(*debug_info),
145 handle(debug_info->wasm_instance(), isolate)) {}
147 ~InterpreterHandle() { DCHECK_EQ(0, activations_.size()); }
149 WasmInterpreter* interpreter() {
return &interpreter_; }
150 const WasmModule* module()
const {
return module_; }
152 void PrepareStep(StepAction step_action) {
153 next_step_action_ = step_action;
154 last_step_stack_depth_ = CurrentStackDepth();
157 void ClearStepping() { next_step_action_ = StepNone; }
159 int CurrentStackDepth() {
160 DCHECK_EQ(1, interpreter()->GetThreadCount());
161 return interpreter()->GetThread(0)->GetFrameCount();
167 bool Execute(Handle<WasmInstanceObject> instance_object,
168 Address frame_pointer,
uint32_t func_index, Address arg_buffer) {
169 DCHECK_GE(module()->functions.size(), func_index);
170 FunctionSig* sig = module()->functions[func_index].sig;
171 DCHECK_GE(kMaxInt, sig->parameter_count());
172 int num_params =
static_cast<int>(sig->parameter_count());
173 ScopedVector<WasmValue> wasm_args(num_params);
174 Address arg_buf_ptr = arg_buffer;
175 for (
int i = 0;
i < num_params; ++
i) {
177 ValueTypes::ElementSizeInBytes(sig->GetParam(
i)));
178 #define CASE_ARG_TYPE(type, ctype) \ 180 DCHECK_EQ(param_size, sizeof(ctype)); \ 181 wasm_args[i] = WasmValue(ReadUnalignedValue<ctype>(arg_buf_ptr)); \ 183 switch (sig->GetParam(
i)) {
185 CASE_ARG_TYPE(kWasmI64, uint64_t)
186 CASE_ARG_TYPE(kWasmF32,
float)
187 CASE_ARG_TYPE(kWasmF64,
double)
192 arg_buf_ptr += param_size;
195 uint32_t activation_id = StartActivation(frame_pointer);
197 WasmInterpreter::Thread* thread = interpreter_.GetThread(0);
198 thread->InitFrame(&module()->functions[func_index], wasm_args.start());
199 bool finished =
false;
202 WasmInterpreter::State state = ContinueExecution(thread);
204 case WasmInterpreter::State::PAUSED:
205 NotifyDebugEventListeners(thread);
207 case WasmInterpreter::State::FINISHED:
211 case WasmInterpreter::State::TRAPPED: {
212 MessageTemplate message_id =
213 WasmOpcodes::TrapReasonToMessageId(thread->GetTrapReason());
214 Handle<Object> exception =
215 isolate_->factory()->NewWasmRuntimeError(message_id);
216 isolate_->Throw(*exception);
219 auto result = thread->HandleException(isolate_);
220 return result == WasmInterpreter::Thread::HANDLED;
222 case WasmInterpreter::State::STOPPED:
224 DCHECK_EQ(thread->ActivationFrameBase(activation_id),
225 thread->GetFrameCount());
228 case WasmInterpreter::State::RUNNING:
235 DCHECK_GE(kV8MaxWasmFunctionReturns, sig->return_count());
237 DCHECK_EQ(1, kV8MaxWasmFunctionReturns);
238 if (sig->return_count()) {
239 WasmValue ret_val = thread->GetReturnValue(0);
240 #define CASE_RET_TYPE(type, ctype) \ 242 DCHECK_EQ(ValueTypes::ElementSizeInBytes(sig->GetReturn(0)), \ 244 WriteUnalignedValue<ctype>(arg_buffer, ret_val.to<ctype>()); \ 246 switch (sig->GetReturn(0)) {
248 CASE_RET_TYPE(kWasmI64, uint64_t)
249 CASE_RET_TYPE(kWasmF32,
float)
250 CASE_RET_TYPE(kWasmF64,
double)
257 FinishActivation(frame_pointer, activation_id);
262 WasmInterpreter::State ContinueExecution(WasmInterpreter::Thread* thread) {
263 switch (next_step_action_) {
265 return thread->Run();
267 return thread->Step();
269 thread->AddBreakFlags(WasmInterpreter::BreakFlag::AfterReturn);
270 return thread->Run();
272 int stack_depth = thread->GetFrameCount();
273 if (stack_depth == last_step_stack_depth_)
return thread->Step();
274 thread->AddBreakFlags(stack_depth > last_step_stack_depth_
275 ? WasmInterpreter::BreakFlag::AfterReturn
276 : WasmInterpreter::BreakFlag::AfterCall);
277 return thread->Run();
284 Handle<WasmInstanceObject> GetInstanceObject() {
285 StackTraceFrameIterator it(isolate_);
286 WasmInterpreterEntryFrame* frame =
287 WasmInterpreterEntryFrame::cast(it.frame());
288 Handle<WasmInstanceObject> instance_obj(frame->wasm_instance(), isolate_);
291 DCHECK_EQ(
this, Managed<InterpreterHandle>::cast(
292 instance_obj->debug_info()->interpreter_handle())
297 void NotifyDebugEventListeners(WasmInterpreter::Thread* thread) {
299 DebugScope debug_scope(isolate_->debug());
302 if (isolate_->debug()->break_points_active()) {
303 Handle<WasmModuleObject> module_object(
304 GetInstanceObject()->module_object(), isolate_);
305 int position = GetTopPosition(module_object);
306 Handle<FixedArray> breakpoints;
307 if (WasmModuleObject::CheckBreakPoints(isolate_, module_object, position)
308 .ToHandle(&breakpoints)) {
312 isolate_->debug()->OnDebugBreak(breakpoints);
318 bool hit_step =
false;
319 switch (next_step_action_) {
326 hit_step = thread->GetFrameCount() < last_step_stack_depth_;
329 hit_step = thread->GetFrameCount() == last_step_stack_depth_;
335 if (!hit_step)
return;
337 isolate_->debug()->OnDebugBreak(isolate_->factory()->empty_fixed_array());
340 int GetTopPosition(Handle<WasmModuleObject> module_object) {
341 DCHECK_EQ(1, interpreter()->GetThreadCount());
342 WasmInterpreter::Thread* thread = interpreter()->GetThread(0);
343 DCHECK_LT(0, thread->GetFrameCount());
345 auto frame = thread->GetFrame(thread->GetFrameCount() - 1);
346 return module_object->GetFunctionOffset(frame->function()->func_index) +
350 std::vector<std::pair<uint32_t, int>> GetInterpretedStack(
351 Address frame_pointer) {
352 DCHECK_EQ(1, interpreter()->GetThreadCount());
353 WasmInterpreter::Thread* thread = interpreter()->GetThread(0);
355 std::pair<uint32_t, uint32_t> frame_range =
356 GetActivationFrameRange(thread, frame_pointer);
358 std::vector<std::pair<uint32_t, int>> stack;
359 stack.reserve(frame_range.second - frame_range.first);
360 for (
uint32_t fp = frame_range.first; fp < frame_range.second; ++fp) {
361 auto frame = thread->GetFrame(fp);
362 stack.emplace_back(frame->function()->func_index, frame->pc());
367 WasmInterpreter::FramePtr GetInterpretedFrame(Address frame_pointer,
369 DCHECK_EQ(1, interpreter()->GetThreadCount());
370 WasmInterpreter::Thread* thread = interpreter()->GetThread(0);
372 std::pair<uint32_t, uint32_t> frame_range =
373 GetActivationFrameRange(thread, frame_pointer);
375 DCHECK_GT(frame_range.second - frame_range.first, idx);
377 return thread->GetFrame(frame_range.first + idx);
380 void Unwind(Address frame_pointer) {
382 DCHECK_EQ(1, activations_.count(frame_pointer));
384 DCHECK_EQ(activations_.size() - 1, activations_[frame_pointer]);
388 WasmInterpreter::Thread* thread = interpreter()->GetThread(0);
389 if (static_cast<uint32_t>(thread->GetFrameCount()) >
390 thread->ActivationFrameBase(activation_id)) {
391 using ExceptionResult = WasmInterpreter::Thread::ExceptionHandlingResult;
392 ExceptionResult result = thread->HandleException(isolate_);
394 CHECK_EQ(ExceptionResult::UNWOUND, result);
397 FinishActivation(frame_pointer, activation_id);
400 uint64_t NumInterpretedCalls() {
401 DCHECK_EQ(1, interpreter()->GetThreadCount());
402 return interpreter()->GetThread(0)->NumInterpretedCalls();
405 Handle<JSObject> GetGlobalScopeObject(InterpretedFrame* frame,
406 Handle<WasmDebugInfo> debug_info) {
407 Isolate* isolate = isolate_;
408 Handle<WasmInstanceObject> instance(debug_info->wasm_instance(), isolate);
411 Handle<JSObject> global_scope_object =
412 isolate_->factory()->NewJSObjectWithNullProto();
413 if (instance->has_memory_object()) {
414 Handle<String> name = isolate_->factory()->InternalizeOneByteString(
415 STATIC_CHAR_VECTOR(
"memory"));
416 Handle<JSArrayBuffer> memory_buffer(
417 instance->memory_object()->array_buffer(), isolate_);
418 Handle<JSTypedArray> uint8_array = isolate_->factory()->NewJSTypedArray(
419 kExternalUint8Array, memory_buffer, 0, memory_buffer->byte_length());
420 JSObject::SetOwnPropertyIgnoreAttributes(global_scope_object, name,
424 return global_scope_object;
427 Handle<JSObject> GetLocalScopeObject(InterpretedFrame* frame,
428 Handle<WasmDebugInfo> debug_info) {
429 Isolate* isolate = isolate_;
431 Handle<JSObject> local_scope_object =
432 isolate_->factory()->NewJSObjectWithNullProto();
434 int num_params = frame->GetParameterCount();
435 int num_locals = frame->GetLocalCount();
436 DCHECK_LE(num_params, num_locals);
437 if (num_locals > 0) {
438 Handle<JSObject> locals_obj =
439 isolate_->factory()->NewJSObjectWithNullProto();
440 Handle<String> locals_name =
441 isolate_->factory()->InternalizeOneByteString(
442 STATIC_CHAR_VECTOR(
"locals"));
443 JSObject::SetOwnPropertyIgnoreAttributes(local_scope_object, locals_name,
446 for (
int i = 0;
i < num_locals; ++
i) {
447 MaybeHandle<String> name =
448 GetLocalName(isolate, debug_info, frame->function()->func_index,
i);
449 if (name.is_null()) {
452 const char* label =
i < num_params ?
"arg#%d" :
"local#%d";
453 name = PrintFToOneByteString<true>(isolate_, label,
i);
455 WasmValue value = frame->GetLocalValue(
i);
456 Handle<Object> value_obj = WasmValueToValueObject(isolate_, value);
457 JSObject::SetOwnPropertyIgnoreAttributes(
458 locals_obj, name.ToHandleChecked(), value_obj, NONE)
464 int stack_count = frame->GetStackHeight();
468 Handle<JSObject> stack_obj =
469 isolate_->factory()->NewJSObjectWithNullProto();
470 Handle<String> stack_name = isolate_->factory()->InternalizeOneByteString(
471 STATIC_CHAR_VECTOR(
"stack"));
472 JSObject::SetOwnPropertyIgnoreAttributes(local_scope_object, stack_name,
475 for (
int i = 0;
i < stack_count; ++
i) {
476 WasmValue value = frame->GetStackValue(
i);
477 Handle<Object> value_obj = WasmValueToValueObject(isolate_, value);
478 JSObject::SetOwnElementIgnoreAttributes(
479 stack_obj, static_cast<uint32_t>(
i), value_obj, NONE)
482 return local_scope_object;
485 Handle<JSArray> GetScopeDetails(Address frame_pointer,
int frame_index,
486 Handle<WasmDebugInfo> debug_info) {
487 auto frame = GetInterpretedFrame(frame_pointer, frame_index);
489 Handle<FixedArray> global_scope =
490 isolate_->factory()->NewFixedArray(ScopeIterator::kScopeDetailsSize);
491 global_scope->set(ScopeIterator::kScopeDetailsTypeIndex,
492 Smi::FromInt(ScopeIterator::ScopeTypeGlobal));
493 Handle<JSObject> global_scope_object =
494 GetGlobalScopeObject(frame.get(), debug_info);
495 global_scope->set(ScopeIterator::kScopeDetailsObjectIndex,
496 *global_scope_object);
498 Handle<FixedArray> local_scope =
499 isolate_->factory()->NewFixedArray(ScopeIterator::kScopeDetailsSize);
500 local_scope->set(ScopeIterator::kScopeDetailsTypeIndex,
501 Smi::FromInt(ScopeIterator::ScopeTypeLocal));
502 Handle<JSObject> local_scope_object =
503 GetLocalScopeObject(frame.get(), debug_info);
504 local_scope->set(ScopeIterator::kScopeDetailsObjectIndex,
505 *local_scope_object);
507 Handle<JSArray> global_jsarr =
508 isolate_->factory()->NewJSArrayWithElements(global_scope);
509 Handle<JSArray> local_jsarr =
510 isolate_->factory()->NewJSArrayWithElements(local_scope);
511 Handle<FixedArray> all_scopes = isolate_->factory()->NewFixedArray(2);
512 all_scopes->set(0, *global_jsarr);
513 all_scopes->set(1, *local_jsarr);
514 return isolate_->factory()->NewJSArrayWithElements(all_scopes);
524 wasm::InterpreterHandle* GetOrCreateInterpreterHandle(
525 Isolate* isolate, Handle<WasmDebugInfo> debug_info) {
526 Handle<Object> handle(debug_info->interpreter_handle(), isolate);
527 if (handle->IsUndefined(isolate)) {
533 size_t interpreter_size = FLAG_stack_size * KB * 2;
534 handle = Managed<wasm::InterpreterHandle>::Allocate(
535 isolate, interpreter_size, isolate, debug_info);
536 debug_info->set_interpreter_handle(*handle);
539 return Handle<Managed<wasm::InterpreterHandle>>::cast(handle)->raw();
542 wasm::InterpreterHandle* GetInterpreterHandle(WasmDebugInfo* debug_info) {
543 Object* handle_obj = debug_info->interpreter_handle();
544 DCHECK(!handle_obj->IsUndefined());
545 return Managed<wasm::InterpreterHandle>::cast(handle_obj)->raw();
548 wasm::InterpreterHandle* GetInterpreterHandleOrNull(WasmDebugInfo* debug_info) {
549 Object* handle_obj = debug_info->interpreter_handle();
550 if (handle_obj->IsUndefined())
return nullptr;
551 return Managed<wasm::InterpreterHandle>::cast(handle_obj)->raw();
554 Handle<FixedArray> GetOrCreateInterpretedFunctions(
555 Isolate* isolate, Handle<WasmDebugInfo> debug_info) {
556 Handle<FixedArray> arr(debug_info->interpreted_functions(), isolate);
557 int num_functions = debug_info->wasm_instance()
561 if (arr->length() == 0 && num_functions > 0) {
562 arr = isolate->factory()->NewFixedArray(num_functions);
563 debug_info->set_interpreted_functions(*arr);
565 DCHECK_EQ(num_functions, arr->length());
571 Handle<WasmDebugInfo> WasmDebugInfo::New(Handle<WasmInstanceObject> instance) {
572 DCHECK(!instance->has_debug_info());
573 Factory* factory = instance->GetIsolate()->factory();
574 Handle<WasmDebugInfo> debug_info = Handle<WasmDebugInfo>::cast(
575 factory->NewStruct(WASM_DEBUG_INFO_TYPE, TENURED));
576 debug_info->set_wasm_instance(*instance);
577 debug_info->set_interpreted_functions(*factory->empty_fixed_array());
578 instance->set_debug_info(*debug_info);
582 wasm::WasmInterpreter* WasmDebugInfo::SetupForTesting(
583 Handle<WasmInstanceObject> instance_obj) {
584 Handle<WasmDebugInfo> debug_info = WasmDebugInfo::New(instance_obj);
585 Isolate* isolate = instance_obj->GetIsolate();
590 size_t interpreter_size = FLAG_stack_size * KB * 2;
591 auto interp_handle = Managed<wasm::InterpreterHandle>::Allocate(
592 isolate, interpreter_size, isolate, debug_info);
593 debug_info->set_interpreter_handle(*interp_handle);
594 auto ret = interp_handle->raw()->interpreter();
595 ret->SetCallIndirectTestMode();
599 void WasmDebugInfo::SetBreakpoint(Handle<WasmDebugInfo> debug_info,
600 int func_index,
int offset) {
601 Isolate* isolate = debug_info->GetIsolate();
602 auto* handle = GetOrCreateInterpreterHandle(isolate, debug_info);
603 RedirectToInterpreter(debug_info, Vector<int>(&func_index, 1));
604 const wasm::WasmFunction* func = &handle->module()->functions[func_index];
605 handle->interpreter()->SetBreakpoint(func, offset,
true);
608 void WasmDebugInfo::RedirectToInterpreter(Handle<WasmDebugInfo> debug_info,
609 Vector<int> func_indexes) {
610 Isolate* isolate = debug_info->GetIsolate();
612 GetOrCreateInterpreterHandle(isolate, debug_info);
613 Handle<FixedArray> interpreted_functions =
614 GetOrCreateInterpretedFunctions(isolate, debug_info);
615 Handle<WasmInstanceObject> instance(debug_info->wasm_instance(), isolate);
616 wasm::NativeModule* native_module =
617 instance->module_object()->native_module();
618 const wasm::WasmModule* module = instance->module();
621 wasm::NativeModuleModificationScope native_module_modification_scope(
624 for (
int func_index : func_indexes) {
625 DCHECK_LE(0, func_index);
626 DCHECK_GT(module->functions.size(), func_index);
627 if (!interpreted_functions->get(func_index)->IsUndefined(isolate))
continue;
629 wasm::WasmCode* wasm_new_code = compiler::CompileWasmInterpreterEntry(
630 isolate, native_module, func_index, module->functions[func_index].sig);
631 native_module->PublishInterpreterEntry(wasm_new_code, func_index);
632 Handle<Foreign> foreign_holder = isolate->factory()->NewForeign(
633 wasm_new_code->instruction_start(), TENURED);
634 interpreted_functions->set(func_index, *foreign_holder);
638 void WasmDebugInfo::PrepareStep(StepAction step_action) {
639 GetInterpreterHandle(
this)->PrepareStep(step_action);
643 bool WasmDebugInfo::RunInterpreter(Isolate* isolate,
644 Handle<WasmDebugInfo> debug_info,
645 Address frame_pointer,
int func_index,
646 Address arg_buffer) {
647 DCHECK_LE(0, func_index);
648 auto* handle = GetOrCreateInterpreterHandle(isolate, debug_info);
649 Handle<WasmInstanceObject> instance(debug_info->wasm_instance(), isolate);
650 return handle->Execute(instance, frame_pointer,
651 static_cast<uint32_t>(func_index), arg_buffer);
654 std::vector<std::pair<uint32_t, int>> WasmDebugInfo::GetInterpretedStack(
655 Address frame_pointer) {
656 return GetInterpreterHandle(
this)->GetInterpretedStack(frame_pointer);
659 wasm::WasmInterpreter::FramePtr WasmDebugInfo::GetInterpretedFrame(
660 Address frame_pointer,
int idx) {
661 return GetInterpreterHandle(
this)->GetInterpretedFrame(frame_pointer, idx);
664 void WasmDebugInfo::Unwind(Address frame_pointer) {
665 return GetInterpreterHandle(
this)->Unwind(frame_pointer);
668 uint64_t WasmDebugInfo::NumInterpretedCalls() {
669 auto* handle = GetInterpreterHandleOrNull(
this);
670 return handle ? handle->NumInterpretedCalls() : 0;
674 Handle<JSObject> WasmDebugInfo::GetScopeDetails(
675 Handle<WasmDebugInfo> debug_info, Address frame_pointer,
int frame_index) {
676 auto* interp_handle = GetInterpreterHandle(*debug_info);
677 return interp_handle->GetScopeDetails(frame_pointer, frame_index, debug_info);
681 Handle<JSObject> WasmDebugInfo::GetGlobalScopeObject(
682 Handle<WasmDebugInfo> debug_info, Address frame_pointer,
int frame_index) {
683 auto* interp_handle = GetInterpreterHandle(*debug_info);
684 auto frame = interp_handle->GetInterpretedFrame(frame_pointer, frame_index);
685 return interp_handle->GetGlobalScopeObject(frame.get(), debug_info);
689 Handle<JSObject> WasmDebugInfo::GetLocalScopeObject(
690 Handle<WasmDebugInfo> debug_info, Address frame_pointer,
int frame_index) {
691 auto* interp_handle = GetInterpreterHandle(*debug_info);
692 auto frame = interp_handle->GetInterpretedFrame(frame_pointer, frame_index);
693 return interp_handle->GetLocalScopeObject(frame.get(), debug_info);
697 Handle<JSFunction> WasmDebugInfo::GetCWasmEntry(
698 Handle<WasmDebugInfo> debug_info, wasm::FunctionSig* sig) {
699 Isolate* isolate = debug_info->GetIsolate();
700 DCHECK_EQ(debug_info->has_c_wasm_entries(),
701 debug_info->has_c_wasm_entry_map());
702 if (!debug_info->has_c_wasm_entries()) {
703 auto entries = isolate->factory()->NewFixedArray(4, TENURED);
704 debug_info->set_c_wasm_entries(*entries);
706 auto managed_map = Managed<wasm::SignatureMap>::Allocate(isolate, map_size);
707 debug_info->set_c_wasm_entry_map(*managed_map);
709 Handle<FixedArray> entries(debug_info->c_wasm_entries(), isolate);
710 wasm::SignatureMap* map = debug_info->c_wasm_entry_map()->raw();
711 int32_t index = map->Find(*sig);
713 index =
static_cast<int32_t
>(map->FindOrInsert(*sig));
714 if (index == entries->length()) {
715 entries = isolate->factory()->CopyFixedArrayAndGrow(
716 entries, entries->length(), TENURED);
717 debug_info->set_c_wasm_entries(*entries);
719 DCHECK(entries->get(index)->IsUndefined(isolate));
720 Handle<Code> new_entry_code =
721 compiler::CompileCWasmEntry(isolate, sig).ToHandleChecked();
722 Handle<WasmExportedFunctionData> function_data =
723 Handle<WasmExportedFunctionData>::cast(isolate->factory()->NewStruct(
724 WASM_EXPORTED_FUNCTION_DATA_TYPE, TENURED));
725 function_data->set_wrapper_code(*new_entry_code);
726 function_data->set_instance(debug_info->wasm_instance());
727 function_data->set_jump_table_offset(-1);
728 function_data->set_function_index(-1);
729 Handle<String> name = isolate->factory()->InternalizeOneByteString(
730 STATIC_CHAR_VECTOR(
"c-wasm-entry"));
731 NewFunctionArgs args = NewFunctionArgs::ForWasm(
732 name, function_data, isolate->sloppy_function_map());
733 Handle<JSFunction> new_entry = isolate->factory()->NewFunction(args);
734 new_entry->set_context(debug_info->wasm_instance()->native_context());
735 new_entry->shared()->set_internal_formal_parameter_count(
736 compiler::CWasmEntryParameters::kNumParameters);
737 entries->set(index, *new_entry);
739 return handle(JSFunction::cast(entries->get(index)), isolate);