44using i::wasm::AddressType;
45using i::wasm::CompileTimeImport;
46using i::wasm::CompileTimeImports;
47using i::wasm::ErrorThrower;
48using i::wasm::WasmEnabledFeatures;
54void ToUtf8Lossy(Isolate* isolate, DirectHandle<String>
string,
62 i::Isolate* isolate,
const char* api_method_name,
63 CompileTimeImports compile_imports,
64 std::shared_ptr<internal::wasm::CompilationResultResolver> resolver)
76 void Finish(
bool can_use_compiled_module) {
87 if (exception.is_null())
return;
89 resolver_->OnCompilationFailed(exception.ToHandleChecked());
103 const std::shared_ptr<i::wasm::NativeModule>& native_module) {
104 callback(CompiledWasmModule{native_module, url->data(), url->size()});
114 const std::shared_ptr<internal::wasm::CompilationResultResolver>
resolver_;
117WasmStreaming::WasmStreaming(std::unique_ptr<WasmStreamingImpl> impl)
127 TRACE_EVENT1(
"v8.wasm",
"wasm.OnBytesReceived",
"bytes", size);
128 impl_->OnBytesReceived(bytes, size);
133 impl_->Finish(can_use_compiled_module);
139 if (!exception.IsEmpty()) {
143 impl_->Abort(maybe_exception);
152 std::function<
void(CompiledWasmModule)>
callback) {
153 impl_->SetMoreFunctionsCanBeSerializedCallback(std::move(
callback));
164 Local<Value> value) {
169 return managed->get();
175 return isolate->factory()->NewStringFromAsciiChecked(str);
177Local<String> v8_str(Isolate* isolate,
const char* str) {
178 return Utils::ToLocal(v8_str(
reinterpret_cast<i::Isolate*
>(isolate), str));
181#define GET_FIRST_ARGUMENT_AS(Type) \
182 i::MaybeDirectHandle<i::Wasm##Type##Object> GetFirstArgumentAs##Type( \
183 const v8::FunctionCallbackInfo<v8::Value>& info, \
184 ErrorThrower* thrower) { \
185 i::DirectHandle<i::Object> arg0 = Utils::OpenDirectHandle(*info[0]); \
186 if (!IsWasm##Type##Object(*arg0)) { \
187 thrower->TypeError("Argument 0 must be a WebAssembly." #Type); \
190 return i::Cast<i::Wasm##Type##Object>(arg0); \
196#undef GET_FIRST_ARGUMENT_AS
198base::Vector<const uint8_t> GetFirstArgumentAsBytes(
200 ErrorThrower* thrower,
bool* is_shared) {
201 const uint8_t*
start =
nullptr;
204 if (source->IsArrayBuffer()) {
207 auto backing_store = buffer->GetBackingStore();
209 start =
reinterpret_cast<const uint8_t*
>(backing_store->Data());
210 length = backing_store->ByteLength();
211 *is_shared = buffer->IsSharedArrayBuffer();
212 }
else if (source->IsTypedArray()) {
215 Local<ArrayBuffer> buffer = array->Buffer();
217 auto backing_store = buffer->GetBackingStore();
219 start =
reinterpret_cast<const uint8_t*
>(backing_store->Data()) +
221 length = array->ByteLength();
222 *is_shared = buffer->IsSharedArrayBuffer();
224 thrower->TypeError(
"Argument 0 must be a buffer source");
229 thrower->CompileError(
"BufferSource argument is empty");
232 if (length > max_length) {
235 thrower->CompileError(
"buffer source exceeds maximum size of %zu (is %zu)",
243base::OwnedVector<const uint8_t> GetAndCopyFirstArgumentAsBytes(
245 ErrorThrower* thrower) {
247 base::Vector<const uint8_t> bytes =
248 GetFirstArgumentAsBytes(info, max_length, thrower, &is_shared);
264 if (ffi->IsUndefined())
return {};
272class AsyncCompilationResolver :
public i::wasm::CompilationResultResolver {
274 AsyncCompilationResolver(Isolate* isolate, Local<Context> context,
275 Local<Promise::Resolver> promise_resolver)
278 promise_resolver_(isolate, promise_resolver) {
280 promise_resolver_.AnnotateStrongRetainer(kGlobalPromiseHandle);
283 void OnCompilationSucceeded(
285 if (finished_)
return;
289 ->wasm_async_resolve_promise_callback();
293 WasmAsyncSuccess::kSuccess);
297 if (finished_)
return;
301 ->wasm_async_resolve_promise_callback();
304 Utils::ToLocal(error_reason), WasmAsyncSuccess::kFail);
308 static constexpr char kGlobalPromiseHandle[] =
309 "AsyncCompilationResolver::promise_";
310 bool finished_ =
false;
313 Global<Promise::Resolver> promise_resolver_;
316constexpr char AsyncCompilationResolver::kGlobalPromiseHandle[];
320class InstantiateModuleResultResolver
321 :
public i::wasm::InstantiationResultResolver {
323 InstantiateModuleResultResolver(Isolate* isolate, Local<Context> context,
324 Local<Promise::Resolver> promise_resolver)
327 promise_resolver_(isolate, promise_resolver) {
329 promise_resolver_.AnnotateStrongRetainer(kGlobalPromiseHandle);
332 void OnInstantiationSucceeded(
336 ->wasm_async_resolve_promise_callback();
340 WasmAsyncSuccess::kSuccess);
346 ->wasm_async_resolve_promise_callback();
349 Utils::ToLocal(error_reason), WasmAsyncSuccess::kFail);
353 static constexpr char kGlobalPromiseHandle[] =
354 "InstantiateModuleResultResolver::promise_";
357 Global<Promise::Resolver> promise_resolver_;
360constexpr char InstantiateModuleResultResolver::kGlobalPromiseHandle[];
365class InstantiateBytesResultResolver
366 :
public i::wasm::InstantiationResultResolver {
368 InstantiateBytesResultResolver(Isolate* isolate, Local<Context> context,
369 Local<Promise::Resolver> promise_resolver,
373 promise_resolver_(isolate, promise_resolver),
376 promise_resolver_.AnnotateStrongRetainer(kGlobalPromiseHandle);
377 module_.AnnotateStrongRetainer(kGlobalModuleHandle);
380 void OnInstantiationSucceeded(
390 ->CreateDataProperty(context,
401 success = WasmAsyncSuccess::kFail;
404 ->CreateDataProperty(
405 context, v8_str(
isolate_,
"instance"),
412 success = WasmAsyncSuccess::kFail;
416 ->wasm_async_resolve_promise_callback();
425 ->wasm_async_resolve_promise_callback();
428 Utils::ToLocal(error_reason), WasmAsyncSuccess::kFail);
432 static constexpr char kGlobalPromiseHandle[] =
433 "InstantiateBytesResultResolver::promise_";
434 static constexpr char kGlobalModuleHandle[] =
435 "InstantiateBytesResultResolver::module_";
438 Global<Promise::Resolver> promise_resolver_;
442constexpr char InstantiateBytesResultResolver::kGlobalPromiseHandle[];
443constexpr char InstantiateBytesResultResolver::kGlobalModuleHandle[];
448class AsyncInstantiateCompileResultResolver
449 :
public i::wasm::CompilationResultResolver {
451 AsyncInstantiateCompileResultResolver(
452 Isolate* isolate, Local<Context> context,
453 Local<Promise::Resolver> promise_resolver, Local<Value> imports)
456 promise_resolver_(isolate, promise_resolver),
457 imports_(isolate, imports) {
459 promise_resolver_.AnnotateStrongRetainer(kGlobalPromiseHandle);
460 imports_.AnnotateStrongRetainer(kGlobalImportsHandle);
463 void OnCompilationSucceeded(
465 if (finished_)
return;
467 i::wasm::GetWasmEngine()->AsyncInstantiate(
469 std::make_unique<InstantiateBytesResultResolver>(
476 if (finished_)
return;
480 ->wasm_async_resolve_promise_callback();
483 Utils::ToLocal(error_reason), WasmAsyncSuccess::kFail);
487 static constexpr char kGlobalPromiseHandle[] =
488 "AsyncInstantiateCompileResultResolver::promise_";
489 static constexpr char kGlobalImportsHandle[] =
490 "AsyncInstantiateCompileResultResolver::module_";
491 bool finished_ =
false;
494 Global<Promise::Resolver> promise_resolver_;
495 Global<Value> imports_;
498constexpr char AsyncInstantiateCompileResultResolver::kGlobalPromiseHandle[];
499constexpr char AsyncInstantiateCompileResultResolver::kGlobalImportsHandle[];
502std::string
ToString(
const char* name) {
return std::string(name); }
505 return std::string(
"Property '") + name->ToCString().get() +
"'";
510template <
typename Name>
511std::optional<uint32_t> EnforceUint32(Name argument_name, Local<v8::Value> v,
512 Local<Context> context,
513 ErrorThrower* thrower) {
514 double double_number;
515 if (!v->NumberValue(context).To(&double_number)) {
516 thrower->TypeError(
"%s must be convertible to a number",
520 if (!std::isfinite(double_number)) {
521 thrower->TypeError(
"%s must be convertible to a valid number",
525 if (double_number < 0) {
526 thrower->TypeError(
"%s must be non-negative",
530 if (double_number > std::numeric_limits<uint32_t>::max()) {
531 thrower->TypeError(
"%s must be in the unsigned long range",
536 return static_cast<uint32_t
>(double_number);
540template <
typename Name>
541std::optional<uint64_t> EnforceBigIntUint64(Name argument_name, Local<Value> v,
542 Local<Context> context,
543 ErrorThrower* thrower) {
546 i::Isolate* i_isolate = i::Isolate::Current();
548 .ToHandle(&bigint)) {
553 uint64_t
result = bigint->AsUint64(&lossless);
555 thrower->TypeError(
"%s must be in u64 range",
565enum CompilationMethod {
566 kSyncCompilation = 0,
567 kAsyncCompilation = 1,
568 kStreamingCompilation = 2,
569 kAsyncInstantiation = 3,
570 kStreamingInstantiation = 4,
573void RecordCompilationMethod(
i::Isolate* isolate, CompilationMethod
method) {
574 isolate->counters()->wasm_compilation_method()->AddSample(
method);
577CompileTimeImports ArgumentToCompileOptions(
579 WasmEnabledFeatures enabled_features) {
580 CompileTimeImports
result;
582 result.Add(CompileTimeImport::kDisableDenormalFloats);
584 if (!enabled_features.has_imported_strings())
return result;
586 if (!i::IsJSReceiver(*arg))
return result;
595 if (i::IsJSReceiver(*builtins)) {
599 i::Object::GetLengthFromArrayLike(isolate,
602 double raw_length = i::Object::NumberValue(*length_obj);
609 :
static_cast<uint32_t
>(raw_length);
610 for (uint32_t
i = 0;
i < len;
i++) {
612 Maybe<bool> maybe_found = i::JSReceiver::HasProperty(&it);
614 if (!maybe_found.FromJust())
continue;
617 i::Object::GetProperty(&it), {});
618 if (i::IsString(*value)) {
624 result.Add(CompileTimeImport::kJsString);
627 if (enabled_features.has_imported_strings_utf8()) {
629 result.Add(CompileTimeImport::kTextEncoder);
633 result.Add(CompileTimeImport::kTextDecoder);
643 isolate->factory()->InternalizeUtf8String(
"importedStringConstants");
644 if (i::JSReceiver::HasProperty(isolate,
receiver, importedStringConstants)
648 isolate, constants_value,
649 i::JSReceiver::GetProperty(isolate,
receiver, importedStringConstants),
651 if (i::IsString(*constants_value)) {
653 result.constants_module());
654 result.Add(CompileTimeImport::kStringConstants);
663class WasmJSApiScope {
665 explicit WasmJSApiScope(
667 const char* api_name)
668 : callback_info_(callback_info),
669 isolate_{callback_info.GetIsolate()},
671 thrower_{reinterpret_cast<
i::Isolate*>(
isolate_), api_name} {
675 WasmJSApiScope(
const WasmJSApiScope&) =
delete;
676 WasmJSApiScope& operator=(
const WasmJSApiScope&) =
delete;
678 void AssertException()
const {
679 DCHECK(i_isolate()->has_exception() || thrower_.error());
683 return callback_info_;
686 const char* api_name()
const {
return thrower_.context_name(); }
690 std::tuple<v8::Isolate*, i::Isolate*, ErrorThrower&> isolates_and_thrower() {
691 return {
isolate_, i_isolate(), thrower_};
701 HandleScope handle_scope_;
702 ErrorThrower thrower_;
709 WasmJSApiScope js_api_scope{
info,
"WebAssembly.compile()"};
710 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
711 RecordCompilationMethod(i_isolate, kAsyncCompilation);
713 Local<Context> context = isolate->GetCurrentContext();
714 Local<Promise::Resolver> promise_resolver;
716 return js_api_scope.AssertException();
718 Local<Promise> promise = promise_resolver->GetPromise();
719 info.GetReturnValue().Set(promise);
721 std::shared_ptr<i::wasm::CompilationResultResolver> resolver(
722 new AsyncCompilationResolver(isolate, context, promise_resolver));
725 i_isolate->native_context();
726 if (!i::wasm::IsWasmCodegenAllowed(i_isolate, native_context)) {
728 i::wasm::ErrorStringForCodegen(i_isolate, native_context);
729 thrower.CompileError(
"%s", error->ToCString().get());
730 resolver->OnCompilationFailed(thrower.Reify());
734 base::OwnedVector<const uint8_t> bytes = GetAndCopyFirstArgumentAsBytes(
735 info, i::wasm::max_module_size(), &thrower);
737 resolver->OnCompilationFailed(thrower.Reify());
740 auto enabled_features = WasmEnabledFeatures::FromIsolate(i_isolate);
741 CompileTimeImports compile_imports =
742 ArgumentToCompileOptions(info[1], i_isolate, enabled_features);
743 if (i_isolate->has_exception()) {
744 if (i_isolate->is_execution_terminating())
return;
747 i_isolate->clear_exception();
748 resolver->OnCompilationFailed(exception);
751 i::wasm::GetWasmEngine()->AsyncCompile(
752 i_isolate, enabled_features, std::move(compile_imports),
753 std::move(resolver), std::move(bytes), js_api_scope.api_name());
756void WasmStreamingCallbackForTesting(
758 WasmJSApiScope js_api_scope{
info,
"WebAssembly.compile()"};
759 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
761 std::shared_ptr<v8::WasmStreaming> streaming =
766 size_t unlimited = std::numeric_limits<size_t>::max();
767 base::OwnedVector<const uint8_t> bytes =
768 GetAndCopyFirstArgumentAsBytes(info, unlimited, &thrower);
770 streaming->Abort(Utils::ToLocal(thrower.Reify()));
773 streaming->OnBytesReceived(bytes.begin(), bytes.size());
775 CHECK(!thrower.error());
778void WasmStreamingPromiseFailedCallback(
781 std::shared_ptr<v8::WasmStreaming> streaming =
783 streaming->Abort(info[0]);
786void StartAsyncCompilationWithResolver(
787 WasmJSApiScope& js_api_scope, Local<Value> response_or_promise,
788 Local<Value> options_arg_value,
789 std::shared_ptr<i::wasm::CompilationResultResolver> resolver) {
790 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
792 Local<Context> context = isolate->GetCurrentContext();
796 if (!i::wasm::IsWasmCodegenAllowed(i_isolate, native_context)) {
798 i::wasm::ErrorStringForCodegen(i_isolate, native_context);
799 thrower.CompileError(
"%s", error->ToCString().get());
800 resolver->OnCompilationFailed(thrower.Reify());
804 auto enabled_features = WasmEnabledFeatures::FromIsolate(i_isolate);
805 CompileTimeImports compile_imports =
806 ArgumentToCompileOptions(options_arg_value, i_isolate, enabled_features);
807 if (i_isolate->has_exception()) {
808 if (i_isolate->is_execution_terminating())
return;
811 i_isolate->clear_exception();
812 resolver->OnCompilationFailed(exception);
818 std::shared_ptr<WasmStreaming> streaming = std::make_shared<WasmStreaming>(
819 std::make_unique<WasmStreaming::WasmStreamingImpl>(
820 i_isolate, js_api_scope.api_name(), std::move(compile_imports),
826 Local<v8::Function> compile_callback, reject_callback;
829 .ToLocal(&compile_callback) ||
832 .ToLocal(&reject_callback)) {
833 return js_api_scope.AssertException();
842 Local<Promise::Resolver> input_resolver;
844 input_resolver->Resolve(context, response_or_promise).IsNothing()) {
845 return js_api_scope.AssertException();
853 if (input_resolver->GetPromise()
854 ->Then(context, compile_callback, reject_callback)
856 streaming->Abort(MaybeLocal<Value>{});
857 return js_api_scope.AssertException();
863void WebAssemblyCompileStreaming(
865 WasmJSApiScope js_api_scope{
info,
"WebAssembly.compileStreaming()"};
866 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
867 RecordCompilationMethod(i_isolate, kStreamingCompilation);
868 Local<Context> context = isolate->GetCurrentContext();
871 Local<Promise::Resolver> promise_resolver;
873 return js_api_scope.AssertException();
875 Local<Promise> promise = promise_resolver->GetPromise();
876 info.GetReturnValue().Set(promise);
879 auto resolver = std::make_shared<AsyncCompilationResolver>(isolate, context,
882 StartAsyncCompilationWithResolver(js_api_scope, info[0], info[1], resolver);
887 WasmJSApiScope js_api_scope{
info,
"WebAssembly.validate()"};
888 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
891 bool bytes_are_shared =
false;
892 base::Vector<const uint8_t> bytes = GetFirstArgumentAsBytes(
893 info, i::wasm::max_module_size(), &thrower, &bytes_are_shared);
895 js_api_scope.AssertException();
897 if (!thrower.wasm_error())
return;
904 auto enabled_features = WasmEnabledFeatures::FromIsolate(i_isolate);
905 CompileTimeImports compile_imports =
906 ArgumentToCompileOptions(info[1], i_isolate, enabled_features);
907 if (i_isolate->has_exception()) {
908 if (i_isolate->is_execution_terminating())
return;
909 i_isolate->clear_exception();
914 bool validated =
false;
915 if (bytes_are_shared) {
923 validated = i::wasm::GetWasmEngine()->SyncValidate(
924 i_isolate, enabled_features, std::move(compile_imports),
925 bytes_copy.as_vector());
928 validated = i::wasm::GetWasmEngine()->SyncValidate(
929 i_isolate, enabled_features, std::move(compile_imports), bytes);
932 return_value.
Set(validated);
940 i::JSObject::GetPrototype(isolate, source);
942 if (maybe_prototype.
ToHandle(&prototype)) {
943 Maybe<bool>
result = i::JSObject::SetPrototype(
947 DCHECK(isolate->has_exception());
957 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Module()"};
958 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
959 if (i_isolate->wasm_module_callback()(info))
return;
960 RecordCompilationMethod(i_isolate, kSyncCompilation);
962 if (!info.IsConstructCall()) {
963 thrower.TypeError(
"WebAssembly.Module must be invoked with 'new'");
967 i_isolate->native_context();
968 if (!i::wasm::IsWasmCodegenAllowed(i_isolate, native_context)) {
970 i::wasm::ErrorStringForCodegen(i_isolate, native_context);
971 thrower.CompileError(
"%s", error->ToCString().get());
975 base::OwnedVector<const uint8_t> bytes = GetAndCopyFirstArgumentAsBytes(
976 info, i::wasm::max_module_size(), &thrower);
978 if (bytes.empty())
return js_api_scope.AssertException();
980 auto enabled_features = WasmEnabledFeatures::FromIsolate(i_isolate);
981 CompileTimeImports compile_imports =
982 ArgumentToCompileOptions(info[1], i_isolate, enabled_features);
983 if (i_isolate->has_exception()) {
989 maybe_module_obj = i::wasm::GetWasmEngine()->SyncCompile(
990 i_isolate, enabled_features, std::move(compile_imports), &thrower,
994 if (!maybe_module_obj.
ToHandle(&module_obj))
return;
1003 if (!TransferPrototype(i_isolate, module_obj,
1009 return_value.
Set(Utils::ToLocal(module_obj));
1013void WebAssemblyModuleImportsImpl(
1015 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Module.imports()"};
1016 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
1019 if (!GetFirstArgumentAsModule(info, &thrower).ToHandle(&module_object)) {
1020 return js_api_scope.AssertException();
1022 auto imports = i::wasm::GetImports(i_isolate, module_object);
1023 info.GetReturnValue().Set(Utils::ToLocal(imports));
1027void WebAssemblyModuleExportsImpl(
1029 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Module.exports()"};
1030 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
1033 if (!GetFirstArgumentAsModule(info, &thrower).ToHandle(&module_object)) {
1034 return js_api_scope.AssertException();
1036 auto exports = i::wasm::GetExports(i_isolate, module_object);
1037 info.GetReturnValue().Set(Utils::ToLocal(exports));
1041void WebAssemblyModuleCustomSectionsImpl(
1043 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Module.customSections()"};
1044 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
1047 if (!GetFirstArgumentAsModule(info, &thrower).ToHandle(&module_object)) {
1048 return js_api_scope.AssertException();
1051 if (info[1]->IsUndefined()) {
1052 thrower.TypeError(
"Argument 1 is required");
1059 return js_api_scope.AssertException();
1061 auto custom_sections = i::wasm::GetCustomSections(
1063 if (thrower.error())
return;
1064 info.GetReturnValue().Set(Utils::ToLocal(custom_sections));
1069 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Instance()"};
1070 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
1071 RecordCompilationMethod(i_isolate, kAsyncInstantiation);
1072 i_isolate->CountUsage(
1075 if (i_isolate->wasm_instance_callback()(info))
return;
1079 if (!info.IsConstructCall()) {
1080 thrower.TypeError(
"WebAssembly.Instance must be invoked with 'new'");
1085 if (!GetFirstArgumentAsModule(info, &thrower).ToHandle(&module_object)) {
1086 return js_api_scope.AssertException();
1089 Local<Value> ffi = info[1];
1091 if (!ffi->IsUndefined() && !ffi->IsObject()) {
1092 thrower.TypeError(
"Argument 1 must be an object");
1096 if (!i::wasm::GetWasmEngine()
1097 ->SyncInstantiate(i_isolate, &thrower, module_object,
1098 ImportsAsMaybeReceiver(ffi),
1100 .ToHandle(&instance_obj)) {
1101 return js_api_scope.AssertException();
1112 if (!TransferPrototype(i_isolate, instance_obj,
1114 return js_api_scope.AssertException();
1117 info.GetReturnValue().Set(Utils::ToLocal(instance_obj));
1124void WebAssemblyInstantiateStreaming(
1126 WasmJSApiScope js_api_scope{
info,
"WebAssembly.instantiateStreaming()"};
1127 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
1128 RecordCompilationMethod(i_isolate, kStreamingInstantiation);
1129 i_isolate->CountUsage(
1132 Local<Context> context = isolate->GetCurrentContext();
1135 Local<Promise::Resolver> result_resolver;
1137 return js_api_scope.AssertException();
1139 Local<Promise> promise = result_resolver->GetPromise();
1140 info.GetReturnValue().Set(promise);
1143 Local<Value> ffi = info[1];
1145 if (!ffi->IsUndefined() && !ffi->IsObject()) {
1146 thrower.TypeError(
"Argument 1 must be an object");
1147 InstantiateModuleResultResolver resolver(isolate, context, result_resolver);
1148 resolver.OnInstantiationFailed(thrower.Reify());
1152 auto compilation_resolver =
1153 std::make_shared<AsyncInstantiateCompileResultResolver>(
1154 isolate, context, result_resolver, ffi);
1155 StartAsyncCompilationWithResolver(js_api_scope, info[0], info[2],
1156 std::move(compilation_resolver));
1162void WebAssemblyInstantiateImpl(
1164 WasmJSApiScope js_api_scope{
info,
"WebAssembly.instantiate()"};
1165 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
1166 i_isolate->CountUsage(
1169 Local<Context> context = isolate->GetCurrentContext();
1171 Local<Promise::Resolver> promise_resolver;
1173 return js_api_scope.AssertException();
1175 Local<Promise> promise = promise_resolver->GetPromise();
1176 info.GetReturnValue().Set(promise);
1178 std::unique_ptr<i::wasm::InstantiationResultResolver> resolver(
1179 new InstantiateModuleResultResolver(isolate, context, promise_resolver));
1181 Local<Value> first_arg_value = info[0];
1186 "Argument 0 must be a buffer source or a WebAssembly.Module object");
1187 resolver->OnInstantiationFailed(thrower.Reify());
1192 Local<Value> ffi = info[1];
1194 if (!ffi->IsUndefined() && !ffi->IsObject()) {
1195 thrower.TypeError(
"Argument 1 must be an object");
1196 resolver->OnInstantiationFailed(thrower.Reify());
1204 i::wasm::GetWasmEngine()->AsyncInstantiate(i_isolate, std::move(resolver),
1206 ImportsAsMaybeReceiver(ffi));
1210 base::OwnedVector<const uint8_t> bytes = GetAndCopyFirstArgumentAsBytes(
1211 info, i::wasm::max_module_size(), &thrower);
1212 if (bytes.empty()) {
1213 resolver->OnInstantiationFailed(thrower.Reify());
1221 std::shared_ptr<i::wasm::CompilationResultResolver> compilation_resolver(
1222 new AsyncInstantiateCompileResultResolver(isolate, context,
1223 promise_resolver, ffi));
1228 i_isolate->native_context();
1229 if (!i::wasm::IsWasmCodegenAllowed(i_isolate, native_context)) {
1231 i::wasm::ErrorStringForCodegen(i_isolate, native_context);
1232 thrower.CompileError(
"%s", error->ToCString().get());
1233 compilation_resolver->OnCompilationFailed(thrower.Reify());
1237 auto enabled_features = WasmEnabledFeatures::FromIsolate(i_isolate);
1238 CompileTimeImports compile_imports =
1239 ArgumentToCompileOptions(info[2], i_isolate, enabled_features);
1240 if (i_isolate->has_exception()) {
1241 if (i_isolate->is_execution_terminating())
return;
1244 i_isolate->clear_exception();
1245 compilation_resolver->OnCompilationFailed(exception);
1249 i::wasm::GetWasmEngine()->AsyncCompile(
1250 i_isolate, enabled_features, std::move(compile_imports),
1251 std::move(compilation_resolver), std::move(bytes),
1252 js_api_scope.api_name());
1259template <
typename Name>
1260std::optional<uint64_t> AddressValueToU64(ErrorThrower* thrower,
1261 Local<Context> context,
1264 AddressType address_type) {
1265 switch (address_type) {
1266 case AddressType::kI32:
1267 return EnforceUint32(property_name, value, context, thrower);
1268 case AddressType::kI64:
1269 return EnforceBigIntUint64(property_name, value, context, thrower);
1277std::optional<uint64_t> AddressValueToBoundedU64(
1280 uint64_t lower_bound, uint64_t upper_bound) {
1281 std::optional<uint64_t> maybe_address_value =
1282 AddressValueToU64(thrower, context, value, property_name, address_type);
1283 if (!maybe_address_value)
return std::nullopt;
1284 uint64_t address_value = *maybe_address_value;
1286 if (address_value < lower_bound) {
1287 thrower->RangeError(
1288 "Property '%s': value %" PRIu64
" is below the lower bound %" PRIx64,
1289 property_name->ToCString().get(), address_value, lower_bound);
1290 return std::nullopt;
1293 if (address_value > upper_bound) {
1294 thrower->RangeError(
1295 "Property '%s': value %" PRIu64
" is above the upper bound %" PRIu64,
1296 property_name->ToCString().get(), address_value, upper_bound);
1297 return std::nullopt;
1300 return address_value;
1306std::optional<std::optional<uint64_t>> GetOptionalAddressValue(
1307 ErrorThrower* thrower, Local<Context> context, Local<v8::Object> descriptor,
1308 Local<String> property, AddressType address_type, int64_t lower_bound,
1309 uint64_t upper_bound) {
1311 if (!descriptor->Get(context, property).ToLocal(&value)) {
1312 return std::nullopt;
1317 if (value->IsUndefined()) {
1319 return std::optional<uint64_t>{};
1325 std::optional<uint64_t> maybe_address_value =
1326 AddressValueToBoundedU64(thrower, context, value, property_name,
1327 address_type, lower_bound, upper_bound);
1328 if (!maybe_address_value)
return std::nullopt;
1329 return *maybe_address_value;
1337std::optional<uint64_t> GetInitialOrMinimumProperty(
1338 v8::Isolate* isolate, ErrorThrower* thrower, Local<Context> context,
1339 Local<v8::Object> descriptor, AddressType address_type,
1340 uint64_t upper_bound) {
1341 auto maybe_maybe_initial = GetOptionalAddressValue(
1342 thrower, context, descriptor, v8_str(isolate,
"initial"), address_type, 0,
1344 if (!maybe_maybe_initial)
return std::nullopt;
1345 std::optional<uint64_t> maybe_initial = *maybe_maybe_initial;
1347 auto enabled_features =
1348 WasmEnabledFeatures::FromIsolate(
reinterpret_cast<i::Isolate*
>(isolate));
1349 if (enabled_features.has_type_reflection()) {
1350 auto maybe_maybe_minimum = GetOptionalAddressValue(
1351 thrower, context, descriptor, v8_str(isolate,
"minimum"), address_type,
1353 if (!maybe_maybe_minimum)
return std::nullopt;
1354 std::optional<uint64_t> maybe_minimum = *maybe_maybe_minimum;
1356 if (maybe_initial && maybe_minimum) {
1358 "The properties 'initial' and 'minimum' are not allowed at the same "
1360 return std::nullopt;
1362 if (maybe_minimum) {
1364 return *maybe_minimum;
1367 if (!maybe_initial) {
1369 thrower->TypeError(
"Property 'initial' is required");
1370 return std::nullopt;
1372 return *maybe_initial;
1376 i::wasm::AddressType type,
1378 return type == i::wasm::AddressType::kI64
1380 : Integer::NewFromUnsigned(isolate, value).As<Value>();
1384 i::wasm::ValueType type) {
1385 DCHECK(type.is_object_reference());
1388 if (type.heap_representation() == i::wasm::HeapType::kExtern) {
1389 return isolate->factory()->undefined_value();
1390 }
else if (!type.use_wasm_null()) {
1391 return isolate->factory()->null_value();
1393 return isolate->factory()->wasm_null();
1397std::optional<AddressType> GetAddressType(Isolate* isolate,
1398 Local<Context> context,
1399 Local<v8::Object> descriptor,
1400 ErrorThrower* thrower) {
1402 if (!descriptor->Get(context, v8_str(isolate,
"address"))
1404 return std::nullopt;
1407 if (address_value->IsUndefined())
return AddressType::kI32;
1410 if (!i::Object::ToString(
reinterpret_cast<i::Isolate*
>(isolate),
1412 .ToHandle(&address)) {
1413 return std::nullopt;
1419 thrower->TypeError(
"Unknown address type '%s'; pass 'i32' or 'i64'",
1420 address->ToCString().get());
1421 return std::nullopt;
1427 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Table()"};
1428 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
1430 if (!info.IsConstructCall()) {
1431 thrower.TypeError(
"WebAssembly.Table must be invoked with 'new'");
1435 thrower.TypeError(
"Argument 0 must be a table descriptor");
1438 Local<Context> context = isolate->GetCurrentContext();
1440 i::wasm::ValueType
type;
1444 if (!descriptor->Get(context, v8_str(isolate,
"element")).
ToLocal(&value)) {
1445 return js_api_scope.AssertException();
1448 if (!i::Object::ToString(
reinterpret_cast<i::Isolate*
>(isolate),
1450 .ToHandle(&
string)) {
1451 return js_api_scope.AssertException();
1453 auto enabled_features = WasmEnabledFeatures::FromIsolate(i_isolate);
1456 type = i::wasm::kWasmFuncRef;
1457 }
else if (enabled_features.has_type_reflection() &&
1461 type = i::wasm::kWasmFuncRef;
1463 type = i::wasm::kWasmExternRef;
1464 }
else if (enabled_features.has_stringref() &&
1466 type = i::wasm::kWasmStringRef;
1468 type = i::wasm::kWasmAnyRef;
1470 type = i::wasm::kWasmEqRef;
1472 type = i::wasm::kWasmStructRef;
1474 type = i::wasm::kWasmArrayRef;
1476 type = i::wasm::kWasmI31Ref;
1479 "Descriptor property 'element' must be a WebAssembly reference type");
1486 std::optional<AddressType> maybe_address_type =
1487 GetAddressType(isolate, context, descriptor, &thrower);
1488 if (!maybe_address_type) {
1489 DCHECK(i_isolate->has_exception() || thrower.error());
1492 AddressType address_type = *maybe_address_type;
1495 std::optional<uint64_t> maybe_initial = GetInitialOrMinimumProperty(
1496 isolate, &thrower, context, descriptor, address_type,
1497 i::wasm::max_table_init_entries());
1498 if (!maybe_initial)
return js_api_scope.AssertException();
1499 static_assert(i::wasm::kV8MaxWasmTableInitEntries <=
i::kMaxUInt32);
1500 uint32_t initial =
static_cast<uint32_t
>(*maybe_initial);
1504 auto maybe_maybe_maximum = GetOptionalAddressValue(
1505 &thrower, context, descriptor, v8_str(isolate,
"maximum"), address_type,
1506 initial, kNoMaximum);
1507 if (!maybe_maybe_maximum)
return js_api_scope.AssertException();
1508 std::optional<uint64_t> maybe_maximum = *maybe_maybe_maximum;
1510 DCHECK(!type.has_index());
1511 i::wasm::CanonicalValueType canonical_type{type};
1514 canonical_type, initial, maybe_maximum.has_value(),
1515 maybe_maximum.value_or(0) ,
1516 DefaultReferenceValue(i_isolate, type), address_type);
1525 if (!TransferPrototype(i_isolate, table_obj,
1527 return js_api_scope.AssertException();
1530 if (initial > 0 && info.Length() >= 2 && !info[1]->IsUndefined()) {
1532 const char* error_message;
1533 if (!i::WasmTableObject::JSToWasmElement(i_isolate, table_obj, element,
1535 .ToHandle(&element)) {
1537 "Argument 2 must be undefined or a value of type compatible "
1538 "with the type of the new table: %s.",
1543 i::WasmTableObject::Set(i_isolate, table_obj, index, element);
1545 }
else if (initial > 0) {
1546 DCHECK_EQ(type, table_obj->unsafe_type());
1547 switch (type.heap_representation()) {
1548 case i::wasm::HeapType::kString:
1550 "Missing initial value when creating stringref table");
1552 case i::wasm::HeapType::kStringViewWtf8:
1553 thrower.TypeError(
"stringview_wtf8 has no JS representation");
1555 case i::wasm::HeapType::kStringViewWtf16:
1556 thrower.TypeError(
"stringview_wtf16 has no JS representation");
1558 case i::wasm::HeapType::kStringViewIter:
1559 thrower.TypeError(
"stringview_iter has no JS representation");
1571 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Memory()"};
1572 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
1574 if (!info.IsConstructCall()) {
1575 thrower.TypeError(
"WebAssembly.Memory must be invoked with 'new'");
1579 thrower.TypeError(
"Argument 0 must be a memory descriptor");
1582 Local<Context> context = isolate->GetCurrentContext();
1586 std::optional<AddressType> maybe_address_type =
1587 GetAddressType(isolate, context, descriptor, &thrower);
1588 if (!maybe_address_type)
return js_api_scope.AssertException();
1589 AddressType address_type = *maybe_address_type;
1590 uint64_t max_supported_pages = address_type == AddressType::kI64
1591 ? i::wasm::kSpecMaxMemory64Pages
1592 : i::wasm::kSpecMaxMemory32Pages;
1595 static_assert(i::wasm::kSpecMaxMemory32Pages <
i::kMaxInt);
1596 static_assert(i::wasm::kSpecMaxMemory64Pages <
i::kMaxInt);
1599 std::optional<uint64_t> maybe_initial =
1600 GetInitialOrMinimumProperty(isolate, &thrower, context, descriptor,
1601 address_type, max_supported_pages);
1602 if (!maybe_initial) {
1603 return js_api_scope.AssertException();
1605 uint64_t initial = *maybe_initial;
1608 auto maybe_maybe_maximum = GetOptionalAddressValue(
1609 &thrower, context, descriptor, v8_str(isolate,
"maximum"), address_type,
1610 initial, max_supported_pages);
1611 if (!maybe_maybe_maximum) {
1612 return js_api_scope.AssertException();
1614 std::optional<uint64_t> maybe_maximum = *maybe_maybe_maximum;
1618 if (!descriptor->Get(context, v8_str(isolate,
"shared")).
ToLocal(&value)) {
1619 return js_api_scope.AssertException();
1622 auto shared = value->BooleanValue(isolate) ? i::SharedFlag::kShared
1623 : i::SharedFlag::kNotShared;
1626 if (shared == i::SharedFlag::kShared && !maybe_maximum.has_value()) {
1627 thrower.TypeError(
"If shared is true, maximum property should be defined.");
1632 if (!i::WasmMemoryObject::New(i_isolate,
static_cast<int>(initial),
1633 maybe_maximum ?
static_cast<int>(*maybe_maximum)
1634 : i::WasmMemoryObject::kNoMaximum,
1635 shared, address_type)
1636 .ToHandle(&memory_obj)) {
1637 thrower.RangeError(
"could not allocate memory");
1648 if (!TransferPrototype(i_isolate, memory_obj,
1650 return js_api_scope.AssertException();
1653 if (shared == i::SharedFlag::kShared) {
1658 if (!
result.FromJust()) {
1660 "Status of setting SetIntegrityLevel of buffer is false.");
1664 info.GetReturnValue().Set(Utils::ToLocal(memory_obj));
1668void WebAssemblyMemoryMapDescriptorImpl(
1671 WasmJSApiScope js_api_scope{
info,
"WebAssembly.MemoryMapDescriptor()"};
1672 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
1673 if (!info.IsConstructCall()) {
1675 "WebAssembly.MemoryMapDescriptor must be invoked with 'new'");
1676 return js_api_scope.AssertException();
1679 std::optional<uint32_t> size =
1680 EnforceUint32(
"size", info[0], isolate->GetCurrentContext(), &thrower);
1682 if (!size.has_value()) {
1683 return js_api_scope.AssertException();
1687 if (!i::WasmMemoryMapDescriptor::NewFromAnonymous(i_isolate, size.value())
1688 .ToHandle(&descriptor_obj)) {
1689 thrower.RuntimeError(
"Failed to create a MemoryMapDescriptor");
1690 return js_api_scope.AssertException();
1700 if (!TransferPrototype(i_isolate, descriptor_obj,
1702 DCHECK(i_isolate->has_exception());
1703 return js_api_scope.AssertException();
1706 info.GetReturnValue().Set(Utils::ToLocal(descriptor_obj));
1713std::optional<i::wasm::ValueType> GetValueType(
1714 Isolate* isolate, MaybeLocal<Value> maybe, Local<Context> context,
1715 WasmEnabledFeatures enabled_features) {
1717 if (!maybe.ToLocal(&value))
return std::nullopt;
1719 if (!i::Object::ToString(
reinterpret_cast<i::Isolate*
>(isolate),
1721 .ToHandle(&
string)) {
1722 return std::nullopt;
1725 return i::wasm::kWasmI32;
1727 return i::wasm::kWasmF32;
1729 return i::wasm::kWasmI64;
1731 return i::wasm::kWasmF64;
1733 return i::wasm::kWasmS128;
1735 return i::wasm::kWasmExternRef;
1736 }
else if (enabled_features.has_type_reflection() &&
1740 return i::wasm::kWasmFuncRef;
1743 return i::wasm::kWasmFuncRef;
1745 return i::wasm::kWasmEqRef;
1746 }
else if (enabled_features.has_stringref() &&
1748 return i::wasm::kWasmStringRef;
1750 return i::wasm::kWasmAnyRef;
1752 return i::wasm::kWasmStructRef;
1754 return i::wasm::kWasmArrayRef;
1756 return i::wasm::kWasmI31Ref;
1757 }
else if (enabled_features.has_exnref() &&
1759 return i::wasm::kWasmExnRef;
1762 return i::wasm::kWasmVoid;
1767bool ToI32(Local<v8::Value> value, Local<Context> context, int32_t* i32_value) {
1768 if (!value->IsUndefined()) {
1770 if (!value->ToInt32(context).ToLocal(&int32_value))
return false;
1771 if (!int32_value->Int32Value(context).To(i32_value))
return false;
1776bool ToI64(Local<v8::Value> value, Local<Context> context, int64_t* i64_value) {
1777 if (!value->IsUndefined()) {
1779 if (!value->ToBigInt(context).ToLocal(&bigint_value))
return false;
1780 *i64_value = bigint_value->Int64Value();
1785bool ToF32(Local<v8::Value> value, Local<Context> context,
float* f32_value) {
1786 if (!value->IsUndefined()) {
1787 double f64_value = 0;
1789 if (!value->ToNumber(context).ToLocal(&number_value))
return false;
1790 if (!number_value->NumberValue(context).To(&f64_value))
return false;
1796bool ToF64(Local<v8::Value> value, Local<Context> context,
double* f64_value) {
1797 if (!value->IsUndefined()) {
1799 if (!value->ToNumber(context).ToLocal(&number_value))
return false;
1800 if (!number_value->NumberValue(context).To(f64_value))
return false;
1808 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Global()"};
1809 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
1811 if (!info.IsConstructCall()) {
1812 thrower.TypeError(
"WebAssembly.Global must be invoked with 'new'");
1816 thrower.TypeError(
"Argument 0 must be a global descriptor");
1819 Local<Context> context = isolate->GetCurrentContext();
1821 auto enabled_features = WasmEnabledFeatures::FromIsolate(i_isolate);
1827 if (!descriptor->Get(context, v8_str(isolate,
"mutable")).
ToLocal(&value)) {
1828 return js_api_scope.AssertException();
1830 is_mutable = value->BooleanValue(isolate);
1836 i::wasm::ValueType
type;
1839 descriptor->Get(context, v8_str(isolate,
"value"));
1840 std::optional<i::wasm::ValueType> maybe_type =
1841 GetValueType(isolate, maybe, context, enabled_features);
1842 if (!maybe_type)
return js_api_scope.AssertException();
1844 if (type == i::wasm::kWasmVoid) {
1846 "Descriptor property 'value' must be a WebAssembly type");
1851 const uint32_t
offset = 0;
1853 i::WasmGlobalObject::New(
1859 if (!maybe_global_obj.
ToHandle(&global_obj)) {
1860 return js_api_scope.AssertException();
1870 if (!TransferPrototype(i_isolate, global_obj,
1872 return js_api_scope.AssertException();
1877 switch (type.kind()) {
1878 case i::wasm::kI32: {
1880 if (!ToI32(value, context, &i32_value)) {
1881 return js_api_scope.AssertException();
1883 global_obj->SetI32(i32_value);
1886 case i::wasm::kI64: {
1887 int64_t i64_value = 0;
1888 if (!ToI64(value, context, &i64_value)) {
1889 return js_api_scope.AssertException();
1891 global_obj->SetI64(i64_value);
1894 case i::wasm::kF32: {
1895 float f32_value = 0;
1896 if (!ToF32(value, context, &f32_value)) {
1897 return js_api_scope.AssertException();
1899 global_obj->SetF32(f32_value);
1902 case i::wasm::kF64: {
1903 double f64_value = 0;
1904 if (!ToF64(value, context, &f64_value)) {
1905 return js_api_scope.AssertException();
1907 global_obj->SetF64(f64_value);
1911 if (info.Length() < 2) {
1912 thrower.TypeError(
"Non-defaultable global needs initial value");
1916 case i::wasm::kRefNull: {
1919 if (info.Length() < 2) {
1920 value_handle = DefaultReferenceValue(i_isolate, type);
1923 const char* error_message;
1927 DCHECK(!type.has_index());
1928 i::wasm::CanonicalValueType canonical_type{type};
1929 if (!i::wasm::JSToWasmObject(i_isolate, value_handle, canonical_type,
1931 .ToHandle(&value_handle)) {
1932 thrower.TypeError(
"%s", error_message);
1936 global_obj->SetRef(value_handle);
1939 case i::wasm::kS128: {
1941 "A global of type 'v128' cannot be created in JavaScript");
1947 case i::wasm::kVoid:
1949 case i::wasm::kBottom:
1954 info.GetReturnValue().Set(Utils::ToLocal(global_js_object));
1959uint32_t GetIterableLength(
i::Isolate* isolate, Local<Context> context,
1960 Local<Object> iterable) {
1961 Local<String> length = Utils::ToLocal(isolate->factory()->length_string());
1962 MaybeLocal<Value>
property = iterable->Get(context, length);
1964 MaybeLocal<Uint32> number =
property.ToLocalChecked()->ToArrayIndex(context);
1967 return number.ToLocalChecked()->Value();
1974 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Tag()"};
1975 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
1977 if (!info.IsConstructCall()) {
1978 thrower.TypeError(
"WebAssembly.Tag must be invoked with 'new'");
1982 thrower.TypeError(
"Argument 0 must be a tag type");
1987 Local<Context> context = isolate->GetCurrentContext();
1988 auto enabled_features = WasmEnabledFeatures::FromIsolate(i_isolate);
1991 Local<String> parameters_key = v8_str(isolate,
"parameters");
1993 event_type->Get(context, parameters_key);
1995 if (!parameters_maybe.
ToLocal(¶meters_value) ||
1996 !parameters_value->IsObject()) {
1997 thrower.TypeError(
"Argument 0 must be a tag type with 'parameters'");
2000 Local<Object> parameters = parameters_value.
As<Object>();
2001 uint32_t parameters_len = GetIterableLength(i_isolate, context, parameters);
2003 thrower.TypeError(
"Argument 0 contains parameters without 'length'");
2006 if (parameters_len > i::wasm::kV8MaxWasmFunctionParams) {
2007 thrower.TypeError(
"Argument 0 contains too many parameters");
2012 std::vector<i::wasm::ValueType> param_types(parameters_len,
2013 i::wasm::kWasmVoid);
2014 for (uint32_t
i = 0;
i < parameters_len; ++
i) {
2015 i::wasm::ValueType& type = param_types[
i];
2016 MaybeLocal<Value> maybe = parameters->Get(context,
i);
2017 std::optional<i::wasm::ValueType> maybe_type =
2018 GetValueType(isolate, maybe, context, enabled_features);
2019 if (!maybe_type)
return;
2021 if (type == i::wasm::kWasmVoid) {
2023 "Argument 0 parameter type at index #%u must be a value type",
i);
2027 const i::wasm::FunctionSig
sig{0, parameters_len, param_types.data()};
2030 auto tag = i::WasmExceptionTag::New(i_isolate, 0);
2032 i::wasm::CanonicalTypeIndex type_index =
2033 i::wasm::GetWasmEngine()->type_canonicalizer()->AddRecursiveGroup(&sig);
2036 i::WasmTagObject::New(i_isolate, &sig, type_index, tag,
2038 info.GetReturnValue().Set(Utils::ToLocal(tag_object));
2044 auto serialized_sig = tag_object->serialized_signature();
2045 i::wasm::WasmTagSig
sig{
2046 0,
static_cast<size_t>(serialized_sig->length()),
2047 reinterpret_cast<i::wasm::ValueType*
>(serialized_sig->begin())};
2048 return i::WasmExceptionPackage::GetEncodedSize(&sig);
2056 Local<Context> context = isolate->GetCurrentContext();
2058 if (!arg->IsObject()) {
2059 thrower->TypeError(
"Exception values must be an iterable object");
2063 auto values = arg.As<Object>();
2064 uint32_t length = GetIterableLength(i_isolate, context, values);
2066 thrower->TypeError(
"Exception values argument has no length");
2069 if (length !=
static_cast<uint32_t
>(signature->length())) {
2071 "Number of exception values does not match signature length");
2074 for (
int i = 0;
i < signature->
length(); ++
i) {
2076 if (!values->Get(context,
i).ToLocal(&value))
return false;
2077 i::wasm::ValueType type = signature->get(
i);
2078 switch (type.kind()) {
2079 case i::wasm::kI32: {
2081 if (!ToI32(value, context, &i32))
return false;
2085 case i::wasm::kI64: {
2087 if (!ToI64(value, context, &i64))
return false;
2091 case i::wasm::kF32: {
2093 if (!ToF32(value, context, &f32))
return false;
2098 case i::wasm::kF64: {
2100 if (!ToF64(value, context, &f64))
return false;
2106 case i::wasm::kRefNull: {
2107 const char* error_message;
2110 i::wasm::CanonicalValueType canonical_type = i::wasm::kWasmBottom;
2111 if (type.has_index()) {
2114 DCHECK(tag_object->has_trusted_data());
2116 tag_object->trusted_data(i_isolate);
2117 const i::wasm::WasmModule* module = wtid->module();
2119 type.Canonicalize(module->canonical_type_id(type.ref_index()));
2121 canonical_type = i::wasm::CanonicalValueType{type};
2123 if (!i::wasm::JSToWasmObject(i_isolate, value_handle, canonical_type,
2125 .ToHandle(&value_handle)) {
2126 thrower->TypeError(
"%s", error_message);
2129 values_out->set(index++, *value_handle);
2132 case i::wasm::kS128:
2133 thrower->TypeError(
"Invalid type v128");
2138 case i::wasm::kVoid:
2140 case i::wasm::kBottom:
2150 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Exception()"};
2151 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
2153 if (!info.IsConstructCall()) {
2154 thrower.TypeError(
"WebAssembly.Exception must be invoked with 'new'");
2158 thrower.TypeError(
"Argument 0 must be a WebAssembly tag");
2163 thrower.TypeError(
"Argument 0 must be a WebAssembly tag");
2170 if (*tag == js_tag->tag()) {
2171 thrower.TypeError(
"Argument 0 cannot be WebAssembly.JSTag");
2174 const i::wasm::CanonicalSig*
sig =
2175 i::wasm::GetTypeCanonicalizer()->LookupFunctionSignature(
2176 i::wasm::CanonicalTypeIndex{
2177 static_cast<uint32_t
>(tag_object->canonical_type_index())});
2179 if (
sig->return_count() != 0) {
2181 "Invalid WebAssembly tag (return values not permitted in Exception "
2186 uint32_t size = GetEncodedSize(tag_object);
2188 i::WasmExceptionPackage::New(i_isolate, tag, size);
2192 i_isolate, runtime_exception));
2194 tag_object->serialized_signature(), i_isolate);
2195 if (!EncodeExceptionValues(isolate, signature, tag_object, info[1], &thrower,
2197 return js_api_scope.AssertException();
2202 thrower.TypeError(
"Argument 2 is not an object");
2206 Local<Context> context = isolate->GetCurrentContext();
2208 Local<String> trace_stack_key = v8_str(isolate,
"traceStack");
2210 if (!trace_stack_obj->Get(context, trace_stack_key)
2211 .ToLocal(&trace_stack_value)) {
2212 return js_api_scope.AssertException();
2214 if (trace_stack_value->BooleanValue(isolate)) {
2218 if (!i::ErrorUtils::CaptureStackTrace(i_isolate, runtime_exception,
2220 .ToHandle(&capture_result)) {
2221 return js_api_scope.AssertException();
2226 info.GetReturnValue().Set(
2232 ErrorThrower& thrower) {
2234 data->instance_data(), i_isolate};
2235 int func_index = data->function_index();
2236 const i::wasm::WasmModule* module = trusted_instance_data->module();
2237 i::wasm::ModuleTypeIndex sig_index =
module->functions[func_index].sig_index;
2238 const i::wasm::CanonicalSig*
sig =
2239 i::wasm::GetTypeCanonicalizer()->LookupFunctionSignature(
2240 module->canonical_sig_id(sig_index));
2254 trusted_instance_data->managed_object_maps()->get(sig_index.index)),
2257 int num_imported_functions =
module->num_imported_functions;
2259 if (func_index >= num_imported_functions) {
2260 implicit_arg = trusted_instance_data;
2264 trusted_instance_data->dispatch_table_for_imports()->implicit_arg(
2270 i_isolate->
factory()->NewWasmInternalFunction(implicit_arg, func_index);
2272 i_isolate->
factory()->NewWasmFuncRef(internal, rtt);
2273 internal->set_call_target(trusted_instance_data->GetCallTarget(func_index));
2274 if (func_index < num_imported_functions) {
2279 i_isolate, trusted_instance_data, func_ref, internal,
2280 static_cast<int>(data->sig()->parameter_count()), wrapper);
2286 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Function()"};
2287 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
2289 if (!info.IsConstructCall()) {
2290 thrower.TypeError(
"WebAssembly.Function must be invoked with 'new'");
2294 thrower.TypeError(
"Argument 0 must be a function type");
2298 Local<Context> context = isolate->GetCurrentContext();
2299 auto enabled_features = WasmEnabledFeatures::FromIsolate(i_isolate);
2302 Local<String> parameters_key = v8_str(isolate,
"parameters");
2304 function_type->Get(context, parameters_key);
2306 if (!parameters_maybe.
ToLocal(¶meters_value) ||
2307 !parameters_value->IsObject()) {
2308 thrower.TypeError(
"Argument 0 must be a function type with 'parameters'");
2311 Local<Object> parameters = parameters_value.
As<Object>();
2312 uint32_t parameters_len = GetIterableLength(i_isolate, context, parameters);
2314 thrower.TypeError(
"Argument 0 contains parameters without 'length'");
2317 if (parameters_len > i::wasm::kV8MaxWasmFunctionParams) {
2318 thrower.TypeError(
"Argument 0 contains too many parameters");
2324 if (!function_type->Get(context, v8_str(isolate,
"results"))
2326 return js_api_scope.AssertException();
2328 if (!results_value->IsObject()) {
2329 thrower.TypeError(
"Argument 0 must be a function type with 'results'");
2332 Local<Object> results = results_value.
As<Object>();
2333 uint32_t results_len = GetIterableLength(i_isolate, context, results);
2335 thrower.TypeError(
"Argument 0 contains results without 'length'");
2338 if (results_len > i::wasm::kV8MaxWasmFunctionReturns) {
2339 thrower.TypeError(
"Argument 0 contains too many results");
2345 i::wasm::FunctionSig::Builder builder(&zone, results_len, parameters_len);
2346 for (uint32_t
i = 0;
i < parameters_len; ++
i) {
2347 MaybeLocal<Value> maybe = parameters->Get(context,
i);
2348 std::optional<i::wasm::ValueType> maybe_type =
2349 GetValueType(isolate, maybe, context, enabled_features);
2350 if (!maybe_type)
return;
2351 i::wasm::ValueType type = *maybe_type;
2352 if (type == i::wasm::kWasmVoid) {
2354 "Argument 0 parameter type at index #%u must be a value type",
i);
2357 builder.AddParam(type);
2359 for (uint32_t
i = 0;
i < results_len; ++
i) {
2360 MaybeLocal<Value> maybe = results->Get(context,
i);
2361 std::optional<i::wasm::ValueType> maybe_type =
2362 GetValueType(isolate, maybe, context, enabled_features);
2363 if (!maybe_type)
return js_api_scope.AssertException();
2364 i::wasm::ValueType type = *maybe_type;
2365 if (type == i::wasm::kWasmVoid) {
2367 "Argument 0 result type at index #%u must be a value type",
i);
2370 builder.AddReturn(type);
2374 thrower.TypeError(
"Argument 1 must be a function");
2377 const i::wasm::FunctionSig*
sig = builder.Get();
2378 i::wasm::Suspend suspend = i::wasm::kNoSuspend;
2382 if (i::IsWasmSuspendingObject(*callable)) {
2383 suspend = i::wasm::kSuspend;
2386 DCHECK(i::IsCallable(*callable));
2387 }
else if (!i::IsCallable(*callable)) {
2388 thrower.TypeError(
"Argument 1 must be a function");
2393 i::WasmJSFunction::New(i_isolate, sig, callable, suspend);
2394 info.GetReturnValue().Set(Utils::ToLocal(
result));
2399 WasmJSApiScope js_api_scope{
info,
"WebAssembly.promising()"};
2400 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
2403 if (!info[0]->IsFunction()) {
2404 thrower.TypeError(
"Argument 0 must be a function");
2410 if (!i::WasmExportedFunction::IsWasmExportedFunction(*callable)) {
2411 thrower.TypeError(
"Argument 0 must be a WebAssembly exported function");
2416 wasm_exported_function->shared()->wasm_exported_function_data(),
2418 if (data->instance_data()->module_object()->is_asm_js()) {
2419 thrower.TypeError(
"Argument 0 must be a WebAssembly exported function");
2423 NewPromisingWasmExportedFunction(i_isolate, data, thrower);
2428void WebAssemblySuspendingImpl(
2430 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Suspending()"};
2431 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
2434 if (!info.IsConstructCall()) {
2435 thrower.TypeError(
"WebAssembly.Suspending must be invoked with 'new'");
2438 if (!info[0]->IsFunction()) {
2439 thrower.TypeError(
"Argument 0 must be a function");
2446 if (i::WasmExportedFunction::IsWasmExportedFunction(*callable) ||
2447 i::WasmJSFunction::IsWasmJSFunction(*callable)) {
2448 thrower.TypeError(
"Argument 0 must not be a WebAssembly function");
2453 i::WasmSuspendingObject::New(i_isolate, callable);
2459 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Function.type()"};
2460 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
2465 if (i::WasmExportedFunction::IsWasmExportedFunction(*fun)) {
2468 wasm_exported_function->shared()->wasm_exported_function_data();
2476 const i::wasm::FunctionSig*
sig =
2477 data->instance_data()->module()->functions[data->function_index()].sig;
2478 i::wasm::Promise promise_flags =
2479 i::WasmFunctionData::PromiseField::decode(data->js_promise_flags());
2480 if (promise_flags == i::wasm::kPromise) {
2483 size_t param_count =
sig->parameter_count();
2484 i::wasm::FunctionSig::Builder builder(&zone, 1, param_count);
2485 for (
size_t i = 0;
i < param_count; ++
i) {
2486 builder.AddParam(
sig->GetParam(
i));
2488 builder.AddReturn(i::wasm::kWasmExternRef);
2489 sig = builder.Get();
2491 type = i::wasm::GetTypeForFunction(i_isolate, sig);
2492 }
else if (i::WasmJSFunction::IsWasmJSFunction(*fun)) {
2495 ->wasm_js_function_data()
2500 for (i::wasm::CanonicalValueType t :
sig->all()) {
2504 static_assert(
sizeof(i::wasm::ValueType) ==
2505 sizeof(i::wasm::CanonicalValueType));
2506 type = i::wasm::GetTypeForFunction(
2507 i_isolate,
reinterpret_cast<const i::wasm::FunctionSig*
>(sig));
2509 thrower.TypeError(
"Receiver must be a WebAssembly.Function");
2513 info.GetReturnValue().Set(Utils::ToLocal(type));
2516constexpr const char* kName_WasmGlobalObject =
"WebAssembly.Global";
2517constexpr const char* kName_WasmMemoryObject =
"WebAssembly.Memory";
2518constexpr const char* kName_WasmMemoryMapDescriptor =
2519 "WebAssembly.MemoryMapDescriptor";
2520constexpr const char* kName_WasmInstanceObject =
"WebAssembly.Instance";
2521constexpr const char* kName_WasmTableObject =
"WebAssembly.Table";
2522constexpr const char* kName_WasmTagObject =
"WebAssembly.Tag";
2523constexpr const char* kName_WasmExceptionPackage =
"WebAssembly.Exception";
2525#define EXTRACT_THIS(var, WasmType) \
2526 i::DirectHandle<i::WasmType> var; \
2528 i::DirectHandle<i::Object> this_arg = \
2529 Utils::OpenDirectHandle(*info.This()); \
2530 if (!Is##WasmType(*this_arg)) { \
2531 thrower.TypeError("Receiver is not a %s", kName_##WasmType); \
2534 var = i::Cast<i::WasmType>(this_arg); \
2537void WebAssemblyInstanceGetExportsImpl(
2539 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Instance.exports()"};
2540 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
2545 info.GetReturnValue().Set(Utils::ToLocal(exports_object));
2548void WebAssemblyTableGetLengthImpl(
2550 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Table.length()"};
2551 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
2554 int length =
receiver->current_length();
2556 info.GetReturnValue().Set(
2557 AddressValueFromUnsigned(isolate,
receiver->address_type(), length));
2562 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Table.grow()"};
2563 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
2564 Local<Context> context = isolate->GetCurrentContext();
2567 std::optional<uint64_t> maybe_grow_by = AddressValueToU64(
2568 &thrower, context, info[0],
"Argument 0",
receiver->address_type());
2569 if (!maybe_grow_by)
return js_api_scope.AssertException();
2570 uint64_t grow_by = *maybe_grow_by;
2574 if (info.Length() >= 2) {
2576 const char* error_message;
2577 if (!i::WasmTableObject::JSToWasmElement(i_isolate,
receiver, init_value,
2579 .ToHandle(&init_value)) {
2580 thrower.TypeError(
"Argument 1 is invalid: %s", error_message);
2583 }
else if (
receiver->unsafe_type().is_non_nullable()) {
2585 "Argument 1 must be specified for non-nullable element type");
2588 init_value = DefaultReferenceValue(i_isolate,
receiver->unsafe_type());
2591 static_assert(i::wasm::kV8MaxWasmTableSize <=
i::kMaxUInt32);
2592 int old_size = grow_by > i::wasm::max_table_size()
2594 : i::WasmTableObject::Grow(i_isolate,
receiver,
2595 static_cast<uint32_t
>(grow_by),
2598 thrower.RangeError(
"failed to grow table by %" PRIu64, grow_by);
2601 info.GetReturnValue().Set(
2602 AddressValueFromUnsigned(isolate,
receiver->address_type(), old_size));
2608 i::wasm::ValueType type,
i::Isolate* isolate, ErrorThrower* thrower) {
2609 switch (type.heap_type().representation()) {
2611 thrower->TypeError(
"%s",
"stringview_wtf8 has no JS representation");
2614 thrower->TypeError(
"%s",
"stringview_wtf16 has no JS representation");
2617 thrower->TypeError(
"%s",
"stringview_iter has no JS representation");
2623 thrower->TypeError(
"invalid type %s", type.name().c_str());
2626 return_value.
Set(Utils::ToLocal(i::wasm::WasmToJSObject(isolate, value)));
2634 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Table.get()"};
2635 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
2636 Local<Context> context = isolate->GetCurrentContext();
2639 std::optional<uint64_t> maybe_address = AddressValueToU64(
2640 &thrower, context, info[0],
"Argument 0",
receiver->address_type());
2641 if (!maybe_address)
return;
2642 uint64_t address = *maybe_address;
2645 !
receiver->is_in_bounds(
static_cast<uint32_t
>(address))) {
2646 thrower.RangeError(
"invalid address %" PRIu64
" in %s table of size %d",
2647 address,
receiver->unsafe_type().name().c_str(),
2653 i_isolate,
receiver,
static_cast<uint32_t
>(address));
2656 if (!WasmObjectToJSReturnValue(return_value,
result,
receiver->unsafe_type(),
2657 i_isolate, &thrower)) {
2658 return js_api_scope.AssertException();
2664 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Table.set()"};
2665 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
2666 Local<Context> context = isolate->GetCurrentContext();
2669 std::optional<uint64_t> maybe_address = AddressValueToU64(
2670 &thrower, context, info[0],
"Argument 0", table_object->address_type());
2671 if (!maybe_address)
return js_api_scope.AssertException();
2672 uint64_t address = *maybe_address;
2675 !table_object->is_in_bounds(
static_cast<uint32_t
>(address))) {
2676 thrower.RangeError(
"invalid address %" PRIu64
" in %s table of size %d",
2677 address, table_object->unsafe_type().name().c_str(),
2678 table_object->current_length());
2683 if (info.Length() >= 2) {
2685 const char* error_message;
2686 if (!i::WasmTableObject::JSToWasmElement(i_isolate, table_object, element,
2688 .ToHandle(&element)) {
2689 thrower.TypeError(
"Argument 1 is invalid for table: %s", error_message);
2692 }
else if (table_object->unsafe_type().is_defaultable()) {
2693 element = DefaultReferenceValue(i_isolate, table_object->unsafe_type());
2695 thrower.TypeError(
"Table of non-defaultable type %s needs explicit element",
2696 table_object->unsafe_type().name().c_str());
2700 i::WasmTableObject::Set(i_isolate, table_object,
2701 static_cast<uint32_t
>(address), element);
2706 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Table.type()"};
2707 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
2709 std::optional<uint64_t> max_size = table->maximum_length_u64();
2710 auto type = i::wasm::GetTypeForTable(i_isolate, table->unsafe_type(),
2711 table->current_length(), max_size,
2712 table->address_type());
2713 info.GetReturnValue().Set(Utils::ToLocal(type));
2717void WebAssemblyMemoryMapDescriptorMapImpl(
2720 WasmJSApiScope js_api_scope{
info,
"WebAssembly.MemoryMapDescriptor.map()"};
2721 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
2727 if (!i::IsWasmMemoryObject(*memory_param)) {
2728 thrower.TypeError(
"Parameter is not a WebAssembly.Memory");
2729 return js_api_scope.AssertException();
2734 Local<Context> context = isolate->GetCurrentContext();
2735 std::optional<uint32_t>
offset =
2736 EnforceUint32(
"Argument 1", info[1], context, &thrower);
2737 if (!
offset.has_value()) {
2738 return js_api_scope.AssertException();
2740 size_t mapped_size =
receiver->MapDescriptor(memory,
offset.value());
2742 thrower.RuntimeError(
2743 "Failed to map the MemoryMapDescriptor to WebAssembly memory.");
2744 return js_api_scope.AssertException();
2748 receiver->set_size(
static_cast<uint32_t
>(mapped_size));
2749 info.GetReturnValue().Set(
static_cast<int64_t
>(mapped_size));
2753void WebAssemblyMemoryMapDescriptorUnmapImpl(
2756 WasmJSApiScope js_api_scope{
info,
"WebAssembly.MemoryMapDescriptor.unmap()"};
2757 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
2760 if (!
receiver->UnmapDescriptor()) {
2761 thrower.RangeError(
"Failed to unmap the MemoryMapDescriptor.");
2767void WebAssemblyMemoryGrowImpl(
2769 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Memory.grow()"};
2770 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
2771 Local<Context> context = isolate->GetCurrentContext();
2774 std::optional<uint64_t> maybe_delta_pages = AddressValueToU64(
2775 &thrower, context, info[0],
"Argument 0",
receiver->address_type());
2776 if (!maybe_delta_pages)
return js_api_scope.AssertException();
2777 uint64_t delta_pages = *maybe_delta_pages;
2782 uint64_t old_pages = old_buffer->GetByteLength() / i::wasm::kWasmPageSize;
2783 uint64_t max_pages =
receiver->maximum_pages();
2785 if (delta_pages > max_pages - old_pages) {
2786 thrower.RangeError(
"Maximum memory size exceeded");
2790 static_assert(i::wasm::kV8MaxWasmMemory64Pages <=
i::kMaxUInt32);
2792 static_cast<uint32_t
>(delta_pages));
2794 thrower.RangeError(
"Unable to grow instance memory");
2797 info.GetReturnValue().Set(
2798 AddressValueFromUnsigned(isolate,
receiver->address_type(), ret));
2802void WebAssemblyMemoryGetBufferImpl(
2804 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Memory.buffer"};
2805 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
2809 DCHECK(IsJSArrayBuffer(*buffer_obj));
2812 if (buffer->is_shared()) {
2818 if (!
result.FromJust()) {
2820 "Status of setting SetIntegrityLevel of buffer is false.");
2824 info.GetReturnValue().Set(Utils::ToLocal(buffer));
2828void WebAssemblyMemoryToFixedLengthBufferImpl(
2830 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Memory.toFixedLengthBuffer()"};
2831 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
2835 DCHECK(IsJSArrayBuffer(*buffer_obj));
2838 if (buffer->is_resizable_by_js()) {
2839 buffer = i::WasmMemoryObject::ToFixedLengthBuffer(i_isolate,
receiver);
2841 if (buffer->is_shared()) {
2844 if (!
result.FromJust()) {
2846 "Status of setting SetIntegrityLevel of buffer is false.");
2851 return_value.
Set(Utils::ToLocal(buffer));
2855void WebAssemblyMemoryToResizableBufferImpl(
2857 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Memory.toResizableBuffer()"};
2858 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
2862 DCHECK(IsJSArrayBuffer(*buffer_obj));
2865 if (!buffer->is_resizable_by_js()) {
2866 if (!
receiver->has_maximum_pages()) {
2867 thrower.TypeError(
"Memory must have a maximum");
2870 buffer = i::WasmMemoryObject::ToResizableBuffer(i_isolate,
receiver);
2872 if (buffer->is_shared()) {
2875 if (!
result.FromJust()) {
2877 "Status of setting SetIntegrityLevel of buffer is false.");
2882 return_value.
Set(Utils::ToLocal(buffer));
2887 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Memory.type()"};
2888 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
2892 size_t curr_size = buffer->GetByteLength() / i::wasm::kWasmPageSize;
2893 DCHECK_LE(curr_size, std::numeric_limits<uint32_t>::max());
2894 uint32_t min_size =
static_cast<uint32_t
>(curr_size);
2895 std::optional<uint32_t> max_size;
2896 if (memory->has_maximum_pages()) {
2897 uint64_t max_size64 = memory->maximum_pages();
2898 DCHECK_LE(max_size64, std::numeric_limits<uint32_t>::max());
2899 max_size.emplace(
static_cast<uint32_t
>(max_size64));
2901 bool shared = buffer->is_shared();
2902 auto type = i::wasm::GetTypeForMemory(i_isolate, min_size, max_size, shared,
2903 memory->address_type());
2904 info.GetReturnValue().Set(Utils::ToLocal(type));
2909 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Tag.type()"};
2910 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
2913 int n = tag->serialized_signature()->length();
2914 std::vector<i::wasm::ValueType>
data(n);
2916 tag->serialized_signature()->copy_out(0, data.data(), n);
2918 const i::wasm::FunctionSig
sig{0, data.size(), data.data()};
2919 constexpr bool kForException =
true;
2920 auto type = i::wasm::GetTypeForFunction(i_isolate, &sig, kForException);
2921 info.GetReturnValue().Set(Utils::ToLocal(type));
2924void WebAssemblyExceptionGetArgImpl(
2926 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Exception.getArg()"};
2927 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
2931 if (!GetFirstArgumentAsTag(info, &thrower).ToHandle(&tag_object)) {
2932 return js_api_scope.AssertException();
2934 Local<Context> context = isolate->GetCurrentContext();
2935 std::optional<uint32_t> maybe_index =
2936 EnforceUint32(
"Index", info[1], context, &thrower);
2937 if (!maybe_index)
return js_api_scope.AssertException();
2938 uint32_t index = *maybe_index;
2940 i::WasmExceptionPackage::GetExceptionValues(i_isolate, exception);
2943 i::WasmExceptionPackage::GetExceptionTag(i_isolate, exception);
2944 DCHECK(IsWasmExceptionTag(*this_tag));
2945 if (tag_object->tag() != *this_tag) {
2946 thrower.TypeError(
"First argument does not match the exception tag");
2950 DCHECK(!IsUndefined(*maybe_values));
2952 auto signature = tag_object->serialized_signature();
2953 if (index >=
static_cast<uint32_t
>(signature->length())) {
2954 thrower.RangeError(
"Index out of range");
2958 uint32_t decode_index = 0;
2960 for (
int i = 0; i < static_cast<int>(index); ++
i) {
2961 switch (signature->get(
i).kind()) {
2971 case i::wasm::kRefNull:
2974 case i::wasm::kS128:
2980 case i::wasm::kVoid:
2982 case i::wasm::kBottom:
2988 switch (signature->get(index).kind()) {
2989 case i::wasm::kI32: {
2990 uint32_t u32_bits = 0;
2996 case i::wasm::kI64: {
2997 uint64_t u64_bits = 0;
2999 int64_t i64 =
static_cast<int64_t
>(u64_bits);
3003 case i::wasm::kF32: {
3004 uint32_t f32_bits = 0;
3010 case i::wasm::kF64: {
3011 uint64_t f64_bits = 0;
3018 case i::wasm::kRefNull: {
3020 ReturnValue<Value> return_value = info.GetReturnValue();
3021 if (!WasmObjectToJSReturnValue(return_value, obj, signature->get(index),
3022 i_isolate, &thrower)) {
3023 return js_api_scope.AssertException();
3027 case i::wasm::kS128:
3028 thrower.TypeError(
"Invalid type v128");
3033 case i::wasm::kVoid:
3035 case i::wasm::kBottom:
3038 info.GetReturnValue().Set(
result);
3041void WebAssemblyExceptionIsImpl(
3043 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Exception.is()"};
3044 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
3047 auto tag = i::WasmExceptionPackage::GetExceptionTag(i_isolate, exception);
3048 DCHECK(IsWasmExceptionTag(*tag));
3051 if (!GetFirstArgumentAsTag(info, &thrower).ToHandle(&tag_object)) {
3052 return js_api_scope.AssertException();
3054 info.GetReturnValue().Set(tag_object->tag() == *tag);
3057void WebAssemblyGlobalGetValueCommon(WasmJSApiScope& js_api_scope) {
3058 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
3059 auto& info = js_api_scope.callback_info();
3068 case i::wasm::kI64: {
3070 return_value.
Set(value);
3079 case i::wasm::kS128:
3080 thrower.TypeError(
"Can't get the value of s128 WebAssembly.Global");
3083 case i::wasm::kRefNull:
3084 if (!WasmObjectToJSReturnValue(return_value,
receiver->GetRef(),
3085 receiver->type(), i_isolate, &thrower)) {
3086 return js_api_scope.AssertException();
3093 case i::wasm::kBottom:
3094 case i::wasm::kVoid:
3100void WebAssemblyGlobalValueOfImpl(
3102 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Global.valueOf()"};
3103 return WebAssemblyGlobalGetValueCommon(js_api_scope);
3107void WebAssemblyGlobalGetValueImpl(
3109 WasmJSApiScope js_api_scope{
info,
"get WebAssembly.Global.value)"};
3110 return WebAssemblyGlobalGetValueCommon(js_api_scope);
3114void WebAssemblyGlobalSetValueImpl(
3116 WasmJSApiScope js_api_scope{
info,
"set WebAssembly.Global.value)"};
3117 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
3121 thrower.TypeError(
"Can't set the value of an immutable global.");
3124 if (info.Length() == 0) {
3125 thrower.TypeError(
"Argument 0 is required");
3129 Local<Context> context = isolate->GetCurrentContext();
3131 case i::wasm::kI32: {
3133 if (!info[0]->Int32Value(context).To(&i32_value)) {
3134 return js_api_scope.AssertException();
3139 case i::wasm::kI64: {
3141 if (!info[0]->ToBigInt(context).
ToLocal(&bigint_value)) {
3142 return js_api_scope.AssertException();
3144 receiver->SetI64(bigint_value->Int64Value());
3147 case i::wasm::kF32: {
3148 double f64_value = 0;
3149 if (!info[0]->NumberValue(context).To(&f64_value)) {
3150 return js_api_scope.AssertException();
3155 case i::wasm::kF64: {
3156 double f64_value = 0;
3157 if (!info[0]->NumberValue(context).To(&f64_value)) {
3158 return js_api_scope.AssertException();
3163 case i::wasm::kS128:
3164 thrower.TypeError(
"Can't set the value of s128 WebAssembly.Global");
3167 case i::wasm::kRefNull: {
3168 const i::wasm::WasmModule* module =
3170 ?
receiver->trusted_data(i_isolate)->module()
3173 const char* error_message;
3174 if (!i::wasm::JSToWasmObject(i_isolate, module, value,
receiver->type(),
3176 .ToHandle(&value)) {
3177 thrower.TypeError(
"%s", error_message);
3187 case i::wasm::kBottom:
3188 case i::wasm::kVoid:
3195 WasmJSApiScope js_api_scope{
info,
"WebAssembly.Global.type())"};
3196 auto [
isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
3199 auto type = i::wasm::GetTypeForGlobal(i_isolate, global->is_mutable(),
3201 info.GetReturnValue().Set(Utils::ToLocal(type));
3211#define DEF_WASM_JS_EXTERNAL_REFERENCE(Name) \
3212 void Name(const v8::FunctionCallbackInfo<v8::Value>& info) { \
3216#undef DEF_WASM_JS_EXTERNAL_REFERENCE
3230 isolate, func, {}, {}, 0, behavior, side_effect_type);
3231 if (has_prototype) templ->ReadOnlyPrototype();
3245DirectHandle<JSFunction> CreateFunc(
3246 Isolate* isolate, DirectHandle<String> name, FunctionCallback func,
3248 SideEffectType side_effect_type = SideEffectType::kHasSideEffect,
3249 DirectHandle<FunctionTemplateInfo> parent = {}) {
3250 DirectHandle<FunctionTemplateInfo> temp =
3253 if (!parent.is_null()) {
3255 FunctionTemplateInfo::SetParentTemplate(isolate, temp, parent);
3258 DirectHandle<JSFunction> function =
3259 ApiNatives::InstantiateFunction(isolate, temp, name).ToHandleChecked();
3260 DCHECK(function->shared()->HasSharedName());
3264DirectHandle<JSFunction> InstallFunc(
3265 Isolate* isolate, DirectHandle<JSObject>
object, DirectHandle<String> name,
3266 FunctionCallback func,
int length,
bool has_prototype =
false,
3267 PropertyAttributes attributes = NONE,
3268 SideEffectType side_effect_type = SideEffectType::kHasSideEffect) {
3269 DirectHandle<JSFunction> function =
3270 CreateFunc(isolate, name, func, has_prototype, side_effect_type);
3271 function->shared()->set_length(length);
3272 CHECK(!JSObject::HasRealNamedProperty(isolate,
object, name).FromMaybe(
true));
3273 CHECK(object->map()->is_extensible());
3274 JSObject::AddProperty(isolate,
object, name, function, attributes);
3278DirectHandle<JSFunction> InstallFunc(
3279 Isolate* isolate, DirectHandle<JSObject>
object,
const char* str,
3280 FunctionCallback func,
int length,
bool has_prototype =
false,
3281 PropertyAttributes attributes = NONE,
3282 SideEffectType side_effect_type = SideEffectType::kHasSideEffect) {
3283 DirectHandle<String> name = v8_str(isolate, str);
3284 return InstallFunc(isolate,
object, name, func, length, has_prototype,
3285 attributes, side_effect_type);
3288DirectHandle<JSFunction> InstallConstructorFunc(Isolate* isolate,
3289 DirectHandle<JSObject>
object,
3291 FunctionCallback func) {
3292 return InstallFunc(isolate,
object, str, func, 1,
true, DONT_ENUM,
3293 SideEffectType::kHasNoSideEffect);
3296DirectHandle<String> GetterName(Isolate* isolate, DirectHandle<String> name) {
3297 return Name::ToFunctionName(isolate, name, isolate->factory()->get_string())
3301void InstallGetter(Isolate* isolate, DirectHandle<JSObject>
object,
3302 const char* str, FunctionCallback func) {
3303 DirectHandle<String> name = v8_str(isolate, str);
3304 DirectHandle<JSFunction> function =
3305 CreateFunc(isolate, GetterName(isolate, name), func,
false,
3306 SideEffectType::kHasNoSideEffect);
3308 Utils::ToLocal(
object)->SetAccessorProperty(Utils::ToLocal(name),
3309 Utils::ToLocal(function),
3313DirectHandle<String> SetterName(Isolate* isolate, DirectHandle<String> name) {
3314 return Name::ToFunctionName(isolate, name, isolate->factory()->set_string())
3318void InstallGetterSetter(Isolate* isolate, DirectHandle<JSObject>
object,
3319 const char* str, FunctionCallback
getter,
3320 FunctionCallback
setter) {
3321 DirectHandle<String> name = v8_str(isolate, str);
3322 DirectHandle<JSFunction> getter_func =
3323 CreateFunc(isolate, GetterName(isolate, name),
getter,
false,
3324 SideEffectType::kHasNoSideEffect);
3325 DirectHandle<JSFunction> setter_func =
3326 CreateFunc(isolate, SetterName(isolate, name),
setter,
false);
3327 setter_func->shared()->set_length(1);
3329 Utils::ToLocal(
object)->SetAccessorProperty(
3330 Utils::ToLocal(name), Utils::ToLocal(getter_func),
3331 Utils::ToLocal(setter_func),
v8::None);
3338void SetDummyInstanceTemplate(Isolate* isolate, DirectHandle<JSFunction> fun) {
3339 DirectHandle<ObjectTemplateInfo> instance_template =
3341 FunctionTemplateInfo::SetInstanceTemplate(
3342 isolate,
direct_handle(fun->shared()->api_func_data(), isolate),
3346DirectHandle<JSObject> SetupConstructor(Isolate* isolate,
3347 DirectHandle<JSFunction> constructor,
3348 InstanceType instance_type,
3350 const char* name =
nullptr,
3351 int in_object_properties = 0) {
3352 SetDummyInstanceTemplate(isolate, constructor);
3353 JSFunction::EnsureHasInitialMap(constructor);
3354 DirectHandle<JSObject> proto(
3355 Cast<JSObject>(constructor->instance_prototype()), isolate);
3356 DirectHandle<Map> map = isolate->factory()->NewContextfulMap(
3357 constructor, instance_type, instance_size, TERMINAL_FAST_ELEMENTS_KIND,
3358 in_object_properties);
3359 JSFunction::SetInitialMap(isolate, constructor, map, proto);
3363 JSObject::AddProperty(isolate, proto,
3364 isolate->factory()->to_string_tag_symbol(),
3365 v8_str(isolate, name), ro_attributes);
3370constexpr wasm::ValueType kWasmExceptionTagParams[] = {
3371 wasm::kWasmExternRef,
3373constexpr wasm::FunctionSig kWasmExceptionTagSignature{
3374 0,
arraysize(kWasmExceptionTagParams), kWasmExceptionTagParams};
3378void WasmJs::PrepareForSnapshot(
Isolate* isolate) {
3387 Factory*
const f = isolate->factory();
3397 WebAssembly_string, Builtin::kIllegal, 0,
kDontAdapt);
3398 sfi->set_language_mode(LanguageMode::kStrict);
3402 JSFunction::SetPrototype(ctor, isolate->initial_object_prototype());
3403 webassembly = f->
NewJSObject(ctor, AllocationType::kOld);
3406 JSObject::AddProperty(isolate, webassembly, f->to_string_tag_symbol(),
3407 WebAssembly_string, ro_attributes);
3408 InstallFunc(isolate, webassembly,
"compile", wasm::WebAssemblyCompile, 1);
3409 InstallFunc(isolate, webassembly,
"validate", wasm::WebAssemblyValidate, 1);
3410 InstallFunc(isolate, webassembly,
"instantiate",
3411 wasm::WebAssemblyInstantiate, 1);
3415 InstallModule(isolate, webassembly);
3420 isolate, webassembly,
"Instance", wasm::WebAssemblyInstance);
3422 isolate, instance_constructor, WASM_INSTANCE_OBJECT_TYPE,
3423 WasmInstanceObject::kHeaderSize,
"WebAssembly.Instance");
3424 native_context->set_wasm_instance_constructor(*instance_constructor);
3425 InstallGetter(isolate, instance_proto,
"exports",
3426 wasm::WebAssemblyInstanceGetExports);
3432 isolate, webassembly,
"Table", wasm::WebAssemblyTable);
3434 SetupConstructor(isolate, table_constructor, WASM_TABLE_OBJECT_TYPE,
3435 WasmTableObject::kHeaderSize,
"WebAssembly.Table");
3437 InstallGetter(isolate, table_proto,
"length",
3438 wasm::WebAssemblyTableGetLength);
3439 InstallFunc(isolate, table_proto,
"grow", wasm::WebAssemblyTableGrow, 1);
3440 InstallFunc(isolate, table_proto,
"set", wasm::WebAssemblyTableSet, 1);
3441 InstallFunc(isolate, table_proto,
"get", wasm::WebAssemblyTableGet, 1,
3442 false,
NONE, SideEffectType::kHasNoSideEffect);
3448 isolate, webassembly,
"Memory", wasm::WebAssemblyMemory);
3450 SetupConstructor(isolate, memory_constructor, WASM_MEMORY_OBJECT_TYPE,
3451 WasmMemoryObject::kHeaderSize,
"WebAssembly.Memory");
3452 native_context->set_wasm_memory_constructor(*memory_constructor);
3453 InstallFunc(isolate, memory_proto,
"grow", wasm::WebAssemblyMemoryGrow, 1);
3454 InstallGetter(isolate, memory_proto,
"buffer",
3455 wasm::WebAssemblyMemoryGetBuffer);
3461 isolate, webassembly,
"Global", wasm::WebAssemblyGlobal);
3463 SetupConstructor(isolate, global_constructor, WASM_GLOBAL_OBJECT_TYPE,
3464 WasmGlobalObject::kHeaderSize,
"WebAssembly.Global");
3465 native_context->set_wasm_global_constructor(*global_constructor);
3466 InstallFunc(isolate, global_proto,
"valueOf",
3467 wasm::WebAssemblyGlobalValueOf, 0,
false,
NONE,
3468 SideEffectType::kHasNoSideEffect);
3469 InstallGetterSetter(isolate, global_proto,
"value",
3470 wasm::WebAssemblyGlobalGetValue,
3471 wasm::WebAssemblyGlobalSetValue);
3477 isolate, webassembly,
"Tag", wasm::WebAssemblyTag);
3478 SetupConstructor(isolate, tag_constructor, WASM_TAG_OBJECT_TYPE,
3479 WasmTagObject::kHeaderSize,
"WebAssembly.Tag");
3481 auto js_tag = WasmExceptionTag::New(isolate, 0);
3486 isolate, &kWasmExceptionTagSignature, kInitialCanonicalTypeIndex,
3489 JSObject::AddProperty(isolate, webassembly,
"JSTag", js_tag_object,
3496 isolate, webassembly,
"Exception", wasm::WebAssemblyException);
3497 SetDummyInstanceTemplate(isolate, exception_constructor);
3499 isolate, exception_constructor, WASM_EXCEPTION_PACKAGE_TYPE,
3500 WasmExceptionPackage::kSize,
"WebAssembly.Exception",
3501 WasmExceptionPackage::kInObjectFieldCount);
3502 InstallFunc(isolate, exception_proto,
"getArg",
3503 wasm::WebAssemblyExceptionGetArg, 2);
3504 InstallFunc(isolate, exception_proto,
"is", wasm::WebAssemblyExceptionIs,
3506 native_context->set_wasm_exception_constructor(*exception_constructor);
3510 Map::EnsureDescriptorSlack(isolate, initial_map, 2);
3513 isolate, f->wasm_exception_tag_symbol(),
3514 WasmExceptionPackage::kTagIndex,
DONT_ENUM, Representation::Tagged());
3515 initial_map->AppendDescriptor(isolate, &d);
3519 Descriptor::DataField(isolate, f->wasm_exception_values_symbol(),
3520 WasmExceptionPackage::kValuesIndex,
DONT_ENUM,
3521 Representation::Tagged());
3522 initial_map->AppendDescriptor(isolate, &d);
3529 isolate->sloppy_function_without_prototype_map();
3535 InstallError(isolate, webassembly, f->CompileError_string(),
3536 Context::WASM_COMPILE_ERROR_FUNCTION_INDEX);
3537 InstallError(isolate, webassembly, f->LinkError_string(),
3538 Context::WASM_LINK_ERROR_FUNCTION_INDEX);
3539 InstallError(isolate, webassembly, f->RuntimeError_string(),
3540 Context::WASM_RUNTIME_ERROR_FUNCTION_INDEX);
3550 if (
v8_flags.js_source_phase_imports) {
3552 intrinsic_abstract_module_source_interface_template =
3557 ApiNatives::AddDataProperty(
3558 isolate, intrinsic_abstract_module_source_interface_template,
3559 isolate->factory()->prototype_string(),
3560 abstract_module_source_prototype,
NONE);
3565 JSObject::HasRealNamedProperty(isolate, webassembly, name).ToChecked());
3567 module_constructor =
3568 CreateFunc(isolate, name, wasm::WebAssemblyModule,
true,
3569 SideEffectType::kHasNoSideEffect,
3570 intrinsic_abstract_module_source_interface_template);
3573 JSObject::ForceSetPrototype(
3574 isolate, module_constructor,
3577 module_constructor->shared()->set_length(1);
3578 JSObject::SetOwnPropertyIgnoreAttributes(webassembly, name,
3582 module_constructor = InstallConstructorFunc(isolate, webassembly,
"Module",
3583 wasm::WebAssemblyModule);
3585 SetupConstructor(isolate, module_constructor, WASM_MODULE_OBJECT_TYPE,
3586 WasmModuleObject::kHeaderSize,
"WebAssembly.Module");
3587 native_context->set_wasm_module_constructor(*module_constructor);
3589 InstallFunc(isolate, module_constructor,
"imports",
3590 wasm::WebAssemblyModuleImports, 1,
false,
NONE,
3591 SideEffectType::kHasNoSideEffect);
3592 InstallFunc(isolate, module_constructor,
"exports",
3593 wasm::WebAssemblyModuleExports, 1,
false,
NONE,
3594 SideEffectType::kHasNoSideEffect);
3595 InstallFunc(isolate, module_constructor,
"customSections",
3596 wasm::WebAssemblyModuleCustomSections, 2,
false,
NONE,
3597 SideEffectType::kHasNoSideEffect);
3605 if (
native_context->is_wasm_js_installed() != Smi::zero())
return;
3615 if (
v8_flags.js_source_phase_imports) {
3617 InstallModule(isolate, webassembly);
3636 JSObject::AddProperty(isolate, global, WebAssembly_string, webassembly,
3645 js_tag_object->set_canonical_type_index(
3646 wasm::GetWasmEngine()
3647 ->type_canonicalizer()
3648 ->AddRecursiveGroup(&kWasmExceptionTagSignature)
3652 if (
v8_flags.wasm_test_streaming) {
3653 isolate->set_wasm_streaming_callback(WasmStreamingCallbackForTesting);
3656 if (isolate->wasm_streaming_callback() !=
nullptr) {
3657 InstallFunc(isolate, webassembly,
"compileStreaming",
3658 WebAssemblyCompileStreaming, 1);
3659 InstallFunc(isolate, webassembly,
"instantiateStreaming",
3660 WebAssemblyInstantiateStreaming, 1);
3666 const auto enabled_features = wasm::WasmEnabledFeatures::FromFlags();
3668 if (enabled_features.has_type_reflection()) {
3672 if (enabled_features.has_memory_control()) {
3677 if (enabled_features.has_jspi()) {
3679 isolate->WasmInitJSPIFeature();
3680 InstallJSPromiseIntegration(isolate,
native_context, webassembly);
3682 }
else if (
v8_flags.stress_wasm_stack_switching) {
3685 isolate->WasmInitJSPIFeature();
3688 if (enabled_features.has_rab_integration()) {
3689 InstallResizableBufferIntegration(isolate,
native_context, webassembly);
3694void WasmJs::InstallConditionalFeatures(
Isolate* isolate,
3698 if (!webassembly->map()->is_extensible())
return;
3699 if (webassembly->map()->is_access_check_needed())
return;
3712 if (isolate->IsWasmJSPIRequested(context)) {
3713 if (context->is_wasm_jspi_installed() == Smi::zero()) {
3714 isolate->WasmInitJSPIFeature();
3715 if (InstallJSPromiseIntegration(isolate, context, webassembly) &&
3716 InstallTypeReflection(isolate, context, webassembly)) {
3717 context->set_is_wasm_jspi_installed(Smi::FromInt(1));
3725bool WasmJs::InstallJSPromiseIntegration(
Isolate* isolate,
3729 if (JSObject::HasRealNamedProperty(isolate, webassembly, suspender_string)
3734 if (JSObject::HasRealNamedProperty(isolate, webassembly, suspending_string)
3739 if (JSObject::HasRealNamedProperty(isolate, webassembly, promising_string)
3744 if (JSObject::HasRealNamedProperty(isolate, webassembly, suspend_error_string)
3749 isolate, webassembly,
"Suspending", WebAssemblySuspendingImpl);
3750 context->set_wasm_suspending_constructor(*suspending_constructor);
3751 SetupConstructor(isolate, suspending_constructor, WASM_SUSPENDING_OBJECT_TYPE,
3752 WasmSuspendingObject::kHeaderSize,
"WebAssembly.Suspending");
3753 InstallFunc(isolate, webassembly,
"promising", WebAssemblyPromising, 1);
3754 InstallError(isolate, webassembly, isolate->factory()->SuspendError_string(),
3755 Context::WASM_SUSPEND_ERROR_FUNCTION_INDEX);
3759void WasmJs::InstallMemoryControl(
Isolate* isolate,
3764 DCHECK(webassembly->map()->is_extensible());
3767 InstallConstructorFunc(isolate, webassembly,
"MemoryMapDescriptor",
3768 wasm::WebAssemblyMemoryMapDescriptor);
3770 isolate, descriptor_constructor, WASM_MEMORY_MAP_DESCRIPTOR_TYPE,
3771 WasmMemoryMapDescriptor::kHeaderSize,
"WebAssembly.MemoryMapDescriptor");
3772 context->set_wasm_memory_map_descriptor_constructor(*descriptor_constructor);
3775 Cast<JSObject>(descriptor_constructor->instance_prototype()), isolate);
3777 InstallFunc(isolate, descriptor_proto,
"map",
3778 wasm::WebAssemblyMemoryMapDescriptorMap, 2);
3779 InstallFunc(isolate, descriptor_proto,
"unmap",
3780 wasm::WebAssemblyMemoryMapDescriptorUnmap, 0);
3785bool WasmJs::InstallTypeReflection(
Isolate* isolate,
3790 DCHECK(webassembly->map()->is_extensible());
3794 if (JSObject::HasRealNamedProperty(isolate, webassembly,
3795 isolate->factory()->Function_string())
3801 return handle(Cast<JSObject>(constructor->instance_prototype()), isolate);
3804 GetProto(context->wasm_table_constructor());
3806 GetProto(context->wasm_global_constructor());
3808 GetProto(context->wasm_memory_constructor());
3813 if (JSObject::HasRealNamedProperty(isolate, proto, type_string)
3818 if (!proto->map()->is_extensible())
return false;
3821 if (!CheckProto(table_proto))
return false;
3822 if (!CheckProto(global_proto))
return false;
3823 if (!CheckProto(memory_proto))
return false;
3824 if (!CheckProto(tag_proto))
return false;
3827 InstallFunc(isolate, table_proto, type_string, WebAssemblyTableType, 0,
false,
3828 NONE, SideEffectType::kHasNoSideEffect);
3829 InstallFunc(isolate, memory_proto, type_string, WebAssemblyMemoryType, 0,
3830 false,
NONE, SideEffectType::kHasNoSideEffect);
3831 InstallFunc(isolate, global_proto, type_string, WebAssemblyGlobalType, 0,
3832 false,
NONE, SideEffectType::kHasNoSideEffect);
3833 InstallFunc(isolate, tag_proto, type_string, WebAssemblyTagType, 0,
false,
3834 NONE, SideEffectType::kHasNoSideEffect);
3838 isolate, webassembly,
"Function", WebAssemblyFunction);
3839 SetDummyInstanceTemplate(isolate, function_constructor);
3840 JSFunction::EnsureHasInitialMap(function_constructor);
3842 Cast<JSObject>(function_constructor->instance_prototype()), isolate);
3844 Map::Copy(isolate, isolate->sloppy_function_without_prototype_map(),
3845 "WebAssembly.Function");
3846 CHECK(JSObject::SetPrototype(
3847 isolate, function_proto,
3848 direct_handle(context->function_function()->prototype(), isolate),
3851 JSFunction::SetInitialMap(isolate, function_constructor, function_map,
3856 JSObject::AddProperty(isolate, function_proto,
3857 isolate->factory()->to_string_tag_symbol(),
3858 v8_str(isolate,
"WebAssembly.Function"), ro_attributes);
3860 InstallFunc(isolate, function_proto, type_string, WebAssemblyFunctionType, 0);
3862 Builtin::kWebAssemblyFunctionPrototypeBind, 1,
3865 context->set_wasm_exported_function_map(*function_map);
3870void WasmJs::InstallResizableBufferIntegration(
3875 DCHECK(webassembly->map()->is_extensible());
3878 Cast<JSObject>(context->wasm_memory_constructor()->instance_prototype()),
3880 InstallFunc(isolate, memory_proto,
"toFixedLengthBuffer",
3881 wasm::WebAssemblyMemoryToFixedLengthBuffer, 0);
3882 InstallFunc(isolate, memory_proto,
"toResizableBuffer",
3883 wasm::WebAssemblyMemoryToResizableBuffer, 0);
3890 std::shared_ptr<wasm::CompilationResultResolver> resolver) {
3891 return std::make_unique<WasmStreaming>(
3892 std::make_unique<WasmStreaming::WasmStreamingImpl>(
union v8::internal::@341::BuiltinMetadata::KindSpecificData data
#define BUILTIN_CODE(isolate, name)
#define SBXCHECK(condition)
static Local< BigInt > New(Isolate *isolate, int64_t value)
static Local< BigInt > NewFromUnsigned(Isolate *isolate, uint64_t value)
static Local< FunctionTemplate > New(Isolate *isolate, FunctionCallback callback=nullptr, Local< Value > data=Local< Value >(), Local< Signature > signature=Local< Signature >(), int length=0, ConstructorBehavior behavior=ConstructorBehavior::kAllow, SideEffectType side_effect_type=SideEffectType::kHasSideEffect, const CFunction *c_function=nullptr, uint16_t instance_type=0, uint16_t allowed_receiver_instance_type_range_start=0, uint16_t allowed_receiver_instance_type_range_end=0)
static MaybeLocal< Function > New(Local< Context > context, FunctionCallback callback, Local< Value > data=Local< Value >(), int length=0, ConstructorBehavior behavior=ConstructorBehavior::kAllow, SideEffectType side_effect_type=SideEffectType::kHasSideEffect)
static Local< Integer > New(Isolate *isolate, int32_t value)
@ kWasmJavaScriptPromiseIntegration
@ kWebAssemblyInstantiation
V8_INLINE Local< S > As() const
static V8_INLINE Local< T > Cast(Local< S > that)
V8_WARN_UNUSED_RESULT V8_INLINE bool ToLocal(Local< S > *out) const
static Local< Number > New(Isolate *isolate, double value)
static Local< ObjectTemplate > New(Isolate *isolate, Local< FunctionTemplate > constructor=Local< FunctionTemplate >())
static V8_WARN_UNUSED_RESULT MaybeLocal< Resolver > New(Local< Context > context)
V8_INLINE void Set(const Global< S > &handle)
static v8::internal::Handle< To > OpenHandle(v8::Local< From > handle)
static v8::internal::DirectHandle< To > OpenDirectHandle(v8::Local< From > handle)
void SetMoreFunctionsCanBeSerializedCallback(std::function< void(CompiledWasmModule)> callback)
bool SetCompiledModuleBytes(base::Vector< const uint8_t > bytes)
void Abort(i::MaybeHandle< i::JSAny > exception)
const WasmEnabledFeatures enabled_features_
const std::shared_ptr< internal::wasm::CompilationResultResolver > resolver_
i::Isolate *const i_isolate_
WasmStreamingImpl(i::Isolate *isolate, const char *api_method_name, CompileTimeImports compile_imports, std::shared_ptr< internal::wasm::CompilationResultResolver > resolver)
void Finish(bool can_use_compiled_module)
const std::shared_ptr< internal::wasm::StreamingDecoder > streaming_decoder_
void OnBytesReceived(const uint8_t *bytes, size_t size)
void SetUrl(base::Vector< const char > url)
std::unique_ptr< WasmStreamingImpl > impl_
void Finish(bool can_use_compiled_module=true)
bool SetCompiledModuleBytes(const uint8_t *bytes, size_t size)
void SetUrl(const char *url, size_t length)
void SetMoreFunctionsCanBeSerializedCallback(std::function< void(CompiledWasmModule)>)
void Abort(MaybeLocal< Value > exception)
void OnBytesReceived(const uint8_t *bytes, size_t size)
static std::shared_ptr< WasmStreaming > Unpack(Isolate *isolate, Local< Value > value)
static V8_BASE_EXPORT bool GetFlushDenormals()
static OwnedVector< T > NewForOverwrite(size_t size)
V8_WARN_UNUSED_RESULT Handle< JSFunction > Build()
Handle< SharedFunctionInfo > NewSharedFunctionInfoForBuiltin(MaybeDirectHandle< String > name, Builtin builtin, int len, AdaptArguments adapt, FunctionKind kind=FunctionKind::kNormalFunction)
Handle< JSObject > NewJSObject(DirectHandle< JSFunction > constructor, AllocationType allocation=AllocationType::kYoung, NewJSObjectType=NewJSObjectType::kNoAPIWrapper)
Tagged< Object > exception()
v8::internal::Factory * factory()
V8_WARN_UNUSED_RESULT V8_INLINE bool ToHandle(DirectHandle< S > *out) const
constexpr const char * ToString(DataViewOp op)
Handle< SharedFunctionInfo > info
Handle< Context > context_
#define ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, dst, call, value)
#define MAYBE_RETURN(call, value)
ZoneVector< RpoNumber > & result
InstructionOperand destination
void MakeWeak(i::Address *location, void *parameter, WeakCallbackInfo< void >::Callback weak_callback, WeakCallbackType type)
V8_INLINE Dest bit_cast(Source const &source)
void Relaxed_Memcpy(volatile Atomic8 *dst, volatile const Atomic8 *src, size_t bytes)
constexpr Vector< T > VectorOf(T *start, size_t size)
Vector< const char > CStrVector(const char *data)
std::unique_ptr< WasmStreaming > StartStreamingForTesting(Isolate *isolate, std::shared_ptr< wasm::CompilationResultResolver > resolver)
bool IsJSCompatibleSignature(const CanonicalSig *sig)
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
Handle< JSFunction > SimpleInstallFunction(Isolate *isolate, DirectHandle< JSObject > base, const char *name, Builtin call, int len, AdaptArguments adapt, PropertyAttributes attrs)
void EncodeI32ExceptionValue(DirectHandle< FixedArray > encoded_values, uint32_t *encoded_index, uint32_t value)
void DecodeI32ExceptionValue(DirectHandle< FixedArray > encoded_values, uint32_t *encoded_index, uint32_t *value)
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
kWasmInternalFunctionIndirectPointerTag kProtectedInstanceDataOffset sig
bool IsNullOrUndefined(Tagged< Object > obj, Isolate *isolate)
constexpr uint64_t kMaxUInt64
void DecodeI64ExceptionValue(DirectHandle< FixedArray > encoded_values, uint32_t *encoded_index, uint64_t *value)
bool V8_EXPORT ValidateCallbackInfo(const FunctionCallbackInfo< void > &info)
V8_INLINE constexpr bool IsObject(TaggedImpl< kRefType, StorageType > obj)
V8_EXPORT_PRIVATE FlagValues v8_flags
void ToUtf8Lossy(Isolate *isolate, DirectHandle< String > string, std::string &out)
float DoubleToFloat32(double x)
void InstallError(Isolate *isolate, DirectHandle< JSObject > global, DirectHandle< String > name, int context_index, Builtin error_constructor, int error_function_length)
JSArrayBuffer::IsDetachableBit is_shared
constexpr uint32_t kMaxUInt32
void EncodeI64ExceptionValue(DirectHandle< FixedArray > encoded_values, uint32_t *encoded_index, uint64_t value)
!IsContextMap !IsContextMap native_context
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
V8_INLINE Local< Boolean > False(Isolate *isolate)
bool ToLocal(v8::internal::MaybeDirectHandle< v8::internal::Object > maybe, Local< T > *local)
void(*)(const FunctionCallbackInfo< Value > &info) FunctionCallback
static i::DirectHandle< i::ObjectTemplateInfo > NewObjectTemplate(i::Isolate *i_isolate)
static i::DirectHandle< i::FunctionTemplateInfo > NewFunctionTemplate(i::Isolate *i_isolate, FunctionCallback func, bool has_prototype, SideEffectType side_effect_type=SideEffectType::kHasSideEffect)
#define DCHECK_LE(v1, v2)
#define DCHECK_NOT_NULL(val)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK_NE(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define TRACE_EVENT0(category_group, name)
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)
#define V8_WARN_UNUSED_RESULT
#define V8_UNLIKELY(condition)
std::unique_ptr< ValueMirror > value
const wasm::WasmModule * module_
#define DEF_WASM_JS_EXTERNAL_REFERENCE(Name)
#define GET_FIRST_ARGUMENT_AS(Type)
#define EXTRACT_THIS(var, WasmType)
#define WASM_JS_EXTERNAL_REFERENCE_LIST(V)