37#ifdef V8_USE_SIMULATOR_WITH_GENERIC_C_CALLS
43 if (v8_flags.trace_wasm_instances) PrintF(__VA_ARGS__); \
50uint8_t* raw_buffer_ptr(MaybeDirectHandle<JSArrayBuffer> buffer,
int offset) {
51 return static_cast<uint8_t*
>(buffer.ToHandleChecked()->backing_store()) +
61 if (IsMap(maybe_shared_maps->get(type_index.
index)))
return;
64 module->canonical_type_id(type_index);
68 direct_handle(isolate->heap()->wasm_canonical_rtts(), isolate);
69 DCHECK_GT(
static_cast<uint32_t
>(canonical_rtts->length()),
70 canonical_type_index.
index);
72 canonical_rtts->get(canonical_type_index.
index);
74 maybe_shared_maps->set(type_index.
index,
84 if (supertype.
valid()) {
94 switch (module->
type(type_index).kind) {
110 canonical_rtts->set(canonical_type_index.
index,
MakeWeak(*map));
111 maybe_shared_maps->set(type_index.
index, *map);
116bool CompareWithNormalizedCType(
const CTypeInfo& info,
117 CanonicalValueType expected,
137 return t.representation() == expected.machine_representation();
140enum class ReceiverKind { kFirstParamIsReceiver, kAnyReceiver };
142bool IsSupportedWasmFastApiFunction(Isolate* isolate,
143 const wasm::CanonicalSig* expected_sig,
145 ReceiverKind receiver_kind,
147 if (!shared->IsApiFunction()) {
150 if (shared->api_func_data()->GetCFunctionsCount() == 0) {
153 if (receiver_kind == ReceiverKind::kAnyReceiver &&
154 !shared->api_func_data()->accept_any_receiver()) {
157 if (receiver_kind == ReceiverKind::kAnyReceiver &&
158 !IsUndefined(shared->api_func_data()->signature())) {
163 const auto log_imported_function_mismatch = [&
shared,
isolate](
165 const char* reason) {
167 CodeTracer::Scope scope(isolate->GetCodeTracer());
168 PrintF(scope.file(),
"[disabled optimization for ");
171 " for C function %d, reason: the signature of the imported "
172 "function in the Wasm module doesn't match that of the Fast API "
179 if (expected_sig->return_count() > 1) {
184 log_imported_function_mismatch(0,
"too many return values");
188 for (
int c_func_id = 0,
end = shared->api_func_data()->GetCFunctionsCount();
189 c_func_id <
end; ++c_func_id) {
190 const CFunctionInfo* info =
191 shared->api_func_data()->GetCSignature(isolate, c_func_id);
193 log_imported_function_mismatch(c_func_id,
194 "signature not supported by the fast API");
198 CTypeInfo return_info = info->ReturnInfo();
200 if (expected_sig->return_count() == 0 &&
202 log_imported_function_mismatch(c_func_id,
"too few return values");
206 if (expected_sig->return_count() == 1) {
208 log_imported_function_mismatch(c_func_id,
"too many return values");
211 if (!CompareWithNormalizedCType(return_info, expected_sig->GetReturn(0),
212 info->GetInt64Representation())) {
213 log_imported_function_mismatch(c_func_id,
"mismatching return value");
218 if (receiver_kind == ReceiverKind::kFirstParamIsReceiver) {
219 if (expected_sig->parameter_count() < 1) {
220 log_imported_function_mismatch(
221 c_func_id,
"at least one parameter is needed as the receiver");
224 if (!expected_sig->GetParam(0).is_reference()) {
225 log_imported_function_mismatch(c_func_id,
226 "the receiver has to be a reference");
232 receiver_kind == ReceiverKind::kFirstParamIsReceiver ? 1 : 0;
234 if (expected_sig->parameter_count() - param_offset !=
235 info->ArgumentCount() - 1) {
236 log_imported_function_mismatch(c_func_id,
"mismatched arity");
240 bool param_mismatch =
false;
241 for (
unsigned int i = 0;
i < expected_sig->parameter_count() - param_offset;
243 int sig_index =
i + param_offset;
246 CTypeInfo arg = info->ArgumentInfo(
i + 1);
247 if (!CompareWithNormalizedCType(arg, expected_sig->GetParam(sig_index),
248 info->GetInt64Representation())) {
249 log_imported_function_mismatch(c_func_id,
"parameter type mismatch");
250 param_mismatch =
true;
254 if (arg.GetSequenceType() == CTypeInfo::SequenceType::kIsSequence) {
255 log_imported_function_mismatch(c_func_id,
256 "sequence types are not allowed");
257 param_mismatch =
true;
262 if (param_mismatch) {
265 *out_index = c_func_id;
271bool ResolveBoundJSFastApiFunction(
const wasm::CanonicalSig* expected_sig,
272 DirectHandle<JSReceiver> callable) {
275 DirectHandle<JSFunction>
target;
276 if (IsJSBoundFunction(*callable)) {
279 if (bound_target->bound_arguments()->length() > 0) {
282 if (IsJSBoundFunction(bound_target->bound_target_function())) {
285 DirectHandle<JSReceiver> bound_target_function(
286 bound_target->bound_target_function(), isolate);
287 if (!IsJSFunction(*bound_target_function)) {
291 }
else if (IsJSFunction(*callable)) {
297 DirectHandle<SharedFunctionInfo>
shared(target->shared(), isolate);
298 int api_function_index = -1;
302 return IsSupportedWasmFastApiFunction(isolate, expected_sig, *shared,
303 ReceiverKind::kAnyReceiver,
304 &api_function_index) &&
305 api_function_index == 0;
308bool IsStringRef(wasm::CanonicalValueType type) {
309 return type.is_abstract_ref() && type.generic_kind() == GenericKind::kString;
312bool IsExternRef(wasm::CanonicalValueType type) {
313 return type.is_abstract_ref() && type.generic_kind() == GenericKind::kExtern;
316bool IsStringOrExternRef(wasm::CanonicalValueType type) {
317 return IsStringRef(type) || IsExternRef(type);
320bool IsDataViewGetterSig(
const wasm::CanonicalSig*
sig,
321 wasm::CanonicalValueType return_type) {
322 return sig->parameter_count() == 3 &&
sig->return_count() == 1 &&
328bool IsDataViewSetterSig(
const wasm::CanonicalSig*
sig,
330 return sig->parameter_count() == 4 &&
sig->return_count() == 0 &&
337 Zone* zone,
const CFunctionInfo* info) {
338 uint32_t arg_count = info->ArgumentCount();
341 constexpr uint32_t param_offset = 1;
344 arg_count - param_offset);
349 for (uint32_t
i = param_offset;
i < arg_count; ++
i) {
352 return sig_builder.Get();
360 DirectHandle<WasmTrustedInstanceData> trusted_instance_data,
int func_index,
361 DirectHandle<JSReceiver> callable,
const wasm::CanonicalSig*
sig) {
363 if (trusted_instance_data.is_null())
return kGeneric;
365 if (IsJSFunction(*callable)) {
367 if (!sfi->HasBuiltinId())
return kGeneric;
372 switch (sfi->builtin_id()) {
376 case Builtin::kNumberParseFloat:
377 if (
sig->parameter_count() == 1 &&
sig->return_count() == 1 &&
378 IsStringRef(
sig->GetParam(0)) &&
386#define COMPARE_MATH_BUILTIN_F64(name) \
387 case Builtin::kMath##name: { \
388 if (!v8_flags.wasm_math_intrinsics) return kGeneric; \
389 const FunctionSig* builtin_sig = WasmOpcodes::Signature(kExprF64##name); \
390 if (!builtin_sig) { \
391 builtin_sig = WasmOpcodes::AsmjsSignature(kExprF64##name); \
393 DCHECK_NOT_NULL(builtin_sig); \
394 if (EquivalentNumericSig(sig, builtin_sig)) { \
395 return WellKnownImport::kMathF64##name; \
412#undef COMPARE_MATH_BUILTIN_F64
423 if (!IsJSBoundFunction(*callable))
return kGeneric;
425 if (bound->bound_arguments()->length() != 0)
return kGeneric;
426 if (!IsJSFunction(bound->bound_target_function()))
return kGeneric;
429 if (!sfi->HasBuiltinId())
return kGeneric;
430 if (sfi->builtin_id() != Builtin::kFunctionPrototypeCall)
return kGeneric;
434 if (!IsJSFunction(bound_this))
return kGeneric;
437 int out_api_function_index = -1;
439 IsSupportedWasmFastApiFunction(isolate,
sig, sfi,
440 ReceiverKind::kFirstParamIsReceiver,
441 &out_api_function_index)) {
443 NativeModule* native_module = trusted_instance_data->native_module();
444 if (!native_module->TrySetFastApiCallTarget(
446 func_data->GetCFunction(isolate, out_api_function_index))) {
449#ifdef V8_USE_SIMULATOR_WITH_GENERIC_C_CALLS
450 Address c_functions[] = {func_data->GetCFunction(isolate, 0)};
452 func_data->GetCSignature(isolate, 0)};
453 isolate->simulator_data()->RegisterFunctionsAndSignatures(c_functions,
464 if (!native_module->has_fast_api_signature(func_index)) {
465 native_module->set_fast_api_signature(
467 GetFunctionSigForFastApiImport(
468 &native_module->module()->signature_zone,
469 func_data->GetCSignature(isolate, out_api_function_index)));
472 DirectHandle<HeapObject> js_signature(sfi->api_func_data()->signature(),
474 DirectHandle<Object> callback_data(
475 sfi->api_func_data()->callback_data(
kAcquireLoad), isolate);
476 DirectHandle<WasmFastApiCallData> fast_api_call_data =
477 isolate->factory()->NewWasmFastApiCallData(js_signature, callback_data);
478 trusted_instance_data->well_known_imports()->set(func_index,
479 *fast_api_call_data);
482 if (!sfi->HasBuiltinId())
return kGeneric;
483 switch (sfi->builtin_id()) {
485 case Builtin::kStringPrototypeToLocaleLowerCase:
486 if (
sig->parameter_count() == 2 &&
sig->return_count() == 1 &&
487 IsStringRef(
sig->GetParam(0)) && IsStringRef(
sig->GetParam(1)) &&
488 IsStringRef(
sig->GetReturn(0))) {
490 trusted_instance_data->well_known_imports()->set(func_index,
495 case Builtin::kStringPrototypeToLowerCaseIntl:
496 if (
sig->parameter_count() == 1 &&
sig->return_count() == 1 &&
497 IsStringRef(
sig->GetParam(0)) && IsStringRef(
sig->GetReturn(0))) {
499 }
else if (
sig->parameter_count() == 1 &&
sig->return_count() == 1 &&
506 case Builtin::kDataViewPrototypeGetBigInt64:
511 case Builtin::kDataViewPrototypeGetBigUint64:
516 case Builtin::kDataViewPrototypeGetFloat32:
521 case Builtin::kDataViewPrototypeGetFloat64:
526 case Builtin::kDataViewPrototypeGetInt8:
527 if (
sig->parameter_count() == 2 &&
sig->return_count() == 1 &&
534 case Builtin::kDataViewPrototypeGetInt16:
539 case Builtin::kDataViewPrototypeGetInt32:
544 case Builtin::kDataViewPrototypeGetUint8:
545 if (
sig->parameter_count() == 2 &&
sig->return_count() == 1 &&
552 case Builtin::kDataViewPrototypeGetUint16:
557 case Builtin::kDataViewPrototypeGetUint32:
563 case Builtin::kDataViewPrototypeSetBigInt64:
568 case Builtin::kDataViewPrototypeSetBigUint64:
573 case Builtin::kDataViewPrototypeSetFloat32:
578 case Builtin::kDataViewPrototypeSetFloat64:
583 case Builtin::kDataViewPrototypeSetInt8:
584 if (
sig->parameter_count() == 3 &&
sig->return_count() == 0 &&
591 case Builtin::kDataViewPrototypeSetInt16:
596 case Builtin::kDataViewPrototypeSetInt32:
601 case Builtin::kDataViewPrototypeSetUint8:
602 if (
sig->parameter_count() == 3 &&
sig->return_count() == 0 &&
609 case Builtin::kDataViewPrototypeSetUint16:
614 case Builtin::kDataViewPrototypeSetUint32:
619 case Builtin::kDataViewPrototypeGetByteLength:
620 if (
sig->parameter_count() == 1 &&
sig->return_count() == 1 &&
626 case Builtin::kNumberPrototypeToString:
627 if (
sig->parameter_count() == 2 &&
sig->return_count() == 1 &&
630 IsStringOrExternRef(
sig->GetReturn(0))) {
633 if (
sig->parameter_count() == 1 &&
sig->return_count() == 1 &&
635 IsStringOrExternRef(
sig->GetReturn(0))) {
639 case Builtin::kStringPrototypeIndexOf:
641 if (
sig->parameter_count() == 3 &&
sig->return_count() == 1 &&
642 IsStringRef(
sig->GetParam(0)) && IsStringRef(
sig->GetParam(1)) &&
646 }
else if (
sig->parameter_count() == 3 &&
sig->return_count() == 1 &&
670 expected_sig_id, preknown_import);
681 if (!IsJSFunction(*
callable))
return;
683 if (sfi->HasWasmFunctionData()) {
698 ->internal_formal_parameter_count_without_receiver(),
703 if (IsWasmSuspendingObject(*
callable_)) {
711 if (!data->MatchesSignature(expected_sig_id)) {
714 uint32_t function_index =
static_cast<uint32_t
>(data->function_index());
715 if (function_index >=
716 data->instance_data()->module()->num_imported_functions) {
729 suspend_ = js_function_data->GetSuspend();
730 if (!js_function_data->MatchesSignature(expected_sig_id)) {
733 if (IsJSFunction(js_function_data->GetCallable())) {
736 if (sfi->HasWasmFunctionData()) {
745 SetCallable(isolate, js_function_data->GetCallable());
751 if (!capi_function->MatchesSignature(expected_sig_id)) {
761 if (
v8_flags.turbo_fast_api_calls &&
762 ResolveBoundJSFastApiFunction(expected_sig,
callable_)) {
766 trusted_instance_data, func_index,
callable_, expected_sig);
785 if (shared->internal_formal_parameter_count_without_receiver() ==
836 const WasmImport&
import = module_->import_table[index];
837 const char* wire_bytes_start =
reinterpret_cast<const char*
>(
839 std::ostringstream oss;
840 oss <<
"Import #" << index <<
" \"";
841 oss.write(wire_bytes_start +
import.module_name.offset(),
842 import.module_name.length());
844 oss.write(wire_bytes_start +
import.field_name.offset(),
845 import.field_name.length());
851 std::ostringstream oss;
852 oss <<
"Import #" << index <<
" \"" << module_name->ToCString().get()
886 const DisallowJavascriptExecution& no_js);
943 template <
typename T>
972class WriteOutPGOTask :
public v8::Task {
974 explicit WriteOutPGOTask(std::weak_ptr<NativeModule> native_module)
978 std::shared_ptr<NativeModule> native_module =
native_module_.lock();
979 if (!native_module)
return;
981 native_module->tiering_budget_array());
982 Schedule(std::move(native_module_));
985 static void Schedule(std::weak_ptr<NativeModule> native_module) {
989 std::make_unique<WriteOutPGOTask>(std::move(native_module)), 10.0);
1004 isolate->GetOrRegisterRecorderContextId(isolate->native_context());
1005 InstanceBuilder builder(isolate, context_id, thrower, module_object, imports,
1009 const std::shared_ptr<NativeModule>& native_module =
1010 module_object->shared_native_module();
1011 if (
v8_flags.experimental_wasm_pgo_to_file &&
1012 native_module->ShouldPgoDataBeWritten() &&
1013 native_module->module()->num_declared_functions > 0) {
1014 WriteOutPGOTask::Schedule(native_module);
1020 DCHECK(isolate->has_exception() || thrower->
error());
1031 enabled_(module_object->native_module()->enabled_features()),
1032 module_(module_object->module()),
1034 module_object_(module_object),
1036 asmjs_memory_buffer_(asmjs_memory_buffer),
1037 tags_wrappers_(isolate),
1038 shared_tags_wrappers_(isolate),
1039 sanitized_imports_(isolate),
1040 init_expr_zone_(
isolate_->allocator(),
"constant expression zone") {
1048 "wasm.InstanceBuilder.Build");
1054 DisallowJavascriptExecution no_js(
isolate_);
1070 wasm_module_instantiated.
success =
true;
1072 module_->num_imported_functions;
1073 if (timer.IsStarted()) {
1079 ->AddTimedSample(instantiation_time);
1088 const DisallowJavascriptExecution& no_js) {
1101 TRACE(
"New module instantiation for %p\n", native_module);
1107 shared_trusted_data =
1124 if (!new_buffer.
ToHandle(&buffer)) {
1125 thrower_->RangeError(
"Out of memory: asm.js memory");
1128 buffer->set_is_detachable(
false);
1132 CHECK(!buffer->is_detachable());
1137 auto maximum_pages =
1142 constexpr int kMemoryIndexZero = 0;
1143 trusted_data->memory_objects()->set(kMemoryIndexZero, *memory_object);
1154 uint32_t num_memories =
static_cast<uint32_t
>(
module_->memories.size());
1155 for (uint32_t memory_index = 0; memory_index < num_memories;
1171 uint32_t untagged_globals_buffer_size =
module_->untagged_globals_buffer_size;
1172 if (untagged_globals_buffer_size > 0) {
1179 thrower_->RangeError(
"Out of memory: wasm globals");
1195 thrower_->RangeError(
"Out of memory: wasm globals");
1199 shared_trusted_data->set_untagged_globals_buffer(
1201 shared_trusted_data->set_globals_start(
reinterpret_cast<uint8_t*
>(
1206 uint32_t tagged_globals_buffer_size =
module_->tagged_globals_buffer_size;
1207 if (tagged_globals_buffer_size > 0) {
1209 static_cast<int>(tagged_globals_buffer_size));
1213 static_cast<int>(tagged_globals_buffer_size));
1221 if (
module_->num_imported_mutable_globals > 0) {
1227 trusted_data->set_imported_mutable_globals_buffers(*buffers_array);
1232 shared_trusted_data->set_imported_mutable_globals_buffers(
1233 *shared_buffers_array);
1240 int tags_count =
static_cast<int>(
module_->tags.size());
1241 if (tags_count > 0) {
1249 shared_trusted_data->set_tags_table(*shared_tag_table);
1257 int table_count =
static_cast<int>(
module_->tables.size());
1258 if (table_count == 0) {
1261 shared_trusted_data->set_tables(
1275 shared_dispatch_tables =
1277 shared_trusted_data->set_tables(*shared_tables);
1278 shared_trusted_data->set_dispatch_tables(*shared_dispatch_tables);
1280 for (
int i =
module_->num_imported_tables;
i < table_count;
i++) {
1288 table.type, canonical_type, table.initial_size,
1289 table.has_maximum_size, table.maximum_size,
1293 table.address_type, &dispatch_table);
1294 (table.shared ? shared_tables :
tables)->set(
i, *table_obj);
1295 if (!dispatch_table.
is_null()) {
1296 (table.shared ? shared_dispatch_tables : dispatch_tables)
1297 ->set(
i, *dispatch_table);
1300 ->set_dispatch_table0(*dispatch_table);
1309 if (!
module_->import_table.empty()) {
1310 int num_imported_functions =
1312 if (num_imported_functions < 0)
return {};
1319 if (!
module_->isorecursive_canonical_type_ids.empty()) {
1326 static_cast<int>(
module_->types.size()));
1329 static_cast<int>(
module_->types.size()))
1331 for (uint32_t index = 0; index <
module_->types.size(); index++) {
1334 type_is_shared ? shared_maps : non_shared_maps);
1336 trusted_data->set_managed_object_maps(*non_shared_maps);
1337 if (shared) shared_trusted_data->set_managed_object_maps(*shared_maps);
1339 for (uint32_t
i = 0;
i <
module_->types.size();
i++) {
1341 module_->types[
i].is_shared ? shared_maps : non_shared_maps;
1346 if (
module_->has_signature(index)) {
1347 DCHECK_EQ(map->instance_type(), WASM_FUNC_REF_TYPE);
1348 }
else if (
module_->has_array(index)) {
1349 DCHECK_EQ(map->instance_type(), WASM_ARRAY_TYPE);
1350 }
else if (
module_->has_struct(index)) {
1351 DCHECK_EQ(map->instance_type(), WASM_STRUCT_TYPE);
1360 int num_functions =
static_cast<int>(
module_->num_declared_functions);
1371 shared_trusted_data->set_feedback_vectors(*shared_vectors);
1388 if (tags_count > 0) {
1401 if (!
module_->elem_segments.empty()) {
1403 static_cast<int>(
module_->elem_segments.size()));
1406 static_cast<int>(
module_->elem_segments.size()))
1408 for (uint32_t
i = 0;
i <
module_->elem_segments.size();
i++) {
1411 bool is_declarative =
module_->elem_segments[
i].status ==
1413 (
module_->elem_segments[
i].shared ? shared_elements : elements)
1414 ->set(
i, is_declarative
1419 if (shared) shared_trusted_data->set_element_segments(*shared_elements);
1425 if (
module_->start_function_index >= 0) {
1426 int start_index =
module_->start_function_index;
1427 auto& function =
module_->functions[start_index];
1430 if (function.imported) {
1433 if (IsJSFunction(callable)) {
1444 bool function_is_shared =
module_->type(function.sig_index).is_shared;
1456 TRACE(
"Successfully built instance for module %p\n",
1459#if V8_ENABLE_DRUMBRAKE
1479 size_t num_memories =
module_->memories.size();
1482 for (uint32_t
i = 0;
i < num_memories;
i++) {
1486 shared_trusted_data,
i);
1492 size_t num_tables =
module_->tables.size();
1493 for (uint32_t
i = 0;
i < num_tables;
i++) {
1497 Tagged<Object> maybe_dispatch_table = data_part->dispatch_tables()->get(
i);
1498 if (maybe_dispatch_table ==
Smi::zero())
continue;
1508 if (
module_->has_shared_part) {
1515 if (
module_->tables.size() > 0) {
1523 if (!
module_->data_segments.empty()) {
1533 "wasm.ExecuteStartFunction");
1571 .ToHandle(&module) ||
1573 const char* error =
module.is_null()
1574 ? "module not found"
1575 : "module is not an object or function";
1583 if (value.is_null()) {
1592bool HasDefaultToNumberBehaviour(
Isolate* isolate,
1596 isolate->factory()->to_primitive_symbol()};
1601 isolate->factory()->valueOf_string()};
1603 DirectHandle<Object> value_of = value_of_it.
GetDataValue();
1604 if (!IsJSFunction(*value_of))
return false;
1607 if (value_of_builtin_id != Builtin::kObjectPrototypeValueOf)
return false;
1610 LookupIterator to_string_it{
isolate, function,
1611 isolate->factory()->toString_string()};
1613 DirectHandle<Object> to_string = to_string_it.GetDataValue();
1614 if (!IsJSFunction(*to_string))
return false;
1615 Builtin to_string_builtin_id =
1617 if (to_string_builtin_id != Builtin::kFunctionPrototypeToString)
return false;
1623bool MaybeMarkError(
ValueOrError value, ErrorThrower* thrower) {
1625 thrower->RuntimeError(
"%s",
1647 switch (it.state()) {
1655 thrower_->LinkError(
"%s: not a data property",
1668 if (IsJSFunction(*value) &&
1671 thrower_->LinkError(
"%s: function has special ToNumber behaviour",
1691 if (!segment.
active)
continue;
1698 trusted_instance_data, shared_trusted_instance_data);
1706 dest_offset =
static_cast<size_t>(std::min(
1707 dest_offset_64, uint64_t{std::numeric_limits<size_t>::max()}));
1712 size_t memory_size =
1713 trusted_instance_data->memory_size(segment.
memory_index);
1715 size_t segment_index = &segment -
module_->data_segments.data();
1717 "data segment %zu is out of bounds (offset %zu, "
1718 "length %u, memory size %zu)",
1719 segment_index, dest_offset, size, memory_size);
1723 uint8_t* memory_base =
1724 trusted_instance_data->memory_base(segment.
memory_index);
1725 std::memcpy(memory_base + dest_offset,
1732 TRACE(
"init [globals_start=%p + %u] = %s, type = %s\n",
1736 global.
offset, value.to_string().c_str(), global.
type.
name().c_str());
1738 ? (value.type() ==
module_->canonical_type(global.
type))
1750#define CASE(CamelName, name, length) \
1751 case WellKnownImport::kString##CamelName: \
1752 return std::make_tuple(name, Builtin::kWebAssemblyString##CamelName, length)
1755 CASE(CharCodeAt,
"charCodeAt", 2);
1756 CASE(CodePointAt,
"codePointAt", 2);
1758 CASE(Concat,
"concat", 2);
1759 CASE(Equals,
"equals", 2);
1760 CASE(FromCharCode,
"fromCharCode", 1);
1761 CASE(FromCodePoint,
"fromCodePoint", 1);
1762 CASE(FromUtf8Array,
"decodeStringFromUTF8Array", 3);
1763 CASE(FromWtf16Array,
"fromCharCodeArray", 3);
1764 CASE(IntoUtf8Array,
"encodeStringIntoUTF8Array", 3);
1765 CASE(Length,
"length", 1);
1766 CASE(MeasureUtf8,
"measureStringAsUTF8", 1);
1767 CASE(Substring,
"substring", 3);
1768 CASE(Test,
"test", 1);
1769 CASE(ToUtf8Array,
"encodeStringToUTF8Array", 1);
1770 CASE(ToWtf16Array,
"intoCharCodeArray", 3);
1780 Factory* factory = isolate->factory();
1787 info->set_native(
true);
1798 module_->type_feedback.well_known_imports;
1799 const std::string& magic_string_constants =
1801 const bool has_magic_string_constants =
1804 for (uint32_t index = 0; index <
module_->import_table.size(); ++
index) {
1805 const WasmImport&
import = module_->import_table[index];
1808 import.module_name.length() == magic_string_constants.size() &&
1809 std::equal(magic_string_constants.begin(), magic_string_constants.end(),
1810 wire_bytes.
begin() +
import.module_name.offset())) {
1828 if (
ffi_.is_null()) {
1831 "Imports argument must be present and must be an object");
1860 if (!IsCallable(*value)) {
1861 if (!IsWasmSuspendingObject(*value)) {
1862 thrower_->LinkError(
"%s: function import requires a callable",
1872 trusted_instance_data->func_refs()->set(
1877 module_->canonical_sig_id(
module_->functions[func_index].sig_index);
1881 expected_sig, sig_index, preknown_import);
1884 PrintF(
"[import %d is well-known built-in %s]\n", import_index,
1900 "%s: imported function does not match the expected type",
1905 auto function_data =
1909 function_data->instance_data();
1910 CHECK_GE(function_data->function_index(),
1913 instance_data->GetCallTarget(function_data->function_index());
1915#
if V8_ENABLE_DRUMBRAKE
1917 function_data->function_index()
1923 int expected_arity =
static_cast<int>(expected_sig->
parameter_count());
1928 if (wasm_code ==
nullptr) {
1955 DCHECK(IsJSFunction(*js_receiver) || IsJSBoundFunction(*js_receiver));
1996 resolved.
suspend(), expected_sig,
2000 int expected_arity =
static_cast<int>(expected_sig->
parameter_count());
2005 shared->internal_formal_parameter_count_without_receiver();
2011 cache->MaybeGet(
kind, sig_index, expected_arity, resolved.
suspend());
2017 wasm_code = cache->CompileWasmImportCallWrapper(
2019 expected_arity, resolved.
suspend());
2026 resolved.
suspend(), expected_sig,
2037 if (!IsWasmTableObject(*value)) {
2038 thrower_->LinkError(
"%s: table import requires a WebAssembly.Table",
2046 uint32_t imported_table_size =
2047 static_cast<uint32_t
>(table_object->current_length());
2048 if (imported_table_size < table.initial_size) {
2049 thrower_->LinkError(
"table import %d is smaller than initial %u, got %u",
2050 import_index, table.initial_size, imported_table_size);
2054 if (table.has_maximum_size) {
2055 std::optional<uint64_t> max_size = table_object->maximum_length_u64();
2058 "table import %d has no maximum length; required: %" PRIu64,
2059 import_index, table.maximum_size);
2062 if (*max_size > table.maximum_size) {
2063 thrower_->LinkError(
"table import %d has a larger maximum size %" PRIx64
2064 " than the module's declared maximum %" PRIu64,
2065 import_index, *max_size, table.maximum_size);
2070 if (table.address_type != table_object->address_type()) {
2071 thrower_->LinkError(
"cannot import %s table as %s",
2078 table_object->has_trusted_data()
2079 ? table_object->trusted_data(
isolate_)->module()
2084 table_type_module !=
nullptr);
2089 if (!
EquivalentTypes(table.type, table_object->type(table_type_module),
2090 module_, table_type_module)) {
2091 thrower_->LinkError(
"%s: imported table does not match the expected type",
2098 trusted_instance_data->tables()->set(table_index, *table_object);
2099 if (table_object->has_trusted_dispatch_table()) {
2101 table_object->trusted_dispatch_table(
isolate_);
2103 module_->canonical_type(table.type));
2104 SBXCHECK_GE(dispatch_table->length(), table.initial_size);
2105 trusted_instance_data->dispatch_tables()->set(table_index, dispatch_table);
2106 if (table_index == 0) {
2107 trusted_instance_data->set_dispatch_table0(dispatch_table);
2120 if (
static_cast<bool>(global_object->is_mutable()) != global.
mutability) {
2122 "%s: imported global does not match the expected mutability",
2129 if (global_object->has_trusted_data()) {
2130 source_module = global_object->trusted_data(
isolate_)->module();
2148 thrower_->LinkError(
"%s: imported global does not match the expected type",
2156 static_assert(
sizeof(global_object->offset()) <=
sizeof(
Address),
2157 "The offset into the globals buffer does not fit into "
2158 "the imported_mutable_globals array");
2162 trusted_instance_data->imported_mutable_globals()->set(
2163 global.
index, global_object->offset());
2171 trusted_instance_data->imported_mutable_globals()->set_sandboxed_pointer(
2172 global.
index, address);
2174 trusted_instance_data->imported_mutable_globals_buffers()->set(global.
index,
2182 value =
WasmValue(global_object->GetI32());
2185 value =
WasmValue(global_object->GetI64());
2188 value =
WasmValue(global_object->GetF32());
2191 value =
WasmValue(global_object->GetF64());
2198 value =
WasmValue(global_object->GetRef(),
2230 if (global.
type ==
kWasmS128 && !IsWasmGlobalObject(*value)) {
2232 "%s: global import of type v128 must be a WebAssembly.Global",
2251 thrower_->LinkError(
"%s: global import must be a number",
2258 if (IsWasmGlobalObject(*value)) {
2261 global, global_object);
2266 "%s: imported mutable global must be a WebAssembly.Global object",
2272 const char* error_message;
2276 .ToHandle(&wasm_value)) {
2305 "%s: global import must be a number, valid Wasm reference, or "
2306 "WebAssembly.Global object",
2317 int num_imported_functions = 0;
2318 int num_imported_tables = 0;
2323 module_->type_feedback.well_known_imports;
2324 int num_imports =
static_cast<int>(
module_->import_table.size());
2325 for (
int index = 0; index < num_imports; ++
index) {
2326 const WasmImport&
import = module_->import_table[index];
2330 switch (
import.
kind) {
2332 uint32_t func_index =
import.index;
2333 DCHECK_EQ(num_imported_functions, func_index);
2335 bool function_is_shared =
module_->type(sig_index).is_shared;
2337 function_is_shared ? shared_trusted_instance_data
2338 : trusted_instance_data,
2339 index, func_index, value, preknown_imports.
get(func_index))) {
2342 num_imported_functions++;
2346 uint32_t table_index =
import.index;
2347 DCHECK_EQ(table_index, num_imported_tables);
2348 bool table_is_shared =
module_->tables[table_index].shared;
2350 : trusted_instance_data,
2351 index, table_index, value)) {
2354 num_imported_tables++;
2355 USE(num_imported_tables);
2363 bool global_is_shared =
module_->globals[
import.index].shared;
2365 ? shared_trusted_instance_data
2366 : trusted_instance_data,
2367 index,
import.index, value)) {
2374 if (!IsWasmTagObject(*value)) {
2375 thrower_->LinkError(
"%s: tag import requires a WebAssembly.Tag",
2380 if (!imported_tag->MatchesSignature(
module_->canonical_sig_id(
2381 module_->tags[
import.index].sig_index))) {
2383 "%s: imported tag does not match the expected type",
2389 trusted_instance_data->tags_table()->get(
import.index)));
2390 trusted_instance_data->tags_table()->set(
import.index, tag);
2398 if (num_imported_functions > 0) {
2402 return num_imported_functions;
2409 int num_imports =
static_cast<int>(
module_->import_table.size());
2410 for (
int import_index = 0; import_index < num_imports; ++import_index) {
2411 const WasmImport&
import = module_->import_table[import_index];
2417 if (!IsWasmMemoryObject(*value)) {
2419 "%s: memory import must be a WebAssembly.Memory object",
2423 uint32_t memory_index =
import.index;
2427 uint32_t imported_cur_pages =
2428 static_cast<uint32_t
>(buffer->GetByteLength() /
kWasmPageSize);
2430 if (memory->address_type != memory_object->address_type()) {
2431 thrower_->LinkError(
"cannot import %s memory as %s",
2436 if (imported_cur_pages < memory->initial_pages) {
2438 "%s: memory import has %u pages which is smaller than the declared "
2440 ImportName(import_index).c_str(), imported_cur_pages,
2441 memory->initial_pages);
2444 int32_t imported_maximum_pages = memory_object->maximum_pages();
2445 if (memory->has_maximum_pages) {
2446 if (imported_maximum_pages < 0) {
2448 "%s: memory import has no maximum limit, expected at most %u",
2449 ImportName(import_index).c_str(), imported_maximum_pages);
2452 if (
static_cast<uint64_t
>(imported_maximum_pages) >
2453 memory->maximum_pages) {
2455 "%s: memory import has a larger maximum size %u than the "
2456 "module's declared maximum %" PRIu64,
2457 ImportName(import_index).c_str(), imported_maximum_pages,
2458 memory->maximum_pages);
2462 if (memory->is_shared != buffer->is_shared()) {
2464 "%s: mismatch in shared state of memory, declared = %d, imported = "
2466 ImportName(import_index).c_str(), memory->is_shared,
2467 buffer->is_shared());
2472 imported_memory_objects->get(memory_index));
2473 imported_memory_objects->set(memory_index, *memory_object);
2478template <
typename T>
2480 return reinterpret_cast<T*
>(raw_buffer_ptr(
2495 trusted_instance_data, shared_trusted_instance_data);
2509 uint32_t memory_index) {
2511 int initial_pages =
static_cast<int>(memory.initial_pages);
2512 int maximum_pages = memory.has_maximum_pages
2513 ?
static_cast<int>(memory.maximum_pages)
2519 memory.address_type);
2520 if (maybe_memory_object.
is_null()) {
2522 "Out of memory: Cannot allocate Wasm memory for new instance");
2525 return maybe_memory_object;
2533 std::unordered_map<int, IndirectHandle<Object>> imported_globals;
2540 for (
size_t index = 0,
end =
module_->import_table.size(); index <
end;
2542 const WasmImport&
import = module_->import_table[index];
2544 module_->globals[
import.index].exported) {
2546 if (IsWasmGlobalObject(*value)) {
2553 trusted_instance_data->instance_object(),
isolate_};
2562 single_function_name =
2569 DCHECK(exports_object->HasFastProperties());
2572 static_cast<int>(
module_->export_table.size()),
"WasmExportsObject");
2576 desc.set_enumerable(
true);
2577 desc.set_configurable(is_asm_js);
2591 bool shared =
module_->function_is_shared(exp.index);
2595 shared ? shared_trusted_instance_data : trusted_instance_data,
2601 value = wasm_external_function;
2606 desc.set_value(value);
2615 bool shared =
module_->tables[exp.index].shared;
2617 shared ? shared_trusted_instance_data : trusted_instance_data;
2626 value =
direct_handle(trusted_instance_data->memory_object(exp.index),
2633 maybe_shared_trusted_instance_data =
2634 global.
shared ? shared_trusted_instance_data
2635 : trusted_instance_data;
2637 auto cached_global = imported_globals.find(exp.index);
2638 if (cached_global != imported_globals.end()) {
2649 maybe_shared_trusted_instance_data
2650 ->imported_mutable_globals_buffers(),
2657 offset =
static_cast<uint32_t
>(
2658 maybe_shared_trusted_instance_data->imported_mutable_globals()
2659 ->get(global.
index));
2665 maybe_shared_trusted_instance_data->imported_mutable_globals()
2666 ->get_sandboxed_pointer(global.
index);
2668 size_t buffer_size = untagged_buffer->GetByteLength();
2670 reinterpret_cast<Address>(untagged_buffer->backing_store());
2671 CHECK(global_addr >= backing_store &&
2672 global_addr < backing_store + buffer_size);
2673 offset =
static_cast<uint32_t
>(global_addr - backing_store);
2678 maybe_shared_trusted_instance_data->tagged_globals_buffer(),
2682 maybe_shared_trusted_instance_data->untagged_globals_buffer(),
2692 global.
shared ? shared_trusted_instance_data
2693 : trusted_instance_data,
2706 trusted_instance_data->tags_table()->get(exp.index)),
2712 trusted_instance_data);
2726 details.attributes());
2744V8_INLINE void SetFunctionTablePlaceholder(
2748 uint32_t func_index) {
2749 const WasmModule* module = trusted_instance_data->module();
2750 const WasmFunction* function = &
module->functions[func_index];
2752 if (trusted_instance_data->try_get_func_ref(func_index, &func_ref)) {
2753 table_object->entries()->set(entry_index, *func_ref);
2756 isolate, table_object, entry_index, trusted_instance_data, func_index);
2759 function, trusted_instance_data
2760#
if V8_ENABLE_DRUMBRAKE
2767V8_INLINE void SetFunctionTableNullEntry(
2768 Isolate* isolate, DirectHandle<WasmTableObject> table_object,
2769 uint32_t entry_index) {
2770 table_object->entries()->set(entry_index, ReadOnlyRoots{isolate}.wasm_null());
2771 table_object->ClearDispatchTable(entry_index);
2778 for (
int table_index = 0;
2779 table_index < static_cast<int>(
module_->tables.size()); ++table_index) {
2782 table.shared ? shared_trusted_instance_data : trusted_instance_data;
2787 if (!table.initial_value.is_set())
continue;
2790 maybe_shared_trusted_instance_data->tables()->get(table_index)),
2793 if (is_function_table &&
2795 for (uint32_t entry_index = 0; entry_index < table.initial_size;
2797 SetFunctionTablePlaceholder(
2798 isolate_, maybe_shared_trusted_instance_data, table_object,
2799 entry_index, table.initial_value.index());
2801 }
else if (is_function_table && table.initial_value.kind() ==
2803 for (uint32_t entry_index = 0; entry_index < table.initial_size;
2805 SetFunctionTableNullEntry(
isolate_, table_object, entry_index);
2810 maybe_shared_trusted_instance_data, shared_trusted_instance_data);
2812 for (uint32_t entry_index = 0; entry_index < table.initial_size;
2823enum FunctionComputationMode { kLazyFunctionsAndNull, kStrictFunctionsAndNull };
2833 const WasmElemSegment& segment,
Decoder& decoder,
2834 FunctionComputationMode function_mode) {
2835 const WasmModule* module = trusted_instance_data->module();
2837 uint32_t function_index = decoder.consume_u32v();
2838 return function_mode == kStrictFunctionsAndNull
2841 segment.
type, module, isolate, trusted_instance_data,
2842 shared_trusted_instance_data)
2846 switch (
static_cast<WasmOpcode>(*decoder.pc())) {
2847 case kExprRefFunc: {
2848 auto [function_index,
length] =
2849 decoder.read_u32v<Decoder::FullValidationTag>(decoder.pc() + 1,
2851 if (
V8_LIKELY(decoder.lookahead(1 + length, kExprEnd))) {
2852 decoder.consume_bytes(length + 2);
2853 return function_mode == kStrictFunctionsAndNull
2856 segment.
type, module, isolate, trusted_instance_data,
2857 shared_trusted_instance_data)
2862 case kExprRefNull: {
2863 auto [heap_type,
length] =
2867 if (
V8_LIKELY(decoder.lookahead(1 + length, kExprEnd))) {
2868 decoder.consume_bytes(length + 2);
2869 return function_mode == kStrictFunctionsAndNull
2872 segment.
type, module, isolate, trusted_instance_data,
2873 shared_trusted_instance_data)
2883 constexpr bool kIsShared =
false;
2884 FunctionBody body(&
sig, decoder.pc_offset(), decoder.pc(), decoder.end(),
2886 WasmDetectedFeatures detected;
2894 WasmFullDecoder<Decoder::FullValidationTag, ConstantExpressionInterface,
2896 full_decoder(zone, trusted_instance_data->module(),
2898 trusted_instance_data->module(), isolate,
2899 trusted_instance_data, shared_trusted_instance_data);
2901 full_decoder.DecodeFunctionBody();
2903 decoder.consume_bytes(
static_cast<int>(full_decoder.pc() - decoder.pc()));
2905 result = full_decoder.interface().has_error()
2907 :
ValueOrError(full_decoder.interface().computed_value());
2921 uint32_t segment_index) {
2923 trusted_instance_data->module()->elem_segments[segment_index].shared;
2925 shared ? shared_trusted_instance_data : trusted_instance_data;
2926 if (!IsUndefined(data->element_segments()->get(segment_index)))
return {};
2928 const NativeModule* native_module = data->native_module();
2930 const WasmElemSegment& elem_segment =
module->elem_segments[segment_index];
2934 Decoder decoder(module_bytes);
2938 isolate->factory()->NewFixedArray(elem_segment.
element_count);
2942 zone, isolate, trusted_instance_data, shared_trusted_instance_data,
2943 elem_segment, decoder, kStrictFunctionsAndNull);
2948 data->element_segments()->set(segment_index, *
result);
2956 for (uint32_t segment_index = 0;
2957 segment_index <
module_->elem_segments.size(); ++segment_index) {
2962 const uint32_t table_index = elem_segment.
table_index;
2969 trusted_instance_data, shared_trusted_instance_data);
2971 if (table->is_table64()) {
2976 dest_offset =
static_cast<size_t>(std::min(
2977 dest_offset_64, uint64_t{std::numeric_limits<size_t>::max()}));
2986 : trusted_instance_data)
2988 ->get(table_index)),
2991 table_object->current_length())) {
2994 MessageTemplate::kWasmTrapTableOutOfBounds));
2999 trusted_instance_data->native_module()->wire_bytes();
3000 Decoder decoder(module_bytes);
3003 bool is_function_table =
3006 if (is_function_table) {
3007 for (
size_t i = 0;
i <
count;
i++) {
3008 int entry_index =
static_cast<int>(dest_offset +
i);
3009 ValueOrError computed_element = ConsumeElementSegmentEntry(
3011 shared_trusted_instance_data, elem_segment, decoder,
3012 kLazyFunctionsAndNull);
3013 if (MaybeMarkError(computed_element,
thrower_))
return;
3018 if (computed_value.to_i32() >= 0) {
3019 SetFunctionTablePlaceholder(
isolate_, trusted_instance_data,
3020 table_object, entry_index,
3021 computed_value.to_i32());
3023 SetFunctionTableNullEntry(
isolate_, table_object, entry_index);
3027 computed_value.
to_ref());
3031 for (
size_t i = 0;
i <
count;
i++) {
3032 int entry_index =
static_cast<int>(dest_offset +
i);
3033 ValueOrError computed_element = ConsumeElementSegmentEntry(
3035 shared_trusted_instance_data, elem_segment, decoder,
3036 kStrictFunctionsAndNull);
3037 if (MaybeMarkError(computed_element,
thrower_))
return;
3039 to_value(computed_element).to_ref());
3044 (elem_segment.
shared ? shared_trusted_instance_data : trusted_instance_data)
3054 for (
int index = 0; index < tags_table->length(); ++
index) {
3055 if (!IsUndefined(tags_table->get(index),
isolate_))
continue;
3057 tags_table->set(index, *tag);
union v8::internal::@341::BuiltinMetadata::KindSpecificData data
#define SBXCHECK_EQ(lhs, rhs)
#define SBXCHECK_GE(lhs, rhs)
#define SBXCHECK(condition)
int64_t InMicroseconds() const
static bool IsHighResolution()
constexpr T * begin() const
static const char *const kSingleFunctionName
V8_INLINE bool is_null() const
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT MaybeHandle< Object > Call(Isolate *isolate, DirectHandle< Object > callable, DirectHandle< Object > receiver, base::Vector< const DirectHandle< Object > > args)
Handle< ProtectedFixedArray > NewProtectedFixedArray(int length)
Handle< FixedArray > NewFixedArray(int length, AllocationType allocation=AllocationType::kYoung)
DirectHandle< FixedArray > NewFixedArrayWithZeroes(int length, AllocationType allocation=AllocationType::kYoung)
JSFunctionBuilder & set_map(DirectHandle< Map > v)
V8_WARN_UNUSED_RESULT Handle< JSFunction > Build()
Handle< SharedFunctionInfo > NewSharedFunctionInfoForBuiltin(MaybeDirectHandle< String > name, Builtin builtin, int len, AdaptArguments adapt, FunctionKind kind=FunctionKind::kNormalFunction)
MaybeHandle< JSArrayBuffer > NewJSArrayBufferAndBackingStore(size_t byte_length, InitializedFlag initialized, AllocationType allocation=AllocationType::kYoung)
Handle< JSObject > NewJSObject(DirectHandle< JSFunction > constructor, AllocationType allocation=AllocationType::kYoung, NewJSObjectType=NewJSObjectType::kNoAPIWrapper)
Handle< String > InternalizeUtf8String(base::Vector< const char > str)
auto Returns(ReturnTypes... return_types) const
void EnterContext(Tagged< NativeContext > context)
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)
void SetWasmToWasm(Tagged< WasmTrustedInstanceData > target_instance_object, WasmCodePointer call_target, wasm::CanonicalTypeIndex sig_id)
static V8_INLINE Isolate * Current()
HandleScopeImplementer * handle_scope_implementer() const
Handle< NativeContext > native_context()
v8::internal::Factory * factory()
const std::shared_ptr< metrics::Recorder > & metrics_recorder()
static V8_EXPORT_PRIVATE void MigrateSlowToFast(DirectHandle< JSObject > object, int unused_property_fields, const char *reason)
static void SetNormalizedProperty(DirectHandle< JSObject > object, DirectHandle< Name > name, DirectHandle< Object > value, PropertyDetails details)
static V8_EXPORT_PRIVATE void NormalizeProperties(Isolate *isolate, DirectHandle< JSObject > object, PropertyNormalizationMode mode, int expected_additional_properties, bool use_cache, const char *reason)
static V8_EXPORT_PRIVATE Maybe< bool > AddDataElement(DirectHandle< JSObject > receiver, uint32_t index, DirectHandle< Object > value, PropertyAttributes attributes)
static V8_WARN_UNUSED_RESULT Maybe< bool > SetIntegrityLevel(Isolate *isolate, DirectHandle< JSReceiver > object, IntegrityLevel lvl, ShouldThrow should_throw)
static V8_WARN_UNUSED_RESULT Maybe< bool > DefineOwnProperty(Isolate *isolate, DirectHandle< JSReceiver > object, DirectHandle< Object > key, PropertyDescriptor *desc, Maybe< ShouldThrow > should_throw)
Handle< Object > GetDataValue(AllocationPolicy allocation_policy=AllocationPolicy::kAllocationAllowed) const
@ TYPED_ARRAY_INDEX_NOT_FOUND
static MachineType TypeForCType(const CTypeInfo &type)
V8_INLINE DirectHandle< T > ToHandleChecked() const
V8_WARN_UNUSED_RESULT V8_INLINE bool ToHandle(DirectHandle< S > *out) const
V8_INLINE bool is_null() const
static V8_WARN_UNUSED_RESULT MaybeHandle< Object > GetPropertyOrElement(Isolate *isolate, DirectHandle< JSAny > object, DirectHandle< Name > name)
static V8_WARN_UNUSED_RESULT HandleType< Number >::MaybeType ToNumber(Isolate *isolate, HandleType< T > input)
static double NumberValue(Tagged< Number > obj)
static V8_EXPORT_PRIVATE bool ToInt32(Tagged< Object > obj, int32_t *value)
void set_writable(bool writable)
SignatureBuilder< Signature< T >, T > Builder
size_t parameter_count() const
static constexpr Tagged< Smi > zero()
bool Equals(Tagged< String > other) const
constexpr bool IsCleared() const
Tagged< HeapObject > GetHeapObjectAssumeWeak() const
static V8_EXPORT_PRIVATE v8::Platform * GetCurrentPlatform()
static bool IsWasmCapiFunction(Tagged< Object > object)
static void V8_EXPORT_PRIVATE AddUse(Isolate *isolate, DirectHandle< WasmDispatchTable > dispatch_table, DirectHandle< WasmTrustedInstanceData > instance, int table_index)
static V8_EXPORT_PRIVATE DirectHandle< WasmExceptionTag > New(Isolate *isolate, int index)
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)
static V8_EXPORT_PRIVATE DirectHandle< JSFunction > GetOrCreateExternal(DirectHandle< WasmInternalFunction > internal)
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)
static V8_EXPORT_PRIVATE DirectHandle< WasmMemoryObject > New(Isolate *isolate, DirectHandle< JSArrayBuffer > buffer, int maximum, wasm::AddressType address_type)
static DirectHandle< String > ExtractUtf8StringFromModuleBytes(Isolate *, DirectHandle< WasmModuleObject >, wasm::WireBytesRef, InternalizeString)
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 V8_EXPORT_PRIVATE void Set(Isolate *isolate, DirectHandle< WasmTableObject > table, uint32_t index, DirectHandle< Object > entry)
static V8_EXPORT_PRIVATE void SetFunctionTablePlaceholder(Isolate *isolate, DirectHandle< WasmTableObject > table, int entry_index, DirectHandle< WasmTrustedInstanceData > trusted_instance_data, int func_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)
static DirectHandle< WasmFuncRef > GetOrCreateFuncRef(Isolate *isolate, DirectHandle< WasmTrustedInstanceData > trusted_instance_data, int function_index)
uint64_t signature_hash() const
constexpr bool is_set() const
static constexpr ConstantExpression RefFunc(uint32_t index)
static constexpr ConstantExpression RefNull(HeapType type)
constexpr HeapType type() const
void consume_bytes(uint32_t size, const char *name="skip")
void InitGlobals(DirectHandle< WasmTrustedInstanceData > trusted_instance_data, DirectHandle< WasmTrustedInstanceData > shared_trusted_instance_data)
bool ProcessImportedMemories(DirectHandle< FixedArray > imported_memory_objects)
MaybeDirectHandle< JSReceiver > ffi_
DirectHandle< JSFunction > start_function_
MaybeDirectHandle< Object > LookupImportAsm(uint32_t index, DirectHandle< String > import_name)
void LoadTableSegments(DirectHandle< WasmTrustedInstanceData > trusted_instance_data, DirectHandle< WasmTrustedInstanceData > shared_trusted_instance_data)
void Build_Phase1_Infallible(DirectHandle< WasmTrustedInstanceData > trusted_data, DirectHandle< WasmTrustedInstanceData > shared_trusted_data)
MaybeDirectHandle< Object > LookupImport(uint32_t index, DirectHandle< String > module_name, DirectHandle< String > import_name)
DirectHandleVector< Object > sanitized_imports_
DirectHandle< JSArrayBuffer > untagged_globals_
MaybeDirectHandle< WasmTrustedInstanceData > Build_Phase2(DirectHandle< WasmTrustedInstanceData > trusted_data)
std::vector< WellKnownImport > well_known_imports_
DirectHandle< FixedArray > tagged_globals_
DirectHandleVector< WasmTagObject > tags_wrappers_
MaybeDirectHandle< WasmTrustedInstanceData > Build_Phase1(const DisallowJavascriptExecution &no_js)
const WasmEnabledFeatures enabled_
void InitializeTags(DirectHandle< WasmTrustedInstanceData > trusted_instance_data)
std::string ImportName(uint32_t index, DirectHandle< String > module_name)
bool ProcessImportedWasmGlobalObject(DirectHandle< WasmTrustedInstanceData > trusted_instance_data, int import_index, const WasmGlobal &global, DirectHandle< WasmGlobalObject > global_object)
MaybeDirectHandle< WasmInstanceObject > Build()
void SetTableInitialValues(DirectHandle< WasmTrustedInstanceData > trusted_instance_data, DirectHandle< WasmTrustedInstanceData > shared_trusted_instance_data)
bool ProcessImportedTable(DirectHandle< WasmTrustedInstanceData > trusted_instance_data, int import_index, int table_index, DirectHandle< Object > value)
bool ExecuteStartFunction()
int ProcessImports(DirectHandle< WasmTrustedInstanceData > trusted_instance_data, DirectHandle< WasmTrustedInstanceData > shared_trusted_instance_data)
const WasmModule *const module_
bool ProcessImportedGlobal(DirectHandle< WasmTrustedInstanceData > trusted_instance_data, int import_index, int global_index, DirectHandle< Object > value)
std::string ImportName(uint32_t index)
DirectHandle< FixedArray > shared_tagged_globals_
T * GetRawUntaggedGlobalPtr(const WasmGlobal &global)
void ProcessExports(DirectHandle< WasmTrustedInstanceData > trusted_instance_data, DirectHandle< WasmTrustedInstanceData > shared_trusted_instance_data)
MaybeDirectHandle< JSArrayBuffer > asmjs_memory_buffer_
DirectHandleVector< WasmTagObject > shared_tags_wrappers_
v8::metrics::Recorder::ContextId context_id_
InstanceBuilder(Isolate *isolate, v8::metrics::Recorder::ContextId context_id, ErrorThrower *thrower, DirectHandle< WasmModuleObject > module_object, MaybeDirectHandle< JSReceiver > ffi, MaybeDirectHandle< JSArrayBuffer > memory_buffer)
DirectHandle< WasmModuleObject > module_object_
MaybeDirectHandle< WasmMemoryObject > AllocateMemory(uint32_t memory_index)
void LoadDataSegments(DirectHandle< WasmTrustedInstanceData > trusted_instance_data, DirectHandle< WasmTrustedInstanceData > shared_trusted_instance_data)
DirectHandle< JSArrayBuffer > shared_untagged_globals_
void WriteGlobalValue(const WasmGlobal &global, const WasmValue &value)
bool ProcessImportedFunction(DirectHandle< WasmTrustedInstanceData > trusted_instance_data, int import_index, int func_index, DirectHandle< Object > value, WellKnownImport preknown_import)
const WasmModule * module() const
base::Vector< const uint8_t > wire_bytes() const
const CompileTimeImports & compile_imports() const
DirectHandle< JSReceiver > callable_
DirectHandle< WasmFunctionData > trusted_function_data_
DirectHandle< WasmFunctionData > trusted_function_data() const
DirectHandle< JSReceiver > callable() const
ImportCallKind ComputeKind(DirectHandle< WasmTrustedInstanceData > trusted_instance_data, int func_index, const wasm::CanonicalSig *expected_sig, CanonicalTypeIndex expected_canonical_type_index, WellKnownImport preknown_import)
ImportCallKind kind() const
WellKnownImport well_known_status() const
void SetCallable(Isolate *isolate, Tagged< JSReceiver > callable)
WellKnownImport well_known_status_
V8_EXPORT_PRIVATE ResolvedWasmImport(DirectHandle< WasmTrustedInstanceData > trusted_instance_data, int func_index, DirectHandle< JSReceiver > callable, const wasm::CanonicalSig *sig, CanonicalTypeIndex expected_sig_id, WellKnownImport preknown_import)
V8_EXPORT_PRIVATE const CanonicalSig * LookupFunctionSignature(CanonicalTypeIndex index) const
static V8_EXPORT_PRIVATE void PrepareForCanonicalTypeId(Isolate *isolate, CanonicalTypeIndex id)
constexpr ValueKind kind() const
constexpr bool is_reference() const
constexpr bool has_index() const
constexpr bool is_numeric() const
V8_EXPORT_PRIVATE std::string name() const
constexpr bool use_wasm_null() const
constexpr ModuleTypeIndex ref_index() const
base::Vector< uint8_t > instructions() const
base::Vector< const uint8_t > reloc_info() const
static constexpr WasmEnabledFeatures All()
WasmCode * AddWrapper(const CacheKey &key, WasmCompilationResult result, WasmCode::Kind kind, uint64_t signature_hash)
DirectHandle< Object > to_ref() const
void CopyTo(uint8_t *to) const
CanonicalValueType type() const
WellKnownImport get(int index) const
Handle< SharedFunctionInfo > info
SourcePositionTable * source_positions
SharedFunctionInfoRef shared
ZoneVector< RpoNumber > & result
std::shared_ptr< NativeModule > native_module_
v8::metrics::Recorder::ContextId context_id_
#define COMPARE_MATH_BUILTIN_F64(name)
constexpr bool IsInBounds(T index, T length, T max)
constexpr Vector< T > VectorOf(T *start, size_t size)
bool IsFastCallSupportedSignature(const v8::CFunctionInfo *sig)
wasm::WasmCompilationResult CompileWasmCapiCallWrapper(const wasm::CanonicalSig *sig)
wasm::WasmCompilationResult CompileWasmJSFastCallWrapper(const wasm::CanonicalSig *sig, DirectHandle< JSReceiver > callable)
static void Populate(HeapType *unfinished_type, const WasmModule *module)
std::pair< HeapType, uint32_t > read_heap_type(Decoder *decoder, const uint8_t *pc, WasmEnabledFeatures enabled)
bool IsCompileTimeImport(WellKnownImport wki)
const char * WellKnownImportName(WellKnownImport wki)
static ValueType value_type()
std::tuple< const char *, Builtin, int > NameBuiltinLength(WellKnownImport wki)
WasmImportWrapperCache * GetWasmImportWrapperCache()
uint32_t max_table_size()
V8_INLINE bool is_error(ValueOrError result)
MaybeDirectHandle< Object > JSToWasmObject(Isolate *isolate, DirectHandle< Object > value, CanonicalValueType expected, const char **error_message)
std::optional< MessageTemplate > InitializeElementSegment(Zone *zone, Isolate *isolate, DirectHandle< WasmTrustedInstanceData > trusted_instance_data, DirectHandle< WasmTrustedInstanceData > shared_trusted_instance_data, uint32_t segment_index)
std::variant< WasmValue, MessageTemplate > ValueOrError
V8_INLINE MessageTemplate to_error(ValueOrError result)
V8_INLINE WasmValue to_value(ValueOrError result)
constexpr IndependentValueType kWasmF32
V8_NOINLINE bool EquivalentTypes(ValueType type1, ValueType type2, const WasmModule *module1, const WasmModule *module2)
TypeCanonicalizer * GetTypeCanonicalizer()
bool is_asmjs_module(const WasmModule *module)
ValueOrError EvaluateConstantExpression(Zone *zone, ConstantExpression expr, ValueType expected, const WasmModule *module, Isolate *isolate, DirectHandle< WasmTrustedInstanceData > trusted_instance_data, DirectHandle< WasmTrustedInstanceData > shared_trusted_instance_data)
constexpr IndependentHeapType kWasmExternRef
bool IsJSCompatibleSignature(const CanonicalSig *sig)
MaybeDirectHandle< WasmInstanceObject > InstantiateToInstanceObject(Isolate *isolate, ErrorThrower *thrower, DirectHandle< WasmModuleObject > module_object, MaybeDirectHandle< JSReceiver > imports, MaybeDirectHandle< JSArrayBuffer > memory_buffer)
constexpr IndependentValueType kWasmI32
constexpr const char * AddressTypeToStr(AddressType address_type)
constexpr IndependentHeapType kWasmFuncRef
void DumpProfileToFile(const WasmModule *module, base::Vector< const uint8_t > wire_bytes, std::atomic< uint32_t > *tiering_budget_array)
void CreateMapForType(Isolate *isolate, const WasmModule *module, ModuleTypeIndex type_index, DirectHandle< FixedArray > maybe_shared_maps)
constexpr size_t kV8MaxWasmMemories
@ kJSFunctionArityMismatch
constexpr size_t kWasmPageSize
V8_INLINE bool IsSubtypeOf(ValueType subtype, ValueType supertype, const WasmModule *sub_module, const WasmModule *super_module)
constexpr IndependentValueType kWasmS128
DirectHandle< JSFunction > CreateFunctionForCompileTimeImport(Isolate *isolate, WellKnownImport wki)
constexpr IndependentValueType kWasmF64
constexpr IndependentValueType kWasmI64
@ kStringToLowerCaseStringref
@ kStringToLowerCaseImported
@ kStringToLocaleLowerCaseStringref
DirectHandle< Map > CreateStructMap(Isolate *isolate, wasm::CanonicalTypeIndex struct_index, DirectHandle< Map > opt_rtt_parent, DirectHandle< NativeContext > opt_native_context)
bool TryCast(Tagged< From > value, Tagged< To > *out)
bool IsClassConstructor(FunctionKind kind)
bool IsNumber(Tagged< Object > obj)
void PrintF(const char *format,...)
Tagged(T object) -> Tagged< T >
kWasmInternalFunctionIndirectPointerTag instance_data
DirectHandle< Map > CreateArrayMap(Isolate *isolate, wasm::CanonicalTypeIndex array_index, DirectHandle< Map > opt_rtt_parent)
V8_INLINE IndirectHandle< T > indirect_handle(DirectHandle< T > handle)
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 uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset kDataSegmentStartsOffset kElementSegmentsOffset kInstanceObjectOffset memory_objects
Signature< MachineType > MachineSignature
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset kDataSegmentStartsOffset kElementSegmentsOffset kInstanceObjectOffset kMemoryObjectsOffset kTaggedGlobalsBufferOffset tables
bool IsPrimitive(Tagged< Object > obj)
void ShortPrint(Tagged< Object > obj, FILE *out)
Tagged< MaybeWeak< T > > MakeWeak(Tagged< T > value)
int32_t DoubleToInt32(double x)
constexpr AdaptArguments kAdapt
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset kDataSegmentStartsOffset element_segments
V8_EXPORT_PRIVATE FlagValues v8_flags
float DoubleToFloat32(double x)
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
@ KEEP_INOBJECT_PROPERTIES
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
static constexpr AcquireLoadTag kAcquireLoad
Maybe< T > Just(const T &t)
int Compare(const T &a, const T &b)
#define CHECK_GE(lhs, rhs)
#define DCHECK_NOT_NULL(val)
#define DCHECK_IMPLIES(v1, v2)
#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)
constexpr bool valid() const
ConstantExpression dest_addr
uint32_t elements_wire_bytes_offset
ConstantExpression offset
uintptr_t max_memory_size
const TypeDefinition & type(ModuleTypeIndex index) const
bool has_type(ModuleTypeIndex index) const
ModuleTypeIndex sig_index
int64_t wall_clock_duration_in_us
size_t imported_function_count
#define TRACE_EVENT0(category_group, name)
#define TRACE_DISABLED_BY_DEFAULT(name)
#define END_ALLOW_USE_DEPRECATED()
#define V8_LIKELY(condition)
#define V8_UNLIKELY(condition)
#define START_ALLOW_USE_DEPRECATED()
const wasm::WasmModule * module_
#define SELECT_WASM_COUNTER(counters, origin, prefix, suffix)