46#if V8_ENABLE_DRUMBRAKE
54#define TRACE_IFT(...) \
56 if (false) PrintF(__VA_ARGS__); \
66static constexpr int kReservedSlotOffset = 1;
72 if (uses->length() == 0)
return 0;
78 uses->set(slot_index,
MakeWeak(user));
87 uses->get(slot_index).GetHeapObjectAssumeWeak());
91 return Cast<Smi>(uses->get(slot_index + 1)).value();
99 IsWasmTrustedInstanceData(src->get(src_index).GetHeapObjectAssumeWeak()));
101 dst->set(dst_index, src->get(src_index));
102 dst->set(dst_index + 1, src->get(src_index + 1));
113 Isolate* isolate, std::shared_ptr<wasm::NativeModule> native_module,
116 if (script->type() == Script::Type::kWasm) {
122 size_t memory_estimate =
129 isolate->factory()->NewJSObject(isolate->wasm_module_constructor()));
130 module_object->set_managed_native_module(*managed_native_module);
131 module_object->set_script(*script);
132 return module_object;
139 module_object->native_module()->wire_bytes();
151 auto* factory = isolate->factory();
153 ? factory->InternalizeUtf8String(
163 if (!
module->name.is_set())
return {};
170 uint32_t func_index) {
171 DCHECK_LT(func_index, module_object->module()->functions.size());
173 module_object->module()->lazily_generated_names.LookupFunctionName(
176 if (!name.is_set())
return {};
189 module()->lazily_generated_names.LookupFunctionName(wire_bytes,
198 uint32_t initial,
bool has_maximum, uint64_t maximum,
201 CHECK(type.is_object_reference());
205 for (
int i = 0; i < static_cast<int>(initial); ++
i) {
211 ? isolate->factory()->NewWasmDispatchTable(initial,
canonical_type)
215 isolate->factory()->undefined_value();
219 max = isolate->factory()->NewNumber(maximum);
226 isolate->native_context()->wasm_table_constructor(), isolate);
234 table_obj->clear_trusted_data();
236 table_obj->set_entries(*
entries);
237 table_obj->set_current_length(initial);
238 table_obj->set_maximum_length(*max);
239 table_obj->set_raw_type(
static_cast<int>(type.raw_bit_field()));
240 table_obj->set_address_type(address_type);
241 table_obj->set_padding_for_address_type_0(0);
242 table_obj->set_padding_for_address_type_1(0);
243#if TAGGED_SIZE_8_BYTES
244 table_obj->set_padding_for_address_type_2(0);
247 if (is_function_table) {
248 DCHECK_EQ(table_obj->current_length(), dispatch_table->length());
249 table_obj->set_trusted_dispatch_table(*dispatch_table);
250 if (out_dispatch_table) *out_dispatch_table = dispatch_table;
252 table_obj->clear_trusted_dispatch_table();
259 uint32_t old_size = table->current_length();
260 if (
count == 0)
return old_size;
265 uint32_t max_size =
static_cast<uint32_t
>(std::min(
266 static_max_size, table->maximum_length_u64().value_or(static_max_size)));
268 if (
count > max_size - old_size)
return -1;
270 uint32_t new_size = old_size +
count;
274 int old_capacity = table->entries()->length();
275 if (new_size >
static_cast<uint32_t
>(old_capacity)) {
276 int grow =
static_cast<int>(new_size) - old_capacity;
278 grow = std::max(grow, old_capacity);
280 grow = std::min(grow,
static_cast<int>(max_size - old_capacity));
281 auto new_store = isolate->factory()->CopyFixedArrayAndGrow(
286 if (table->has_trusted_dispatch_table()) {
288 table->trusted_dispatch_table(isolate), isolate);
289 DCHECK_EQ(old_size, dispatch_table->length());
293 table->set_trusted_dispatch_table(*new_dispatch_table);
295 DCHECK_EQ(new_size, table->trusted_dispatch_table(isolate)->length());
297#if V8_ENABLE_DRUMBRAKE
300 int used_length = GetUsedLength(uses);
301 for (
int i = kReservedSlotOffset;
i < used_length;
i += 2) {
302 if (uses->get(
i).IsCleared())
continue;
304 if (instance->has_interpreter_object()) {
305 int table_index = GetTableIndex(uses,
i);
307 isolate,
direct_handle(instance->instance_object(), isolate),
318 table->set_current_length(new_size);
320 for (uint32_t entry = old_size; entry < new_size; ++entry) {
329 const WasmModule* module = !table->has_trusted_data()
331 : table->trusted_data(isolate)->module();
340 if (IsWasmNull(*entry, isolate)) {
341 table->ClearDispatchTable(entry_index);
342 table->entries()->set(entry_index,
ReadOnlyRoots(isolate).wasm_null());
345 DCHECK(IsWasmFuncRef(*entry));
351 auto func_data = exported_function->shared()->wasm_exported_function_data();
353 func_data->instance_data(), isolate);
354 int func_index = func_data->function_index();
355 const WasmModule* module = target_instance_data->module();
357 auto* wasm_function =
module->functions.data() + func_index;
360#
if V8_ENABLE_DRUMBRAKE
373 table->entries()->set(entry_index, *entry);
380 DCHECK(table->is_in_bounds(index));
384 int entry_index =
static_cast<int>(
index);
388 DCHECK(table->has_trusted_data());
390 if (module->
has_signature(table->type(module).ref_index())) {
394 entries->set(entry_index, *entry);
398 case wasm::GenericKind::kExtern:
399 case wasm::GenericKind::kString:
400 case wasm::GenericKind::kStringViewWtf8:
401 case wasm::GenericKind::kStringViewWtf16:
402 case wasm::GenericKind::kStringViewIter:
403 case wasm::GenericKind::kEq:
404 case wasm::GenericKind::kStruct:
405 case wasm::GenericKind::kArray:
406 case wasm::GenericKind::kAny:
407 case wasm::GenericKind::kI31:
408 case wasm::GenericKind::kNone:
409 case wasm::GenericKind::kNoFunc:
410 case wasm::GenericKind::kNoExtern:
411 case wasm::GenericKind::kExn:
412 case wasm::GenericKind::kNoExn:
413 case wasm::GenericKind::kCont:
414 case wasm::GenericKind::kNoCont:
415 entries->set(entry_index, *entry);
417 case wasm::GenericKind::kFunc:
420 case wasm::GenericKind::kBottom:
421 case wasm::GenericKind::kTop:
422 case wasm::GenericKind::kVoid:
423 case wasm::GenericKind::kExternString:
434 DCHECK(table->is_in_bounds(index));
437 int entry_index =
static_cast<int>(
index);
441 if (IsWasmNull(*entry, isolate))
return entry;
442 if (IsWasmFuncRef(*entry))
return entry;
446 DCHECK(table->has_trusted_data());
447 const WasmModule* module = table->trusted_data(isolate)->module();
456 case wasm::GenericKind::kStringViewWtf8:
457 case wasm::GenericKind::kStringViewWtf16:
458 case wasm::GenericKind::kStringViewIter:
459 case wasm::GenericKind::kExtern:
460 case wasm::GenericKind::kString:
461 case wasm::GenericKind::kEq:
462 case wasm::GenericKind::kI31:
463 case wasm::GenericKind::kStruct:
464 case wasm::GenericKind::kArray:
465 case wasm::GenericKind::kAny:
466 case wasm::GenericKind::kNone:
467 case wasm::GenericKind::kNoFunc:
468 case wasm::GenericKind::kNoExtern:
469 case wasm::GenericKind::kExn:
470 case wasm::GenericKind::kNoExn:
471 case wasm::GenericKind::kCont:
472 case wasm::GenericKind::kNoCont:
474 case wasm::GenericKind::kFunc:
477 case wasm::GenericKind::kBottom:
478 case wasm::GenericKind::kTop:
479 case wasm::GenericKind::kVoid:
480 case wasm::GenericKind::kExternString:
491 int function_index =
Cast<Smi>(tuple->value2()).value();
497 isolate, trusted_instance_data, function_index);
498 entries->set(entry_index, *func_ref);
510 for (uint32_t
i = 0;
i <
count;
i++) {
515#if V8_ENABLE_SANDBOX || DEBUG
525 table_type.
generic_kind() == wasm::GenericKind::kFunc) {
530 wasm::CanonicalTypeIndex canonical_table_type = table_type.
ref_index();
531 if (
V8_LIKELY(sig_id == canonical_table_type))
return true;
534 sig_id, canonical_table_type);
543#
if V8_ENABLE_DRUMBRAKE
545 int target_func_index
553 target_instance_data->dispatch_table_for_imports()
557 : target_instance_data;
559 target_instance_data->GetCallTarget(func->
func_index);
561#if V8_ENABLE_DRUMBRAKE
562 if (target_func_index <
564 target_instance_data->module()->num_imported_functions)) {
565 target_func_index = target_instance_data->imported_function_indices()->get(
570 const WasmModule* target_module = target_instance_data->module();
574 table->trusted_dispatch_table(isolate), isolate);
575 SBXCHECK(FunctionSigMatchesTable(sig_id, dispatch_table->table_type()));
577 if (
v8_flags.wasm_generic_wrapper && IsWasmImportData(*implicit_arg)) {
580 isolate->factory()->NewWasmImportData(import_data);
581 new_import_data->set_call_origin(*dispatch_table);
582 new_import_data->set_table_slot(entry_index);
583 implicit_arg = new_import_data;
585 if (target_instance_data->dispatch_table_for_imports()->IsAWrapper(
591 dispatch_table->SetForWrapper(
592 entry_index, *implicit_arg,
594 call_target, signature_hash),
595 sig_id, signature_hash,
596#
if V8_ENABLE_DRUMBRAKE
602 dispatch_table->SetForNonWrapper(entry_index, *implicit_arg, call_target,
604#
if V8_ENABLE_DRUMBRAKE
610#if V8_ENABLE_DRUMBRAKE
613 int used_length = GetUsedLength(uses);
614 for (
int i = kReservedSlotOffset;
i < used_length;
i += 2) {
615 if (uses->get(
i).IsCleared())
continue;
617 if (instance->has_interpreter_object()) {
618 int table_index = GetTableIndex(uses,
i);
620 isolate,
direct_handle(instance->instance_object(), isolate),
633 function->shared()->wasm_js_function_data();
639 table->trusted_dispatch_table(isolate), isolate);
640 SBXCHECK(FunctionSigMatchesTable(sig_id, dispatch_table->table_type()));
644 WasmCodePointer code_pointer = function_data->internal()->call_target();
649 uint64_t signature_hash;
660 signature_hash =
sig->signature_hash();
666 int expected_arity =
static_cast<int>(
sig->parameter_count());
670 ->internal_formal_parameter_count_without_receiver();
673 wasm_code = cache->MaybeGet(
kind, sig_id, expected_arity, suspend);
683 Builtin::kWasmToJsWrapperInvalidSig, isolate));
684 import_data = isolate->factory()->NewWasmImportData(
686 import_data->SetIndexInTableAsCallOrigin(*dispatch_table, entry_index);
695 dispatch_table->SetForWrapper(entry_index, *import_data, call_target, sig_id,
697#
if V8_ENABLE_DRUMBRAKE
698 WasmDispatchTable::kInvalidFunctionIndex,
708 capi_function->shared()->wasm_capi_function_data(), isolate);
716 int param_count =
static_cast<int>(
sig->parameter_count());
719 if (wasm_code ==
nullptr) {
728 sig->signature_hash());
733 isolate->counters()->wasm_generated_code_size()->Increment(
735 isolate->counters()->wasm_reloc_size()->Increment(
741 table->trusted_dispatch_table(isolate);
742 SBXCHECK(FunctionSigMatchesTable(sig_index, dispatch_table->table_type()));
743 dispatch_table->SetForWrapper(entry_index, implicit_arg, call_target,
745#
if V8_ENABLE_DRUMBRAKE
746 WasmDispatchTable::kInvalidFunctionIndex,
756#if V8_ENABLE_DRUMBRAKE
759 int used_length = GetUsedLength(uses);
760 for (
int i = kReservedSlotOffset;
i < used_length;
i += 2) {
761 if (uses->get(
i).IsCleared())
continue;
763 GetInstance(uses,
i);
764 if (non_shared_instance_data->has_interpreter_object()) {
765 int table_index = GetTableIndex(uses,
i);
767 non_shared_instance_data->instance_object(), isolate);
769 isolate, instance_handle, table_index, index);
787 CHECK(trusted_instance_data->has_instance_object());
789 direct_handle(trusted_instance_data->instance_object(), isolate),
791 table->entries()->set(entry_index, *tuple);
797 bool* is_valid,
bool* is_null,
801 if (table->has_trusted_data()) {
809 DCHECK_LT(entry_index, table->current_length());
815 *is_null = IsWasmNull(*element, isolate);
816 if (*is_null)
return;
818 if (IsWasmFuncRef(*element)) {
826 target_func->shared()->wasm_exported_function_data());
828 *function_index = func_data->function_index();
837 if (IsTuple2(*element)) {
842 *function_index =
Cast<Smi>(tuple->value2()).value();
852 isolate->native_context()->wasm_suspending_constructor(), isolate);
854 isolate->factory()->NewJSObject(suspending_ctor));
855 suspending_obj->set_callable(*callable);
856 return suspending_obj;
864 const WasmModule* module = trusted_instance_data->module();
867 bool is_wasm_module =
module->origin == wasm::kWasmOrigin;
872 std::shared_ptr<BackingStore> backing_store = buffer->GetBackingStore();
874 CHECK_IMPLIES(is_wasm_module, backing_store->is_wasm_memory());
881 CHECK_IMPLIES(use_trap_handler, backing_store->has_guard_regions());
884 size_t byte_length = buffer->GetByteLength();
887 trusted_instance_data->SetRawMemory(
888 memory_index,
reinterpret_cast<uint8_t*
>(buffer->backing_store()),
891#if V8_ENABLE_DRUMBRAKE
893 trusted_instance_data->has_interpreter_object()) {
898 direct_handle(trusted_instance_data->instance_object(), isolate));
909 isolate->native_context()->wasm_memory_constructor(), isolate);
913 memory_object->set_array_buffer(*buffer);
914 memory_object->set_maximum_pages(maximum);
915 memory_object->set_address_type(address_type);
916 memory_object->set_padding_for_address_type_0(0);
917 memory_object->set_padding_for_address_type_1(0);
918#if TAGGED_SIZE_8_BYTES
919 memory_object->set_padding_for_address_type_2(0);
921 memory_object->set_instances(
ReadOnlyRoots{isolate}.empty_weak_array_list());
923 if (buffer->is_resizable_by_js()) {
924 memory_object->FixUpResizableArrayBuffer(*buffer);
927 std::shared_ptr<BackingStore> backing_store = buffer->GetBackingStore();
928 if (buffer->is_shared()) {
930 CHECK(backing_store && backing_store->is_wasm_memory());
931 backing_store->AttachSharedWasmMemoryObject(isolate, memory_object);
932 }
else if (backing_store) {
933 CHECK(!backing_store->is_shared());
939 isolate->factory()->array_buffer_wasm_memory_symbol();
942 return memory_object;
954 if (initial > engine_maximum)
return {};
956#ifdef V8_TARGET_ARCH_32_BIT
965 int allocation_maximum = std::min(kGBPages, engine_maximum);
966 int heuristic_maximum;
967 if (initial > kGBPages) {
969 heuristic_maximum = initial;
970 }
else if (has_maximum) {
973 heuristic_maximum = std::min(maximum, allocation_maximum);
977 heuristic_maximum = allocation_maximum;
981 heuristic_maximum = initial;
984 int heuristic_maximum =
985 has_maximum ? std::min(engine_maximum, maximum) : engine_maximum;
988 std::unique_ptr<BackingStore> backing_store =
989 BackingStore::AllocateWasmMemory(isolate, initial, heuristic_maximum,
995 if (!backing_store)
return {};
999 ? isolate->factory()->NewJSSharedArrayBuffer(std::move(backing_store))
1000 : isolate->factory()->NewJSArrayBuffer(std::move(backing_store));
1002 return New(isolate, buffer, maximum, address_type);
1009 int memory_index_in_instance) {
1010 SetInstanceMemory(*trusted_instance_data, memory->array_buffer(),
1011 memory_index_in_instance);
1012 if (!shared_trusted_instance_data.
is_null()) {
1013 SetInstanceMemory(*shared_trusted_instance_data, memory->array_buffer(),
1014 memory_index_in_instance);
1018 trusted_instance_data->instance_object(), isolate);
1020 memory->set_instances(*instances);
1026 const bool new_buffer_is_resizable_by_js = new_buffer->is_resizable_by_js();
1027 if (new_buffer_is_resizable_by_js) {
1031 set_array_buffer(new_buffer);
1046 DCHECK(!old_buffer->is_resizable_by_js() ||
1047 !new_buffer->is_resizable_by_js());
1048 if (!old_buffer->is_resizable_by_js() && !new_buffer_is_resizable_by_js) {
1056 for (
int i = 0, len = instances->length();
i < len; ++
i) {
1067 for (
int mem_idx = 0; mem_idx < num_memories; ++mem_idx) {
1069 SetInstanceMemory(
trusted_data, array_buffer(), mem_idx);
1078 DCHECK(new_buffer->is_resizable_by_js());
1080 if (new_buffer->is_shared()) new_buffer->set_byte_length(0);
1083 uintptr_t max_byte_length;
1092 uint64_t max_byte_length64 =
1094 if (max_byte_length64 > std::numeric_limits<uintptr_t>::max()) {
1097 CHECK(new_buffer->GetBackingStore()->max_byte_length() <=
1100 max_byte_length =
static_cast<uintptr_t
>(max_byte_length64);
1104 new_buffer->set_max_byte_length(max_byte_length);
1110 std::shared_ptr<BackingStore> new_backing_store) {
1115 void* old_data_pointer = old_buffer->backing_store();
1116 size_t old_byte_length = old_buffer->byte_length();
1120 isolate->factory()->NewJSArrayBuffer(std::move(new_backing_store));
1122 bool data_pointer_unchanged = new_buffer->backing_store() == old_data_pointer;
1123 bool byte_length_unchanged = new_buffer->byte_length() == old_byte_length;
1124 bool resizability_changed =
1125 old_buffer->is_resizable_by_js() != new_buffer->is_resizable_by_js();
1130 data_pointer_unchanged && byte_length_unchanged);
1132 memory_object->SetNewBuffer(isolate, *new_buffer);
1136 isolate->factory()->array_buffer_wasm_memory_symbol();
1147 std::shared_ptr<BackingStore> backing_store = old_buffer->GetBackingStore();
1150 CHECK(backing_store->is_wasm_memory());
1151 CHECK(backing_store->is_shared());
1155 void* expected_backing_store = backing_store.get();
1158 isolate->factory()->NewJSSharedArrayBuffer(std::move(backing_store));
1159 CHECK_EQ(expected_backing_store, new_buffer->GetBackingStore().get());
1161 new_buffer->set_is_resizable_by_js(
true);
1163 memory_object->SetNewBuffer(isolate, *new_buffer);
1167 isolate->factory()->array_buffer_wasm_memory_symbol();
1180 std::shared_ptr<BackingStore> backing_store = old_buffer->GetBackingStore();
1189 size_t old_size = old_buffer->GetByteLength();
1194 if (memory_object->has_maximum_pages()) {
1195 max_pages = std::min(max_pages,
1196 static_cast<size_t>(memory_object->maximum_pages()));
1199 if (pages > max_pages - old_pages)
return -1;
1201 const bool must_grow_in_place = old_buffer->is_shared() ||
1202 backing_store->has_guard_regions() ||
1203 backing_store->is_resizable_by_js();
1204 const bool try_grow_in_place =
1205 must_grow_in_place || !
v8_flags.stress_wasm_memory_moving;
1207 std::optional<size_t> result_inplace =
1209 ? backing_store->GrowWasmMemoryInPlace(isolate, pages, max_pages)
1211 if (must_grow_in_place && !result_inplace.has_value()) {
1214 if (
v8_flags.correctness_fuzzer_suppressions) {
1215 FATAL(
"could not grow wasm memory");
1221 if (old_buffer->is_shared()) {
1222 DCHECK(result_inplace.has_value());
1223 backing_store->BroadcastSharedWasmMemoryGrow(isolate);
1224 if (!old_buffer->is_resizable_by_js()) {
1226 CHECK_NE(*old_buffer, memory_object->array_buffer());
1228 size_t new_pages = result_inplace.value() +
pages;
1236 CHECK_LE(new_byte_length, memory_object->array_buffer()->GetByteLength());
1240 return static_cast<int32_t
>(result_inplace.value());
1243 size_t new_pages = old_pages +
pages;
1248 if (result_inplace.has_value()) {
1249 if (memory_object->array_buffer()->is_resizable_by_js()) {
1250 memory_object->array_buffer()->set_byte_length(new_pages *
1252 memory_object->UpdateInstances(isolate);
1254 RefreshBuffer(isolate, memory_object, std::move(backing_store));
1256 DCHECK_EQ(result_inplace.value(), old_pages);
1257 return static_cast<int32_t
>(result_inplace.value());
1259 DCHECK(!memory_object->array_buffer()->is_resizable_by_js());
1269 size_t min_growth = old_pages + 8 + (old_pages >> 3);
1273 size_t new_capacity = std::min(max_pages, std::max(new_pages, min_growth));
1275 std::unique_ptr<BackingStore> new_backing_store =
1276 backing_store->CopyWasmMemory(isolate, new_pages, new_capacity,
1277 memory_object->is_memory64()
1280 if (!new_backing_store) {
1282 if (
v8_flags.correctness_fuzzer_suppressions) {
1283 FATAL(
"could not grow wasm memory");
1290 RefreshBuffer(isolate, memory_object, std::move(new_backing_store));
1292 return static_cast<int32_t
>(old_pages);
1300 DCHECK(old_buffer->is_resizable_by_js());
1301 if (old_buffer->is_shared()) {
1305 std::shared_ptr<BackingStore> backing_store = old_buffer->GetBackingStore();
1307 backing_store->MakeWasmMemoryResizableByJS(
false);
1308 return RefreshBuffer(isolate, memory_object, std::move(backing_store));
1316 DCHECK(memory_object->has_maximum_pages());
1319 DCHECK(!old_buffer->is_resizable_by_js());
1320 if (old_buffer->is_shared()) {
1324 std::shared_ptr<BackingStore> backing_store = old_buffer->GetBackingStore();
1326 backing_store->MakeWasmMemoryResizableByJS(
true);
1327 return RefreshBuffer(isolate, memory_object, std::move(backing_store));
1332#if V8_TARGET_OS_LINUX
1335 isolate->native_context()->wasm_memory_map_descriptor_constructor(),
1338 int file_descriptor = memfd_create(
"wasm_memory_map_descriptor", MFD_CLOEXEC);
1339 if (file_descriptor == -1) {
1342 int ret_val = ftruncate(file_descriptor, length);
1343 if (ret_val == -1) {
1355 int file_descriptor) {
1358 isolate->native_context()->wasm_memory_map_descriptor_constructor(),
1364 descriptor_object->set_file_descriptor(file_descriptor);
1366 descriptor_object->set_offset(0);
1367 descriptor_object->set_size(0);
1369 return descriptor_object;
1374#if V8_TARGET_OS_LINUX
1376 if (memory->array_buffer()->is_shared()) {
1382 if (memory->is_memory64()) {
1390 reinterpret_cast<uint8_t*
>(memory->array_buffer()->backing_store()) +
1393 struct stat stat_for_size;
1394 if (fstat(this->file_descriptor(), &stat_for_size) == -1) {
1398 size_t size =
RoundUp(stat_for_size.st_size,
1401 if (size +
offset < size) {
1405 if (size +
offset > memory->array_buffer()->GetByteLength()) {
1409 void* ret_val = mmap(target, size, PROT_READ | PROT_WRITE,
1410 MAP_FIXED | MAP_SHARED, this->file_descriptor(), 0);
1420#if V8_TARGET_OS_LINUX
1426 if (memory.is_null()) {
1430 uint32_t size = this->
size();
1434 CHECK(!memory->is_memory64());
1435 CHECK(!memory->array_buffer()->is_shared());
1441 reinterpret_cast<uint8_t*
>(memory->array_buffer()->backing_store()) +
1444 void* ret_val = mmap(target, size, PROT_READ | PROT_WRITE,
1445 MAP_FIXED | MAP_SHARED | MAP_ANONYMOUS, -1, 0);
1460 int32_t
offset,
bool is_mutable) {
1462 isolate->native_context()->wasm_global_constructor(), isolate);
1471 global_obj->clear_trusted_data();
1473 global_obj->set_type(type);
1474 global_obj->set_offset(
offset);
1475 global_obj->set_is_mutable(is_mutable);
1478 if (type.is_reference()) {
1490 uint32_t
type_size = type.value_kind_size();
1493 if (!maybe_untagged_buffer.
ToHandle(&untagged_buffer)) {
1495 isolate->factory()->NewJSArrayBufferAndBackingStore(
1498 if (!
result.ToHandle(&untagged_buffer)) {
1499 isolate->Throw(*isolate->factory()->NewRangeError(
1500 MessageTemplate::kOutOfMemory,
1501 isolate->factory()->NewStringFromAsciiChecked(
1502 "WebAssembly.Global")));
1510 global_obj->set_untagged_buffer(*untagged_buffer);
1519 int target_func_index) {
1521 if (target_func_index <
1523 target_instance_data->module()->num_imported_functions)) {
1528 target_instance_data->dispatch_table_for_imports()->implicit_arg(
1529 target_func_index)),
1531#if V8_ENABLE_DRUMBRAKE
1532 target_func_index_ = target_instance_data->imported_function_indices()->get(
1537#if V8_ENABLE_DRUMBRAKE
1538 target_func_index_ = target_func_index;
1541 call_target_ = target_instance_data->GetCallTarget(target_func_index);
1556 TRACE_IFT(
"Import callable 0x%" PRIxPTR
"[%d] = {callable=0x%" PRIxPTR
1557 ", target=0x%" PRIxPTR
"}\n",
1562 import_data->SetIndexInTableAsCallOrigin(
1567 index_, *import_data, wrapper_entry, sig_id,
sig->signature_hash(),
1568#
if V8_ENABLE_DRUMBRAKE
1569 WasmDispatchTable::kInvalidFunctionIndex,
1572#if V8_ENABLE_DRUMBRAKE
1581 TRACE_IFT(
"Import callable 0x%" PRIxPTR
"[%d] = {callable=0x%" PRIxPTR
1584 wasm_to_js_wrapper ?
nullptr
1599 dispatch_table->SetForWrapper(
1603 sig_id,
sig->signature_hash(),
1604#
if V8_ENABLE_DRUMBRAKE
1605 WasmDispatchTable::kInvalidFunctionIndex,
1609#if V8_ENABLE_DRUMBRAKE
1617#
if V8_ENABLE_DRUMBRAKE
1619 int exported_function_index
1622 TRACE_IFT(
"Import Wasm 0x%" PRIxPTR
"[%d] = {instance_data=0x%" PRIxPTR
1623 ", target=0x%" PRIxPTR
"}\n",
1630 dispatch_table->SetForNonWrapper(
index_, target_instance_data, call_target,
1632#
if V8_ENABLE_DRUMBRAKE
1633 WasmDispatchTable::kInvalidFunctionIndex,
1637#if V8_ENABLE_DRUMBRAKE
1639 exported_function_index);
1663#if V8_ENABLE_DRUMBRAKE
1664int ImportedFunctionEntry::function_index_in_called_module() {
1670constexpr std::array<uint16_t, WasmTrustedInstanceData::kTaggedFieldsCount>
1673constexpr std::array<const char*, WasmTrustedInstanceData::kTaggedFieldsCount>
1676constexpr std::array<uint16_t, 6>
1679constexpr std::array<const char*, 6>
1686 CHECK_LE(mem_size,
module()->memories[memory_index].is_memory64()
1691 bases_and_sizes->set(memory_index * 2,
reinterpret_cast<Address>(mem_start));
1692 bases_and_sizes->set(memory_index * 2 + 1, mem_size);
1694 if (memory_index == 0) {
1695 set_memory0_start(mem_start);
1696 set_memory0_size(mem_size);
1700#if V8_ENABLE_DRUMBRAKE
1706 instance->trusted_data(isolate), isolate);
1712 return new_interpreter;
1715DirectHandle<Tuple2> WasmTrustedInstanceData::GetInterpreterObject(
1716 DirectHandle<WasmInstanceObject> instance) {
1720 instance->trusted_data(isolate), isolate);
1741 int num_imported_functions =
module->num_imported_functions;
1743 isolate->factory()->NewWasmDispatchTable(num_imported_functions,
1746 isolate->factory()->NewFixedArray(num_imported_functions);
1749 isolate->factory()->NewFixedArrayWithZeroes(
1750 static_cast<int>(
module->functions.size()));
1752 int num_imported_mutable_globals =
module->num_imported_mutable_globals;
1760 int num_data_segments =
module->num_declared_data_segments;
1766#if V8_ENABLE_DRUMBRAKE
1772 int num_memories =
static_cast<int>(
module->memories.size());
1774 isolate->factory()->NewFixedArray(num_memories);
1783 isolate->factory()->empty_protected_fixed_array();
1788 size_t estimated_size =
1798 isolate->factory()->NewWasmTrustedInstanceData();
1803 uint8_t* empty_backing_store_buffer =
1809 trusted_data->set_imported_mutable_globals(*imported_mutable_globals);
1810 trusted_data->set_dispatch_table0(*empty_dispatch_table);
1811 trusted_data->set_dispatch_tables(*empty_protected_fixed_array);
1814 trusted_data->set_data_segment_sizes(*data_segment_sizes);
1816 trusted_data->set_managed_native_module(*trusted_managed_native_module);
1818 isolate->heap()->NewSpaceAllocationLimitAddress());
1820 isolate->heap()->NewSpaceAllocationTopAddress());
1822 isolate->heap()->OldSpaceAllocationLimitAddress());
1824 isolate->heap()->OldSpaceAllocationTopAddress());
1825 trusted_data->set_globals_start(empty_backing_store_buffer);
1826#if V8_ENABLE_DRUMBRAKE
1827 trusted_data->set_imported_function_indices(*imported_function_indices);
1829 trusted_data->set_native_context(*isolate->native_context());
1832 isolate->debug()->hook_on_function_call_address());
1834 *isolate->factory()->empty_fixed_array());
1835 trusted_data->set_well_known_imports(*well_known_imports);
1838 *isolate->factory()->empty_fixed_array());
1843 trusted_data->set_memory0_start(empty_backing_store_buffer);
1846 trusted_data->set_memory_bases_and_sizes(*memory_bases_and_sizes);
1848 ExternalReference::stress_deopt_count(isolate).
address());
1850 for (
int i = 0;
i < num_memories; ++
i) {
1851 memory_bases_and_sizes->set(
1852 2 *
i,
reinterpret_cast<Address>(empty_backing_store_buffer));
1853 memory_bases_and_sizes->set(2 *
i + 1, 0);
1859 isolate->factory()->NewJSObjectWithNullProto();
1866 isolate->native_context()->wasm_instance_constructor(), isolate);
1877 if (
module_object->script()->type() == Script::Type::kWasm &&
1880 module_object->script()->wasm_weak_instance_list(), isolate);
1881 weak_instance_list =
1884 module_object->script()->set_wasm_weak_instance_list(*weak_instance_list);
1894 uint32_t num_data_segments =
module->num_declared_data_segments;
1900 DCHECK(num_data_segments == 0 ||
1901 num_data_segments ==
module->data_segments.size());
1902 for (uint32_t
i = 0;
i < num_data_segments; ++
i) {
1908 reinterpret_cast<Address>(source_bytes.begin()));
1912 data_segment_sizes()->set(
static_cast<int>(
i),
1913 segment.
active ? 0 : source_bytes.length());
1920 if (func_index < native_module->num_imported_functions()) {
1935 uint32_t table_dst_index, uint32_t table_src_index, uint32_t dst,
1936 uint32_t src, uint32_t
count) {
1937 CHECK_LT(table_dst_index, trusted_instance_data->tables()->length());
1938 CHECK_LT(table_src_index, trusted_instance_data->tables()->length());
1941 trusted_instance_data->tables()->get(table_dst_index)),
1945 trusted_instance_data->tables()->get(table_src_index)),
1947 uint32_t max_dst = table_dst->current_length();
1948 uint32_t max_src = table_src->current_length();
1949 bool copy_backward = src < dst;
1956 if ((dst == src && table_dst_index == table_src_index) ||
count == 0) {
1960 for (uint32_t
i = 0;
i <
count; ++
i) {
1961 uint32_t src_index = copy_backward ? (src +
count -
i - 1) : src +
i;
1962 uint32_t dst_index = copy_backward ? (dst +
count -
i - 1) : dst +
i;
1974 uint32_t table_index, uint32_t segment_index, uint32_t dst, uint32_t src,
1980 Zone zone(&allocator,
"LoadElemSegment");
1984 bool table_is_shared =
module->tables[table_index].shared;
1985 bool segment_is_shared =
module->elem_segments[segment_index].shared;
1989 : trusted_instance_data)
1991 ->get(table_index)),
1996 &zone, isolate, trusted_instance_data, shared_trusted_instance_data,
1998 if (opt_error.has_value())
return opt_error;
2002 : trusted_instance_data)
2004 ->get(segment_index)),
2007 return {MessageTemplate::kWasmTrapTableOutOfBounds};
2010 return {MessageTemplate::kWasmTrapElementSegmentOutOfBounds};
2013 for (
size_t i = 0;
i <
count;
i++) {
2015 isolate, table_object,
static_cast<int>(dst +
i),
2016 direct_handle(elem_segment->get(
static_cast<int>(src +
i)), isolate));
2025 if (
IsSmi(val))
return false;
2033 int function_index) {
2035 if (trusted_instance_data->try_get_func_ref(function_index,
2036 &existing_func_ref)) {
2042 function_index < static_cast<int>(
module->num_imported_functions);
2047 trusted_instance_data->dispatch_table_for_imports()
2048 ->implicit_arg(function_index)),
2050 : trusted_instance_data;
2055 trusted_instance_data->managed_object_maps()->get(sig_index.
index)),
2059 isolate->factory()->NewWasmInternalFunction(implicit_arg, function_index);
2061 isolate->factory()->NewWasmFuncRef(internal_function, rtt);
2062 trusted_instance_data->func_refs()->set(function_index, *func_ref);
2067 internal_function->set_call_target(
2068 trusted_instance_data->GetCallTarget(function_index));
2074 if (IsUndefined(external()))
return false;
2085 if (
internal->try_get_external(&existing_external)) {
2097 IsWasmTrustedInstanceData(*implicit_arg)
2102 const WasmFunction& function =
module->functions[internal->function_index()];
2104 module->canonical_sig_id(function.sig_index);
2108 int wrapper_index = sig_id.
index;
2111 isolate->heap()->js_to_wasm_wrappers()->get(wrapper_index);
2119#if V8_ENABLE_DRUMBRAKE
2120 }
else if (
v8_flags.wasm_jitless) {
2121 wrapper_code = isolate->builtins()->code_handle(
2122 Builtin::kGenericJSToWasmInterpreterWrapper);
2124 }
else if (CanUseGenericJsToWasmWrapper(module,
sig)) {
2125 if (
v8_flags.stress_wasm_stack_switching) {
2127 isolate->builtins()->code_handle(Builtin::kWasmStressSwitch);
2130 isolate->builtins()->code_handle(Builtin::kJSToWasmWrapper);
2135 isolate,
sig, sig_id);
2138 isolate->heap()->js_to_wasm_wrappers()->get(wrapper_index));
2147 static_cast<int>(
sig->parameter_count()), wrapper_code);
2155 set_call_origin(table);
2156 set_table_slot(entry_index);
2160 set_call_origin(func);
2167 return reinterpret_cast<uint8_t*
>(
2168 imported_mutable_globals()->get_sandboxed_pointer(global.
index));
2173std::pair<Tagged<FixedArray>, uint32_t>
2181 Address idx = imported_mutable_globals()->get(global.
index);
2182 DCHECK_LE(idx, std::numeric_limits<uint32_t>::max());
2183 return {buffer,
static_cast<uint32_t
>(idx)};
2193 uint32_t global_index = 0;
2201#define CASE_TYPE(valuetype, ctype) \
2202 case wasm::valuetype: \
2203 return wasm::WasmValue(base::ReadUnalignedValue<ctype>(ptr));
2212 DCHECK_EQ(WASM_STRUCT_TYPE, map->instance_type());
2257 DCHECK(type.is_descriptor());
2261 module->canonical_type_id(type.describes);
2270 isolate->factory()->NewWasmStructUninitialized(type.struct_type, map,
2275 descriptor->set_described_rtt(*rtt);
2276 rtt->set_custom_descriptor(*descriptor);
2283 map()->wasm_type_info()->type_index());
2285 int field_offset = WasmStruct::kHeaderSize + type->field_offset(index);
2286 Address field_address = GetFieldAddress(field_offset);
2287 switch (field_type.
kind()) {
2288#define CASE_TYPE(valuetype, ctype) \
2289 case wasm::valuetype: \
2290 return wasm::WasmValue(base::ReadUnalignedValue<ctype>(field_address));
2299 case wasm::kRefNull: {
2313 map()->wasm_type_info()->element_type();
2317 switch (element_type.
kind()) {
2318#define CASE_TYPE(value_type, ctype) \
2319 case wasm::value_type: \
2320 return wasm::WasmValue(base::ReadUnalignedValue<ctype>(element_address));
2329 case wasm::kRefNull: {
2343 DCHECK(
map()->wasm_type_info()->element_type().is_reference());
2354 isolate->native_context()->wasm_tag_constructor(), isolate);
2358 DCHECK_LE(
sig->parameter_count(), std::numeric_limits<int>::max());
2359 int sig_size =
static_cast<int>(
sig->parameter_count());
2364 serialized_sig->set(index++, param);
2370 tag_wrapper->set_serialized_signature(*serialized_sig);
2371 tag_wrapper->set_canonical_type_index(type_index.
index);
2372 tag_wrapper->set_tag(*tag);
2376 tag_wrapper->clear_trusted_data();
2384 this->canonical_type_index())} == expected_index;
2388 return shared()->wasm_capi_function_data()->sig();
2396 return it->second.call_target;
2406 std::vector<wasm::WasmCode*> codes;
2409 if (entry.code) codes.push_back(entry.code);
2416 uint64_t signature_hash) {
2422 call_target, signature_hash);
2423 auto [wrapper_cache, was_inserted] =
2428 auto& [existing_code_pointer, wrapper_code] = it->second;
2429 code_pointer = existing_code_pointer;
2431 code_pointer, call_target, signature_hash);
2434 wrapper_code = compiled_wrapper;
2436 if (compiled_wrapper) {
2437 compiled_wrapper->
IncRef();
2442 return code_pointer;
2454 auto& [code_pointer, wrapper_code] = entry->second;
2468#
if V8_ENABLE_DRUMBRAKE
2469 uint32_t function_index,
2474 Clear(index, new_or_existing);
2490 offheap_data()->Remove(index, old_target);
2494#if V8_ENABLE_DRUMBRAKE
2509 uint64_t signature_hash,
2510#
if V8_ENABLE_DRUMBRAKE
2511 uint32_t function_index,
2516 SBXCHECK(!compiled_wrapper || !compiled_wrapper->is_dying());
2533 offheap_data()->Remove(index, old_target);
2536 index, call_target, compiled_wrapper, signature_hash);
2539#if V8_ENABLE_DRUMBRAKE
2557 offheap_data()->Remove(index, old_target);
2580 return offheap_data()->IsAWrapper(index);
2590 int cursor = GetUsedLength(uses);
2592 SetEntry(uses, cursor, *instance, table_index);
2593 SetUsedLength(uses, cursor + 2);
2600 int capacity = uses->length();
2601 if (capacity == 0) {
2602 constexpr int kInitialLength = 3;
2604 isolate->factory()->NewProtectedWeakFixedArray(kInitialLength);
2605 SetUsedLength(*new_uses, kReservedSlotOffset);
2606 dispatch_table->set_protected_uses(*new_uses);
2610 int used_length = GetUsedLength(uses);
2611 if (used_length < capacity)
return uses;
2613 int cleared_entries = 0;
2614 int write_cursor = kReservedSlotOffset;
2615 for (
int i = kReservedSlotOffset;
i <
capacity;
i += 2) {
2616 DCHECK(uses->get(
i).IsWeakOrCleared());
2617 if (uses->get(
i).IsCleared()) {
2621 if (write_cursor !=
i) {
2622 CopyEntry(uses, write_cursor, uses,
i);
2628 int min_free_entries = 1 + (capacity >> 2);
2629 if (cleared_entries >= min_free_entries) {
2630 SetUsedLength(uses, write_cursor);
2636 int old_entries = capacity >> 1;
2637 int new_entries = std::max(old_entries + 1, old_entries + (old_entries >> 1));
2638 int new_capacity = new_entries * 2 + kReservedSlotOffset;
2640 isolate->factory()->NewProtectedWeakFixedArray(new_capacity);
2644 used_length = write_cursor;
2646 uses = *uses_handle;
2647 write_cursor = kReservedSlotOffset;
2648 for (
int i = kReservedSlotOffset;
i < used_length;
i += 2) {
2649 if (uses->get(
i).IsCleared())
continue;
2650 CopyEntry(*new_uses, write_cursor, uses,
i);
2653 SetUsedLength(*new_uses, write_cursor);
2654 dispatch_table->set_protected_uses(*new_uses);
2661 return isolate->factory()->NewWasmDispatchTable(length, table_type);
2668 uint32_t old_length = old_table->length();
2674 uint32_t old_capacity = old_table->capacity();
2692 uint32_t max_grow = limit - old_capacity;
2693 uint32_t min_grow =
new_length - old_capacity;
2696 uint32_t exponential_grow = std::max(old_capacity, 8u);
2697 uint32_t grow = std::clamp(exponential_grow, min_grow, max_grow);
2698 uint32_t new_capacity = old_capacity + grow;
2707 for (uint32_t
i = 0;
i < old_length; ++
i) {
2716 if (import_data->has_call_origin()) {
2717 if (import_data->call_origin() == *old_table) {
2718 import_data->set_call_origin(*new_table);
2737 call_target.
value());
2739#if V8_ENABLE_DRUMBRAKE
2741 new_table->WriteField<
int>(
offset + kFunctionIndexBias,
2742 old_table->function_index(
i));
2749 new_table->WriteField<uint32_t>(
offset +
kSigBias, old_table->sig(
i).index);
2752 new_table->offheap_data()->wrappers_ =
2753 std::move(old_table->offheap_data()->wrappers_);
2757 new_table->set_protected_uses(uses);
2758 int used_length = GetUsedLength(uses);
2759 for (
int i = kReservedSlotOffset;
i < used_length;
i += 2) {
2760 if (uses->get(
i).IsCleared())
continue;
2762 int table_index = GetTableIndex(uses,
i);
2763 DCHECK_EQ(instance->dispatch_tables()->get(table_index), *old_table);
2764 instance->dispatch_tables()->set(table_index, *new_table);
2765 if (table_index == 0) {
2766 DCHECK_EQ(instance->dispatch_table0(), *old_table);
2767 instance->set_dispatch_table0(*new_table);
2778 CHECK(!type.has_index());
2783 return shared()->wasm_capi_function_data()->sig_index() ==
2784 other_canonical_sig_index;
2791 return New(isolate, exception_tag, values);
2798 isolate->native_context()->wasm_exception_constructor(), isolate);
2800 isolate->factory()->NewJSObject(exception_cons);
2801 exception->InObjectPropertyAtPut(
kTagIndex, *exception_tag);
2802 exception->InObjectPropertyAtPut(
kValuesIndex, *values);
2811 isolate->factory()->wasm_exception_tag_symbol())
2815 return isolate->factory()->undefined_value();
2823 isolate, exception_package,
2824 isolate->factory()->wasm_exception_values_symbol())
2825 .ToHandle(&values)) {
2829 return isolate->factory()->undefined_value();
2833 uint32_t* encoded_index, uint32_t value) {
2834 encoded_values->set((*encoded_index)++,
Smi::FromInt(value >> 16));
2835 encoded_values->set((*encoded_index)++,
Smi::FromInt(value & 0xffff));
2839 uint32_t* encoded_index, uint64_t value) {
2841 static_cast<uint32_t
>(value >> 32));
2843 static_cast<uint32_t
>(value));
2847 uint32_t* encoded_index, uint32_t* value) {
2848 uint32_t msb =
Cast<Smi>(encoded_values->get((*encoded_index)++)).value();
2849 uint32_t lsb =
Cast<Smi>(encoded_values->get((*encoded_index)++)).value();
2850 *value = (msb << 16) | (lsb & 0xffff);
2854 uint32_t* encoded_index, uint64_t* value) {
2855 uint32_t lsb = 0, msb = 0;
2858 *value = (
static_cast<uint64_t
>(msb) << 32) |
static_cast<uint64_t
>(lsb);
2869#if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_ARM && \
2870 !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_RISCV64 && \
2871 !V8_TARGET_ARCH_RISCV32 && !V8_TARGET_ARCH_PPC64 && \
2872 !V8_TARGET_ARCH_S390X && !V8_TARGET_ARCH_LOONG64 && !V8_TARGET_ARCH_MIPS64
2877 return v8_flags.wasm_generic_wrapper;
2885constexpr uint32_t kBytesPerExceptionValuesArrayElement = 2;
2887size_t ComputeEncodedElementSize(wasm::ValueType type) {
2888 size_t byte_size = type.value_kind_size();
2889 DCHECK_EQ(byte_size % kBytesPerExceptionValuesArrayElement, 0);
2890 DCHECK_LE(1, byte_size / kBytesPerExceptionValuesArrayElement);
2891 return byte_size / kBytesPerExceptionValuesArrayElement;
2905 uint32_t encoded_size = 0;
2906 for (
size_t i = 0;
i <
sig->parameter_count(); ++
i) {
2907 switch (
sig->GetParam(
i).kind()) {
2923 case wasm::kRefNull:
2935 return encoded_size;
2939 if (!IsJSFunction(
object))
return false;
2942 if (CodeKind::JS_TO_WASM_FUNCTION != code->kind() &&
2943#
if V8_ENABLE_DRUMBRAKE
2944 code->builtin_id() != Builtin::kGenericJSToWasmInterpreterWrapper &&
2946 code->builtin_id() != Builtin::kJSToWasmWrapper &&
2947 code->builtin_id() != Builtin::kWasmPromising &&
2948 code->builtin_id() != Builtin::kWasmStressSwitch) {
2951 DCHECK(js_function->shared()->HasWasmExportedFunctionData());
2956 if (!IsJSFunction(
object))
return false;
2965 return js_function->shared()->HasWasmCapiFunctionData();
2981 isolate->factory()->NewWasmCapiFunctionData(
2982 call_target, embedder_data,
BUILTIN_CODE(isolate, Illegal), rtt,
2985 isolate->factory()->NewSharedFunctionInfoForWasmCapiFunction(fun_data);
2989 fun_data->internal()->set_external(*
result);
2998 DCHECK(CodeKind::JS_TO_WASM_FUNCTION == export_wrapper->kind() ||
2999 (export_wrapper->is_builtin() &&
3000 (export_wrapper->builtin_id() == Builtin::kJSToWasmWrapper ||
3001#
if V8_ENABLE_DRUMBRAKE
3002 export_wrapper->builtin_id() ==
3003 Builtin::kGenericJSToWasmInterpreterWrapper ||
3005 export_wrapper->builtin_id() == Builtin::kWasmPromising ||
3006 export_wrapper->builtin_id() == Builtin::kWasmStressSwitch)));
3007 int func_index = internal_function->function_index();
3008 Factory* factory = isolate->factory();
3011 export_wrapper->builtin_id() == Builtin::kWasmPromising
3016 module->canonical_sig_id(module->functions[func_index].sig_index);
3020 factory->NewWasmExportedFunctionData(
3022 sig_id,
v8_flags.wasm_wrapper_tiering_budget, promise);
3024#if V8_ENABLE_DRUMBRAKE
3028 uint32_t aligned_size =
3032 function_data->set_packed_args_size(
3041 bool is_asm_js_module = is_asmjs_module(module);
3042 if (is_asm_js_module) {
3052 int length = SNPrintF(buffer,
"%d", func_index);
3059 switch (module->
origin) {
3061 function_map = isolate->wasm_exported_function_map();
3064 function_map = isolate->sloppy_function_map();
3067 function_map = isolate->strict_function_map();
3073 factory->NewSharedFunctionInfoForWasmExportedFunction(name, function_data,
3083 DCHECK_EQ(is_asm_js_module, IsConstructor(*js_function));
3087 shared->set_script(*isolate->factory()->undefined_value(),
kReleaseStore);
3089 function_data->internal()->set_external(*js_function);
3096 sig_index(), other_canonical_type_index);
3102 constexpr const char kPrefix[] =
"js-to-wasm:";
3104 size_t len = strlen(kPrefix) +
sig->all().size() + 2;
3106 memcpy(buffer.begin(), kPrefix, strlen(kPrefix));
3107 PrintSignature(buffer.as_vector() + strlen(kPrefix),
sig);
3108 return buffer.ReleaseData();
3113 if (!IsJSFunction(
object))
return false;
3115 return js_function->shared()->HasWasmJSFunctionData();
3124 const int inobject_properties = 0;
3132 constexpr bool shared =
false;
3137 heaptype, no_array_element, opt_rtt_parent);
3139 if (opt_native_context.
is_null()) {
3140 map = isolate->factory()->NewContextlessMap(
3141 instance_type, map_instance_size, elements_kind, inobject_properties);
3143 map = isolate->factory()->NewContextfulMap(
3144 opt_native_context, instance_type, map_instance_size, elements_kind,
3145 inobject_properties);
3147 map->set_wasm_type_info(*type_info);
3148 map->set_is_extensible(
false);
3160 const int inobject_properties = 0;
3164 constexpr bool shared =
false;
3168 heaptype, element_type, opt_rtt_parent);
3170 instance_type, instance_size, elements_kind, inobject_properties);
3171 map->set_wasm_type_info(*type_info);
3172 map->SetInstanceDescriptors(isolate,
3173 *isolate->factory()->empty_descriptor_array(), 0,
3175 map->set_is_extensible(
false);
3183 const int inobject_properties = 0;
3187 constexpr bool shared =
false;
3191 heaptype, no_array_element, opt_rtt_parent);
3192 constexpr int kInstanceSize = WasmFuncRef::kSize;
3195 Cast<Map>(isolate->root(RootIndex::kWasmFuncRefMap))->instance_size());
3197 instance_type, kInstanceSize, elements_kind, inobject_properties);
3198 map->set_wasm_type_info(*type_info);
3207 Factory* factory = isolate->factory();
3222 isolate->heap()->wasm_canonical_rtts(), isolate);
3236 ? isolate->builtins()->code_handle(Builtin::kJSToJSWrapper)
3237 : isolate->builtins()->code_handle(Builtin::kJSToJSWrapperInvalidSig);
3240 factory->NewWasmJSFunctionData(sig_id, callable, js_to_js_wrapper_code,
3243 function_data->internal(), isolate};
3249 function_data->offheap_data()->set_generic_wrapper(builtin_entry);
3250 internal_function->set_call_target(wrapper_code_pointer);
3251#if V8_ENABLE_DRUMBRAKE
3252 }
else if (
v8_flags.wasm_jitless) {
3256 function_data->offheap_data()->set_generic_wrapper(builtin_entry);
3257 internal_function->set_call_target(wrapper_code_pointer);
3262 if (IsJSFunction(*callable)) {
3265 shared->internal_formal_parameter_count_without_receiver();
3277 cache->MaybeGet(
kind, sig_id, expected_arity, suspend);
3281 function_data->offheap_data()->set_compiled_wrapper(wrapper);
3285 ->clear_call_origin();
3290 function_data->offheap_data()->set_generic_wrapper(code_entry);
3293 cache->LazyInitialize(isolate);
3294 constexpr bool kNoSourcePositions =
false;
3295 wrapper = cache->CompileWasmImportCallWrapper(
3296 isolate,
kind, canonical_sig, sig_id, kNoSourcePositions,
3297 expected_arity, suspend);
3299 function_data->offheap_data()->set_compiled_wrapper(wrapper);
3303 ->clear_call_origin();
3305 internal_function->set_call_target(code_pointer);
3309 if (IsJSFunction(*callable)) {
3314 factory->NewSharedFunctionInfoForWasmJSFunction(name, function_data);
3315 shared->set_internal_formal_parameter_count(
3319 .
set_map(isolate->wasm_exported_function_map())
3321 internal_function->set_external(*js_function);
3346 wrapper_code_pointer_ =
3348 code_entry, signature_hash_);
3349 return wrapper_code_pointer_;
3358 wrapper_code_pointer_);
3385 return sig_index() == other_canonical_sig_index;
3398 result->set_index(index);
3403 Isolate* isolate, std::shared_ptr<wasm::NativeModule> native_module,
3405 const WasmModule* module = native_module->module();
3406 size_t memory_estimate =
3411 std::move(native_module));
3414 result->set_managed_native_module(*managed_native_module);
3415 result->set_uses_bitset(*uses_bitset);
3420constexpr int32_t kInt31MaxValue = 0x3fffffff;
3421constexpr int32_t kInt31MinValue = -kInt31MaxValue - 1;
3428 if (double_value >= kInt31MinValue && double_value <= kInt31MaxValue &&
3438DirectHandle<Object> CanonicalizeSmi(DirectHandle<Object> smi,
3442 int32_t value =
Cast<Smi>(*smi).value();
3447 return isolate->factory()->NewHeapNumber(value);
3456 const char** error_message) {
3460 case HeapType::kStringViewWtf8:
3461 *error_message =
"stringview_wtf8 has no JS representation";
3463 case HeapType::kStringViewWtf16:
3464 *error_message =
"stringview_wtf16 has no JS representation";
3466 case HeapType::kStringViewIter:
3467 *error_message =
"stringview_iter has no JS representation";
3469 case HeapType::kExn:
3470 *error_message =
"invalid type (ref null exn)";
3472 case HeapType::kNoExn:
3473 *error_message =
"invalid type (ref null noexn)";
3475 case HeapType::kNoCont:
3476 *error_message =
"invalid type (ref null nocont)";
3478 case HeapType::kCont:
3479 *error_message =
"invalid type (ref null cont)";
3482 return expected.
use_wasm_null() ? isolate->factory()->wasm_null()
3488 case HeapType::kFunc: {
3489 if (!(WasmExternalFunction::IsWasmExternalFunction(*value) ||
3490 WasmCapiFunction::IsWasmCapiFunction(*value))) {
3492 "function-typed object must be null (if nullable) or a Wasm "
3497 Cast<JSFunction>(*value)->shared()->wasm_function_data()->func_ref(),
3500 case HeapType::kExtern: {
3502 *error_message =
"null is not allowed for (ref extern)";
3505 case HeapType::kAny: {
3506 if (
IsSmi(*value))
return CanonicalizeSmi(value, isolate);
3507 if (IsHeapNumber(*value)) {
3508 return CanonicalizeHeapNumber(value, isolate);
3511 *error_message =
"null is not allowed for (ref any)";
3514 case HeapType::kExn:
3515 *error_message =
"invalid type (ref exn)";
3517 case HeapType::kCont:
3518 *error_message =
"invalid type (ref cont)";
3520 case HeapType::kStruct: {
3521 if (IsWasmStruct(*value)) {
3525 "structref object must be null (if nullable) or a wasm struct";
3528 case HeapType::kArray: {
3529 if (IsWasmArray(*value)) {
3533 "arrayref object must be null (if nullable) or a wasm array";
3536 case HeapType::kEq: {
3537 if (
IsSmi(*value)) {
3539 if (
IsSmi(*truncated))
return truncated;
3540 }
else if (IsHeapNumber(*value)) {
3542 if (
IsSmi(*truncated))
return truncated;
3543 }
else if (IsWasmStruct(*value) || IsWasmArray(*value)) {
3547 "eqref object must be null (if nullable), or a wasm "
3548 "struct/array, or a Number that fits in i31ref range";
3551 case HeapType::kI31: {
3552 if (
IsSmi(*value)) {
3554 if (
IsSmi(*truncated))
return truncated;
3555 }
else if (IsHeapNumber(*value)) {
3557 if (
IsSmi(*truncated))
return truncated;
3560 "i31ref object must be null (if nullable) or a Number that fits "
3564 case HeapType::kString:
3565 if (IsString(*value))
return value;
3566 *error_message =
"wrong type (expected a string)";
3568 case HeapType::kStringViewWtf8:
3569 *error_message =
"stringview_wtf8 has no JS representation";
3571 case HeapType::kStringViewWtf16:
3572 *error_message =
"stringview_wtf16 has no JS representation";
3574 case HeapType::kStringViewIter:
3575 *error_message =
"stringview_iter has no JS representation";
3577 case HeapType::kNoFunc:
3578 case HeapType::kNoExtern:
3579 case HeapType::kNoExn:
3580 case HeapType::kNoCont:
3581 case HeapType::kNone: {
3582 *error_message =
"only null allowed for null types";
3590 if (WasmExportedFunction::IsWasmExportedFunction(*value)) {
3592 Cast<WasmExportedFunction>(*value);
3594 function->shared()->wasm_exported_function_data()->sig_index();
3595 if (!type_canonicalizer->IsCanonicalSubtype(real_type_index,
3598 "assigned exported function has to be a subtype of the "
3602 return direct_handle(Cast<WasmExternalFunction>(*value)->func_ref(),
3604 }
else if (WasmJSFunction::IsWasmJSFunction(*value)) {
3605 if (!Cast<WasmJSFunction>(*value)
3607 ->wasm_js_function_data()
3608 ->MatchesSignature(canonical_index)) {
3610 "assigned WebAssembly.Function has to be a subtype of the "
3614 return direct_handle(Cast<WasmExternalFunction>(*value)->func_ref(),
3616 }
else if (WasmCapiFunction::IsWasmCapiFunction(*value)) {
3617 if (!Cast<WasmCapiFunction>(*value)->MatchesSignature(
3620 "assigned C API function has to be a subtype of the expected "
3624 return direct_handle(Cast<WasmExternalFunction>(*value)->func_ref(),
3626 }
else if (IsWasmStruct(*value) || IsWasmArray(*value)) {
3630 if (!type_canonicalizer->IsCanonicalSubtype(actual_type,
3632 *error_message =
"object is not a subtype of expected type";
3637 *error_message =
"JS object does not match expected wasm type";
3649 const char** error_message) {
3652 canonical =
module->canonical_type(expected);
3661 if (IsWasmNull(*value)) {
3662 return isolate->factory()->null_value();
3663 }
else if (IsWasmFuncRef(*value)) {
#define BUILTIN_CODE(isolate, name)
#define SBXCHECK_LE(lhs, rhs)
#define SBXCHECK_LT(lhs, rhs)
#define SBXCHECK_BOUNDS(index, limit)
#define SBXCHECK_GE(lhs, rhs)
#define SBXCHECK(condition)
static bool ValidateEncoding(const uint8_t *str, size_t length)
static constexpr U encode(T value)
static OwnedVector< T > New(size_t size)
Vector< T > SubVector(size_t from, size_t to) const
constexpr T * begin() const
static Vector< T > cast(Vector< S > input)
static Handle< AsmWasmData > New(Isolate *isolate, std::shared_ptr< wasm::NativeModule > native_module, DirectHandle< HeapNumber > uses_bitset)
static V8_EXPORT_PRIVATE Handle< BigInt > FromUint64(Isolate *isolate, uint64_t n)
static Address EntryOf(Builtin builtin, Isolate *isolate)
V8_INLINE bool is_null() const
V8_INLINE bool is_identical_to(Handle< S > other) const
V8_EXPORT_PRIVATE Address address() const
static ExternalReference Create(const SCTableReference &table_ref)
MaybeHandle< String > NewStringFromOneByte(base::Vector< const uint8_t > string, AllocationType allocation=AllocationType::kYoung)
JSFunctionBuilder & set_map(DirectHandle< Map > v)
V8_WARN_UNUSED_RESULT Handle< JSFunction > Build()
static DirectHandle< FixedAddressArrayBase > New(Isolate *isolate, int length, MoreArgs &&... more_args)
static Handle< FixedIntegerArrayBase< T, Base > > New(Isolate *isolate, int length, MoreArgs &&... more_args)
FunctionTargetAndImplicitArg(Isolate *isolate, DirectHandle< WasmTrustedInstanceData > target_instance_data, int target_func_index)
DirectHandle< TrustedObject > implicit_arg_
WasmCodePointer call_target_
T ReadField(size_t offset) const
void WriteField(size_t offset, T value) const
Tagged< JSReceiver > callable()
Tagged< Object > implicit_arg()
Tagged< Object > maybe_callable()
V8_EXPORT_PRIVATE void SetCompiledWasmToJs(Isolate *, DirectHandle< JSReceiver > callable, wasm::WasmCode *wasm_to_js_wrapper, wasm::Suspend suspend, const wasm::CanonicalSig *sig, wasm::CanonicalTypeIndex sig_id)
void SetGenericWasmToJs(Isolate *, DirectHandle< JSReceiver > callable, wasm::Suspend suspend, const wasm::CanonicalSig *sig, wasm::CanonicalTypeIndex sig_id)
DirectHandle< WasmTrustedInstanceData > const instance_data_
void SetWasmToWasm(Tagged< WasmTrustedInstanceData > target_instance_object, WasmCodePointer call_target, wasm::CanonicalTypeIndex sig_id)
static V8_INLINE Isolate * Current()
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT Maybe< bool > Detach(DirectHandle< JSArrayBuffer > buffer, bool force_for_wasm_memory=false, DirectHandle< Object > key={})
Tagged< Context > context()
static DirectHandle< String > GetDebugName(DirectHandle< JSFunction > function)
static V8_WARN_UNUSED_RESULT MaybeHandle< Object > GetProperty(Isolate *isolate, DirectHandle< JSReceiver > receiver, const char *key)
static DirectHandle< Managed< CppType > > From(Isolate *isolate, size_t estimated_size, std::shared_ptr< CppType > shared_ptr, AllocationType allocation_type=AllocationType::kYoung)
V8_WARN_UNUSED_RESULT V8_INLINE bool ToHandle(DirectHandle< S > *out) const
V8_INLINE bool is_null() const
static MaybeObjectDirectHandle Weak(Tagged< Object > object, Isolate *isolate)
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT Maybe< bool > SetProperty(LookupIterator *it, DirectHandle< Object > value, StoreOrigin store_origin, Maybe< ShouldThrow > should_throw=Nothing< ShouldThrow >())
static Handle< PodArray< T > > New(Isolate *isolate, int length, AllocationType allocation=AllocationType::kYoung)
static constexpr Tagged< Smi > FromInt(int value)
static constexpr Tagged< Smi > zero()
static V8_INLINE HandleType< String > Flatten(Isolate *isolate, HandleType< T > string, AllocationType allocation=AllocationType::kYoung)
static void store(Tagged< HeapObject > host, PtrType value)
V8_INLINE constexpr StorageType ptr() const
constexpr bool IsCleared() const
constexpr bool IsSmi() const
Tagged< HeapObject > GetHeapObjectAssumeWeak() const
static DirectHandle< TrustedManaged< CppType > > From(Isolate *isolate, size_t estimated_size, std::shared_ptr< CppType > shared_ptr)
void ClearProtectedPointerField(int offset)
void WriteProtectedPointerField(int offset, Tagged< TrustedObject > value)
V8_EXPORT_PRIVATE wasm::WasmValue GetElement(uint32_t index)
uint32_t element_offset(uint32_t index)
void SetTaggedElement(uint32_t index, DirectHandle< Object > value, WriteBarrierMode mode=UPDATE_WRITE_BARRIER)
static void EncodeElementSizeInMap(int element_size, Tagged< Map > map)
const wasm::CanonicalSig * sig() const
static DirectHandle< WasmCapiFunction > New(Isolate *isolate, Address call_target, DirectHandle< Foreign > embedder_data, wasm::CanonicalTypeIndex sig_index, const wasm::CanonicalSig *sig)
static bool IsWasmCapiFunction(Tagged< Object > object)
bool MatchesSignature(wasm::CanonicalTypeIndex other_canonical_sig_index) const
std::unordered_map< int, WrapperEntry > wrappers_
void Remove(int index, WasmCodePointer call_target)
V8_EXPORT_PRIVATE bool IsAWrapper(int index) const
WasmCodePointer Add(int index, Address call_target, wasm::WasmCode *compiled_wrapper, uint64_t signature_hash)
void Clear(int index, NewOrExistingEntry new_or_existing)
static constexpr int kMaxLength
static V8_WARN_UNUSED_RESULT DirectHandle< WasmDispatchTable > Grow(Isolate *, DirectHandle< WasmDispatchTable >, uint32_t new_length)
bool V8_EXPORT_PRIVATE IsAWrapper(int index) const
static constexpr size_t kTargetBias
void V8_EXPORT_PRIVATE SetForNonWrapper(int index, Tagged< Object > implicit_arg, WasmCodePointer call_target, wasm::CanonicalTypeIndex sig_id, NewOrExistingEntry new_or_existing)
static constexpr size_t kSigBias
static void V8_EXPORT_PRIVATE AddUse(Isolate *isolate, DirectHandle< WasmDispatchTable > dispatch_table, DirectHandle< WasmTrustedInstanceData > instance, int table_index)
static V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT DirectHandle< WasmDispatchTable > New(Isolate *isolate, int length, wasm::CanonicalValueType table_type)
static constexpr size_t kImplicitArgBias
static constexpr size_t kLengthOffset
void V8_EXPORT_PRIVATE SetForWrapper(int index, Tagged< Object > implicit_arg, Address call_target, wasm::CanonicalTypeIndex sig_id, uint64_t signature_hash, wasm::WasmCode *compiled_wrapper, NewOrExistingEntry new_or_existing)
Tagged< Object > implicit_arg(int index) const
static Tagged< ProtectedWeakFixedArray > MaybeGrowUsesList(Isolate *isolate, DirectHandle< WasmDispatchTable > dispatch_table)
void InstallCompiledWrapper(int index, wasm::WasmCode *wrapper)
static constexpr int OffsetOf(int index)
static DirectHandle< WasmExceptionPackage > New(Isolate *isolate, DirectHandle< WasmExceptionTag > exception_tag, int encoded_size)
static DirectHandle< Object > GetExceptionValues(Isolate *isolate, DirectHandle< WasmExceptionPackage > exception_package)
static uint32_t GetEncodedSize(const wasm::WasmTagSig *tag)
static DirectHandle< Object > GetExceptionTag(Isolate *isolate, DirectHandle< WasmExceptionPackage > exception_package)
static V8_EXPORT_PRIVATE DirectHandle< WasmExceptionTag > New(Isolate *isolate, int index)
wasm::CanonicalTypeIndex sig_index() const
bool MatchesSignature(wasm::CanonicalTypeIndex other_canonical_sig_index)
static std::unique_ptr< char[]> GetDebugName(const wasm::CanonicalSig *sig)
static V8_EXPORT_PRIVATE bool IsWasmExportedFunction(Tagged< Object > object)
static V8_EXPORT_PRIVATE DirectHandle< WasmExportedFunction > New(Isolate *isolate, DirectHandle< WasmTrustedInstanceData > instance_data, DirectHandle< WasmFuncRef > func_ref, DirectHandle< WasmInternalFunction > internal_function, int arity, DirectHandle< Code > export_wrapper)
static bool IsWasmExternalFunction(Tagged< Object > object)
static V8_EXPORT_PRIVATE MaybeDirectHandle< WasmGlobalObject > New(Isolate *isolate, DirectHandle< WasmTrustedInstanceData > instance_object, MaybeDirectHandle< JSArrayBuffer > maybe_untagged_buffer, MaybeDirectHandle< FixedArray > maybe_tagged_buffer, wasm::ValueType type, int32_t offset, bool is_mutable)
void SetFuncRefAsCallOrigin(Tagged< WasmInternalFunction > func)
void SetIndexInTableAsCallOrigin(Tagged< WasmDispatchTable > table, int entry_index)
static V8_EXPORT_PRIVATE DirectHandle< JSFunction > GetOrCreateExternal(DirectHandle< WasmInternalFunction > internal)
bool try_get_external(Tagged< JSFunction > *result)
static DirectHandle< Tuple2 > New(DirectHandle< WasmInstanceObject >)
const uint64_t signature_hash_
WasmCodePointer set_compiled_wrapper(wasm::WasmCode *wrapper)
wasm::WasmCode * wrapper_
WasmCodePointer set_generic_wrapper(Address call_target)
WasmCodePointer wrapper_code_pointer_
bool MatchesSignature(wasm::CanonicalTypeIndex other_canonical_sig_index) const
const wasm::CanonicalSig * GetSignature() const
wasm::Suspend GetSuspend() const
wasm::CanonicalTypeIndex sig_index() const
Tagged< JSReceiver > GetCallable() const
static DirectHandle< WasmJSFunction > New(Isolate *isolate, const wasm::FunctionSig *sig, DirectHandle< JSReceiver > callable, wasm::Suspend suspend)
static bool IsWasmJSFunction(Tagged< Object > object)
V8_EXPORT_PRIVATE size_t MapDescriptor(DirectHandle< WasmMemoryObject > memory, size_t offset)
V8_EXPORT_PRIVATE bool UnmapDescriptor()
static V8_EXPORT_PRIVATE MaybeDirectHandle< WasmMemoryMapDescriptor > NewFromAnonymous(Isolate *isolate, size_t length)
static V8_EXPORT_PRIVATE DirectHandle< WasmMemoryMapDescriptor > NewFromFileDescriptor(Isolate *isolate, v8::WasmMemoryMapDescriptor::WasmFileDescriptor file_descriptor)
static DirectHandle< JSArrayBuffer > RefreshSharedBuffer(Isolate *isolate, DirectHandle< WasmMemoryObject > memory, ResizableFlag resizable_by_js)
static DirectHandle< JSArrayBuffer > ToFixedLengthBuffer(Isolate *isolate, DirectHandle< WasmMemoryObject > memory)
static DirectHandle< JSArrayBuffer > ToResizableBuffer(Isolate *isolate, DirectHandle< WasmMemoryObject > memory)
static DirectHandle< JSArrayBuffer > RefreshBuffer(Isolate *isolate, DirectHandle< WasmMemoryObject > memory, std::shared_ptr< BackingStore > new_backing_store)
static constexpr int kNoMaximum
static V8_EXPORT_PRIVATE void UseInInstance(Isolate *isolate, DirectHandle< WasmMemoryObject > memory, DirectHandle< WasmTrustedInstanceData > trusted_instance_data, DirectHandle< WasmTrustedInstanceData > shared_trusted_instance_data, int memory_index_in_instance)
void SetNewBuffer(Isolate *isolate, Tagged< JSArrayBuffer > new_buffer)
static V8_EXPORT_PRIVATE int32_t Grow(Isolate *, DirectHandle< WasmMemoryObject >, uint32_t pages)
static V8_EXPORT_PRIVATE DirectHandle< WasmMemoryObject > New(Isolate *isolate, DirectHandle< JSArrayBuffer > buffer, int maximum, wasm::AddressType address_type)
void UpdateInstances(Isolate *isolate)
void FixUpResizableArrayBuffer(Tagged< JSArrayBuffer > new_buffer)
const wasm::WasmModule * module() const
static V8_EXPORT_PRIVATE DirectHandle< WasmModuleObject > New(Isolate *isolate, std::shared_ptr< wasm::NativeModule > native_module, DirectHandle< Script > script)
static MaybeDirectHandle< String > GetFunctionNameOrNull(Isolate *, DirectHandle< WasmModuleObject >, uint32_t func_index)
static MaybeDirectHandle< String > GetModuleNameOrNull(Isolate *, DirectHandle< WasmModuleObject >)
wasm::NativeModule * native_module() const
base::Vector< const uint8_t > GetRawFunctionName(int func_index)
static DirectHandle< String > ExtractUtf8StringFromModuleBytes(Isolate *, DirectHandle< WasmModuleObject >, wasm::WireBytesRef, InternalizeString)
static int Size(const wasm::StructType *type)
static const wasm::CanonicalStructType * GcSafeType(Tagged< Map > map)
static void EncodeInstanceSizeInMap(int instance_size, Tagged< Map > map)
V8_EXPORT_PRIVATE wasm::WasmValue GetFieldValue(uint32_t field_index)
static DirectHandle< WasmStruct > AllocateDescriptorUninitialized(Isolate *isolate, DirectHandle< WasmTrustedInstanceData > trusted_data, wasm::ModuleTypeIndex index, DirectHandle< Map > map)
static V8_EXPORT_PRIVATE DirectHandle< WasmSuspendingObject > New(Isolate *isolate, DirectHandle< JSReceiver > callable)
void ClearDispatchTable(int index)
static void GetFunctionTableEntry(Isolate *isolate, DirectHandle< WasmTableObject > table, int entry_index, bool *is_valid, bool *is_null, MaybeDirectHandle< WasmTrustedInstanceData > *instance_data, int *function_index, MaybeDirectHandle< WasmJSFunction > *maybe_js_function)
static void UpdateDispatchTable(Isolate *isolate, DirectHandle< WasmTableObject > table, int entry_index, const wasm::WasmFunction *func, DirectHandle< WasmTrustedInstanceData > target_instance)
static V8_EXPORT_PRIVATE DirectHandle< WasmTableObject > New(Isolate *isolate, DirectHandle< WasmTrustedInstanceData > trusted_data, wasm::ValueType type, wasm::CanonicalValueType canonical_type, uint32_t initial, bool has_maximum, uint64_t maximum, DirectHandle< Object > initial_value, wasm::AddressType address_type, DirectHandle< WasmDispatchTable > *out_dispatch_table=nullptr)
static void SetFunctionTableEntry(Isolate *isolate, DirectHandle< WasmTableObject > table, int entry_index, DirectHandle< Object > entry)
wasm::CanonicalValueType canonical_type(const wasm::WasmModule *module)
static V8_EXPORT_PRIVATE DirectHandle< Object > Get(Isolate *isolate, DirectHandle< WasmTableObject > table, uint32_t index)
wasm::ValueType unsafe_type()
static MaybeDirectHandle< Object > JSToWasmElement(Isolate *isolate, DirectHandle< WasmTableObject > table, DirectHandle< Object > entry, const char **error_message)
static V8_EXPORT_PRIVATE void Fill(Isolate *isolate, DirectHandle< WasmTableObject > table, uint32_t start, DirectHandle< Object > entry, uint32_t count)
static V8_EXPORT_PRIVATE void Set(Isolate *isolate, DirectHandle< WasmTableObject > table, uint32_t index, DirectHandle< Object > entry)
static V8_EXPORT_PRIVATE int Grow(Isolate *isolate, DirectHandle< WasmTableObject > table, uint32_t count, DirectHandle< Object > init_value)
static V8_EXPORT_PRIVATE void SetFunctionTablePlaceholder(Isolate *isolate, DirectHandle< WasmTableObject > table, int entry_index, DirectHandle< WasmTrustedInstanceData > trusted_instance_data, int func_index)
bool MatchesSignature(wasm::CanonicalTypeIndex expected_index)
static DirectHandle< WasmTagObject > New(Isolate *isolate, const wasm::FunctionSig *sig, wasm::CanonicalTypeIndex type_index, DirectHandle< HeapObject > tag, DirectHandle< WasmTrustedInstanceData > instance)
static DirectHandle< WasmTrustedInstanceData > New(Isolate *, DirectHandle< WasmModuleObject >, bool shared)
wasm::NativeModule * native_module() const
static DirectHandle< WasmFuncRef > GetOrCreateFuncRef(Isolate *isolate, DirectHandle< WasmTrustedInstanceData > trusted_instance_data, int function_index)
std::pair< Tagged< FixedArray >, uint32_t > GetGlobalBufferAndIndex(const wasm::WasmGlobal &)
void SetRawMemory(int memory_index, uint8_t *mem_start, size_t mem_size)
Tagged< WasmModuleObject > module_object() const
static constexpr std::array< const char *, 6 > kProtectedFieldNames
bool try_get_func_ref(int index, Tagged< WasmFuncRef > *result)
static constexpr std::array< uint16_t, 6 > kProtectedFieldOffsets
void InitDataSegmentArrays(const wasm::NativeModule *)
uint8_t * GetGlobalStorage(const wasm::WasmGlobal &)
static std::optional< MessageTemplate > InitTableEntries(Isolate *isolate, DirectHandle< WasmTrustedInstanceData > trusted_instance_data, DirectHandle< WasmTrustedInstanceData > shared_trusted_instance_data, uint32_t table_index, uint32_t segment_index, uint32_t dst, uint32_t src, uint32_t count) V8_WARN_UNUSED_RESULT
static constexpr std::array< const char *, kTaggedFieldsCount > kTaggedFieldNames
static constexpr std::array< uint16_t, kTaggedFieldsCount > kTaggedFieldOffsets
wasm::WasmValue GetGlobalValue(Isolate *, const wasm::WasmGlobal &)
const wasm::WasmModule * module() const
static bool CopyTableEntries(Isolate *isolate, DirectHandle< WasmTrustedInstanceData > trusted_instance_data, uint32_t table_dst_index, uint32_t table_src_index, uint32_t dst, uint32_t src, uint32_t count) V8_WARN_UNUSED_RESULT
WasmCodePointer GetCallTarget(uint32_t func_index)
static V8_WARN_UNUSED_RESULT DirectHandle< WeakArrayList > Append(Isolate *isolate, DirectHandle< WeakArrayList > array, MaybeObjectDirectHandle value, AllocationType allocation=AllocationType::kYoung)
constexpr HeapType::Representation heap_representation() const
static constexpr CanonicalValueType Ref(CanonicalTypeIndex index, bool shared, RefTypeKind kind)
constexpr HeapType::Representation heap_representation_non_shared() const
constexpr CanonicalTypeIndex ref_index() const
constexpr bool IsFunctionType() const
static DirectHandle< Code > CompileJSToWasmWrapper(Isolate *isolate, const CanonicalSig *sig, CanonicalTypeIndex sig_index)
std::atomic< uint32_t > * tiering_budget_array() const
uint32_t num_functions() const
const WasmModule * module() const
base::Vector< const uint8_t > wire_bytes() const
WasmCodePointer GetCodePointerHandle(int index) const
Address jump_table_start() const
size_t committed_code_space() const
ImportCallKind kind() const
V8_EXPORT_PRIVATE bool IsCanonicalSubtype(CanonicalTypeIndex sub_index, CanonicalTypeIndex super_index)
V8_EXPORT_PRIVATE const CanonicalStructType * LookupStruct(CanonicalTypeIndex index) const
V8_EXPORT_PRIVATE const CanonicalArrayType * LookupArray(CanonicalTypeIndex index) const
V8_EXPORT_PRIVATE const CanonicalSig * LookupFunctionSignature(CanonicalTypeIndex index) const
V8_EXPORT_PRIVATE void AddRecursiveGroup(WasmModule *module, uint32_t size)
static V8_EXPORT_PRIVATE void PrepareForCanonicalTypeId(Isolate *isolate, CanonicalTypeIndex id)
constexpr int value_kind_size() const
constexpr ValueKind kind() const
constexpr bool is_reference() const
constexpr bool has_index() const
constexpr bool is_object_reference() const
constexpr bool use_wasm_null() const
constexpr GenericKind generic_kind() const
static uint32_t JSToWasmWrapperPackedArraySize(const FunctionSig *sig)
static uint32_t RefArgsCount(const FunctionSig *sig)
static uint32_t RefRetsCount(const FunctionSig *sig)
static size_t EstimateNativeModuleMetaDataSize(const WasmModule *)
static size_t EstimateNativeModuleCodeSize(const WasmModule *)
void UpdateEntrypoint(WasmCodePointer index, Address value, uint64_t signature_hash)
Address GetEntrypointWithoutSignatureCheck(WasmCodePointer index) const
void FreeEntry(WasmCodePointer index)
WasmCodePointer AllocateAndInitializeEntry(Address entrypoint, uint64_t signature_hash)
uint64_t signature_hash() const
Address instruction_start() const
base::Vector< uint8_t > instructions() const
base::Vector< const uint8_t > reloc_info() const
static void DecrementRefCount(base::Vector< WasmCode *const >)
TypeCanonicalizer * type_canonicalizer()
static void set_had_nondeterminism()
WasmCode * AddWrapper(const CacheKey &key, WasmCompilationResult result, WasmCode::Kind kind, uint64_t signature_hash)
static void ClearIndirectCallCacheEntry(Isolate *isolate, DirectHandle< WasmInstanceObject > instance, uint32_t table_index, uint32_t entry_index)
static void UpdateIndirectCallTable(Isolate *isolate, DirectHandle< WasmInstanceObject > instance, uint32_t table_index)
static void UpdateMemoryAddress(DirectHandle< WasmInstanceObject > instance)
uint32_t end_offset() const
SharedFunctionInfoRef shared
ZoneVector< RpoNumber > & result
ZoneVector< Entry > entries
static V ReadUnalignedValue(Address p)
constexpr bool IsInBounds(T index, T length, T max)
constexpr Vector< T > VectorOf(T *start, size_t size)
wasm::WasmCompilationResult CompileWasmCapiCallWrapper(const wasm::CanonicalSig *sig)
V8_EXPORT_PRIVATE WasmCodePointerTable * GetProcessWideWasmCodePointerTable()
constexpr int kAnonymousFuncIndex
uint32_t max_mem32_pages()
static constexpr size_t kMaxCanonicalTypes
WasmImportWrapperCache * GetWasmImportWrapperCache()
uint32_t max_table_size()
MaybeDirectHandle< Object > JSToWasmObject(Isolate *isolate, DirectHandle< Object > value, CanonicalValueType expected, const char **error_message)
uint32_t max_mem64_pages()
std::optional< MessageTemplate > InitializeElementSegment(Zone *zone, Isolate *isolate, DirectHandle< WasmTrustedInstanceData > trusted_instance_data, DirectHandle< WasmTrustedInstanceData > shared_trusted_instance_data, uint32_t segment_index)
constexpr ImportCallKind kDefaultImportCallKind
TypeCanonicalizer * GetTypeCanonicalizer()
bool IsJSCompatibleSignature(const CanonicalSig *sig)
constexpr WasmCodePointer kInvalidWasmCodePointer
constexpr IndependentHeapType kWasmFuncRef
uint64_t max_mem32_bytes()
constexpr size_t kV8MaxWasmMemories
WasmEngine * GetWasmEngine()
@ kJSFunctionArityMismatch
constexpr size_t kWasmPageSize
V8_INLINE bool IsSubtypeOf(ValueType subtype, ValueType supertype, const WasmModule *sub_module, const WasmModule *super_module)
constexpr IndependentHeapType kWasmBottom
constexpr size_t kV8MaxWasmTableSize
uint64_t max_mem64_bytes()
DirectHandle< Object > WasmToJSObject(Isolate *isolate, DirectHandle< Object > value)
DirectHandle< Map > CreateStructMap(Isolate *isolate, wasm::CanonicalTypeIndex struct_index, DirectHandle< Map > opt_rtt_parent, DirectHandle< NativeContext > opt_native_context)
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset kDataSegmentStartsOffset kElementSegmentsOffset kInstanceObjectOffset kMemoryObjectsOffset kTaggedGlobalsBufferOffset kTablesOffset kProtectedDispatchTable0Offset dispatch_table_for_imports
void EncodeI32ExceptionValue(DirectHandle< FixedArray > encoded_values, uint32_t *encoded_index, uint32_t value)
Tagged< T > MakeStrong(Tagged< T > value)
void DecodeI32ExceptionValue(DirectHandle< FixedArray > encoded_values, uint32_t *encoded_index, uint32_t *value)
Tagged(T object) -> Tagged< T >
V8_INLINE IsolateForSandbox GetCurrentIsolateForSandbox()
kWasmInternalFunctionIndirectPointerTag instance_data
V8_INLINE Isolate * GetIsolateFromWritableObject(Tagged< HeapObject > object)
DirectHandle< Map > CreateArrayMap(Isolate *isolate, wasm::CanonicalTypeIndex array_index, DirectHandle< Map > opt_rtt_parent)
V8_INLINE constexpr bool IsSmi(TaggedImpl< kRefType, StorageType > obj)
@ TERMINAL_FAST_ELEMENTS_KIND
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in name
kWasmInternalFunctionIndirectPointerTag kProtectedInstanceDataOffset sig
bool UseGenericWasmToJSWrapper(wasm::ImportCallKind kind, const wasm::CanonicalSig *sig, wasm::Suspend suspend)
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset globals_start
const int kVariableSizeSentinel
v8::PageAllocator * GetArrayBufferPageAllocator()
Handle< To > UncheckedCast(Handle< From > value)
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset kDataSegmentStartsOffset kElementSegmentsOffset kInstanceObjectOffset memory_objects
constexpr int kSystemPointerSize
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset kDataSegmentStartsOffset kElementSegmentsOffset kInstanceObjectOffset kMemoryObjectsOffset kTaggedGlobalsBufferOffset tables
void DecodeI64ExceptionValue(DirectHandle< FixedArray > encoded_values, uint32_t *encoded_index, uint64_t *value)
V8_INLINE void * EmptyBackingStoreBuffer()
constexpr bool SmiValuesAre31Bits()
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset data_segment_starts
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset kDataSegmentStartsOffset kElementSegmentsOffset kInstanceObjectOffset kMemoryObjectsOffset kTaggedGlobalsBufferOffset kTablesOffset kProtectedDispatchTable0Offset kProtectedDispatchTableForImportsOffset func_refs
Tagged< MaybeWeak< T > > MakeWeak(Tagged< T > value)
size_t AllocatePageSize()
Tagged< ClearedWeakValue > ClearedValue(PtrComprCageBase cage_base)
constexpr AdaptArguments kAdapt
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset kDataSegmentStartsOffset element_segments
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset kDataSegmentStartsOffset kElementSegmentsOffset kInstanceObjectOffset kMemoryObjectsOffset tagged_globals_buffer
V8_EXPORT_PRIVATE FlagValues v8_flags
constexpr int JSParameterCount(int param_count_without_receiver)
refactor address components for immediate indexing make OptimizeMaglevOnNextCall optimize to turbofan instead of maglev filter for tracing turbofan compilation nullptr
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in allocation gc speed threshold for starting incremental marking via a task in percent of available threshold for starting incremental marking immediately in percent of available Use a single schedule for determining a marking schedule between JS and C objects schedules the minor GC task with kUserVisible priority max worker number of concurrent for NumberOfWorkerThreads start background threads that allocate memory concurrent_array_buffer_sweeping use parallel threads to clear weak refs in the atomic pause trace progress of the incremental marking trace object counts and memory usage report a tick only when allocated zone memory changes by this amount TracingFlags::gc_stats TracingFlags::gc_stats track native contexts that are expected to be garbage collected verify heap pointers before and after GC memory reducer runs GC with ReduceMemoryFootprint flag Maximum number of memory reducer GCs scheduled Old gen GC speed is computed directly from gc tracer counters Perform compaction on full GCs based on V8 s default heuristics Perform compaction on every full GC Perform code space compaction when finalizing a full GC with stack Stress GC compaction to flush out bugs with moving objects flush of baseline code when it has not been executed recently Use time base code flushing instead of age Use a progress bar to scan large objects in increments when incremental marking is active force incremental marking for small heaps and run it more often force marking at random points between and force scavenge at random points between and reclaim otherwise unreachable unmodified wrapper objects when possible less compaction in non memory reducing mode use high priority threads for concurrent Marking Test mode only flag It allows an unit test to select evacuation candidates pages(requires --stress_compaction).") DEFINE_BOOL(cppheap_incremental_marking
static bool IsMinusZero(double value)
DirectHandle< Map > CreateFuncRefMap(Isolate *isolate, wasm::CanonicalTypeIndex type, DirectHandle< Map > opt_rtt_parent)
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset kDataSegmentStartsOffset kElementSegmentsOffset instance_object
constexpr uint32_t kMaxUInt32
kInstanceDescriptorsOffset kTransitionsOrPrototypeInfoOffset IsNull(value)||IsJSProxy(value)||IsWasmObject(value)||(IsJSObject(value) &&(HeapLayout
void EncodeI64ExceptionValue(DirectHandle< FixedArray > encoded_values, uint32_t *encoded_index, uint64_t value)
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
static constexpr ReleaseStoreTag kReleaseStore
#define CONDITIONAL_WRITE_BARRIER(object, offset, value, mode)
#define RELEASE_WRITE_INT32_FIELD(p, offset, value)
#define DCHECK_LE(v1, v2)
#define CHECK_GE(lhs, rhs)
#define CHECK_IMPLIES(lhs, rhs)
#define CHECK_LT(lhs, rhs)
#define CHECK_LE(lhs, rhs)
#define DCHECK_NOT_NULL(val)
#define CHECK_NOT_NULL(val)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK_NE(v1, v2)
#define CHECK_NE(lhs, rhs)
#define DCHECK_GE(v1, v2)
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)
constexpr T RoundUp(T x, intptr_t m)
WasmName GetNameOrNull(WireBytesRef ref) const
constexpr bool valid() const
ModuleTypeIndex sig_index
BoundsCheckStrategy bounds_checks
bool has_signature(ModuleTypeIndex index) const
bool has_array(ModuleTypeIndex index) const
const ModuleOrigin origin
std::vector< WasmFunction > functions
CanonicalTypeIndex canonical_sig_id(ModuleTypeIndex index) const
bool has_struct(ModuleTypeIndex index) const
#define TRACE_EVENT0(category_group, name)
#define V8_LIKELY(condition)
std::unique_ptr< ValueMirror > value
#define FOREACH_WASMVALUE_CTYPES(V)
#define CASE_TYPE(valuetype, ctype)