11cb0ef41Sopenharmony_ci// Copyright 2015 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/wasm/wasm-js.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include <cinttypes>
81cb0ef41Sopenharmony_ci#include <cstring>
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci#include "include/v8-function.h"
111cb0ef41Sopenharmony_ci#include "include/v8-wasm.h"
121cb0ef41Sopenharmony_ci#include "src/api/api-inl.h"
131cb0ef41Sopenharmony_ci#include "src/api/api-natives.h"
141cb0ef41Sopenharmony_ci#include "src/ast/ast.h"
151cb0ef41Sopenharmony_ci#include "src/base/logging.h"
161cb0ef41Sopenharmony_ci#include "src/base/overflowing-math.h"
171cb0ef41Sopenharmony_ci#include "src/base/platform/wrappers.h"
181cb0ef41Sopenharmony_ci#include "src/common/assert-scope.h"
191cb0ef41Sopenharmony_ci#include "src/execution/execution.h"
201cb0ef41Sopenharmony_ci#include "src/execution/frames-inl.h"
211cb0ef41Sopenharmony_ci#include "src/execution/isolate.h"
221cb0ef41Sopenharmony_ci#include "src/handles/global-handles-inl.h"
231cb0ef41Sopenharmony_ci#include "src/handles/handles.h"
241cb0ef41Sopenharmony_ci#include "src/heap/factory.h"
251cb0ef41Sopenharmony_ci#include "src/init/v8.h"
261cb0ef41Sopenharmony_ci#include "src/objects/fixed-array.h"
271cb0ef41Sopenharmony_ci#include "src/objects/instance-type.h"
281cb0ef41Sopenharmony_ci#include "src/objects/js-function.h"
291cb0ef41Sopenharmony_ci#include "src/objects/js-promise-inl.h"
301cb0ef41Sopenharmony_ci#include "src/objects/managed-inl.h"
311cb0ef41Sopenharmony_ci#include "src/objects/objects-inl.h"
321cb0ef41Sopenharmony_ci#include "src/objects/shared-function-info.h"
331cb0ef41Sopenharmony_ci#include "src/objects/templates.h"
341cb0ef41Sopenharmony_ci#include "src/parsing/parse-info.h"
351cb0ef41Sopenharmony_ci#include "src/tasks/task-utils.h"
361cb0ef41Sopenharmony_ci#include "src/trap-handler/trap-handler.h"
371cb0ef41Sopenharmony_ci#include "src/wasm/function-compiler.h"
381cb0ef41Sopenharmony_ci#include "src/wasm/streaming-decoder.h"
391cb0ef41Sopenharmony_ci#include "src/wasm/value-type.h"
401cb0ef41Sopenharmony_ci#include "src/wasm/wasm-debug.h"
411cb0ef41Sopenharmony_ci#include "src/wasm/wasm-engine.h"
421cb0ef41Sopenharmony_ci#include "src/wasm/wasm-limits.h"
431cb0ef41Sopenharmony_ci#include "src/wasm/wasm-objects-inl.h"
441cb0ef41Sopenharmony_ci#include "src/wasm/wasm-serialization.h"
451cb0ef41Sopenharmony_ci#include "src/wasm/wasm-value.h"
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ciusing v8::internal::wasm::ErrorThrower;
481cb0ef41Sopenharmony_ciusing v8::internal::wasm::ScheduledErrorThrower;
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_cinamespace v8 {
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ciclass WasmStreaming::WasmStreamingImpl {
531cb0ef41Sopenharmony_ci public:
541cb0ef41Sopenharmony_ci  WasmStreamingImpl(
551cb0ef41Sopenharmony_ci      Isolate* isolate, const char* api_method_name,
561cb0ef41Sopenharmony_ci      std::shared_ptr<internal::wasm::CompilationResultResolver> resolver)
571cb0ef41Sopenharmony_ci      : isolate_(isolate), resolver_(std::move(resolver)) {
581cb0ef41Sopenharmony_ci    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_);
591cb0ef41Sopenharmony_ci    auto enabled_features = i::wasm::WasmFeatures::FromIsolate(i_isolate);
601cb0ef41Sopenharmony_ci    streaming_decoder_ = i::wasm::GetWasmEngine()->StartStreamingCompilation(
611cb0ef41Sopenharmony_ci        i_isolate, enabled_features, handle(i_isolate->context(), i_isolate),
621cb0ef41Sopenharmony_ci        api_method_name, resolver_);
631cb0ef41Sopenharmony_ci  }
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci  void OnBytesReceived(const uint8_t* bytes, size_t size) {
661cb0ef41Sopenharmony_ci    streaming_decoder_->OnBytesReceived(base::VectorOf(bytes, size));
671cb0ef41Sopenharmony_ci  }
681cb0ef41Sopenharmony_ci  void Finish(bool can_use_compiled_module) {
691cb0ef41Sopenharmony_ci    streaming_decoder_->Finish(can_use_compiled_module);
701cb0ef41Sopenharmony_ci  }
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci  void Abort(MaybeLocal<Value> exception) {
731cb0ef41Sopenharmony_ci    i::HandleScope scope(reinterpret_cast<i::Isolate*>(isolate_));
741cb0ef41Sopenharmony_ci    streaming_decoder_->Abort();
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci    // If no exception value is provided, we do not reject the promise. This can
771cb0ef41Sopenharmony_ci    // happen when streaming compilation gets aborted when no script execution
781cb0ef41Sopenharmony_ci    // is allowed anymore, e.g. when a browser tab gets refreshed.
791cb0ef41Sopenharmony_ci    if (exception.IsEmpty()) return;
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci    resolver_->OnCompilationFailed(
821cb0ef41Sopenharmony_ci        Utils::OpenHandle(*exception.ToLocalChecked()));
831cb0ef41Sopenharmony_ci  }
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci  bool SetCompiledModuleBytes(const uint8_t* bytes, size_t size) {
861cb0ef41Sopenharmony_ci    if (!i::wasm::IsSupportedVersion({bytes, size})) return false;
871cb0ef41Sopenharmony_ci    return streaming_decoder_->SetCompiledModuleBytes({bytes, size});
881cb0ef41Sopenharmony_ci  }
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci  void SetClient(std::shared_ptr<Client> client) {
911cb0ef41Sopenharmony_ci    streaming_decoder_->SetModuleCompiledCallback(
921cb0ef41Sopenharmony_ci        [client, streaming_decoder = streaming_decoder_](
931cb0ef41Sopenharmony_ci            const std::shared_ptr<i::wasm::NativeModule>& native_module) {
941cb0ef41Sopenharmony_ci          base::Vector<const char> url = streaming_decoder->url();
951cb0ef41Sopenharmony_ci          auto compiled_wasm_module =
961cb0ef41Sopenharmony_ci              CompiledWasmModule(native_module, url.begin(), url.size());
971cb0ef41Sopenharmony_ci          client->OnModuleCompiled(compiled_wasm_module);
981cb0ef41Sopenharmony_ci        });
991cb0ef41Sopenharmony_ci  }
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ci  void SetUrl(base::Vector<const char> url) { streaming_decoder_->SetUrl(url); }
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_ci private:
1041cb0ef41Sopenharmony_ci  Isolate* const isolate_;
1051cb0ef41Sopenharmony_ci  std::shared_ptr<internal::wasm::StreamingDecoder> streaming_decoder_;
1061cb0ef41Sopenharmony_ci  std::shared_ptr<internal::wasm::CompilationResultResolver> resolver_;
1071cb0ef41Sopenharmony_ci};
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_ciWasmStreaming::WasmStreaming(std::unique_ptr<WasmStreamingImpl> impl)
1101cb0ef41Sopenharmony_ci    : impl_(std::move(impl)) {
1111cb0ef41Sopenharmony_ci  TRACE_EVENT0("v8.wasm", "wasm.InitializeStreaming");
1121cb0ef41Sopenharmony_ci}
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ci// The destructor is defined here because we have a unique_ptr with forward
1151cb0ef41Sopenharmony_ci// declaration.
1161cb0ef41Sopenharmony_ciWasmStreaming::~WasmStreaming() = default;
1171cb0ef41Sopenharmony_ci
1181cb0ef41Sopenharmony_civoid WasmStreaming::OnBytesReceived(const uint8_t* bytes, size_t size) {
1191cb0ef41Sopenharmony_ci  TRACE_EVENT1("v8.wasm", "wasm.OnBytesReceived", "bytes", size);
1201cb0ef41Sopenharmony_ci  impl_->OnBytesReceived(bytes, size);
1211cb0ef41Sopenharmony_ci}
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_civoid WasmStreaming::Finish(bool can_use_compiled_module) {
1241cb0ef41Sopenharmony_ci  TRACE_EVENT0("v8.wasm", "wasm.FinishStreaming");
1251cb0ef41Sopenharmony_ci  impl_->Finish(can_use_compiled_module);
1261cb0ef41Sopenharmony_ci}
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_civoid WasmStreaming::Abort(MaybeLocal<Value> exception) {
1291cb0ef41Sopenharmony_ci  TRACE_EVENT0("v8.wasm", "wasm.AbortStreaming");
1301cb0ef41Sopenharmony_ci  impl_->Abort(exception);
1311cb0ef41Sopenharmony_ci}
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_cibool WasmStreaming::SetCompiledModuleBytes(const uint8_t* bytes, size_t size) {
1341cb0ef41Sopenharmony_ci  TRACE_EVENT0("v8.wasm", "wasm.SetCompiledModuleBytes");
1351cb0ef41Sopenharmony_ci  return impl_->SetCompiledModuleBytes(bytes, size);
1361cb0ef41Sopenharmony_ci}
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_civoid WasmStreaming::SetClient(std::shared_ptr<Client> client) {
1391cb0ef41Sopenharmony_ci  TRACE_EVENT0("v8.wasm", "wasm.WasmStreaming.SetClient");
1401cb0ef41Sopenharmony_ci  impl_->SetClient(client);
1411cb0ef41Sopenharmony_ci}
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_civoid WasmStreaming::SetUrl(const char* url, size_t length) {
1441cb0ef41Sopenharmony_ci  DCHECK_EQ('\0', url[length]);  // {url} is null-terminated.
1451cb0ef41Sopenharmony_ci  TRACE_EVENT1("v8.wasm", "wasm.SetUrl", "url", url);
1461cb0ef41Sopenharmony_ci  impl_->SetUrl(base::VectorOf(url, length));
1471cb0ef41Sopenharmony_ci}
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ci// static
1501cb0ef41Sopenharmony_cistd::shared_ptr<WasmStreaming> WasmStreaming::Unpack(Isolate* isolate,
1511cb0ef41Sopenharmony_ci                                                     Local<Value> value) {
1521cb0ef41Sopenharmony_ci  TRACE_EVENT0("v8.wasm", "wasm.WasmStreaming.Unpack");
1531cb0ef41Sopenharmony_ci  i::HandleScope scope(reinterpret_cast<i::Isolate*>(isolate));
1541cb0ef41Sopenharmony_ci  auto managed =
1551cb0ef41Sopenharmony_ci      i::Handle<i::Managed<WasmStreaming>>::cast(Utils::OpenHandle(*value));
1561cb0ef41Sopenharmony_ci  return managed->get();
1571cb0ef41Sopenharmony_ci}
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_cinamespace {
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_ci#define ASSIGN(type, var, expr)                      \
1621cb0ef41Sopenharmony_ci  Local<type> var;                                   \
1631cb0ef41Sopenharmony_ci  do {                                               \
1641cb0ef41Sopenharmony_ci    if (!expr.ToLocal(&var)) {                       \
1651cb0ef41Sopenharmony_ci      DCHECK(i_isolate->has_scheduled_exception());  \
1661cb0ef41Sopenharmony_ci      return;                                        \
1671cb0ef41Sopenharmony_ci    } else {                                         \
1681cb0ef41Sopenharmony_ci      DCHECK(!i_isolate->has_scheduled_exception()); \
1691cb0ef41Sopenharmony_ci    }                                                \
1701cb0ef41Sopenharmony_ci  } while (false)
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_cii::Handle<i::String> v8_str(i::Isolate* isolate, const char* str) {
1731cb0ef41Sopenharmony_ci  return isolate->factory()->NewStringFromAsciiChecked(str);
1741cb0ef41Sopenharmony_ci}
1751cb0ef41Sopenharmony_ciLocal<String> v8_str(Isolate* isolate, const char* str) {
1761cb0ef41Sopenharmony_ci  return Utils::ToLocal(v8_str(reinterpret_cast<i::Isolate*>(isolate), str));
1771cb0ef41Sopenharmony_ci}
1781cb0ef41Sopenharmony_ci
1791cb0ef41Sopenharmony_ci#define GET_FIRST_ARGUMENT_AS(Type)                                  \
1801cb0ef41Sopenharmony_ci  i::MaybeHandle<i::Wasm##Type##Object> GetFirstArgumentAs##Type(    \
1811cb0ef41Sopenharmony_ci      const v8::FunctionCallbackInfo<v8::Value>& args,               \
1821cb0ef41Sopenharmony_ci      ErrorThrower* thrower) {                                       \
1831cb0ef41Sopenharmony_ci    i::Handle<i::Object> arg0 = Utils::OpenHandle(*args[0]);         \
1841cb0ef41Sopenharmony_ci    if (!arg0->IsWasm##Type##Object()) {                             \
1851cb0ef41Sopenharmony_ci      thrower->TypeError("Argument 0 must be a WebAssembly." #Type); \
1861cb0ef41Sopenharmony_ci      return {};                                                     \
1871cb0ef41Sopenharmony_ci    }                                                                \
1881cb0ef41Sopenharmony_ci    return i::Handle<i::Wasm##Type##Object>::cast(arg0);             \
1891cb0ef41Sopenharmony_ci  }
1901cb0ef41Sopenharmony_ci
1911cb0ef41Sopenharmony_ciGET_FIRST_ARGUMENT_AS(Module)
1921cb0ef41Sopenharmony_ciGET_FIRST_ARGUMENT_AS(Tag)
1931cb0ef41Sopenharmony_ci
1941cb0ef41Sopenharmony_ci#undef GET_FIRST_ARGUMENT_AS
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_cii::wasm::ModuleWireBytes GetFirstArgumentAsBytes(
1971cb0ef41Sopenharmony_ci    const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower,
1981cb0ef41Sopenharmony_ci    bool* is_shared) {
1991cb0ef41Sopenharmony_ci  const uint8_t* start = nullptr;
2001cb0ef41Sopenharmony_ci  size_t length = 0;
2011cb0ef41Sopenharmony_ci  v8::Local<v8::Value> source = args[0];
2021cb0ef41Sopenharmony_ci  if (source->IsArrayBuffer()) {
2031cb0ef41Sopenharmony_ci    // A raw array buffer was passed.
2041cb0ef41Sopenharmony_ci    Local<ArrayBuffer> buffer = Local<ArrayBuffer>::Cast(source);
2051cb0ef41Sopenharmony_ci    auto backing_store = buffer->GetBackingStore();
2061cb0ef41Sopenharmony_ci
2071cb0ef41Sopenharmony_ci    start = reinterpret_cast<const uint8_t*>(backing_store->Data());
2081cb0ef41Sopenharmony_ci    length = backing_store->ByteLength();
2091cb0ef41Sopenharmony_ci    *is_shared = buffer->IsSharedArrayBuffer();
2101cb0ef41Sopenharmony_ci  } else if (source->IsTypedArray()) {
2111cb0ef41Sopenharmony_ci    // A TypedArray was passed.
2121cb0ef41Sopenharmony_ci    Local<TypedArray> array = Local<TypedArray>::Cast(source);
2131cb0ef41Sopenharmony_ci    Local<ArrayBuffer> buffer = array->Buffer();
2141cb0ef41Sopenharmony_ci
2151cb0ef41Sopenharmony_ci    auto backing_store = buffer->GetBackingStore();
2161cb0ef41Sopenharmony_ci
2171cb0ef41Sopenharmony_ci    start = reinterpret_cast<const uint8_t*>(backing_store->Data()) +
2181cb0ef41Sopenharmony_ci            array->ByteOffset();
2191cb0ef41Sopenharmony_ci    length = array->ByteLength();
2201cb0ef41Sopenharmony_ci    *is_shared = buffer->IsSharedArrayBuffer();
2211cb0ef41Sopenharmony_ci  } else {
2221cb0ef41Sopenharmony_ci    thrower->TypeError("Argument 0 must be a buffer source");
2231cb0ef41Sopenharmony_ci  }
2241cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(length, start != nullptr);
2251cb0ef41Sopenharmony_ci  if (length == 0) {
2261cb0ef41Sopenharmony_ci    thrower->CompileError("BufferSource argument is empty");
2271cb0ef41Sopenharmony_ci  }
2281cb0ef41Sopenharmony_ci  size_t max_length = i::wasm::max_module_size();
2291cb0ef41Sopenharmony_ci  if (length > max_length) {
2301cb0ef41Sopenharmony_ci    thrower->RangeError("buffer source exceeds maximum size of %zu (is %zu)",
2311cb0ef41Sopenharmony_ci                        max_length, length);
2321cb0ef41Sopenharmony_ci  }
2331cb0ef41Sopenharmony_ci  if (thrower->error()) return i::wasm::ModuleWireBytes(nullptr, nullptr);
2341cb0ef41Sopenharmony_ci  return i::wasm::ModuleWireBytes(start, start + length);
2351cb0ef41Sopenharmony_ci}
2361cb0ef41Sopenharmony_ci
2371cb0ef41Sopenharmony_cii::MaybeHandle<i::JSFunction> GetFirstArgumentAsJSFunction(
2381cb0ef41Sopenharmony_ci    const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
2391cb0ef41Sopenharmony_ci  i::Handle<i::Object> arg0 = Utils::OpenHandle(*args[0]);
2401cb0ef41Sopenharmony_ci  if (!arg0->IsJSFunction()) {
2411cb0ef41Sopenharmony_ci    thrower->TypeError("Argument 0 must be a function");
2421cb0ef41Sopenharmony_ci    return {};
2431cb0ef41Sopenharmony_ci  }
2441cb0ef41Sopenharmony_ci  return i::Handle<i::JSFunction>::cast(arg0);
2451cb0ef41Sopenharmony_ci}
2461cb0ef41Sopenharmony_ci
2471cb0ef41Sopenharmony_cii::MaybeHandle<i::JSReceiver> GetValueAsImports(Local<Value> arg,
2481cb0ef41Sopenharmony_ci                                                ErrorThrower* thrower) {
2491cb0ef41Sopenharmony_ci  if (arg->IsUndefined()) return {};
2501cb0ef41Sopenharmony_ci
2511cb0ef41Sopenharmony_ci  if (!arg->IsObject()) {
2521cb0ef41Sopenharmony_ci    thrower->TypeError("Argument 1 must be an object");
2531cb0ef41Sopenharmony_ci    return {};
2541cb0ef41Sopenharmony_ci  }
2551cb0ef41Sopenharmony_ci  Local<Object> obj = Local<Object>::Cast(arg);
2561cb0ef41Sopenharmony_ci  return i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj));
2571cb0ef41Sopenharmony_ci}
2581cb0ef41Sopenharmony_ci
2591cb0ef41Sopenharmony_cinamespace {
2601cb0ef41Sopenharmony_ci// This class resolves the result of WebAssembly.compile. It just places the
2611cb0ef41Sopenharmony_ci// compilation result in the supplied {promise}.
2621cb0ef41Sopenharmony_ciclass AsyncCompilationResolver : public i::wasm::CompilationResultResolver {
2631cb0ef41Sopenharmony_ci public:
2641cb0ef41Sopenharmony_ci  AsyncCompilationResolver(i::Isolate* isolate, i::Handle<i::JSPromise> promise)
2651cb0ef41Sopenharmony_ci      : promise_(isolate->global_handles()->Create(*promise)) {
2661cb0ef41Sopenharmony_ci    i::GlobalHandles::AnnotateStrongRetainer(promise_.location(),
2671cb0ef41Sopenharmony_ci                                             kGlobalPromiseHandle);
2681cb0ef41Sopenharmony_ci  }
2691cb0ef41Sopenharmony_ci
2701cb0ef41Sopenharmony_ci  ~AsyncCompilationResolver() override {
2711cb0ef41Sopenharmony_ci    i::GlobalHandles::Destroy(promise_.location());
2721cb0ef41Sopenharmony_ci  }
2731cb0ef41Sopenharmony_ci
2741cb0ef41Sopenharmony_ci  void OnCompilationSucceeded(i::Handle<i::WasmModuleObject> result) override {
2751cb0ef41Sopenharmony_ci    if (finished_) return;
2761cb0ef41Sopenharmony_ci    finished_ = true;
2771cb0ef41Sopenharmony_ci    i::MaybeHandle<i::Object> promise_result =
2781cb0ef41Sopenharmony_ci        i::JSPromise::Resolve(promise_, result);
2791cb0ef41Sopenharmony_ci    CHECK_EQ(promise_result.is_null(),
2801cb0ef41Sopenharmony_ci             promise_->GetIsolate()->has_pending_exception());
2811cb0ef41Sopenharmony_ci  }
2821cb0ef41Sopenharmony_ci
2831cb0ef41Sopenharmony_ci  void OnCompilationFailed(i::Handle<i::Object> error_reason) override {
2841cb0ef41Sopenharmony_ci    if (finished_) return;
2851cb0ef41Sopenharmony_ci    finished_ = true;
2861cb0ef41Sopenharmony_ci    i::MaybeHandle<i::Object> promise_result =
2871cb0ef41Sopenharmony_ci        i::JSPromise::Reject(promise_, error_reason);
2881cb0ef41Sopenharmony_ci    CHECK_EQ(promise_result.is_null(),
2891cb0ef41Sopenharmony_ci             promise_->GetIsolate()->has_pending_exception());
2901cb0ef41Sopenharmony_ci  }
2911cb0ef41Sopenharmony_ci
2921cb0ef41Sopenharmony_ci private:
2931cb0ef41Sopenharmony_ci  static constexpr char kGlobalPromiseHandle[] =
2941cb0ef41Sopenharmony_ci      "AsyncCompilationResolver::promise_";
2951cb0ef41Sopenharmony_ci  bool finished_ = false;
2961cb0ef41Sopenharmony_ci  i::Handle<i::JSPromise> promise_;
2971cb0ef41Sopenharmony_ci};
2981cb0ef41Sopenharmony_ci
2991cb0ef41Sopenharmony_ciconstexpr char AsyncCompilationResolver::kGlobalPromiseHandle[];
3001cb0ef41Sopenharmony_ci
3011cb0ef41Sopenharmony_ci// This class resolves the result of WebAssembly.instantiate(module, imports).
3021cb0ef41Sopenharmony_ci// It just places the instantiation result in the supplied {promise}.
3031cb0ef41Sopenharmony_ciclass InstantiateModuleResultResolver
3041cb0ef41Sopenharmony_ci    : public i::wasm::InstantiationResultResolver {
3051cb0ef41Sopenharmony_ci public:
3061cb0ef41Sopenharmony_ci  InstantiateModuleResultResolver(i::Isolate* isolate,
3071cb0ef41Sopenharmony_ci                                  i::Handle<i::JSPromise> promise)
3081cb0ef41Sopenharmony_ci      : promise_(isolate->global_handles()->Create(*promise)) {
3091cb0ef41Sopenharmony_ci    i::GlobalHandles::AnnotateStrongRetainer(promise_.location(),
3101cb0ef41Sopenharmony_ci                                             kGlobalPromiseHandle);
3111cb0ef41Sopenharmony_ci  }
3121cb0ef41Sopenharmony_ci
3131cb0ef41Sopenharmony_ci  ~InstantiateModuleResultResolver() override {
3141cb0ef41Sopenharmony_ci    i::GlobalHandles::Destroy(promise_.location());
3151cb0ef41Sopenharmony_ci  }
3161cb0ef41Sopenharmony_ci
3171cb0ef41Sopenharmony_ci  void OnInstantiationSucceeded(
3181cb0ef41Sopenharmony_ci      i::Handle<i::WasmInstanceObject> instance) override {
3191cb0ef41Sopenharmony_ci    i::MaybeHandle<i::Object> promise_result =
3201cb0ef41Sopenharmony_ci        i::JSPromise::Resolve(promise_, instance);
3211cb0ef41Sopenharmony_ci    CHECK_EQ(promise_result.is_null(),
3221cb0ef41Sopenharmony_ci             promise_->GetIsolate()->has_pending_exception());
3231cb0ef41Sopenharmony_ci  }
3241cb0ef41Sopenharmony_ci
3251cb0ef41Sopenharmony_ci  void OnInstantiationFailed(i::Handle<i::Object> error_reason) override {
3261cb0ef41Sopenharmony_ci    i::MaybeHandle<i::Object> promise_result =
3271cb0ef41Sopenharmony_ci        i::JSPromise::Reject(promise_, error_reason);
3281cb0ef41Sopenharmony_ci    CHECK_EQ(promise_result.is_null(),
3291cb0ef41Sopenharmony_ci             promise_->GetIsolate()->has_pending_exception());
3301cb0ef41Sopenharmony_ci  }
3311cb0ef41Sopenharmony_ci
3321cb0ef41Sopenharmony_ci private:
3331cb0ef41Sopenharmony_ci  static constexpr char kGlobalPromiseHandle[] =
3341cb0ef41Sopenharmony_ci      "InstantiateModuleResultResolver::promise_";
3351cb0ef41Sopenharmony_ci  i::Handle<i::JSPromise> promise_;
3361cb0ef41Sopenharmony_ci};
3371cb0ef41Sopenharmony_ci
3381cb0ef41Sopenharmony_ciconstexpr char InstantiateModuleResultResolver::kGlobalPromiseHandle[];
3391cb0ef41Sopenharmony_ci
3401cb0ef41Sopenharmony_ci// This class resolves the result of WebAssembly.instantiate(bytes, imports).
3411cb0ef41Sopenharmony_ci// For that it creates a new {JSObject} which contains both the provided
3421cb0ef41Sopenharmony_ci// {WasmModuleObject} and the resulting {WebAssemblyInstanceObject} itself.
3431cb0ef41Sopenharmony_ciclass InstantiateBytesResultResolver
3441cb0ef41Sopenharmony_ci    : public i::wasm::InstantiationResultResolver {
3451cb0ef41Sopenharmony_ci public:
3461cb0ef41Sopenharmony_ci  InstantiateBytesResultResolver(i::Isolate* isolate,
3471cb0ef41Sopenharmony_ci                                 i::Handle<i::JSPromise> promise,
3481cb0ef41Sopenharmony_ci                                 i::Handle<i::WasmModuleObject> module)
3491cb0ef41Sopenharmony_ci      : isolate_(isolate),
3501cb0ef41Sopenharmony_ci        promise_(isolate_->global_handles()->Create(*promise)),
3511cb0ef41Sopenharmony_ci        module_(isolate_->global_handles()->Create(*module)) {
3521cb0ef41Sopenharmony_ci    i::GlobalHandles::AnnotateStrongRetainer(promise_.location(),
3531cb0ef41Sopenharmony_ci                                             kGlobalPromiseHandle);
3541cb0ef41Sopenharmony_ci    i::GlobalHandles::AnnotateStrongRetainer(module_.location(),
3551cb0ef41Sopenharmony_ci                                             kGlobalModuleHandle);
3561cb0ef41Sopenharmony_ci  }
3571cb0ef41Sopenharmony_ci
3581cb0ef41Sopenharmony_ci  ~InstantiateBytesResultResolver() override {
3591cb0ef41Sopenharmony_ci    i::GlobalHandles::Destroy(promise_.location());
3601cb0ef41Sopenharmony_ci    i::GlobalHandles::Destroy(module_.location());
3611cb0ef41Sopenharmony_ci  }
3621cb0ef41Sopenharmony_ci
3631cb0ef41Sopenharmony_ci  void OnInstantiationSucceeded(
3641cb0ef41Sopenharmony_ci      i::Handle<i::WasmInstanceObject> instance) override {
3651cb0ef41Sopenharmony_ci    // The result is a JSObject with 2 fields which contain the
3661cb0ef41Sopenharmony_ci    // WasmInstanceObject and the WasmModuleObject.
3671cb0ef41Sopenharmony_ci    i::Handle<i::JSObject> result =
3681cb0ef41Sopenharmony_ci        isolate_->factory()->NewJSObject(isolate_->object_function());
3691cb0ef41Sopenharmony_ci
3701cb0ef41Sopenharmony_ci    i::Handle<i::String> instance_name =
3711cb0ef41Sopenharmony_ci        isolate_->factory()->NewStringFromStaticChars("instance");
3721cb0ef41Sopenharmony_ci
3731cb0ef41Sopenharmony_ci    i::Handle<i::String> module_name =
3741cb0ef41Sopenharmony_ci        isolate_->factory()->NewStringFromStaticChars("module");
3751cb0ef41Sopenharmony_ci
3761cb0ef41Sopenharmony_ci    i::JSObject::AddProperty(isolate_, result, instance_name, instance,
3771cb0ef41Sopenharmony_ci                             i::NONE);
3781cb0ef41Sopenharmony_ci    i::JSObject::AddProperty(isolate_, result, module_name, module_, i::NONE);
3791cb0ef41Sopenharmony_ci
3801cb0ef41Sopenharmony_ci    i::MaybeHandle<i::Object> promise_result =
3811cb0ef41Sopenharmony_ci        i::JSPromise::Resolve(promise_, result);
3821cb0ef41Sopenharmony_ci    CHECK_EQ(promise_result.is_null(), isolate_->has_pending_exception());
3831cb0ef41Sopenharmony_ci  }
3841cb0ef41Sopenharmony_ci
3851cb0ef41Sopenharmony_ci  void OnInstantiationFailed(i::Handle<i::Object> error_reason) override {
3861cb0ef41Sopenharmony_ci    i::MaybeHandle<i::Object> promise_result =
3871cb0ef41Sopenharmony_ci        i::JSPromise::Reject(promise_, error_reason);
3881cb0ef41Sopenharmony_ci    CHECK_EQ(promise_result.is_null(), isolate_->has_pending_exception());
3891cb0ef41Sopenharmony_ci  }
3901cb0ef41Sopenharmony_ci
3911cb0ef41Sopenharmony_ci private:
3921cb0ef41Sopenharmony_ci  static constexpr char kGlobalPromiseHandle[] =
3931cb0ef41Sopenharmony_ci      "InstantiateBytesResultResolver::promise_";
3941cb0ef41Sopenharmony_ci  static constexpr char kGlobalModuleHandle[] =
3951cb0ef41Sopenharmony_ci      "InstantiateBytesResultResolver::module_";
3961cb0ef41Sopenharmony_ci  i::Isolate* isolate_;
3971cb0ef41Sopenharmony_ci  i::Handle<i::JSPromise> promise_;
3981cb0ef41Sopenharmony_ci  i::Handle<i::WasmModuleObject> module_;
3991cb0ef41Sopenharmony_ci};
4001cb0ef41Sopenharmony_ci
4011cb0ef41Sopenharmony_ciconstexpr char InstantiateBytesResultResolver::kGlobalPromiseHandle[];
4021cb0ef41Sopenharmony_ciconstexpr char InstantiateBytesResultResolver::kGlobalModuleHandle[];
4031cb0ef41Sopenharmony_ci
4041cb0ef41Sopenharmony_ci// This class is the {CompilationResultResolver} for
4051cb0ef41Sopenharmony_ci// WebAssembly.instantiate(bytes, imports). When compilation finishes,
4061cb0ef41Sopenharmony_ci// {AsyncInstantiate} is started on the compilation result.
4071cb0ef41Sopenharmony_ciclass AsyncInstantiateCompileResultResolver
4081cb0ef41Sopenharmony_ci    : public i::wasm::CompilationResultResolver {
4091cb0ef41Sopenharmony_ci public:
4101cb0ef41Sopenharmony_ci  AsyncInstantiateCompileResultResolver(
4111cb0ef41Sopenharmony_ci      i::Isolate* isolate, i::Handle<i::JSPromise> promise,
4121cb0ef41Sopenharmony_ci      i::MaybeHandle<i::JSReceiver> maybe_imports)
4131cb0ef41Sopenharmony_ci      : isolate_(isolate),
4141cb0ef41Sopenharmony_ci        promise_(isolate_->global_handles()->Create(*promise)),
4151cb0ef41Sopenharmony_ci        maybe_imports_(maybe_imports.is_null()
4161cb0ef41Sopenharmony_ci                           ? maybe_imports
4171cb0ef41Sopenharmony_ci                           : isolate_->global_handles()->Create(
4181cb0ef41Sopenharmony_ci                                 *maybe_imports.ToHandleChecked())) {
4191cb0ef41Sopenharmony_ci    i::GlobalHandles::AnnotateStrongRetainer(promise_.location(),
4201cb0ef41Sopenharmony_ci                                             kGlobalPromiseHandle);
4211cb0ef41Sopenharmony_ci    if (!maybe_imports_.is_null()) {
4221cb0ef41Sopenharmony_ci      i::GlobalHandles::AnnotateStrongRetainer(
4231cb0ef41Sopenharmony_ci          maybe_imports_.ToHandleChecked().location(), kGlobalImportsHandle);
4241cb0ef41Sopenharmony_ci    }
4251cb0ef41Sopenharmony_ci  }
4261cb0ef41Sopenharmony_ci
4271cb0ef41Sopenharmony_ci  ~AsyncInstantiateCompileResultResolver() override {
4281cb0ef41Sopenharmony_ci    i::GlobalHandles::Destroy(promise_.location());
4291cb0ef41Sopenharmony_ci    if (!maybe_imports_.is_null()) {
4301cb0ef41Sopenharmony_ci      i::GlobalHandles::Destroy(maybe_imports_.ToHandleChecked().location());
4311cb0ef41Sopenharmony_ci    }
4321cb0ef41Sopenharmony_ci  }
4331cb0ef41Sopenharmony_ci
4341cb0ef41Sopenharmony_ci  void OnCompilationSucceeded(i::Handle<i::WasmModuleObject> result) override {
4351cb0ef41Sopenharmony_ci    if (finished_) return;
4361cb0ef41Sopenharmony_ci    finished_ = true;
4371cb0ef41Sopenharmony_ci    i::wasm::GetWasmEngine()->AsyncInstantiate(
4381cb0ef41Sopenharmony_ci        isolate_,
4391cb0ef41Sopenharmony_ci        std::make_unique<InstantiateBytesResultResolver>(isolate_, promise_,
4401cb0ef41Sopenharmony_ci                                                         result),
4411cb0ef41Sopenharmony_ci        result, maybe_imports_);
4421cb0ef41Sopenharmony_ci  }
4431cb0ef41Sopenharmony_ci
4441cb0ef41Sopenharmony_ci  void OnCompilationFailed(i::Handle<i::Object> error_reason) override {
4451cb0ef41Sopenharmony_ci    if (finished_) return;
4461cb0ef41Sopenharmony_ci    finished_ = true;
4471cb0ef41Sopenharmony_ci    i::MaybeHandle<i::Object> promise_result =
4481cb0ef41Sopenharmony_ci        i::JSPromise::Reject(promise_, error_reason);
4491cb0ef41Sopenharmony_ci    CHECK_EQ(promise_result.is_null(), isolate_->has_pending_exception());
4501cb0ef41Sopenharmony_ci  }
4511cb0ef41Sopenharmony_ci
4521cb0ef41Sopenharmony_ci private:
4531cb0ef41Sopenharmony_ci  static constexpr char kGlobalPromiseHandle[] =
4541cb0ef41Sopenharmony_ci      "AsyncInstantiateCompileResultResolver::promise_";
4551cb0ef41Sopenharmony_ci  static constexpr char kGlobalImportsHandle[] =
4561cb0ef41Sopenharmony_ci      "AsyncInstantiateCompileResultResolver::module_";
4571cb0ef41Sopenharmony_ci  bool finished_ = false;
4581cb0ef41Sopenharmony_ci  i::Isolate* isolate_;
4591cb0ef41Sopenharmony_ci  i::Handle<i::JSPromise> promise_;
4601cb0ef41Sopenharmony_ci  i::MaybeHandle<i::JSReceiver> maybe_imports_;
4611cb0ef41Sopenharmony_ci};
4621cb0ef41Sopenharmony_ci
4631cb0ef41Sopenharmony_ciconstexpr char AsyncInstantiateCompileResultResolver::kGlobalPromiseHandle[];
4641cb0ef41Sopenharmony_ciconstexpr char AsyncInstantiateCompileResultResolver::kGlobalImportsHandle[];
4651cb0ef41Sopenharmony_ci
4661cb0ef41Sopenharmony_cistd::string ToString(const char* name) { return std::string(name); }
4671cb0ef41Sopenharmony_ci
4681cb0ef41Sopenharmony_cistd::string ToString(const i::Handle<i::String> name) {
4691cb0ef41Sopenharmony_ci  return std::string("Property '") + name->ToCString().get() + "'";
4701cb0ef41Sopenharmony_ci}
4711cb0ef41Sopenharmony_ci
4721cb0ef41Sopenharmony_ci// Web IDL: '[EnforceRange] unsigned long'
4731cb0ef41Sopenharmony_ci// Previously called ToNonWrappingUint32 in the draft WebAssembly JS spec.
4741cb0ef41Sopenharmony_ci// https://heycam.github.io/webidl/#EnforceRange
4751cb0ef41Sopenharmony_citemplate <typename T>
4761cb0ef41Sopenharmony_cibool EnforceUint32(T argument_name, Local<v8::Value> v, Local<Context> context,
4771cb0ef41Sopenharmony_ci                   ErrorThrower* thrower, uint32_t* res) {
4781cb0ef41Sopenharmony_ci  double double_number;
4791cb0ef41Sopenharmony_ci
4801cb0ef41Sopenharmony_ci  if (!v->NumberValue(context).To(&double_number)) {
4811cb0ef41Sopenharmony_ci    thrower->TypeError("%s must be convertible to a number",
4821cb0ef41Sopenharmony_ci                       ToString(argument_name).c_str());
4831cb0ef41Sopenharmony_ci    return false;
4841cb0ef41Sopenharmony_ci  }
4851cb0ef41Sopenharmony_ci  if (!std::isfinite(double_number)) {
4861cb0ef41Sopenharmony_ci    thrower->TypeError("%s must be convertible to a valid number",
4871cb0ef41Sopenharmony_ci                       ToString(argument_name).c_str());
4881cb0ef41Sopenharmony_ci    return false;
4891cb0ef41Sopenharmony_ci  }
4901cb0ef41Sopenharmony_ci  if (double_number < 0) {
4911cb0ef41Sopenharmony_ci    thrower->TypeError("%s must be non-negative",
4921cb0ef41Sopenharmony_ci                       ToString(argument_name).c_str());
4931cb0ef41Sopenharmony_ci    return false;
4941cb0ef41Sopenharmony_ci  }
4951cb0ef41Sopenharmony_ci  if (double_number > std::numeric_limits<uint32_t>::max()) {
4961cb0ef41Sopenharmony_ci    thrower->TypeError("%s must be in the unsigned long range",
4971cb0ef41Sopenharmony_ci                       ToString(argument_name).c_str());
4981cb0ef41Sopenharmony_ci    return false;
4991cb0ef41Sopenharmony_ci  }
5001cb0ef41Sopenharmony_ci
5011cb0ef41Sopenharmony_ci  *res = static_cast<uint32_t>(double_number);
5021cb0ef41Sopenharmony_ci  return true;
5031cb0ef41Sopenharmony_ci}
5041cb0ef41Sopenharmony_ci}  // namespace
5051cb0ef41Sopenharmony_ci
5061cb0ef41Sopenharmony_ci// WebAssembly.compile(bytes) -> Promise
5071cb0ef41Sopenharmony_civoid WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) {
5081cb0ef41Sopenharmony_ci  constexpr const char* kAPIMethodName = "WebAssembly.compile()";
5091cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
5101cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5111cb0ef41Sopenharmony_ci
5121cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
5131cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, kAPIMethodName);
5141cb0ef41Sopenharmony_ci
5151cb0ef41Sopenharmony_ci  if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
5161cb0ef41Sopenharmony_ci    thrower.CompileError("Wasm code generation disallowed by embedder");
5171cb0ef41Sopenharmony_ci  }
5181cb0ef41Sopenharmony_ci
5191cb0ef41Sopenharmony_ci  Local<Context> context = isolate->GetCurrentContext();
5201cb0ef41Sopenharmony_ci  ASSIGN(Promise::Resolver, promise_resolver, Promise::Resolver::New(context));
5211cb0ef41Sopenharmony_ci  Local<Promise> promise = promise_resolver->GetPromise();
5221cb0ef41Sopenharmony_ci  v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
5231cb0ef41Sopenharmony_ci  return_value.Set(promise);
5241cb0ef41Sopenharmony_ci
5251cb0ef41Sopenharmony_ci  std::shared_ptr<i::wasm::CompilationResultResolver> resolver(
5261cb0ef41Sopenharmony_ci      new AsyncCompilationResolver(i_isolate, Utils::OpenHandle(*promise)));
5271cb0ef41Sopenharmony_ci
5281cb0ef41Sopenharmony_ci  bool is_shared = false;
5291cb0ef41Sopenharmony_ci  auto bytes = GetFirstArgumentAsBytes(args, &thrower, &is_shared);
5301cb0ef41Sopenharmony_ci  if (thrower.error()) {
5311cb0ef41Sopenharmony_ci    resolver->OnCompilationFailed(thrower.Reify());
5321cb0ef41Sopenharmony_ci    return;
5331cb0ef41Sopenharmony_ci  }
5341cb0ef41Sopenharmony_ci  // Asynchronous compilation handles copying wire bytes if necessary.
5351cb0ef41Sopenharmony_ci  auto enabled_features = i::wasm::WasmFeatures::FromIsolate(i_isolate);
5361cb0ef41Sopenharmony_ci  i::wasm::GetWasmEngine()->AsyncCompile(i_isolate, enabled_features,
5371cb0ef41Sopenharmony_ci                                         std::move(resolver), bytes, is_shared,
5381cb0ef41Sopenharmony_ci                                         kAPIMethodName);
5391cb0ef41Sopenharmony_ci}
5401cb0ef41Sopenharmony_ci
5411cb0ef41Sopenharmony_civoid WasmStreamingCallbackForTesting(
5421cb0ef41Sopenharmony_ci    const v8::FunctionCallbackInfo<v8::Value>& args) {
5431cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
5441cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5451cb0ef41Sopenharmony_ci
5461cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
5471cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.compile()");
5481cb0ef41Sopenharmony_ci
5491cb0ef41Sopenharmony_ci  std::shared_ptr<v8::WasmStreaming> streaming =
5501cb0ef41Sopenharmony_ci      v8::WasmStreaming::Unpack(args.GetIsolate(), args.Data());
5511cb0ef41Sopenharmony_ci
5521cb0ef41Sopenharmony_ci  bool is_shared = false;
5531cb0ef41Sopenharmony_ci  i::wasm::ModuleWireBytes bytes =
5541cb0ef41Sopenharmony_ci      GetFirstArgumentAsBytes(args, &thrower, &is_shared);
5551cb0ef41Sopenharmony_ci  if (thrower.error()) {
5561cb0ef41Sopenharmony_ci    streaming->Abort(Utils::ToLocal(thrower.Reify()));
5571cb0ef41Sopenharmony_ci    return;
5581cb0ef41Sopenharmony_ci  }
5591cb0ef41Sopenharmony_ci  streaming->OnBytesReceived(bytes.start(), bytes.length());
5601cb0ef41Sopenharmony_ci  streaming->Finish();
5611cb0ef41Sopenharmony_ci  CHECK(!thrower.error());
5621cb0ef41Sopenharmony_ci}
5631cb0ef41Sopenharmony_ci
5641cb0ef41Sopenharmony_civoid WasmStreamingPromiseFailedCallback(
5651cb0ef41Sopenharmony_ci    const v8::FunctionCallbackInfo<v8::Value>& args) {
5661cb0ef41Sopenharmony_ci  std::shared_ptr<v8::WasmStreaming> streaming =
5671cb0ef41Sopenharmony_ci      v8::WasmStreaming::Unpack(args.GetIsolate(), args.Data());
5681cb0ef41Sopenharmony_ci  streaming->Abort(args[0]);
5691cb0ef41Sopenharmony_ci}
5701cb0ef41Sopenharmony_ci
5711cb0ef41Sopenharmony_ci// WebAssembly.compileStreaming(Response | Promise<Response>)
5721cb0ef41Sopenharmony_ci//   -> Promise<WebAssembly.Module>
5731cb0ef41Sopenharmony_civoid WebAssemblyCompileStreaming(
5741cb0ef41Sopenharmony_ci    const v8::FunctionCallbackInfo<v8::Value>& args) {
5751cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
5761cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5771cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
5781cb0ef41Sopenharmony_ci  const char* const kAPIMethodName = "WebAssembly.compileStreaming()";
5791cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, kAPIMethodName);
5801cb0ef41Sopenharmony_ci  Local<Context> context = isolate->GetCurrentContext();
5811cb0ef41Sopenharmony_ci
5821cb0ef41Sopenharmony_ci  // Create and assign the return value of this function.
5831cb0ef41Sopenharmony_ci  ASSIGN(Promise::Resolver, result_resolver, Promise::Resolver::New(context));
5841cb0ef41Sopenharmony_ci  Local<Promise> promise = result_resolver->GetPromise();
5851cb0ef41Sopenharmony_ci  v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
5861cb0ef41Sopenharmony_ci  return_value.Set(promise);
5871cb0ef41Sopenharmony_ci
5881cb0ef41Sopenharmony_ci  // Prepare the CompilationResultResolver for the compilation.
5891cb0ef41Sopenharmony_ci  auto resolver = std::make_shared<AsyncCompilationResolver>(
5901cb0ef41Sopenharmony_ci      i_isolate, Utils::OpenHandle(*promise));
5911cb0ef41Sopenharmony_ci
5921cb0ef41Sopenharmony_ci  if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
5931cb0ef41Sopenharmony_ci    thrower.CompileError("Wasm code generation disallowed by embedder");
5941cb0ef41Sopenharmony_ci    resolver->OnCompilationFailed(thrower.Reify());
5951cb0ef41Sopenharmony_ci    return;
5961cb0ef41Sopenharmony_ci  }
5971cb0ef41Sopenharmony_ci
5981cb0ef41Sopenharmony_ci  // Allocate the streaming decoder in a Managed so we can pass it to the
5991cb0ef41Sopenharmony_ci  // embedder.
6001cb0ef41Sopenharmony_ci  i::Handle<i::Managed<WasmStreaming>> data =
6011cb0ef41Sopenharmony_ci      i::Managed<WasmStreaming>::Allocate(
6021cb0ef41Sopenharmony_ci          i_isolate, 0,
6031cb0ef41Sopenharmony_ci          std::make_unique<WasmStreaming::WasmStreamingImpl>(
6041cb0ef41Sopenharmony_ci              isolate, kAPIMethodName, resolver));
6051cb0ef41Sopenharmony_ci
6061cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(i_isolate->wasm_streaming_callback());
6071cb0ef41Sopenharmony_ci  ASSIGN(
6081cb0ef41Sopenharmony_ci      v8::Function, compile_callback,
6091cb0ef41Sopenharmony_ci      v8::Function::New(context, i_isolate->wasm_streaming_callback(),
6101cb0ef41Sopenharmony_ci                        Utils::ToLocal(i::Handle<i::Object>::cast(data)), 1));
6111cb0ef41Sopenharmony_ci  ASSIGN(
6121cb0ef41Sopenharmony_ci      v8::Function, reject_callback,
6131cb0ef41Sopenharmony_ci      v8::Function::New(context, WasmStreamingPromiseFailedCallback,
6141cb0ef41Sopenharmony_ci                        Utils::ToLocal(i::Handle<i::Object>::cast(data)), 1));
6151cb0ef41Sopenharmony_ci
6161cb0ef41Sopenharmony_ci  // The parameter may be of type {Response} or of type {Promise<Response>}.
6171cb0ef41Sopenharmony_ci  // Treat either case of parameter as Promise.resolve(parameter)
6181cb0ef41Sopenharmony_ci  // as per https://www.w3.org/2001/tag/doc/promises-guide#resolve-arguments
6191cb0ef41Sopenharmony_ci
6201cb0ef41Sopenharmony_ci  // Ending with:
6211cb0ef41Sopenharmony_ci  //    return Promise.resolve(parameter).then(compile_callback);
6221cb0ef41Sopenharmony_ci  ASSIGN(Promise::Resolver, input_resolver, Promise::Resolver::New(context));
6231cb0ef41Sopenharmony_ci  if (!input_resolver->Resolve(context, args[0]).IsJust()) return;
6241cb0ef41Sopenharmony_ci
6251cb0ef41Sopenharmony_ci  // We do not have any use of the result here. The {compile_callback} will
6261cb0ef41Sopenharmony_ci  // start streaming compilation, which will eventually resolve the promise we
6271cb0ef41Sopenharmony_ci  // set as result value.
6281cb0ef41Sopenharmony_ci  USE(input_resolver->GetPromise()->Then(context, compile_callback,
6291cb0ef41Sopenharmony_ci                                         reject_callback));
6301cb0ef41Sopenharmony_ci}
6311cb0ef41Sopenharmony_ci
6321cb0ef41Sopenharmony_ci// WebAssembly.validate(bytes) -> bool
6331cb0ef41Sopenharmony_civoid WebAssemblyValidate(const v8::FunctionCallbackInfo<v8::Value>& args) {
6341cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
6351cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6361cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
6371cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.validate()");
6381cb0ef41Sopenharmony_ci
6391cb0ef41Sopenharmony_ci  bool is_shared = false;
6401cb0ef41Sopenharmony_ci  auto bytes = GetFirstArgumentAsBytes(args, &thrower, &is_shared);
6411cb0ef41Sopenharmony_ci
6421cb0ef41Sopenharmony_ci  v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
6431cb0ef41Sopenharmony_ci
6441cb0ef41Sopenharmony_ci  if (thrower.error()) {
6451cb0ef41Sopenharmony_ci    if (thrower.wasm_error()) thrower.Reset();  // Clear error.
6461cb0ef41Sopenharmony_ci    return_value.Set(v8::False(isolate));
6471cb0ef41Sopenharmony_ci    return;
6481cb0ef41Sopenharmony_ci  }
6491cb0ef41Sopenharmony_ci
6501cb0ef41Sopenharmony_ci  auto enabled_features = i::wasm::WasmFeatures::FromIsolate(i_isolate);
6511cb0ef41Sopenharmony_ci  bool validated = false;
6521cb0ef41Sopenharmony_ci  if (is_shared) {
6531cb0ef41Sopenharmony_ci    // Make a copy of the wire bytes to avoid concurrent modification.
6541cb0ef41Sopenharmony_ci    std::unique_ptr<uint8_t[]> copy(new uint8_t[bytes.length()]);
6551cb0ef41Sopenharmony_ci    memcpy(copy.get(), bytes.start(), bytes.length());
6561cb0ef41Sopenharmony_ci    i::wasm::ModuleWireBytes bytes_copy(copy.get(),
6571cb0ef41Sopenharmony_ci                                        copy.get() + bytes.length());
6581cb0ef41Sopenharmony_ci    validated = i::wasm::GetWasmEngine()->SyncValidate(
6591cb0ef41Sopenharmony_ci        i_isolate, enabled_features, bytes_copy);
6601cb0ef41Sopenharmony_ci  } else {
6611cb0ef41Sopenharmony_ci    // The wire bytes are not shared, OK to use them directly.
6621cb0ef41Sopenharmony_ci    validated = i::wasm::GetWasmEngine()->SyncValidate(i_isolate,
6631cb0ef41Sopenharmony_ci                                                       enabled_features, bytes);
6641cb0ef41Sopenharmony_ci  }
6651cb0ef41Sopenharmony_ci
6661cb0ef41Sopenharmony_ci  return_value.Set(Boolean::New(isolate, validated));
6671cb0ef41Sopenharmony_ci}
6681cb0ef41Sopenharmony_ci
6691cb0ef41Sopenharmony_cinamespace {
6701cb0ef41Sopenharmony_cibool TransferPrototype(i::Isolate* isolate, i::Handle<i::JSObject> destination,
6711cb0ef41Sopenharmony_ci                       i::Handle<i::JSReceiver> source) {
6721cb0ef41Sopenharmony_ci  i::MaybeHandle<i::HeapObject> maybe_prototype =
6731cb0ef41Sopenharmony_ci      i::JSObject::GetPrototype(isolate, source);
6741cb0ef41Sopenharmony_ci  i::Handle<i::HeapObject> prototype;
6751cb0ef41Sopenharmony_ci  if (maybe_prototype.ToHandle(&prototype)) {
6761cb0ef41Sopenharmony_ci    Maybe<bool> result = i::JSObject::SetPrototype(
6771cb0ef41Sopenharmony_ci        isolate, destination, prototype,
6781cb0ef41Sopenharmony_ci        /*from_javascript=*/false, internal::kThrowOnError);
6791cb0ef41Sopenharmony_ci    if (!result.FromJust()) {
6801cb0ef41Sopenharmony_ci      DCHECK(isolate->has_pending_exception());
6811cb0ef41Sopenharmony_ci      return false;
6821cb0ef41Sopenharmony_ci    }
6831cb0ef41Sopenharmony_ci  }
6841cb0ef41Sopenharmony_ci  return true;
6851cb0ef41Sopenharmony_ci}
6861cb0ef41Sopenharmony_ci}  // namespace
6871cb0ef41Sopenharmony_ci
6881cb0ef41Sopenharmony_ci// new WebAssembly.Module(bytes) -> WebAssembly.Module
6891cb0ef41Sopenharmony_civoid WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) {
6901cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
6911cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6921cb0ef41Sopenharmony_ci  if (i_isolate->wasm_module_callback()(args)) return;
6931cb0ef41Sopenharmony_ci
6941cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
6951cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Module()");
6961cb0ef41Sopenharmony_ci
6971cb0ef41Sopenharmony_ci  if (!args.IsConstructCall()) {
6981cb0ef41Sopenharmony_ci    thrower.TypeError("WebAssembly.Module must be invoked with 'new'");
6991cb0ef41Sopenharmony_ci    return;
7001cb0ef41Sopenharmony_ci  }
7011cb0ef41Sopenharmony_ci  if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
7021cb0ef41Sopenharmony_ci    thrower.CompileError("Wasm code generation disallowed by embedder");
7031cb0ef41Sopenharmony_ci    return;
7041cb0ef41Sopenharmony_ci  }
7051cb0ef41Sopenharmony_ci
7061cb0ef41Sopenharmony_ci  bool is_shared = false;
7071cb0ef41Sopenharmony_ci  auto bytes = GetFirstArgumentAsBytes(args, &thrower, &is_shared);
7081cb0ef41Sopenharmony_ci
7091cb0ef41Sopenharmony_ci  if (thrower.error()) {
7101cb0ef41Sopenharmony_ci    return;
7111cb0ef41Sopenharmony_ci  }
7121cb0ef41Sopenharmony_ci  auto enabled_features = i::wasm::WasmFeatures::FromIsolate(i_isolate);
7131cb0ef41Sopenharmony_ci  i::MaybeHandle<i::WasmModuleObject> maybe_module_obj;
7141cb0ef41Sopenharmony_ci  if (is_shared) {
7151cb0ef41Sopenharmony_ci    // Make a copy of the wire bytes to avoid concurrent modification.
7161cb0ef41Sopenharmony_ci    std::unique_ptr<uint8_t[]> copy(new uint8_t[bytes.length()]);
7171cb0ef41Sopenharmony_ci    memcpy(copy.get(), bytes.start(), bytes.length());
7181cb0ef41Sopenharmony_ci    i::wasm::ModuleWireBytes bytes_copy(copy.get(),
7191cb0ef41Sopenharmony_ci                                        copy.get() + bytes.length());
7201cb0ef41Sopenharmony_ci    maybe_module_obj = i::wasm::GetWasmEngine()->SyncCompile(
7211cb0ef41Sopenharmony_ci        i_isolate, enabled_features, &thrower, bytes_copy);
7221cb0ef41Sopenharmony_ci  } else {
7231cb0ef41Sopenharmony_ci    // The wire bytes are not shared, OK to use them directly.
7241cb0ef41Sopenharmony_ci    maybe_module_obj = i::wasm::GetWasmEngine()->SyncCompile(
7251cb0ef41Sopenharmony_ci        i_isolate, enabled_features, &thrower, bytes);
7261cb0ef41Sopenharmony_ci  }
7271cb0ef41Sopenharmony_ci
7281cb0ef41Sopenharmony_ci  i::Handle<i::WasmModuleObject> module_obj;
7291cb0ef41Sopenharmony_ci  if (!maybe_module_obj.ToHandle(&module_obj)) return;
7301cb0ef41Sopenharmony_ci
7311cb0ef41Sopenharmony_ci  // The infrastructure for `new Foo` calls allocates an object, which is
7321cb0ef41Sopenharmony_ci  // available here as {args.This()}. We're going to discard this object
7331cb0ef41Sopenharmony_ci  // and use {module_obj} instead, but it does have the correct prototype,
7341cb0ef41Sopenharmony_ci  // which we must harvest from it. This makes a difference when the JS
7351cb0ef41Sopenharmony_ci  // constructor function wasn't {WebAssembly.Module} directly, but some
7361cb0ef41Sopenharmony_ci  // subclass: {module_obj} has {WebAssembly.Module}'s prototype at this
7371cb0ef41Sopenharmony_ci  // point, so we must overwrite that with the correct prototype for {Foo}.
7381cb0ef41Sopenharmony_ci  if (!TransferPrototype(i_isolate, module_obj,
7391cb0ef41Sopenharmony_ci                         Utils::OpenHandle(*args.This()))) {
7401cb0ef41Sopenharmony_ci    return;
7411cb0ef41Sopenharmony_ci  }
7421cb0ef41Sopenharmony_ci
7431cb0ef41Sopenharmony_ci  v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
7441cb0ef41Sopenharmony_ci  return_value.Set(Utils::ToLocal(i::Handle<i::JSObject>::cast(module_obj)));
7451cb0ef41Sopenharmony_ci}
7461cb0ef41Sopenharmony_ci
7471cb0ef41Sopenharmony_ci// WebAssembly.Module.imports(module) -> Array<Import>
7481cb0ef41Sopenharmony_civoid WebAssemblyModuleImports(const v8::FunctionCallbackInfo<v8::Value>& args) {
7491cb0ef41Sopenharmony_ci  HandleScope scope(args.GetIsolate());
7501cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
7511cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7521cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Module.imports()");
7531cb0ef41Sopenharmony_ci
7541cb0ef41Sopenharmony_ci  auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
7551cb0ef41Sopenharmony_ci  if (thrower.error()) return;
7561cb0ef41Sopenharmony_ci  auto imports = i::wasm::GetImports(i_isolate, maybe_module.ToHandleChecked());
7571cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(Utils::ToLocal(imports));
7581cb0ef41Sopenharmony_ci}
7591cb0ef41Sopenharmony_ci
7601cb0ef41Sopenharmony_ci// WebAssembly.Module.exports(module) -> Array<Export>
7611cb0ef41Sopenharmony_civoid WebAssemblyModuleExports(const v8::FunctionCallbackInfo<v8::Value>& args) {
7621cb0ef41Sopenharmony_ci  HandleScope scope(args.GetIsolate());
7631cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
7641cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7651cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Module.exports()");
7661cb0ef41Sopenharmony_ci
7671cb0ef41Sopenharmony_ci  auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
7681cb0ef41Sopenharmony_ci  if (thrower.error()) return;
7691cb0ef41Sopenharmony_ci  auto exports = i::wasm::GetExports(i_isolate, maybe_module.ToHandleChecked());
7701cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(Utils::ToLocal(exports));
7711cb0ef41Sopenharmony_ci}
7721cb0ef41Sopenharmony_ci
7731cb0ef41Sopenharmony_ci// WebAssembly.Module.customSections(module, name) -> Array<Section>
7741cb0ef41Sopenharmony_civoid WebAssemblyModuleCustomSections(
7751cb0ef41Sopenharmony_ci    const v8::FunctionCallbackInfo<v8::Value>& args) {
7761cb0ef41Sopenharmony_ci  HandleScope scope(args.GetIsolate());
7771cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
7781cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7791cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate,
7801cb0ef41Sopenharmony_ci                                "WebAssembly.Module.customSections()");
7811cb0ef41Sopenharmony_ci
7821cb0ef41Sopenharmony_ci  auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
7831cb0ef41Sopenharmony_ci  if (thrower.error()) return;
7841cb0ef41Sopenharmony_ci
7851cb0ef41Sopenharmony_ci  if (args[1]->IsUndefined()) {
7861cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 1 is required");
7871cb0ef41Sopenharmony_ci    return;
7881cb0ef41Sopenharmony_ci  }
7891cb0ef41Sopenharmony_ci
7901cb0ef41Sopenharmony_ci  i::MaybeHandle<i::Object> maybe_name =
7911cb0ef41Sopenharmony_ci      i::Object::ToString(i_isolate, Utils::OpenHandle(*args[1]));
7921cb0ef41Sopenharmony_ci  i::Handle<i::Object> name;
7931cb0ef41Sopenharmony_ci  if (!maybe_name.ToHandle(&name)) return;
7941cb0ef41Sopenharmony_ci  auto custom_sections =
7951cb0ef41Sopenharmony_ci      i::wasm::GetCustomSections(i_isolate, maybe_module.ToHandleChecked(),
7961cb0ef41Sopenharmony_ci                                 i::Handle<i::String>::cast(name), &thrower);
7971cb0ef41Sopenharmony_ci  if (thrower.error()) return;
7981cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(Utils::ToLocal(custom_sections));
7991cb0ef41Sopenharmony_ci}
8001cb0ef41Sopenharmony_ci
8011cb0ef41Sopenharmony_ci// new WebAssembly.Instance(module, imports) -> WebAssembly.Instance
8021cb0ef41Sopenharmony_civoid WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {
8031cb0ef41Sopenharmony_ci  Isolate* isolate = args.GetIsolate();
8041cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8051cb0ef41Sopenharmony_ci  i_isolate->CountUsage(
8061cb0ef41Sopenharmony_ci      v8::Isolate::UseCounterFeature::kWebAssemblyInstantiation);
8071cb0ef41Sopenharmony_ci
8081cb0ef41Sopenharmony_ci  HandleScope scope(args.GetIsolate());
8091cb0ef41Sopenharmony_ci  if (i_isolate->wasm_instance_callback()(args)) return;
8101cb0ef41Sopenharmony_ci
8111cb0ef41Sopenharmony_ci  i::MaybeHandle<i::JSObject> maybe_instance_obj;
8121cb0ef41Sopenharmony_ci  {
8131cb0ef41Sopenharmony_ci    ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Instance()");
8141cb0ef41Sopenharmony_ci    if (!args.IsConstructCall()) {
8151cb0ef41Sopenharmony_ci      thrower.TypeError("WebAssembly.Instance must be invoked with 'new'");
8161cb0ef41Sopenharmony_ci      return;
8171cb0ef41Sopenharmony_ci    }
8181cb0ef41Sopenharmony_ci
8191cb0ef41Sopenharmony_ci    i::MaybeHandle<i::WasmModuleObject> maybe_module =
8201cb0ef41Sopenharmony_ci        GetFirstArgumentAsModule(args, &thrower);
8211cb0ef41Sopenharmony_ci    if (thrower.error()) return;
8221cb0ef41Sopenharmony_ci
8231cb0ef41Sopenharmony_ci    i::Handle<i::WasmModuleObject> module_obj = maybe_module.ToHandleChecked();
8241cb0ef41Sopenharmony_ci
8251cb0ef41Sopenharmony_ci    i::MaybeHandle<i::JSReceiver> maybe_imports =
8261cb0ef41Sopenharmony_ci        GetValueAsImports(args[1], &thrower);
8271cb0ef41Sopenharmony_ci    if (thrower.error()) return;
8281cb0ef41Sopenharmony_ci
8291cb0ef41Sopenharmony_ci    maybe_instance_obj = i::wasm::GetWasmEngine()->SyncInstantiate(
8301cb0ef41Sopenharmony_ci        i_isolate, &thrower, module_obj, maybe_imports,
8311cb0ef41Sopenharmony_ci        i::MaybeHandle<i::JSArrayBuffer>());
8321cb0ef41Sopenharmony_ci  }
8331cb0ef41Sopenharmony_ci
8341cb0ef41Sopenharmony_ci  i::Handle<i::JSObject> instance_obj;
8351cb0ef41Sopenharmony_ci  if (!maybe_instance_obj.ToHandle(&instance_obj)) {
8361cb0ef41Sopenharmony_ci    DCHECK(i_isolate->has_scheduled_exception());
8371cb0ef41Sopenharmony_ci    return;
8381cb0ef41Sopenharmony_ci  }
8391cb0ef41Sopenharmony_ci
8401cb0ef41Sopenharmony_ci  // The infrastructure for `new Foo` calls allocates an object, which is
8411cb0ef41Sopenharmony_ci  // available here as {args.This()}. We're going to discard this object
8421cb0ef41Sopenharmony_ci  // and use {instance_obj} instead, but it does have the correct prototype,
8431cb0ef41Sopenharmony_ci  // which we must harvest from it. This makes a difference when the JS
8441cb0ef41Sopenharmony_ci  // constructor function wasn't {WebAssembly.Instance} directly, but some
8451cb0ef41Sopenharmony_ci  // subclass: {instance_obj} has {WebAssembly.Instance}'s prototype at this
8461cb0ef41Sopenharmony_ci  // point, so we must overwrite that with the correct prototype for {Foo}.
8471cb0ef41Sopenharmony_ci  if (!TransferPrototype(i_isolate, instance_obj,
8481cb0ef41Sopenharmony_ci                         Utils::OpenHandle(*args.This()))) {
8491cb0ef41Sopenharmony_ci    return;
8501cb0ef41Sopenharmony_ci  }
8511cb0ef41Sopenharmony_ci
8521cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(Utils::ToLocal(instance_obj));
8531cb0ef41Sopenharmony_ci}
8541cb0ef41Sopenharmony_ci
8551cb0ef41Sopenharmony_ci// WebAssembly.instantiateStreaming(Response | Promise<Response> [, imports])
8561cb0ef41Sopenharmony_ci//   -> Promise<ResultObject>
8571cb0ef41Sopenharmony_ci// (where ResultObject has a "module" and an "instance" field)
8581cb0ef41Sopenharmony_civoid WebAssemblyInstantiateStreaming(
8591cb0ef41Sopenharmony_ci    const v8::FunctionCallbackInfo<v8::Value>& args) {
8601cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
8611cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8621cb0ef41Sopenharmony_ci  i_isolate->CountUsage(
8631cb0ef41Sopenharmony_ci      v8::Isolate::UseCounterFeature::kWebAssemblyInstantiation);
8641cb0ef41Sopenharmony_ci
8651cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
8661cb0ef41Sopenharmony_ci  Local<Context> context = isolate->GetCurrentContext();
8671cb0ef41Sopenharmony_ci  const char* const kAPIMethodName = "WebAssembly.instantiateStreaming()";
8681cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, kAPIMethodName);
8691cb0ef41Sopenharmony_ci
8701cb0ef41Sopenharmony_ci  // Create and assign the return value of this function.
8711cb0ef41Sopenharmony_ci  ASSIGN(Promise::Resolver, result_resolver, Promise::Resolver::New(context));
8721cb0ef41Sopenharmony_ci  Local<Promise> promise = result_resolver->GetPromise();
8731cb0ef41Sopenharmony_ci  v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
8741cb0ef41Sopenharmony_ci  return_value.Set(promise);
8751cb0ef41Sopenharmony_ci
8761cb0ef41Sopenharmony_ci  // Create an InstantiateResultResolver in case there is an issue with the
8771cb0ef41Sopenharmony_ci  // passed parameters.
8781cb0ef41Sopenharmony_ci  std::unique_ptr<i::wasm::InstantiationResultResolver> resolver(
8791cb0ef41Sopenharmony_ci      new InstantiateModuleResultResolver(i_isolate,
8801cb0ef41Sopenharmony_ci                                          Utils::OpenHandle(*promise)));
8811cb0ef41Sopenharmony_ci
8821cb0ef41Sopenharmony_ci  if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
8831cb0ef41Sopenharmony_ci    thrower.CompileError("Wasm code generation disallowed by embedder");
8841cb0ef41Sopenharmony_ci    resolver->OnInstantiationFailed(thrower.Reify());
8851cb0ef41Sopenharmony_ci    return;
8861cb0ef41Sopenharmony_ci  }
8871cb0ef41Sopenharmony_ci
8881cb0ef41Sopenharmony_ci  // If args.Length < 2, this will be undefined - see FunctionCallbackInfo.
8891cb0ef41Sopenharmony_ci  Local<Value> ffi = args[1];
8901cb0ef41Sopenharmony_ci  i::MaybeHandle<i::JSReceiver> maybe_imports =
8911cb0ef41Sopenharmony_ci      GetValueAsImports(ffi, &thrower);
8921cb0ef41Sopenharmony_ci
8931cb0ef41Sopenharmony_ci  if (thrower.error()) {
8941cb0ef41Sopenharmony_ci    resolver->OnInstantiationFailed(thrower.Reify());
8951cb0ef41Sopenharmony_ci    return;
8961cb0ef41Sopenharmony_ci  }
8971cb0ef41Sopenharmony_ci
8981cb0ef41Sopenharmony_ci  // We start compilation now, we have no use for the
8991cb0ef41Sopenharmony_ci  // {InstantiationResultResolver}.
9001cb0ef41Sopenharmony_ci  resolver.reset();
9011cb0ef41Sopenharmony_ci
9021cb0ef41Sopenharmony_ci  std::shared_ptr<i::wasm::CompilationResultResolver> compilation_resolver(
9031cb0ef41Sopenharmony_ci      new AsyncInstantiateCompileResultResolver(
9041cb0ef41Sopenharmony_ci          i_isolate, Utils::OpenHandle(*promise), maybe_imports));
9051cb0ef41Sopenharmony_ci
9061cb0ef41Sopenharmony_ci  // Allocate the streaming decoder in a Managed so we can pass it to the
9071cb0ef41Sopenharmony_ci  // embedder.
9081cb0ef41Sopenharmony_ci  i::Handle<i::Managed<WasmStreaming>> data =
9091cb0ef41Sopenharmony_ci      i::Managed<WasmStreaming>::Allocate(
9101cb0ef41Sopenharmony_ci          i_isolate, 0,
9111cb0ef41Sopenharmony_ci          std::make_unique<WasmStreaming::WasmStreamingImpl>(
9121cb0ef41Sopenharmony_ci              isolate, kAPIMethodName, compilation_resolver));
9131cb0ef41Sopenharmony_ci
9141cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(i_isolate->wasm_streaming_callback());
9151cb0ef41Sopenharmony_ci  ASSIGN(
9161cb0ef41Sopenharmony_ci      v8::Function, compile_callback,
9171cb0ef41Sopenharmony_ci      v8::Function::New(context, i_isolate->wasm_streaming_callback(),
9181cb0ef41Sopenharmony_ci                        Utils::ToLocal(i::Handle<i::Object>::cast(data)), 1));
9191cb0ef41Sopenharmony_ci  ASSIGN(
9201cb0ef41Sopenharmony_ci      v8::Function, reject_callback,
9211cb0ef41Sopenharmony_ci      v8::Function::New(context, WasmStreamingPromiseFailedCallback,
9221cb0ef41Sopenharmony_ci                        Utils::ToLocal(i::Handle<i::Object>::cast(data)), 1));
9231cb0ef41Sopenharmony_ci
9241cb0ef41Sopenharmony_ci  // The parameter may be of type {Response} or of type {Promise<Response>}.
9251cb0ef41Sopenharmony_ci  // Treat either case of parameter as Promise.resolve(parameter)
9261cb0ef41Sopenharmony_ci  // as per https://www.w3.org/2001/tag/doc/promises-guide#resolve-arguments
9271cb0ef41Sopenharmony_ci
9281cb0ef41Sopenharmony_ci  // Ending with:
9291cb0ef41Sopenharmony_ci  //    return Promise.resolve(parameter).then(compile_callback);
9301cb0ef41Sopenharmony_ci  ASSIGN(Promise::Resolver, input_resolver, Promise::Resolver::New(context));
9311cb0ef41Sopenharmony_ci  if (!input_resolver->Resolve(context, args[0]).IsJust()) return;
9321cb0ef41Sopenharmony_ci
9331cb0ef41Sopenharmony_ci  // We do not have any use of the result here. The {compile_callback} will
9341cb0ef41Sopenharmony_ci  // start streaming compilation, which will eventually resolve the promise we
9351cb0ef41Sopenharmony_ci  // set as result value.
9361cb0ef41Sopenharmony_ci  USE(input_resolver->GetPromise()->Then(context, compile_callback,
9371cb0ef41Sopenharmony_ci                                         reject_callback));
9381cb0ef41Sopenharmony_ci}
9391cb0ef41Sopenharmony_ci
9401cb0ef41Sopenharmony_ci// WebAssembly.instantiate(module, imports) -> WebAssembly.Instance
9411cb0ef41Sopenharmony_ci// WebAssembly.instantiate(bytes, imports) ->
9421cb0ef41Sopenharmony_ci//     {module: WebAssembly.Module, instance: WebAssembly.Instance}
9431cb0ef41Sopenharmony_civoid WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
9441cb0ef41Sopenharmony_ci  constexpr const char* kAPIMethodName = "WebAssembly.instantiate()";
9451cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
9461cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9471cb0ef41Sopenharmony_ci  i_isolate->CountUsage(
9481cb0ef41Sopenharmony_ci      v8::Isolate::UseCounterFeature::kWebAssemblyInstantiation);
9491cb0ef41Sopenharmony_ci
9501cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, kAPIMethodName);
9511cb0ef41Sopenharmony_ci
9521cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
9531cb0ef41Sopenharmony_ci
9541cb0ef41Sopenharmony_ci  Local<Context> context = isolate->GetCurrentContext();
9551cb0ef41Sopenharmony_ci
9561cb0ef41Sopenharmony_ci  ASSIGN(Promise::Resolver, promise_resolver, Promise::Resolver::New(context));
9571cb0ef41Sopenharmony_ci  Local<Promise> promise = promise_resolver->GetPromise();
9581cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(promise);
9591cb0ef41Sopenharmony_ci
9601cb0ef41Sopenharmony_ci  std::unique_ptr<i::wasm::InstantiationResultResolver> resolver(
9611cb0ef41Sopenharmony_ci      new InstantiateModuleResultResolver(i_isolate,
9621cb0ef41Sopenharmony_ci                                          Utils::OpenHandle(*promise)));
9631cb0ef41Sopenharmony_ci
9641cb0ef41Sopenharmony_ci  Local<Value> first_arg_value = args[0];
9651cb0ef41Sopenharmony_ci  i::Handle<i::Object> first_arg = Utils::OpenHandle(*first_arg_value);
9661cb0ef41Sopenharmony_ci  if (!first_arg->IsJSObject()) {
9671cb0ef41Sopenharmony_ci    thrower.TypeError(
9681cb0ef41Sopenharmony_ci        "Argument 0 must be a buffer source or a WebAssembly.Module object");
9691cb0ef41Sopenharmony_ci    resolver->OnInstantiationFailed(thrower.Reify());
9701cb0ef41Sopenharmony_ci    return;
9711cb0ef41Sopenharmony_ci  }
9721cb0ef41Sopenharmony_ci
9731cb0ef41Sopenharmony_ci  // If args.Length < 2, this will be undefined - see FunctionCallbackInfo.
9741cb0ef41Sopenharmony_ci  Local<Value> ffi = args[1];
9751cb0ef41Sopenharmony_ci  i::MaybeHandle<i::JSReceiver> maybe_imports =
9761cb0ef41Sopenharmony_ci      GetValueAsImports(ffi, &thrower);
9771cb0ef41Sopenharmony_ci
9781cb0ef41Sopenharmony_ci  if (thrower.error()) {
9791cb0ef41Sopenharmony_ci    resolver->OnInstantiationFailed(thrower.Reify());
9801cb0ef41Sopenharmony_ci    return;
9811cb0ef41Sopenharmony_ci  }
9821cb0ef41Sopenharmony_ci
9831cb0ef41Sopenharmony_ci  if (first_arg->IsWasmModuleObject()) {
9841cb0ef41Sopenharmony_ci    i::Handle<i::WasmModuleObject> module_obj =
9851cb0ef41Sopenharmony_ci        i::Handle<i::WasmModuleObject>::cast(first_arg);
9861cb0ef41Sopenharmony_ci
9871cb0ef41Sopenharmony_ci    i::wasm::GetWasmEngine()->AsyncInstantiate(i_isolate, std::move(resolver),
9881cb0ef41Sopenharmony_ci                                               module_obj, maybe_imports);
9891cb0ef41Sopenharmony_ci    return;
9901cb0ef41Sopenharmony_ci  }
9911cb0ef41Sopenharmony_ci
9921cb0ef41Sopenharmony_ci  bool is_shared = false;
9931cb0ef41Sopenharmony_ci  auto bytes = GetFirstArgumentAsBytes(args, &thrower, &is_shared);
9941cb0ef41Sopenharmony_ci  if (thrower.error()) {
9951cb0ef41Sopenharmony_ci    resolver->OnInstantiationFailed(thrower.Reify());
9961cb0ef41Sopenharmony_ci    return;
9971cb0ef41Sopenharmony_ci  }
9981cb0ef41Sopenharmony_ci
9991cb0ef41Sopenharmony_ci  // We start compilation now, we have no use for the
10001cb0ef41Sopenharmony_ci  // {InstantiationResultResolver}.
10011cb0ef41Sopenharmony_ci  resolver.reset();
10021cb0ef41Sopenharmony_ci
10031cb0ef41Sopenharmony_ci  std::shared_ptr<i::wasm::CompilationResultResolver> compilation_resolver(
10041cb0ef41Sopenharmony_ci      new AsyncInstantiateCompileResultResolver(
10051cb0ef41Sopenharmony_ci          i_isolate, Utils::OpenHandle(*promise), maybe_imports));
10061cb0ef41Sopenharmony_ci
10071cb0ef41Sopenharmony_ci  // The first parameter is a buffer source, we have to check if we are allowed
10081cb0ef41Sopenharmony_ci  // to compile it.
10091cb0ef41Sopenharmony_ci  if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
10101cb0ef41Sopenharmony_ci    thrower.CompileError("Wasm code generation disallowed by embedder");
10111cb0ef41Sopenharmony_ci    compilation_resolver->OnCompilationFailed(thrower.Reify());
10121cb0ef41Sopenharmony_ci    return;
10131cb0ef41Sopenharmony_ci  }
10141cb0ef41Sopenharmony_ci
10151cb0ef41Sopenharmony_ci  // Asynchronous compilation handles copying wire bytes if necessary.
10161cb0ef41Sopenharmony_ci  auto enabled_features = i::wasm::WasmFeatures::FromIsolate(i_isolate);
10171cb0ef41Sopenharmony_ci  i::wasm::GetWasmEngine()->AsyncCompile(i_isolate, enabled_features,
10181cb0ef41Sopenharmony_ci                                         std::move(compilation_resolver), bytes,
10191cb0ef41Sopenharmony_ci                                         is_shared, kAPIMethodName);
10201cb0ef41Sopenharmony_ci}
10211cb0ef41Sopenharmony_ci
10221cb0ef41Sopenharmony_cibool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower,
10231cb0ef41Sopenharmony_ci                        Local<Context> context, v8::Local<v8::Value> value,
10241cb0ef41Sopenharmony_ci                        i::Handle<i::String> property_name, int64_t* result,
10251cb0ef41Sopenharmony_ci                        int64_t lower_bound, uint64_t upper_bound) {
10261cb0ef41Sopenharmony_ci  uint32_t number;
10271cb0ef41Sopenharmony_ci  if (!EnforceUint32(property_name, value, context, thrower, &number)) {
10281cb0ef41Sopenharmony_ci    return false;
10291cb0ef41Sopenharmony_ci  }
10301cb0ef41Sopenharmony_ci  if (number < lower_bound) {
10311cb0ef41Sopenharmony_ci    thrower->RangeError("Property '%s': value %" PRIu32
10321cb0ef41Sopenharmony_ci                        " is below the lower bound %" PRIx64,
10331cb0ef41Sopenharmony_ci                        property_name->ToCString().get(), number, lower_bound);
10341cb0ef41Sopenharmony_ci    return false;
10351cb0ef41Sopenharmony_ci  }
10361cb0ef41Sopenharmony_ci  if (number > upper_bound) {
10371cb0ef41Sopenharmony_ci    thrower->RangeError("Property '%s': value %" PRIu32
10381cb0ef41Sopenharmony_ci                        " is above the upper bound %" PRIu64,
10391cb0ef41Sopenharmony_ci                        property_name->ToCString().get(), number, upper_bound);
10401cb0ef41Sopenharmony_ci    return false;
10411cb0ef41Sopenharmony_ci  }
10421cb0ef41Sopenharmony_ci
10431cb0ef41Sopenharmony_ci  *result = static_cast<int64_t>(number);
10441cb0ef41Sopenharmony_ci  return true;
10451cb0ef41Sopenharmony_ci}
10461cb0ef41Sopenharmony_ci
10471cb0ef41Sopenharmony_cibool GetOptionalIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower,
10481cb0ef41Sopenharmony_ci                                Local<Context> context,
10491cb0ef41Sopenharmony_ci                                Local<v8::Object> object,
10501cb0ef41Sopenharmony_ci                                Local<String> property, bool* has_property,
10511cb0ef41Sopenharmony_ci                                int64_t* result, int64_t lower_bound,
10521cb0ef41Sopenharmony_ci                                uint64_t upper_bound) {
10531cb0ef41Sopenharmony_ci  v8::Local<v8::Value> value;
10541cb0ef41Sopenharmony_ci  if (!object->Get(context, property).ToLocal(&value)) {
10551cb0ef41Sopenharmony_ci    return false;
10561cb0ef41Sopenharmony_ci  }
10571cb0ef41Sopenharmony_ci
10581cb0ef41Sopenharmony_ci  // Web IDL: dictionary presence
10591cb0ef41Sopenharmony_ci  // https://heycam.github.io/webidl/#dfn-present
10601cb0ef41Sopenharmony_ci  if (value->IsUndefined()) {
10611cb0ef41Sopenharmony_ci    if (has_property != nullptr) *has_property = false;
10621cb0ef41Sopenharmony_ci    return true;
10631cb0ef41Sopenharmony_ci  }
10641cb0ef41Sopenharmony_ci
10651cb0ef41Sopenharmony_ci  if (has_property != nullptr) *has_property = true;
10661cb0ef41Sopenharmony_ci  i::Handle<i::String> property_name = v8::Utils::OpenHandle(*property);
10671cb0ef41Sopenharmony_ci
10681cb0ef41Sopenharmony_ci  return GetIntegerProperty(isolate, thrower, context, value, property_name,
10691cb0ef41Sopenharmony_ci                            result, lower_bound, upper_bound);
10701cb0ef41Sopenharmony_ci}
10711cb0ef41Sopenharmony_ci
10721cb0ef41Sopenharmony_ci// Fetch 'initial' or 'minimum' property from object. If both are provided,
10731cb0ef41Sopenharmony_ci// a TypeError is thrown.
10741cb0ef41Sopenharmony_ci// TODO(aseemgarg): change behavior when the following bug is resolved:
10751cb0ef41Sopenharmony_ci// https://github.com/WebAssembly/js-types/issues/6
10761cb0ef41Sopenharmony_cibool GetInitialOrMinimumProperty(v8::Isolate* isolate, ErrorThrower* thrower,
10771cb0ef41Sopenharmony_ci                                 Local<Context> context,
10781cb0ef41Sopenharmony_ci                                 Local<v8::Object> object, int64_t* result,
10791cb0ef41Sopenharmony_ci                                 int64_t lower_bound, uint64_t upper_bound) {
10801cb0ef41Sopenharmony_ci  bool has_initial = false;
10811cb0ef41Sopenharmony_ci  if (!GetOptionalIntegerProperty(isolate, thrower, context, object,
10821cb0ef41Sopenharmony_ci                                  v8_str(isolate, "initial"), &has_initial,
10831cb0ef41Sopenharmony_ci                                  result, lower_bound, upper_bound)) {
10841cb0ef41Sopenharmony_ci    return false;
10851cb0ef41Sopenharmony_ci  }
10861cb0ef41Sopenharmony_ci  auto enabled_features = i::wasm::WasmFeatures::FromIsolate(
10871cb0ef41Sopenharmony_ci      reinterpret_cast<i::Isolate*>(isolate));
10881cb0ef41Sopenharmony_ci  if (enabled_features.has_type_reflection()) {
10891cb0ef41Sopenharmony_ci    bool has_minimum = false;
10901cb0ef41Sopenharmony_ci    int64_t minimum = 0;
10911cb0ef41Sopenharmony_ci    if (!GetOptionalIntegerProperty(isolate, thrower, context, object,
10921cb0ef41Sopenharmony_ci                                    v8_str(isolate, "minimum"), &has_minimum,
10931cb0ef41Sopenharmony_ci                                    &minimum, lower_bound, upper_bound)) {
10941cb0ef41Sopenharmony_ci      return false;
10951cb0ef41Sopenharmony_ci    }
10961cb0ef41Sopenharmony_ci    if (has_initial && has_minimum) {
10971cb0ef41Sopenharmony_ci      thrower->TypeError(
10981cb0ef41Sopenharmony_ci          "The properties 'initial' and 'minimum' are not allowed at the same "
10991cb0ef41Sopenharmony_ci          "time");
11001cb0ef41Sopenharmony_ci      return false;
11011cb0ef41Sopenharmony_ci    }
11021cb0ef41Sopenharmony_ci    if (has_minimum) {
11031cb0ef41Sopenharmony_ci      // Only {minimum} exists, so we use {minimum} as {initial}.
11041cb0ef41Sopenharmony_ci      has_initial = true;
11051cb0ef41Sopenharmony_ci      *result = minimum;
11061cb0ef41Sopenharmony_ci    }
11071cb0ef41Sopenharmony_ci  }
11081cb0ef41Sopenharmony_ci  if (!has_initial) {
11091cb0ef41Sopenharmony_ci    // TODO(aseemgarg): update error message when the spec issue is resolved.
11101cb0ef41Sopenharmony_ci    thrower->TypeError("Property 'initial' is required");
11111cb0ef41Sopenharmony_ci    return false;
11121cb0ef41Sopenharmony_ci  }
11131cb0ef41Sopenharmony_ci  return true;
11141cb0ef41Sopenharmony_ci}
11151cb0ef41Sopenharmony_ci
11161cb0ef41Sopenharmony_cinamespace {
11171cb0ef41Sopenharmony_cii::Handle<i::Object> DefaultReferenceValue(i::Isolate* isolate,
11181cb0ef41Sopenharmony_ci                                           i::wasm::ValueType type) {
11191cb0ef41Sopenharmony_ci  if (type == i::wasm::kWasmFuncRef) {
11201cb0ef41Sopenharmony_ci    return isolate->factory()->null_value();
11211cb0ef41Sopenharmony_ci  }
11221cb0ef41Sopenharmony_ci  if (type.is_reference()) {
11231cb0ef41Sopenharmony_ci    return isolate->factory()->undefined_value();
11241cb0ef41Sopenharmony_ci  }
11251cb0ef41Sopenharmony_ci  UNREACHABLE();
11261cb0ef41Sopenharmony_ci}
11271cb0ef41Sopenharmony_ci}  // namespace
11281cb0ef41Sopenharmony_ci
11291cb0ef41Sopenharmony_ci// new WebAssembly.Table(args) -> WebAssembly.Table
11301cb0ef41Sopenharmony_civoid WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) {
11311cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
11321cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
11331cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
11341cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Table()");
11351cb0ef41Sopenharmony_ci  if (!args.IsConstructCall()) {
11361cb0ef41Sopenharmony_ci    thrower.TypeError("WebAssembly.Table must be invoked with 'new'");
11371cb0ef41Sopenharmony_ci    return;
11381cb0ef41Sopenharmony_ci  }
11391cb0ef41Sopenharmony_ci  if (!args[0]->IsObject()) {
11401cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 must be a table descriptor");
11411cb0ef41Sopenharmony_ci    return;
11421cb0ef41Sopenharmony_ci  }
11431cb0ef41Sopenharmony_ci  Local<Context> context = isolate->GetCurrentContext();
11441cb0ef41Sopenharmony_ci  Local<v8::Object> descriptor = Local<Object>::Cast(args[0]);
11451cb0ef41Sopenharmony_ci  i::wasm::ValueType type;
11461cb0ef41Sopenharmony_ci  // The descriptor's 'element'.
11471cb0ef41Sopenharmony_ci  {
11481cb0ef41Sopenharmony_ci    v8::MaybeLocal<v8::Value> maybe =
11491cb0ef41Sopenharmony_ci        descriptor->Get(context, v8_str(isolate, "element"));
11501cb0ef41Sopenharmony_ci    v8::Local<v8::Value> value;
11511cb0ef41Sopenharmony_ci    if (!maybe.ToLocal(&value)) return;
11521cb0ef41Sopenharmony_ci    v8::Local<v8::String> string;
11531cb0ef41Sopenharmony_ci    if (!value->ToString(context).ToLocal(&string)) return;
11541cb0ef41Sopenharmony_ci    auto enabled_features = i::wasm::WasmFeatures::FromIsolate(i_isolate);
11551cb0ef41Sopenharmony_ci    // The JS api uses 'anyfunc' instead of 'funcref'.
11561cb0ef41Sopenharmony_ci    if (string->StringEquals(v8_str(isolate, "anyfunc"))) {
11571cb0ef41Sopenharmony_ci      type = i::wasm::kWasmFuncRef;
11581cb0ef41Sopenharmony_ci    } else if (enabled_features.has_type_reflection() &&
11591cb0ef41Sopenharmony_ci               string->StringEquals(v8_str(isolate, "funcref"))) {
11601cb0ef41Sopenharmony_ci      // With the type reflection proposal, "funcref" replaces "anyfunc",
11611cb0ef41Sopenharmony_ci      // and anyfunc just becomes an alias for "funcref".
11621cb0ef41Sopenharmony_ci      type = i::wasm::kWasmFuncRef;
11631cb0ef41Sopenharmony_ci    } else if (string->StringEquals(v8_str(isolate, "externref"))) {
11641cb0ef41Sopenharmony_ci      // externref is known as anyref as of wasm-gc.
11651cb0ef41Sopenharmony_ci      type = i::wasm::kWasmAnyRef;
11661cb0ef41Sopenharmony_ci    } else {
11671cb0ef41Sopenharmony_ci      thrower.TypeError(
11681cb0ef41Sopenharmony_ci          "Descriptor property 'element' must be a WebAssembly reference type");
11691cb0ef41Sopenharmony_ci      return;
11701cb0ef41Sopenharmony_ci    }
11711cb0ef41Sopenharmony_ci  }
11721cb0ef41Sopenharmony_ci
11731cb0ef41Sopenharmony_ci  int64_t initial = 0;
11741cb0ef41Sopenharmony_ci  if (!GetInitialOrMinimumProperty(isolate, &thrower, context, descriptor,
11751cb0ef41Sopenharmony_ci                                   &initial, 0,
11761cb0ef41Sopenharmony_ci                                   i::wasm::max_table_init_entries())) {
11771cb0ef41Sopenharmony_ci    return;
11781cb0ef41Sopenharmony_ci  }
11791cb0ef41Sopenharmony_ci  // The descriptor's 'maximum'.
11801cb0ef41Sopenharmony_ci  int64_t maximum = -1;
11811cb0ef41Sopenharmony_ci  bool has_maximum = true;
11821cb0ef41Sopenharmony_ci  if (!GetOptionalIntegerProperty(isolate, &thrower, context, descriptor,
11831cb0ef41Sopenharmony_ci                                  v8_str(isolate, "maximum"), &has_maximum,
11841cb0ef41Sopenharmony_ci                                  &maximum, initial,
11851cb0ef41Sopenharmony_ci                                  std::numeric_limits<uint32_t>::max())) {
11861cb0ef41Sopenharmony_ci    return;
11871cb0ef41Sopenharmony_ci  }
11881cb0ef41Sopenharmony_ci
11891cb0ef41Sopenharmony_ci  i::Handle<i::FixedArray> fixed_array;
11901cb0ef41Sopenharmony_ci  i::Handle<i::WasmTableObject> table_obj =
11911cb0ef41Sopenharmony_ci      i::WasmTableObject::New(i_isolate, i::Handle<i::WasmInstanceObject>(),
11921cb0ef41Sopenharmony_ci                              type, static_cast<uint32_t>(initial), has_maximum,
11931cb0ef41Sopenharmony_ci                              static_cast<uint32_t>(maximum), &fixed_array,
11941cb0ef41Sopenharmony_ci                              DefaultReferenceValue(i_isolate, type));
11951cb0ef41Sopenharmony_ci
11961cb0ef41Sopenharmony_ci  // The infrastructure for `new Foo` calls allocates an object, which is
11971cb0ef41Sopenharmony_ci  // available here as {args.This()}. We're going to discard this object
11981cb0ef41Sopenharmony_ci  // and use {table_obj} instead, but it does have the correct prototype,
11991cb0ef41Sopenharmony_ci  // which we must harvest from it. This makes a difference when the JS
12001cb0ef41Sopenharmony_ci  // constructor function wasn't {WebAssembly.Table} directly, but some
12011cb0ef41Sopenharmony_ci  // subclass: {table_obj} has {WebAssembly.Table}'s prototype at this
12021cb0ef41Sopenharmony_ci  // point, so we must overwrite that with the correct prototype for {Foo}.
12031cb0ef41Sopenharmony_ci  if (!TransferPrototype(i_isolate, table_obj,
12041cb0ef41Sopenharmony_ci                         Utils::OpenHandle(*args.This()))) {
12051cb0ef41Sopenharmony_ci    return;
12061cb0ef41Sopenharmony_ci  }
12071cb0ef41Sopenharmony_ci
12081cb0ef41Sopenharmony_ci  if (initial > 0 && args.Length() >= 2 && !args[1]->IsUndefined()) {
12091cb0ef41Sopenharmony_ci    i::Handle<i::Object> element = Utils::OpenHandle(*args[1]);
12101cb0ef41Sopenharmony_ci    if (!i::WasmTableObject::IsValidElement(i_isolate, table_obj, element)) {
12111cb0ef41Sopenharmony_ci      thrower.TypeError(
12121cb0ef41Sopenharmony_ci          "Argument 2 must be undefined, null, or a value of type compatible "
12131cb0ef41Sopenharmony_ci          "with the type of the new table.");
12141cb0ef41Sopenharmony_ci      return;
12151cb0ef41Sopenharmony_ci    }
12161cb0ef41Sopenharmony_ci    // TODO(7748): Generalize this if other table types are allowed.
12171cb0ef41Sopenharmony_ci    if (type == i::wasm::kWasmFuncRef && !element->IsNull()) {
12181cb0ef41Sopenharmony_ci      element = i::WasmInternalFunction::FromExternal(element, i_isolate)
12191cb0ef41Sopenharmony_ci                    .ToHandleChecked();
12201cb0ef41Sopenharmony_ci    }
12211cb0ef41Sopenharmony_ci    for (uint32_t index = 0; index < static_cast<uint32_t>(initial); ++index) {
12221cb0ef41Sopenharmony_ci      i::WasmTableObject::Set(i_isolate, table_obj, index, element);
12231cb0ef41Sopenharmony_ci    }
12241cb0ef41Sopenharmony_ci  }
12251cb0ef41Sopenharmony_ci  v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
12261cb0ef41Sopenharmony_ci  return_value.Set(Utils::ToLocal(i::Handle<i::JSObject>::cast(table_obj)));
12271cb0ef41Sopenharmony_ci}
12281cb0ef41Sopenharmony_ci
12291cb0ef41Sopenharmony_civoid WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) {
12301cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
12311cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
12321cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
12331cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Memory()");
12341cb0ef41Sopenharmony_ci  if (!args.IsConstructCall()) {
12351cb0ef41Sopenharmony_ci    thrower.TypeError("WebAssembly.Memory must be invoked with 'new'");
12361cb0ef41Sopenharmony_ci    return;
12371cb0ef41Sopenharmony_ci  }
12381cb0ef41Sopenharmony_ci  if (!args[0]->IsObject()) {
12391cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 must be a memory descriptor");
12401cb0ef41Sopenharmony_ci    return;
12411cb0ef41Sopenharmony_ci  }
12421cb0ef41Sopenharmony_ci  Local<Context> context = isolate->GetCurrentContext();
12431cb0ef41Sopenharmony_ci  Local<v8::Object> descriptor = Local<Object>::Cast(args[0]);
12441cb0ef41Sopenharmony_ci
12451cb0ef41Sopenharmony_ci  int64_t initial = 0;
12461cb0ef41Sopenharmony_ci  if (!GetInitialOrMinimumProperty(isolate, &thrower, context, descriptor,
12471cb0ef41Sopenharmony_ci                                   &initial, 0, i::wasm::kSpecMaxMemoryPages)) {
12481cb0ef41Sopenharmony_ci    return;
12491cb0ef41Sopenharmony_ci  }
12501cb0ef41Sopenharmony_ci  // The descriptor's 'maximum'.
12511cb0ef41Sopenharmony_ci  int64_t maximum = i::WasmMemoryObject::kNoMaximum;
12521cb0ef41Sopenharmony_ci  if (!GetOptionalIntegerProperty(isolate, &thrower, context, descriptor,
12531cb0ef41Sopenharmony_ci                                  v8_str(isolate, "maximum"), nullptr, &maximum,
12541cb0ef41Sopenharmony_ci                                  initial, i::wasm::kSpecMaxMemoryPages)) {
12551cb0ef41Sopenharmony_ci    return;
12561cb0ef41Sopenharmony_ci  }
12571cb0ef41Sopenharmony_ci
12581cb0ef41Sopenharmony_ci  auto shared = i::SharedFlag::kNotShared;
12591cb0ef41Sopenharmony_ci  auto enabled_features = i::wasm::WasmFeatures::FromIsolate(i_isolate);
12601cb0ef41Sopenharmony_ci  if (enabled_features.has_threads()) {
12611cb0ef41Sopenharmony_ci    // Shared property of descriptor
12621cb0ef41Sopenharmony_ci    Local<String> shared_key = v8_str(isolate, "shared");
12631cb0ef41Sopenharmony_ci    v8::MaybeLocal<v8::Value> maybe_value =
12641cb0ef41Sopenharmony_ci        descriptor->Get(context, shared_key);
12651cb0ef41Sopenharmony_ci    v8::Local<v8::Value> value;
12661cb0ef41Sopenharmony_ci    if (maybe_value.ToLocal(&value)) {
12671cb0ef41Sopenharmony_ci      shared = value->BooleanValue(isolate) ? i::SharedFlag::kShared
12681cb0ef41Sopenharmony_ci                                            : i::SharedFlag::kNotShared;
12691cb0ef41Sopenharmony_ci    } else {
12701cb0ef41Sopenharmony_ci      DCHECK(i_isolate->has_scheduled_exception());
12711cb0ef41Sopenharmony_ci      return;
12721cb0ef41Sopenharmony_ci    }
12731cb0ef41Sopenharmony_ci
12741cb0ef41Sopenharmony_ci    // Throw TypeError if shared is true, and the descriptor has no "maximum"
12751cb0ef41Sopenharmony_ci    if (shared == i::SharedFlag::kShared && maximum == -1) {
12761cb0ef41Sopenharmony_ci      thrower.TypeError(
12771cb0ef41Sopenharmony_ci          "If shared is true, maximum property should be defined.");
12781cb0ef41Sopenharmony_ci      return;
12791cb0ef41Sopenharmony_ci    }
12801cb0ef41Sopenharmony_ci  }
12811cb0ef41Sopenharmony_ci
12821cb0ef41Sopenharmony_ci  i::Handle<i::JSObject> memory_obj;
12831cb0ef41Sopenharmony_ci  if (!i::WasmMemoryObject::New(i_isolate, static_cast<int>(initial),
12841cb0ef41Sopenharmony_ci                                static_cast<int>(maximum), shared)
12851cb0ef41Sopenharmony_ci           .ToHandle(&memory_obj)) {
12861cb0ef41Sopenharmony_ci    thrower.RangeError("could not allocate memory");
12871cb0ef41Sopenharmony_ci    return;
12881cb0ef41Sopenharmony_ci  }
12891cb0ef41Sopenharmony_ci
12901cb0ef41Sopenharmony_ci  // The infrastructure for `new Foo` calls allocates an object, which is
12911cb0ef41Sopenharmony_ci  // available here as {args.This()}. We're going to discard this object
12921cb0ef41Sopenharmony_ci  // and use {memory_obj} instead, but it does have the correct prototype,
12931cb0ef41Sopenharmony_ci  // which we must harvest from it. This makes a difference when the JS
12941cb0ef41Sopenharmony_ci  // constructor function wasn't {WebAssembly.Memory} directly, but some
12951cb0ef41Sopenharmony_ci  // subclass: {memory_obj} has {WebAssembly.Memory}'s prototype at this
12961cb0ef41Sopenharmony_ci  // point, so we must overwrite that with the correct prototype for {Foo}.
12971cb0ef41Sopenharmony_ci  if (!TransferPrototype(i_isolate, memory_obj,
12981cb0ef41Sopenharmony_ci                         Utils::OpenHandle(*args.This()))) {
12991cb0ef41Sopenharmony_ci    return;
13001cb0ef41Sopenharmony_ci  }
13011cb0ef41Sopenharmony_ci
13021cb0ef41Sopenharmony_ci  if (shared == i::SharedFlag::kShared) {
13031cb0ef41Sopenharmony_ci    i::Handle<i::JSArrayBuffer> buffer(
13041cb0ef41Sopenharmony_ci        i::Handle<i::WasmMemoryObject>::cast(memory_obj)->array_buffer(),
13051cb0ef41Sopenharmony_ci        i_isolate);
13061cb0ef41Sopenharmony_ci    Maybe<bool> result =
13071cb0ef41Sopenharmony_ci        buffer->SetIntegrityLevel(buffer, i::FROZEN, i::kDontThrow);
13081cb0ef41Sopenharmony_ci    if (!result.FromJust()) {
13091cb0ef41Sopenharmony_ci      thrower.TypeError(
13101cb0ef41Sopenharmony_ci          "Status of setting SetIntegrityLevel of buffer is false.");
13111cb0ef41Sopenharmony_ci      return;
13121cb0ef41Sopenharmony_ci    }
13131cb0ef41Sopenharmony_ci  }
13141cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(Utils::ToLocal(memory_obj));
13151cb0ef41Sopenharmony_ci}
13161cb0ef41Sopenharmony_ci
13171cb0ef41Sopenharmony_ci// Determines the type encoded in a value type property (e.g. type reflection).
13181cb0ef41Sopenharmony_ci// Returns false if there was an exception, true upon success. On success the
13191cb0ef41Sopenharmony_ci// outgoing {type} is set accordingly, or set to {wasm::kWasmVoid} in case the
13201cb0ef41Sopenharmony_ci// type could not be properly recognized.
13211cb0ef41Sopenharmony_cibool GetValueType(Isolate* isolate, MaybeLocal<Value> maybe,
13221cb0ef41Sopenharmony_ci                  Local<Context> context, i::wasm::ValueType* type,
13231cb0ef41Sopenharmony_ci                  i::wasm::WasmFeatures enabled_features) {
13241cb0ef41Sopenharmony_ci  v8::Local<v8::Value> value;
13251cb0ef41Sopenharmony_ci  if (!maybe.ToLocal(&value)) return false;
13261cb0ef41Sopenharmony_ci  v8::Local<v8::String> string;
13271cb0ef41Sopenharmony_ci  if (!value->ToString(context).ToLocal(&string)) return false;
13281cb0ef41Sopenharmony_ci  if (string->StringEquals(v8_str(isolate, "i32"))) {
13291cb0ef41Sopenharmony_ci    *type = i::wasm::kWasmI32;
13301cb0ef41Sopenharmony_ci  } else if (string->StringEquals(v8_str(isolate, "f32"))) {
13311cb0ef41Sopenharmony_ci    *type = i::wasm::kWasmF32;
13321cb0ef41Sopenharmony_ci  } else if (string->StringEquals(v8_str(isolate, "i64"))) {
13331cb0ef41Sopenharmony_ci    *type = i::wasm::kWasmI64;
13341cb0ef41Sopenharmony_ci  } else if (string->StringEquals(v8_str(isolate, "f64"))) {
13351cb0ef41Sopenharmony_ci    *type = i::wasm::kWasmF64;
13361cb0ef41Sopenharmony_ci  } else if (string->StringEquals(v8_str(isolate, "externref"))) {
13371cb0ef41Sopenharmony_ci    *type = i::wasm::kWasmAnyRef;
13381cb0ef41Sopenharmony_ci  } else if (enabled_features.has_type_reflection() &&
13391cb0ef41Sopenharmony_ci             string->StringEquals(v8_str(isolate, "funcref"))) {
13401cb0ef41Sopenharmony_ci    // The type reflection proposal renames "anyfunc" to "funcref", and makes
13411cb0ef41Sopenharmony_ci    // "anyfunc" an alias of "funcref".
13421cb0ef41Sopenharmony_ci    *type = i::wasm::kWasmFuncRef;
13431cb0ef41Sopenharmony_ci  } else if (string->StringEquals(v8_str(isolate, "anyfunc"))) {
13441cb0ef41Sopenharmony_ci    // The JS api spec uses 'anyfunc' instead of 'funcref'.
13451cb0ef41Sopenharmony_ci    *type = i::wasm::kWasmFuncRef;
13461cb0ef41Sopenharmony_ci  } else if (enabled_features.has_gc() &&
13471cb0ef41Sopenharmony_ci             string->StringEquals(v8_str(isolate, "eqref"))) {
13481cb0ef41Sopenharmony_ci    *type = i::wasm::kWasmEqRef;
13491cb0ef41Sopenharmony_ci  } else {
13501cb0ef41Sopenharmony_ci    // Unrecognized type.
13511cb0ef41Sopenharmony_ci    *type = i::wasm::kWasmVoid;
13521cb0ef41Sopenharmony_ci  }
13531cb0ef41Sopenharmony_ci  return true;
13541cb0ef41Sopenharmony_ci}
13551cb0ef41Sopenharmony_ci
13561cb0ef41Sopenharmony_cinamespace {
13571cb0ef41Sopenharmony_ci
13581cb0ef41Sopenharmony_cibool ToI32(Local<v8::Value> value, Local<Context> context, int32_t* i32_value) {
13591cb0ef41Sopenharmony_ci  if (!value->IsUndefined()) {
13601cb0ef41Sopenharmony_ci    v8::Local<v8::Int32> int32_value;
13611cb0ef41Sopenharmony_ci    if (!value->ToInt32(context).ToLocal(&int32_value)) return false;
13621cb0ef41Sopenharmony_ci    if (!int32_value->Int32Value(context).To(i32_value)) return false;
13631cb0ef41Sopenharmony_ci  }
13641cb0ef41Sopenharmony_ci  return true;
13651cb0ef41Sopenharmony_ci}
13661cb0ef41Sopenharmony_ci
13671cb0ef41Sopenharmony_cibool ToI64(Local<v8::Value> value, Local<Context> context, int64_t* i64_value) {
13681cb0ef41Sopenharmony_ci  if (!value->IsUndefined()) {
13691cb0ef41Sopenharmony_ci    v8::Local<v8::BigInt> bigint_value;
13701cb0ef41Sopenharmony_ci    if (!value->ToBigInt(context).ToLocal(&bigint_value)) return false;
13711cb0ef41Sopenharmony_ci    *i64_value = bigint_value->Int64Value();
13721cb0ef41Sopenharmony_ci  }
13731cb0ef41Sopenharmony_ci  return true;
13741cb0ef41Sopenharmony_ci}
13751cb0ef41Sopenharmony_ci
13761cb0ef41Sopenharmony_cibool ToF32(Local<v8::Value> value, Local<Context> context, float* f32_value) {
13771cb0ef41Sopenharmony_ci  if (!value->IsUndefined()) {
13781cb0ef41Sopenharmony_ci    double f64_value = 0;
13791cb0ef41Sopenharmony_ci    v8::Local<v8::Number> number_value;
13801cb0ef41Sopenharmony_ci    if (!value->ToNumber(context).ToLocal(&number_value)) return false;
13811cb0ef41Sopenharmony_ci    if (!number_value->NumberValue(context).To(&f64_value)) return false;
13821cb0ef41Sopenharmony_ci    *f32_value = i::DoubleToFloat32(f64_value);
13831cb0ef41Sopenharmony_ci  }
13841cb0ef41Sopenharmony_ci  return true;
13851cb0ef41Sopenharmony_ci}
13861cb0ef41Sopenharmony_ci
13871cb0ef41Sopenharmony_cibool ToF64(Local<v8::Value> value, Local<Context> context, double* f64_value) {
13881cb0ef41Sopenharmony_ci  if (!value->IsUndefined()) {
13891cb0ef41Sopenharmony_ci    v8::Local<v8::Number> number_value;
13901cb0ef41Sopenharmony_ci    if (!value->ToNumber(context).ToLocal(&number_value)) return false;
13911cb0ef41Sopenharmony_ci    if (!number_value->NumberValue(context).To(f64_value)) return false;
13921cb0ef41Sopenharmony_ci  }
13931cb0ef41Sopenharmony_ci  return true;
13941cb0ef41Sopenharmony_ci}
13951cb0ef41Sopenharmony_ci
13961cb0ef41Sopenharmony_ci}  // namespace
13971cb0ef41Sopenharmony_ci
13981cb0ef41Sopenharmony_ci// WebAssembly.Global
13991cb0ef41Sopenharmony_civoid WebAssemblyGlobal(const v8::FunctionCallbackInfo<v8::Value>& args) {
14001cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
14011cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
14021cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
14031cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Global()");
14041cb0ef41Sopenharmony_ci  if (!args.IsConstructCall()) {
14051cb0ef41Sopenharmony_ci    thrower.TypeError("WebAssembly.Global must be invoked with 'new'");
14061cb0ef41Sopenharmony_ci    return;
14071cb0ef41Sopenharmony_ci  }
14081cb0ef41Sopenharmony_ci  if (!args[0]->IsObject()) {
14091cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 must be a global descriptor");
14101cb0ef41Sopenharmony_ci    return;
14111cb0ef41Sopenharmony_ci  }
14121cb0ef41Sopenharmony_ci  Local<Context> context = isolate->GetCurrentContext();
14131cb0ef41Sopenharmony_ci  Local<v8::Object> descriptor = Local<Object>::Cast(args[0]);
14141cb0ef41Sopenharmony_ci  auto enabled_features = i::wasm::WasmFeatures::FromIsolate(i_isolate);
14151cb0ef41Sopenharmony_ci
14161cb0ef41Sopenharmony_ci  // The descriptor's 'mutable'.
14171cb0ef41Sopenharmony_ci  bool is_mutable = false;
14181cb0ef41Sopenharmony_ci  {
14191cb0ef41Sopenharmony_ci    Local<String> mutable_key = v8_str(isolate, "mutable");
14201cb0ef41Sopenharmony_ci    v8::MaybeLocal<v8::Value> maybe = descriptor->Get(context, mutable_key);
14211cb0ef41Sopenharmony_ci    v8::Local<v8::Value> value;
14221cb0ef41Sopenharmony_ci    if (maybe.ToLocal(&value)) {
14231cb0ef41Sopenharmony_ci      is_mutable = value->BooleanValue(isolate);
14241cb0ef41Sopenharmony_ci    } else {
14251cb0ef41Sopenharmony_ci      DCHECK(i_isolate->has_scheduled_exception());
14261cb0ef41Sopenharmony_ci      return;
14271cb0ef41Sopenharmony_ci    }
14281cb0ef41Sopenharmony_ci  }
14291cb0ef41Sopenharmony_ci
14301cb0ef41Sopenharmony_ci  // The descriptor's type, called 'value'. It is called 'value' because this
14311cb0ef41Sopenharmony_ci  // descriptor is planned to be re-used as the global's type for reflection,
14321cb0ef41Sopenharmony_ci  // so calling it 'type' is redundant.
14331cb0ef41Sopenharmony_ci  i::wasm::ValueType type;
14341cb0ef41Sopenharmony_ci  {
14351cb0ef41Sopenharmony_ci    v8::MaybeLocal<v8::Value> maybe =
14361cb0ef41Sopenharmony_ci        descriptor->Get(context, v8_str(isolate, "value"));
14371cb0ef41Sopenharmony_ci    if (!GetValueType(isolate, maybe, context, &type, enabled_features)) return;
14381cb0ef41Sopenharmony_ci    if (type == i::wasm::kWasmVoid) {
14391cb0ef41Sopenharmony_ci      thrower.TypeError(
14401cb0ef41Sopenharmony_ci          "Descriptor property 'value' must be a WebAssembly type");
14411cb0ef41Sopenharmony_ci      return;
14421cb0ef41Sopenharmony_ci    }
14431cb0ef41Sopenharmony_ci  }
14441cb0ef41Sopenharmony_ci
14451cb0ef41Sopenharmony_ci  const uint32_t offset = 0;
14461cb0ef41Sopenharmony_ci  i::MaybeHandle<i::WasmGlobalObject> maybe_global_obj =
14471cb0ef41Sopenharmony_ci      i::WasmGlobalObject::New(i_isolate, i::Handle<i::WasmInstanceObject>(),
14481cb0ef41Sopenharmony_ci                               i::MaybeHandle<i::JSArrayBuffer>(),
14491cb0ef41Sopenharmony_ci                               i::MaybeHandle<i::FixedArray>(), type, offset,
14501cb0ef41Sopenharmony_ci                               is_mutable);
14511cb0ef41Sopenharmony_ci
14521cb0ef41Sopenharmony_ci  i::Handle<i::WasmGlobalObject> global_obj;
14531cb0ef41Sopenharmony_ci  if (!maybe_global_obj.ToHandle(&global_obj)) {
14541cb0ef41Sopenharmony_ci    thrower.RangeError("could not allocate memory");
14551cb0ef41Sopenharmony_ci    return;
14561cb0ef41Sopenharmony_ci  }
14571cb0ef41Sopenharmony_ci
14581cb0ef41Sopenharmony_ci  // The infrastructure for `new Foo` calls allocates an object, which is
14591cb0ef41Sopenharmony_ci  // available here as {args.This()}. We're going to discard this object
14601cb0ef41Sopenharmony_ci  // and use {global_obj} instead, but it does have the correct prototype,
14611cb0ef41Sopenharmony_ci  // which we must harvest from it. This makes a difference when the JS
14621cb0ef41Sopenharmony_ci  // constructor function wasn't {WebAssembly.Global} directly, but some
14631cb0ef41Sopenharmony_ci  // subclass: {global_obj} has {WebAssembly.Global}'s prototype at this
14641cb0ef41Sopenharmony_ci  // point, so we must overwrite that with the correct prototype for {Foo}.
14651cb0ef41Sopenharmony_ci  if (!TransferPrototype(i_isolate, global_obj,
14661cb0ef41Sopenharmony_ci                         Utils::OpenHandle(*args.This()))) {
14671cb0ef41Sopenharmony_ci    return;
14681cb0ef41Sopenharmony_ci  }
14691cb0ef41Sopenharmony_ci
14701cb0ef41Sopenharmony_ci  // Convert value to a WebAssembly value, the default value is 0.
14711cb0ef41Sopenharmony_ci  Local<v8::Value> value = Local<Value>::Cast(args[1]);
14721cb0ef41Sopenharmony_ci  switch (type.kind()) {
14731cb0ef41Sopenharmony_ci    case i::wasm::kI32: {
14741cb0ef41Sopenharmony_ci      int32_t i32_value = 0;
14751cb0ef41Sopenharmony_ci      if (!ToI32(value, context, &i32_value)) return;
14761cb0ef41Sopenharmony_ci      global_obj->SetI32(i32_value);
14771cb0ef41Sopenharmony_ci      break;
14781cb0ef41Sopenharmony_ci    }
14791cb0ef41Sopenharmony_ci    case i::wasm::kI64: {
14801cb0ef41Sopenharmony_ci      int64_t i64_value = 0;
14811cb0ef41Sopenharmony_ci      if (!ToI64(value, context, &i64_value)) return;
14821cb0ef41Sopenharmony_ci      global_obj->SetI64(i64_value);
14831cb0ef41Sopenharmony_ci      break;
14841cb0ef41Sopenharmony_ci    }
14851cb0ef41Sopenharmony_ci    case i::wasm::kF32: {
14861cb0ef41Sopenharmony_ci      float f32_value = 0;
14871cb0ef41Sopenharmony_ci      if (!ToF32(value, context, &f32_value)) return;
14881cb0ef41Sopenharmony_ci      global_obj->SetF32(f32_value);
14891cb0ef41Sopenharmony_ci      break;
14901cb0ef41Sopenharmony_ci    }
14911cb0ef41Sopenharmony_ci    case i::wasm::kF64: {
14921cb0ef41Sopenharmony_ci      double f64_value = 0;
14931cb0ef41Sopenharmony_ci      if (!ToF64(value, context, &f64_value)) return;
14941cb0ef41Sopenharmony_ci      global_obj->SetF64(f64_value);
14951cb0ef41Sopenharmony_ci      break;
14961cb0ef41Sopenharmony_ci    }
14971cb0ef41Sopenharmony_ci    case i::wasm::kRef:
14981cb0ef41Sopenharmony_ci    case i::wasm::kOptRef: {
14991cb0ef41Sopenharmony_ci      switch (type.heap_representation()) {
15001cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kAny: {
15011cb0ef41Sopenharmony_ci          if (args.Length() < 2) {
15021cb0ef41Sopenharmony_ci            // When no initial value is provided, we have to use the WebAssembly
15031cb0ef41Sopenharmony_ci            // default value 'null', and not the JS default value 'undefined'.
15041cb0ef41Sopenharmony_ci            global_obj->SetExternRef(i_isolate->factory()->null_value());
15051cb0ef41Sopenharmony_ci            break;
15061cb0ef41Sopenharmony_ci          }
15071cb0ef41Sopenharmony_ci          global_obj->SetExternRef(Utils::OpenHandle(*value));
15081cb0ef41Sopenharmony_ci          break;
15091cb0ef41Sopenharmony_ci        }
15101cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kFunc: {
15111cb0ef41Sopenharmony_ci          if (args.Length() < 2) {
15121cb0ef41Sopenharmony_ci            // When no initial value is provided, we have to use the WebAssembly
15131cb0ef41Sopenharmony_ci            // default value 'null', and not the JS default value 'undefined'.
15141cb0ef41Sopenharmony_ci            global_obj->SetFuncRef(i_isolate,
15151cb0ef41Sopenharmony_ci                                   i_isolate->factory()->null_value());
15161cb0ef41Sopenharmony_ci            break;
15171cb0ef41Sopenharmony_ci          }
15181cb0ef41Sopenharmony_ci
15191cb0ef41Sopenharmony_ci          if (!global_obj->SetFuncRef(i_isolate, Utils::OpenHandle(*value))) {
15201cb0ef41Sopenharmony_ci            thrower.TypeError(
15211cb0ef41Sopenharmony_ci                "The value of funcref globals must be null or an "
15221cb0ef41Sopenharmony_ci                "exported function");
15231cb0ef41Sopenharmony_ci          }
15241cb0ef41Sopenharmony_ci          break;
15251cb0ef41Sopenharmony_ci        }
15261cb0ef41Sopenharmony_ci        case internal::wasm::HeapType::kBottom:
15271cb0ef41Sopenharmony_ci          UNREACHABLE();
15281cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kEq:
15291cb0ef41Sopenharmony_ci        case internal::wasm::HeapType::kI31:
15301cb0ef41Sopenharmony_ci        case internal::wasm::HeapType::kData:
15311cb0ef41Sopenharmony_ci        case internal::wasm::HeapType::kArray:
15321cb0ef41Sopenharmony_ci        default:
15331cb0ef41Sopenharmony_ci          // TODO(7748): Implement these.
15341cb0ef41Sopenharmony_ci          UNIMPLEMENTED();
15351cb0ef41Sopenharmony_ci      }
15361cb0ef41Sopenharmony_ci      break;
15371cb0ef41Sopenharmony_ci    }
15381cb0ef41Sopenharmony_ci    case i::wasm::kRtt:
15391cb0ef41Sopenharmony_ci      // TODO(7748): Implement.
15401cb0ef41Sopenharmony_ci      UNIMPLEMENTED();
15411cb0ef41Sopenharmony_ci    case i::wasm::kI8:
15421cb0ef41Sopenharmony_ci    case i::wasm::kI16:
15431cb0ef41Sopenharmony_ci    case i::wasm::kVoid:
15441cb0ef41Sopenharmony_ci    case i::wasm::kS128:
15451cb0ef41Sopenharmony_ci    case i::wasm::kBottom:
15461cb0ef41Sopenharmony_ci      UNREACHABLE();
15471cb0ef41Sopenharmony_ci  }
15481cb0ef41Sopenharmony_ci
15491cb0ef41Sopenharmony_ci  i::Handle<i::JSObject> global_js_object(global_obj);
15501cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(Utils::ToLocal(global_js_object));
15511cb0ef41Sopenharmony_ci}
15521cb0ef41Sopenharmony_ci
15531cb0ef41Sopenharmony_cinamespace {
15541cb0ef41Sopenharmony_ci
15551cb0ef41Sopenharmony_ciuint32_t GetIterableLength(i::Isolate* isolate, Local<Context> context,
15561cb0ef41Sopenharmony_ci                           Local<Object> iterable) {
15571cb0ef41Sopenharmony_ci  Local<String> length = Utils::ToLocal(isolate->factory()->length_string());
15581cb0ef41Sopenharmony_ci  MaybeLocal<Value> property = iterable->Get(context, length);
15591cb0ef41Sopenharmony_ci  if (property.IsEmpty()) return i::kMaxUInt32;
15601cb0ef41Sopenharmony_ci  MaybeLocal<Uint32> number = property.ToLocalChecked()->ToArrayIndex(context);
15611cb0ef41Sopenharmony_ci  if (number.IsEmpty()) return i::kMaxUInt32;
15621cb0ef41Sopenharmony_ci  DCHECK_NE(i::kMaxUInt32, number.ToLocalChecked()->Value());
15631cb0ef41Sopenharmony_ci  return number.ToLocalChecked()->Value();
15641cb0ef41Sopenharmony_ci}
15651cb0ef41Sopenharmony_ci
15661cb0ef41Sopenharmony_ci}  // namespace
15671cb0ef41Sopenharmony_ci
15681cb0ef41Sopenharmony_ci// WebAssembly.Tag
15691cb0ef41Sopenharmony_civoid WebAssemblyTag(const v8::FunctionCallbackInfo<v8::Value>& args) {
15701cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
15711cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
15721cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
15731cb0ef41Sopenharmony_ci
15741cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Tag()");
15751cb0ef41Sopenharmony_ci  if (!args.IsConstructCall()) {
15761cb0ef41Sopenharmony_ci    thrower.TypeError("WebAssembly.Tag must be invoked with 'new'");
15771cb0ef41Sopenharmony_ci    return;
15781cb0ef41Sopenharmony_ci  }
15791cb0ef41Sopenharmony_ci  if (!args[0]->IsObject()) {
15801cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 must be a tag type");
15811cb0ef41Sopenharmony_ci    return;
15821cb0ef41Sopenharmony_ci  }
15831cb0ef41Sopenharmony_ci
15841cb0ef41Sopenharmony_ci  Local<Object> event_type = Local<Object>::Cast(args[0]);
15851cb0ef41Sopenharmony_ci  Local<Context> context = isolate->GetCurrentContext();
15861cb0ef41Sopenharmony_ci  auto enabled_features = i::wasm::WasmFeatures::FromIsolate(i_isolate);
15871cb0ef41Sopenharmony_ci
15881cb0ef41Sopenharmony_ci  // Load the 'parameters' property of the event type.
15891cb0ef41Sopenharmony_ci  Local<String> parameters_key = v8_str(isolate, "parameters");
15901cb0ef41Sopenharmony_ci  v8::MaybeLocal<v8::Value> parameters_maybe =
15911cb0ef41Sopenharmony_ci      event_type->Get(context, parameters_key);
15921cb0ef41Sopenharmony_ci  v8::Local<v8::Value> parameters_value;
15931cb0ef41Sopenharmony_ci  if (!parameters_maybe.ToLocal(&parameters_value) ||
15941cb0ef41Sopenharmony_ci      !parameters_value->IsObject()) {
15951cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 must be a tag type with 'parameters'");
15961cb0ef41Sopenharmony_ci    return;
15971cb0ef41Sopenharmony_ci  }
15981cb0ef41Sopenharmony_ci  Local<Object> parameters = parameters_value.As<Object>();
15991cb0ef41Sopenharmony_ci  uint32_t parameters_len = GetIterableLength(i_isolate, context, parameters);
16001cb0ef41Sopenharmony_ci  if (parameters_len == i::kMaxUInt32) {
16011cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 contains parameters without 'length'");
16021cb0ef41Sopenharmony_ci    return;
16031cb0ef41Sopenharmony_ci  }
16041cb0ef41Sopenharmony_ci  if (parameters_len > i::wasm::kV8MaxWasmFunctionParams) {
16051cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 contains too many parameters");
16061cb0ef41Sopenharmony_ci    return;
16071cb0ef41Sopenharmony_ci  }
16081cb0ef41Sopenharmony_ci
16091cb0ef41Sopenharmony_ci  // Decode the tag type and construct a signature.
16101cb0ef41Sopenharmony_ci  std::vector<i::wasm::ValueType> param_types(parameters_len,
16111cb0ef41Sopenharmony_ci                                              i::wasm::kWasmVoid);
16121cb0ef41Sopenharmony_ci  for (uint32_t i = 0; i < parameters_len; ++i) {
16131cb0ef41Sopenharmony_ci    i::wasm::ValueType& type = param_types[i];
16141cb0ef41Sopenharmony_ci    MaybeLocal<Value> maybe = parameters->Get(context, i);
16151cb0ef41Sopenharmony_ci    if (!GetValueType(isolate, maybe, context, &type, enabled_features) ||
16161cb0ef41Sopenharmony_ci        type == i::wasm::kWasmVoid) {
16171cb0ef41Sopenharmony_ci      thrower.TypeError(
16181cb0ef41Sopenharmony_ci          "Argument 0 parameter type at index #%u must be a value type", i);
16191cb0ef41Sopenharmony_ci      return;
16201cb0ef41Sopenharmony_ci    }
16211cb0ef41Sopenharmony_ci  }
16221cb0ef41Sopenharmony_ci  const i::wasm::FunctionSig sig{0, parameters_len, param_types.data()};
16231cb0ef41Sopenharmony_ci  // Set the tag index to 0. It is only used for debugging purposes, and has no
16241cb0ef41Sopenharmony_ci  // meaningful value when declared outside of a wasm module.
16251cb0ef41Sopenharmony_ci  auto tag = i::WasmExceptionTag::New(i_isolate, 0);
16261cb0ef41Sopenharmony_ci  i::Handle<i::JSObject> tag_object =
16271cb0ef41Sopenharmony_ci      i::WasmTagObject::New(i_isolate, &sig, tag);
16281cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(Utils::ToLocal(tag_object));
16291cb0ef41Sopenharmony_ci}
16301cb0ef41Sopenharmony_ci
16311cb0ef41Sopenharmony_ci// WebAssembly.Suspender
16321cb0ef41Sopenharmony_civoid WebAssemblySuspender(const v8::FunctionCallbackInfo<v8::Value>& args) {
16331cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
16341cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
16351cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
16361cb0ef41Sopenharmony_ci
16371cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Suspender()");
16381cb0ef41Sopenharmony_ci  if (!args.IsConstructCall()) {
16391cb0ef41Sopenharmony_ci    thrower.TypeError("WebAssembly.Suspender must be invoked with 'new'");
16401cb0ef41Sopenharmony_ci    return;
16411cb0ef41Sopenharmony_ci  }
16421cb0ef41Sopenharmony_ci
16431cb0ef41Sopenharmony_ci  i::Handle<i::JSObject> suspender = i::WasmSuspenderObject::New(i_isolate);
16441cb0ef41Sopenharmony_ci
16451cb0ef41Sopenharmony_ci  // The infrastructure for `new Foo` calls allocates an object, which is
16461cb0ef41Sopenharmony_ci  // available here as {args.This()}. We're going to discard this object
16471cb0ef41Sopenharmony_ci  // and use {suspender} instead, but it does have the correct prototype,
16481cb0ef41Sopenharmony_ci  // which we must harvest from it. This makes a difference when the JS
16491cb0ef41Sopenharmony_ci  // constructor function wasn't {WebAssembly.Suspender} directly, but some
16501cb0ef41Sopenharmony_ci  // subclass: {suspender} has {WebAssembly.Suspender}'s prototype at this
16511cb0ef41Sopenharmony_ci  // point, so we must overwrite that with the correct prototype for {Foo}.
16521cb0ef41Sopenharmony_ci  if (!TransferPrototype(i_isolate, suspender,
16531cb0ef41Sopenharmony_ci                         Utils::OpenHandle(*args.This()))) {
16541cb0ef41Sopenharmony_ci    return;
16551cb0ef41Sopenharmony_ci  }
16561cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(Utils::ToLocal(suspender));
16571cb0ef41Sopenharmony_ci}
16581cb0ef41Sopenharmony_ci
16591cb0ef41Sopenharmony_cinamespace {
16601cb0ef41Sopenharmony_ci
16611cb0ef41Sopenharmony_ciuint32_t GetEncodedSize(i::Handle<i::WasmTagObject> tag_object) {
16621cb0ef41Sopenharmony_ci  auto serialized_sig = tag_object->serialized_signature();
16631cb0ef41Sopenharmony_ci  i::wasm::WasmTagSig sig{0, static_cast<size_t>(serialized_sig.length()),
16641cb0ef41Sopenharmony_ci                          reinterpret_cast<i::wasm::ValueType*>(
16651cb0ef41Sopenharmony_ci                              serialized_sig.GetDataStartAddress())};
16661cb0ef41Sopenharmony_ci  i::wasm::WasmTag tag(&sig);
16671cb0ef41Sopenharmony_ci  return i::WasmExceptionPackage::GetEncodedSize(&tag);
16681cb0ef41Sopenharmony_ci}
16691cb0ef41Sopenharmony_ci
16701cb0ef41Sopenharmony_civoid EncodeExceptionValues(v8::Isolate* isolate,
16711cb0ef41Sopenharmony_ci                           i::Handle<i::PodArray<i::wasm::ValueType>> signature,
16721cb0ef41Sopenharmony_ci                           const Local<Value>& arg,
16731cb0ef41Sopenharmony_ci                           ScheduledErrorThrower* thrower,
16741cb0ef41Sopenharmony_ci                           i::Handle<i::FixedArray> values_out) {
16751cb0ef41Sopenharmony_ci  Local<Context> context = isolate->GetCurrentContext();
16761cb0ef41Sopenharmony_ci  uint32_t index = 0;
16771cb0ef41Sopenharmony_ci  if (!arg->IsObject()) {
16781cb0ef41Sopenharmony_ci    thrower->TypeError("Exception values must be an iterable object");
16791cb0ef41Sopenharmony_ci    return;
16801cb0ef41Sopenharmony_ci  }
16811cb0ef41Sopenharmony_ci  auto values = arg.As<Object>();
16821cb0ef41Sopenharmony_ci  for (int i = 0; i < signature->length(); ++i) {
16831cb0ef41Sopenharmony_ci    MaybeLocal<Value> maybe_value = values->Get(context, i);
16841cb0ef41Sopenharmony_ci    Local<Value> value = maybe_value.ToLocalChecked();
16851cb0ef41Sopenharmony_ci    i::wasm::ValueType type = signature->get(i);
16861cb0ef41Sopenharmony_ci    switch (type.kind()) {
16871cb0ef41Sopenharmony_ci      case i::wasm::kI32: {
16881cb0ef41Sopenharmony_ci        int32_t i32 = 0;
16891cb0ef41Sopenharmony_ci        if (!ToI32(value, context, &i32)) return;
16901cb0ef41Sopenharmony_ci        i::EncodeI32ExceptionValue(values_out, &index, i32);
16911cb0ef41Sopenharmony_ci        break;
16921cb0ef41Sopenharmony_ci      }
16931cb0ef41Sopenharmony_ci      case i::wasm::kI64: {
16941cb0ef41Sopenharmony_ci        int64_t i64 = 0;
16951cb0ef41Sopenharmony_ci        if (!ToI64(value, context, &i64)) return;
16961cb0ef41Sopenharmony_ci        i::EncodeI64ExceptionValue(values_out, &index, i64);
16971cb0ef41Sopenharmony_ci        break;
16981cb0ef41Sopenharmony_ci      }
16991cb0ef41Sopenharmony_ci      case i::wasm::kF32: {
17001cb0ef41Sopenharmony_ci        float f32 = 0;
17011cb0ef41Sopenharmony_ci        if (!ToF32(value, context, &f32)) return;
17021cb0ef41Sopenharmony_ci        int32_t i32 = bit_cast<int32_t>(f32);
17031cb0ef41Sopenharmony_ci        i::EncodeI32ExceptionValue(values_out, &index, i32);
17041cb0ef41Sopenharmony_ci        break;
17051cb0ef41Sopenharmony_ci      }
17061cb0ef41Sopenharmony_ci      case i::wasm::kF64: {
17071cb0ef41Sopenharmony_ci        double f64 = 0;
17081cb0ef41Sopenharmony_ci        if (!ToF64(value, context, &f64)) return;
17091cb0ef41Sopenharmony_ci        int64_t i64 = bit_cast<int64_t>(f64);
17101cb0ef41Sopenharmony_ci        i::EncodeI64ExceptionValue(values_out, &index, i64);
17111cb0ef41Sopenharmony_ci        break;
17121cb0ef41Sopenharmony_ci      }
17131cb0ef41Sopenharmony_ci      case i::wasm::kRef:
17141cb0ef41Sopenharmony_ci      case i::wasm::kOptRef:
17151cb0ef41Sopenharmony_ci        switch (type.heap_representation()) {
17161cb0ef41Sopenharmony_ci          case i::wasm::HeapType::kFunc:
17171cb0ef41Sopenharmony_ci          case i::wasm::HeapType::kAny:
17181cb0ef41Sopenharmony_ci          case i::wasm::HeapType::kEq:
17191cb0ef41Sopenharmony_ci          case i::wasm::HeapType::kI31:
17201cb0ef41Sopenharmony_ci          case i::wasm::HeapType::kData:
17211cb0ef41Sopenharmony_ci          case i::wasm::HeapType::kArray:
17221cb0ef41Sopenharmony_ci            values_out->set(index++, *Utils::OpenHandle(*value));
17231cb0ef41Sopenharmony_ci            break;
17241cb0ef41Sopenharmony_ci          case internal::wasm::HeapType::kBottom:
17251cb0ef41Sopenharmony_ci            UNREACHABLE();
17261cb0ef41Sopenharmony_ci          default:
17271cb0ef41Sopenharmony_ci            // TODO(7748): Add support for custom struct/array types.
17281cb0ef41Sopenharmony_ci            UNIMPLEMENTED();
17291cb0ef41Sopenharmony_ci        }
17301cb0ef41Sopenharmony_ci        break;
17311cb0ef41Sopenharmony_ci      case i::wasm::kRtt:
17321cb0ef41Sopenharmony_ci      case i::wasm::kI8:
17331cb0ef41Sopenharmony_ci      case i::wasm::kI16:
17341cb0ef41Sopenharmony_ci      case i::wasm::kVoid:
17351cb0ef41Sopenharmony_ci      case i::wasm::kBottom:
17361cb0ef41Sopenharmony_ci      case i::wasm::kS128:
17371cb0ef41Sopenharmony_ci        UNREACHABLE();
17381cb0ef41Sopenharmony_ci    }
17391cb0ef41Sopenharmony_ci  }
17401cb0ef41Sopenharmony_ci}
17411cb0ef41Sopenharmony_ci
17421cb0ef41Sopenharmony_ci}  // namespace
17431cb0ef41Sopenharmony_ci
17441cb0ef41Sopenharmony_civoid WebAssemblyException(const v8::FunctionCallbackInfo<v8::Value>& args) {
17451cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
17461cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
17471cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
17481cb0ef41Sopenharmony_ci
17491cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Exception()");
17501cb0ef41Sopenharmony_ci  if (!args.IsConstructCall()) {
17511cb0ef41Sopenharmony_ci    thrower.TypeError("WebAssembly.Exception must be invoked with 'new'");
17521cb0ef41Sopenharmony_ci    return;
17531cb0ef41Sopenharmony_ci  }
17541cb0ef41Sopenharmony_ci  if (!args[0]->IsObject()) {
17551cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 must be a WebAssembly tag");
17561cb0ef41Sopenharmony_ci    return;
17571cb0ef41Sopenharmony_ci  }
17581cb0ef41Sopenharmony_ci  i::Handle<i::Object> arg0 = Utils::OpenHandle(*args[0]);
17591cb0ef41Sopenharmony_ci  if (!i::HeapObject::cast(*arg0).IsWasmTagObject()) {
17601cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 must be a WebAssembly tag");
17611cb0ef41Sopenharmony_ci    return;
17621cb0ef41Sopenharmony_ci  }
17631cb0ef41Sopenharmony_ci  i::Handle<i::WasmTagObject> tag_object =
17641cb0ef41Sopenharmony_ci      i::Handle<i::WasmTagObject>::cast(arg0);
17651cb0ef41Sopenharmony_ci  i::Handle<i::WasmExceptionTag> tag(
17661cb0ef41Sopenharmony_ci      i::WasmExceptionTag::cast(tag_object->tag()), i_isolate);
17671cb0ef41Sopenharmony_ci  uint32_t size = GetEncodedSize(tag_object);
17681cb0ef41Sopenharmony_ci  i::Handle<i::WasmExceptionPackage> runtime_exception =
17691cb0ef41Sopenharmony_ci      i::WasmExceptionPackage::New(i_isolate, tag, size);
17701cb0ef41Sopenharmony_ci  // The constructor above should guarantee that the cast below succeeds.
17711cb0ef41Sopenharmony_ci  i::Handle<i::FixedArray> values = i::Handle<i::FixedArray>::cast(
17721cb0ef41Sopenharmony_ci      i::WasmExceptionPackage::GetExceptionValues(i_isolate,
17731cb0ef41Sopenharmony_ci                                                  runtime_exception));
17741cb0ef41Sopenharmony_ci  i::Handle<i::PodArray<i::wasm::ValueType>> signature(
17751cb0ef41Sopenharmony_ci      tag_object->serialized_signature(), i_isolate);
17761cb0ef41Sopenharmony_ci  EncodeExceptionValues(isolate, signature, args[1], &thrower, values);
17771cb0ef41Sopenharmony_ci  if (thrower.error()) return;
17781cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(
17791cb0ef41Sopenharmony_ci      Utils::ToLocal(i::Handle<i::Object>::cast(runtime_exception)));
17801cb0ef41Sopenharmony_ci}
17811cb0ef41Sopenharmony_ci
17821cb0ef41Sopenharmony_ci// WebAssembly.Function
17831cb0ef41Sopenharmony_civoid WebAssemblyFunction(const v8::FunctionCallbackInfo<v8::Value>& args) {
17841cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
17851cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
17861cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
17871cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Function()");
17881cb0ef41Sopenharmony_ci  if (!args.IsConstructCall()) {
17891cb0ef41Sopenharmony_ci    thrower.TypeError("WebAssembly.Function must be invoked with 'new'");
17901cb0ef41Sopenharmony_ci    return;
17911cb0ef41Sopenharmony_ci  }
17921cb0ef41Sopenharmony_ci  if (!args[0]->IsObject()) {
17931cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 must be a function type");
17941cb0ef41Sopenharmony_ci    return;
17951cb0ef41Sopenharmony_ci  }
17961cb0ef41Sopenharmony_ci  Local<Object> function_type = Local<Object>::Cast(args[0]);
17971cb0ef41Sopenharmony_ci  Local<Context> context = isolate->GetCurrentContext();
17981cb0ef41Sopenharmony_ci  auto enabled_features = i::wasm::WasmFeatures::FromIsolate(i_isolate);
17991cb0ef41Sopenharmony_ci
18001cb0ef41Sopenharmony_ci  // Load the 'parameters' property of the function type.
18011cb0ef41Sopenharmony_ci  Local<String> parameters_key = v8_str(isolate, "parameters");
18021cb0ef41Sopenharmony_ci  v8::MaybeLocal<v8::Value> parameters_maybe =
18031cb0ef41Sopenharmony_ci      function_type->Get(context, parameters_key);
18041cb0ef41Sopenharmony_ci  v8::Local<v8::Value> parameters_value;
18051cb0ef41Sopenharmony_ci  if (!parameters_maybe.ToLocal(&parameters_value) ||
18061cb0ef41Sopenharmony_ci      !parameters_value->IsObject()) {
18071cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 must be a function type with 'parameters'");
18081cb0ef41Sopenharmony_ci    return;
18091cb0ef41Sopenharmony_ci  }
18101cb0ef41Sopenharmony_ci  Local<Object> parameters = parameters_value.As<Object>();
18111cb0ef41Sopenharmony_ci  uint32_t parameters_len = GetIterableLength(i_isolate, context, parameters);
18121cb0ef41Sopenharmony_ci  if (parameters_len == i::kMaxUInt32) {
18131cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 contains parameters without 'length'");
18141cb0ef41Sopenharmony_ci    return;
18151cb0ef41Sopenharmony_ci  }
18161cb0ef41Sopenharmony_ci  if (parameters_len > i::wasm::kV8MaxWasmFunctionParams) {
18171cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 contains too many parameters");
18181cb0ef41Sopenharmony_ci    return;
18191cb0ef41Sopenharmony_ci  }
18201cb0ef41Sopenharmony_ci
18211cb0ef41Sopenharmony_ci  // Load the 'results' property of the function type.
18221cb0ef41Sopenharmony_ci  Local<String> results_key = v8_str(isolate, "results");
18231cb0ef41Sopenharmony_ci  v8::MaybeLocal<v8::Value> results_maybe =
18241cb0ef41Sopenharmony_ci      function_type->Get(context, results_key);
18251cb0ef41Sopenharmony_ci  v8::Local<v8::Value> results_value;
18261cb0ef41Sopenharmony_ci  if (!results_maybe.ToLocal(&results_value)) return;
18271cb0ef41Sopenharmony_ci  if (!results_value->IsObject()) {
18281cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 must be a function type with 'results'");
18291cb0ef41Sopenharmony_ci    return;
18301cb0ef41Sopenharmony_ci  }
18311cb0ef41Sopenharmony_ci  Local<Object> results = results_value.As<Object>();
18321cb0ef41Sopenharmony_ci  uint32_t results_len = GetIterableLength(i_isolate, context, results);
18331cb0ef41Sopenharmony_ci  if (results_len == i::kMaxUInt32) {
18341cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 contains results without 'length'");
18351cb0ef41Sopenharmony_ci    return;
18361cb0ef41Sopenharmony_ci  }
18371cb0ef41Sopenharmony_ci  if (results_len > i::wasm::kV8MaxWasmFunctionReturns) {
18381cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 contains too many results");
18391cb0ef41Sopenharmony_ci    return;
18401cb0ef41Sopenharmony_ci  }
18411cb0ef41Sopenharmony_ci
18421cb0ef41Sopenharmony_ci  // Decode the function type and construct a signature.
18431cb0ef41Sopenharmony_ci  i::Zone zone(i_isolate->allocator(), ZONE_NAME);
18441cb0ef41Sopenharmony_ci  i::wasm::FunctionSig::Builder builder(&zone, results_len, parameters_len);
18451cb0ef41Sopenharmony_ci  for (uint32_t i = 0; i < parameters_len; ++i) {
18461cb0ef41Sopenharmony_ci    i::wasm::ValueType type;
18471cb0ef41Sopenharmony_ci    MaybeLocal<Value> maybe = parameters->Get(context, i);
18481cb0ef41Sopenharmony_ci    if (!GetValueType(isolate, maybe, context, &type, enabled_features) ||
18491cb0ef41Sopenharmony_ci        type == i::wasm::kWasmVoid) {
18501cb0ef41Sopenharmony_ci      thrower.TypeError(
18511cb0ef41Sopenharmony_ci          "Argument 0 parameter type at index #%u must be a value type", i);
18521cb0ef41Sopenharmony_ci      return;
18531cb0ef41Sopenharmony_ci    }
18541cb0ef41Sopenharmony_ci    builder.AddParam(type);
18551cb0ef41Sopenharmony_ci  }
18561cb0ef41Sopenharmony_ci  for (uint32_t i = 0; i < results_len; ++i) {
18571cb0ef41Sopenharmony_ci    i::wasm::ValueType type;
18581cb0ef41Sopenharmony_ci    MaybeLocal<Value> maybe = results->Get(context, i);
18591cb0ef41Sopenharmony_ci    if (!GetValueType(isolate, maybe, context, &type, enabled_features)) return;
18601cb0ef41Sopenharmony_ci    if (type == i::wasm::kWasmVoid) {
18611cb0ef41Sopenharmony_ci      thrower.TypeError(
18621cb0ef41Sopenharmony_ci          "Argument 0 result type at index #%u must be a value type", i);
18631cb0ef41Sopenharmony_ci      return;
18641cb0ef41Sopenharmony_ci    }
18651cb0ef41Sopenharmony_ci    builder.AddReturn(type);
18661cb0ef41Sopenharmony_ci  }
18671cb0ef41Sopenharmony_ci
18681cb0ef41Sopenharmony_ci  if (!args[1]->IsFunction()) {
18691cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 1 must be a function");
18701cb0ef41Sopenharmony_ci    return;
18711cb0ef41Sopenharmony_ci  }
18721cb0ef41Sopenharmony_ci  const i::wasm::FunctionSig* sig = builder.Build();
18731cb0ef41Sopenharmony_ci
18741cb0ef41Sopenharmony_ci  i::Handle<i::JSReceiver> callable =
18751cb0ef41Sopenharmony_ci      Utils::OpenHandle(*args[1].As<Function>());
18761cb0ef41Sopenharmony_ci  if (i::WasmExportedFunction::IsWasmExportedFunction(*callable)) {
18771cb0ef41Sopenharmony_ci    if (*i::Handle<i::WasmExportedFunction>::cast(callable)->sig() == *sig) {
18781cb0ef41Sopenharmony_ci      args.GetReturnValue().Set(Utils::ToLocal(callable));
18791cb0ef41Sopenharmony_ci      return;
18801cb0ef41Sopenharmony_ci    }
18811cb0ef41Sopenharmony_ci
18821cb0ef41Sopenharmony_ci    thrower.TypeError(
18831cb0ef41Sopenharmony_ci        "The signature of Argument 1 (a WebAssembly function) does "
18841cb0ef41Sopenharmony_ci        "not match the signature specified in Argument 0");
18851cb0ef41Sopenharmony_ci    return;
18861cb0ef41Sopenharmony_ci  }
18871cb0ef41Sopenharmony_ci
18881cb0ef41Sopenharmony_ci  if (i::WasmJSFunction::IsWasmJSFunction(*callable)) {
18891cb0ef41Sopenharmony_ci    if (i::Handle<i::WasmJSFunction>::cast(callable)->MatchesSignature(sig)) {
18901cb0ef41Sopenharmony_ci      args.GetReturnValue().Set(Utils::ToLocal(callable));
18911cb0ef41Sopenharmony_ci      return;
18921cb0ef41Sopenharmony_ci    }
18931cb0ef41Sopenharmony_ci
18941cb0ef41Sopenharmony_ci    thrower.TypeError(
18951cb0ef41Sopenharmony_ci        "The signature of Argument 1 (a WebAssembly function) does "
18961cb0ef41Sopenharmony_ci        "not match the signature specified in Argument 0");
18971cb0ef41Sopenharmony_ci    return;
18981cb0ef41Sopenharmony_ci  }
18991cb0ef41Sopenharmony_ci
19001cb0ef41Sopenharmony_ci  i::Handle<i::JSFunction> result = i::WasmJSFunction::New(
19011cb0ef41Sopenharmony_ci      i_isolate, sig, callable, i::Handle<i::HeapObject>());
19021cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(Utils::ToLocal(result));
19031cb0ef41Sopenharmony_ci}
19041cb0ef41Sopenharmony_ci
19051cb0ef41Sopenharmony_ci// WebAssembly.Function.type(WebAssembly.Function) -> FunctionType
19061cb0ef41Sopenharmony_civoid WebAssemblyFunctionType(const v8::FunctionCallbackInfo<v8::Value>& args) {
19071cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
19081cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
19091cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
19101cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Function.type()");
19111cb0ef41Sopenharmony_ci
19121cb0ef41Sopenharmony_ci  const i::wasm::FunctionSig* sig;
19131cb0ef41Sopenharmony_ci  i::Zone zone(i_isolate->allocator(), ZONE_NAME);
19141cb0ef41Sopenharmony_ci  i::Handle<i::Object> arg0 = Utils::OpenHandle(*args[0]);
19151cb0ef41Sopenharmony_ci  if (i::WasmExportedFunction::IsWasmExportedFunction(*arg0)) {
19161cb0ef41Sopenharmony_ci    auto wasm_exported_function =
19171cb0ef41Sopenharmony_ci        i::Handle<i::WasmExportedFunction>::cast(arg0);
19181cb0ef41Sopenharmony_ci    auto sfi = handle(wasm_exported_function->shared(), i_isolate);
19191cb0ef41Sopenharmony_ci    i::Handle<i::WasmExportedFunctionData> data =
19201cb0ef41Sopenharmony_ci        handle(sfi->wasm_exported_function_data(), i_isolate);
19211cb0ef41Sopenharmony_ci    sig = wasm_exported_function->sig();
19221cb0ef41Sopenharmony_ci    if (!data->suspender().IsUndefined()) {
19231cb0ef41Sopenharmony_ci      // If this export is wrapped by a Suspender, the function returns a
19241cb0ef41Sopenharmony_ci      // promise as an externref instead of the original return type.
19251cb0ef41Sopenharmony_ci      size_t param_count = sig->parameter_count();
19261cb0ef41Sopenharmony_ci      i::wasm::FunctionSig::Builder builder(&zone, 1, param_count);
19271cb0ef41Sopenharmony_ci      for (size_t i = 0; i < param_count; ++i) {
19281cb0ef41Sopenharmony_ci        builder.AddParam(sig->GetParam(0));
19291cb0ef41Sopenharmony_ci      }
19301cb0ef41Sopenharmony_ci      builder.AddReturn(i::wasm::kWasmAnyRef);
19311cb0ef41Sopenharmony_ci      sig = builder.Build();
19321cb0ef41Sopenharmony_ci    }
19331cb0ef41Sopenharmony_ci  } else if (i::WasmJSFunction::IsWasmJSFunction(*arg0)) {
19341cb0ef41Sopenharmony_ci    sig = i::Handle<i::WasmJSFunction>::cast(arg0)->GetSignature(&zone);
19351cb0ef41Sopenharmony_ci  } else {
19361cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 must be a WebAssembly.Function");
19371cb0ef41Sopenharmony_ci    return;
19381cb0ef41Sopenharmony_ci  }
19391cb0ef41Sopenharmony_ci
19401cb0ef41Sopenharmony_ci  auto type = i::wasm::GetTypeForFunction(i_isolate, sig);
19411cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(Utils::ToLocal(type));
19421cb0ef41Sopenharmony_ci}
19431cb0ef41Sopenharmony_ci
19441cb0ef41Sopenharmony_ciconstexpr const char* kName_WasmGlobalObject = "WebAssembly.Global";
19451cb0ef41Sopenharmony_ciconstexpr const char* kName_WasmMemoryObject = "WebAssembly.Memory";
19461cb0ef41Sopenharmony_ciconstexpr const char* kName_WasmInstanceObject = "WebAssembly.Instance";
19471cb0ef41Sopenharmony_ciconstexpr const char* kName_WasmSuspenderObject = "WebAssembly.Suspender";
19481cb0ef41Sopenharmony_ciconstexpr const char* kName_WasmTableObject = "WebAssembly.Table";
19491cb0ef41Sopenharmony_ciconstexpr const char* kName_WasmTagObject = "WebAssembly.Tag";
19501cb0ef41Sopenharmony_ciconstexpr const char* kName_WasmExceptionPackage = "WebAssembly.Exception";
19511cb0ef41Sopenharmony_ci
19521cb0ef41Sopenharmony_ci#define EXTRACT_THIS(var, WasmType)                                  \
19531cb0ef41Sopenharmony_ci  i::Handle<i::WasmType> var;                                        \
19541cb0ef41Sopenharmony_ci  {                                                                  \
19551cb0ef41Sopenharmony_ci    i::Handle<i::Object> this_arg = Utils::OpenHandle(*args.This()); \
19561cb0ef41Sopenharmony_ci    if (!this_arg->Is##WasmType()) {                                 \
19571cb0ef41Sopenharmony_ci      thrower.TypeError("Receiver is not a %s", kName_##WasmType);   \
19581cb0ef41Sopenharmony_ci      return;                                                        \
19591cb0ef41Sopenharmony_ci    }                                                                \
19601cb0ef41Sopenharmony_ci    var = i::Handle<i::WasmType>::cast(this_arg);                    \
19611cb0ef41Sopenharmony_ci  }
19621cb0ef41Sopenharmony_ci
19631cb0ef41Sopenharmony_civoid WebAssemblyInstanceGetExports(
19641cb0ef41Sopenharmony_ci    const v8::FunctionCallbackInfo<v8::Value>& args) {
19651cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
19661cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
19671cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
19681cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Instance.exports()");
19691cb0ef41Sopenharmony_ci  EXTRACT_THIS(receiver, WasmInstanceObject);
19701cb0ef41Sopenharmony_ci  i::Handle<i::JSObject> exports_object(receiver->exports_object(), i_isolate);
19711cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(Utils::ToLocal(exports_object));
19721cb0ef41Sopenharmony_ci}
19731cb0ef41Sopenharmony_ci
19741cb0ef41Sopenharmony_civoid WebAssemblyTableGetLength(
19751cb0ef41Sopenharmony_ci    const v8::FunctionCallbackInfo<v8::Value>& args) {
19761cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
19771cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
19781cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
19791cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Table.length()");
19801cb0ef41Sopenharmony_ci  EXTRACT_THIS(receiver, WasmTableObject);
19811cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(
19821cb0ef41Sopenharmony_ci      v8::Number::New(isolate, receiver->current_length()));
19831cb0ef41Sopenharmony_ci}
19841cb0ef41Sopenharmony_ci
19851cb0ef41Sopenharmony_ci// WebAssembly.Table.grow(num, init_value = null) -> num
19861cb0ef41Sopenharmony_civoid WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
19871cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
19881cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
19891cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
19901cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Table.grow()");
19911cb0ef41Sopenharmony_ci  Local<Context> context = isolate->GetCurrentContext();
19921cb0ef41Sopenharmony_ci  EXTRACT_THIS(receiver, WasmTableObject);
19931cb0ef41Sopenharmony_ci
19941cb0ef41Sopenharmony_ci  uint32_t grow_by;
19951cb0ef41Sopenharmony_ci  if (!EnforceUint32("Argument 0", args[0], context, &thrower, &grow_by)) {
19961cb0ef41Sopenharmony_ci    return;
19971cb0ef41Sopenharmony_ci  }
19981cb0ef41Sopenharmony_ci
19991cb0ef41Sopenharmony_ci  i::Handle<i::Object> init_value;
20001cb0ef41Sopenharmony_ci
20011cb0ef41Sopenharmony_ci  if (args.Length() >= 2 && !args[1]->IsUndefined()) {
20021cb0ef41Sopenharmony_ci    init_value = Utils::OpenHandle(*args[1]);
20031cb0ef41Sopenharmony_ci    if (!i::WasmTableObject::IsValidElement(i_isolate, receiver, init_value)) {
20041cb0ef41Sopenharmony_ci      thrower.TypeError("Argument 1 must be a valid type for the table");
20051cb0ef41Sopenharmony_ci      return;
20061cb0ef41Sopenharmony_ci    }
20071cb0ef41Sopenharmony_ci  } else {
20081cb0ef41Sopenharmony_ci    init_value = DefaultReferenceValue(i_isolate, receiver->type());
20091cb0ef41Sopenharmony_ci  }
20101cb0ef41Sopenharmony_ci
20111cb0ef41Sopenharmony_ci  // TODO(7748): Generalize this if other table types are allowed.
20121cb0ef41Sopenharmony_ci  bool has_function_type =
20131cb0ef41Sopenharmony_ci      receiver->type() == i::wasm::kWasmFuncRef || receiver->type().has_index();
20141cb0ef41Sopenharmony_ci  if (has_function_type && !init_value->IsNull()) {
20151cb0ef41Sopenharmony_ci    init_value = i::WasmInternalFunction::FromExternal(init_value, i_isolate)
20161cb0ef41Sopenharmony_ci                     .ToHandleChecked();
20171cb0ef41Sopenharmony_ci  }
20181cb0ef41Sopenharmony_ci
20191cb0ef41Sopenharmony_ci  int old_size =
20201cb0ef41Sopenharmony_ci      i::WasmTableObject::Grow(i_isolate, receiver, grow_by, init_value);
20211cb0ef41Sopenharmony_ci
20221cb0ef41Sopenharmony_ci  if (old_size < 0) {
20231cb0ef41Sopenharmony_ci    thrower.RangeError("failed to grow table by %u", grow_by);
20241cb0ef41Sopenharmony_ci    return;
20251cb0ef41Sopenharmony_ci  }
20261cb0ef41Sopenharmony_ci  v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
20271cb0ef41Sopenharmony_ci  return_value.Set(old_size);
20281cb0ef41Sopenharmony_ci}
20291cb0ef41Sopenharmony_ci
20301cb0ef41Sopenharmony_ci// WebAssembly.Table.get(num) -> any
20311cb0ef41Sopenharmony_civoid WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) {
20321cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
20331cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
20341cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
20351cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Table.get()");
20361cb0ef41Sopenharmony_ci  Local<Context> context = isolate->GetCurrentContext();
20371cb0ef41Sopenharmony_ci  EXTRACT_THIS(receiver, WasmTableObject);
20381cb0ef41Sopenharmony_ci
20391cb0ef41Sopenharmony_ci  uint32_t index;
20401cb0ef41Sopenharmony_ci  if (!EnforceUint32("Argument 0", args[0], context, &thrower, &index)) {
20411cb0ef41Sopenharmony_ci    return;
20421cb0ef41Sopenharmony_ci  }
20431cb0ef41Sopenharmony_ci  if (!i::WasmTableObject::IsInBounds(i_isolate, receiver, index)) {
20441cb0ef41Sopenharmony_ci    thrower.RangeError("invalid index %u into function table", index);
20451cb0ef41Sopenharmony_ci    return;
20461cb0ef41Sopenharmony_ci  }
20471cb0ef41Sopenharmony_ci
20481cb0ef41Sopenharmony_ci  i::Handle<i::Object> result =
20491cb0ef41Sopenharmony_ci      i::WasmTableObject::Get(i_isolate, receiver, index);
20501cb0ef41Sopenharmony_ci  if (result->IsWasmInternalFunction()) {
20511cb0ef41Sopenharmony_ci    result =
20521cb0ef41Sopenharmony_ci        handle(i::Handle<i::WasmInternalFunction>::cast(result)->external(),
20531cb0ef41Sopenharmony_ci               i_isolate);
20541cb0ef41Sopenharmony_ci  }
20551cb0ef41Sopenharmony_ci
20561cb0ef41Sopenharmony_ci  v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
20571cb0ef41Sopenharmony_ci  return_value.Set(Utils::ToLocal(result));
20581cb0ef41Sopenharmony_ci}
20591cb0ef41Sopenharmony_ci
20601cb0ef41Sopenharmony_ci// WebAssembly.Table.set(num, any)
20611cb0ef41Sopenharmony_civoid WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) {
20621cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
20631cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
20641cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
20651cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Table.set()");
20661cb0ef41Sopenharmony_ci  Local<Context> context = isolate->GetCurrentContext();
20671cb0ef41Sopenharmony_ci  EXTRACT_THIS(table_object, WasmTableObject);
20681cb0ef41Sopenharmony_ci
20691cb0ef41Sopenharmony_ci  // Parameter 0.
20701cb0ef41Sopenharmony_ci  uint32_t index;
20711cb0ef41Sopenharmony_ci  if (!EnforceUint32("Argument 0", args[0], context, &thrower, &index)) {
20721cb0ef41Sopenharmony_ci    return;
20731cb0ef41Sopenharmony_ci  }
20741cb0ef41Sopenharmony_ci  if (!i::WasmTableObject::IsInBounds(i_isolate, table_object, index)) {
20751cb0ef41Sopenharmony_ci    thrower.RangeError("invalid index %u into function table", index);
20761cb0ef41Sopenharmony_ci    return;
20771cb0ef41Sopenharmony_ci  }
20781cb0ef41Sopenharmony_ci
20791cb0ef41Sopenharmony_ci  i::Handle<i::Object> element =
20801cb0ef41Sopenharmony_ci      args.Length() >= 2
20811cb0ef41Sopenharmony_ci          ? Utils::OpenHandle(*args[1])
20821cb0ef41Sopenharmony_ci          : DefaultReferenceValue(i_isolate, table_object->type());
20831cb0ef41Sopenharmony_ci
20841cb0ef41Sopenharmony_ci  if (!i::WasmTableObject::IsValidElement(i_isolate, table_object, element)) {
20851cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 1 is invalid for table of type %s",
20861cb0ef41Sopenharmony_ci                      table_object->type().name().c_str());
20871cb0ef41Sopenharmony_ci    return;
20881cb0ef41Sopenharmony_ci  }
20891cb0ef41Sopenharmony_ci
20901cb0ef41Sopenharmony_ci  i::Handle<i::Object> external_element;
20911cb0ef41Sopenharmony_ci  bool is_external = i::WasmInternalFunction::FromExternal(element, i_isolate)
20921cb0ef41Sopenharmony_ci                         .ToHandle(&external_element);
20931cb0ef41Sopenharmony_ci
20941cb0ef41Sopenharmony_ci  i::WasmTableObject::Set(i_isolate, table_object, index,
20951cb0ef41Sopenharmony_ci                          is_external ? external_element : element);
20961cb0ef41Sopenharmony_ci}
20971cb0ef41Sopenharmony_ci
20981cb0ef41Sopenharmony_ci// WebAssembly.Table.type() -> TableType
20991cb0ef41Sopenharmony_civoid WebAssemblyTableType(const v8::FunctionCallbackInfo<v8::Value>& args) {
21001cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
21011cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
21021cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
21031cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Table.type()");
21041cb0ef41Sopenharmony_ci
21051cb0ef41Sopenharmony_ci  EXTRACT_THIS(table, WasmTableObject);
21061cb0ef41Sopenharmony_ci  base::Optional<uint32_t> max_size;
21071cb0ef41Sopenharmony_ci  if (!table->maximum_length().IsUndefined()) {
21081cb0ef41Sopenharmony_ci    uint64_t max_size64 = table->maximum_length().Number();
21091cb0ef41Sopenharmony_ci    DCHECK_LE(max_size64, std::numeric_limits<uint32_t>::max());
21101cb0ef41Sopenharmony_ci    max_size.emplace(static_cast<uint32_t>(max_size64));
21111cb0ef41Sopenharmony_ci  }
21121cb0ef41Sopenharmony_ci  auto type = i::wasm::GetTypeForTable(i_isolate, table->type(),
21131cb0ef41Sopenharmony_ci                                       table->current_length(), max_size);
21141cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(Utils::ToLocal(type));
21151cb0ef41Sopenharmony_ci}
21161cb0ef41Sopenharmony_ci
21171cb0ef41Sopenharmony_ci// WebAssembly.Memory.grow(num) -> num
21181cb0ef41Sopenharmony_civoid WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
21191cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
21201cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
21211cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
21221cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Memory.grow()");
21231cb0ef41Sopenharmony_ci  Local<Context> context = isolate->GetCurrentContext();
21241cb0ef41Sopenharmony_ci  EXTRACT_THIS(receiver, WasmMemoryObject);
21251cb0ef41Sopenharmony_ci
21261cb0ef41Sopenharmony_ci  uint32_t delta_pages;
21271cb0ef41Sopenharmony_ci  if (!EnforceUint32("Argument 0", args[0], context, &thrower, &delta_pages)) {
21281cb0ef41Sopenharmony_ci    return;
21291cb0ef41Sopenharmony_ci  }
21301cb0ef41Sopenharmony_ci
21311cb0ef41Sopenharmony_ci  i::Handle<i::JSArrayBuffer> old_buffer(receiver->array_buffer(), i_isolate);
21321cb0ef41Sopenharmony_ci
21331cb0ef41Sopenharmony_ci  uint64_t old_pages64 = old_buffer->byte_length() / i::wasm::kWasmPageSize;
21341cb0ef41Sopenharmony_ci  uint64_t new_pages64 = old_pages64 + static_cast<uint64_t>(delta_pages);
21351cb0ef41Sopenharmony_ci
21361cb0ef41Sopenharmony_ci  if (new_pages64 > static_cast<uint64_t>(receiver->maximum_pages())) {
21371cb0ef41Sopenharmony_ci    thrower.RangeError("Maximum memory size exceeded");
21381cb0ef41Sopenharmony_ci    return;
21391cb0ef41Sopenharmony_ci  }
21401cb0ef41Sopenharmony_ci
21411cb0ef41Sopenharmony_ci  int32_t ret = i::WasmMemoryObject::Grow(i_isolate, receiver, delta_pages);
21421cb0ef41Sopenharmony_ci  if (ret == -1) {
21431cb0ef41Sopenharmony_ci    thrower.RangeError("Unable to grow instance memory");
21441cb0ef41Sopenharmony_ci    return;
21451cb0ef41Sopenharmony_ci  }
21461cb0ef41Sopenharmony_ci  v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
21471cb0ef41Sopenharmony_ci  return_value.Set(ret);
21481cb0ef41Sopenharmony_ci}
21491cb0ef41Sopenharmony_ci
21501cb0ef41Sopenharmony_ci// WebAssembly.Memory.buffer -> ArrayBuffer
21511cb0ef41Sopenharmony_civoid WebAssemblyMemoryGetBuffer(
21521cb0ef41Sopenharmony_ci    const v8::FunctionCallbackInfo<v8::Value>& args) {
21531cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
21541cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
21551cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
21561cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Memory.buffer");
21571cb0ef41Sopenharmony_ci  EXTRACT_THIS(receiver, WasmMemoryObject);
21581cb0ef41Sopenharmony_ci
21591cb0ef41Sopenharmony_ci  i::Handle<i::Object> buffer_obj(receiver->array_buffer(), i_isolate);
21601cb0ef41Sopenharmony_ci  DCHECK(buffer_obj->IsJSArrayBuffer());
21611cb0ef41Sopenharmony_ci  i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(*buffer_obj),
21621cb0ef41Sopenharmony_ci                                     i_isolate);
21631cb0ef41Sopenharmony_ci  if (buffer->is_shared()) {
21641cb0ef41Sopenharmony_ci    // TODO(gdeepti): More needed here for when cached buffer, and current
21651cb0ef41Sopenharmony_ci    // buffer are out of sync, handle that here when bounds checks, and Grow
21661cb0ef41Sopenharmony_ci    // are handled correctly.
21671cb0ef41Sopenharmony_ci    Maybe<bool> result =
21681cb0ef41Sopenharmony_ci        buffer->SetIntegrityLevel(buffer, i::FROZEN, i::kDontThrow);
21691cb0ef41Sopenharmony_ci    if (!result.FromJust()) {
21701cb0ef41Sopenharmony_ci      thrower.TypeError(
21711cb0ef41Sopenharmony_ci          "Status of setting SetIntegrityLevel of buffer is false.");
21721cb0ef41Sopenharmony_ci    }
21731cb0ef41Sopenharmony_ci  }
21741cb0ef41Sopenharmony_ci  v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
21751cb0ef41Sopenharmony_ci  return_value.Set(Utils::ToLocal(buffer));
21761cb0ef41Sopenharmony_ci}
21771cb0ef41Sopenharmony_ci
21781cb0ef41Sopenharmony_ci// WebAssembly.Memory.type() -> MemoryType
21791cb0ef41Sopenharmony_civoid WebAssemblyMemoryType(const v8::FunctionCallbackInfo<v8::Value>& args) {
21801cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
21811cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
21821cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
21831cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Memory.type()");
21841cb0ef41Sopenharmony_ci
21851cb0ef41Sopenharmony_ci  EXTRACT_THIS(memory, WasmMemoryObject);
21861cb0ef41Sopenharmony_ci  i::Handle<i::JSArrayBuffer> buffer(memory->array_buffer(), i_isolate);
21871cb0ef41Sopenharmony_ci  size_t curr_size = buffer->byte_length() / i::wasm::kWasmPageSize;
21881cb0ef41Sopenharmony_ci  DCHECK_LE(curr_size, std::numeric_limits<uint32_t>::max());
21891cb0ef41Sopenharmony_ci  uint32_t min_size = static_cast<uint32_t>(curr_size);
21901cb0ef41Sopenharmony_ci  base::Optional<uint32_t> max_size;
21911cb0ef41Sopenharmony_ci  if (memory->has_maximum_pages()) {
21921cb0ef41Sopenharmony_ci    uint64_t max_size64 = memory->maximum_pages();
21931cb0ef41Sopenharmony_ci    DCHECK_LE(max_size64, std::numeric_limits<uint32_t>::max());
21941cb0ef41Sopenharmony_ci    max_size.emplace(static_cast<uint32_t>(max_size64));
21951cb0ef41Sopenharmony_ci  }
21961cb0ef41Sopenharmony_ci  bool shared = buffer->is_shared();
21971cb0ef41Sopenharmony_ci  auto type = i::wasm::GetTypeForMemory(i_isolate, min_size, max_size, shared);
21981cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(Utils::ToLocal(type));
21991cb0ef41Sopenharmony_ci}
22001cb0ef41Sopenharmony_ci
22011cb0ef41Sopenharmony_ci// WebAssembly.Tag.type() -> FunctionType
22021cb0ef41Sopenharmony_civoid WebAssemblyTagType(const v8::FunctionCallbackInfo<v8::Value>& args) {
22031cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
22041cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
22051cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
22061cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Tag.type()");
22071cb0ef41Sopenharmony_ci
22081cb0ef41Sopenharmony_ci  EXTRACT_THIS(tag, WasmTagObject);
22091cb0ef41Sopenharmony_ci  if (thrower.error()) return;
22101cb0ef41Sopenharmony_ci
22111cb0ef41Sopenharmony_ci  int n = tag->serialized_signature().length();
22121cb0ef41Sopenharmony_ci  std::vector<i::wasm::ValueType> data(n);
22131cb0ef41Sopenharmony_ci  if (n > 0) {
22141cb0ef41Sopenharmony_ci    tag->serialized_signature().copy_out(0, data.data(), n);
22151cb0ef41Sopenharmony_ci  }
22161cb0ef41Sopenharmony_ci  const i::wasm::FunctionSig sig{0, data.size(), data.data()};
22171cb0ef41Sopenharmony_ci  constexpr bool kForException = true;
22181cb0ef41Sopenharmony_ci  auto type = i::wasm::GetTypeForFunction(i_isolate, &sig, kForException);
22191cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(Utils::ToLocal(type));
22201cb0ef41Sopenharmony_ci}
22211cb0ef41Sopenharmony_ci
22221cb0ef41Sopenharmony_civoid WebAssemblyExceptionGetArg(
22231cb0ef41Sopenharmony_ci    const v8::FunctionCallbackInfo<v8::Value>& args) {
22241cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
22251cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
22261cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
22271cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Exception.getArg()");
22281cb0ef41Sopenharmony_ci
22291cb0ef41Sopenharmony_ci  EXTRACT_THIS(exception, WasmExceptionPackage);
22301cb0ef41Sopenharmony_ci  if (thrower.error()) return;
22311cb0ef41Sopenharmony_ci
22321cb0ef41Sopenharmony_ci  i::MaybeHandle<i::WasmTagObject> maybe_tag =
22331cb0ef41Sopenharmony_ci      GetFirstArgumentAsTag(args, &thrower);
22341cb0ef41Sopenharmony_ci  if (thrower.error()) return;
22351cb0ef41Sopenharmony_ci  auto tag = maybe_tag.ToHandleChecked();
22361cb0ef41Sopenharmony_ci  Local<Context> context = isolate->GetCurrentContext();
22371cb0ef41Sopenharmony_ci  uint32_t index;
22381cb0ef41Sopenharmony_ci  if (!EnforceUint32("Index", args[1], context, &thrower, &index)) {
22391cb0ef41Sopenharmony_ci    return;
22401cb0ef41Sopenharmony_ci  }
22411cb0ef41Sopenharmony_ci  auto maybe_values =
22421cb0ef41Sopenharmony_ci      i::WasmExceptionPackage::GetExceptionValues(i_isolate, exception);
22431cb0ef41Sopenharmony_ci
22441cb0ef41Sopenharmony_ci  auto this_tag =
22451cb0ef41Sopenharmony_ci      i::WasmExceptionPackage::GetExceptionTag(i_isolate, exception);
22461cb0ef41Sopenharmony_ci  if (this_tag->IsUndefined()) {
22471cb0ef41Sopenharmony_ci    thrower.TypeError("Expected a WebAssembly.Exception object");
22481cb0ef41Sopenharmony_ci    return;
22491cb0ef41Sopenharmony_ci  }
22501cb0ef41Sopenharmony_ci  DCHECK(this_tag->IsWasmExceptionTag());
22511cb0ef41Sopenharmony_ci  if (tag->tag() != *this_tag) {
22521cb0ef41Sopenharmony_ci    thrower.TypeError("First argument does not match the exception tag");
22531cb0ef41Sopenharmony_ci    return;
22541cb0ef41Sopenharmony_ci  }
22551cb0ef41Sopenharmony_ci
22561cb0ef41Sopenharmony_ci  DCHECK(!maybe_values->IsUndefined());
22571cb0ef41Sopenharmony_ci  auto values = i::Handle<i::FixedArray>::cast(maybe_values);
22581cb0ef41Sopenharmony_ci  auto signature = tag->serialized_signature();
22591cb0ef41Sopenharmony_ci  if (index >= static_cast<uint32_t>(signature.length())) {
22601cb0ef41Sopenharmony_ci    thrower.RangeError("Index out of range");
22611cb0ef41Sopenharmony_ci    return;
22621cb0ef41Sopenharmony_ci  }
22631cb0ef41Sopenharmony_ci  // First, find the index in the values array.
22641cb0ef41Sopenharmony_ci  uint32_t decode_index = 0;
22651cb0ef41Sopenharmony_ci  // Since the bounds check above passed, the cast to int is safe.
22661cb0ef41Sopenharmony_ci  for (int i = 0; i < static_cast<int>(index); ++i) {
22671cb0ef41Sopenharmony_ci    switch (signature.get(i).kind()) {
22681cb0ef41Sopenharmony_ci      case i::wasm::kI32:
22691cb0ef41Sopenharmony_ci      case i::wasm::kF32:
22701cb0ef41Sopenharmony_ci        decode_index += 2;
22711cb0ef41Sopenharmony_ci        break;
22721cb0ef41Sopenharmony_ci      case i::wasm::kI64:
22731cb0ef41Sopenharmony_ci      case i::wasm::kF64:
22741cb0ef41Sopenharmony_ci        decode_index += 4;
22751cb0ef41Sopenharmony_ci        break;
22761cb0ef41Sopenharmony_ci      case i::wasm::kRef:
22771cb0ef41Sopenharmony_ci      case i::wasm::kOptRef:
22781cb0ef41Sopenharmony_ci        switch (signature.get(i).heap_representation()) {
22791cb0ef41Sopenharmony_ci          case i::wasm::HeapType::kFunc:
22801cb0ef41Sopenharmony_ci          case i::wasm::HeapType::kAny:
22811cb0ef41Sopenharmony_ci          case i::wasm::HeapType::kEq:
22821cb0ef41Sopenharmony_ci          case i::wasm::HeapType::kI31:
22831cb0ef41Sopenharmony_ci          case i::wasm::HeapType::kData:
22841cb0ef41Sopenharmony_ci          case i::wasm::HeapType::kArray:
22851cb0ef41Sopenharmony_ci            decode_index++;
22861cb0ef41Sopenharmony_ci            break;
22871cb0ef41Sopenharmony_ci          case i::wasm::HeapType::kBottom:
22881cb0ef41Sopenharmony_ci            UNREACHABLE();
22891cb0ef41Sopenharmony_ci          default:
22901cb0ef41Sopenharmony_ci            // TODO(7748): Add support for custom struct/array types.
22911cb0ef41Sopenharmony_ci            UNIMPLEMENTED();
22921cb0ef41Sopenharmony_ci        }
22931cb0ef41Sopenharmony_ci        break;
22941cb0ef41Sopenharmony_ci      case i::wasm::kRtt:
22951cb0ef41Sopenharmony_ci      case i::wasm::kI8:
22961cb0ef41Sopenharmony_ci      case i::wasm::kI16:
22971cb0ef41Sopenharmony_ci      case i::wasm::kVoid:
22981cb0ef41Sopenharmony_ci      case i::wasm::kBottom:
22991cb0ef41Sopenharmony_ci      case i::wasm::kS128:
23001cb0ef41Sopenharmony_ci        UNREACHABLE();
23011cb0ef41Sopenharmony_ci    }
23021cb0ef41Sopenharmony_ci  }
23031cb0ef41Sopenharmony_ci  // Decode the value at {decode_index}.
23041cb0ef41Sopenharmony_ci  Local<Value> result;
23051cb0ef41Sopenharmony_ci  switch (signature.get(index).kind()) {
23061cb0ef41Sopenharmony_ci    case i::wasm::kI32: {
23071cb0ef41Sopenharmony_ci      uint32_t u32_bits = 0;
23081cb0ef41Sopenharmony_ci      i::DecodeI32ExceptionValue(values, &decode_index, &u32_bits);
23091cb0ef41Sopenharmony_ci      int32_t i32 = static_cast<int32_t>(u32_bits);
23101cb0ef41Sopenharmony_ci      result = v8::Integer::New(isolate, i32);
23111cb0ef41Sopenharmony_ci      break;
23121cb0ef41Sopenharmony_ci    }
23131cb0ef41Sopenharmony_ci    case i::wasm::kI64: {
23141cb0ef41Sopenharmony_ci      uint64_t u64_bits = 0;
23151cb0ef41Sopenharmony_ci      i::DecodeI64ExceptionValue(values, &decode_index, &u64_bits);
23161cb0ef41Sopenharmony_ci      int64_t i64 = static_cast<int64_t>(u64_bits);
23171cb0ef41Sopenharmony_ci      result = v8::BigInt::New(isolate, i64);
23181cb0ef41Sopenharmony_ci      break;
23191cb0ef41Sopenharmony_ci    }
23201cb0ef41Sopenharmony_ci    case i::wasm::kF32: {
23211cb0ef41Sopenharmony_ci      uint32_t f32_bits = 0;
23221cb0ef41Sopenharmony_ci      DecodeI32ExceptionValue(values, &decode_index, &f32_bits);
23231cb0ef41Sopenharmony_ci      float f32 = bit_cast<float>(f32_bits);
23241cb0ef41Sopenharmony_ci      result = v8::Number::New(isolate, f32);
23251cb0ef41Sopenharmony_ci      break;
23261cb0ef41Sopenharmony_ci    }
23271cb0ef41Sopenharmony_ci    case i::wasm::kF64: {
23281cb0ef41Sopenharmony_ci      uint64_t f64_bits = 0;
23291cb0ef41Sopenharmony_ci      DecodeI64ExceptionValue(values, &decode_index, &f64_bits);
23301cb0ef41Sopenharmony_ci      double f64 = bit_cast<double>(f64_bits);
23311cb0ef41Sopenharmony_ci      result = v8::Number::New(isolate, f64);
23321cb0ef41Sopenharmony_ci      break;
23331cb0ef41Sopenharmony_ci    }
23341cb0ef41Sopenharmony_ci    case i::wasm::kRef:
23351cb0ef41Sopenharmony_ci    case i::wasm::kOptRef:
23361cb0ef41Sopenharmony_ci      switch (signature.get(index).heap_representation()) {
23371cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kFunc:
23381cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kAny:
23391cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kEq:
23401cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kI31:
23411cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kArray:
23421cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kData: {
23431cb0ef41Sopenharmony_ci          auto obj = values->get(decode_index);
23441cb0ef41Sopenharmony_ci          result = Utils::ToLocal(i::Handle<i::Object>(obj, i_isolate));
23451cb0ef41Sopenharmony_ci          break;
23461cb0ef41Sopenharmony_ci        }
23471cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kBottom:
23481cb0ef41Sopenharmony_ci          UNREACHABLE();
23491cb0ef41Sopenharmony_ci        default:
23501cb0ef41Sopenharmony_ci          // TODO(7748): Add support for custom struct/array types.
23511cb0ef41Sopenharmony_ci          UNIMPLEMENTED();
23521cb0ef41Sopenharmony_ci      }
23531cb0ef41Sopenharmony_ci      break;
23541cb0ef41Sopenharmony_ci    case i::wasm::kRtt:
23551cb0ef41Sopenharmony_ci    case i::wasm::kI8:
23561cb0ef41Sopenharmony_ci    case i::wasm::kI16:
23571cb0ef41Sopenharmony_ci    case i::wasm::kVoid:
23581cb0ef41Sopenharmony_ci    case i::wasm::kBottom:
23591cb0ef41Sopenharmony_ci    case i::wasm::kS128:
23601cb0ef41Sopenharmony_ci      UNREACHABLE();
23611cb0ef41Sopenharmony_ci  }
23621cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(result);
23631cb0ef41Sopenharmony_ci}
23641cb0ef41Sopenharmony_ci
23651cb0ef41Sopenharmony_civoid WebAssemblyExceptionIs(const v8::FunctionCallbackInfo<v8::Value>& args) {
23661cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
23671cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
23681cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
23691cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Exception.is()");
23701cb0ef41Sopenharmony_ci
23711cb0ef41Sopenharmony_ci  EXTRACT_THIS(exception, WasmExceptionPackage);
23721cb0ef41Sopenharmony_ci  if (thrower.error()) return;
23731cb0ef41Sopenharmony_ci
23741cb0ef41Sopenharmony_ci  auto tag = i::WasmExceptionPackage::GetExceptionTag(i_isolate, exception);
23751cb0ef41Sopenharmony_ci  if (tag->IsUndefined()) {
23761cb0ef41Sopenharmony_ci    thrower.TypeError("Expected a WebAssembly.Exception object");
23771cb0ef41Sopenharmony_ci    return;
23781cb0ef41Sopenharmony_ci  }
23791cb0ef41Sopenharmony_ci  DCHECK(tag->IsWasmExceptionTag());
23801cb0ef41Sopenharmony_ci
23811cb0ef41Sopenharmony_ci  auto maybe_tag = GetFirstArgumentAsTag(args, &thrower);
23821cb0ef41Sopenharmony_ci  if (thrower.error()) {
23831cb0ef41Sopenharmony_ci    return;
23841cb0ef41Sopenharmony_ci  }
23851cb0ef41Sopenharmony_ci  auto tag_arg = maybe_tag.ToHandleChecked();
23861cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(tag_arg->tag() == *tag);
23871cb0ef41Sopenharmony_ci}
23881cb0ef41Sopenharmony_ci
23891cb0ef41Sopenharmony_civoid WebAssemblyGlobalGetValueCommon(
23901cb0ef41Sopenharmony_ci    const v8::FunctionCallbackInfo<v8::Value>& args, const char* name) {
23911cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
23921cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
23931cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
23941cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, name);
23951cb0ef41Sopenharmony_ci  EXTRACT_THIS(receiver, WasmGlobalObject);
23961cb0ef41Sopenharmony_ci
23971cb0ef41Sopenharmony_ci  v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
23981cb0ef41Sopenharmony_ci
23991cb0ef41Sopenharmony_ci  switch (receiver->type().kind()) {
24001cb0ef41Sopenharmony_ci    case i::wasm::kI32:
24011cb0ef41Sopenharmony_ci      return_value.Set(receiver->GetI32());
24021cb0ef41Sopenharmony_ci      break;
24031cb0ef41Sopenharmony_ci    case i::wasm::kI64: {
24041cb0ef41Sopenharmony_ci      Local<BigInt> value = BigInt::New(isolate, receiver->GetI64());
24051cb0ef41Sopenharmony_ci      return_value.Set(value);
24061cb0ef41Sopenharmony_ci      break;
24071cb0ef41Sopenharmony_ci    }
24081cb0ef41Sopenharmony_ci    case i::wasm::kF32:
24091cb0ef41Sopenharmony_ci      return_value.Set(receiver->GetF32());
24101cb0ef41Sopenharmony_ci      break;
24111cb0ef41Sopenharmony_ci    case i::wasm::kF64:
24121cb0ef41Sopenharmony_ci      return_value.Set(receiver->GetF64());
24131cb0ef41Sopenharmony_ci      break;
24141cb0ef41Sopenharmony_ci    case i::wasm::kS128:
24151cb0ef41Sopenharmony_ci      thrower.TypeError("Can't get the value of s128 WebAssembly.Global");
24161cb0ef41Sopenharmony_ci      break;
24171cb0ef41Sopenharmony_ci    case i::wasm::kRef:
24181cb0ef41Sopenharmony_ci    case i::wasm::kOptRef:
24191cb0ef41Sopenharmony_ci      switch (receiver->type().heap_representation()) {
24201cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kAny:
24211cb0ef41Sopenharmony_ci          return_value.Set(Utils::ToLocal(receiver->GetRef()));
24221cb0ef41Sopenharmony_ci          break;
24231cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kFunc: {
24241cb0ef41Sopenharmony_ci          i::Handle<i::Object> result = receiver->GetRef();
24251cb0ef41Sopenharmony_ci          if (result->IsWasmInternalFunction()) {
24261cb0ef41Sopenharmony_ci            result = handle(
24271cb0ef41Sopenharmony_ci                i::Handle<i::WasmInternalFunction>::cast(result)->external(),
24281cb0ef41Sopenharmony_ci                i_isolate);
24291cb0ef41Sopenharmony_ci          }
24301cb0ef41Sopenharmony_ci          return_value.Set(Utils::ToLocal(result));
24311cb0ef41Sopenharmony_ci          break;
24321cb0ef41Sopenharmony_ci        }
24331cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kBottom:
24341cb0ef41Sopenharmony_ci          UNREACHABLE();
24351cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kI31:
24361cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kData:
24371cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kArray:
24381cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kEq:
24391cb0ef41Sopenharmony_ci        default:
24401cb0ef41Sopenharmony_ci          // TODO(7748): Implement these.
24411cb0ef41Sopenharmony_ci          UNIMPLEMENTED();
24421cb0ef41Sopenharmony_ci      }
24431cb0ef41Sopenharmony_ci      break;
24441cb0ef41Sopenharmony_ci    case i::wasm::kRtt:
24451cb0ef41Sopenharmony_ci      UNIMPLEMENTED();  // TODO(7748): Implement.
24461cb0ef41Sopenharmony_ci    case i::wasm::kI8:
24471cb0ef41Sopenharmony_ci    case i::wasm::kI16:
24481cb0ef41Sopenharmony_ci    case i::wasm::kBottom:
24491cb0ef41Sopenharmony_ci    case i::wasm::kVoid:
24501cb0ef41Sopenharmony_ci      UNREACHABLE();
24511cb0ef41Sopenharmony_ci  }
24521cb0ef41Sopenharmony_ci}
24531cb0ef41Sopenharmony_ci
24541cb0ef41Sopenharmony_ci// WebAssembly.Global.valueOf() -> num
24551cb0ef41Sopenharmony_civoid WebAssemblyGlobalValueOf(const v8::FunctionCallbackInfo<v8::Value>& args) {
24561cb0ef41Sopenharmony_ci  return WebAssemblyGlobalGetValueCommon(args, "WebAssembly.Global.valueOf()");
24571cb0ef41Sopenharmony_ci}
24581cb0ef41Sopenharmony_ci
24591cb0ef41Sopenharmony_ci// get WebAssembly.Global.value -> num
24601cb0ef41Sopenharmony_civoid WebAssemblyGlobalGetValue(
24611cb0ef41Sopenharmony_ci    const v8::FunctionCallbackInfo<v8::Value>& args) {
24621cb0ef41Sopenharmony_ci  return WebAssemblyGlobalGetValueCommon(args, "get WebAssembly.Global.value");
24631cb0ef41Sopenharmony_ci}
24641cb0ef41Sopenharmony_ci
24651cb0ef41Sopenharmony_ci// set WebAssembly.Global.value(num)
24661cb0ef41Sopenharmony_civoid WebAssemblyGlobalSetValue(
24671cb0ef41Sopenharmony_ci    const v8::FunctionCallbackInfo<v8::Value>& args) {
24681cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
24691cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
24701cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
24711cb0ef41Sopenharmony_ci  Local<Context> context = isolate->GetCurrentContext();
24721cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "set WebAssembly.Global.value");
24731cb0ef41Sopenharmony_ci  EXTRACT_THIS(receiver, WasmGlobalObject);
24741cb0ef41Sopenharmony_ci
24751cb0ef41Sopenharmony_ci  if (!receiver->is_mutable()) {
24761cb0ef41Sopenharmony_ci    thrower.TypeError("Can't set the value of an immutable global.");
24771cb0ef41Sopenharmony_ci    return;
24781cb0ef41Sopenharmony_ci  }
24791cb0ef41Sopenharmony_ci  if (args.Length() == 0) {
24801cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 is required");
24811cb0ef41Sopenharmony_ci    return;
24821cb0ef41Sopenharmony_ci  }
24831cb0ef41Sopenharmony_ci
24841cb0ef41Sopenharmony_ci  switch (receiver->type().kind()) {
24851cb0ef41Sopenharmony_ci    case i::wasm::kI32: {
24861cb0ef41Sopenharmony_ci      int32_t i32_value = 0;
24871cb0ef41Sopenharmony_ci      if (!args[0]->Int32Value(context).To(&i32_value)) return;
24881cb0ef41Sopenharmony_ci      receiver->SetI32(i32_value);
24891cb0ef41Sopenharmony_ci      break;
24901cb0ef41Sopenharmony_ci    }
24911cb0ef41Sopenharmony_ci    case i::wasm::kI64: {
24921cb0ef41Sopenharmony_ci      v8::Local<v8::BigInt> bigint_value;
24931cb0ef41Sopenharmony_ci      if (!args[0]->ToBigInt(context).ToLocal(&bigint_value)) return;
24941cb0ef41Sopenharmony_ci      receiver->SetI64(bigint_value->Int64Value());
24951cb0ef41Sopenharmony_ci      break;
24961cb0ef41Sopenharmony_ci    }
24971cb0ef41Sopenharmony_ci    case i::wasm::kF32: {
24981cb0ef41Sopenharmony_ci      double f64_value = 0;
24991cb0ef41Sopenharmony_ci      if (!args[0]->NumberValue(context).To(&f64_value)) return;
25001cb0ef41Sopenharmony_ci      receiver->SetF32(i::DoubleToFloat32(f64_value));
25011cb0ef41Sopenharmony_ci      break;
25021cb0ef41Sopenharmony_ci    }
25031cb0ef41Sopenharmony_ci    case i::wasm::kF64: {
25041cb0ef41Sopenharmony_ci      double f64_value = 0;
25051cb0ef41Sopenharmony_ci      if (!args[0]->NumberValue(context).To(&f64_value)) return;
25061cb0ef41Sopenharmony_ci      receiver->SetF64(f64_value);
25071cb0ef41Sopenharmony_ci      break;
25081cb0ef41Sopenharmony_ci    }
25091cb0ef41Sopenharmony_ci    case i::wasm::kS128:
25101cb0ef41Sopenharmony_ci      thrower.TypeError("Can't set the value of s128 WebAssembly.Global");
25111cb0ef41Sopenharmony_ci      break;
25121cb0ef41Sopenharmony_ci    case i::wasm::kRef:
25131cb0ef41Sopenharmony_ci    case i::wasm::kOptRef:
25141cb0ef41Sopenharmony_ci      switch (receiver->type().heap_representation()) {
25151cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kAny:
25161cb0ef41Sopenharmony_ci          receiver->SetExternRef(Utils::OpenHandle(*args[0]));
25171cb0ef41Sopenharmony_ci          break;
25181cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kFunc: {
25191cb0ef41Sopenharmony_ci          if (!receiver->SetFuncRef(i_isolate, Utils::OpenHandle(*args[0]))) {
25201cb0ef41Sopenharmony_ci            thrower.TypeError(
25211cb0ef41Sopenharmony_ci                "value of an funcref reference must be either null or an "
25221cb0ef41Sopenharmony_ci                "exported function");
25231cb0ef41Sopenharmony_ci          }
25241cb0ef41Sopenharmony_ci          break;
25251cb0ef41Sopenharmony_ci        }
25261cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kBottom:
25271cb0ef41Sopenharmony_ci          UNREACHABLE();
25281cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kI31:
25291cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kData:
25301cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kArray:
25311cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kEq:
25321cb0ef41Sopenharmony_ci        default:
25331cb0ef41Sopenharmony_ci          // TODO(7748): Implement these.
25341cb0ef41Sopenharmony_ci          UNIMPLEMENTED();
25351cb0ef41Sopenharmony_ci      }
25361cb0ef41Sopenharmony_ci      break;
25371cb0ef41Sopenharmony_ci    case i::wasm::kRtt:
25381cb0ef41Sopenharmony_ci      // TODO(7748): Implement.
25391cb0ef41Sopenharmony_ci      UNIMPLEMENTED();
25401cb0ef41Sopenharmony_ci    case i::wasm::kI8:
25411cb0ef41Sopenharmony_ci    case i::wasm::kI16:
25421cb0ef41Sopenharmony_ci    case i::wasm::kBottom:
25431cb0ef41Sopenharmony_ci    case i::wasm::kVoid:
25441cb0ef41Sopenharmony_ci      UNREACHABLE();
25451cb0ef41Sopenharmony_ci  }
25461cb0ef41Sopenharmony_ci}
25471cb0ef41Sopenharmony_ci
25481cb0ef41Sopenharmony_ci// WebAssembly.Global.type() -> GlobalType
25491cb0ef41Sopenharmony_civoid WebAssemblyGlobalType(const v8::FunctionCallbackInfo<v8::Value>& args) {
25501cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
25511cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
25521cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
25531cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Global.type()");
25541cb0ef41Sopenharmony_ci
25551cb0ef41Sopenharmony_ci  EXTRACT_THIS(global, WasmGlobalObject);
25561cb0ef41Sopenharmony_ci  auto type = i::wasm::GetTypeForGlobal(i_isolate, global->is_mutable(),
25571cb0ef41Sopenharmony_ci                                        global->type());
25581cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(Utils::ToLocal(type));
25591cb0ef41Sopenharmony_ci}
25601cb0ef41Sopenharmony_ci
25611cb0ef41Sopenharmony_ci// WebAssembly.Suspender.returnPromiseOnSuspend(WebAssembly.Function) ->
25621cb0ef41Sopenharmony_ci// WebAssembly.Function
25631cb0ef41Sopenharmony_civoid WebAssemblySuspenderReturnPromiseOnSuspend(
25641cb0ef41Sopenharmony_ci    const v8::FunctionCallbackInfo<v8::Value>& args) {
25651cb0ef41Sopenharmony_ci  Isolate* isolate = args.GetIsolate();
25661cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
25671cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
25681cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(
25691cb0ef41Sopenharmony_ci      i_isolate, "WebAssembly.Suspender.returnPromiseOnSuspend()");
25701cb0ef41Sopenharmony_ci  if (args.Length() == 0) {
25711cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 is required");
25721cb0ef41Sopenharmony_ci    return;
25731cb0ef41Sopenharmony_ci  }
25741cb0ef41Sopenharmony_ci  auto maybe_function = GetFirstArgumentAsJSFunction(args, &thrower);
25751cb0ef41Sopenharmony_ci  if (thrower.error()) return;
25761cb0ef41Sopenharmony_ci  i::Handle<i::JSFunction> function = maybe_function.ToHandleChecked();
25771cb0ef41Sopenharmony_ci  i::SharedFunctionInfo sfi = function->shared();
25781cb0ef41Sopenharmony_ci  if (!sfi.HasWasmExportedFunctionData()) {
25791cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 must be a wasm function");
25801cb0ef41Sopenharmony_ci  }
25811cb0ef41Sopenharmony_ci  i::WasmExportedFunctionData data = sfi.wasm_exported_function_data();
25821cb0ef41Sopenharmony_ci  if (data.sig()->return_count() != 1) {
25831cb0ef41Sopenharmony_ci    thrower.TypeError(
25841cb0ef41Sopenharmony_ci        "Expected a WebAssembly.Function with exactly one return type");
25851cb0ef41Sopenharmony_ci  }
25861cb0ef41Sopenharmony_ci  int index = data.function_index();
25871cb0ef41Sopenharmony_ci  i::Handle<i::WasmInstanceObject> instance(
25881cb0ef41Sopenharmony_ci      i::WasmInstanceObject::cast(data.internal().ref()), i_isolate);
25891cb0ef41Sopenharmony_ci  i::Handle<i::CodeT> wrapper =
25901cb0ef41Sopenharmony_ci      BUILTIN_CODE(i_isolate, WasmReturnPromiseOnSuspend);
25911cb0ef41Sopenharmony_ci  // Upcast to JSFunction to re-use the existing ToLocal helper below.
25921cb0ef41Sopenharmony_ci  i::Handle<i::JSFunction> result =
25931cb0ef41Sopenharmony_ci      i::Handle<i::WasmExternalFunction>::cast(i::WasmExportedFunction::New(
25941cb0ef41Sopenharmony_ci          i_isolate, instance, index,
25951cb0ef41Sopenharmony_ci          static_cast<int>(data.sig()->parameter_count()), wrapper));
25961cb0ef41Sopenharmony_ci  EXTRACT_THIS(suspender, WasmSuspenderObject);
25971cb0ef41Sopenharmony_ci  auto function_data = i::WasmExportedFunctionData::cast(
25981cb0ef41Sopenharmony_ci      result->shared().function_data(kAcquireLoad));
25991cb0ef41Sopenharmony_ci  function_data.set_suspender(*suspender);
26001cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(Utils::ToLocal(result));
26011cb0ef41Sopenharmony_ci}
26021cb0ef41Sopenharmony_ci
26031cb0ef41Sopenharmony_ci// WebAssembly.Suspender.suspendOnReturnedPromise(Function) -> Function
26041cb0ef41Sopenharmony_civoid WebAssemblySuspenderSuspendOnReturnedPromise(
26051cb0ef41Sopenharmony_ci    const v8::FunctionCallbackInfo<v8::Value>& args) {
26061cb0ef41Sopenharmony_ci  v8::Isolate* isolate = args.GetIsolate();
26071cb0ef41Sopenharmony_ci  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
26081cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
26091cb0ef41Sopenharmony_ci  ScheduledErrorThrower thrower(
26101cb0ef41Sopenharmony_ci      i_isolate, "WebAssembly.Suspender.suspendOnReturnedPromise()");
26111cb0ef41Sopenharmony_ci  if (!args[0]->IsObject()) {
26121cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 must be a WebAssembly.Function");
26131cb0ef41Sopenharmony_ci    return;
26141cb0ef41Sopenharmony_ci  }
26151cb0ef41Sopenharmony_ci  i::Zone zone(i_isolate->allocator(), ZONE_NAME);
26161cb0ef41Sopenharmony_ci  const i::wasm::FunctionSig* sig;
26171cb0ef41Sopenharmony_ci  i::Handle<i::Object> arg0 = Utils::OpenHandle(*args[0]);
26181cb0ef41Sopenharmony_ci
26191cb0ef41Sopenharmony_ci  if (i::WasmExportedFunction::IsWasmExportedFunction(*arg0)) {
26201cb0ef41Sopenharmony_ci    // TODO(thibaudm): Suspend on wrapped wasm-to-wasm calls too.
26211cb0ef41Sopenharmony_ci    UNIMPLEMENTED();
26221cb0ef41Sopenharmony_ci  } else if (!i::WasmJSFunction::IsWasmJSFunction(*arg0)) {
26231cb0ef41Sopenharmony_ci    thrower.TypeError("Argument 0 must be a WebAssembly.Function");
26241cb0ef41Sopenharmony_ci    return;
26251cb0ef41Sopenharmony_ci  }
26261cb0ef41Sopenharmony_ci  sig = i::Handle<i::WasmJSFunction>::cast(arg0)->GetSignature(&zone);
26271cb0ef41Sopenharmony_ci  if (sig->return_count() != 1 || sig->GetReturn(0) != i::wasm::kWasmAnyRef) {
26281cb0ef41Sopenharmony_ci    thrower.TypeError("Expected a WebAssembly.Function with return type %s",
26291cb0ef41Sopenharmony_ci                      i::wasm::kWasmAnyRef.name().c_str());
26301cb0ef41Sopenharmony_ci  }
26311cb0ef41Sopenharmony_ci
26321cb0ef41Sopenharmony_ci  auto callable = handle(
26331cb0ef41Sopenharmony_ci      i::Handle<i::WasmJSFunction>::cast(arg0)->GetCallable(), i_isolate);
26341cb0ef41Sopenharmony_ci  EXTRACT_THIS(suspender, WasmSuspenderObject);
26351cb0ef41Sopenharmony_ci  i::Handle<i::JSFunction> result =
26361cb0ef41Sopenharmony_ci      i::WasmJSFunction::New(i_isolate, sig, callable, suspender);
26371cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(Utils::ToLocal(result));
26381cb0ef41Sopenharmony_ci}
26391cb0ef41Sopenharmony_ci}  // namespace
26401cb0ef41Sopenharmony_ci
26411cb0ef41Sopenharmony_ci// TODO(titzer): we use the API to create the function template because the
26421cb0ef41Sopenharmony_ci// internal guts are too ugly to replicate here.
26431cb0ef41Sopenharmony_cistatic i::Handle<i::FunctionTemplateInfo> NewFunctionTemplate(
26441cb0ef41Sopenharmony_ci    i::Isolate* i_isolate, FunctionCallback func, bool has_prototype,
26451cb0ef41Sopenharmony_ci    SideEffectType side_effect_type = SideEffectType::kHasSideEffect) {
26461cb0ef41Sopenharmony_ci  Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
26471cb0ef41Sopenharmony_ci  ConstructorBehavior behavior =
26481cb0ef41Sopenharmony_ci      has_prototype ? ConstructorBehavior::kAllow : ConstructorBehavior::kThrow;
26491cb0ef41Sopenharmony_ci  Local<FunctionTemplate> templ = FunctionTemplate::New(
26501cb0ef41Sopenharmony_ci      isolate, func, {}, {}, 0, behavior, side_effect_type);
26511cb0ef41Sopenharmony_ci  if (has_prototype) templ->ReadOnlyPrototype();
26521cb0ef41Sopenharmony_ci  return v8::Utils::OpenHandle(*templ);
26531cb0ef41Sopenharmony_ci}
26541cb0ef41Sopenharmony_ci
26551cb0ef41Sopenharmony_cistatic i::Handle<i::ObjectTemplateInfo> NewObjectTemplate(
26561cb0ef41Sopenharmony_ci    i::Isolate* i_isolate) {
26571cb0ef41Sopenharmony_ci  Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
26581cb0ef41Sopenharmony_ci  Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
26591cb0ef41Sopenharmony_ci  return v8::Utils::OpenHandle(*templ);
26601cb0ef41Sopenharmony_ci}
26611cb0ef41Sopenharmony_ci
26621cb0ef41Sopenharmony_cinamespace internal {
26631cb0ef41Sopenharmony_ci
26641cb0ef41Sopenharmony_ciHandle<JSFunction> CreateFunc(
26651cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<String> name, FunctionCallback func,
26661cb0ef41Sopenharmony_ci    bool has_prototype,
26671cb0ef41Sopenharmony_ci    SideEffectType side_effect_type = SideEffectType::kHasSideEffect) {
26681cb0ef41Sopenharmony_ci  Handle<FunctionTemplateInfo> temp =
26691cb0ef41Sopenharmony_ci      NewFunctionTemplate(isolate, func, has_prototype, side_effect_type);
26701cb0ef41Sopenharmony_ci  Handle<JSFunction> function =
26711cb0ef41Sopenharmony_ci      ApiNatives::InstantiateFunction(temp, name).ToHandleChecked();
26721cb0ef41Sopenharmony_ci  DCHECK(function->shared().HasSharedName());
26731cb0ef41Sopenharmony_ci  return function;
26741cb0ef41Sopenharmony_ci}
26751cb0ef41Sopenharmony_ci
26761cb0ef41Sopenharmony_ciHandle<JSFunction> InstallFunc(
26771cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<JSObject> object, const char* str,
26781cb0ef41Sopenharmony_ci    FunctionCallback func, int length, bool has_prototype = false,
26791cb0ef41Sopenharmony_ci    PropertyAttributes attributes = NONE,
26801cb0ef41Sopenharmony_ci    SideEffectType side_effect_type = SideEffectType::kHasSideEffect) {
26811cb0ef41Sopenharmony_ci  Handle<String> name = v8_str(isolate, str);
26821cb0ef41Sopenharmony_ci  Handle<JSFunction> function =
26831cb0ef41Sopenharmony_ci      CreateFunc(isolate, name, func, has_prototype, side_effect_type);
26841cb0ef41Sopenharmony_ci  function->shared().set_length(length);
26851cb0ef41Sopenharmony_ci  JSObject::AddProperty(isolate, object, name, function, attributes);
26861cb0ef41Sopenharmony_ci  return function;
26871cb0ef41Sopenharmony_ci}
26881cb0ef41Sopenharmony_ci
26891cb0ef41Sopenharmony_ciHandle<JSFunction> InstallConstructorFunc(Isolate* isolate,
26901cb0ef41Sopenharmony_ci                                          Handle<JSObject> object,
26911cb0ef41Sopenharmony_ci                                          const char* str,
26921cb0ef41Sopenharmony_ci                                          FunctionCallback func) {
26931cb0ef41Sopenharmony_ci  return InstallFunc(isolate, object, str, func, 1, true, DONT_ENUM,
26941cb0ef41Sopenharmony_ci                     SideEffectType::kHasNoSideEffect);
26951cb0ef41Sopenharmony_ci}
26961cb0ef41Sopenharmony_ci
26971cb0ef41Sopenharmony_ciHandle<String> GetterName(Isolate* isolate, Handle<String> name) {
26981cb0ef41Sopenharmony_ci  return Name::ToFunctionName(isolate, name, isolate->factory()->get_string())
26991cb0ef41Sopenharmony_ci      .ToHandleChecked();
27001cb0ef41Sopenharmony_ci}
27011cb0ef41Sopenharmony_ci
27021cb0ef41Sopenharmony_civoid InstallGetter(Isolate* isolate, Handle<JSObject> object, const char* str,
27031cb0ef41Sopenharmony_ci                   FunctionCallback func) {
27041cb0ef41Sopenharmony_ci  Handle<String> name = v8_str(isolate, str);
27051cb0ef41Sopenharmony_ci  Handle<JSFunction> function =
27061cb0ef41Sopenharmony_ci      CreateFunc(isolate, GetterName(isolate, name), func, false,
27071cb0ef41Sopenharmony_ci                 SideEffectType::kHasNoSideEffect);
27081cb0ef41Sopenharmony_ci
27091cb0ef41Sopenharmony_ci  Utils::ToLocal(object)->SetAccessorProperty(Utils::ToLocal(name),
27101cb0ef41Sopenharmony_ci                                              Utils::ToLocal(function),
27111cb0ef41Sopenharmony_ci                                              Local<Function>(), v8::None);
27121cb0ef41Sopenharmony_ci}
27131cb0ef41Sopenharmony_ci
27141cb0ef41Sopenharmony_ciHandle<String> SetterName(Isolate* isolate, Handle<String> name) {
27151cb0ef41Sopenharmony_ci  return Name::ToFunctionName(isolate, name, isolate->factory()->set_string())
27161cb0ef41Sopenharmony_ci      .ToHandleChecked();
27171cb0ef41Sopenharmony_ci}
27181cb0ef41Sopenharmony_ci
27191cb0ef41Sopenharmony_civoid InstallGetterSetter(Isolate* isolate, Handle<JSObject> object,
27201cb0ef41Sopenharmony_ci                         const char* str, FunctionCallback getter,
27211cb0ef41Sopenharmony_ci                         FunctionCallback setter) {
27221cb0ef41Sopenharmony_ci  Handle<String> name = v8_str(isolate, str);
27231cb0ef41Sopenharmony_ci  Handle<JSFunction> getter_func =
27241cb0ef41Sopenharmony_ci      CreateFunc(isolate, GetterName(isolate, name), getter, false,
27251cb0ef41Sopenharmony_ci                 SideEffectType::kHasNoSideEffect);
27261cb0ef41Sopenharmony_ci  Handle<JSFunction> setter_func =
27271cb0ef41Sopenharmony_ci      CreateFunc(isolate, SetterName(isolate, name), setter, false);
27281cb0ef41Sopenharmony_ci  setter_func->shared().set_length(1);
27291cb0ef41Sopenharmony_ci
27301cb0ef41Sopenharmony_ci  Utils::ToLocal(object)->SetAccessorProperty(
27311cb0ef41Sopenharmony_ci      Utils::ToLocal(name), Utils::ToLocal(getter_func),
27321cb0ef41Sopenharmony_ci      Utils::ToLocal(setter_func), v8::None);
27331cb0ef41Sopenharmony_ci}
27341cb0ef41Sopenharmony_ci
27351cb0ef41Sopenharmony_ci// Assigns a dummy instance template to the given constructor function. Used to
27361cb0ef41Sopenharmony_ci// make sure the implicit receivers for the constructors in this file have an
27371cb0ef41Sopenharmony_ci// instance type different from the internal one, they allocate the resulting
27381cb0ef41Sopenharmony_ci// object explicitly and ignore implicit receiver.
27391cb0ef41Sopenharmony_civoid SetDummyInstanceTemplate(Isolate* isolate, Handle<JSFunction> fun) {
27401cb0ef41Sopenharmony_ci  Handle<ObjectTemplateInfo> instance_template = NewObjectTemplate(isolate);
27411cb0ef41Sopenharmony_ci  FunctionTemplateInfo::SetInstanceTemplate(
27421cb0ef41Sopenharmony_ci      isolate, handle(fun->shared().get_api_func_data(), isolate),
27431cb0ef41Sopenharmony_ci      instance_template);
27441cb0ef41Sopenharmony_ci}
27451cb0ef41Sopenharmony_ci
27461cb0ef41Sopenharmony_ciHandle<JSObject> SetupConstructor(Isolate* isolate,
27471cb0ef41Sopenharmony_ci                                  Handle<JSFunction> constructor,
27481cb0ef41Sopenharmony_ci                                  InstanceType instance_type, int instance_size,
27491cb0ef41Sopenharmony_ci                                  const char* name = nullptr) {
27501cb0ef41Sopenharmony_ci  SetDummyInstanceTemplate(isolate, constructor);
27511cb0ef41Sopenharmony_ci  JSFunction::EnsureHasInitialMap(constructor);
27521cb0ef41Sopenharmony_ci  Handle<JSObject> proto(JSObject::cast(constructor->instance_prototype()),
27531cb0ef41Sopenharmony_ci                         isolate);
27541cb0ef41Sopenharmony_ci  Handle<Map> map = isolate->factory()->NewMap(instance_type, instance_size);
27551cb0ef41Sopenharmony_ci  JSFunction::SetInitialMap(isolate, constructor, map, proto);
27561cb0ef41Sopenharmony_ci  constexpr PropertyAttributes ro_attributes =
27571cb0ef41Sopenharmony_ci      static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
27581cb0ef41Sopenharmony_ci  if (name) {
27591cb0ef41Sopenharmony_ci    JSObject::AddProperty(isolate, proto,
27601cb0ef41Sopenharmony_ci                          isolate->factory()->to_string_tag_symbol(),
27611cb0ef41Sopenharmony_ci                          v8_str(isolate, name), ro_attributes);
27621cb0ef41Sopenharmony_ci  }
27631cb0ef41Sopenharmony_ci  return proto;
27641cb0ef41Sopenharmony_ci}
27651cb0ef41Sopenharmony_ci
27661cb0ef41Sopenharmony_ci// static
27671cb0ef41Sopenharmony_civoid WasmJs::Install(Isolate* isolate, bool exposed_on_global_object) {
27681cb0ef41Sopenharmony_ci  Handle<JSGlobalObject> global = isolate->global_object();
27691cb0ef41Sopenharmony_ci  Handle<Context> context(global->native_context(), isolate);
27701cb0ef41Sopenharmony_ci  // Install the JS API once only.
27711cb0ef41Sopenharmony_ci  Object prev = context->get(Context::WASM_MODULE_CONSTRUCTOR_INDEX);
27721cb0ef41Sopenharmony_ci  if (!prev.IsUndefined(isolate)) {
27731cb0ef41Sopenharmony_ci    DCHECK(prev.IsJSFunction());
27741cb0ef41Sopenharmony_ci    return;
27751cb0ef41Sopenharmony_ci  }
27761cb0ef41Sopenharmony_ci
27771cb0ef41Sopenharmony_ci  Factory* factory = isolate->factory();
27781cb0ef41Sopenharmony_ci
27791cb0ef41Sopenharmony_ci  // Setup WebAssembly
27801cb0ef41Sopenharmony_ci  Handle<String> name = v8_str(isolate, "WebAssembly");
27811cb0ef41Sopenharmony_ci  // Not supposed to be called, hence using the kIllegal builtin as code.
27821cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> info =
27831cb0ef41Sopenharmony_ci      factory->NewSharedFunctionInfoForBuiltin(name, Builtin::kIllegal);
27841cb0ef41Sopenharmony_ci  info->set_language_mode(LanguageMode::kStrict);
27851cb0ef41Sopenharmony_ci
27861cb0ef41Sopenharmony_ci  Handle<JSFunction> cons =
27871cb0ef41Sopenharmony_ci      Factory::JSFunctionBuilder{isolate, info, context}.Build();
27881cb0ef41Sopenharmony_ci  JSFunction::SetPrototype(cons, isolate->initial_object_prototype());
27891cb0ef41Sopenharmony_ci  Handle<JSObject> webassembly =
27901cb0ef41Sopenharmony_ci      factory->NewJSObject(cons, AllocationType::kOld);
27911cb0ef41Sopenharmony_ci
27921cb0ef41Sopenharmony_ci  PropertyAttributes ro_attributes =
27931cb0ef41Sopenharmony_ci      static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
27941cb0ef41Sopenharmony_ci  JSObject::AddProperty(isolate, webassembly, factory->to_string_tag_symbol(),
27951cb0ef41Sopenharmony_ci                        name, ro_attributes);
27961cb0ef41Sopenharmony_ci  InstallFunc(isolate, webassembly, "compile", WebAssemblyCompile, 1);
27971cb0ef41Sopenharmony_ci  InstallFunc(isolate, webassembly, "validate", WebAssemblyValidate, 1);
27981cb0ef41Sopenharmony_ci  InstallFunc(isolate, webassembly, "instantiate", WebAssemblyInstantiate, 1);
27991cb0ef41Sopenharmony_ci
28001cb0ef41Sopenharmony_ci  if (FLAG_wasm_test_streaming) {
28011cb0ef41Sopenharmony_ci    isolate->set_wasm_streaming_callback(WasmStreamingCallbackForTesting);
28021cb0ef41Sopenharmony_ci  }
28031cb0ef41Sopenharmony_ci
28041cb0ef41Sopenharmony_ci  if (isolate->wasm_streaming_callback() != nullptr) {
28051cb0ef41Sopenharmony_ci    InstallFunc(isolate, webassembly, "compileStreaming",
28061cb0ef41Sopenharmony_ci                WebAssemblyCompileStreaming, 1);
28071cb0ef41Sopenharmony_ci    InstallFunc(isolate, webassembly, "instantiateStreaming",
28081cb0ef41Sopenharmony_ci                WebAssemblyInstantiateStreaming, 1);
28091cb0ef41Sopenharmony_ci  }
28101cb0ef41Sopenharmony_ci
28111cb0ef41Sopenharmony_ci  // Expose the API on the global object if configured to do so.
28121cb0ef41Sopenharmony_ci  if (exposed_on_global_object) {
28131cb0ef41Sopenharmony_ci    JSObject::AddProperty(isolate, global, name, webassembly, DONT_ENUM);
28141cb0ef41Sopenharmony_ci  }
28151cb0ef41Sopenharmony_ci
28161cb0ef41Sopenharmony_ci  // Setup Module
28171cb0ef41Sopenharmony_ci  Handle<JSFunction> module_constructor =
28181cb0ef41Sopenharmony_ci      InstallConstructorFunc(isolate, webassembly, "Module", WebAssemblyModule);
28191cb0ef41Sopenharmony_ci  SetupConstructor(isolate, module_constructor, i::WASM_MODULE_OBJECT_TYPE,
28201cb0ef41Sopenharmony_ci                   WasmModuleObject::kHeaderSize, "WebAssembly.Module");
28211cb0ef41Sopenharmony_ci  context->set_wasm_module_constructor(*module_constructor);
28221cb0ef41Sopenharmony_ci  InstallFunc(isolate, module_constructor, "imports", WebAssemblyModuleImports,
28231cb0ef41Sopenharmony_ci              1, false, NONE, SideEffectType::kHasNoSideEffect);
28241cb0ef41Sopenharmony_ci  InstallFunc(isolate, module_constructor, "exports", WebAssemblyModuleExports,
28251cb0ef41Sopenharmony_ci              1, false, NONE, SideEffectType::kHasNoSideEffect);
28261cb0ef41Sopenharmony_ci  InstallFunc(isolate, module_constructor, "customSections",
28271cb0ef41Sopenharmony_ci              WebAssemblyModuleCustomSections, 2, false, NONE,
28281cb0ef41Sopenharmony_ci              SideEffectType::kHasNoSideEffect);
28291cb0ef41Sopenharmony_ci
28301cb0ef41Sopenharmony_ci  // Setup Instance
28311cb0ef41Sopenharmony_ci  Handle<JSFunction> instance_constructor = InstallConstructorFunc(
28321cb0ef41Sopenharmony_ci      isolate, webassembly, "Instance", WebAssemblyInstance);
28331cb0ef41Sopenharmony_ci  Handle<JSObject> instance_proto = SetupConstructor(
28341cb0ef41Sopenharmony_ci      isolate, instance_constructor, i::WASM_INSTANCE_OBJECT_TYPE,
28351cb0ef41Sopenharmony_ci      WasmInstanceObject::kHeaderSize, "WebAssembly.Instance");
28361cb0ef41Sopenharmony_ci  context->set_wasm_instance_constructor(*instance_constructor);
28371cb0ef41Sopenharmony_ci  InstallGetter(isolate, instance_proto, "exports",
28381cb0ef41Sopenharmony_ci                WebAssemblyInstanceGetExports);
28391cb0ef41Sopenharmony_ci
28401cb0ef41Sopenharmony_ci  // The context is not set up completely yet. That's why we cannot use
28411cb0ef41Sopenharmony_ci  // {WasmFeatures::FromIsolate} and have to use {WasmFeatures::FromFlags}
28421cb0ef41Sopenharmony_ci  // instead.
28431cb0ef41Sopenharmony_ci  auto enabled_features = i::wasm::WasmFeatures::FromFlags();
28441cb0ef41Sopenharmony_ci
28451cb0ef41Sopenharmony_ci  // Setup Table
28461cb0ef41Sopenharmony_ci  Handle<JSFunction> table_constructor =
28471cb0ef41Sopenharmony_ci      InstallConstructorFunc(isolate, webassembly, "Table", WebAssemblyTable);
28481cb0ef41Sopenharmony_ci  Handle<JSObject> table_proto =
28491cb0ef41Sopenharmony_ci      SetupConstructor(isolate, table_constructor, i::WASM_TABLE_OBJECT_TYPE,
28501cb0ef41Sopenharmony_ci                       WasmTableObject::kHeaderSize, "WebAssembly.Table");
28511cb0ef41Sopenharmony_ci  context->set_wasm_table_constructor(*table_constructor);
28521cb0ef41Sopenharmony_ci  InstallGetter(isolate, table_proto, "length", WebAssemblyTableGetLength);
28531cb0ef41Sopenharmony_ci  InstallFunc(isolate, table_proto, "grow", WebAssemblyTableGrow, 1);
28541cb0ef41Sopenharmony_ci  InstallFunc(isolate, table_proto, "get", WebAssemblyTableGet, 1, false, NONE,
28551cb0ef41Sopenharmony_ci              SideEffectType::kHasNoSideEffect);
28561cb0ef41Sopenharmony_ci  InstallFunc(isolate, table_proto, "set", WebAssemblyTableSet, 2);
28571cb0ef41Sopenharmony_ci  if (enabled_features.has_type_reflection()) {
28581cb0ef41Sopenharmony_ci    InstallFunc(isolate, table_proto, "type", WebAssemblyTableType, 0, false,
28591cb0ef41Sopenharmony_ci                NONE, SideEffectType::kHasNoSideEffect);
28601cb0ef41Sopenharmony_ci  }
28611cb0ef41Sopenharmony_ci
28621cb0ef41Sopenharmony_ci  // Setup Memory
28631cb0ef41Sopenharmony_ci  Handle<JSFunction> memory_constructor =
28641cb0ef41Sopenharmony_ci      InstallConstructorFunc(isolate, webassembly, "Memory", WebAssemblyMemory);
28651cb0ef41Sopenharmony_ci  Handle<JSObject> memory_proto =
28661cb0ef41Sopenharmony_ci      SetupConstructor(isolate, memory_constructor, i::WASM_MEMORY_OBJECT_TYPE,
28671cb0ef41Sopenharmony_ci                       WasmMemoryObject::kHeaderSize, "WebAssembly.Memory");
28681cb0ef41Sopenharmony_ci  context->set_wasm_memory_constructor(*memory_constructor);
28691cb0ef41Sopenharmony_ci  InstallFunc(isolate, memory_proto, "grow", WebAssemblyMemoryGrow, 1);
28701cb0ef41Sopenharmony_ci  InstallGetter(isolate, memory_proto, "buffer", WebAssemblyMemoryGetBuffer);
28711cb0ef41Sopenharmony_ci  if (enabled_features.has_type_reflection()) {
28721cb0ef41Sopenharmony_ci    InstallFunc(isolate, memory_proto, "type", WebAssemblyMemoryType, 0, false,
28731cb0ef41Sopenharmony_ci                NONE, SideEffectType::kHasNoSideEffect);
28741cb0ef41Sopenharmony_ci  }
28751cb0ef41Sopenharmony_ci
28761cb0ef41Sopenharmony_ci  // Setup Global
28771cb0ef41Sopenharmony_ci  Handle<JSFunction> global_constructor =
28781cb0ef41Sopenharmony_ci      InstallConstructorFunc(isolate, webassembly, "Global", WebAssemblyGlobal);
28791cb0ef41Sopenharmony_ci  Handle<JSObject> global_proto =
28801cb0ef41Sopenharmony_ci      SetupConstructor(isolate, global_constructor, i::WASM_GLOBAL_OBJECT_TYPE,
28811cb0ef41Sopenharmony_ci                       WasmGlobalObject::kHeaderSize, "WebAssembly.Global");
28821cb0ef41Sopenharmony_ci  context->set_wasm_global_constructor(*global_constructor);
28831cb0ef41Sopenharmony_ci  InstallFunc(isolate, global_proto, "valueOf", WebAssemblyGlobalValueOf, 0,
28841cb0ef41Sopenharmony_ci              false, NONE, SideEffectType::kHasNoSideEffect);
28851cb0ef41Sopenharmony_ci  InstallGetterSetter(isolate, global_proto, "value", WebAssemblyGlobalGetValue,
28861cb0ef41Sopenharmony_ci                      WebAssemblyGlobalSetValue);
28871cb0ef41Sopenharmony_ci  if (enabled_features.has_type_reflection()) {
28881cb0ef41Sopenharmony_ci    InstallFunc(isolate, global_proto, "type", WebAssemblyGlobalType, 0, false,
28891cb0ef41Sopenharmony_ci                NONE, SideEffectType::kHasNoSideEffect);
28901cb0ef41Sopenharmony_ci  }
28911cb0ef41Sopenharmony_ci
28921cb0ef41Sopenharmony_ci  // Setup Exception
28931cb0ef41Sopenharmony_ci  if (enabled_features.has_eh()) {
28941cb0ef41Sopenharmony_ci    Handle<JSFunction> tag_constructor =
28951cb0ef41Sopenharmony_ci        InstallConstructorFunc(isolate, webassembly, "Tag", WebAssemblyTag);
28961cb0ef41Sopenharmony_ci    Handle<JSObject> tag_proto =
28971cb0ef41Sopenharmony_ci        SetupConstructor(isolate, tag_constructor, i::WASM_TAG_OBJECT_TYPE,
28981cb0ef41Sopenharmony_ci                         WasmTagObject::kHeaderSize, "WebAssembly.Tag");
28991cb0ef41Sopenharmony_ci    context->set_wasm_tag_constructor(*tag_constructor);
29001cb0ef41Sopenharmony_ci
29011cb0ef41Sopenharmony_ci    if (enabled_features.has_type_reflection()) {
29021cb0ef41Sopenharmony_ci      InstallFunc(isolate, tag_proto, "type", WebAssemblyTagType, 0);
29031cb0ef41Sopenharmony_ci    }
29041cb0ef41Sopenharmony_ci    // Set up runtime exception constructor.
29051cb0ef41Sopenharmony_ci    Handle<JSFunction> exception_constructor = InstallConstructorFunc(
29061cb0ef41Sopenharmony_ci        isolate, webassembly, "Exception", WebAssemblyException);
29071cb0ef41Sopenharmony_ci    SetDummyInstanceTemplate(isolate, exception_constructor);
29081cb0ef41Sopenharmony_ci    Handle<Map> exception_map(isolate->native_context()
29091cb0ef41Sopenharmony_ci                                  ->wasm_exception_error_function()
29101cb0ef41Sopenharmony_ci                                  .initial_map(),
29111cb0ef41Sopenharmony_ci                              isolate);
29121cb0ef41Sopenharmony_ci    Handle<JSObject> exception_proto(
29131cb0ef41Sopenharmony_ci        JSObject::cast(isolate->native_context()
29141cb0ef41Sopenharmony_ci                           ->wasm_exception_error_function()
29151cb0ef41Sopenharmony_ci                           .instance_prototype()),
29161cb0ef41Sopenharmony_ci        isolate);
29171cb0ef41Sopenharmony_ci    InstallFunc(isolate, exception_proto, "getArg", WebAssemblyExceptionGetArg,
29181cb0ef41Sopenharmony_ci                2);
29191cb0ef41Sopenharmony_ci    InstallFunc(isolate, exception_proto, "is", WebAssemblyExceptionIs, 1);
29201cb0ef41Sopenharmony_ci    context->set_wasm_exception_constructor(*exception_constructor);
29211cb0ef41Sopenharmony_ci    JSFunction::SetInitialMap(isolate, exception_constructor, exception_map,
29221cb0ef41Sopenharmony_ci                              exception_proto);
29231cb0ef41Sopenharmony_ci  }
29241cb0ef41Sopenharmony_ci
29251cb0ef41Sopenharmony_ci  // Setup Suspender.
29261cb0ef41Sopenharmony_ci  if (enabled_features.has_stack_switching()) {
29271cb0ef41Sopenharmony_ci    Handle<JSFunction> suspender_constructor = InstallConstructorFunc(
29281cb0ef41Sopenharmony_ci        isolate, webassembly, "Suspender", WebAssemblySuspender);
29291cb0ef41Sopenharmony_ci    context->set_wasm_suspender_constructor(*suspender_constructor);
29301cb0ef41Sopenharmony_ci    Handle<JSObject> suspender_proto = SetupConstructor(
29311cb0ef41Sopenharmony_ci        isolate, suspender_constructor, i::WASM_SUSPENDER_OBJECT_TYPE,
29321cb0ef41Sopenharmony_ci        WasmSuspenderObject::kHeaderSize, "WebAssembly.Suspender");
29331cb0ef41Sopenharmony_ci    InstallFunc(isolate, suspender_proto, "returnPromiseOnSuspend",
29341cb0ef41Sopenharmony_ci                WebAssemblySuspenderReturnPromiseOnSuspend, 1);
29351cb0ef41Sopenharmony_ci    InstallFunc(isolate, suspender_proto, "suspendOnReturnedPromise",
29361cb0ef41Sopenharmony_ci                WebAssemblySuspenderSuspendOnReturnedPromise, 1);
29371cb0ef41Sopenharmony_ci  }
29381cb0ef41Sopenharmony_ci
29391cb0ef41Sopenharmony_ci  // Setup Function
29401cb0ef41Sopenharmony_ci  if (enabled_features.has_type_reflection()) {
29411cb0ef41Sopenharmony_ci    Handle<JSFunction> function_constructor = InstallConstructorFunc(
29421cb0ef41Sopenharmony_ci        isolate, webassembly, "Function", WebAssemblyFunction);
29431cb0ef41Sopenharmony_ci    SetDummyInstanceTemplate(isolate, function_constructor);
29441cb0ef41Sopenharmony_ci    JSFunction::EnsureHasInitialMap(function_constructor);
29451cb0ef41Sopenharmony_ci    Handle<JSObject> function_proto(
29461cb0ef41Sopenharmony_ci        JSObject::cast(function_constructor->instance_prototype()), isolate);
29471cb0ef41Sopenharmony_ci    Handle<Map> function_map = isolate->factory()->CreateSloppyFunctionMap(
29481cb0ef41Sopenharmony_ci        FUNCTION_WITHOUT_PROTOTYPE, MaybeHandle<JSFunction>());
29491cb0ef41Sopenharmony_ci    CHECK(JSObject::SetPrototype(
29501cb0ef41Sopenharmony_ci              isolate, function_proto,
29511cb0ef41Sopenharmony_ci              handle(context->function_function().prototype(), isolate), false,
29521cb0ef41Sopenharmony_ci              kDontThrow)
29531cb0ef41Sopenharmony_ci              .FromJust());
29541cb0ef41Sopenharmony_ci    JSFunction::SetInitialMap(isolate, function_constructor, function_map,
29551cb0ef41Sopenharmony_ci                              function_proto);
29561cb0ef41Sopenharmony_ci    InstallFunc(isolate, function_constructor, "type", WebAssemblyFunctionType,
29571cb0ef41Sopenharmony_ci                1);
29581cb0ef41Sopenharmony_ci    // Make all exported functions an instance of {WebAssembly.Function}.
29591cb0ef41Sopenharmony_ci    context->set_wasm_exported_function_map(*function_map);
29601cb0ef41Sopenharmony_ci  } else {
29611cb0ef41Sopenharmony_ci    // Make all exported functions an instance of {Function}.
29621cb0ef41Sopenharmony_ci    Handle<Map> function_map = isolate->sloppy_function_without_prototype_map();
29631cb0ef41Sopenharmony_ci    context->set_wasm_exported_function_map(*function_map);
29641cb0ef41Sopenharmony_ci  }
29651cb0ef41Sopenharmony_ci
29661cb0ef41Sopenharmony_ci  // Setup errors
29671cb0ef41Sopenharmony_ci  Handle<JSFunction> compile_error(
29681cb0ef41Sopenharmony_ci      isolate->native_context()->wasm_compile_error_function(), isolate);
29691cb0ef41Sopenharmony_ci  JSObject::AddProperty(isolate, webassembly,
29701cb0ef41Sopenharmony_ci                        isolate->factory()->CompileError_string(),
29711cb0ef41Sopenharmony_ci                        compile_error, DONT_ENUM);
29721cb0ef41Sopenharmony_ci  Handle<JSFunction> link_error(
29731cb0ef41Sopenharmony_ci      isolate->native_context()->wasm_link_error_function(), isolate);
29741cb0ef41Sopenharmony_ci  JSObject::AddProperty(isolate, webassembly,
29751cb0ef41Sopenharmony_ci                        isolate->factory()->LinkError_string(), link_error,
29761cb0ef41Sopenharmony_ci                        DONT_ENUM);
29771cb0ef41Sopenharmony_ci  Handle<JSFunction> runtime_error(
29781cb0ef41Sopenharmony_ci      isolate->native_context()->wasm_runtime_error_function(), isolate);
29791cb0ef41Sopenharmony_ci  JSObject::AddProperty(isolate, webassembly,
29801cb0ef41Sopenharmony_ci                        isolate->factory()->RuntimeError_string(),
29811cb0ef41Sopenharmony_ci                        runtime_error, DONT_ENUM);
29821cb0ef41Sopenharmony_ci}
29831cb0ef41Sopenharmony_ci
29841cb0ef41Sopenharmony_ci// static
29851cb0ef41Sopenharmony_civoid WasmJs::InstallConditionalFeatures(Isolate* isolate,
29861cb0ef41Sopenharmony_ci                                        Handle<Context> context) {
29871cb0ef41Sopenharmony_ci  // Exception handling may have been enabled by an origin trial. If so, make
29881cb0ef41Sopenharmony_ci  // sure that the {WebAssembly.Tag} constructor is set up.
29891cb0ef41Sopenharmony_ci  auto enabled_features = i::wasm::WasmFeatures::FromContext(isolate, context);
29901cb0ef41Sopenharmony_ci  if (enabled_features.has_eh()) {
29911cb0ef41Sopenharmony_ci    Handle<JSGlobalObject> global = handle(context->global_object(), isolate);
29921cb0ef41Sopenharmony_ci    MaybeHandle<Object> maybe_webassembly =
29931cb0ef41Sopenharmony_ci        JSObject::GetProperty(isolate, global, "WebAssembly");
29941cb0ef41Sopenharmony_ci    Handle<Object> webassembly_obj;
29951cb0ef41Sopenharmony_ci    if (!maybe_webassembly.ToHandle(&webassembly_obj) ||
29961cb0ef41Sopenharmony_ci        !webassembly_obj->IsJSObject()) {
29971cb0ef41Sopenharmony_ci      // There is no {WebAssembly} object, or it's not what we expect.
29981cb0ef41Sopenharmony_ci      // Just return without adding the {Tag} constructor.
29991cb0ef41Sopenharmony_ci      return;
30001cb0ef41Sopenharmony_ci    }
30011cb0ef41Sopenharmony_ci    Handle<JSObject> webassembly = Handle<JSObject>::cast(webassembly_obj);
30021cb0ef41Sopenharmony_ci    // Setup Tag.
30031cb0ef41Sopenharmony_ci    Handle<String> tag_name = v8_str(isolate, "Tag");
30041cb0ef41Sopenharmony_ci    // The {WebAssembly} object may already have been modified. The following
30051cb0ef41Sopenharmony_ci    // code is designed to:
30061cb0ef41Sopenharmony_ci    //  - check for existing {Tag} properties on the object itself, and avoid
30071cb0ef41Sopenharmony_ci    //    overwriting them or adding duplicate properties
30081cb0ef41Sopenharmony_ci    //  - disregard any setters or read-only properties on the prototype chain
30091cb0ef41Sopenharmony_ci    //  - only make objects accessible to user code after all internal setup
30101cb0ef41Sopenharmony_ci    //    has been completed.
30111cb0ef41Sopenharmony_ci    if (JSObject::HasOwnProperty(isolate, webassembly, tag_name)
30121cb0ef41Sopenharmony_ci            .FromMaybe(true)) {
30131cb0ef41Sopenharmony_ci      // Existing property, or exception.
30141cb0ef41Sopenharmony_ci      return;
30151cb0ef41Sopenharmony_ci    }
30161cb0ef41Sopenharmony_ci
30171cb0ef41Sopenharmony_ci    bool has_prototype = true;
30181cb0ef41Sopenharmony_ci    Handle<JSFunction> tag_constructor =
30191cb0ef41Sopenharmony_ci        CreateFunc(isolate, tag_name, WebAssemblyTag, has_prototype,
30201cb0ef41Sopenharmony_ci                   SideEffectType::kHasNoSideEffect);
30211cb0ef41Sopenharmony_ci    tag_constructor->shared().set_length(1);
30221cb0ef41Sopenharmony_ci    context->set_wasm_tag_constructor(*tag_constructor);
30231cb0ef41Sopenharmony_ci    Handle<JSObject> tag_proto =
30241cb0ef41Sopenharmony_ci        SetupConstructor(isolate, tag_constructor, i::WASM_TAG_OBJECT_TYPE,
30251cb0ef41Sopenharmony_ci                         WasmTagObject::kHeaderSize, "WebAssembly.Tag");
30261cb0ef41Sopenharmony_ci    if (enabled_features.has_type_reflection()) {
30271cb0ef41Sopenharmony_ci      InstallFunc(isolate, tag_proto, "type", WebAssemblyTagType, 0);
30281cb0ef41Sopenharmony_ci    }
30291cb0ef41Sopenharmony_ci    LookupIterator it(isolate, webassembly, tag_name, LookupIterator::OWN);
30301cb0ef41Sopenharmony_ci    Maybe<bool> result = JSObject::DefineOwnPropertyIgnoreAttributes(
30311cb0ef41Sopenharmony_ci        &it, tag_constructor, DONT_ENUM, Just(kDontThrow));
30321cb0ef41Sopenharmony_ci    // This could still fail if the object was non-extensible, but now we
30331cb0ef41Sopenharmony_ci    // return anyway so there's no need to even check.
30341cb0ef41Sopenharmony_ci    USE(result);
30351cb0ef41Sopenharmony_ci  }
30361cb0ef41Sopenharmony_ci}
30371cb0ef41Sopenharmony_ci#undef ASSIGN
30381cb0ef41Sopenharmony_ci#undef EXTRACT_THIS
30391cb0ef41Sopenharmony_ci
30401cb0ef41Sopenharmony_ci}  // namespace internal
30411cb0ef41Sopenharmony_ci}  // namespace v8
3042