11cb0ef41Sopenharmony_ci// Copyright 2019 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/module-instantiate.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "src/api/api-inl.h"
81cb0ef41Sopenharmony_ci#include "src/asmjs/asm-js.h"
91cb0ef41Sopenharmony_ci#include "src/base/atomicops.h"
101cb0ef41Sopenharmony_ci#include "src/base/platform/wrappers.h"
111cb0ef41Sopenharmony_ci#include "src/logging/counters-scopes.h"
121cb0ef41Sopenharmony_ci#include "src/logging/metrics.h"
131cb0ef41Sopenharmony_ci#include "src/numbers/conversions-inl.h"
141cb0ef41Sopenharmony_ci#include "src/objects/descriptor-array-inl.h"
151cb0ef41Sopenharmony_ci#include "src/objects/property-descriptor.h"
161cb0ef41Sopenharmony_ci#include "src/tracing/trace-event.h"
171cb0ef41Sopenharmony_ci#include "src/utils/utils.h"
181cb0ef41Sopenharmony_ci#include "src/wasm/code-space-access.h"
191cb0ef41Sopenharmony_ci#include "src/wasm/init-expr-interface.h"
201cb0ef41Sopenharmony_ci#include "src/wasm/module-compiler.h"
211cb0ef41Sopenharmony_ci#include "src/wasm/wasm-constants.h"
221cb0ef41Sopenharmony_ci#include "src/wasm/wasm-engine.h"
231cb0ef41Sopenharmony_ci#include "src/wasm/wasm-external-refs.h"
241cb0ef41Sopenharmony_ci#include "src/wasm/wasm-import-wrapper-cache.h"
251cb0ef41Sopenharmony_ci#include "src/wasm/wasm-module.h"
261cb0ef41Sopenharmony_ci#include "src/wasm/wasm-objects-inl.h"
271cb0ef41Sopenharmony_ci#include "src/wasm/wasm-opcodes-inl.h"
281cb0ef41Sopenharmony_ci#include "src/wasm/wasm-subtyping.h"
291cb0ef41Sopenharmony_ci#include "src/wasm/wasm-value.h"
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ci#define TRACE(...)                                      \
321cb0ef41Sopenharmony_ci  do {                                                  \
331cb0ef41Sopenharmony_ci    if (FLAG_trace_wasm_instances) PrintF(__VA_ARGS__); \
341cb0ef41Sopenharmony_ci  } while (false)
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_cinamespace v8 {
371cb0ef41Sopenharmony_cinamespace internal {
381cb0ef41Sopenharmony_cinamespace wasm {
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_cinamespace {
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_cibyte* raw_buffer_ptr(MaybeHandle<JSArrayBuffer> buffer, int offset) {
431cb0ef41Sopenharmony_ci  return static_cast<byte*>(buffer.ToHandleChecked()->backing_store()) + offset;
441cb0ef41Sopenharmony_ci}
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ciusing ImportWrapperQueue = WrapperQueue<WasmImportWrapperCache::CacheKey,
471cb0ef41Sopenharmony_ci                                        WasmImportWrapperCache::CacheKeyHash>;
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ciclass CompileImportWrapperJob final : public JobTask {
501cb0ef41Sopenharmony_ci public:
511cb0ef41Sopenharmony_ci  CompileImportWrapperJob(
521cb0ef41Sopenharmony_ci      Counters* counters, NativeModule* native_module,
531cb0ef41Sopenharmony_ci      ImportWrapperQueue* queue,
541cb0ef41Sopenharmony_ci      WasmImportWrapperCache::ModificationScope* cache_scope)
551cb0ef41Sopenharmony_ci      : counters_(counters),
561cb0ef41Sopenharmony_ci        native_module_(native_module),
571cb0ef41Sopenharmony_ci        queue_(queue),
581cb0ef41Sopenharmony_ci        cache_scope_(cache_scope) {}
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci  size_t GetMaxConcurrency(size_t worker_count) const override {
611cb0ef41Sopenharmony_ci    size_t flag_limit =
621cb0ef41Sopenharmony_ci        static_cast<size_t>(std::max(1, FLAG_wasm_num_compilation_tasks));
631cb0ef41Sopenharmony_ci    // Add {worker_count} to the queue size because workers might still be
641cb0ef41Sopenharmony_ci    // processing units that have already been popped from the queue.
651cb0ef41Sopenharmony_ci    return std::min(flag_limit, worker_count + queue_->size());
661cb0ef41Sopenharmony_ci  }
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci  void Run(JobDelegate* delegate) override {
691cb0ef41Sopenharmony_ci    TRACE_EVENT0("v8.wasm", "wasm.CompileImportWrapperJob.Run");
701cb0ef41Sopenharmony_ci    while (base::Optional<WasmImportWrapperCache::CacheKey> key =
711cb0ef41Sopenharmony_ci               queue_->pop()) {
721cb0ef41Sopenharmony_ci      // TODO(wasm): Batch code publishing, to avoid repeated locking and
731cb0ef41Sopenharmony_ci      // permission switching.
741cb0ef41Sopenharmony_ci      CompileImportWrapper(native_module_, counters_, key->kind, key->signature,
751cb0ef41Sopenharmony_ci                           key->expected_arity, key->suspend, cache_scope_);
761cb0ef41Sopenharmony_ci      if (delegate->ShouldYield()) return;
771cb0ef41Sopenharmony_ci    }
781cb0ef41Sopenharmony_ci  }
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci private:
811cb0ef41Sopenharmony_ci  Counters* const counters_;
821cb0ef41Sopenharmony_ci  NativeModule* const native_module_;
831cb0ef41Sopenharmony_ci  ImportWrapperQueue* const queue_;
841cb0ef41Sopenharmony_ci  WasmImportWrapperCache::ModificationScope* const cache_scope_;
851cb0ef41Sopenharmony_ci};
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ciHandle<DescriptorArray> CreateStructDescriptorArray(
881cb0ef41Sopenharmony_ci    Isolate* isolate, const wasm::StructType* type) {
891cb0ef41Sopenharmony_ci  if (type->field_count() == 0) {
901cb0ef41Sopenharmony_ci    return isolate->factory()->empty_descriptor_array();
911cb0ef41Sopenharmony_ci  }
921cb0ef41Sopenharmony_ci  uint32_t field_count = type->field_count();
931cb0ef41Sopenharmony_ci  static_assert(kV8MaxWasmStructFields <= kMaxNumberOfDescriptors,
941cb0ef41Sopenharmony_ci                "Bigger numbers of struct fields require different approach");
951cb0ef41Sopenharmony_ci  Handle<DescriptorArray> descriptors =
961cb0ef41Sopenharmony_ci      isolate->factory()->NewDescriptorArray(field_count);
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ci  // TODO(ishell): cache Wasm field type in FieldType value.
991cb0ef41Sopenharmony_ci  MaybeObject any_type = MaybeObject::FromObject(FieldType::Any());
1001cb0ef41Sopenharmony_ci  DCHECK(any_type->IsSmi());
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ci  base::EmbeddedVector<char, 128> name_buffer;
1031cb0ef41Sopenharmony_ci  for (uint32_t i = 0; i < field_count; i++) {
1041cb0ef41Sopenharmony_ci    // TODO(ishell): consider introducing a cache of first N internalized field
1051cb0ef41Sopenharmony_ci    // names similar to LookupSingleCharacterStringFromCode().
1061cb0ef41Sopenharmony_ci    SNPrintF(name_buffer, "$field%d", i);
1071cb0ef41Sopenharmony_ci    Handle<String> name =
1081cb0ef41Sopenharmony_ci        isolate->factory()->InternalizeUtf8String(name_buffer.begin());
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci    PropertyAttributes attributes = type->mutability(i) ? SEALED : FROZEN;
1111cb0ef41Sopenharmony_ci    PropertyDetails details(
1121cb0ef41Sopenharmony_ci        PropertyKind::kData, attributes, PropertyLocation::kField,
1131cb0ef41Sopenharmony_ci        PropertyConstness::kMutable,  // Don't track constness
1141cb0ef41Sopenharmony_ci        Representation::WasmValue(), static_cast<int>(i));
1151cb0ef41Sopenharmony_ci    descriptors->Set(InternalIndex(i), *name, any_type, details);
1161cb0ef41Sopenharmony_ci  }
1171cb0ef41Sopenharmony_ci  descriptors->Sort();
1181cb0ef41Sopenharmony_ci  return descriptors;
1191cb0ef41Sopenharmony_ci}
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_ciHandle<DescriptorArray> CreateArrayDescriptorArray(
1221cb0ef41Sopenharmony_ci    Isolate* isolate, const wasm::ArrayType* type) {
1231cb0ef41Sopenharmony_ci  uint32_t kDescriptorsCount = 1;
1241cb0ef41Sopenharmony_ci  Handle<DescriptorArray> descriptors =
1251cb0ef41Sopenharmony_ci      isolate->factory()->NewDescriptorArray(kDescriptorsCount);
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ci  // TODO(ishell): cache Wasm field type in FieldType value.
1281cb0ef41Sopenharmony_ci  MaybeObject any_type = MaybeObject::FromObject(FieldType::Any());
1291cb0ef41Sopenharmony_ci  DCHECK(any_type->IsSmi());
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ci  // Add descriptor for length property.
1321cb0ef41Sopenharmony_ci  PropertyDetails details(PropertyKind::kData, FROZEN, PropertyLocation::kField,
1331cb0ef41Sopenharmony_ci                          PropertyConstness::kConst,
1341cb0ef41Sopenharmony_ci                          Representation::WasmValue(), static_cast<int>(0));
1351cb0ef41Sopenharmony_ci  descriptors->Set(InternalIndex(0), *isolate->factory()->length_string(),
1361cb0ef41Sopenharmony_ci                   any_type, details);
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_ci  descriptors->Sort();
1391cb0ef41Sopenharmony_ci  return descriptors;
1401cb0ef41Sopenharmony_ci}
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ciHandle<Map> CreateStructMap(Isolate* isolate, const WasmModule* module,
1431cb0ef41Sopenharmony_ci                            int struct_index, Handle<Map> opt_rtt_parent,
1441cb0ef41Sopenharmony_ci                            Handle<WasmInstanceObject> instance) {
1451cb0ef41Sopenharmony_ci  const wasm::StructType* type = module->struct_type(struct_index);
1461cb0ef41Sopenharmony_ci  const int inobject_properties = 0;
1471cb0ef41Sopenharmony_ci  // We have to use the variable size sentinel because the instance size
1481cb0ef41Sopenharmony_ci  // stored directly in a Map is capped at 255 pointer sizes.
1491cb0ef41Sopenharmony_ci  const int map_instance_size = kVariableSizeSentinel;
1501cb0ef41Sopenharmony_ci  const int real_instance_size = WasmStruct::Size(type);
1511cb0ef41Sopenharmony_ci  const InstanceType instance_type = WASM_STRUCT_TYPE;
1521cb0ef41Sopenharmony_ci  // TODO(jkummerow): If NO_ELEMENTS were supported, we could use that here.
1531cb0ef41Sopenharmony_ci  const ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND;
1541cb0ef41Sopenharmony_ci  Handle<WasmTypeInfo> type_info = isolate->factory()->NewWasmTypeInfo(
1551cb0ef41Sopenharmony_ci      reinterpret_cast<Address>(type), opt_rtt_parent, real_instance_size,
1561cb0ef41Sopenharmony_ci      instance);
1571cb0ef41Sopenharmony_ci  Handle<DescriptorArray> descriptors =
1581cb0ef41Sopenharmony_ci      CreateStructDescriptorArray(isolate, type);
1591cb0ef41Sopenharmony_ci  Handle<Map> map = isolate->factory()->NewMap(
1601cb0ef41Sopenharmony_ci      instance_type, map_instance_size, elements_kind, inobject_properties);
1611cb0ef41Sopenharmony_ci  map->set_wasm_type_info(*type_info);
1621cb0ef41Sopenharmony_ci  map->SetInstanceDescriptors(isolate, *descriptors,
1631cb0ef41Sopenharmony_ci                              descriptors->number_of_descriptors());
1641cb0ef41Sopenharmony_ci  map->set_is_extensible(false);
1651cb0ef41Sopenharmony_ci  WasmStruct::EncodeInstanceSizeInMap(real_instance_size, *map);
1661cb0ef41Sopenharmony_ci  return map;
1671cb0ef41Sopenharmony_ci}
1681cb0ef41Sopenharmony_ci
1691cb0ef41Sopenharmony_ciHandle<Map> CreateArrayMap(Isolate* isolate, const WasmModule* module,
1701cb0ef41Sopenharmony_ci                           int array_index, Handle<Map> opt_rtt_parent,
1711cb0ef41Sopenharmony_ci                           Handle<WasmInstanceObject> instance) {
1721cb0ef41Sopenharmony_ci  const wasm::ArrayType* type = module->array_type(array_index);
1731cb0ef41Sopenharmony_ci  const int inobject_properties = 0;
1741cb0ef41Sopenharmony_ci  const int instance_size = kVariableSizeSentinel;
1751cb0ef41Sopenharmony_ci  // Wasm Arrays don't have a static instance size.
1761cb0ef41Sopenharmony_ci  const int cached_instance_size = 0;
1771cb0ef41Sopenharmony_ci  const InstanceType instance_type = WASM_ARRAY_TYPE;
1781cb0ef41Sopenharmony_ci  const ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND;
1791cb0ef41Sopenharmony_ci  Handle<WasmTypeInfo> type_info = isolate->factory()->NewWasmTypeInfo(
1801cb0ef41Sopenharmony_ci      reinterpret_cast<Address>(type), opt_rtt_parent, cached_instance_size,
1811cb0ef41Sopenharmony_ci      instance);
1821cb0ef41Sopenharmony_ci  // TODO(ishell): get canonical descriptor array for WasmArrays from roots.
1831cb0ef41Sopenharmony_ci  Handle<DescriptorArray> descriptors =
1841cb0ef41Sopenharmony_ci      CreateArrayDescriptorArray(isolate, type);
1851cb0ef41Sopenharmony_ci  Handle<Map> map = isolate->factory()->NewMap(
1861cb0ef41Sopenharmony_ci      instance_type, instance_size, elements_kind, inobject_properties);
1871cb0ef41Sopenharmony_ci  map->set_wasm_type_info(*type_info);
1881cb0ef41Sopenharmony_ci  map->SetInstanceDescriptors(isolate, *descriptors,
1891cb0ef41Sopenharmony_ci                              descriptors->number_of_descriptors());
1901cb0ef41Sopenharmony_ci  map->set_is_extensible(false);
1911cb0ef41Sopenharmony_ci  WasmArray::EncodeElementSizeInMap(type->element_type().value_kind_size(),
1921cb0ef41Sopenharmony_ci                                    *map);
1931cb0ef41Sopenharmony_ci  return map;
1941cb0ef41Sopenharmony_ci}
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_ciHandle<Map> CreateFuncRefMap(Isolate* isolate, const WasmModule* module,
1971cb0ef41Sopenharmony_ci                             Handle<Map> opt_rtt_parent,
1981cb0ef41Sopenharmony_ci                             Handle<WasmInstanceObject> instance) {
1991cb0ef41Sopenharmony_ci  const int inobject_properties = 0;
2001cb0ef41Sopenharmony_ci  const int instance_size =
2011cb0ef41Sopenharmony_ci      Map::cast(isolate->root(RootIndex::kWasmInternalFunctionMap))
2021cb0ef41Sopenharmony_ci          .instance_size();
2031cb0ef41Sopenharmony_ci  const InstanceType instance_type = WASM_INTERNAL_FUNCTION_TYPE;
2041cb0ef41Sopenharmony_ci  const ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND;
2051cb0ef41Sopenharmony_ci  Handle<WasmTypeInfo> type_info = isolate->factory()->NewWasmTypeInfo(
2061cb0ef41Sopenharmony_ci      kNullAddress, opt_rtt_parent, instance_size, instance);
2071cb0ef41Sopenharmony_ci  Handle<Map> map = isolate->factory()->NewMap(
2081cb0ef41Sopenharmony_ci      instance_type, instance_size, elements_kind, inobject_properties);
2091cb0ef41Sopenharmony_ci  map->set_wasm_type_info(*type_info);
2101cb0ef41Sopenharmony_ci  return map;
2111cb0ef41Sopenharmony_ci}
2121cb0ef41Sopenharmony_ci
2131cb0ef41Sopenharmony_civoid CreateMapForType(Isolate* isolate, const WasmModule* module,
2141cb0ef41Sopenharmony_ci                      int type_index, Handle<WasmInstanceObject> instance,
2151cb0ef41Sopenharmony_ci                      Handle<FixedArray> maps) {
2161cb0ef41Sopenharmony_ci  // Recursive calls for supertypes may already have created this map.
2171cb0ef41Sopenharmony_ci  if (maps->get(type_index).IsMap()) return;
2181cb0ef41Sopenharmony_ci
2191cb0ef41Sopenharmony_ci  Handle<WeakArrayList> canonical_rtts;
2201cb0ef41Sopenharmony_ci  uint32_t canonical_type_index =
2211cb0ef41Sopenharmony_ci      module->isorecursive_canonical_type_ids[type_index];
2221cb0ef41Sopenharmony_ci
2231cb0ef41Sopenharmony_ci  if (FLAG_wasm_type_canonicalization) {
2241cb0ef41Sopenharmony_ci    // Try to find the canonical map for this type in the isolate store.
2251cb0ef41Sopenharmony_ci    canonical_rtts = handle(isolate->heap()->wasm_canonical_rtts(), isolate);
2261cb0ef41Sopenharmony_ci    DCHECK_GT(static_cast<uint32_t>(canonical_rtts->length()),
2271cb0ef41Sopenharmony_ci              canonical_type_index);
2281cb0ef41Sopenharmony_ci    MaybeObject maybe_canonical_map = canonical_rtts->Get(canonical_type_index);
2291cb0ef41Sopenharmony_ci    if (maybe_canonical_map.IsStrongOrWeak() &&
2301cb0ef41Sopenharmony_ci        maybe_canonical_map.GetHeapObject().IsMap()) {
2311cb0ef41Sopenharmony_ci      maps->set(type_index, maybe_canonical_map.GetHeapObject());
2321cb0ef41Sopenharmony_ci      return;
2331cb0ef41Sopenharmony_ci    }
2341cb0ef41Sopenharmony_ci  }
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_ci  Handle<Map> rtt_parent;
2371cb0ef41Sopenharmony_ci  // If the type with {type_index} has an explicit supertype, make sure the
2381cb0ef41Sopenharmony_ci  // map for that supertype is created first, so that the supertypes list
2391cb0ef41Sopenharmony_ci  // that's cached on every RTT can be set up correctly.
2401cb0ef41Sopenharmony_ci  uint32_t supertype = module->supertype(type_index);
2411cb0ef41Sopenharmony_ci  if (supertype != kNoSuperType) {
2421cb0ef41Sopenharmony_ci    // This recursion is safe, because kV8MaxRttSubtypingDepth limits the
2431cb0ef41Sopenharmony_ci    // number of recursive steps, so we won't overflow the stack.
2441cb0ef41Sopenharmony_ci    CreateMapForType(isolate, module, supertype, instance, maps);
2451cb0ef41Sopenharmony_ci    rtt_parent = handle(Map::cast(maps->get(supertype)), isolate);
2461cb0ef41Sopenharmony_ci  }
2471cb0ef41Sopenharmony_ci  Handle<Map> map;
2481cb0ef41Sopenharmony_ci  switch (module->types[type_index].kind) {
2491cb0ef41Sopenharmony_ci    case TypeDefinition::kStruct:
2501cb0ef41Sopenharmony_ci      map = CreateStructMap(isolate, module, type_index, rtt_parent, instance);
2511cb0ef41Sopenharmony_ci      break;
2521cb0ef41Sopenharmony_ci    case TypeDefinition::kArray:
2531cb0ef41Sopenharmony_ci      map = CreateArrayMap(isolate, module, type_index, rtt_parent, instance);
2541cb0ef41Sopenharmony_ci      break;
2551cb0ef41Sopenharmony_ci    case TypeDefinition::kFunction:
2561cb0ef41Sopenharmony_ci      map = CreateFuncRefMap(isolate, module, rtt_parent, instance);
2571cb0ef41Sopenharmony_ci      break;
2581cb0ef41Sopenharmony_ci  }
2591cb0ef41Sopenharmony_ci  if (FLAG_wasm_type_canonicalization) {
2601cb0ef41Sopenharmony_ci    canonical_rtts->Set(canonical_type_index, HeapObjectReference::Weak(*map));
2611cb0ef41Sopenharmony_ci  }
2621cb0ef41Sopenharmony_ci  maps->set(type_index, *map);
2631cb0ef41Sopenharmony_ci}
2641cb0ef41Sopenharmony_ci
2651cb0ef41Sopenharmony_ci}  // namespace
2661cb0ef41Sopenharmony_ci
2671cb0ef41Sopenharmony_ci// A helper class to simplify instantiating a module from a module object.
2681cb0ef41Sopenharmony_ci// It closes over the {Isolate}, the {ErrorThrower}, etc.
2691cb0ef41Sopenharmony_ciclass InstanceBuilder {
2701cb0ef41Sopenharmony_ci public:
2711cb0ef41Sopenharmony_ci  InstanceBuilder(Isolate* isolate, v8::metrics::Recorder::ContextId context_id,
2721cb0ef41Sopenharmony_ci                  ErrorThrower* thrower, Handle<WasmModuleObject> module_object,
2731cb0ef41Sopenharmony_ci                  MaybeHandle<JSReceiver> ffi,
2741cb0ef41Sopenharmony_ci                  MaybeHandle<JSArrayBuffer> memory_buffer);
2751cb0ef41Sopenharmony_ci
2761cb0ef41Sopenharmony_ci  // Build an instance, in all of its glory.
2771cb0ef41Sopenharmony_ci  MaybeHandle<WasmInstanceObject> Build();
2781cb0ef41Sopenharmony_ci  // Run the start function, if any.
2791cb0ef41Sopenharmony_ci  bool ExecuteStartFunction();
2801cb0ef41Sopenharmony_ci
2811cb0ef41Sopenharmony_ci private:
2821cb0ef41Sopenharmony_ci  // A pre-evaluated value to use in import binding.
2831cb0ef41Sopenharmony_ci  struct SanitizedImport {
2841cb0ef41Sopenharmony_ci    Handle<String> module_name;
2851cb0ef41Sopenharmony_ci    Handle<String> import_name;
2861cb0ef41Sopenharmony_ci    Handle<Object> value;
2871cb0ef41Sopenharmony_ci  };
2881cb0ef41Sopenharmony_ci
2891cb0ef41Sopenharmony_ci  Isolate* isolate_;
2901cb0ef41Sopenharmony_ci  v8::metrics::Recorder::ContextId context_id_;
2911cb0ef41Sopenharmony_ci  const WasmFeatures enabled_;
2921cb0ef41Sopenharmony_ci  const WasmModule* const module_;
2931cb0ef41Sopenharmony_ci  ErrorThrower* thrower_;
2941cb0ef41Sopenharmony_ci  Handle<WasmModuleObject> module_object_;
2951cb0ef41Sopenharmony_ci  MaybeHandle<JSReceiver> ffi_;
2961cb0ef41Sopenharmony_ci  MaybeHandle<JSArrayBuffer> memory_buffer_;
2971cb0ef41Sopenharmony_ci  Handle<WasmMemoryObject> memory_object_;
2981cb0ef41Sopenharmony_ci  Handle<JSArrayBuffer> untagged_globals_;
2991cb0ef41Sopenharmony_ci  Handle<FixedArray> tagged_globals_;
3001cb0ef41Sopenharmony_ci  std::vector<Handle<WasmTagObject>> tags_wrappers_;
3011cb0ef41Sopenharmony_ci  Handle<WasmExportedFunction> start_function_;
3021cb0ef41Sopenharmony_ci  std::vector<SanitizedImport> sanitized_imports_;
3031cb0ef41Sopenharmony_ci  // We pass this {Zone} to the temporary {WasmFullDecoder} we allocate during
3041cb0ef41Sopenharmony_ci  // each call to {EvaluateInitExpression}. This has been found to improve
3051cb0ef41Sopenharmony_ci  // performance a bit over allocating a new {Zone} each time.
3061cb0ef41Sopenharmony_ci  Zone init_expr_zone_;
3071cb0ef41Sopenharmony_ci
3081cb0ef41Sopenharmony_ci// Helper routines to print out errors with imports.
3091cb0ef41Sopenharmony_ci#define ERROR_THROWER_WITH_MESSAGE(TYPE)                                      \
3101cb0ef41Sopenharmony_ci  void Report##TYPE(const char* error, uint32_t index,                        \
3111cb0ef41Sopenharmony_ci                    Handle<String> module_name, Handle<String> import_name) { \
3121cb0ef41Sopenharmony_ci    thrower_->TYPE("Import #%d module=\"%s\" function=\"%s\" error: %s",      \
3131cb0ef41Sopenharmony_ci                   index, module_name->ToCString().get(),                     \
3141cb0ef41Sopenharmony_ci                   import_name->ToCString().get(), error);                    \
3151cb0ef41Sopenharmony_ci  }                                                                           \
3161cb0ef41Sopenharmony_ci                                                                              \
3171cb0ef41Sopenharmony_ci  MaybeHandle<Object> Report##TYPE(const char* error, uint32_t index,         \
3181cb0ef41Sopenharmony_ci                                   Handle<String> module_name) {              \
3191cb0ef41Sopenharmony_ci    thrower_->TYPE("Import #%d module=\"%s\" error: %s", index,               \
3201cb0ef41Sopenharmony_ci                   module_name->ToCString().get(), error);                    \
3211cb0ef41Sopenharmony_ci    return MaybeHandle<Object>();                                             \
3221cb0ef41Sopenharmony_ci  }
3231cb0ef41Sopenharmony_ci
3241cb0ef41Sopenharmony_ci  ERROR_THROWER_WITH_MESSAGE(LinkError)
3251cb0ef41Sopenharmony_ci  ERROR_THROWER_WITH_MESSAGE(TypeError)
3261cb0ef41Sopenharmony_ci
3271cb0ef41Sopenharmony_ci#undef ERROR_THROWER_WITH_MESSAGE
3281cb0ef41Sopenharmony_ci
3291cb0ef41Sopenharmony_ci  // Look up an import value in the {ffi_} object.
3301cb0ef41Sopenharmony_ci  MaybeHandle<Object> LookupImport(uint32_t index, Handle<String> module_name,
3311cb0ef41Sopenharmony_ci                                   Handle<String> import_name);
3321cb0ef41Sopenharmony_ci
3331cb0ef41Sopenharmony_ci  // Look up an import value in the {ffi_} object specifically for linking an
3341cb0ef41Sopenharmony_ci  // asm.js module. This only performs non-observable lookups, which allows
3351cb0ef41Sopenharmony_ci  // falling back to JavaScript proper (and hence re-executing all lookups) if
3361cb0ef41Sopenharmony_ci  // module instantiation fails.
3371cb0ef41Sopenharmony_ci  MaybeHandle<Object> LookupImportAsm(uint32_t index,
3381cb0ef41Sopenharmony_ci                                      Handle<String> import_name);
3391cb0ef41Sopenharmony_ci
3401cb0ef41Sopenharmony_ci  // Load data segments into the memory.
3411cb0ef41Sopenharmony_ci  void LoadDataSegments(Handle<WasmInstanceObject> instance);
3421cb0ef41Sopenharmony_ci
3431cb0ef41Sopenharmony_ci  void WriteGlobalValue(const WasmGlobal& global, const WasmValue& value);
3441cb0ef41Sopenharmony_ci
3451cb0ef41Sopenharmony_ci  void SanitizeImports();
3461cb0ef41Sopenharmony_ci
3471cb0ef41Sopenharmony_ci  // Find the imported memory if there is one.
3481cb0ef41Sopenharmony_ci  bool FindImportedMemory();
3491cb0ef41Sopenharmony_ci
3501cb0ef41Sopenharmony_ci  // Allocate the memory.
3511cb0ef41Sopenharmony_ci  bool AllocateMemory();
3521cb0ef41Sopenharmony_ci
3531cb0ef41Sopenharmony_ci  // Processes a single imported function.
3541cb0ef41Sopenharmony_ci  bool ProcessImportedFunction(Handle<WasmInstanceObject> instance,
3551cb0ef41Sopenharmony_ci                               int import_index, int func_index,
3561cb0ef41Sopenharmony_ci                               Handle<String> module_name,
3571cb0ef41Sopenharmony_ci                               Handle<String> import_name,
3581cb0ef41Sopenharmony_ci                               Handle<Object> value);
3591cb0ef41Sopenharmony_ci
3601cb0ef41Sopenharmony_ci  // Initialize imported tables of type funcref.
3611cb0ef41Sopenharmony_ci  bool InitializeImportedIndirectFunctionTable(
3621cb0ef41Sopenharmony_ci      Handle<WasmInstanceObject> instance, int table_index, int import_index,
3631cb0ef41Sopenharmony_ci      Handle<WasmTableObject> table_object);
3641cb0ef41Sopenharmony_ci
3651cb0ef41Sopenharmony_ci  // Process a single imported table.
3661cb0ef41Sopenharmony_ci  bool ProcessImportedTable(Handle<WasmInstanceObject> instance,
3671cb0ef41Sopenharmony_ci                            int import_index, int table_index,
3681cb0ef41Sopenharmony_ci                            Handle<String> module_name,
3691cb0ef41Sopenharmony_ci                            Handle<String> import_name, Handle<Object> value);
3701cb0ef41Sopenharmony_ci
3711cb0ef41Sopenharmony_ci  // Process a single imported memory.
3721cb0ef41Sopenharmony_ci  bool ProcessImportedMemory(Handle<WasmInstanceObject> instance,
3731cb0ef41Sopenharmony_ci                             int import_index, Handle<String> module_name,
3741cb0ef41Sopenharmony_ci                             Handle<String> import_name, Handle<Object> value);
3751cb0ef41Sopenharmony_ci
3761cb0ef41Sopenharmony_ci  // Process a single imported global.
3771cb0ef41Sopenharmony_ci  bool ProcessImportedGlobal(Handle<WasmInstanceObject> instance,
3781cb0ef41Sopenharmony_ci                             int import_index, int global_index,
3791cb0ef41Sopenharmony_ci                             Handle<String> module_name,
3801cb0ef41Sopenharmony_ci                             Handle<String> import_name, Handle<Object> value);
3811cb0ef41Sopenharmony_ci
3821cb0ef41Sopenharmony_ci  // Process a single imported WasmGlobalObject.
3831cb0ef41Sopenharmony_ci  bool ProcessImportedWasmGlobalObject(Handle<WasmInstanceObject> instance,
3841cb0ef41Sopenharmony_ci                                       int import_index,
3851cb0ef41Sopenharmony_ci                                       Handle<String> module_name,
3861cb0ef41Sopenharmony_ci                                       Handle<String> import_name,
3871cb0ef41Sopenharmony_ci                                       const WasmGlobal& global,
3881cb0ef41Sopenharmony_ci                                       Handle<WasmGlobalObject> global_object);
3891cb0ef41Sopenharmony_ci
3901cb0ef41Sopenharmony_ci  // Compile import wrappers in parallel. The result goes into the native
3911cb0ef41Sopenharmony_ci  // module's import_wrapper_cache.
3921cb0ef41Sopenharmony_ci  void CompileImportWrappers(Handle<WasmInstanceObject> instance);
3931cb0ef41Sopenharmony_ci
3941cb0ef41Sopenharmony_ci  // Process the imports, including functions, tables, globals, and memory, in
3951cb0ef41Sopenharmony_ci  // order, loading them from the {ffi_} object. Returns the number of imported
3961cb0ef41Sopenharmony_ci  // functions, or {-1} on error.
3971cb0ef41Sopenharmony_ci  int ProcessImports(Handle<WasmInstanceObject> instance);
3981cb0ef41Sopenharmony_ci
3991cb0ef41Sopenharmony_ci  template <typename T>
4001cb0ef41Sopenharmony_ci  T* GetRawUntaggedGlobalPtr(const WasmGlobal& global);
4011cb0ef41Sopenharmony_ci
4021cb0ef41Sopenharmony_ci  // Process initialization of globals.
4031cb0ef41Sopenharmony_ci  void InitGlobals(Handle<WasmInstanceObject> instance);
4041cb0ef41Sopenharmony_ci
4051cb0ef41Sopenharmony_ci  // Process the exports, creating wrappers for functions, tables, memories,
4061cb0ef41Sopenharmony_ci  // and globals.
4071cb0ef41Sopenharmony_ci  void ProcessExports(Handle<WasmInstanceObject> instance);
4081cb0ef41Sopenharmony_ci
4091cb0ef41Sopenharmony_ci  void InitializeNonDefaultableTables(Handle<WasmInstanceObject> instance);
4101cb0ef41Sopenharmony_ci
4111cb0ef41Sopenharmony_ci  void LoadTableSegments(Handle<WasmInstanceObject> instance);
4121cb0ef41Sopenharmony_ci
4131cb0ef41Sopenharmony_ci  // Creates new tags. Note that some tags might already exist if they were
4141cb0ef41Sopenharmony_ci  // imported, those tags will be re-used.
4151cb0ef41Sopenharmony_ci  void InitializeTags(Handle<WasmInstanceObject> instance);
4161cb0ef41Sopenharmony_ci};
4171cb0ef41Sopenharmony_ci
4181cb0ef41Sopenharmony_ciMaybeHandle<WasmInstanceObject> InstantiateToInstanceObject(
4191cb0ef41Sopenharmony_ci    Isolate* isolate, ErrorThrower* thrower,
4201cb0ef41Sopenharmony_ci    Handle<WasmModuleObject> module_object, MaybeHandle<JSReceiver> imports,
4211cb0ef41Sopenharmony_ci    MaybeHandle<JSArrayBuffer> memory_buffer) {
4221cb0ef41Sopenharmony_ci  v8::metrics::Recorder::ContextId context_id =
4231cb0ef41Sopenharmony_ci      isolate->GetOrRegisterRecorderContextId(isolate->native_context());
4241cb0ef41Sopenharmony_ci  InstanceBuilder builder(isolate, context_id, thrower, module_object, imports,
4251cb0ef41Sopenharmony_ci                          memory_buffer);
4261cb0ef41Sopenharmony_ci  auto instance = builder.Build();
4271cb0ef41Sopenharmony_ci  if (!instance.is_null() && builder.ExecuteStartFunction()) {
4281cb0ef41Sopenharmony_ci    return instance;
4291cb0ef41Sopenharmony_ci  }
4301cb0ef41Sopenharmony_ci  DCHECK(isolate->has_pending_exception() || thrower->error());
4311cb0ef41Sopenharmony_ci  return {};
4321cb0ef41Sopenharmony_ci}
4331cb0ef41Sopenharmony_ci
4341cb0ef41Sopenharmony_ciInstanceBuilder::InstanceBuilder(Isolate* isolate,
4351cb0ef41Sopenharmony_ci                                 v8::metrics::Recorder::ContextId context_id,
4361cb0ef41Sopenharmony_ci                                 ErrorThrower* thrower,
4371cb0ef41Sopenharmony_ci                                 Handle<WasmModuleObject> module_object,
4381cb0ef41Sopenharmony_ci                                 MaybeHandle<JSReceiver> ffi,
4391cb0ef41Sopenharmony_ci                                 MaybeHandle<JSArrayBuffer> memory_buffer)
4401cb0ef41Sopenharmony_ci    : isolate_(isolate),
4411cb0ef41Sopenharmony_ci      context_id_(context_id),
4421cb0ef41Sopenharmony_ci      enabled_(module_object->native_module()->enabled_features()),
4431cb0ef41Sopenharmony_ci      module_(module_object->module()),
4441cb0ef41Sopenharmony_ci      thrower_(thrower),
4451cb0ef41Sopenharmony_ci      module_object_(module_object),
4461cb0ef41Sopenharmony_ci      ffi_(ffi),
4471cb0ef41Sopenharmony_ci      memory_buffer_(memory_buffer),
4481cb0ef41Sopenharmony_ci      init_expr_zone_(isolate_->allocator(), "init. expression zone") {
4491cb0ef41Sopenharmony_ci  sanitized_imports_.reserve(module_->import_table.size());
4501cb0ef41Sopenharmony_ci}
4511cb0ef41Sopenharmony_ci
4521cb0ef41Sopenharmony_ci// Build an instance, in all of its glory.
4531cb0ef41Sopenharmony_ciMaybeHandle<WasmInstanceObject> InstanceBuilder::Build() {
4541cb0ef41Sopenharmony_ci  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm.detailed"),
4551cb0ef41Sopenharmony_ci               "wasm.InstanceBuilder.Build");
4561cb0ef41Sopenharmony_ci  // Check that an imports argument was provided, if the module requires it.
4571cb0ef41Sopenharmony_ci  // No point in continuing otherwise.
4581cb0ef41Sopenharmony_ci  if (!module_->import_table.empty() && ffi_.is_null()) {
4591cb0ef41Sopenharmony_ci    thrower_->TypeError(
4601cb0ef41Sopenharmony_ci        "Imports argument must be present and must be an object");
4611cb0ef41Sopenharmony_ci    return {};
4621cb0ef41Sopenharmony_ci  }
4631cb0ef41Sopenharmony_ci
4641cb0ef41Sopenharmony_ci  SanitizeImports();
4651cb0ef41Sopenharmony_ci  if (thrower_->error()) return {};
4661cb0ef41Sopenharmony_ci
4671cb0ef41Sopenharmony_ci  // From here on, we expect the build pipeline to run without exiting to JS.
4681cb0ef41Sopenharmony_ci  DisallowJavascriptExecution no_js(isolate_);
4691cb0ef41Sopenharmony_ci  // Record build time into correct bucket, then build instance.
4701cb0ef41Sopenharmony_ci  TimedHistogramScope wasm_instantiate_module_time_scope(SELECT_WASM_COUNTER(
4711cb0ef41Sopenharmony_ci      isolate_->counters(), module_->origin, wasm_instantiate, module_time));
4721cb0ef41Sopenharmony_ci  v8::metrics::WasmModuleInstantiated wasm_module_instantiated;
4731cb0ef41Sopenharmony_ci  base::ElapsedTimer timer;
4741cb0ef41Sopenharmony_ci  timer.Start();
4751cb0ef41Sopenharmony_ci  NativeModule* native_module = module_object_->native_module();
4761cb0ef41Sopenharmony_ci
4771cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
4781cb0ef41Sopenharmony_ci  // Set up the memory buffer and memory objects.
4791cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
4801cb0ef41Sopenharmony_ci  uint32_t initial_pages = module_->initial_pages;
4811cb0ef41Sopenharmony_ci  auto initial_pages_counter = SELECT_WASM_COUNTER(
4821cb0ef41Sopenharmony_ci      isolate_->counters(), module_->origin, wasm, min_mem_pages_count);
4831cb0ef41Sopenharmony_ci  initial_pages_counter->AddSample(initial_pages);
4841cb0ef41Sopenharmony_ci  if (module_->has_maximum_pages) {
4851cb0ef41Sopenharmony_ci    DCHECK_EQ(kWasmOrigin, module_->origin);
4861cb0ef41Sopenharmony_ci    auto max_pages_counter =
4871cb0ef41Sopenharmony_ci        isolate_->counters()->wasm_wasm_max_mem_pages_count();
4881cb0ef41Sopenharmony_ci    max_pages_counter->AddSample(module_->maximum_pages);
4891cb0ef41Sopenharmony_ci  }
4901cb0ef41Sopenharmony_ci
4911cb0ef41Sopenharmony_ci  if (is_asmjs_module(module_)) {
4921cb0ef41Sopenharmony_ci    Handle<JSArrayBuffer> buffer;
4931cb0ef41Sopenharmony_ci    if (memory_buffer_.ToHandle(&buffer)) {
4941cb0ef41Sopenharmony_ci      // asm.js instantiation should have changed the state of the buffer.
4951cb0ef41Sopenharmony_ci      CHECK(!buffer->is_detachable());
4961cb0ef41Sopenharmony_ci      CHECK(buffer->is_asmjs_memory());
4971cb0ef41Sopenharmony_ci    } else {
4981cb0ef41Sopenharmony_ci      // Use an empty JSArrayBuffer for degenerate asm.js modules.
4991cb0ef41Sopenharmony_ci      memory_buffer_ = isolate_->factory()->NewJSArrayBufferAndBackingStore(
5001cb0ef41Sopenharmony_ci          0, InitializedFlag::kUninitialized);
5011cb0ef41Sopenharmony_ci      if (!memory_buffer_.ToHandle(&buffer)) {
5021cb0ef41Sopenharmony_ci        thrower_->RangeError("Out of memory: asm.js memory");
5031cb0ef41Sopenharmony_ci        return {};
5041cb0ef41Sopenharmony_ci      }
5051cb0ef41Sopenharmony_ci      buffer->set_is_asmjs_memory(true);
5061cb0ef41Sopenharmony_ci      buffer->set_is_detachable(false);
5071cb0ef41Sopenharmony_ci    }
5081cb0ef41Sopenharmony_ci
5091cb0ef41Sopenharmony_ci    // The maximum number of pages isn't strictly necessary for memory
5101cb0ef41Sopenharmony_ci    // objects used for asm.js, as they are never visible, but we might
5111cb0ef41Sopenharmony_ci    // as well make it accurate.
5121cb0ef41Sopenharmony_ci    auto maximum_pages =
5131cb0ef41Sopenharmony_ci        static_cast<int>(RoundUp(buffer->byte_length(), wasm::kWasmPageSize) /
5141cb0ef41Sopenharmony_ci                         wasm::kWasmPageSize);
5151cb0ef41Sopenharmony_ci    memory_object_ =
5161cb0ef41Sopenharmony_ci        WasmMemoryObject::New(isolate_, memory_buffer_, maximum_pages)
5171cb0ef41Sopenharmony_ci            .ToHandleChecked();
5181cb0ef41Sopenharmony_ci  } else {
5191cb0ef41Sopenharmony_ci    // Actual wasm module must have either imported or created memory.
5201cb0ef41Sopenharmony_ci    CHECK(memory_buffer_.is_null());
5211cb0ef41Sopenharmony_ci    if (!FindImportedMemory()) {
5221cb0ef41Sopenharmony_ci      if (module_->has_memory && !AllocateMemory()) {
5231cb0ef41Sopenharmony_ci        DCHECK(isolate_->has_pending_exception() || thrower_->error());
5241cb0ef41Sopenharmony_ci        return {};
5251cb0ef41Sopenharmony_ci      }
5261cb0ef41Sopenharmony_ci    }
5271cb0ef41Sopenharmony_ci  }
5281cb0ef41Sopenharmony_ci
5291cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
5301cb0ef41Sopenharmony_ci  // Create the WebAssembly.Instance object.
5311cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
5321cb0ef41Sopenharmony_ci  TRACE("New module instantiation for %p\n", native_module);
5331cb0ef41Sopenharmony_ci  Handle<WasmInstanceObject> instance =
5341cb0ef41Sopenharmony_ci      WasmInstanceObject::New(isolate_, module_object_);
5351cb0ef41Sopenharmony_ci
5361cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
5371cb0ef41Sopenharmony_ci  // Attach the memory to the instance.
5381cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
5391cb0ef41Sopenharmony_ci  if (module_->has_memory) {
5401cb0ef41Sopenharmony_ci    DCHECK(!memory_object_.is_null());
5411cb0ef41Sopenharmony_ci    if (!instance->has_memory_object()) {
5421cb0ef41Sopenharmony_ci      instance->set_memory_object(*memory_object_);
5431cb0ef41Sopenharmony_ci    }
5441cb0ef41Sopenharmony_ci    // Add the instance object to the list of instances for this memory.
5451cb0ef41Sopenharmony_ci    WasmMemoryObject::AddInstance(isolate_, memory_object_, instance);
5461cb0ef41Sopenharmony_ci
5471cb0ef41Sopenharmony_ci    // Double-check the {memory} array buffer matches the instance.
5481cb0ef41Sopenharmony_ci    Handle<JSArrayBuffer> memory = memory_buffer_.ToHandleChecked();
5491cb0ef41Sopenharmony_ci    CHECK_EQ(instance->memory_size(), memory->byte_length());
5501cb0ef41Sopenharmony_ci    CHECK_EQ(instance->memory_start(), memory->backing_store());
5511cb0ef41Sopenharmony_ci  }
5521cb0ef41Sopenharmony_ci
5531cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
5541cb0ef41Sopenharmony_ci  // Set up the globals for the new instance.
5551cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
5561cb0ef41Sopenharmony_ci  uint32_t untagged_globals_buffer_size = module_->untagged_globals_buffer_size;
5571cb0ef41Sopenharmony_ci  if (untagged_globals_buffer_size > 0) {
5581cb0ef41Sopenharmony_ci    MaybeHandle<JSArrayBuffer> result =
5591cb0ef41Sopenharmony_ci        isolate_->factory()->NewJSArrayBufferAndBackingStore(
5601cb0ef41Sopenharmony_ci            untagged_globals_buffer_size, InitializedFlag::kZeroInitialized,
5611cb0ef41Sopenharmony_ci            AllocationType::kOld);
5621cb0ef41Sopenharmony_ci
5631cb0ef41Sopenharmony_ci    if (!result.ToHandle(&untagged_globals_)) {
5641cb0ef41Sopenharmony_ci      thrower_->RangeError("Out of memory: wasm globals");
5651cb0ef41Sopenharmony_ci      return {};
5661cb0ef41Sopenharmony_ci    }
5671cb0ef41Sopenharmony_ci
5681cb0ef41Sopenharmony_ci    instance->set_untagged_globals_buffer(*untagged_globals_);
5691cb0ef41Sopenharmony_ci    instance->set_globals_start(
5701cb0ef41Sopenharmony_ci        reinterpret_cast<byte*>(untagged_globals_->backing_store()));
5711cb0ef41Sopenharmony_ci  }
5721cb0ef41Sopenharmony_ci
5731cb0ef41Sopenharmony_ci  uint32_t tagged_globals_buffer_size = module_->tagged_globals_buffer_size;
5741cb0ef41Sopenharmony_ci  if (tagged_globals_buffer_size > 0) {
5751cb0ef41Sopenharmony_ci    tagged_globals_ = isolate_->factory()->NewFixedArray(
5761cb0ef41Sopenharmony_ci        static_cast<int>(tagged_globals_buffer_size));
5771cb0ef41Sopenharmony_ci    instance->set_tagged_globals_buffer(*tagged_globals_);
5781cb0ef41Sopenharmony_ci  }
5791cb0ef41Sopenharmony_ci
5801cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
5811cb0ef41Sopenharmony_ci  // Set up the array of references to imported globals' array buffers.
5821cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
5831cb0ef41Sopenharmony_ci  if (module_->num_imported_mutable_globals > 0) {
5841cb0ef41Sopenharmony_ci    // TODO(binji): This allocates one slot for each mutable global, which is
5851cb0ef41Sopenharmony_ci    // more than required if multiple globals are imported from the same
5861cb0ef41Sopenharmony_ci    // module.
5871cb0ef41Sopenharmony_ci    Handle<FixedArray> buffers_array = isolate_->factory()->NewFixedArray(
5881cb0ef41Sopenharmony_ci        module_->num_imported_mutable_globals, AllocationType::kOld);
5891cb0ef41Sopenharmony_ci    instance->set_imported_mutable_globals_buffers(*buffers_array);
5901cb0ef41Sopenharmony_ci  }
5911cb0ef41Sopenharmony_ci
5921cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
5931cb0ef41Sopenharmony_ci  // Set up the tag table used for exception tag checks.
5941cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
5951cb0ef41Sopenharmony_ci  int tags_count = static_cast<int>(module_->tags.size());
5961cb0ef41Sopenharmony_ci  if (tags_count > 0) {
5971cb0ef41Sopenharmony_ci    Handle<FixedArray> tag_table =
5981cb0ef41Sopenharmony_ci        isolate_->factory()->NewFixedArray(tags_count, AllocationType::kOld);
5991cb0ef41Sopenharmony_ci    instance->set_tags_table(*tag_table);
6001cb0ef41Sopenharmony_ci    tags_wrappers_.resize(tags_count);
6011cb0ef41Sopenharmony_ci  }
6021cb0ef41Sopenharmony_ci
6031cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
6041cb0ef41Sopenharmony_ci  // Set up table storage space.
6051cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
6061cb0ef41Sopenharmony_ci  int table_count = static_cast<int>(module_->tables.size());
6071cb0ef41Sopenharmony_ci  {
6081cb0ef41Sopenharmony_ci    for (int i = 0; i < table_count; i++) {
6091cb0ef41Sopenharmony_ci      const WasmTable& table = module_->tables[i];
6101cb0ef41Sopenharmony_ci      if (table.initial_size > FLAG_wasm_max_table_size) {
6111cb0ef41Sopenharmony_ci        thrower_->RangeError(
6121cb0ef41Sopenharmony_ci            "initial table size (%u elements) is larger than implementation "
6131cb0ef41Sopenharmony_ci            "limit (%u elements)",
6141cb0ef41Sopenharmony_ci            table.initial_size, FLAG_wasm_max_table_size);
6151cb0ef41Sopenharmony_ci        return {};
6161cb0ef41Sopenharmony_ci      }
6171cb0ef41Sopenharmony_ci    }
6181cb0ef41Sopenharmony_ci
6191cb0ef41Sopenharmony_ci    Handle<FixedArray> tables = isolate_->factory()->NewFixedArray(table_count);
6201cb0ef41Sopenharmony_ci    for (int i = module_->num_imported_tables; i < table_count; i++) {
6211cb0ef41Sopenharmony_ci      const WasmTable& table = module_->tables[i];
6221cb0ef41Sopenharmony_ci      // Initialize tables with null for now. We will initialize non-defaultable
6231cb0ef41Sopenharmony_ci      // tables later, in {InitializeNonDefaultableTables}.
6241cb0ef41Sopenharmony_ci      Handle<WasmTableObject> table_obj = WasmTableObject::New(
6251cb0ef41Sopenharmony_ci          isolate_, instance, table.type, table.initial_size,
6261cb0ef41Sopenharmony_ci          table.has_maximum_size, table.maximum_size, nullptr,
6271cb0ef41Sopenharmony_ci          isolate_->factory()->null_value());
6281cb0ef41Sopenharmony_ci      tables->set(i, *table_obj);
6291cb0ef41Sopenharmony_ci    }
6301cb0ef41Sopenharmony_ci    instance->set_tables(*tables);
6311cb0ef41Sopenharmony_ci  }
6321cb0ef41Sopenharmony_ci
6331cb0ef41Sopenharmony_ci  {
6341cb0ef41Sopenharmony_ci    Handle<FixedArray> tables = isolate_->factory()->NewFixedArray(table_count);
6351cb0ef41Sopenharmony_ci    for (int i = 0; i < table_count; ++i) {
6361cb0ef41Sopenharmony_ci      const WasmTable& table = module_->tables[i];
6371cb0ef41Sopenharmony_ci      if (IsSubtypeOf(table.type, kWasmFuncRef, module_)) {
6381cb0ef41Sopenharmony_ci        Handle<WasmIndirectFunctionTable> table_obj =
6391cb0ef41Sopenharmony_ci            WasmIndirectFunctionTable::New(isolate_, table.initial_size);
6401cb0ef41Sopenharmony_ci        tables->set(i, *table_obj);
6411cb0ef41Sopenharmony_ci      }
6421cb0ef41Sopenharmony_ci    }
6431cb0ef41Sopenharmony_ci    instance->set_indirect_function_tables(*tables);
6441cb0ef41Sopenharmony_ci  }
6451cb0ef41Sopenharmony_ci
6461cb0ef41Sopenharmony_ci  instance->SetIndirectFunctionTableShortcuts(isolate_);
6471cb0ef41Sopenharmony_ci
6481cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
6491cb0ef41Sopenharmony_ci  // Process the imports for the module.
6501cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
6511cb0ef41Sopenharmony_ci  if (!module_->import_table.empty()) {
6521cb0ef41Sopenharmony_ci    int num_imported_functions = ProcessImports(instance);
6531cb0ef41Sopenharmony_ci    if (num_imported_functions < 0) return {};
6541cb0ef41Sopenharmony_ci    wasm_module_instantiated.imported_function_count = num_imported_functions;
6551cb0ef41Sopenharmony_ci  }
6561cb0ef41Sopenharmony_ci
6571cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
6581cb0ef41Sopenharmony_ci  // Create maps for managed objects (GC proposal).
6591cb0ef41Sopenharmony_ci  // Must happen before {InitGlobals} because globals can refer to these maps.
6601cb0ef41Sopenharmony_ci  // We do not need to cache the canonical rtts to (rtt.canon any)'s subtype
6611cb0ef41Sopenharmony_ci  // list.
6621cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
6631cb0ef41Sopenharmony_ci  if (enabled_.has_gc()) {
6641cb0ef41Sopenharmony_ci    if (FLAG_wasm_type_canonicalization) {
6651cb0ef41Sopenharmony_ci      uint32_t maximum_canonical_type_index =
6661cb0ef41Sopenharmony_ci          *std::max_element(module_->isorecursive_canonical_type_ids.begin(),
6671cb0ef41Sopenharmony_ci                            module_->isorecursive_canonical_type_ids.end());
6681cb0ef41Sopenharmony_ci      // Make sure all canonical indices have been set.
6691cb0ef41Sopenharmony_ci      DCHECK_NE(maximum_canonical_type_index, kNoSuperType);
6701cb0ef41Sopenharmony_ci      isolate_->heap()->EnsureWasmCanonicalRttsSize(
6711cb0ef41Sopenharmony_ci          maximum_canonical_type_index + 1);
6721cb0ef41Sopenharmony_ci    }
6731cb0ef41Sopenharmony_ci    Handle<FixedArray> maps = isolate_->factory()->NewFixedArray(
6741cb0ef41Sopenharmony_ci        static_cast<int>(module_->types.size()));
6751cb0ef41Sopenharmony_ci    for (uint32_t index = 0; index < module_->types.size(); index++) {
6761cb0ef41Sopenharmony_ci      CreateMapForType(isolate_, module_, index, instance, maps);
6771cb0ef41Sopenharmony_ci    }
6781cb0ef41Sopenharmony_ci    instance->set_managed_object_maps(*maps);
6791cb0ef41Sopenharmony_ci  }
6801cb0ef41Sopenharmony_ci
6811cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
6821cb0ef41Sopenharmony_ci  // Allocate type feedback vectors for functions.
6831cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
6841cb0ef41Sopenharmony_ci  if (FLAG_wasm_speculative_inlining) {
6851cb0ef41Sopenharmony_ci    int num_functions = static_cast<int>(module_->num_declared_functions);
6861cb0ef41Sopenharmony_ci    Handle<FixedArray> vectors =
6871cb0ef41Sopenharmony_ci        isolate_->factory()->NewFixedArray(num_functions, AllocationType::kOld);
6881cb0ef41Sopenharmony_ci    instance->set_feedback_vectors(*vectors);
6891cb0ef41Sopenharmony_ci    for (int i = 0; i < num_functions; i++) {
6901cb0ef41Sopenharmony_ci      int func_index = module_->num_imported_functions + i;
6911cb0ef41Sopenharmony_ci      int slots =
6921cb0ef41Sopenharmony_ci          base::Relaxed_Load(&module_->functions[func_index].feedback_slots);
6931cb0ef41Sopenharmony_ci      if (slots == 0) continue;
6941cb0ef41Sopenharmony_ci      if (FLAG_trace_wasm_speculative_inlining) {
6951cb0ef41Sopenharmony_ci        PrintF("[Function %d (declared %d): allocating %d feedback slots]\n",
6961cb0ef41Sopenharmony_ci               func_index, i, slots);
6971cb0ef41Sopenharmony_ci      }
6981cb0ef41Sopenharmony_ci      Handle<FixedArray> feedback =
6991cb0ef41Sopenharmony_ci          isolate_->factory()->NewFixedArrayWithZeroes(slots);
7001cb0ef41Sopenharmony_ci      vectors->set(i, *feedback);
7011cb0ef41Sopenharmony_ci    }
7021cb0ef41Sopenharmony_ci  }
7031cb0ef41Sopenharmony_ci
7041cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
7051cb0ef41Sopenharmony_ci  // Process the initialization for the module's globals.
7061cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
7071cb0ef41Sopenharmony_ci  InitGlobals(instance);
7081cb0ef41Sopenharmony_ci
7091cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
7101cb0ef41Sopenharmony_ci  // Initialize the indirect function tables and dispatch tables. We do this
7111cb0ef41Sopenharmony_ci  // before initializing non-defaultable tables and loading element segments, so
7121cb0ef41Sopenharmony_ci  // that indirect function tables in this module are included in the updates
7131cb0ef41Sopenharmony_ci  // when we do so.
7141cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
7151cb0ef41Sopenharmony_ci  for (int table_index = 0;
7161cb0ef41Sopenharmony_ci       table_index < static_cast<int>(module_->tables.size()); ++table_index) {
7171cb0ef41Sopenharmony_ci    const WasmTable& table = module_->tables[table_index];
7181cb0ef41Sopenharmony_ci
7191cb0ef41Sopenharmony_ci    if (IsSubtypeOf(table.type, kWasmFuncRef, module_)) {
7201cb0ef41Sopenharmony_ci      WasmInstanceObject::EnsureIndirectFunctionTableWithMinimumSize(
7211cb0ef41Sopenharmony_ci          instance, table_index, table.initial_size);
7221cb0ef41Sopenharmony_ci      if (thrower_->error()) return {};
7231cb0ef41Sopenharmony_ci      auto table_object = handle(
7241cb0ef41Sopenharmony_ci          WasmTableObject::cast(instance->tables().get(table_index)), isolate_);
7251cb0ef41Sopenharmony_ci      WasmTableObject::AddDispatchTable(isolate_, table_object, instance,
7261cb0ef41Sopenharmony_ci                                        table_index);
7271cb0ef41Sopenharmony_ci    }
7281cb0ef41Sopenharmony_ci  }
7291cb0ef41Sopenharmony_ci
7301cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
7311cb0ef41Sopenharmony_ci  // Initialize non-defaultable tables.
7321cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
7331cb0ef41Sopenharmony_ci  if (FLAG_experimental_wasm_typed_funcref) {
7341cb0ef41Sopenharmony_ci    InitializeNonDefaultableTables(instance);
7351cb0ef41Sopenharmony_ci  }
7361cb0ef41Sopenharmony_ci
7371cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
7381cb0ef41Sopenharmony_ci  // Initialize the tags table.
7391cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
7401cb0ef41Sopenharmony_ci  if (tags_count > 0) {
7411cb0ef41Sopenharmony_ci    InitializeTags(instance);
7421cb0ef41Sopenharmony_ci  }
7431cb0ef41Sopenharmony_ci
7441cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
7451cb0ef41Sopenharmony_ci  // Set up the exports object for the new instance.
7461cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
7471cb0ef41Sopenharmony_ci  ProcessExports(instance);
7481cb0ef41Sopenharmony_ci  if (thrower_->error()) return {};
7491cb0ef41Sopenharmony_ci
7501cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
7511cb0ef41Sopenharmony_ci  // Load element segments into tables.
7521cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
7531cb0ef41Sopenharmony_ci  if (table_count > 0) {
7541cb0ef41Sopenharmony_ci    LoadTableSegments(instance);
7551cb0ef41Sopenharmony_ci    if (thrower_->error()) return {};
7561cb0ef41Sopenharmony_ci  }
7571cb0ef41Sopenharmony_ci
7581cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
7591cb0ef41Sopenharmony_ci  // Initialize the memory by loading data segments.
7601cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
7611cb0ef41Sopenharmony_ci  if (module_->data_segments.size() > 0) {
7621cb0ef41Sopenharmony_ci    LoadDataSegments(instance);
7631cb0ef41Sopenharmony_ci    if (thrower_->error()) return {};
7641cb0ef41Sopenharmony_ci  }
7651cb0ef41Sopenharmony_ci
7661cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
7671cb0ef41Sopenharmony_ci  // Create a wrapper for the start function.
7681cb0ef41Sopenharmony_ci  //--------------------------------------------------------------------------
7691cb0ef41Sopenharmony_ci  if (module_->start_function_index >= 0) {
7701cb0ef41Sopenharmony_ci    int start_index = module_->start_function_index;
7711cb0ef41Sopenharmony_ci    auto& function = module_->functions[start_index];
7721cb0ef41Sopenharmony_ci    Handle<CodeT> wrapper_code =
7731cb0ef41Sopenharmony_ci        ToCodeT(JSToWasmWrapperCompilationUnit::CompileJSToWasmWrapper(
7741cb0ef41Sopenharmony_ci                    isolate_, function.sig, module_, function.imported),
7751cb0ef41Sopenharmony_ci                isolate_);
7761cb0ef41Sopenharmony_ci    // TODO(clemensb): Don't generate an exported function for the start
7771cb0ef41Sopenharmony_ci    // function. Use CWasmEntry instead.
7781cb0ef41Sopenharmony_ci    start_function_ = WasmExportedFunction::New(
7791cb0ef41Sopenharmony_ci        isolate_, instance, start_index,
7801cb0ef41Sopenharmony_ci        static_cast<int>(function.sig->parameter_count()), wrapper_code);
7811cb0ef41Sopenharmony_ci
7821cb0ef41Sopenharmony_ci    if (function.imported) {
7831cb0ef41Sopenharmony_ci      ImportedFunctionEntry entry(instance, module_->start_function_index);
7841cb0ef41Sopenharmony_ci      Object callable = entry.maybe_callable();
7851cb0ef41Sopenharmony_ci      if (callable.IsJSFunction()) {
7861cb0ef41Sopenharmony_ci        // If the start function was imported and calls into Blink, we have
7871cb0ef41Sopenharmony_ci        // to pretend that the V8 API was used to enter its correct context.
7881cb0ef41Sopenharmony_ci        // To get that context to {ExecuteStartFunction} below, we install it
7891cb0ef41Sopenharmony_ci        // as the context of the wrapper we just compiled. That's a bit of a
7901cb0ef41Sopenharmony_ci        // hack because it's not really the wrapper's context, only its wrapped
7911cb0ef41Sopenharmony_ci        // target's context, but the end result is the same, and since the
7921cb0ef41Sopenharmony_ci        // start function wrapper doesn't leak, neither does this
7931cb0ef41Sopenharmony_ci        // implementation detail.
7941cb0ef41Sopenharmony_ci        start_function_->set_context(JSFunction::cast(callable).context());
7951cb0ef41Sopenharmony_ci      }
7961cb0ef41Sopenharmony_ci    }
7971cb0ef41Sopenharmony_ci  }
7981cb0ef41Sopenharmony_ci
7991cb0ef41Sopenharmony_ci  DCHECK(!isolate_->has_pending_exception());
8001cb0ef41Sopenharmony_ci  TRACE("Successfully built instance for module %p\n",
8011cb0ef41Sopenharmony_ci        module_object_->native_module());
8021cb0ef41Sopenharmony_ci  wasm_module_instantiated.success = true;
8031cb0ef41Sopenharmony_ci  wasm_module_instantiated.wall_clock_duration_in_us =
8041cb0ef41Sopenharmony_ci      timer.Elapsed().InMicroseconds();
8051cb0ef41Sopenharmony_ci  timer.Stop();
8061cb0ef41Sopenharmony_ci  isolate_->metrics_recorder()->DelayMainThreadEvent(wasm_module_instantiated,
8071cb0ef41Sopenharmony_ci                                                     context_id_);
8081cb0ef41Sopenharmony_ci  return instance;
8091cb0ef41Sopenharmony_ci}
8101cb0ef41Sopenharmony_ci
8111cb0ef41Sopenharmony_cibool InstanceBuilder::ExecuteStartFunction() {
8121cb0ef41Sopenharmony_ci  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm.detailed"),
8131cb0ef41Sopenharmony_ci               "wasm.ExecuteStartFunction");
8141cb0ef41Sopenharmony_ci  if (start_function_.is_null()) return true;  // No start function.
8151cb0ef41Sopenharmony_ci
8161cb0ef41Sopenharmony_ci  HandleScope scope(isolate_);
8171cb0ef41Sopenharmony_ci  // In case the start function calls out to Blink, we have to make sure that
8181cb0ef41Sopenharmony_ci  // the correct "entered context" is available. This is the equivalent of
8191cb0ef41Sopenharmony_ci  // v8::Context::Enter() and must happen in addition to the function call
8201cb0ef41Sopenharmony_ci  // sequence doing the compiled version of "isolate->set_context(...)".
8211cb0ef41Sopenharmony_ci  HandleScopeImplementer* hsi = isolate_->handle_scope_implementer();
8221cb0ef41Sopenharmony_ci  hsi->EnterContext(start_function_->native_context());
8231cb0ef41Sopenharmony_ci
8241cb0ef41Sopenharmony_ci  // Call the JS function.
8251cb0ef41Sopenharmony_ci  Handle<Object> undefined = isolate_->factory()->undefined_value();
8261cb0ef41Sopenharmony_ci  MaybeHandle<Object> retval =
8271cb0ef41Sopenharmony_ci      Execution::Call(isolate_, start_function_, undefined, 0, nullptr);
8281cb0ef41Sopenharmony_ci  hsi->LeaveContext();
8291cb0ef41Sopenharmony_ci
8301cb0ef41Sopenharmony_ci  if (retval.is_null()) {
8311cb0ef41Sopenharmony_ci    DCHECK(isolate_->has_pending_exception());
8321cb0ef41Sopenharmony_ci    return false;
8331cb0ef41Sopenharmony_ci  }
8341cb0ef41Sopenharmony_ci  return true;
8351cb0ef41Sopenharmony_ci}
8361cb0ef41Sopenharmony_ci
8371cb0ef41Sopenharmony_ci// Look up an import value in the {ffi_} object.
8381cb0ef41Sopenharmony_ciMaybeHandle<Object> InstanceBuilder::LookupImport(uint32_t index,
8391cb0ef41Sopenharmony_ci                                                  Handle<String> module_name,
8401cb0ef41Sopenharmony_ci                                                  Handle<String> import_name) {
8411cb0ef41Sopenharmony_ci  // We pre-validated in the js-api layer that the ffi object is present, and
8421cb0ef41Sopenharmony_ci  // a JSObject, if the module has imports.
8431cb0ef41Sopenharmony_ci  DCHECK(!ffi_.is_null());
8441cb0ef41Sopenharmony_ci  // Look up the module first.
8451cb0ef41Sopenharmony_ci  MaybeHandle<Object> result = Object::GetPropertyOrElement(
8461cb0ef41Sopenharmony_ci      isolate_, ffi_.ToHandleChecked(), module_name);
8471cb0ef41Sopenharmony_ci  if (result.is_null()) {
8481cb0ef41Sopenharmony_ci    return ReportTypeError("module not found", index, module_name);
8491cb0ef41Sopenharmony_ci  }
8501cb0ef41Sopenharmony_ci
8511cb0ef41Sopenharmony_ci  Handle<Object> module = result.ToHandleChecked();
8521cb0ef41Sopenharmony_ci
8531cb0ef41Sopenharmony_ci  // Look up the value in the module.
8541cb0ef41Sopenharmony_ci  if (!module->IsJSReceiver()) {
8551cb0ef41Sopenharmony_ci    return ReportTypeError("module is not an object or function", index,
8561cb0ef41Sopenharmony_ci                           module_name);
8571cb0ef41Sopenharmony_ci  }
8581cb0ef41Sopenharmony_ci
8591cb0ef41Sopenharmony_ci  result = Object::GetPropertyOrElement(isolate_, module, import_name);
8601cb0ef41Sopenharmony_ci  if (result.is_null()) {
8611cb0ef41Sopenharmony_ci    ReportLinkError("import not found", index, module_name, import_name);
8621cb0ef41Sopenharmony_ci    return MaybeHandle<JSFunction>();
8631cb0ef41Sopenharmony_ci  }
8641cb0ef41Sopenharmony_ci
8651cb0ef41Sopenharmony_ci  return result;
8661cb0ef41Sopenharmony_ci}
8671cb0ef41Sopenharmony_ci
8681cb0ef41Sopenharmony_cinamespace {
8691cb0ef41Sopenharmony_cibool HasDefaultToNumberBehaviour(Isolate* isolate,
8701cb0ef41Sopenharmony_ci                                 Handle<JSFunction> function) {
8711cb0ef41Sopenharmony_ci  // Disallow providing a [Symbol.toPrimitive] member.
8721cb0ef41Sopenharmony_ci  LookupIterator to_primitive_it{isolate, function,
8731cb0ef41Sopenharmony_ci                                 isolate->factory()->to_primitive_symbol()};
8741cb0ef41Sopenharmony_ci  if (to_primitive_it.state() != LookupIterator::NOT_FOUND) return false;
8751cb0ef41Sopenharmony_ci
8761cb0ef41Sopenharmony_ci  // The {valueOf} member must be the default "ObjectPrototypeValueOf".
8771cb0ef41Sopenharmony_ci  LookupIterator value_of_it{isolate, function,
8781cb0ef41Sopenharmony_ci                             isolate->factory()->valueOf_string()};
8791cb0ef41Sopenharmony_ci  if (value_of_it.state() != LookupIterator::DATA) return false;
8801cb0ef41Sopenharmony_ci  Handle<Object> value_of = value_of_it.GetDataValue();
8811cb0ef41Sopenharmony_ci  if (!value_of->IsJSFunction()) return false;
8821cb0ef41Sopenharmony_ci  Builtin value_of_builtin_id =
8831cb0ef41Sopenharmony_ci      Handle<JSFunction>::cast(value_of)->code().builtin_id();
8841cb0ef41Sopenharmony_ci  if (value_of_builtin_id != Builtin::kObjectPrototypeValueOf) return false;
8851cb0ef41Sopenharmony_ci
8861cb0ef41Sopenharmony_ci  // The {toString} member must be the default "FunctionPrototypeToString".
8871cb0ef41Sopenharmony_ci  LookupIterator to_string_it{isolate, function,
8881cb0ef41Sopenharmony_ci                              isolate->factory()->toString_string()};
8891cb0ef41Sopenharmony_ci  if (to_string_it.state() != LookupIterator::DATA) return false;
8901cb0ef41Sopenharmony_ci  Handle<Object> to_string = to_string_it.GetDataValue();
8911cb0ef41Sopenharmony_ci  if (!to_string->IsJSFunction()) return false;
8921cb0ef41Sopenharmony_ci  Builtin to_string_builtin_id =
8931cb0ef41Sopenharmony_ci      Handle<JSFunction>::cast(to_string)->code().builtin_id();
8941cb0ef41Sopenharmony_ci  if (to_string_builtin_id != Builtin::kFunctionPrototypeToString) return false;
8951cb0ef41Sopenharmony_ci
8961cb0ef41Sopenharmony_ci  // Just a default function, which will convert to "Nan". Accept this.
8971cb0ef41Sopenharmony_ci  return true;
8981cb0ef41Sopenharmony_ci}
8991cb0ef41Sopenharmony_ci
9001cb0ef41Sopenharmony_ciV8_INLINE WasmValue EvaluateInitExpression(Zone* zone, ConstantExpression expr,
9011cb0ef41Sopenharmony_ci                                           ValueType expected, Isolate* isolate,
9021cb0ef41Sopenharmony_ci                                           Handle<WasmInstanceObject> instance,
9031cb0ef41Sopenharmony_ci                                           ErrorThrower* thrower) {
9041cb0ef41Sopenharmony_ci  switch (expr.kind()) {
9051cb0ef41Sopenharmony_ci    case ConstantExpression::kEmpty:
9061cb0ef41Sopenharmony_ci      UNREACHABLE();
9071cb0ef41Sopenharmony_ci    case ConstantExpression::kI32Const:
9081cb0ef41Sopenharmony_ci      return WasmValue(expr.i32_value());
9091cb0ef41Sopenharmony_ci    case ConstantExpression::kRefNull:
9101cb0ef41Sopenharmony_ci      return WasmValue(isolate->factory()->null_value(),
9111cb0ef41Sopenharmony_ci                       ValueType::Ref(expr.repr(), kNullable));
9121cb0ef41Sopenharmony_ci    case ConstantExpression::kRefFunc: {
9131cb0ef41Sopenharmony_ci      uint32_t index = expr.index();
9141cb0ef41Sopenharmony_ci      Handle<Object> value =
9151cb0ef41Sopenharmony_ci          WasmInstanceObject::GetOrCreateWasmInternalFunction(isolate, instance,
9161cb0ef41Sopenharmony_ci                                                              index);
9171cb0ef41Sopenharmony_ci      return WasmValue(value, expected);
9181cb0ef41Sopenharmony_ci    }
9191cb0ef41Sopenharmony_ci    case ConstantExpression::kWireBytesRef: {
9201cb0ef41Sopenharmony_ci      WireBytesRef ref = expr.wire_bytes_ref();
9211cb0ef41Sopenharmony_ci
9221cb0ef41Sopenharmony_ci      base::Vector<const byte> module_bytes =
9231cb0ef41Sopenharmony_ci          instance->module_object().native_module()->wire_bytes();
9241cb0ef41Sopenharmony_ci
9251cb0ef41Sopenharmony_ci      const byte* start = module_bytes.begin() + ref.offset();
9261cb0ef41Sopenharmony_ci      const byte* end = module_bytes.begin() + ref.end_offset();
9271cb0ef41Sopenharmony_ci
9281cb0ef41Sopenharmony_ci      auto sig = FixedSizeSignature<ValueType>::Returns(expected);
9291cb0ef41Sopenharmony_ci      FunctionBody body(&sig, ref.offset(), start, end);
9301cb0ef41Sopenharmony_ci      WasmFeatures detected;
9311cb0ef41Sopenharmony_ci      // We use kFullValidation so we do not have to create another template
9321cb0ef41Sopenharmony_ci      // instance of WasmFullDecoder, which would cost us >50Kb binary code
9331cb0ef41Sopenharmony_ci      // size.
9341cb0ef41Sopenharmony_ci      WasmFullDecoder<Decoder::kFullValidation, InitExprInterface,
9351cb0ef41Sopenharmony_ci                      kInitExpression>
9361cb0ef41Sopenharmony_ci          decoder(zone, instance->module(), WasmFeatures::All(), &detected,
9371cb0ef41Sopenharmony_ci                  body, instance->module(), isolate, instance);
9381cb0ef41Sopenharmony_ci
9391cb0ef41Sopenharmony_ci      decoder.DecodeFunctionBody();
9401cb0ef41Sopenharmony_ci
9411cb0ef41Sopenharmony_ci      if (decoder.interface().runtime_error()) {
9421cb0ef41Sopenharmony_ci        thrower->RuntimeError("%s", decoder.interface().runtime_error_msg());
9431cb0ef41Sopenharmony_ci        return {};
9441cb0ef41Sopenharmony_ci      }
9451cb0ef41Sopenharmony_ci
9461cb0ef41Sopenharmony_ci      return decoder.interface().result();
9471cb0ef41Sopenharmony_ci    }
9481cb0ef41Sopenharmony_ci  }
9491cb0ef41Sopenharmony_ci}
9501cb0ef41Sopenharmony_ci}  // namespace
9511cb0ef41Sopenharmony_ci
9521cb0ef41Sopenharmony_ci// Look up an import value in the {ffi_} object specifically for linking an
9531cb0ef41Sopenharmony_ci// asm.js module. This only performs non-observable lookups, which allows
9541cb0ef41Sopenharmony_ci// falling back to JavaScript proper (and hence re-executing all lookups) if
9551cb0ef41Sopenharmony_ci// module instantiation fails.
9561cb0ef41Sopenharmony_ciMaybeHandle<Object> InstanceBuilder::LookupImportAsm(
9571cb0ef41Sopenharmony_ci    uint32_t index, Handle<String> import_name) {
9581cb0ef41Sopenharmony_ci  // Check that a foreign function interface object was provided.
9591cb0ef41Sopenharmony_ci  if (ffi_.is_null()) {
9601cb0ef41Sopenharmony_ci    return ReportLinkError("missing imports object", index, import_name);
9611cb0ef41Sopenharmony_ci  }
9621cb0ef41Sopenharmony_ci
9631cb0ef41Sopenharmony_ci  // Perform lookup of the given {import_name} without causing any observable
9641cb0ef41Sopenharmony_ci  // side-effect. We only accept accesses that resolve to data properties,
9651cb0ef41Sopenharmony_ci  // which is indicated by the asm.js spec in section 7 ("Linking") as well.
9661cb0ef41Sopenharmony_ci  PropertyKey key(isolate_, Handle<Name>::cast(import_name));
9671cb0ef41Sopenharmony_ci  LookupIterator it(isolate_, ffi_.ToHandleChecked(), key);
9681cb0ef41Sopenharmony_ci  switch (it.state()) {
9691cb0ef41Sopenharmony_ci    case LookupIterator::ACCESS_CHECK:
9701cb0ef41Sopenharmony_ci    case LookupIterator::INTEGER_INDEXED_EXOTIC:
9711cb0ef41Sopenharmony_ci    case LookupIterator::INTERCEPTOR:
9721cb0ef41Sopenharmony_ci    case LookupIterator::JSPROXY:
9731cb0ef41Sopenharmony_ci    case LookupIterator::ACCESSOR:
9741cb0ef41Sopenharmony_ci    case LookupIterator::TRANSITION:
9751cb0ef41Sopenharmony_ci      return ReportLinkError("not a data property", index, import_name);
9761cb0ef41Sopenharmony_ci    case LookupIterator::NOT_FOUND:
9771cb0ef41Sopenharmony_ci      // Accepting missing properties as undefined does not cause any
9781cb0ef41Sopenharmony_ci      // observable difference from JavaScript semantics, we are lenient.
9791cb0ef41Sopenharmony_ci      return isolate_->factory()->undefined_value();
9801cb0ef41Sopenharmony_ci    case LookupIterator::DATA: {
9811cb0ef41Sopenharmony_ci      Handle<Object> value = it.GetDataValue();
9821cb0ef41Sopenharmony_ci      // For legacy reasons, we accept functions for imported globals (see
9831cb0ef41Sopenharmony_ci      // {ProcessImportedGlobal}), but only if we can easily determine that
9841cb0ef41Sopenharmony_ci      // their Number-conversion is side effect free and returns NaN (which is
9851cb0ef41Sopenharmony_ci      // the case as long as "valueOf" (or others) are not overwritten).
9861cb0ef41Sopenharmony_ci      if (value->IsJSFunction() &&
9871cb0ef41Sopenharmony_ci          module_->import_table[index].kind == kExternalGlobal &&
9881cb0ef41Sopenharmony_ci          !HasDefaultToNumberBehaviour(isolate_,
9891cb0ef41Sopenharmony_ci                                       Handle<JSFunction>::cast(value))) {
9901cb0ef41Sopenharmony_ci        return ReportLinkError("function has special ToNumber behaviour", index,
9911cb0ef41Sopenharmony_ci                               import_name);
9921cb0ef41Sopenharmony_ci      }
9931cb0ef41Sopenharmony_ci      return value;
9941cb0ef41Sopenharmony_ci    }
9951cb0ef41Sopenharmony_ci  }
9961cb0ef41Sopenharmony_ci}
9971cb0ef41Sopenharmony_ci
9981cb0ef41Sopenharmony_ci// Load data segments into the memory.
9991cb0ef41Sopenharmony_civoid InstanceBuilder::LoadDataSegments(Handle<WasmInstanceObject> instance) {
10001cb0ef41Sopenharmony_ci  base::Vector<const uint8_t> wire_bytes =
10011cb0ef41Sopenharmony_ci      module_object_->native_module()->wire_bytes();
10021cb0ef41Sopenharmony_ci  for (const WasmDataSegment& segment : module_->data_segments) {
10031cb0ef41Sopenharmony_ci    uint32_t size = segment.source.length();
10041cb0ef41Sopenharmony_ci
10051cb0ef41Sopenharmony_ci    // Passive segments are not copied during instantiation.
10061cb0ef41Sopenharmony_ci    if (!segment.active) continue;
10071cb0ef41Sopenharmony_ci
10081cb0ef41Sopenharmony_ci    size_t dest_offset;
10091cb0ef41Sopenharmony_ci    if (module_->is_memory64) {
10101cb0ef41Sopenharmony_ci      uint64_t dest_offset_64 =
10111cb0ef41Sopenharmony_ci          EvaluateInitExpression(&init_expr_zone_, segment.dest_addr, kWasmI64,
10121cb0ef41Sopenharmony_ci                                 isolate_, instance, thrower_)
10131cb0ef41Sopenharmony_ci              .to_u64();
10141cb0ef41Sopenharmony_ci      if (thrower_->error()) return;
10151cb0ef41Sopenharmony_ci      // Clamp to {std::numeric_limits<size_t>::max()}, which is always an
10161cb0ef41Sopenharmony_ci      // invalid offset.
10171cb0ef41Sopenharmony_ci      DCHECK_GT(std::numeric_limits<size_t>::max(), instance->memory_size());
10181cb0ef41Sopenharmony_ci      dest_offset = static_cast<size_t>(std::min(
10191cb0ef41Sopenharmony_ci          dest_offset_64, uint64_t{std::numeric_limits<size_t>::max()}));
10201cb0ef41Sopenharmony_ci    } else {
10211cb0ef41Sopenharmony_ci      dest_offset =
10221cb0ef41Sopenharmony_ci          EvaluateInitExpression(&init_expr_zone_, segment.dest_addr, kWasmI32,
10231cb0ef41Sopenharmony_ci                                 isolate_, instance, thrower_)
10241cb0ef41Sopenharmony_ci              .to_u32();
10251cb0ef41Sopenharmony_ci      if (thrower_->error()) return;
10261cb0ef41Sopenharmony_ci    }
10271cb0ef41Sopenharmony_ci
10281cb0ef41Sopenharmony_ci    if (!base::IsInBounds<size_t>(dest_offset, size, instance->memory_size())) {
10291cb0ef41Sopenharmony_ci      thrower_->RuntimeError("data segment is out of bounds");
10301cb0ef41Sopenharmony_ci      return;
10311cb0ef41Sopenharmony_ci    }
10321cb0ef41Sopenharmony_ci
10331cb0ef41Sopenharmony_ci    std::memcpy(instance->memory_start() + dest_offset,
10341cb0ef41Sopenharmony_ci                wire_bytes.begin() + segment.source.offset(), size);
10351cb0ef41Sopenharmony_ci  }
10361cb0ef41Sopenharmony_ci}
10371cb0ef41Sopenharmony_ci
10381cb0ef41Sopenharmony_civoid InstanceBuilder::WriteGlobalValue(const WasmGlobal& global,
10391cb0ef41Sopenharmony_ci                                       const WasmValue& value) {
10401cb0ef41Sopenharmony_ci  TRACE("init [globals_start=%p + %u] = %s, type = %s\n",
10411cb0ef41Sopenharmony_ci        global.type.is_reference()
10421cb0ef41Sopenharmony_ci            ? reinterpret_cast<byte*>(tagged_globals_->address())
10431cb0ef41Sopenharmony_ci            : raw_buffer_ptr(untagged_globals_, 0),
10441cb0ef41Sopenharmony_ci        global.offset, value.to_string().c_str(), global.type.name().c_str());
10451cb0ef41Sopenharmony_ci  DCHECK(IsSubtypeOf(value.type(), global.type, module_));
10461cb0ef41Sopenharmony_ci  if (global.type.is_numeric()) {
10471cb0ef41Sopenharmony_ci    value.CopyTo(GetRawUntaggedGlobalPtr<byte>(global));
10481cb0ef41Sopenharmony_ci  } else {
10491cb0ef41Sopenharmony_ci    tagged_globals_->set(global.offset, *value.to_ref());
10501cb0ef41Sopenharmony_ci  }
10511cb0ef41Sopenharmony_ci}
10521cb0ef41Sopenharmony_ci
10531cb0ef41Sopenharmony_civoid InstanceBuilder::SanitizeImports() {
10541cb0ef41Sopenharmony_ci  base::Vector<const uint8_t> wire_bytes =
10551cb0ef41Sopenharmony_ci      module_object_->native_module()->wire_bytes();
10561cb0ef41Sopenharmony_ci  for (size_t index = 0; index < module_->import_table.size(); ++index) {
10571cb0ef41Sopenharmony_ci    const WasmImport& import = module_->import_table[index];
10581cb0ef41Sopenharmony_ci
10591cb0ef41Sopenharmony_ci    Handle<String> module_name =
10601cb0ef41Sopenharmony_ci        WasmModuleObject::ExtractUtf8StringFromModuleBytes(
10611cb0ef41Sopenharmony_ci            isolate_, wire_bytes, import.module_name, kInternalize);
10621cb0ef41Sopenharmony_ci
10631cb0ef41Sopenharmony_ci    Handle<String> import_name =
10641cb0ef41Sopenharmony_ci        WasmModuleObject::ExtractUtf8StringFromModuleBytes(
10651cb0ef41Sopenharmony_ci            isolate_, wire_bytes, import.field_name, kInternalize);
10661cb0ef41Sopenharmony_ci
10671cb0ef41Sopenharmony_ci    int int_index = static_cast<int>(index);
10681cb0ef41Sopenharmony_ci    MaybeHandle<Object> result =
10691cb0ef41Sopenharmony_ci        is_asmjs_module(module_)
10701cb0ef41Sopenharmony_ci            ? LookupImportAsm(int_index, import_name)
10711cb0ef41Sopenharmony_ci            : LookupImport(int_index, module_name, import_name);
10721cb0ef41Sopenharmony_ci    if (thrower_->error()) {
10731cb0ef41Sopenharmony_ci      thrower_->LinkError("Could not find value for import %zu", index);
10741cb0ef41Sopenharmony_ci      return;
10751cb0ef41Sopenharmony_ci    }
10761cb0ef41Sopenharmony_ci    Handle<Object> value = result.ToHandleChecked();
10771cb0ef41Sopenharmony_ci    sanitized_imports_.push_back({module_name, import_name, value});
10781cb0ef41Sopenharmony_ci  }
10791cb0ef41Sopenharmony_ci}
10801cb0ef41Sopenharmony_ci
10811cb0ef41Sopenharmony_cibool InstanceBuilder::FindImportedMemory() {
10821cb0ef41Sopenharmony_ci  DCHECK_EQ(module_->import_table.size(), sanitized_imports_.size());
10831cb0ef41Sopenharmony_ci  for (size_t index = 0; index < module_->import_table.size(); index++) {
10841cb0ef41Sopenharmony_ci    WasmImport import = module_->import_table[index];
10851cb0ef41Sopenharmony_ci
10861cb0ef41Sopenharmony_ci    if (import.kind == kExternalMemory) {
10871cb0ef41Sopenharmony_ci      auto& value = sanitized_imports_[index].value;
10881cb0ef41Sopenharmony_ci      if (!value->IsWasmMemoryObject()) return false;
10891cb0ef41Sopenharmony_ci      memory_object_ = Handle<WasmMemoryObject>::cast(value);
10901cb0ef41Sopenharmony_ci      memory_buffer_ =
10911cb0ef41Sopenharmony_ci          Handle<JSArrayBuffer>(memory_object_->array_buffer(), isolate_);
10921cb0ef41Sopenharmony_ci      return true;
10931cb0ef41Sopenharmony_ci    }
10941cb0ef41Sopenharmony_ci  }
10951cb0ef41Sopenharmony_ci  return false;
10961cb0ef41Sopenharmony_ci}
10971cb0ef41Sopenharmony_ci
10981cb0ef41Sopenharmony_cibool InstanceBuilder::ProcessImportedFunction(
10991cb0ef41Sopenharmony_ci    Handle<WasmInstanceObject> instance, int import_index, int func_index,
11001cb0ef41Sopenharmony_ci    Handle<String> module_name, Handle<String> import_name,
11011cb0ef41Sopenharmony_ci    Handle<Object> value) {
11021cb0ef41Sopenharmony_ci  // Function imports must be callable.
11031cb0ef41Sopenharmony_ci  if (!value->IsCallable()) {
11041cb0ef41Sopenharmony_ci    ReportLinkError("function import requires a callable", import_index,
11051cb0ef41Sopenharmony_ci                    module_name, import_name);
11061cb0ef41Sopenharmony_ci    return false;
11071cb0ef41Sopenharmony_ci  }
11081cb0ef41Sopenharmony_ci  // Store any {WasmExternalFunction} callable in the instance before the call
11091cb0ef41Sopenharmony_ci  // is resolved to preserve its identity. This handles exported functions as
11101cb0ef41Sopenharmony_ci  // well as functions constructed via other means (e.g. WebAssembly.Function).
11111cb0ef41Sopenharmony_ci  if (WasmExternalFunction::IsWasmExternalFunction(*value)) {
11121cb0ef41Sopenharmony_ci    WasmInstanceObject::SetWasmInternalFunction(
11131cb0ef41Sopenharmony_ci        isolate_, instance, func_index,
11141cb0ef41Sopenharmony_ci        WasmInternalFunction::FromExternal(
11151cb0ef41Sopenharmony_ci            Handle<WasmExternalFunction>::cast(value), isolate_)
11161cb0ef41Sopenharmony_ci            .ToHandleChecked());
11171cb0ef41Sopenharmony_ci  }
11181cb0ef41Sopenharmony_ci  auto js_receiver = Handle<JSReceiver>::cast(value);
11191cb0ef41Sopenharmony_ci  const FunctionSig* expected_sig = module_->functions[func_index].sig;
11201cb0ef41Sopenharmony_ci  auto resolved = compiler::ResolveWasmImportCall(js_receiver, expected_sig,
11211cb0ef41Sopenharmony_ci                                                  module_, enabled_);
11221cb0ef41Sopenharmony_ci  compiler::WasmImportCallKind kind = resolved.kind;
11231cb0ef41Sopenharmony_ci  js_receiver = resolved.callable;
11241cb0ef41Sopenharmony_ci  switch (kind) {
11251cb0ef41Sopenharmony_ci    case compiler::WasmImportCallKind::kLinkError:
11261cb0ef41Sopenharmony_ci      ReportLinkError("imported function does not match the expected type",
11271cb0ef41Sopenharmony_ci                      import_index, module_name, import_name);
11281cb0ef41Sopenharmony_ci      return false;
11291cb0ef41Sopenharmony_ci    case compiler::WasmImportCallKind::kWasmToWasm: {
11301cb0ef41Sopenharmony_ci      // The imported function is a Wasm function from another instance.
11311cb0ef41Sopenharmony_ci      auto imported_function = Handle<WasmExportedFunction>::cast(js_receiver);
11321cb0ef41Sopenharmony_ci      Handle<WasmInstanceObject> imported_instance(
11331cb0ef41Sopenharmony_ci          imported_function->instance(), isolate_);
11341cb0ef41Sopenharmony_ci      // The import reference is the instance object itself.
11351cb0ef41Sopenharmony_ci      Address imported_target = imported_function->GetWasmCallTarget();
11361cb0ef41Sopenharmony_ci      ImportedFunctionEntry entry(instance, func_index);
11371cb0ef41Sopenharmony_ci      entry.SetWasmToWasm(*imported_instance, imported_target);
11381cb0ef41Sopenharmony_ci      break;
11391cb0ef41Sopenharmony_ci    }
11401cb0ef41Sopenharmony_ci    case compiler::WasmImportCallKind::kWasmToCapi: {
11411cb0ef41Sopenharmony_ci      NativeModule* native_module = instance->module_object().native_module();
11421cb0ef41Sopenharmony_ci      int expected_arity = static_cast<int>(expected_sig->parameter_count());
11431cb0ef41Sopenharmony_ci      WasmImportWrapperCache* cache = native_module->import_wrapper_cache();
11441cb0ef41Sopenharmony_ci      // TODO(jkummerow): Consider precompiling CapiCallWrappers in parallel,
11451cb0ef41Sopenharmony_ci      // just like other import wrappers.
11461cb0ef41Sopenharmony_ci      WasmCode* wasm_code =
11471cb0ef41Sopenharmony_ci          cache->MaybeGet(kind, expected_sig, expected_arity, kNoSuspend);
11481cb0ef41Sopenharmony_ci      if (wasm_code == nullptr) {
11491cb0ef41Sopenharmony_ci        WasmCodeRefScope code_ref_scope;
11501cb0ef41Sopenharmony_ci        WasmImportWrapperCache::ModificationScope cache_scope(cache);
11511cb0ef41Sopenharmony_ci        wasm_code =
11521cb0ef41Sopenharmony_ci            compiler::CompileWasmCapiCallWrapper(native_module, expected_sig);
11531cb0ef41Sopenharmony_ci        WasmImportWrapperCache::CacheKey key(kind, expected_sig, expected_arity,
11541cb0ef41Sopenharmony_ci                                             kNoSuspend);
11551cb0ef41Sopenharmony_ci        cache_scope[key] = wasm_code;
11561cb0ef41Sopenharmony_ci        wasm_code->IncRef();
11571cb0ef41Sopenharmony_ci        isolate_->counters()->wasm_generated_code_size()->Increment(
11581cb0ef41Sopenharmony_ci            wasm_code->instructions().length());
11591cb0ef41Sopenharmony_ci        isolate_->counters()->wasm_reloc_size()->Increment(
11601cb0ef41Sopenharmony_ci            wasm_code->reloc_info().length());
11611cb0ef41Sopenharmony_ci      }
11621cb0ef41Sopenharmony_ci
11631cb0ef41Sopenharmony_ci      ImportedFunctionEntry entry(instance, func_index);
11641cb0ef41Sopenharmony_ci      // We re-use the SetWasmToJs infrastructure because it passes the
11651cb0ef41Sopenharmony_ci      // callable to the wrapper, which we need to get the function data.
11661cb0ef41Sopenharmony_ci      entry.SetWasmToJs(isolate_, js_receiver, wasm_code,
11671cb0ef41Sopenharmony_ci                        isolate_->factory()->undefined_value());
11681cb0ef41Sopenharmony_ci      break;
11691cb0ef41Sopenharmony_ci    }
11701cb0ef41Sopenharmony_ci    case compiler::WasmImportCallKind::kWasmToJSFastApi: {
11711cb0ef41Sopenharmony_ci      NativeModule* native_module = instance->module_object().native_module();
11721cb0ef41Sopenharmony_ci      DCHECK(js_receiver->IsJSFunction());
11731cb0ef41Sopenharmony_ci      Handle<JSFunction> function = Handle<JSFunction>::cast(js_receiver);
11741cb0ef41Sopenharmony_ci
11751cb0ef41Sopenharmony_ci      WasmCodeRefScope code_ref_scope;
11761cb0ef41Sopenharmony_ci      WasmCode* wasm_code = compiler::CompileWasmJSFastCallWrapper(
11771cb0ef41Sopenharmony_ci          native_module, expected_sig, function);
11781cb0ef41Sopenharmony_ci      ImportedFunctionEntry entry(instance, func_index);
11791cb0ef41Sopenharmony_ci      entry.SetWasmToJs(isolate_, js_receiver, wasm_code,
11801cb0ef41Sopenharmony_ci                        isolate_->factory()->undefined_value());
11811cb0ef41Sopenharmony_ci      break;
11821cb0ef41Sopenharmony_ci    }
11831cb0ef41Sopenharmony_ci    default: {
11841cb0ef41Sopenharmony_ci      // The imported function is a callable.
11851cb0ef41Sopenharmony_ci
11861cb0ef41Sopenharmony_ci      int expected_arity = static_cast<int>(expected_sig->parameter_count());
11871cb0ef41Sopenharmony_ci      if (kind == compiler::WasmImportCallKind::kJSFunctionArityMismatch) {
11881cb0ef41Sopenharmony_ci        Handle<JSFunction> function = Handle<JSFunction>::cast(js_receiver);
11891cb0ef41Sopenharmony_ci        SharedFunctionInfo shared = function->shared();
11901cb0ef41Sopenharmony_ci        expected_arity =
11911cb0ef41Sopenharmony_ci            shared.internal_formal_parameter_count_without_receiver();
11921cb0ef41Sopenharmony_ci      }
11931cb0ef41Sopenharmony_ci
11941cb0ef41Sopenharmony_ci      NativeModule* native_module = instance->module_object().native_module();
11951cb0ef41Sopenharmony_ci      Suspend suspend =
11961cb0ef41Sopenharmony_ci          resolved.suspender.is_null() || resolved.suspender->IsUndefined()
11971cb0ef41Sopenharmony_ci              ? kNoSuspend
11981cb0ef41Sopenharmony_ci              : kSuspend;
11991cb0ef41Sopenharmony_ci      WasmCode* wasm_code = native_module->import_wrapper_cache()->Get(
12001cb0ef41Sopenharmony_ci          kind, expected_sig, expected_arity, suspend);
12011cb0ef41Sopenharmony_ci      DCHECK_NOT_NULL(wasm_code);
12021cb0ef41Sopenharmony_ci      ImportedFunctionEntry entry(instance, func_index);
12031cb0ef41Sopenharmony_ci      if (wasm_code->kind() == WasmCode::kWasmToJsWrapper) {
12041cb0ef41Sopenharmony_ci        // Wasm to JS wrappers are treated specially in the import table.
12051cb0ef41Sopenharmony_ci        entry.SetWasmToJs(isolate_, js_receiver, wasm_code, resolved.suspender);
12061cb0ef41Sopenharmony_ci      } else {
12071cb0ef41Sopenharmony_ci        // Wasm math intrinsics are compiled as regular Wasm functions.
12081cb0ef41Sopenharmony_ci        DCHECK(kind >= compiler::WasmImportCallKind::kFirstMathIntrinsic &&
12091cb0ef41Sopenharmony_ci               kind <= compiler::WasmImportCallKind::kLastMathIntrinsic);
12101cb0ef41Sopenharmony_ci        entry.SetWasmToWasm(*instance, wasm_code->instruction_start());
12111cb0ef41Sopenharmony_ci      }
12121cb0ef41Sopenharmony_ci      break;
12131cb0ef41Sopenharmony_ci    }
12141cb0ef41Sopenharmony_ci  }
12151cb0ef41Sopenharmony_ci  return true;
12161cb0ef41Sopenharmony_ci}
12171cb0ef41Sopenharmony_ci
12181cb0ef41Sopenharmony_cibool InstanceBuilder::InitializeImportedIndirectFunctionTable(
12191cb0ef41Sopenharmony_ci    Handle<WasmInstanceObject> instance, int table_index, int import_index,
12201cb0ef41Sopenharmony_ci    Handle<WasmTableObject> table_object) {
12211cb0ef41Sopenharmony_ci  int imported_table_size = table_object->current_length();
12221cb0ef41Sopenharmony_ci  // Allocate a new dispatch table.
12231cb0ef41Sopenharmony_ci  WasmInstanceObject::EnsureIndirectFunctionTableWithMinimumSize(
12241cb0ef41Sopenharmony_ci      instance, table_index, imported_table_size);
12251cb0ef41Sopenharmony_ci  // Initialize the dispatch table with the (foreign) JS functions
12261cb0ef41Sopenharmony_ci  // that are already in the table.
12271cb0ef41Sopenharmony_ci  for (int i = 0; i < imported_table_size; ++i) {
12281cb0ef41Sopenharmony_ci    bool is_valid;
12291cb0ef41Sopenharmony_ci    bool is_null;
12301cb0ef41Sopenharmony_ci    MaybeHandle<WasmInstanceObject> maybe_target_instance;
12311cb0ef41Sopenharmony_ci    int function_index;
12321cb0ef41Sopenharmony_ci    MaybeHandle<WasmJSFunction> maybe_js_function;
12331cb0ef41Sopenharmony_ci    WasmTableObject::GetFunctionTableEntry(
12341cb0ef41Sopenharmony_ci        isolate_, module_, table_object, i, &is_valid, &is_null,
12351cb0ef41Sopenharmony_ci        &maybe_target_instance, &function_index, &maybe_js_function);
12361cb0ef41Sopenharmony_ci    if (!is_valid) {
12371cb0ef41Sopenharmony_ci      thrower_->LinkError("table import %d[%d] is not a wasm function",
12381cb0ef41Sopenharmony_ci                          import_index, i);
12391cb0ef41Sopenharmony_ci      return false;
12401cb0ef41Sopenharmony_ci    }
12411cb0ef41Sopenharmony_ci    if (is_null) continue;
12421cb0ef41Sopenharmony_ci    Handle<WasmJSFunction> js_function;
12431cb0ef41Sopenharmony_ci    if (maybe_js_function.ToHandle(&js_function)) {
12441cb0ef41Sopenharmony_ci      WasmInstanceObject::ImportWasmJSFunctionIntoTable(
12451cb0ef41Sopenharmony_ci          isolate_, instance, table_index, i, js_function);
12461cb0ef41Sopenharmony_ci      continue;
12471cb0ef41Sopenharmony_ci    }
12481cb0ef41Sopenharmony_ci
12491cb0ef41Sopenharmony_ci    Handle<WasmInstanceObject> target_instance =
12501cb0ef41Sopenharmony_ci        maybe_target_instance.ToHandleChecked();
12511cb0ef41Sopenharmony_ci    const FunctionSig* sig = target_instance->module_object()
12521cb0ef41Sopenharmony_ci                                 .module()
12531cb0ef41Sopenharmony_ci                                 ->functions[function_index]
12541cb0ef41Sopenharmony_ci                                 .sig;
12551cb0ef41Sopenharmony_ci
12561cb0ef41Sopenharmony_ci    // Look up the signature's canonical id. If there is no canonical
12571cb0ef41Sopenharmony_ci    // id, then the signature does not appear at all in this module,
12581cb0ef41Sopenharmony_ci    // so putting {-1} in the table will cause checks to always fail.
12591cb0ef41Sopenharmony_ci    FunctionTargetAndRef entry(target_instance, function_index);
12601cb0ef41Sopenharmony_ci    instance->GetIndirectFunctionTable(isolate_, table_index)
12611cb0ef41Sopenharmony_ci        ->Set(i, module_->signature_map.Find(*sig), entry.call_target(),
12621cb0ef41Sopenharmony_ci              *entry.ref());
12631cb0ef41Sopenharmony_ci  }
12641cb0ef41Sopenharmony_ci  return true;
12651cb0ef41Sopenharmony_ci}
12661cb0ef41Sopenharmony_ci
12671cb0ef41Sopenharmony_cibool InstanceBuilder::ProcessImportedTable(Handle<WasmInstanceObject> instance,
12681cb0ef41Sopenharmony_ci                                           int import_index, int table_index,
12691cb0ef41Sopenharmony_ci                                           Handle<String> module_name,
12701cb0ef41Sopenharmony_ci                                           Handle<String> import_name,
12711cb0ef41Sopenharmony_ci                                           Handle<Object> value) {
12721cb0ef41Sopenharmony_ci  if (!value->IsWasmTableObject()) {
12731cb0ef41Sopenharmony_ci    ReportLinkError("table import requires a WebAssembly.Table", import_index,
12741cb0ef41Sopenharmony_ci                    module_name, import_name);
12751cb0ef41Sopenharmony_ci    return false;
12761cb0ef41Sopenharmony_ci  }
12771cb0ef41Sopenharmony_ci  const WasmTable& table = module_->tables[table_index];
12781cb0ef41Sopenharmony_ci
12791cb0ef41Sopenharmony_ci  auto table_object = Handle<WasmTableObject>::cast(value);
12801cb0ef41Sopenharmony_ci
12811cb0ef41Sopenharmony_ci  uint32_t imported_table_size =
12821cb0ef41Sopenharmony_ci      static_cast<uint32_t>(table_object->current_length());
12831cb0ef41Sopenharmony_ci  if (imported_table_size < table.initial_size) {
12841cb0ef41Sopenharmony_ci    thrower_->LinkError("table import %d is smaller than initial %u, got %u",
12851cb0ef41Sopenharmony_ci                        import_index, table.initial_size, imported_table_size);
12861cb0ef41Sopenharmony_ci    return false;
12871cb0ef41Sopenharmony_ci  }
12881cb0ef41Sopenharmony_ci
12891cb0ef41Sopenharmony_ci  if (table.has_maximum_size) {
12901cb0ef41Sopenharmony_ci    if (table_object->maximum_length().IsUndefined(isolate_)) {
12911cb0ef41Sopenharmony_ci      thrower_->LinkError("table import %d has no maximum length, expected %u",
12921cb0ef41Sopenharmony_ci                          import_index, table.maximum_size);
12931cb0ef41Sopenharmony_ci      return false;
12941cb0ef41Sopenharmony_ci    }
12951cb0ef41Sopenharmony_ci    int64_t imported_maximum_size = table_object->maximum_length().Number();
12961cb0ef41Sopenharmony_ci    if (imported_maximum_size < 0) {
12971cb0ef41Sopenharmony_ci      thrower_->LinkError("table import %d has no maximum length, expected %u",
12981cb0ef41Sopenharmony_ci                          import_index, table.maximum_size);
12991cb0ef41Sopenharmony_ci      return false;
13001cb0ef41Sopenharmony_ci    }
13011cb0ef41Sopenharmony_ci    if (imported_maximum_size > table.maximum_size) {
13021cb0ef41Sopenharmony_ci      thrower_->LinkError("table import %d has a larger maximum size %" PRIx64
13031cb0ef41Sopenharmony_ci                          " than the module's declared maximum %u",
13041cb0ef41Sopenharmony_ci                          import_index, imported_maximum_size,
13051cb0ef41Sopenharmony_ci                          table.maximum_size);
13061cb0ef41Sopenharmony_ci      return false;
13071cb0ef41Sopenharmony_ci    }
13081cb0ef41Sopenharmony_ci  }
13091cb0ef41Sopenharmony_ci
13101cb0ef41Sopenharmony_ci  const WasmModule* table_type_module =
13111cb0ef41Sopenharmony_ci      !table_object->instance().IsUndefined()
13121cb0ef41Sopenharmony_ci          ? WasmInstanceObject::cast(table_object->instance()).module()
13131cb0ef41Sopenharmony_ci          : instance->module();
13141cb0ef41Sopenharmony_ci
13151cb0ef41Sopenharmony_ci  if (!EquivalentTypes(table.type, table_object->type(), module_,
13161cb0ef41Sopenharmony_ci                       table_type_module)) {
13171cb0ef41Sopenharmony_ci    ReportLinkError("imported table does not match the expected type",
13181cb0ef41Sopenharmony_ci                    import_index, module_name, import_name);
13191cb0ef41Sopenharmony_ci    return false;
13201cb0ef41Sopenharmony_ci  }
13211cb0ef41Sopenharmony_ci
13221cb0ef41Sopenharmony_ci  if (IsSubtypeOf(table.type, kWasmFuncRef, module_) &&
13231cb0ef41Sopenharmony_ci      !InitializeImportedIndirectFunctionTable(instance, table_index,
13241cb0ef41Sopenharmony_ci                                               import_index, table_object)) {
13251cb0ef41Sopenharmony_ci    return false;
13261cb0ef41Sopenharmony_ci  }
13271cb0ef41Sopenharmony_ci
13281cb0ef41Sopenharmony_ci  instance->tables().set(table_index, *value);
13291cb0ef41Sopenharmony_ci  return true;
13301cb0ef41Sopenharmony_ci}
13311cb0ef41Sopenharmony_ci
13321cb0ef41Sopenharmony_cibool InstanceBuilder::ProcessImportedMemory(Handle<WasmInstanceObject> instance,
13331cb0ef41Sopenharmony_ci                                            int import_index,
13341cb0ef41Sopenharmony_ci                                            Handle<String> module_name,
13351cb0ef41Sopenharmony_ci                                            Handle<String> import_name,
13361cb0ef41Sopenharmony_ci                                            Handle<Object> value) {
13371cb0ef41Sopenharmony_ci  if (!value->IsWasmMemoryObject()) {
13381cb0ef41Sopenharmony_ci    ReportLinkError("memory import must be a WebAssembly.Memory object",
13391cb0ef41Sopenharmony_ci                    import_index, module_name, import_name);
13401cb0ef41Sopenharmony_ci    return false;
13411cb0ef41Sopenharmony_ci  }
13421cb0ef41Sopenharmony_ci  auto memory_object = Handle<WasmMemoryObject>::cast(value);
13431cb0ef41Sopenharmony_ci
13441cb0ef41Sopenharmony_ci  // The imported memory should have been already set up early.
13451cb0ef41Sopenharmony_ci  CHECK_EQ(instance->memory_object(), *memory_object);
13461cb0ef41Sopenharmony_ci
13471cb0ef41Sopenharmony_ci  Handle<JSArrayBuffer> buffer(memory_object_->array_buffer(), isolate_);
13481cb0ef41Sopenharmony_ci  // memory_ should have already been assigned in Build().
13491cb0ef41Sopenharmony_ci  DCHECK_EQ(*memory_buffer_.ToHandleChecked(), *buffer);
13501cb0ef41Sopenharmony_ci  uint32_t imported_cur_pages =
13511cb0ef41Sopenharmony_ci      static_cast<uint32_t>(buffer->byte_length() / kWasmPageSize);
13521cb0ef41Sopenharmony_ci  if (imported_cur_pages < module_->initial_pages) {
13531cb0ef41Sopenharmony_ci    thrower_->LinkError("memory import %d is smaller than initial %u, got %u",
13541cb0ef41Sopenharmony_ci                        import_index, module_->initial_pages,
13551cb0ef41Sopenharmony_ci                        imported_cur_pages);
13561cb0ef41Sopenharmony_ci    return false;
13571cb0ef41Sopenharmony_ci  }
13581cb0ef41Sopenharmony_ci  int32_t imported_maximum_pages = memory_object_->maximum_pages();
13591cb0ef41Sopenharmony_ci  if (module_->has_maximum_pages) {
13601cb0ef41Sopenharmony_ci    if (imported_maximum_pages < 0) {
13611cb0ef41Sopenharmony_ci      thrower_->LinkError(
13621cb0ef41Sopenharmony_ci          "memory import %d has no maximum limit, expected at most %u",
13631cb0ef41Sopenharmony_ci          import_index, imported_maximum_pages);
13641cb0ef41Sopenharmony_ci      return false;
13651cb0ef41Sopenharmony_ci    }
13661cb0ef41Sopenharmony_ci    if (static_cast<uint32_t>(imported_maximum_pages) >
13671cb0ef41Sopenharmony_ci        module_->maximum_pages) {
13681cb0ef41Sopenharmony_ci      thrower_->LinkError(
13691cb0ef41Sopenharmony_ci          "memory import %d has a larger maximum size %u than the "
13701cb0ef41Sopenharmony_ci          "module's declared maximum %u",
13711cb0ef41Sopenharmony_ci          import_index, imported_maximum_pages, module_->maximum_pages);
13721cb0ef41Sopenharmony_ci      return false;
13731cb0ef41Sopenharmony_ci    }
13741cb0ef41Sopenharmony_ci  }
13751cb0ef41Sopenharmony_ci  if (module_->has_shared_memory != buffer->is_shared()) {
13761cb0ef41Sopenharmony_ci    thrower_->LinkError(
13771cb0ef41Sopenharmony_ci        "mismatch in shared state of memory, declared = %d, imported = %d",
13781cb0ef41Sopenharmony_ci        module_->has_shared_memory, buffer->is_shared());
13791cb0ef41Sopenharmony_ci    return false;
13801cb0ef41Sopenharmony_ci  }
13811cb0ef41Sopenharmony_ci
13821cb0ef41Sopenharmony_ci  return true;
13831cb0ef41Sopenharmony_ci}
13841cb0ef41Sopenharmony_ci
13851cb0ef41Sopenharmony_cibool InstanceBuilder::ProcessImportedWasmGlobalObject(
13861cb0ef41Sopenharmony_ci    Handle<WasmInstanceObject> instance, int import_index,
13871cb0ef41Sopenharmony_ci    Handle<String> module_name, Handle<String> import_name,
13881cb0ef41Sopenharmony_ci    const WasmGlobal& global, Handle<WasmGlobalObject> global_object) {
13891cb0ef41Sopenharmony_ci  if (static_cast<bool>(global_object->is_mutable()) != global.mutability) {
13901cb0ef41Sopenharmony_ci    ReportLinkError("imported global does not match the expected mutability",
13911cb0ef41Sopenharmony_ci                    import_index, module_name, import_name);
13921cb0ef41Sopenharmony_ci    return false;
13931cb0ef41Sopenharmony_ci  }
13941cb0ef41Sopenharmony_ci
13951cb0ef41Sopenharmony_ci  const WasmModule* global_type_module =
13961cb0ef41Sopenharmony_ci      !global_object->instance().IsUndefined()
13971cb0ef41Sopenharmony_ci          ? WasmInstanceObject::cast(global_object->instance()).module()
13981cb0ef41Sopenharmony_ci          : instance->module();
13991cb0ef41Sopenharmony_ci
14001cb0ef41Sopenharmony_ci  bool valid_type =
14011cb0ef41Sopenharmony_ci      global.mutability
14021cb0ef41Sopenharmony_ci          ? EquivalentTypes(global_object->type(), global.type,
14031cb0ef41Sopenharmony_ci                            global_type_module, instance->module())
14041cb0ef41Sopenharmony_ci          : IsSubtypeOf(global_object->type(), global.type, global_type_module,
14051cb0ef41Sopenharmony_ci                        instance->module());
14061cb0ef41Sopenharmony_ci
14071cb0ef41Sopenharmony_ci  if (!valid_type) {
14081cb0ef41Sopenharmony_ci    ReportLinkError("imported global does not match the expected type",
14091cb0ef41Sopenharmony_ci                    import_index, module_name, import_name);
14101cb0ef41Sopenharmony_ci    return false;
14111cb0ef41Sopenharmony_ci  }
14121cb0ef41Sopenharmony_ci  if (global.mutability) {
14131cb0ef41Sopenharmony_ci    DCHECK_LT(global.index, module_->num_imported_mutable_globals);
14141cb0ef41Sopenharmony_ci    Handle<Object> buffer;
14151cb0ef41Sopenharmony_ci    Address address_or_offset;
14161cb0ef41Sopenharmony_ci    if (global.type.is_reference()) {
14171cb0ef41Sopenharmony_ci      static_assert(sizeof(global_object->offset()) <= sizeof(Address),
14181cb0ef41Sopenharmony_ci                    "The offset into the globals buffer does not fit into "
14191cb0ef41Sopenharmony_ci                    "the imported_mutable_globals array");
14201cb0ef41Sopenharmony_ci      buffer = handle(global_object->tagged_buffer(), isolate_);
14211cb0ef41Sopenharmony_ci      // For externref globals we use a relative offset, not an absolute
14221cb0ef41Sopenharmony_ci      // address.
14231cb0ef41Sopenharmony_ci      address_or_offset = static_cast<Address>(global_object->offset());
14241cb0ef41Sopenharmony_ci    } else {
14251cb0ef41Sopenharmony_ci      buffer = handle(global_object->untagged_buffer(), isolate_);
14261cb0ef41Sopenharmony_ci      // It is safe in this case to store the raw pointer to the buffer
14271cb0ef41Sopenharmony_ci      // since the backing store of the JSArrayBuffer will not be
14281cb0ef41Sopenharmony_ci      // relocated.
14291cb0ef41Sopenharmony_ci      address_or_offset = reinterpret_cast<Address>(raw_buffer_ptr(
14301cb0ef41Sopenharmony_ci          Handle<JSArrayBuffer>::cast(buffer), global_object->offset()));
14311cb0ef41Sopenharmony_ci    }
14321cb0ef41Sopenharmony_ci    instance->imported_mutable_globals_buffers().set(global.index, *buffer);
14331cb0ef41Sopenharmony_ci    instance->imported_mutable_globals()[global.index] = address_or_offset;
14341cb0ef41Sopenharmony_ci    return true;
14351cb0ef41Sopenharmony_ci  }
14361cb0ef41Sopenharmony_ci
14371cb0ef41Sopenharmony_ci  WasmValue value;
14381cb0ef41Sopenharmony_ci  switch (global_object->type().kind()) {
14391cb0ef41Sopenharmony_ci    case kI32:
14401cb0ef41Sopenharmony_ci      value = WasmValue(global_object->GetI32());
14411cb0ef41Sopenharmony_ci      break;
14421cb0ef41Sopenharmony_ci    case kI64:
14431cb0ef41Sopenharmony_ci      value = WasmValue(global_object->GetI64());
14441cb0ef41Sopenharmony_ci      break;
14451cb0ef41Sopenharmony_ci    case kF32:
14461cb0ef41Sopenharmony_ci      value = WasmValue(global_object->GetF32());
14471cb0ef41Sopenharmony_ci      break;
14481cb0ef41Sopenharmony_ci    case kF64:
14491cb0ef41Sopenharmony_ci      value = WasmValue(global_object->GetF64());
14501cb0ef41Sopenharmony_ci      break;
14511cb0ef41Sopenharmony_ci    case kRtt:
14521cb0ef41Sopenharmony_ci    case kRef:
14531cb0ef41Sopenharmony_ci    case kOptRef:
14541cb0ef41Sopenharmony_ci      value = WasmValue(global_object->GetRef(), global_object->type());
14551cb0ef41Sopenharmony_ci      break;
14561cb0ef41Sopenharmony_ci    case kVoid:
14571cb0ef41Sopenharmony_ci    case kS128:
14581cb0ef41Sopenharmony_ci    case kBottom:
14591cb0ef41Sopenharmony_ci    case kI8:
14601cb0ef41Sopenharmony_ci    case kI16:
14611cb0ef41Sopenharmony_ci      UNREACHABLE();
14621cb0ef41Sopenharmony_ci  }
14631cb0ef41Sopenharmony_ci
14641cb0ef41Sopenharmony_ci  WriteGlobalValue(global, value);
14651cb0ef41Sopenharmony_ci  return true;
14661cb0ef41Sopenharmony_ci}
14671cb0ef41Sopenharmony_ci
14681cb0ef41Sopenharmony_cibool InstanceBuilder::ProcessImportedGlobal(Handle<WasmInstanceObject> instance,
14691cb0ef41Sopenharmony_ci                                            int import_index, int global_index,
14701cb0ef41Sopenharmony_ci                                            Handle<String> module_name,
14711cb0ef41Sopenharmony_ci                                            Handle<String> import_name,
14721cb0ef41Sopenharmony_ci                                            Handle<Object> value) {
14731cb0ef41Sopenharmony_ci  // Immutable global imports are converted to numbers and written into
14741cb0ef41Sopenharmony_ci  // the {untagged_globals_} array buffer.
14751cb0ef41Sopenharmony_ci  //
14761cb0ef41Sopenharmony_ci  // Mutable global imports instead have their backing array buffers
14771cb0ef41Sopenharmony_ci  // referenced by this instance, and store the address of the imported
14781cb0ef41Sopenharmony_ci  // global in the {imported_mutable_globals_} array.
14791cb0ef41Sopenharmony_ci  const WasmGlobal& global = module_->globals[global_index];
14801cb0ef41Sopenharmony_ci
14811cb0ef41Sopenharmony_ci  // SIMD proposal allows modules to define an imported v128 global, and only
14821cb0ef41Sopenharmony_ci  // supports importing a WebAssembly.Global object for this global, but also
14831cb0ef41Sopenharmony_ci  // defines constructing a WebAssembly.Global of v128 to be a TypeError.
14841cb0ef41Sopenharmony_ci  // We *should* never hit this case in the JS API, but the module should should
14851cb0ef41Sopenharmony_ci  // be allowed to declare such a global (no validation error).
14861cb0ef41Sopenharmony_ci  if (global.type == kWasmS128 && !value->IsWasmGlobalObject()) {
14871cb0ef41Sopenharmony_ci    ReportLinkError("global import of type v128 must be a WebAssembly.Global",
14881cb0ef41Sopenharmony_ci                    import_index, module_name, import_name);
14891cb0ef41Sopenharmony_ci    return false;
14901cb0ef41Sopenharmony_ci  }
14911cb0ef41Sopenharmony_ci
14921cb0ef41Sopenharmony_ci  if (is_asmjs_module(module_)) {
14931cb0ef41Sopenharmony_ci    // Accepting {JSFunction} on top of just primitive values here is a
14941cb0ef41Sopenharmony_ci    // workaround to support legacy asm.js code with broken binding. Note
14951cb0ef41Sopenharmony_ci    // that using {NaN} (or Smi::zero()) here is what using the observable
14961cb0ef41Sopenharmony_ci    // conversion via {ToPrimitive} would produce as well. {LookupImportAsm}
14971cb0ef41Sopenharmony_ci    // checked via {HasDefaultToNumberBehaviour} that "valueOf" or friends have
14981cb0ef41Sopenharmony_ci    // not been patched.
14991cb0ef41Sopenharmony_ci    if (value->IsJSFunction()) value = isolate_->factory()->nan_value();
15001cb0ef41Sopenharmony_ci    if (value->IsPrimitive()) {
15011cb0ef41Sopenharmony_ci      MaybeHandle<Object> converted = global.type == kWasmI32
15021cb0ef41Sopenharmony_ci                                          ? Object::ToInt32(isolate_, value)
15031cb0ef41Sopenharmony_ci                                          : Object::ToNumber(isolate_, value);
15041cb0ef41Sopenharmony_ci      if (!converted.ToHandle(&value)) {
15051cb0ef41Sopenharmony_ci        // Conversion is known to fail for Symbols and BigInts.
15061cb0ef41Sopenharmony_ci        ReportLinkError("global import must be a number", import_index,
15071cb0ef41Sopenharmony_ci                        module_name, import_name);
15081cb0ef41Sopenharmony_ci        return false;
15091cb0ef41Sopenharmony_ci      }
15101cb0ef41Sopenharmony_ci    }
15111cb0ef41Sopenharmony_ci  }
15121cb0ef41Sopenharmony_ci
15131cb0ef41Sopenharmony_ci  if (value->IsWasmGlobalObject()) {
15141cb0ef41Sopenharmony_ci    auto global_object = Handle<WasmGlobalObject>::cast(value);
15151cb0ef41Sopenharmony_ci    return ProcessImportedWasmGlobalObject(instance, import_index, module_name,
15161cb0ef41Sopenharmony_ci                                           import_name, global, global_object);
15171cb0ef41Sopenharmony_ci  }
15181cb0ef41Sopenharmony_ci
15191cb0ef41Sopenharmony_ci  if (global.mutability) {
15201cb0ef41Sopenharmony_ci    ReportLinkError(
15211cb0ef41Sopenharmony_ci        "imported mutable global must be a WebAssembly.Global object",
15221cb0ef41Sopenharmony_ci        import_index, module_name, import_name);
15231cb0ef41Sopenharmony_ci    return false;
15241cb0ef41Sopenharmony_ci  }
15251cb0ef41Sopenharmony_ci
15261cb0ef41Sopenharmony_ci  if (global.type.is_reference()) {
15271cb0ef41Sopenharmony_ci    const char* error_message;
15281cb0ef41Sopenharmony_ci    if (!wasm::TypecheckJSObject(isolate_, module_, value, global.type,
15291cb0ef41Sopenharmony_ci                                 &error_message)) {
15301cb0ef41Sopenharmony_ci      ReportLinkError(error_message, global_index, module_name, import_name);
15311cb0ef41Sopenharmony_ci      return false;
15321cb0ef41Sopenharmony_ci    }
15331cb0ef41Sopenharmony_ci    if (IsSubtypeOf(global.type, kWasmFuncRef, module_) && !value->IsNull()) {
15341cb0ef41Sopenharmony_ci      value =
15351cb0ef41Sopenharmony_ci          WasmInternalFunction::FromExternal(value, isolate_).ToHandleChecked();
15361cb0ef41Sopenharmony_ci    }
15371cb0ef41Sopenharmony_ci    WriteGlobalValue(global, WasmValue(value, global.type));
15381cb0ef41Sopenharmony_ci    return true;
15391cb0ef41Sopenharmony_ci  }
15401cb0ef41Sopenharmony_ci
15411cb0ef41Sopenharmony_ci  if (value->IsNumber() && global.type != kWasmI64) {
15421cb0ef41Sopenharmony_ci    double number_value = value->Number();
15431cb0ef41Sopenharmony_ci    // The Wasm-BigInt proposal currently says that i64 globals may
15441cb0ef41Sopenharmony_ci    // only be initialized with BigInts. See:
15451cb0ef41Sopenharmony_ci    // https://github.com/WebAssembly/JS-BigInt-integration/issues/12
15461cb0ef41Sopenharmony_ci    WasmValue wasm_value = global.type == kWasmI32
15471cb0ef41Sopenharmony_ci                               ? WasmValue(DoubleToInt32(number_value))
15481cb0ef41Sopenharmony_ci                               : global.type == kWasmF32
15491cb0ef41Sopenharmony_ci                                     ? WasmValue(DoubleToFloat32(number_value))
15501cb0ef41Sopenharmony_ci                                     : WasmValue(number_value);
15511cb0ef41Sopenharmony_ci    WriteGlobalValue(global, wasm_value);
15521cb0ef41Sopenharmony_ci    return true;
15531cb0ef41Sopenharmony_ci  }
15541cb0ef41Sopenharmony_ci
15551cb0ef41Sopenharmony_ci  if (global.type == kWasmI64 && value->IsBigInt()) {
15561cb0ef41Sopenharmony_ci    WriteGlobalValue(global, WasmValue(BigInt::cast(*value).AsInt64()));
15571cb0ef41Sopenharmony_ci    return true;
15581cb0ef41Sopenharmony_ci  }
15591cb0ef41Sopenharmony_ci
15601cb0ef41Sopenharmony_ci  ReportLinkError(
15611cb0ef41Sopenharmony_ci      "global import must be a number, valid Wasm reference, or "
15621cb0ef41Sopenharmony_ci      "WebAssembly.Global object",
15631cb0ef41Sopenharmony_ci      import_index, module_name, import_name);
15641cb0ef41Sopenharmony_ci  return false;
15651cb0ef41Sopenharmony_ci}
15661cb0ef41Sopenharmony_ci
15671cb0ef41Sopenharmony_civoid InstanceBuilder::CompileImportWrappers(
15681cb0ef41Sopenharmony_ci    Handle<WasmInstanceObject> instance) {
15691cb0ef41Sopenharmony_ci  int num_imports = static_cast<int>(module_->import_table.size());
15701cb0ef41Sopenharmony_ci  TRACE_EVENT1("v8.wasm", "wasm.CompileImportWrappers", "num_imports",
15711cb0ef41Sopenharmony_ci               num_imports);
15721cb0ef41Sopenharmony_ci  NativeModule* native_module = instance->module_object().native_module();
15731cb0ef41Sopenharmony_ci  WasmImportWrapperCache::ModificationScope cache_scope(
15741cb0ef41Sopenharmony_ci      native_module->import_wrapper_cache());
15751cb0ef41Sopenharmony_ci
15761cb0ef41Sopenharmony_ci  // Compilation is done in two steps:
15771cb0ef41Sopenharmony_ci  // 1) Insert nullptr entries in the cache for wrappers that need to be
15781cb0ef41Sopenharmony_ci  // compiled. 2) Compile wrappers in background tasks using the
15791cb0ef41Sopenharmony_ci  // ImportWrapperQueue. This way the cache won't invalidate other iterators
15801cb0ef41Sopenharmony_ci  // when inserting a new WasmCode, since the key will already be there.
15811cb0ef41Sopenharmony_ci  ImportWrapperQueue import_wrapper_queue;
15821cb0ef41Sopenharmony_ci  for (int index = 0; index < num_imports; ++index) {
15831cb0ef41Sopenharmony_ci    Handle<Object> value = sanitized_imports_[index].value;
15841cb0ef41Sopenharmony_ci    if (module_->import_table[index].kind != kExternalFunction ||
15851cb0ef41Sopenharmony_ci        !value->IsCallable()) {
15861cb0ef41Sopenharmony_ci      continue;
15871cb0ef41Sopenharmony_ci    }
15881cb0ef41Sopenharmony_ci    auto js_receiver = Handle<JSReceiver>::cast(value);
15891cb0ef41Sopenharmony_ci    uint32_t func_index = module_->import_table[index].index;
15901cb0ef41Sopenharmony_ci    const FunctionSig* sig = module_->functions[func_index].sig;
15911cb0ef41Sopenharmony_ci    auto resolved =
15921cb0ef41Sopenharmony_ci        compiler::ResolveWasmImportCall(js_receiver, sig, module_, enabled_);
15931cb0ef41Sopenharmony_ci    compiler::WasmImportCallKind kind = resolved.kind;
15941cb0ef41Sopenharmony_ci    if (kind == compiler::WasmImportCallKind::kWasmToWasm ||
15951cb0ef41Sopenharmony_ci        kind == compiler::WasmImportCallKind::kLinkError ||
15961cb0ef41Sopenharmony_ci        kind == compiler::WasmImportCallKind::kWasmToCapi ||
15971cb0ef41Sopenharmony_ci        kind == compiler::WasmImportCallKind::kWasmToJSFastApi) {
15981cb0ef41Sopenharmony_ci      continue;
15991cb0ef41Sopenharmony_ci    }
16001cb0ef41Sopenharmony_ci
16011cb0ef41Sopenharmony_ci    int expected_arity = static_cast<int>(sig->parameter_count());
16021cb0ef41Sopenharmony_ci    if (resolved.kind ==
16031cb0ef41Sopenharmony_ci        compiler::WasmImportCallKind::kJSFunctionArityMismatch) {
16041cb0ef41Sopenharmony_ci      Handle<JSFunction> function = Handle<JSFunction>::cast(resolved.callable);
16051cb0ef41Sopenharmony_ci      SharedFunctionInfo shared = function->shared();
16061cb0ef41Sopenharmony_ci      expected_arity =
16071cb0ef41Sopenharmony_ci          shared.internal_formal_parameter_count_without_receiver();
16081cb0ef41Sopenharmony_ci    }
16091cb0ef41Sopenharmony_ci
16101cb0ef41Sopenharmony_ci    Suspend suspend =
16111cb0ef41Sopenharmony_ci        resolved.suspender.is_null() || resolved.suspender->IsUndefined()
16121cb0ef41Sopenharmony_ci            ? kNoSuspend
16131cb0ef41Sopenharmony_ci            : kSuspend;
16141cb0ef41Sopenharmony_ci    WasmImportWrapperCache::CacheKey key(kind, sig, expected_arity, suspend);
16151cb0ef41Sopenharmony_ci    if (cache_scope[key] != nullptr) {
16161cb0ef41Sopenharmony_ci      // Cache entry already exists, no need to compile it again.
16171cb0ef41Sopenharmony_ci      continue;
16181cb0ef41Sopenharmony_ci    }
16191cb0ef41Sopenharmony_ci    import_wrapper_queue.insert(key);
16201cb0ef41Sopenharmony_ci  }
16211cb0ef41Sopenharmony_ci
16221cb0ef41Sopenharmony_ci  auto compile_job_task = std::make_unique<CompileImportWrapperJob>(
16231cb0ef41Sopenharmony_ci      isolate_->counters(), native_module, &import_wrapper_queue, &cache_scope);
16241cb0ef41Sopenharmony_ci  auto compile_job = V8::GetCurrentPlatform()->PostJob(
16251cb0ef41Sopenharmony_ci      TaskPriority::kUserVisible, std::move(compile_job_task));
16261cb0ef41Sopenharmony_ci
16271cb0ef41Sopenharmony_ci  // Wait for the job to finish, while contributing in this thread.
16281cb0ef41Sopenharmony_ci  compile_job->Join();
16291cb0ef41Sopenharmony_ci}
16301cb0ef41Sopenharmony_ci
16311cb0ef41Sopenharmony_ci// Process the imports, including functions, tables, globals, and memory, in
16321cb0ef41Sopenharmony_ci// order, loading them from the {ffi_} object. Returns the number of imported
16331cb0ef41Sopenharmony_ci// functions.
16341cb0ef41Sopenharmony_ciint InstanceBuilder::ProcessImports(Handle<WasmInstanceObject> instance) {
16351cb0ef41Sopenharmony_ci  int num_imported_functions = 0;
16361cb0ef41Sopenharmony_ci  int num_imported_tables = 0;
16371cb0ef41Sopenharmony_ci
16381cb0ef41Sopenharmony_ci  DCHECK_EQ(module_->import_table.size(), sanitized_imports_.size());
16391cb0ef41Sopenharmony_ci
16401cb0ef41Sopenharmony_ci  CompileImportWrappers(instance);
16411cb0ef41Sopenharmony_ci  int num_imports = static_cast<int>(module_->import_table.size());
16421cb0ef41Sopenharmony_ci  for (int index = 0; index < num_imports; ++index) {
16431cb0ef41Sopenharmony_ci    const WasmImport& import = module_->import_table[index];
16441cb0ef41Sopenharmony_ci
16451cb0ef41Sopenharmony_ci    Handle<String> module_name = sanitized_imports_[index].module_name;
16461cb0ef41Sopenharmony_ci    Handle<String> import_name = sanitized_imports_[index].import_name;
16471cb0ef41Sopenharmony_ci    Handle<Object> value = sanitized_imports_[index].value;
16481cb0ef41Sopenharmony_ci
16491cb0ef41Sopenharmony_ci    switch (import.kind) {
16501cb0ef41Sopenharmony_ci      case kExternalFunction: {
16511cb0ef41Sopenharmony_ci        uint32_t func_index = import.index;
16521cb0ef41Sopenharmony_ci        DCHECK_EQ(num_imported_functions, func_index);
16531cb0ef41Sopenharmony_ci        if (!ProcessImportedFunction(instance, index, func_index, module_name,
16541cb0ef41Sopenharmony_ci                                     import_name, value)) {
16551cb0ef41Sopenharmony_ci          return -1;
16561cb0ef41Sopenharmony_ci        }
16571cb0ef41Sopenharmony_ci        num_imported_functions++;
16581cb0ef41Sopenharmony_ci        break;
16591cb0ef41Sopenharmony_ci      }
16601cb0ef41Sopenharmony_ci      case kExternalTable: {
16611cb0ef41Sopenharmony_ci        uint32_t table_index = import.index;
16621cb0ef41Sopenharmony_ci        DCHECK_EQ(table_index, num_imported_tables);
16631cb0ef41Sopenharmony_ci        if (!ProcessImportedTable(instance, index, table_index, module_name,
16641cb0ef41Sopenharmony_ci                                  import_name, value)) {
16651cb0ef41Sopenharmony_ci          return -1;
16661cb0ef41Sopenharmony_ci        }
16671cb0ef41Sopenharmony_ci        num_imported_tables++;
16681cb0ef41Sopenharmony_ci        USE(num_imported_tables);
16691cb0ef41Sopenharmony_ci        break;
16701cb0ef41Sopenharmony_ci      }
16711cb0ef41Sopenharmony_ci      case kExternalMemory: {
16721cb0ef41Sopenharmony_ci        if (!ProcessImportedMemory(instance, index, module_name, import_name,
16731cb0ef41Sopenharmony_ci                                   value)) {
16741cb0ef41Sopenharmony_ci          return -1;
16751cb0ef41Sopenharmony_ci        }
16761cb0ef41Sopenharmony_ci        break;
16771cb0ef41Sopenharmony_ci      }
16781cb0ef41Sopenharmony_ci      case kExternalGlobal: {
16791cb0ef41Sopenharmony_ci        if (!ProcessImportedGlobal(instance, index, import.index, module_name,
16801cb0ef41Sopenharmony_ci                                   import_name, value)) {
16811cb0ef41Sopenharmony_ci          return -1;
16821cb0ef41Sopenharmony_ci        }
16831cb0ef41Sopenharmony_ci        break;
16841cb0ef41Sopenharmony_ci      }
16851cb0ef41Sopenharmony_ci      case kExternalTag: {
16861cb0ef41Sopenharmony_ci        if (!value->IsWasmTagObject()) {
16871cb0ef41Sopenharmony_ci          ReportLinkError("tag import requires a WebAssembly.Tag", index,
16881cb0ef41Sopenharmony_ci                          module_name, import_name);
16891cb0ef41Sopenharmony_ci          return -1;
16901cb0ef41Sopenharmony_ci        }
16911cb0ef41Sopenharmony_ci        Handle<WasmTagObject> imported_tag = Handle<WasmTagObject>::cast(value);
16921cb0ef41Sopenharmony_ci        if (!imported_tag->MatchesSignature(module_->tags[import.index].sig)) {
16931cb0ef41Sopenharmony_ci          ReportLinkError("imported tag does not match the expected type",
16941cb0ef41Sopenharmony_ci                          index, module_name, import_name);
16951cb0ef41Sopenharmony_ci          return -1;
16961cb0ef41Sopenharmony_ci        }
16971cb0ef41Sopenharmony_ci        Object tag = imported_tag->tag();
16981cb0ef41Sopenharmony_ci        DCHECK(instance->tags_table().get(import.index).IsUndefined());
16991cb0ef41Sopenharmony_ci        instance->tags_table().set(import.index, tag);
17001cb0ef41Sopenharmony_ci        tags_wrappers_[import.index] = imported_tag;
17011cb0ef41Sopenharmony_ci        break;
17021cb0ef41Sopenharmony_ci      }
17031cb0ef41Sopenharmony_ci      default:
17041cb0ef41Sopenharmony_ci        UNREACHABLE();
17051cb0ef41Sopenharmony_ci    }
17061cb0ef41Sopenharmony_ci  }
17071cb0ef41Sopenharmony_ci  return num_imported_functions;
17081cb0ef41Sopenharmony_ci}
17091cb0ef41Sopenharmony_ci
17101cb0ef41Sopenharmony_citemplate <typename T>
17111cb0ef41Sopenharmony_ciT* InstanceBuilder::GetRawUntaggedGlobalPtr(const WasmGlobal& global) {
17121cb0ef41Sopenharmony_ci  return reinterpret_cast<T*>(raw_buffer_ptr(untagged_globals_, global.offset));
17131cb0ef41Sopenharmony_ci}
17141cb0ef41Sopenharmony_ci
17151cb0ef41Sopenharmony_ci// Process initialization of globals.
17161cb0ef41Sopenharmony_civoid InstanceBuilder::InitGlobals(Handle<WasmInstanceObject> instance) {
17171cb0ef41Sopenharmony_ci  for (const WasmGlobal& global : module_->globals) {
17181cb0ef41Sopenharmony_ci    if (global.mutability && global.imported) continue;
17191cb0ef41Sopenharmony_ci    // Happens with imported globals.
17201cb0ef41Sopenharmony_ci    if (!global.init.is_set()) continue;
17211cb0ef41Sopenharmony_ci
17221cb0ef41Sopenharmony_ci    WasmValue value =
17231cb0ef41Sopenharmony_ci        EvaluateInitExpression(&init_expr_zone_, global.init, global.type,
17241cb0ef41Sopenharmony_ci                               isolate_, instance, thrower_);
17251cb0ef41Sopenharmony_ci    if (thrower_->error()) return;
17261cb0ef41Sopenharmony_ci
17271cb0ef41Sopenharmony_ci    if (global.type.is_reference()) {
17281cb0ef41Sopenharmony_ci      tagged_globals_->set(global.offset, *value.to_ref());
17291cb0ef41Sopenharmony_ci    } else {
17301cb0ef41Sopenharmony_ci      value.CopyTo(GetRawUntaggedGlobalPtr<byte>(global));
17311cb0ef41Sopenharmony_ci    }
17321cb0ef41Sopenharmony_ci  }
17331cb0ef41Sopenharmony_ci}
17341cb0ef41Sopenharmony_ci
17351cb0ef41Sopenharmony_ci// Allocate memory for a module instance as a new JSArrayBuffer.
17361cb0ef41Sopenharmony_cibool InstanceBuilder::AllocateMemory() {
17371cb0ef41Sopenharmony_ci  int initial_pages = static_cast<int>(module_->initial_pages);
17381cb0ef41Sopenharmony_ci  int maximum_pages = module_->has_maximum_pages
17391cb0ef41Sopenharmony_ci                          ? static_cast<int>(module_->maximum_pages)
17401cb0ef41Sopenharmony_ci                          : WasmMemoryObject::kNoMaximum;
17411cb0ef41Sopenharmony_ci  auto shared = (module_->has_shared_memory && enabled_.has_threads())
17421cb0ef41Sopenharmony_ci                    ? SharedFlag::kShared
17431cb0ef41Sopenharmony_ci                    : SharedFlag::kNotShared;
17441cb0ef41Sopenharmony_ci
17451cb0ef41Sopenharmony_ci  if (!WasmMemoryObject::New(isolate_, initial_pages, maximum_pages, shared)
17461cb0ef41Sopenharmony_ci           .ToHandle(&memory_object_)) {
17471cb0ef41Sopenharmony_ci    thrower_->RangeError("Out of memory: wasm memory");
17481cb0ef41Sopenharmony_ci    return false;
17491cb0ef41Sopenharmony_ci  }
17501cb0ef41Sopenharmony_ci  memory_buffer_ =
17511cb0ef41Sopenharmony_ci      Handle<JSArrayBuffer>(memory_object_->array_buffer(), isolate_);
17521cb0ef41Sopenharmony_ci  return true;
17531cb0ef41Sopenharmony_ci}
17541cb0ef41Sopenharmony_ci
17551cb0ef41Sopenharmony_ci// Process the exports, creating wrappers for functions, tables, memories,
17561cb0ef41Sopenharmony_ci// globals, and exceptions.
17571cb0ef41Sopenharmony_civoid InstanceBuilder::ProcessExports(Handle<WasmInstanceObject> instance) {
17581cb0ef41Sopenharmony_ci  std::unordered_map<int, Handle<Object>> imported_globals;
17591cb0ef41Sopenharmony_ci
17601cb0ef41Sopenharmony_ci  // If an imported WebAssembly function or global gets exported, the export
17611cb0ef41Sopenharmony_ci  // has to be identical to to import. Therefore we cache all imported
17621cb0ef41Sopenharmony_ci  // WebAssembly functions in the instance, and all imported globals in a map
17631cb0ef41Sopenharmony_ci  // here.
17641cb0ef41Sopenharmony_ci  for (int index = 0, end = static_cast<int>(module_->import_table.size());
17651cb0ef41Sopenharmony_ci       index < end; ++index) {
17661cb0ef41Sopenharmony_ci    const WasmImport& import = module_->import_table[index];
17671cb0ef41Sopenharmony_ci    if (import.kind == kExternalFunction) {
17681cb0ef41Sopenharmony_ci      Handle<Object> value = sanitized_imports_[index].value;
17691cb0ef41Sopenharmony_ci      if (WasmExternalFunction::IsWasmExternalFunction(*value)) {
17701cb0ef41Sopenharmony_ci        WasmInstanceObject::SetWasmInternalFunction(
17711cb0ef41Sopenharmony_ci            isolate_, instance, import.index,
17721cb0ef41Sopenharmony_ci            WasmInternalFunction::FromExternal(
17731cb0ef41Sopenharmony_ci                Handle<WasmExternalFunction>::cast(value), isolate_)
17741cb0ef41Sopenharmony_ci                .ToHandleChecked());
17751cb0ef41Sopenharmony_ci      }
17761cb0ef41Sopenharmony_ci    } else if (import.kind == kExternalGlobal) {
17771cb0ef41Sopenharmony_ci      Handle<Object> value = sanitized_imports_[index].value;
17781cb0ef41Sopenharmony_ci      if (value->IsWasmGlobalObject()) {
17791cb0ef41Sopenharmony_ci        imported_globals[import.index] = value;
17801cb0ef41Sopenharmony_ci      }
17811cb0ef41Sopenharmony_ci    }
17821cb0ef41Sopenharmony_ci  }
17831cb0ef41Sopenharmony_ci
17841cb0ef41Sopenharmony_ci  Handle<JSObject> exports_object;
17851cb0ef41Sopenharmony_ci  MaybeHandle<String> single_function_name;
17861cb0ef41Sopenharmony_ci  bool is_asm_js = is_asmjs_module(module_);
17871cb0ef41Sopenharmony_ci  if (is_asm_js) {
17881cb0ef41Sopenharmony_ci    Handle<JSFunction> object_function = Handle<JSFunction>(
17891cb0ef41Sopenharmony_ci        isolate_->native_context()->object_function(), isolate_);
17901cb0ef41Sopenharmony_ci    exports_object = isolate_->factory()->NewJSObject(object_function);
17911cb0ef41Sopenharmony_ci    single_function_name =
17921cb0ef41Sopenharmony_ci        isolate_->factory()->InternalizeUtf8String(AsmJs::kSingleFunctionName);
17931cb0ef41Sopenharmony_ci  } else {
17941cb0ef41Sopenharmony_ci    exports_object = isolate_->factory()->NewJSObjectWithNullProto();
17951cb0ef41Sopenharmony_ci  }
17961cb0ef41Sopenharmony_ci  instance->set_exports_object(*exports_object);
17971cb0ef41Sopenharmony_ci
17981cb0ef41Sopenharmony_ci  PropertyDescriptor desc;
17991cb0ef41Sopenharmony_ci  desc.set_writable(is_asm_js);
18001cb0ef41Sopenharmony_ci  desc.set_enumerable(true);
18011cb0ef41Sopenharmony_ci  desc.set_configurable(is_asm_js);
18021cb0ef41Sopenharmony_ci
18031cb0ef41Sopenharmony_ci  // Process each export in the export table.
18041cb0ef41Sopenharmony_ci  for (const WasmExport& exp : module_->export_table) {
18051cb0ef41Sopenharmony_ci    Handle<String> name = WasmModuleObject::ExtractUtf8StringFromModuleBytes(
18061cb0ef41Sopenharmony_ci        isolate_, module_object_, exp.name, kInternalize);
18071cb0ef41Sopenharmony_ci    Handle<JSObject> export_to = exports_object;
18081cb0ef41Sopenharmony_ci    switch (exp.kind) {
18091cb0ef41Sopenharmony_ci      case kExternalFunction: {
18101cb0ef41Sopenharmony_ci        // Wrap and export the code as a JSFunction.
18111cb0ef41Sopenharmony_ci        // TODO(wasm): reduce duplication with LoadElemSegment() further below
18121cb0ef41Sopenharmony_ci        Handle<WasmInternalFunction> internal =
18131cb0ef41Sopenharmony_ci            WasmInstanceObject::GetOrCreateWasmInternalFunction(
18141cb0ef41Sopenharmony_ci                isolate_, instance, exp.index);
18151cb0ef41Sopenharmony_ci        Handle<WasmExternalFunction> wasm_external_function =
18161cb0ef41Sopenharmony_ci            handle(WasmExternalFunction::cast(internal->external()), isolate_);
18171cb0ef41Sopenharmony_ci        desc.set_value(wasm_external_function);
18181cb0ef41Sopenharmony_ci
18191cb0ef41Sopenharmony_ci        if (is_asm_js &&
18201cb0ef41Sopenharmony_ci            String::Equals(isolate_, name,
18211cb0ef41Sopenharmony_ci                           single_function_name.ToHandleChecked())) {
18221cb0ef41Sopenharmony_ci          export_to = instance;
18231cb0ef41Sopenharmony_ci        }
18241cb0ef41Sopenharmony_ci        break;
18251cb0ef41Sopenharmony_ci      }
18261cb0ef41Sopenharmony_ci      case kExternalTable: {
18271cb0ef41Sopenharmony_ci        desc.set_value(handle(instance->tables().get(exp.index), isolate_));
18281cb0ef41Sopenharmony_ci        break;
18291cb0ef41Sopenharmony_ci      }
18301cb0ef41Sopenharmony_ci      case kExternalMemory: {
18311cb0ef41Sopenharmony_ci        // Export the memory as a WebAssembly.Memory object. A WasmMemoryObject
18321cb0ef41Sopenharmony_ci        // should already be available if the module has memory, since we always
18331cb0ef41Sopenharmony_ci        // create or import it when building an WasmInstanceObject.
18341cb0ef41Sopenharmony_ci        DCHECK(instance->has_memory_object());
18351cb0ef41Sopenharmony_ci        desc.set_value(
18361cb0ef41Sopenharmony_ci            Handle<WasmMemoryObject>(instance->memory_object(), isolate_));
18371cb0ef41Sopenharmony_ci        break;
18381cb0ef41Sopenharmony_ci      }
18391cb0ef41Sopenharmony_ci      case kExternalGlobal: {
18401cb0ef41Sopenharmony_ci        const WasmGlobal& global = module_->globals[exp.index];
18411cb0ef41Sopenharmony_ci        if (global.imported) {
18421cb0ef41Sopenharmony_ci          auto cached_global = imported_globals.find(exp.index);
18431cb0ef41Sopenharmony_ci          if (cached_global != imported_globals.end()) {
18441cb0ef41Sopenharmony_ci            desc.set_value(cached_global->second);
18451cb0ef41Sopenharmony_ci            break;
18461cb0ef41Sopenharmony_ci          }
18471cb0ef41Sopenharmony_ci        }
18481cb0ef41Sopenharmony_ci        Handle<JSArrayBuffer> untagged_buffer;
18491cb0ef41Sopenharmony_ci        Handle<FixedArray> tagged_buffer;
18501cb0ef41Sopenharmony_ci        uint32_t offset;
18511cb0ef41Sopenharmony_ci
18521cb0ef41Sopenharmony_ci        if (global.mutability && global.imported) {
18531cb0ef41Sopenharmony_ci          Handle<FixedArray> buffers_array(
18541cb0ef41Sopenharmony_ci              instance->imported_mutable_globals_buffers(), isolate_);
18551cb0ef41Sopenharmony_ci          if (global.type.is_reference()) {
18561cb0ef41Sopenharmony_ci            tagged_buffer = handle(
18571cb0ef41Sopenharmony_ci                FixedArray::cast(buffers_array->get(global.index)), isolate_);
18581cb0ef41Sopenharmony_ci            // For externref globals we store the relative offset in the
18591cb0ef41Sopenharmony_ci            // imported_mutable_globals array instead of an absolute address.
18601cb0ef41Sopenharmony_ci            Address addr = instance->imported_mutable_globals()[global.index];
18611cb0ef41Sopenharmony_ci            DCHECK_LE(addr, static_cast<Address>(
18621cb0ef41Sopenharmony_ci                                std::numeric_limits<uint32_t>::max()));
18631cb0ef41Sopenharmony_ci            offset = static_cast<uint32_t>(addr);
18641cb0ef41Sopenharmony_ci          } else {
18651cb0ef41Sopenharmony_ci            untagged_buffer =
18661cb0ef41Sopenharmony_ci                handle(JSArrayBuffer::cast(buffers_array->get(global.index)),
18671cb0ef41Sopenharmony_ci                       isolate_);
18681cb0ef41Sopenharmony_ci            Address global_addr =
18691cb0ef41Sopenharmony_ci                instance->imported_mutable_globals()[global.index];
18701cb0ef41Sopenharmony_ci
18711cb0ef41Sopenharmony_ci            size_t buffer_size = untagged_buffer->byte_length();
18721cb0ef41Sopenharmony_ci            Address backing_store =
18731cb0ef41Sopenharmony_ci                reinterpret_cast<Address>(untagged_buffer->backing_store());
18741cb0ef41Sopenharmony_ci            CHECK(global_addr >= backing_store &&
18751cb0ef41Sopenharmony_ci                  global_addr < backing_store + buffer_size);
18761cb0ef41Sopenharmony_ci            offset = static_cast<uint32_t>(global_addr - backing_store);
18771cb0ef41Sopenharmony_ci          }
18781cb0ef41Sopenharmony_ci        } else {
18791cb0ef41Sopenharmony_ci          if (global.type.is_reference()) {
18801cb0ef41Sopenharmony_ci            tagged_buffer = handle(instance->tagged_globals_buffer(), isolate_);
18811cb0ef41Sopenharmony_ci          } else {
18821cb0ef41Sopenharmony_ci            untagged_buffer =
18831cb0ef41Sopenharmony_ci                handle(instance->untagged_globals_buffer(), isolate_);
18841cb0ef41Sopenharmony_ci          }
18851cb0ef41Sopenharmony_ci          offset = global.offset;
18861cb0ef41Sopenharmony_ci        }
18871cb0ef41Sopenharmony_ci
18881cb0ef41Sopenharmony_ci        // Since the global's array untagged_buffer is always provided,
18891cb0ef41Sopenharmony_ci        // allocation should never fail.
18901cb0ef41Sopenharmony_ci        Handle<WasmGlobalObject> global_obj =
18911cb0ef41Sopenharmony_ci            WasmGlobalObject::New(isolate_, instance, untagged_buffer,
18921cb0ef41Sopenharmony_ci                                  tagged_buffer, global.type, offset,
18931cb0ef41Sopenharmony_ci                                  global.mutability)
18941cb0ef41Sopenharmony_ci                .ToHandleChecked();
18951cb0ef41Sopenharmony_ci        desc.set_value(global_obj);
18961cb0ef41Sopenharmony_ci        break;
18971cb0ef41Sopenharmony_ci      }
18981cb0ef41Sopenharmony_ci      case kExternalTag: {
18991cb0ef41Sopenharmony_ci        const WasmTag& tag = module_->tags[exp.index];
19001cb0ef41Sopenharmony_ci        Handle<WasmTagObject> wrapper = tags_wrappers_[exp.index];
19011cb0ef41Sopenharmony_ci        if (wrapper.is_null()) {
19021cb0ef41Sopenharmony_ci          Handle<HeapObject> tag_object(
19031cb0ef41Sopenharmony_ci              HeapObject::cast(instance->tags_table().get(exp.index)),
19041cb0ef41Sopenharmony_ci              isolate_);
19051cb0ef41Sopenharmony_ci          wrapper = WasmTagObject::New(isolate_, tag.sig, tag_object);
19061cb0ef41Sopenharmony_ci          tags_wrappers_[exp.index] = wrapper;
19071cb0ef41Sopenharmony_ci        }
19081cb0ef41Sopenharmony_ci        desc.set_value(wrapper);
19091cb0ef41Sopenharmony_ci        break;
19101cb0ef41Sopenharmony_ci      }
19111cb0ef41Sopenharmony_ci      default:
19121cb0ef41Sopenharmony_ci        UNREACHABLE();
19131cb0ef41Sopenharmony_ci    }
19141cb0ef41Sopenharmony_ci
19151cb0ef41Sopenharmony_ci    v8::Maybe<bool> status = JSReceiver::DefineOwnProperty(
19161cb0ef41Sopenharmony_ci        isolate_, export_to, name, &desc, Just(kThrowOnError));
19171cb0ef41Sopenharmony_ci    if (!status.IsJust()) {
19181cb0ef41Sopenharmony_ci      DisallowGarbageCollection no_gc;
19191cb0ef41Sopenharmony_ci      TruncatedUserString<> trunc_name(name->GetCharVector<uint8_t>(no_gc));
19201cb0ef41Sopenharmony_ci      thrower_->LinkError("export of %.*s failed.", trunc_name.length(),
19211cb0ef41Sopenharmony_ci                          trunc_name.start());
19221cb0ef41Sopenharmony_ci      return;
19231cb0ef41Sopenharmony_ci    }
19241cb0ef41Sopenharmony_ci  }
19251cb0ef41Sopenharmony_ci
19261cb0ef41Sopenharmony_ci  if (module_->origin == kWasmOrigin) {
19271cb0ef41Sopenharmony_ci    v8::Maybe<bool> success =
19281cb0ef41Sopenharmony_ci        JSReceiver::SetIntegrityLevel(exports_object, FROZEN, kDontThrow);
19291cb0ef41Sopenharmony_ci    DCHECK(success.FromMaybe(false));
19301cb0ef41Sopenharmony_ci    USE(success);
19311cb0ef41Sopenharmony_ci  }
19321cb0ef41Sopenharmony_ci}
19331cb0ef41Sopenharmony_ci
19341cb0ef41Sopenharmony_cinamespace {
19351cb0ef41Sopenharmony_ciV8_INLINE void SetFunctionTablePlaceholder(Isolate* isolate,
19361cb0ef41Sopenharmony_ci                                           Handle<WasmInstanceObject> instance,
19371cb0ef41Sopenharmony_ci                                           Handle<WasmTableObject> table_object,
19381cb0ef41Sopenharmony_ci                                           uint32_t entry_index,
19391cb0ef41Sopenharmony_ci                                           uint32_t func_index) {
19401cb0ef41Sopenharmony_ci  const WasmModule* module = instance->module();
19411cb0ef41Sopenharmony_ci  const WasmFunction* function = &module->functions[func_index];
19421cb0ef41Sopenharmony_ci  MaybeHandle<WasmInternalFunction> wasm_internal_function =
19431cb0ef41Sopenharmony_ci      WasmInstanceObject::GetWasmInternalFunction(isolate, instance,
19441cb0ef41Sopenharmony_ci                                                  func_index);
19451cb0ef41Sopenharmony_ci  if (wasm_internal_function.is_null()) {
19461cb0ef41Sopenharmony_ci    // No JSFunction entry yet exists for this function. Create a {Tuple2}
19471cb0ef41Sopenharmony_ci    // holding the information to lazily allocate one.
19481cb0ef41Sopenharmony_ci    WasmTableObject::SetFunctionTablePlaceholder(
19491cb0ef41Sopenharmony_ci        isolate, table_object, entry_index, instance, func_index);
19501cb0ef41Sopenharmony_ci  } else {
19511cb0ef41Sopenharmony_ci    table_object->entries().set(entry_index,
19521cb0ef41Sopenharmony_ci                                *wasm_internal_function.ToHandleChecked());
19531cb0ef41Sopenharmony_ci  }
19541cb0ef41Sopenharmony_ci  WasmTableObject::UpdateDispatchTables(isolate, *table_object, entry_index,
19551cb0ef41Sopenharmony_ci                                        function, *instance);
19561cb0ef41Sopenharmony_ci}
19571cb0ef41Sopenharmony_ci
19581cb0ef41Sopenharmony_ciV8_INLINE void SetFunctionTableNullEntry(Isolate* isolate,
19591cb0ef41Sopenharmony_ci                                         Handle<WasmTableObject> table_object,
19601cb0ef41Sopenharmony_ci                                         uint32_t entry_index) {
19611cb0ef41Sopenharmony_ci  table_object->entries().set(entry_index, *isolate->factory()->null_value());
19621cb0ef41Sopenharmony_ci  WasmTableObject::ClearDispatchTables(isolate, table_object, entry_index);
19631cb0ef41Sopenharmony_ci}
19641cb0ef41Sopenharmony_ci}  // namespace
19651cb0ef41Sopenharmony_ci
19661cb0ef41Sopenharmony_civoid InstanceBuilder::InitializeNonDefaultableTables(
19671cb0ef41Sopenharmony_ci    Handle<WasmInstanceObject> instance) {
19681cb0ef41Sopenharmony_ci  for (int table_index = 0;
19691cb0ef41Sopenharmony_ci       table_index < static_cast<int>(module_->tables.size()); ++table_index) {
19701cb0ef41Sopenharmony_ci    const WasmTable& table = module_->tables[table_index];
19711cb0ef41Sopenharmony_ci    if (!table.type.is_defaultable()) {
19721cb0ef41Sopenharmony_ci      auto table_object = handle(
19731cb0ef41Sopenharmony_ci          WasmTableObject::cast(instance->tables().get(table_index)), isolate_);
19741cb0ef41Sopenharmony_ci      bool is_function_table = IsSubtypeOf(table.type, kWasmFuncRef, module_);
19751cb0ef41Sopenharmony_ci      if (is_function_table &&
19761cb0ef41Sopenharmony_ci          table.initial_value.kind() == ConstantExpression::kRefFunc) {
19771cb0ef41Sopenharmony_ci        for (uint32_t entry_index = 0; entry_index < table.initial_size;
19781cb0ef41Sopenharmony_ci             entry_index++) {
19791cb0ef41Sopenharmony_ci          SetFunctionTablePlaceholder(isolate_, instance, table_object,
19801cb0ef41Sopenharmony_ci                                      entry_index, table.initial_value.index());
19811cb0ef41Sopenharmony_ci        }
19821cb0ef41Sopenharmony_ci      } else if (is_function_table &&
19831cb0ef41Sopenharmony_ci                 table.initial_value.kind() == ConstantExpression::kRefNull) {
19841cb0ef41Sopenharmony_ci        for (uint32_t entry_index = 0; entry_index < table.initial_size;
19851cb0ef41Sopenharmony_ci             entry_index++) {
19861cb0ef41Sopenharmony_ci          SetFunctionTableNullEntry(isolate_, table_object, entry_index);
19871cb0ef41Sopenharmony_ci        }
19881cb0ef41Sopenharmony_ci      } else {
19891cb0ef41Sopenharmony_ci        WasmValue value =
19901cb0ef41Sopenharmony_ci            EvaluateInitExpression(&init_expr_zone_, table.initial_value,
19911cb0ef41Sopenharmony_ci                                   table.type, isolate_, instance, thrower_);
19921cb0ef41Sopenharmony_ci        if (thrower_->error()) return;
19931cb0ef41Sopenharmony_ci        for (uint32_t entry_index = 0; entry_index < table.initial_size;
19941cb0ef41Sopenharmony_ci             entry_index++) {
19951cb0ef41Sopenharmony_ci          WasmTableObject::Set(isolate_, table_object, entry_index,
19961cb0ef41Sopenharmony_ci                               value.to_ref());
19971cb0ef41Sopenharmony_ci        }
19981cb0ef41Sopenharmony_ci      }
19991cb0ef41Sopenharmony_ci  }
20001cb0ef41Sopenharmony_ci}
20011cb0ef41Sopenharmony_ci}
20021cb0ef41Sopenharmony_ci
20031cb0ef41Sopenharmony_cinamespace {
20041cb0ef41Sopenharmony_cibool LoadElemSegmentImpl(Zone* zone, Isolate* isolate,
20051cb0ef41Sopenharmony_ci                         Handle<WasmInstanceObject> instance,
20061cb0ef41Sopenharmony_ci                         Handle<WasmTableObject> table_object,
20071cb0ef41Sopenharmony_ci                         uint32_t table_index, uint32_t segment_index,
20081cb0ef41Sopenharmony_ci                         uint32_t dst, uint32_t src, size_t count) {
20091cb0ef41Sopenharmony_ci  DCHECK_LT(segment_index, instance->module()->elem_segments.size());
20101cb0ef41Sopenharmony_ci  auto& elem_segment = instance->module()->elem_segments[segment_index];
20111cb0ef41Sopenharmony_ci  // TODO(wasm): Move this functionality into wasm-objects, since it is used
20121cb0ef41Sopenharmony_ci  // for both instantiation and in the implementation of the table.init
20131cb0ef41Sopenharmony_ci  // instruction.
20141cb0ef41Sopenharmony_ci  if (!base::IsInBounds<uint64_t>(dst, count, table_object->current_length()) ||
20151cb0ef41Sopenharmony_ci      !base::IsInBounds<uint64_t>(
20161cb0ef41Sopenharmony_ci          src, count,
20171cb0ef41Sopenharmony_ci          instance->dropped_elem_segments()[segment_index] == 0
20181cb0ef41Sopenharmony_ci              ? elem_segment.entries.size()
20191cb0ef41Sopenharmony_ci              : 0)) {
20201cb0ef41Sopenharmony_ci    return false;
20211cb0ef41Sopenharmony_ci  }
20221cb0ef41Sopenharmony_ci
20231cb0ef41Sopenharmony_ci  bool is_function_table =
20241cb0ef41Sopenharmony_ci      IsSubtypeOf(table_object->type(), kWasmFuncRef, instance->module());
20251cb0ef41Sopenharmony_ci
20261cb0ef41Sopenharmony_ci  ErrorThrower thrower(isolate, "LoadElemSegment");
20271cb0ef41Sopenharmony_ci
20281cb0ef41Sopenharmony_ci  for (size_t i = 0; i < count; ++i) {
20291cb0ef41Sopenharmony_ci    ConstantExpression entry = elem_segment.entries[src + i];
20301cb0ef41Sopenharmony_ci    int entry_index = static_cast<int>(dst + i);
20311cb0ef41Sopenharmony_ci    if (is_function_table && entry.kind() == ConstantExpression::kRefFunc) {
20321cb0ef41Sopenharmony_ci      SetFunctionTablePlaceholder(isolate, instance, table_object, entry_index,
20331cb0ef41Sopenharmony_ci                                  entry.index());
20341cb0ef41Sopenharmony_ci    } else if (is_function_table &&
20351cb0ef41Sopenharmony_ci               entry.kind() == ConstantExpression::kRefNull) {
20361cb0ef41Sopenharmony_ci      SetFunctionTableNullEntry(isolate, table_object, entry_index);
20371cb0ef41Sopenharmony_ci    } else {
20381cb0ef41Sopenharmony_ci      WasmValue value = EvaluateInitExpression(zone, entry, elem_segment.type,
20391cb0ef41Sopenharmony_ci                                               isolate, instance, &thrower);
20401cb0ef41Sopenharmony_ci      if (thrower.error()) return false;
20411cb0ef41Sopenharmony_ci      WasmTableObject::Set(isolate, table_object, entry_index, value.to_ref());
20421cb0ef41Sopenharmony_ci    }
20431cb0ef41Sopenharmony_ci  }
20441cb0ef41Sopenharmony_ci  return true;
20451cb0ef41Sopenharmony_ci}
20461cb0ef41Sopenharmony_ci}  // namespace
20471cb0ef41Sopenharmony_ci
20481cb0ef41Sopenharmony_civoid InstanceBuilder::LoadTableSegments(Handle<WasmInstanceObject> instance) {
20491cb0ef41Sopenharmony_ci  for (uint32_t segment_index = 0;
20501cb0ef41Sopenharmony_ci       segment_index < module_->elem_segments.size(); ++segment_index) {
20511cb0ef41Sopenharmony_ci    auto& elem_segment = instance->module()->elem_segments[segment_index];
20521cb0ef41Sopenharmony_ci    // Passive segments are not copied during instantiation.
20531cb0ef41Sopenharmony_ci    if (elem_segment.status != WasmElemSegment::kStatusActive) continue;
20541cb0ef41Sopenharmony_ci
20551cb0ef41Sopenharmony_ci    uint32_t table_index = elem_segment.table_index;
20561cb0ef41Sopenharmony_ci    uint32_t dst =
20571cb0ef41Sopenharmony_ci        EvaluateInitExpression(&init_expr_zone_, elem_segment.offset, kWasmI32,
20581cb0ef41Sopenharmony_ci                               isolate_, instance, thrower_)
20591cb0ef41Sopenharmony_ci            .to_u32();
20601cb0ef41Sopenharmony_ci    if (thrower_->error()) return;
20611cb0ef41Sopenharmony_ci    uint32_t src = 0;
20621cb0ef41Sopenharmony_ci    size_t count = elem_segment.entries.size();
20631cb0ef41Sopenharmony_ci
20641cb0ef41Sopenharmony_ci    bool success = LoadElemSegmentImpl(
20651cb0ef41Sopenharmony_ci        &init_expr_zone_, isolate_, instance,
20661cb0ef41Sopenharmony_ci        handle(WasmTableObject::cast(
20671cb0ef41Sopenharmony_ci                   instance->tables().get(elem_segment.table_index)),
20681cb0ef41Sopenharmony_ci               isolate_),
20691cb0ef41Sopenharmony_ci        table_index, segment_index, dst, src, count);
20701cb0ef41Sopenharmony_ci    // Set the active segments to being already dropped, since table.init on
20711cb0ef41Sopenharmony_ci    // a dropped passive segment and an active segment have the same behavior.
20721cb0ef41Sopenharmony_ci    instance->dropped_elem_segments()[segment_index] = 1;
20731cb0ef41Sopenharmony_ci    if (!success) {
20741cb0ef41Sopenharmony_ci      thrower_->RuntimeError("table initializer is out of bounds");
20751cb0ef41Sopenharmony_ci      return;
20761cb0ef41Sopenharmony_ci    }
20771cb0ef41Sopenharmony_ci  }
20781cb0ef41Sopenharmony_ci}
20791cb0ef41Sopenharmony_ci
20801cb0ef41Sopenharmony_civoid InstanceBuilder::InitializeTags(Handle<WasmInstanceObject> instance) {
20811cb0ef41Sopenharmony_ci  Handle<FixedArray> tags_table(instance->tags_table(), isolate_);
20821cb0ef41Sopenharmony_ci  for (int index = 0; index < tags_table->length(); ++index) {
20831cb0ef41Sopenharmony_ci    if (!tags_table->get(index).IsUndefined(isolate_)) continue;
20841cb0ef41Sopenharmony_ci    Handle<WasmExceptionTag> tag = WasmExceptionTag::New(isolate_, index);
20851cb0ef41Sopenharmony_ci    tags_table->set(index, *tag);
20861cb0ef41Sopenharmony_ci  }
20871cb0ef41Sopenharmony_ci}
20881cb0ef41Sopenharmony_ci
20891cb0ef41Sopenharmony_cibool LoadElemSegment(Isolate* isolate, Handle<WasmInstanceObject> instance,
20901cb0ef41Sopenharmony_ci                     uint32_t table_index, uint32_t segment_index, uint32_t dst,
20911cb0ef41Sopenharmony_ci                     uint32_t src, uint32_t count) {
20921cb0ef41Sopenharmony_ci  AccountingAllocator allocator;
20931cb0ef41Sopenharmony_ci  // This {Zone} will be used only by the temporary WasmFullDecoder allocated
20941cb0ef41Sopenharmony_ci  // down the line from this call. Therefore it is safe to stack-allocate it
20951cb0ef41Sopenharmony_ci  // here.
20961cb0ef41Sopenharmony_ci  Zone zone(&allocator, "LoadElemSegment");
20971cb0ef41Sopenharmony_ci  return LoadElemSegmentImpl(
20981cb0ef41Sopenharmony_ci      &zone, isolate, instance,
20991cb0ef41Sopenharmony_ci      handle(WasmTableObject::cast(instance->tables().get(table_index)),
21001cb0ef41Sopenharmony_ci             isolate),
21011cb0ef41Sopenharmony_ci      table_index, segment_index, dst, src, count);
21021cb0ef41Sopenharmony_ci}
21031cb0ef41Sopenharmony_ci
21041cb0ef41Sopenharmony_ci}  // namespace wasm
21051cb0ef41Sopenharmony_ci}  // namespace internal
21061cb0ef41Sopenharmony_ci}  // namespace v8
21071cb0ef41Sopenharmony_ci
21081cb0ef41Sopenharmony_ci#undef TRACE
2109