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// This implementation is originally from
61cb0ef41Sopenharmony_ci// https://github.com/WebAssembly/wasm-c-api/:
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci// Copyright 2019 Andreas Rossberg
91cb0ef41Sopenharmony_ci//
101cb0ef41Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
111cb0ef41Sopenharmony_ci// you may not use this file except in compliance with the License.
121cb0ef41Sopenharmony_ci// You may obtain a copy of the License at
131cb0ef41Sopenharmony_ci//
141cb0ef41Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
151cb0ef41Sopenharmony_ci//
161cb0ef41Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
171cb0ef41Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
181cb0ef41Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
191cb0ef41Sopenharmony_ci// See the License for the specific language governing permissions and
201cb0ef41Sopenharmony_ci// limitations under the License.
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci#include "src/wasm/c-api.h"
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ci#include <cstring>
251cb0ef41Sopenharmony_ci#include <iomanip>
261cb0ef41Sopenharmony_ci#include <iostream>
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ci#include "include/libplatform/libplatform.h"
291cb0ef41Sopenharmony_ci#include "include/v8-initialization.h"
301cb0ef41Sopenharmony_ci#include "src/api/api-inl.h"
311cb0ef41Sopenharmony_ci#include "src/base/platform/wrappers.h"
321cb0ef41Sopenharmony_ci#include "src/builtins/builtins.h"
331cb0ef41Sopenharmony_ci#include "src/compiler/wasm-compiler.h"
341cb0ef41Sopenharmony_ci#include "src/objects/call-site-info-inl.h"
351cb0ef41Sopenharmony_ci#include "src/objects/js-collection-inl.h"
361cb0ef41Sopenharmony_ci#include "src/objects/managed-inl.h"
371cb0ef41Sopenharmony_ci#include "src/wasm/leb-helper.h"
381cb0ef41Sopenharmony_ci#include "src/wasm/module-instantiate.h"
391cb0ef41Sopenharmony_ci#include "src/wasm/wasm-arguments.h"
401cb0ef41Sopenharmony_ci#include "src/wasm/wasm-constants.h"
411cb0ef41Sopenharmony_ci#include "src/wasm/wasm-engine.h"
421cb0ef41Sopenharmony_ci#include "src/wasm/wasm-objects.h"
431cb0ef41Sopenharmony_ci#include "src/wasm/wasm-result.h"
441cb0ef41Sopenharmony_ci#include "src/wasm/wasm-serialization.h"
451cb0ef41Sopenharmony_ci#include "third_party/wasm-api/wasm.h"
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci#ifdef WASM_API_DEBUG
481cb0ef41Sopenharmony_ci#error "WASM_API_DEBUG is unsupported"
491cb0ef41Sopenharmony_ci#endif
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci// If you want counters support (what --dump-counters does for the d8 shell),
521cb0ef41Sopenharmony_ci// then set this to 1 (in here, or via -DDUMP_COUNTERS=1 compiler argument).
531cb0ef41Sopenharmony_ci#define DUMP_COUNTERS 0
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_cinamespace wasm {
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_cinamespace {
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ciauto ReadLebU64(const byte_t** pos) -> uint64_t {
601cb0ef41Sopenharmony_ci  uint64_t n = 0;
611cb0ef41Sopenharmony_ci  uint64_t shift = 0;
621cb0ef41Sopenharmony_ci  byte_t b;
631cb0ef41Sopenharmony_ci  do {
641cb0ef41Sopenharmony_ci    b = **pos;
651cb0ef41Sopenharmony_ci    (*pos)++;
661cb0ef41Sopenharmony_ci    n += (b & 0x7f) << shift;
671cb0ef41Sopenharmony_ci    shift += 7;
681cb0ef41Sopenharmony_ci  } while ((b & 0x80) != 0);
691cb0ef41Sopenharmony_ci  return n;
701cb0ef41Sopenharmony_ci}
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ciValKind V8ValueTypeToWasm(i::wasm::ValueType v8_valtype) {
731cb0ef41Sopenharmony_ci  switch (v8_valtype.kind()) {
741cb0ef41Sopenharmony_ci    case i::wasm::kI32:
751cb0ef41Sopenharmony_ci      return I32;
761cb0ef41Sopenharmony_ci    case i::wasm::kI64:
771cb0ef41Sopenharmony_ci      return I64;
781cb0ef41Sopenharmony_ci    case i::wasm::kF32:
791cb0ef41Sopenharmony_ci      return F32;
801cb0ef41Sopenharmony_ci    case i::wasm::kF64:
811cb0ef41Sopenharmony_ci      return F64;
821cb0ef41Sopenharmony_ci    case i::wasm::kRef:
831cb0ef41Sopenharmony_ci    case i::wasm::kOptRef:
841cb0ef41Sopenharmony_ci      switch (v8_valtype.heap_representation()) {
851cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kFunc:
861cb0ef41Sopenharmony_ci          return FUNCREF;
871cb0ef41Sopenharmony_ci        case i::wasm::HeapType::kAny:
881cb0ef41Sopenharmony_ci          return ANYREF;
891cb0ef41Sopenharmony_ci        default:
901cb0ef41Sopenharmony_ci          // TODO(wasm+): support new value types
911cb0ef41Sopenharmony_ci          UNREACHABLE();
921cb0ef41Sopenharmony_ci      }
931cb0ef41Sopenharmony_ci    default:
941cb0ef41Sopenharmony_ci      // TODO(wasm+): support new value types
951cb0ef41Sopenharmony_ci      UNREACHABLE();
961cb0ef41Sopenharmony_ci  }
971cb0ef41Sopenharmony_ci}
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_cii::wasm::ValueType WasmValKindToV8(ValKind kind) {
1001cb0ef41Sopenharmony_ci  switch (kind) {
1011cb0ef41Sopenharmony_ci    case I32:
1021cb0ef41Sopenharmony_ci      return i::wasm::kWasmI32;
1031cb0ef41Sopenharmony_ci    case I64:
1041cb0ef41Sopenharmony_ci      return i::wasm::kWasmI64;
1051cb0ef41Sopenharmony_ci    case F32:
1061cb0ef41Sopenharmony_ci      return i::wasm::kWasmF32;
1071cb0ef41Sopenharmony_ci    case F64:
1081cb0ef41Sopenharmony_ci      return i::wasm::kWasmF64;
1091cb0ef41Sopenharmony_ci    case FUNCREF:
1101cb0ef41Sopenharmony_ci      return i::wasm::kWasmFuncRef;
1111cb0ef41Sopenharmony_ci    case ANYREF:
1121cb0ef41Sopenharmony_ci      return i::wasm::kWasmAnyRef;
1131cb0ef41Sopenharmony_ci    default:
1141cb0ef41Sopenharmony_ci      // TODO(wasm+): support new value types
1151cb0ef41Sopenharmony_ci      UNREACHABLE();
1161cb0ef41Sopenharmony_ci  }
1171cb0ef41Sopenharmony_ci}
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ciName GetNameFromWireBytes(const i::wasm::WireBytesRef& ref,
1201cb0ef41Sopenharmony_ci                          const v8::base::Vector<const uint8_t>& wire_bytes) {
1211cb0ef41Sopenharmony_ci  DCHECK_LE(ref.offset(), wire_bytes.length());
1221cb0ef41Sopenharmony_ci  DCHECK_LE(ref.end_offset(), wire_bytes.length());
1231cb0ef41Sopenharmony_ci  if (ref.length() == 0) return Name::make();
1241cb0ef41Sopenharmony_ci  Name name = Name::make_uninitialized(ref.length());
1251cb0ef41Sopenharmony_ci  std::memcpy(name.get(), wire_bytes.begin() + ref.offset(), ref.length());
1261cb0ef41Sopenharmony_ci  return name;
1271cb0ef41Sopenharmony_ci}
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ciown<FuncType> FunctionSigToFuncType(const i::wasm::FunctionSig* sig) {
1301cb0ef41Sopenharmony_ci  size_t param_count = sig->parameter_count();
1311cb0ef41Sopenharmony_ci  ownvec<ValType> params = ownvec<ValType>::make_uninitialized(param_count);
1321cb0ef41Sopenharmony_ci  for (size_t i = 0; i < param_count; i++) {
1331cb0ef41Sopenharmony_ci    params[i] = ValType::make(V8ValueTypeToWasm(sig->GetParam(i)));
1341cb0ef41Sopenharmony_ci  }
1351cb0ef41Sopenharmony_ci  size_t return_count = sig->return_count();
1361cb0ef41Sopenharmony_ci  ownvec<ValType> results = ownvec<ValType>::make_uninitialized(return_count);
1371cb0ef41Sopenharmony_ci  for (size_t i = 0; i < return_count; i++) {
1381cb0ef41Sopenharmony_ci    results[i] = ValType::make(V8ValueTypeToWasm(sig->GetReturn(i)));
1391cb0ef41Sopenharmony_ci  }
1401cb0ef41Sopenharmony_ci  return FuncType::make(std::move(params), std::move(results));
1411cb0ef41Sopenharmony_ci}
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ciown<ExternType> GetImportExportType(const i::wasm::WasmModule* module,
1441cb0ef41Sopenharmony_ci                                    const i::wasm::ImportExportKindCode kind,
1451cb0ef41Sopenharmony_ci                                    const uint32_t index) {
1461cb0ef41Sopenharmony_ci  switch (kind) {
1471cb0ef41Sopenharmony_ci    case i::wasm::kExternalFunction: {
1481cb0ef41Sopenharmony_ci      return FunctionSigToFuncType(module->functions[index].sig);
1491cb0ef41Sopenharmony_ci    }
1501cb0ef41Sopenharmony_ci    case i::wasm::kExternalTable: {
1511cb0ef41Sopenharmony_ci      const i::wasm::WasmTable& table = module->tables[index];
1521cb0ef41Sopenharmony_ci      own<ValType> elem = ValType::make(V8ValueTypeToWasm(table.type));
1531cb0ef41Sopenharmony_ci      Limits limits(table.initial_size,
1541cb0ef41Sopenharmony_ci                    table.has_maximum_size ? table.maximum_size : -1);
1551cb0ef41Sopenharmony_ci      return TableType::make(std::move(elem), limits);
1561cb0ef41Sopenharmony_ci    }
1571cb0ef41Sopenharmony_ci    case i::wasm::kExternalMemory: {
1581cb0ef41Sopenharmony_ci      DCHECK(module->has_memory);
1591cb0ef41Sopenharmony_ci      Limits limits(module->initial_pages,
1601cb0ef41Sopenharmony_ci                    module->has_maximum_pages ? module->maximum_pages : -1);
1611cb0ef41Sopenharmony_ci      return MemoryType::make(limits);
1621cb0ef41Sopenharmony_ci    }
1631cb0ef41Sopenharmony_ci    case i::wasm::kExternalGlobal: {
1641cb0ef41Sopenharmony_ci      const i::wasm::WasmGlobal& global = module->globals[index];
1651cb0ef41Sopenharmony_ci      own<ValType> content = ValType::make(V8ValueTypeToWasm(global.type));
1661cb0ef41Sopenharmony_ci      Mutability mutability = global.mutability ? VAR : CONST;
1671cb0ef41Sopenharmony_ci      return GlobalType::make(std::move(content), mutability);
1681cb0ef41Sopenharmony_ci    }
1691cb0ef41Sopenharmony_ci    case i::wasm::kExternalTag:
1701cb0ef41Sopenharmony_ci      UNREACHABLE();
1711cb0ef41Sopenharmony_ci  }
1721cb0ef41Sopenharmony_ci}
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_ci}  // namespace
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ci/// BEGIN FILE wasm-v8.cc
1771cb0ef41Sopenharmony_ci
1781cb0ef41Sopenharmony_ci///////////////////////////////////////////////////////////////////////////////
1791cb0ef41Sopenharmony_ci// Auxiliaries
1801cb0ef41Sopenharmony_ci
1811cb0ef41Sopenharmony_ci[[noreturn]] void WASM_UNIMPLEMENTED(const char* s) {
1821cb0ef41Sopenharmony_ci  std::cerr << "Wasm API: " << s << " not supported yet!\n";
1831cb0ef41Sopenharmony_ci  exit(1);
1841cb0ef41Sopenharmony_ci}
1851cb0ef41Sopenharmony_ci
1861cb0ef41Sopenharmony_citemplate <class T>
1871cb0ef41Sopenharmony_civoid ignore(T) {}
1881cb0ef41Sopenharmony_ci
1891cb0ef41Sopenharmony_citemplate <class C>
1901cb0ef41Sopenharmony_cistruct implement;
1911cb0ef41Sopenharmony_ci
1921cb0ef41Sopenharmony_citemplate <class C>
1931cb0ef41Sopenharmony_ciauto impl(C* x) -> typename implement<C>::type* {
1941cb0ef41Sopenharmony_ci  return reinterpret_cast<typename implement<C>::type*>(x);
1951cb0ef41Sopenharmony_ci}
1961cb0ef41Sopenharmony_ci
1971cb0ef41Sopenharmony_citemplate <class C>
1981cb0ef41Sopenharmony_ciauto impl(const C* x) -> const typename implement<C>::type* {
1991cb0ef41Sopenharmony_ci  return reinterpret_cast<const typename implement<C>::type*>(x);
2001cb0ef41Sopenharmony_ci}
2011cb0ef41Sopenharmony_ci
2021cb0ef41Sopenharmony_citemplate <class C>
2031cb0ef41Sopenharmony_ciauto seal(typename implement<C>::type* x) -> C* {
2041cb0ef41Sopenharmony_ci  return reinterpret_cast<C*>(x);
2051cb0ef41Sopenharmony_ci}
2061cb0ef41Sopenharmony_ci
2071cb0ef41Sopenharmony_citemplate <class C>
2081cb0ef41Sopenharmony_ciauto seal(const typename implement<C>::type* x) -> const C* {
2091cb0ef41Sopenharmony_ci  return reinterpret_cast<const C*>(x);
2101cb0ef41Sopenharmony_ci}
2111cb0ef41Sopenharmony_ci
2121cb0ef41Sopenharmony_ci///////////////////////////////////////////////////////////////////////////////
2131cb0ef41Sopenharmony_ci// Runtime Environment
2141cb0ef41Sopenharmony_ci
2151cb0ef41Sopenharmony_ci// Configuration
2161cb0ef41Sopenharmony_ci
2171cb0ef41Sopenharmony_cistruct ConfigImpl {};
2181cb0ef41Sopenharmony_ci
2191cb0ef41Sopenharmony_citemplate <>
2201cb0ef41Sopenharmony_cistruct implement<Config> {
2211cb0ef41Sopenharmony_ci  using type = ConfigImpl;
2221cb0ef41Sopenharmony_ci};
2231cb0ef41Sopenharmony_ci
2241cb0ef41Sopenharmony_ciConfig::~Config() { impl(this)->~ConfigImpl(); }
2251cb0ef41Sopenharmony_ci
2261cb0ef41Sopenharmony_civoid Config::operator delete(void* p) { ::operator delete(p); }
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_ciauto Config::make() -> own<Config> {
2291cb0ef41Sopenharmony_ci  return own<Config>(seal<Config>(new (std::nothrow) ConfigImpl()));
2301cb0ef41Sopenharmony_ci}
2311cb0ef41Sopenharmony_ci
2321cb0ef41Sopenharmony_ci// Engine
2331cb0ef41Sopenharmony_ci
2341cb0ef41Sopenharmony_ci#if DUMP_COUNTERS
2351cb0ef41Sopenharmony_ciclass Counter {
2361cb0ef41Sopenharmony_ci public:
2371cb0ef41Sopenharmony_ci  static const int kMaxNameSize = 64;
2381cb0ef41Sopenharmony_ci  int32_t* Bind(const char* name, bool is_histogram) {
2391cb0ef41Sopenharmony_ci    int i;
2401cb0ef41Sopenharmony_ci    for (i = 0; i < kMaxNameSize - 1 && name[i]; i++) {
2411cb0ef41Sopenharmony_ci      name_[i] = static_cast<char>(name[i]);
2421cb0ef41Sopenharmony_ci    }
2431cb0ef41Sopenharmony_ci    name_[i] = '\0';
2441cb0ef41Sopenharmony_ci    is_histogram_ = is_histogram;
2451cb0ef41Sopenharmony_ci    return ptr();
2461cb0ef41Sopenharmony_ci  }
2471cb0ef41Sopenharmony_ci  int32_t* ptr() { return &count_; }
2481cb0ef41Sopenharmony_ci  int32_t count() { return count_; }
2491cb0ef41Sopenharmony_ci  int32_t sample_total() { return sample_total_; }
2501cb0ef41Sopenharmony_ci  bool is_histogram() { return is_histogram_; }
2511cb0ef41Sopenharmony_ci  void AddSample(int32_t sample) {
2521cb0ef41Sopenharmony_ci    count_++;
2531cb0ef41Sopenharmony_ci    sample_total_ += sample;
2541cb0ef41Sopenharmony_ci  }
2551cb0ef41Sopenharmony_ci
2561cb0ef41Sopenharmony_ci private:
2571cb0ef41Sopenharmony_ci  int32_t count_;
2581cb0ef41Sopenharmony_ci  int32_t sample_total_;
2591cb0ef41Sopenharmony_ci  bool is_histogram_;
2601cb0ef41Sopenharmony_ci  uint8_t name_[kMaxNameSize];
2611cb0ef41Sopenharmony_ci};
2621cb0ef41Sopenharmony_ci
2631cb0ef41Sopenharmony_ciclass CounterCollection {
2641cb0ef41Sopenharmony_ci public:
2651cb0ef41Sopenharmony_ci  CounterCollection() = default;
2661cb0ef41Sopenharmony_ci  Counter* GetNextCounter() {
2671cb0ef41Sopenharmony_ci    if (counters_in_use_ == kMaxCounters) return nullptr;
2681cb0ef41Sopenharmony_ci    return &counters_[counters_in_use_++];
2691cb0ef41Sopenharmony_ci  }
2701cb0ef41Sopenharmony_ci
2711cb0ef41Sopenharmony_ci private:
2721cb0ef41Sopenharmony_ci  static const unsigned kMaxCounters = 512;
2731cb0ef41Sopenharmony_ci  uint32_t counters_in_use_{0};
2741cb0ef41Sopenharmony_ci  Counter counters_[kMaxCounters];
2751cb0ef41Sopenharmony_ci};
2761cb0ef41Sopenharmony_ci
2771cb0ef41Sopenharmony_ciusing CounterMap = std::unordered_map<std::string, Counter*>;
2781cb0ef41Sopenharmony_ci
2791cb0ef41Sopenharmony_ci#endif
2801cb0ef41Sopenharmony_ci
2811cb0ef41Sopenharmony_cistruct EngineImpl {
2821cb0ef41Sopenharmony_ci  static bool created;
2831cb0ef41Sopenharmony_ci
2841cb0ef41Sopenharmony_ci  std::unique_ptr<v8::Platform> platform;
2851cb0ef41Sopenharmony_ci
2861cb0ef41Sopenharmony_ci#if DUMP_COUNTERS
2871cb0ef41Sopenharmony_ci  static CounterCollection counters_;
2881cb0ef41Sopenharmony_ci  static CounterMap* counter_map_;
2891cb0ef41Sopenharmony_ci
2901cb0ef41Sopenharmony_ci  static Counter* GetCounter(const char* name, bool is_histogram) {
2911cb0ef41Sopenharmony_ci    auto map_entry = counter_map_->find(name);
2921cb0ef41Sopenharmony_ci    Counter* counter =
2931cb0ef41Sopenharmony_ci        map_entry != counter_map_->end() ? map_entry->second : nullptr;
2941cb0ef41Sopenharmony_ci
2951cb0ef41Sopenharmony_ci    if (counter == nullptr) {
2961cb0ef41Sopenharmony_ci      counter = counters_.GetNextCounter();
2971cb0ef41Sopenharmony_ci      if (counter != nullptr) {
2981cb0ef41Sopenharmony_ci        (*counter_map_)[name] = counter;
2991cb0ef41Sopenharmony_ci        counter->Bind(name, is_histogram);
3001cb0ef41Sopenharmony_ci      }
3011cb0ef41Sopenharmony_ci    } else {
3021cb0ef41Sopenharmony_ci      DCHECK(counter->is_histogram() == is_histogram);
3031cb0ef41Sopenharmony_ci    }
3041cb0ef41Sopenharmony_ci    return counter;
3051cb0ef41Sopenharmony_ci  }
3061cb0ef41Sopenharmony_ci
3071cb0ef41Sopenharmony_ci  static int* LookupCounter(const char* name) {
3081cb0ef41Sopenharmony_ci    Counter* counter = GetCounter(name, false);
3091cb0ef41Sopenharmony_ci
3101cb0ef41Sopenharmony_ci    if (counter != nullptr) {
3111cb0ef41Sopenharmony_ci      return counter->ptr();
3121cb0ef41Sopenharmony_ci    } else {
3131cb0ef41Sopenharmony_ci      return nullptr;
3141cb0ef41Sopenharmony_ci    }
3151cb0ef41Sopenharmony_ci  }
3161cb0ef41Sopenharmony_ci
3171cb0ef41Sopenharmony_ci  static void* CreateHistogram(const char* name, int min, int max,
3181cb0ef41Sopenharmony_ci                               size_t buckets) {
3191cb0ef41Sopenharmony_ci    return GetCounter(name, true);
3201cb0ef41Sopenharmony_ci  }
3211cb0ef41Sopenharmony_ci
3221cb0ef41Sopenharmony_ci  static void AddHistogramSample(void* histogram, int sample) {
3231cb0ef41Sopenharmony_ci    Counter* counter = reinterpret_cast<Counter*>(histogram);
3241cb0ef41Sopenharmony_ci    counter->AddSample(sample);
3251cb0ef41Sopenharmony_ci  }
3261cb0ef41Sopenharmony_ci#endif
3271cb0ef41Sopenharmony_ci
3281cb0ef41Sopenharmony_ci  EngineImpl() {
3291cb0ef41Sopenharmony_ci    assert(!created);
3301cb0ef41Sopenharmony_ci    created = true;
3311cb0ef41Sopenharmony_ci#if DUMP_COUNTERS
3321cb0ef41Sopenharmony_ci    counter_map_ = new CounterMap();
3331cb0ef41Sopenharmony_ci#endif
3341cb0ef41Sopenharmony_ci  }
3351cb0ef41Sopenharmony_ci
3361cb0ef41Sopenharmony_ci  ~EngineImpl() {
3371cb0ef41Sopenharmony_ci#if DUMP_COUNTERS
3381cb0ef41Sopenharmony_ci    std::vector<std::pair<std::string, Counter*>> counters(
3391cb0ef41Sopenharmony_ci        counter_map_->begin(), counter_map_->end());
3401cb0ef41Sopenharmony_ci    std::sort(counters.begin(), counters.end());
3411cb0ef41Sopenharmony_ci    // Dump counters in formatted boxes.
3421cb0ef41Sopenharmony_ci    constexpr int kNameBoxSize = 64;
3431cb0ef41Sopenharmony_ci    constexpr int kValueBoxSize = 13;
3441cb0ef41Sopenharmony_ci    std::cout << "+" << std::string(kNameBoxSize, '-') << "+"
3451cb0ef41Sopenharmony_ci              << std::string(kValueBoxSize, '-') << "+\n";
3461cb0ef41Sopenharmony_ci    std::cout << "| Name" << std::string(kNameBoxSize - 5, ' ') << "| Value"
3471cb0ef41Sopenharmony_ci              << std::string(kValueBoxSize - 6, ' ') << "|\n";
3481cb0ef41Sopenharmony_ci    std::cout << "+" << std::string(kNameBoxSize, '-') << "+"
3491cb0ef41Sopenharmony_ci              << std::string(kValueBoxSize, '-') << "+\n";
3501cb0ef41Sopenharmony_ci    for (const auto& pair : counters) {
3511cb0ef41Sopenharmony_ci      std::string key = pair.first;
3521cb0ef41Sopenharmony_ci      Counter* counter = pair.second;
3531cb0ef41Sopenharmony_ci      if (counter->is_histogram()) {
3541cb0ef41Sopenharmony_ci        std::cout << "| c:" << std::setw(kNameBoxSize - 4) << std::left << key
3551cb0ef41Sopenharmony_ci                  << " | " << std::setw(kValueBoxSize - 2) << std::right
3561cb0ef41Sopenharmony_ci                  << counter->count() << " |\n";
3571cb0ef41Sopenharmony_ci        std::cout << "| t:" << std::setw(kNameBoxSize - 4) << std::left << key
3581cb0ef41Sopenharmony_ci                  << " | " << std::setw(kValueBoxSize - 2) << std::right
3591cb0ef41Sopenharmony_ci                  << counter->sample_total() << " |\n";
3601cb0ef41Sopenharmony_ci      } else {
3611cb0ef41Sopenharmony_ci        std::cout << "| " << std::setw(kNameBoxSize - 2) << std::left << key
3621cb0ef41Sopenharmony_ci                  << " | " << std::setw(kValueBoxSize - 2) << std::right
3631cb0ef41Sopenharmony_ci                  << counter->count() << " |\n";
3641cb0ef41Sopenharmony_ci      }
3651cb0ef41Sopenharmony_ci    }
3661cb0ef41Sopenharmony_ci    std::cout << "+" << std::string(kNameBoxSize, '-') << "+"
3671cb0ef41Sopenharmony_ci              << std::string(kValueBoxSize, '-') << "+\n";
3681cb0ef41Sopenharmony_ci    delete counter_map_;
3691cb0ef41Sopenharmony_ci#endif
3701cb0ef41Sopenharmony_ci    v8::V8::Dispose();
3711cb0ef41Sopenharmony_ci    v8::V8::DisposePlatform();
3721cb0ef41Sopenharmony_ci  }
3731cb0ef41Sopenharmony_ci};
3741cb0ef41Sopenharmony_ci
3751cb0ef41Sopenharmony_cibool EngineImpl::created = false;
3761cb0ef41Sopenharmony_ci
3771cb0ef41Sopenharmony_ci#if DUMP_COUNTERS
3781cb0ef41Sopenharmony_ciCounterCollection EngineImpl::counters_;
3791cb0ef41Sopenharmony_ciCounterMap* EngineImpl::counter_map_;
3801cb0ef41Sopenharmony_ci#endif
3811cb0ef41Sopenharmony_ci
3821cb0ef41Sopenharmony_citemplate <>
3831cb0ef41Sopenharmony_cistruct implement<Engine> {
3841cb0ef41Sopenharmony_ci  using type = EngineImpl;
3851cb0ef41Sopenharmony_ci};
3861cb0ef41Sopenharmony_ci
3871cb0ef41Sopenharmony_ciEngine::~Engine() { impl(this)->~EngineImpl(); }
3881cb0ef41Sopenharmony_ci
3891cb0ef41Sopenharmony_civoid Engine::operator delete(void* p) { ::operator delete(p); }
3901cb0ef41Sopenharmony_ci
3911cb0ef41Sopenharmony_ciauto Engine::make(own<Config>&& config) -> own<Engine> {
3921cb0ef41Sopenharmony_ci  auto engine = new (std::nothrow) EngineImpl;
3931cb0ef41Sopenharmony_ci  if (!engine) return own<Engine>();
3941cb0ef41Sopenharmony_ci  engine->platform = v8::platform::NewDefaultPlatform();
3951cb0ef41Sopenharmony_ci  v8::V8::InitializePlatform(engine->platform.get());
3961cb0ef41Sopenharmony_ci#ifdef V8_SANDBOX
3971cb0ef41Sopenharmony_ci  if (!v8::V8::InitializeSandbox()) {
3981cb0ef41Sopenharmony_ci    FATAL("Could not initialize the sandbox");
3991cb0ef41Sopenharmony_ci  }
4001cb0ef41Sopenharmony_ci#endif
4011cb0ef41Sopenharmony_ci  v8::V8::Initialize();
4021cb0ef41Sopenharmony_ci  // The commandline flags get loaded in V8::Initialize(), so we can override
4031cb0ef41Sopenharmony_ci  // the flag values only afterwards.
4041cb0ef41Sopenharmony_ci  i::FLAG_expose_gc = true;
4051cb0ef41Sopenharmony_ci  // We disable dynamic tiering because it interferes with serialization. We
4061cb0ef41Sopenharmony_ci  // only serialize optimized code, but with dynamic tiering not all code gets
4071cb0ef41Sopenharmony_ci  // optimized. It is then unclear what we should serialize in the first place.
4081cb0ef41Sopenharmony_ci  i::FLAG_wasm_dynamic_tiering = false;
4091cb0ef41Sopenharmony_ci  // We disable speculative inlining, because speculative inlining depends on
4101cb0ef41Sopenharmony_ci  // dynamic tiering.
4111cb0ef41Sopenharmony_ci  i::FLAG_wasm_speculative_inlining = false;
4121cb0ef41Sopenharmony_ci  return make_own(seal<Engine>(engine));
4131cb0ef41Sopenharmony_ci}
4141cb0ef41Sopenharmony_ci
4151cb0ef41Sopenharmony_ci// This should be called somewhat regularly, especially on potentially hot
4161cb0ef41Sopenharmony_ci// sections of pure C++ execution. To achieve that, we call it on API entry
4171cb0ef41Sopenharmony_ci// points that heap-allocate but don't call into generated code.
4181cb0ef41Sopenharmony_ci// For example, finalization of incremental marking is relying on it.
4191cb0ef41Sopenharmony_civoid CheckAndHandleInterrupts(i::Isolate* isolate) {
4201cb0ef41Sopenharmony_ci  i::StackLimitCheck check(isolate);
4211cb0ef41Sopenharmony_ci  if (check.InterruptRequested()) {
4221cb0ef41Sopenharmony_ci    isolate->stack_guard()->HandleInterrupts();
4231cb0ef41Sopenharmony_ci  }
4241cb0ef41Sopenharmony_ci}
4251cb0ef41Sopenharmony_ci
4261cb0ef41Sopenharmony_ci// Stores
4271cb0ef41Sopenharmony_ci
4281cb0ef41Sopenharmony_ciStoreImpl::~StoreImpl() {
4291cb0ef41Sopenharmony_ci#ifdef DEBUG
4301cb0ef41Sopenharmony_ci  reinterpret_cast<i::Isolate*>(isolate_)->heap()->PreciseCollectAllGarbage(
4311cb0ef41Sopenharmony_ci      i::Heap::kForcedGC, i::GarbageCollectionReason::kTesting,
4321cb0ef41Sopenharmony_ci      v8::kNoGCCallbackFlags);
4331cb0ef41Sopenharmony_ci#endif
4341cb0ef41Sopenharmony_ci  context()->Exit();
4351cb0ef41Sopenharmony_ci  isolate_->Dispose();
4361cb0ef41Sopenharmony_ci  delete create_params_.array_buffer_allocator;
4371cb0ef41Sopenharmony_ci}
4381cb0ef41Sopenharmony_ci
4391cb0ef41Sopenharmony_cistruct ManagedData {
4401cb0ef41Sopenharmony_ci  ManagedData(void* info, void (*finalizer)(void*))
4411cb0ef41Sopenharmony_ci      : info(info), finalizer(finalizer) {}
4421cb0ef41Sopenharmony_ci
4431cb0ef41Sopenharmony_ci  ~ManagedData() {
4441cb0ef41Sopenharmony_ci    if (finalizer) (*finalizer)(info);
4451cb0ef41Sopenharmony_ci  }
4461cb0ef41Sopenharmony_ci
4471cb0ef41Sopenharmony_ci  void* info;
4481cb0ef41Sopenharmony_ci  void (*finalizer)(void*);
4491cb0ef41Sopenharmony_ci};
4501cb0ef41Sopenharmony_ci
4511cb0ef41Sopenharmony_civoid StoreImpl::SetHostInfo(i::Handle<i::Object> object, void* info,
4521cb0ef41Sopenharmony_ci                            void (*finalizer)(void*)) {
4531cb0ef41Sopenharmony_ci  i::HandleScope scope(i_isolate());
4541cb0ef41Sopenharmony_ci  // Ideally we would specify the total size kept alive by {info} here,
4551cb0ef41Sopenharmony_ci  // but all we get from the embedder is a {void*}, so our best estimate
4561cb0ef41Sopenharmony_ci  // is the size of the metadata.
4571cb0ef41Sopenharmony_ci  size_t estimated_size = sizeof(ManagedData);
4581cb0ef41Sopenharmony_ci  i::Handle<i::Object> wrapper = i::Managed<ManagedData>::FromRawPtr(
4591cb0ef41Sopenharmony_ci      i_isolate(), estimated_size, new ManagedData(info, finalizer));
4601cb0ef41Sopenharmony_ci  int32_t hash = object->GetOrCreateHash(i_isolate()).value();
4611cb0ef41Sopenharmony_ci  i::JSWeakCollection::Set(host_info_map_, object, wrapper, hash);
4621cb0ef41Sopenharmony_ci}
4631cb0ef41Sopenharmony_ci
4641cb0ef41Sopenharmony_civoid* StoreImpl::GetHostInfo(i::Handle<i::Object> key) {
4651cb0ef41Sopenharmony_ci  i::Object raw =
4661cb0ef41Sopenharmony_ci      i::EphemeronHashTable::cast(host_info_map_->table()).Lookup(key);
4671cb0ef41Sopenharmony_ci  if (raw.IsTheHole(i_isolate())) return nullptr;
4681cb0ef41Sopenharmony_ci  return i::Managed<ManagedData>::cast(raw).raw()->info;
4691cb0ef41Sopenharmony_ci}
4701cb0ef41Sopenharmony_ci
4711cb0ef41Sopenharmony_citemplate <>
4721cb0ef41Sopenharmony_cistruct implement<Store> {
4731cb0ef41Sopenharmony_ci  using type = StoreImpl;
4741cb0ef41Sopenharmony_ci};
4751cb0ef41Sopenharmony_ci
4761cb0ef41Sopenharmony_ciStore::~Store() { impl(this)->~StoreImpl(); }
4771cb0ef41Sopenharmony_ci
4781cb0ef41Sopenharmony_civoid Store::operator delete(void* p) { ::operator delete(p); }
4791cb0ef41Sopenharmony_ci
4801cb0ef41Sopenharmony_ciauto Store::make(Engine*) -> own<Store> {
4811cb0ef41Sopenharmony_ci  auto store = make_own(new (std::nothrow) StoreImpl());
4821cb0ef41Sopenharmony_ci  if (!store) return own<Store>();
4831cb0ef41Sopenharmony_ci
4841cb0ef41Sopenharmony_ci  // Create isolate.
4851cb0ef41Sopenharmony_ci  store->create_params_.array_buffer_allocator =
4861cb0ef41Sopenharmony_ci      v8::ArrayBuffer::Allocator::NewDefaultAllocator();
4871cb0ef41Sopenharmony_ci#if DUMP_COUNTERS
4881cb0ef41Sopenharmony_ci  store->create_params_.counter_lookup_callback = EngineImpl::LookupCounter;
4891cb0ef41Sopenharmony_ci  store->create_params_.create_histogram_callback = EngineImpl::CreateHistogram;
4901cb0ef41Sopenharmony_ci  store->create_params_.add_histogram_sample_callback =
4911cb0ef41Sopenharmony_ci      EngineImpl::AddHistogramSample;
4921cb0ef41Sopenharmony_ci#endif
4931cb0ef41Sopenharmony_ci  v8::Isolate* isolate = v8::Isolate::New(store->create_params_);
4941cb0ef41Sopenharmony_ci  if (!isolate) return own<Store>();
4951cb0ef41Sopenharmony_ci  store->isolate_ = isolate;
4961cb0ef41Sopenharmony_ci  isolate->SetData(0, store.get());
4971cb0ef41Sopenharmony_ci  // We intentionally do not call isolate->Enter() here, because that would
4981cb0ef41Sopenharmony_ci  // prevent embedders from using stores with overlapping but non-nested
4991cb0ef41Sopenharmony_ci  // lifetimes. The consequence is that Isolate::Current() is dysfunctional
5001cb0ef41Sopenharmony_ci  // and hence must not be called by anything reachable via this file.
5011cb0ef41Sopenharmony_ci
5021cb0ef41Sopenharmony_ci  {
5031cb0ef41Sopenharmony_ci    v8::HandleScope handle_scope(isolate);
5041cb0ef41Sopenharmony_ci
5051cb0ef41Sopenharmony_ci    // Create context.
5061cb0ef41Sopenharmony_ci    v8::Local<v8::Context> context = v8::Context::New(isolate);
5071cb0ef41Sopenharmony_ci    if (context.IsEmpty()) return own<Store>();
5081cb0ef41Sopenharmony_ci    context->Enter();  // The Exit() call is in ~StoreImpl.
5091cb0ef41Sopenharmony_ci    store->context_ = v8::Eternal<v8::Context>(isolate, context);
5101cb0ef41Sopenharmony_ci
5111cb0ef41Sopenharmony_ci    // Create weak map for Refs with host info.
5121cb0ef41Sopenharmony_ci    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5131cb0ef41Sopenharmony_ci    store->host_info_map_ = i_isolate->global_handles()->Create(
5141cb0ef41Sopenharmony_ci        *i_isolate->factory()->NewJSWeakMap());
5151cb0ef41Sopenharmony_ci  }
5161cb0ef41Sopenharmony_ci  // We want stack traces for traps.
5171cb0ef41Sopenharmony_ci  constexpr int kStackLimit = 10;
5181cb0ef41Sopenharmony_ci  isolate->SetCaptureStackTraceForUncaughtExceptions(true, kStackLimit,
5191cb0ef41Sopenharmony_ci                                                     v8::StackTrace::kOverview);
5201cb0ef41Sopenharmony_ci
5211cb0ef41Sopenharmony_ci  return make_own(seal<Store>(store.release()));
5221cb0ef41Sopenharmony_ci}
5231cb0ef41Sopenharmony_ci
5241cb0ef41Sopenharmony_ci///////////////////////////////////////////////////////////////////////////////
5251cb0ef41Sopenharmony_ci// Type Representations
5261cb0ef41Sopenharmony_ci
5271cb0ef41Sopenharmony_ci// Value Types
5281cb0ef41Sopenharmony_ci
5291cb0ef41Sopenharmony_cistruct ValTypeImpl {
5301cb0ef41Sopenharmony_ci  ValKind kind;
5311cb0ef41Sopenharmony_ci
5321cb0ef41Sopenharmony_ci  explicit ValTypeImpl(ValKind kind) : kind(kind) {}
5331cb0ef41Sopenharmony_ci};
5341cb0ef41Sopenharmony_ci
5351cb0ef41Sopenharmony_citemplate <>
5361cb0ef41Sopenharmony_cistruct implement<ValType> {
5371cb0ef41Sopenharmony_ci  using type = ValTypeImpl;
5381cb0ef41Sopenharmony_ci};
5391cb0ef41Sopenharmony_ci
5401cb0ef41Sopenharmony_ciValTypeImpl* valtype_i32 = new ValTypeImpl(I32);
5411cb0ef41Sopenharmony_ciValTypeImpl* valtype_i64 = new ValTypeImpl(I64);
5421cb0ef41Sopenharmony_ciValTypeImpl* valtype_f32 = new ValTypeImpl(F32);
5431cb0ef41Sopenharmony_ciValTypeImpl* valtype_f64 = new ValTypeImpl(F64);
5441cb0ef41Sopenharmony_ciValTypeImpl* valtype_externref = new ValTypeImpl(ANYREF);
5451cb0ef41Sopenharmony_ciValTypeImpl* valtype_funcref = new ValTypeImpl(FUNCREF);
5461cb0ef41Sopenharmony_ci
5471cb0ef41Sopenharmony_ciValType::~ValType() = default;
5481cb0ef41Sopenharmony_ci
5491cb0ef41Sopenharmony_civoid ValType::operator delete(void*) {}
5501cb0ef41Sopenharmony_ci
5511cb0ef41Sopenharmony_ciown<ValType> ValType::make(ValKind k) {
5521cb0ef41Sopenharmony_ci  ValTypeImpl* valtype;
5531cb0ef41Sopenharmony_ci  switch (k) {
5541cb0ef41Sopenharmony_ci    case I32:
5551cb0ef41Sopenharmony_ci      valtype = valtype_i32;
5561cb0ef41Sopenharmony_ci      break;
5571cb0ef41Sopenharmony_ci    case I64:
5581cb0ef41Sopenharmony_ci      valtype = valtype_i64;
5591cb0ef41Sopenharmony_ci      break;
5601cb0ef41Sopenharmony_ci    case F32:
5611cb0ef41Sopenharmony_ci      valtype = valtype_f32;
5621cb0ef41Sopenharmony_ci      break;
5631cb0ef41Sopenharmony_ci    case F64:
5641cb0ef41Sopenharmony_ci      valtype = valtype_f64;
5651cb0ef41Sopenharmony_ci      break;
5661cb0ef41Sopenharmony_ci    case ANYREF:
5671cb0ef41Sopenharmony_ci      valtype = valtype_externref;
5681cb0ef41Sopenharmony_ci      break;
5691cb0ef41Sopenharmony_ci    case FUNCREF:
5701cb0ef41Sopenharmony_ci      valtype = valtype_funcref;
5711cb0ef41Sopenharmony_ci      break;
5721cb0ef41Sopenharmony_ci    default:
5731cb0ef41Sopenharmony_ci      // TODO(wasm+): support new value types
5741cb0ef41Sopenharmony_ci      UNREACHABLE();
5751cb0ef41Sopenharmony_ci  }
5761cb0ef41Sopenharmony_ci  return own<ValType>(seal<ValType>(valtype));
5771cb0ef41Sopenharmony_ci}
5781cb0ef41Sopenharmony_ci
5791cb0ef41Sopenharmony_ciauto ValType::copy() const -> own<ValType> { return make(kind()); }
5801cb0ef41Sopenharmony_ci
5811cb0ef41Sopenharmony_ciauto ValType::kind() const -> ValKind { return impl(this)->kind; }
5821cb0ef41Sopenharmony_ci
5831cb0ef41Sopenharmony_ci// Extern Types
5841cb0ef41Sopenharmony_ci
5851cb0ef41Sopenharmony_cistruct ExternTypeImpl {
5861cb0ef41Sopenharmony_ci  ExternKind kind;
5871cb0ef41Sopenharmony_ci
5881cb0ef41Sopenharmony_ci  explicit ExternTypeImpl(ExternKind kind) : kind(kind) {}
5891cb0ef41Sopenharmony_ci  virtual ~ExternTypeImpl() = default;
5901cb0ef41Sopenharmony_ci};
5911cb0ef41Sopenharmony_ci
5921cb0ef41Sopenharmony_citemplate <>
5931cb0ef41Sopenharmony_cistruct implement<ExternType> {
5941cb0ef41Sopenharmony_ci  using type = ExternTypeImpl;
5951cb0ef41Sopenharmony_ci};
5961cb0ef41Sopenharmony_ci
5971cb0ef41Sopenharmony_ciExternType::~ExternType() { impl(this)->~ExternTypeImpl(); }
5981cb0ef41Sopenharmony_ci
5991cb0ef41Sopenharmony_civoid ExternType::operator delete(void* p) { ::operator delete(p); }
6001cb0ef41Sopenharmony_ci
6011cb0ef41Sopenharmony_ciauto ExternType::copy() const -> own<ExternType> {
6021cb0ef41Sopenharmony_ci  switch (kind()) {
6031cb0ef41Sopenharmony_ci    case EXTERN_FUNC:
6041cb0ef41Sopenharmony_ci      return func()->copy();
6051cb0ef41Sopenharmony_ci    case EXTERN_GLOBAL:
6061cb0ef41Sopenharmony_ci      return global()->copy();
6071cb0ef41Sopenharmony_ci    case EXTERN_TABLE:
6081cb0ef41Sopenharmony_ci      return table()->copy();
6091cb0ef41Sopenharmony_ci    case EXTERN_MEMORY:
6101cb0ef41Sopenharmony_ci      return memory()->copy();
6111cb0ef41Sopenharmony_ci  }
6121cb0ef41Sopenharmony_ci}
6131cb0ef41Sopenharmony_ci
6141cb0ef41Sopenharmony_ciauto ExternType::kind() const -> ExternKind { return impl(this)->kind; }
6151cb0ef41Sopenharmony_ci
6161cb0ef41Sopenharmony_ci// Function Types
6171cb0ef41Sopenharmony_ci
6181cb0ef41Sopenharmony_cistruct FuncTypeImpl : ExternTypeImpl {
6191cb0ef41Sopenharmony_ci  ownvec<ValType> params;
6201cb0ef41Sopenharmony_ci  ownvec<ValType> results;
6211cb0ef41Sopenharmony_ci
6221cb0ef41Sopenharmony_ci  FuncTypeImpl(ownvec<ValType>& params, ownvec<ValType>& results)
6231cb0ef41Sopenharmony_ci      : ExternTypeImpl(EXTERN_FUNC),
6241cb0ef41Sopenharmony_ci        params(std::move(params)),
6251cb0ef41Sopenharmony_ci        results(std::move(results)) {}
6261cb0ef41Sopenharmony_ci};
6271cb0ef41Sopenharmony_ci
6281cb0ef41Sopenharmony_citemplate <>
6291cb0ef41Sopenharmony_cistruct implement<FuncType> {
6301cb0ef41Sopenharmony_ci  using type = FuncTypeImpl;
6311cb0ef41Sopenharmony_ci};
6321cb0ef41Sopenharmony_ci
6331cb0ef41Sopenharmony_ciFuncType::~FuncType() = default;
6341cb0ef41Sopenharmony_ci
6351cb0ef41Sopenharmony_ciauto FuncType::make(ownvec<ValType>&& params, ownvec<ValType>&& results)
6361cb0ef41Sopenharmony_ci    -> own<FuncType> {
6371cb0ef41Sopenharmony_ci  return params && results
6381cb0ef41Sopenharmony_ci             ? own<FuncType>(seal<FuncType>(new (std::nothrow)
6391cb0ef41Sopenharmony_ci                                                FuncTypeImpl(params, results)))
6401cb0ef41Sopenharmony_ci             : own<FuncType>();
6411cb0ef41Sopenharmony_ci}
6421cb0ef41Sopenharmony_ci
6431cb0ef41Sopenharmony_ciauto FuncType::copy() const -> own<FuncType> {
6441cb0ef41Sopenharmony_ci  return make(params().deep_copy(), results().deep_copy());
6451cb0ef41Sopenharmony_ci}
6461cb0ef41Sopenharmony_ci
6471cb0ef41Sopenharmony_ciauto FuncType::params() const -> const ownvec<ValType>& {
6481cb0ef41Sopenharmony_ci  return impl(this)->params;
6491cb0ef41Sopenharmony_ci}
6501cb0ef41Sopenharmony_ci
6511cb0ef41Sopenharmony_ciauto FuncType::results() const -> const ownvec<ValType>& {
6521cb0ef41Sopenharmony_ci  return impl(this)->results;
6531cb0ef41Sopenharmony_ci}
6541cb0ef41Sopenharmony_ci
6551cb0ef41Sopenharmony_ciauto ExternType::func() -> FuncType* {
6561cb0ef41Sopenharmony_ci  return kind() == EXTERN_FUNC
6571cb0ef41Sopenharmony_ci             ? seal<FuncType>(static_cast<FuncTypeImpl*>(impl(this)))
6581cb0ef41Sopenharmony_ci             : nullptr;
6591cb0ef41Sopenharmony_ci}
6601cb0ef41Sopenharmony_ci
6611cb0ef41Sopenharmony_ciauto ExternType::func() const -> const FuncType* {
6621cb0ef41Sopenharmony_ci  return kind() == EXTERN_FUNC
6631cb0ef41Sopenharmony_ci             ? seal<FuncType>(static_cast<const FuncTypeImpl*>(impl(this)))
6641cb0ef41Sopenharmony_ci             : nullptr;
6651cb0ef41Sopenharmony_ci}
6661cb0ef41Sopenharmony_ci
6671cb0ef41Sopenharmony_ci// Global Types
6681cb0ef41Sopenharmony_ci
6691cb0ef41Sopenharmony_cistruct GlobalTypeImpl : ExternTypeImpl {
6701cb0ef41Sopenharmony_ci  own<ValType> content;
6711cb0ef41Sopenharmony_ci  Mutability mutability;
6721cb0ef41Sopenharmony_ci
6731cb0ef41Sopenharmony_ci  GlobalTypeImpl(own<ValType>& content, Mutability mutability)
6741cb0ef41Sopenharmony_ci      : ExternTypeImpl(EXTERN_GLOBAL),
6751cb0ef41Sopenharmony_ci        content(std::move(content)),
6761cb0ef41Sopenharmony_ci        mutability(mutability) {}
6771cb0ef41Sopenharmony_ci
6781cb0ef41Sopenharmony_ci  ~GlobalTypeImpl() override = default;
6791cb0ef41Sopenharmony_ci};
6801cb0ef41Sopenharmony_ci
6811cb0ef41Sopenharmony_citemplate <>
6821cb0ef41Sopenharmony_cistruct implement<GlobalType> {
6831cb0ef41Sopenharmony_ci  using type = GlobalTypeImpl;
6841cb0ef41Sopenharmony_ci};
6851cb0ef41Sopenharmony_ci
6861cb0ef41Sopenharmony_ciGlobalType::~GlobalType() = default;
6871cb0ef41Sopenharmony_ci
6881cb0ef41Sopenharmony_ciauto GlobalType::make(own<ValType>&& content, Mutability mutability)
6891cb0ef41Sopenharmony_ci    -> own<GlobalType> {
6901cb0ef41Sopenharmony_ci  return content ? own<GlobalType>(seal<GlobalType>(
6911cb0ef41Sopenharmony_ci                       new (std::nothrow) GlobalTypeImpl(content, mutability)))
6921cb0ef41Sopenharmony_ci                 : own<GlobalType>();
6931cb0ef41Sopenharmony_ci}
6941cb0ef41Sopenharmony_ci
6951cb0ef41Sopenharmony_ciauto GlobalType::copy() const -> own<GlobalType> {
6961cb0ef41Sopenharmony_ci  return make(content()->copy(), mutability());
6971cb0ef41Sopenharmony_ci}
6981cb0ef41Sopenharmony_ci
6991cb0ef41Sopenharmony_ciauto GlobalType::content() const -> const ValType* {
7001cb0ef41Sopenharmony_ci  return impl(this)->content.get();
7011cb0ef41Sopenharmony_ci}
7021cb0ef41Sopenharmony_ci
7031cb0ef41Sopenharmony_ciauto GlobalType::mutability() const -> Mutability {
7041cb0ef41Sopenharmony_ci  return impl(this)->mutability;
7051cb0ef41Sopenharmony_ci}
7061cb0ef41Sopenharmony_ci
7071cb0ef41Sopenharmony_ciauto ExternType::global() -> GlobalType* {
7081cb0ef41Sopenharmony_ci  return kind() == EXTERN_GLOBAL
7091cb0ef41Sopenharmony_ci             ? seal<GlobalType>(static_cast<GlobalTypeImpl*>(impl(this)))
7101cb0ef41Sopenharmony_ci             : nullptr;
7111cb0ef41Sopenharmony_ci}
7121cb0ef41Sopenharmony_ci
7131cb0ef41Sopenharmony_ciauto ExternType::global() const -> const GlobalType* {
7141cb0ef41Sopenharmony_ci  return kind() == EXTERN_GLOBAL
7151cb0ef41Sopenharmony_ci             ? seal<GlobalType>(static_cast<const GlobalTypeImpl*>(impl(this)))
7161cb0ef41Sopenharmony_ci             : nullptr;
7171cb0ef41Sopenharmony_ci}
7181cb0ef41Sopenharmony_ci
7191cb0ef41Sopenharmony_ci// Table Types
7201cb0ef41Sopenharmony_ci
7211cb0ef41Sopenharmony_cistruct TableTypeImpl : ExternTypeImpl {
7221cb0ef41Sopenharmony_ci  own<ValType> element;
7231cb0ef41Sopenharmony_ci  Limits limits;
7241cb0ef41Sopenharmony_ci
7251cb0ef41Sopenharmony_ci  TableTypeImpl(own<ValType>& element, Limits limits)
7261cb0ef41Sopenharmony_ci      : ExternTypeImpl(EXTERN_TABLE),
7271cb0ef41Sopenharmony_ci        element(std::move(element)),
7281cb0ef41Sopenharmony_ci        limits(limits) {}
7291cb0ef41Sopenharmony_ci
7301cb0ef41Sopenharmony_ci  ~TableTypeImpl() override = default;
7311cb0ef41Sopenharmony_ci};
7321cb0ef41Sopenharmony_ci
7331cb0ef41Sopenharmony_citemplate <>
7341cb0ef41Sopenharmony_cistruct implement<TableType> {
7351cb0ef41Sopenharmony_ci  using type = TableTypeImpl;
7361cb0ef41Sopenharmony_ci};
7371cb0ef41Sopenharmony_ci
7381cb0ef41Sopenharmony_ciTableType::~TableType() = default;
7391cb0ef41Sopenharmony_ci
7401cb0ef41Sopenharmony_ciauto TableType::make(own<ValType>&& element, Limits limits) -> own<TableType> {
7411cb0ef41Sopenharmony_ci  return element ? own<TableType>(seal<TableType>(
7421cb0ef41Sopenharmony_ci                       new (std::nothrow) TableTypeImpl(element, limits)))
7431cb0ef41Sopenharmony_ci                 : own<TableType>();
7441cb0ef41Sopenharmony_ci}
7451cb0ef41Sopenharmony_ci
7461cb0ef41Sopenharmony_ciauto TableType::copy() const -> own<TableType> {
7471cb0ef41Sopenharmony_ci  return make(element()->copy(), limits());
7481cb0ef41Sopenharmony_ci}
7491cb0ef41Sopenharmony_ci
7501cb0ef41Sopenharmony_ciauto TableType::element() const -> const ValType* {
7511cb0ef41Sopenharmony_ci  return impl(this)->element.get();
7521cb0ef41Sopenharmony_ci}
7531cb0ef41Sopenharmony_ci
7541cb0ef41Sopenharmony_ciauto TableType::limits() const -> const Limits& { return impl(this)->limits; }
7551cb0ef41Sopenharmony_ci
7561cb0ef41Sopenharmony_ciauto ExternType::table() -> TableType* {
7571cb0ef41Sopenharmony_ci  return kind() == EXTERN_TABLE
7581cb0ef41Sopenharmony_ci             ? seal<TableType>(static_cast<TableTypeImpl*>(impl(this)))
7591cb0ef41Sopenharmony_ci             : nullptr;
7601cb0ef41Sopenharmony_ci}
7611cb0ef41Sopenharmony_ci
7621cb0ef41Sopenharmony_ciauto ExternType::table() const -> const TableType* {
7631cb0ef41Sopenharmony_ci  return kind() == EXTERN_TABLE
7641cb0ef41Sopenharmony_ci             ? seal<TableType>(static_cast<const TableTypeImpl*>(impl(this)))
7651cb0ef41Sopenharmony_ci             : nullptr;
7661cb0ef41Sopenharmony_ci}
7671cb0ef41Sopenharmony_ci
7681cb0ef41Sopenharmony_ci// Memory Types
7691cb0ef41Sopenharmony_ci
7701cb0ef41Sopenharmony_cistruct MemoryTypeImpl : ExternTypeImpl {
7711cb0ef41Sopenharmony_ci  Limits limits;
7721cb0ef41Sopenharmony_ci
7731cb0ef41Sopenharmony_ci  explicit MemoryTypeImpl(Limits limits)
7741cb0ef41Sopenharmony_ci      : ExternTypeImpl(EXTERN_MEMORY), limits(limits) {}
7751cb0ef41Sopenharmony_ci
7761cb0ef41Sopenharmony_ci  ~MemoryTypeImpl() override = default;
7771cb0ef41Sopenharmony_ci};
7781cb0ef41Sopenharmony_ci
7791cb0ef41Sopenharmony_citemplate <>
7801cb0ef41Sopenharmony_cistruct implement<MemoryType> {
7811cb0ef41Sopenharmony_ci  using type = MemoryTypeImpl;
7821cb0ef41Sopenharmony_ci};
7831cb0ef41Sopenharmony_ci
7841cb0ef41Sopenharmony_ciMemoryType::~MemoryType() = default;
7851cb0ef41Sopenharmony_ci
7861cb0ef41Sopenharmony_ciauto MemoryType::make(Limits limits) -> own<MemoryType> {
7871cb0ef41Sopenharmony_ci  return own<MemoryType>(
7881cb0ef41Sopenharmony_ci      seal<MemoryType>(new (std::nothrow) MemoryTypeImpl(limits)));
7891cb0ef41Sopenharmony_ci}
7901cb0ef41Sopenharmony_ci
7911cb0ef41Sopenharmony_ciauto MemoryType::copy() const -> own<MemoryType> {
7921cb0ef41Sopenharmony_ci  return MemoryType::make(limits());
7931cb0ef41Sopenharmony_ci}
7941cb0ef41Sopenharmony_ci
7951cb0ef41Sopenharmony_ciauto MemoryType::limits() const -> const Limits& { return impl(this)->limits; }
7961cb0ef41Sopenharmony_ci
7971cb0ef41Sopenharmony_ciauto ExternType::memory() -> MemoryType* {
7981cb0ef41Sopenharmony_ci  return kind() == EXTERN_MEMORY
7991cb0ef41Sopenharmony_ci             ? seal<MemoryType>(static_cast<MemoryTypeImpl*>(impl(this)))
8001cb0ef41Sopenharmony_ci             : nullptr;
8011cb0ef41Sopenharmony_ci}
8021cb0ef41Sopenharmony_ci
8031cb0ef41Sopenharmony_ciauto ExternType::memory() const -> const MemoryType* {
8041cb0ef41Sopenharmony_ci  return kind() == EXTERN_MEMORY
8051cb0ef41Sopenharmony_ci             ? seal<MemoryType>(static_cast<const MemoryTypeImpl*>(impl(this)))
8061cb0ef41Sopenharmony_ci             : nullptr;
8071cb0ef41Sopenharmony_ci}
8081cb0ef41Sopenharmony_ci
8091cb0ef41Sopenharmony_ci// Import Types
8101cb0ef41Sopenharmony_ci
8111cb0ef41Sopenharmony_cistruct ImportTypeImpl {
8121cb0ef41Sopenharmony_ci  Name module;
8131cb0ef41Sopenharmony_ci  Name name;
8141cb0ef41Sopenharmony_ci  own<ExternType> type;
8151cb0ef41Sopenharmony_ci
8161cb0ef41Sopenharmony_ci  ImportTypeImpl(Name& module, Name& name, own<ExternType>& type)
8171cb0ef41Sopenharmony_ci      : module(std::move(module)),
8181cb0ef41Sopenharmony_ci        name(std::move(name)),
8191cb0ef41Sopenharmony_ci        type(std::move(type)) {}
8201cb0ef41Sopenharmony_ci};
8211cb0ef41Sopenharmony_ci
8221cb0ef41Sopenharmony_citemplate <>
8231cb0ef41Sopenharmony_cistruct implement<ImportType> {
8241cb0ef41Sopenharmony_ci  using type = ImportTypeImpl;
8251cb0ef41Sopenharmony_ci};
8261cb0ef41Sopenharmony_ci
8271cb0ef41Sopenharmony_ciImportType::~ImportType() { impl(this)->~ImportTypeImpl(); }
8281cb0ef41Sopenharmony_ci
8291cb0ef41Sopenharmony_civoid ImportType::operator delete(void* p) { ::operator delete(p); }
8301cb0ef41Sopenharmony_ci
8311cb0ef41Sopenharmony_ciauto ImportType::make(Name&& module, Name&& name, own<ExternType>&& type)
8321cb0ef41Sopenharmony_ci    -> own<ImportType> {
8331cb0ef41Sopenharmony_ci  return module && name && type
8341cb0ef41Sopenharmony_ci             ? own<ImportType>(seal<ImportType>(
8351cb0ef41Sopenharmony_ci                   new (std::nothrow) ImportTypeImpl(module, name, type)))
8361cb0ef41Sopenharmony_ci             : own<ImportType>();
8371cb0ef41Sopenharmony_ci}
8381cb0ef41Sopenharmony_ci
8391cb0ef41Sopenharmony_ciauto ImportType::copy() const -> own<ImportType> {
8401cb0ef41Sopenharmony_ci  return make(module().copy(), name().copy(), type()->copy());
8411cb0ef41Sopenharmony_ci}
8421cb0ef41Sopenharmony_ci
8431cb0ef41Sopenharmony_ciauto ImportType::module() const -> const Name& { return impl(this)->module; }
8441cb0ef41Sopenharmony_ci
8451cb0ef41Sopenharmony_ciauto ImportType::name() const -> const Name& { return impl(this)->name; }
8461cb0ef41Sopenharmony_ci
8471cb0ef41Sopenharmony_ciauto ImportType::type() const -> const ExternType* {
8481cb0ef41Sopenharmony_ci  return impl(this)->type.get();
8491cb0ef41Sopenharmony_ci}
8501cb0ef41Sopenharmony_ci
8511cb0ef41Sopenharmony_ci// Export Types
8521cb0ef41Sopenharmony_ci
8531cb0ef41Sopenharmony_cistruct ExportTypeImpl {
8541cb0ef41Sopenharmony_ci  Name name;
8551cb0ef41Sopenharmony_ci  own<ExternType> type;
8561cb0ef41Sopenharmony_ci
8571cb0ef41Sopenharmony_ci  ExportTypeImpl(Name& name, own<ExternType>& type)
8581cb0ef41Sopenharmony_ci      : name(std::move(name)), type(std::move(type)) {}
8591cb0ef41Sopenharmony_ci};
8601cb0ef41Sopenharmony_ci
8611cb0ef41Sopenharmony_citemplate <>
8621cb0ef41Sopenharmony_cistruct implement<ExportType> {
8631cb0ef41Sopenharmony_ci  using type = ExportTypeImpl;
8641cb0ef41Sopenharmony_ci};
8651cb0ef41Sopenharmony_ci
8661cb0ef41Sopenharmony_ciExportType::~ExportType() { impl(this)->~ExportTypeImpl(); }
8671cb0ef41Sopenharmony_ci
8681cb0ef41Sopenharmony_civoid ExportType::operator delete(void* p) { ::operator delete(p); }
8691cb0ef41Sopenharmony_ci
8701cb0ef41Sopenharmony_ciauto ExportType::make(Name&& name, own<ExternType>&& type) -> own<ExportType> {
8711cb0ef41Sopenharmony_ci  return name && type ? own<ExportType>(seal<ExportType>(
8721cb0ef41Sopenharmony_ci                            new (std::nothrow) ExportTypeImpl(name, type)))
8731cb0ef41Sopenharmony_ci                      : own<ExportType>();
8741cb0ef41Sopenharmony_ci}
8751cb0ef41Sopenharmony_ci
8761cb0ef41Sopenharmony_ciauto ExportType::copy() const -> own<ExportType> {
8771cb0ef41Sopenharmony_ci  return make(name().copy(), type()->copy());
8781cb0ef41Sopenharmony_ci}
8791cb0ef41Sopenharmony_ci
8801cb0ef41Sopenharmony_ciauto ExportType::name() const -> const Name& { return impl(this)->name; }
8811cb0ef41Sopenharmony_ci
8821cb0ef41Sopenharmony_ciauto ExportType::type() const -> const ExternType* {
8831cb0ef41Sopenharmony_ci  return impl(this)->type.get();
8841cb0ef41Sopenharmony_ci}
8851cb0ef41Sopenharmony_ci
8861cb0ef41Sopenharmony_cii::Handle<i::String> VecToString(i::Isolate* isolate,
8871cb0ef41Sopenharmony_ci                                 const vec<byte_t>& chars) {
8881cb0ef41Sopenharmony_ci  size_t length = chars.size();
8891cb0ef41Sopenharmony_ci  // Some, but not all, {chars} vectors we get here are null-terminated,
8901cb0ef41Sopenharmony_ci  // so let's be robust to that.
8911cb0ef41Sopenharmony_ci  if (length > 0 && chars[length - 1] == 0) length--;
8921cb0ef41Sopenharmony_ci  return isolate->factory()
8931cb0ef41Sopenharmony_ci      ->NewStringFromUtf8({chars.get(), length})
8941cb0ef41Sopenharmony_ci      .ToHandleChecked();
8951cb0ef41Sopenharmony_ci}
8961cb0ef41Sopenharmony_ci
8971cb0ef41Sopenharmony_ci// References
8981cb0ef41Sopenharmony_ci
8991cb0ef41Sopenharmony_citemplate <class Ref, class JSType>
9001cb0ef41Sopenharmony_ciclass RefImpl {
9011cb0ef41Sopenharmony_ci public:
9021cb0ef41Sopenharmony_ci  static own<Ref> make(StoreImpl* store, i::Handle<JSType> obj) {
9031cb0ef41Sopenharmony_ci    RefImpl* self = new (std::nothrow) RefImpl();
9041cb0ef41Sopenharmony_ci    if (!self) return nullptr;
9051cb0ef41Sopenharmony_ci    i::Isolate* isolate = store->i_isolate();
9061cb0ef41Sopenharmony_ci    self->val_ = isolate->global_handles()->Create(*obj);
9071cb0ef41Sopenharmony_ci    return make_own(seal<Ref>(self));
9081cb0ef41Sopenharmony_ci  }
9091cb0ef41Sopenharmony_ci
9101cb0ef41Sopenharmony_ci  ~RefImpl() { i::GlobalHandles::Destroy(location()); }
9111cb0ef41Sopenharmony_ci
9121cb0ef41Sopenharmony_ci  own<Ref> copy() const { return make(store(), v8_object()); }
9131cb0ef41Sopenharmony_ci
9141cb0ef41Sopenharmony_ci  StoreImpl* store() const { return StoreImpl::get(isolate()); }
9151cb0ef41Sopenharmony_ci
9161cb0ef41Sopenharmony_ci  i::Isolate* isolate() const { return val_->GetIsolate(); }
9171cb0ef41Sopenharmony_ci
9181cb0ef41Sopenharmony_ci  i::Handle<JSType> v8_object() const { return i::Handle<JSType>::cast(val_); }
9191cb0ef41Sopenharmony_ci
9201cb0ef41Sopenharmony_ci  void* get_host_info() const { return store()->GetHostInfo(v8_object()); }
9211cb0ef41Sopenharmony_ci
9221cb0ef41Sopenharmony_ci  void set_host_info(void* info, void (*finalizer)(void*)) {
9231cb0ef41Sopenharmony_ci    store()->SetHostInfo(v8_object(), info, finalizer);
9241cb0ef41Sopenharmony_ci  }
9251cb0ef41Sopenharmony_ci
9261cb0ef41Sopenharmony_ci private:
9271cb0ef41Sopenharmony_ci  RefImpl() = default;
9281cb0ef41Sopenharmony_ci
9291cb0ef41Sopenharmony_ci  i::Address* location() const {
9301cb0ef41Sopenharmony_ci    return reinterpret_cast<i::Address*>(val_.address());
9311cb0ef41Sopenharmony_ci  }
9321cb0ef41Sopenharmony_ci
9331cb0ef41Sopenharmony_ci  i::Handle<i::JSReceiver> val_;
9341cb0ef41Sopenharmony_ci};
9351cb0ef41Sopenharmony_ci
9361cb0ef41Sopenharmony_citemplate <>
9371cb0ef41Sopenharmony_cistruct implement<Ref> {
9381cb0ef41Sopenharmony_ci  using type = RefImpl<Ref, i::JSReceiver>;
9391cb0ef41Sopenharmony_ci};
9401cb0ef41Sopenharmony_ci
9411cb0ef41Sopenharmony_ciRef::~Ref() { delete impl(this); }
9421cb0ef41Sopenharmony_ci
9431cb0ef41Sopenharmony_civoid Ref::operator delete(void* p) {}
9441cb0ef41Sopenharmony_ci
9451cb0ef41Sopenharmony_ciauto Ref::copy() const -> own<Ref> { return impl(this)->copy(); }
9461cb0ef41Sopenharmony_ci
9471cb0ef41Sopenharmony_ciauto Ref::same(const Ref* that) const -> bool {
9481cb0ef41Sopenharmony_ci  i::HandleScope handle_scope(impl(this)->isolate());
9491cb0ef41Sopenharmony_ci  return impl(this)->v8_object()->SameValue(*impl(that)->v8_object());
9501cb0ef41Sopenharmony_ci}
9511cb0ef41Sopenharmony_ci
9521cb0ef41Sopenharmony_ciauto Ref::get_host_info() const -> void* { return impl(this)->get_host_info(); }
9531cb0ef41Sopenharmony_ci
9541cb0ef41Sopenharmony_civoid Ref::set_host_info(void* info, void (*finalizer)(void*)) {
9551cb0ef41Sopenharmony_ci  impl(this)->set_host_info(info, finalizer);
9561cb0ef41Sopenharmony_ci}
9571cb0ef41Sopenharmony_ci
9581cb0ef41Sopenharmony_ci///////////////////////////////////////////////////////////////////////////////
9591cb0ef41Sopenharmony_ci// Runtime Objects
9601cb0ef41Sopenharmony_ci
9611cb0ef41Sopenharmony_ci// Frames
9621cb0ef41Sopenharmony_ci
9631cb0ef41Sopenharmony_cinamespace {
9641cb0ef41Sopenharmony_ci
9651cb0ef41Sopenharmony_cistruct FrameImpl {
9661cb0ef41Sopenharmony_ci  FrameImpl(own<Instance>&& instance, uint32_t func_index, size_t func_offset,
9671cb0ef41Sopenharmony_ci            size_t module_offset)
9681cb0ef41Sopenharmony_ci      : instance(std::move(instance)),
9691cb0ef41Sopenharmony_ci        func_index(func_index),
9701cb0ef41Sopenharmony_ci        func_offset(func_offset),
9711cb0ef41Sopenharmony_ci        module_offset(module_offset) {}
9721cb0ef41Sopenharmony_ci
9731cb0ef41Sopenharmony_ci  own<Instance> instance;
9741cb0ef41Sopenharmony_ci  uint32_t func_index;
9751cb0ef41Sopenharmony_ci  size_t func_offset;
9761cb0ef41Sopenharmony_ci  size_t module_offset;
9771cb0ef41Sopenharmony_ci};
9781cb0ef41Sopenharmony_ci
9791cb0ef41Sopenharmony_ci}  // namespace
9801cb0ef41Sopenharmony_ci
9811cb0ef41Sopenharmony_citemplate <>
9821cb0ef41Sopenharmony_cistruct implement<Frame> {
9831cb0ef41Sopenharmony_ci  using type = FrameImpl;
9841cb0ef41Sopenharmony_ci};
9851cb0ef41Sopenharmony_ci
9861cb0ef41Sopenharmony_ciFrame::~Frame() { impl(this)->~FrameImpl(); }
9871cb0ef41Sopenharmony_ci
9881cb0ef41Sopenharmony_civoid Frame::operator delete(void* p) { ::operator delete(p); }
9891cb0ef41Sopenharmony_ci
9901cb0ef41Sopenharmony_ciown<Frame> Frame::copy() const {
9911cb0ef41Sopenharmony_ci  auto self = impl(this);
9921cb0ef41Sopenharmony_ci  return own<Frame>(seal<Frame>(
9931cb0ef41Sopenharmony_ci      new (std::nothrow) FrameImpl(self->instance->copy(), self->func_index,
9941cb0ef41Sopenharmony_ci                                   self->func_offset, self->module_offset)));
9951cb0ef41Sopenharmony_ci}
9961cb0ef41Sopenharmony_ci
9971cb0ef41Sopenharmony_ciInstance* Frame::instance() const { return impl(this)->instance.get(); }
9981cb0ef41Sopenharmony_ci
9991cb0ef41Sopenharmony_ciuint32_t Frame::func_index() const { return impl(this)->func_index; }
10001cb0ef41Sopenharmony_ci
10011cb0ef41Sopenharmony_cisize_t Frame::func_offset() const { return impl(this)->func_offset; }
10021cb0ef41Sopenharmony_ci
10031cb0ef41Sopenharmony_cisize_t Frame::module_offset() const { return impl(this)->module_offset; }
10041cb0ef41Sopenharmony_ci
10051cb0ef41Sopenharmony_ci// Traps
10061cb0ef41Sopenharmony_ci
10071cb0ef41Sopenharmony_citemplate <>
10081cb0ef41Sopenharmony_cistruct implement<Trap> {
10091cb0ef41Sopenharmony_ci  using type = RefImpl<Trap, i::JSReceiver>;
10101cb0ef41Sopenharmony_ci};
10111cb0ef41Sopenharmony_ci
10121cb0ef41Sopenharmony_ciTrap::~Trap() = default;
10131cb0ef41Sopenharmony_ci
10141cb0ef41Sopenharmony_ciauto Trap::copy() const -> own<Trap> { return impl(this)->copy(); }
10151cb0ef41Sopenharmony_ci
10161cb0ef41Sopenharmony_ciauto Trap::make(Store* store_abs, const Message& message) -> own<Trap> {
10171cb0ef41Sopenharmony_ci  auto store = impl(store_abs);
10181cb0ef41Sopenharmony_ci  i::Isolate* isolate = store->i_isolate();
10191cb0ef41Sopenharmony_ci  i::HandleScope handle_scope(isolate);
10201cb0ef41Sopenharmony_ci  i::Handle<i::String> string = VecToString(isolate, message);
10211cb0ef41Sopenharmony_ci  i::Handle<i::JSObject> exception =
10221cb0ef41Sopenharmony_ci      isolate->factory()->NewError(isolate->error_function(), string);
10231cb0ef41Sopenharmony_ci  i::JSObject::AddProperty(isolate, exception,
10241cb0ef41Sopenharmony_ci                           isolate->factory()->wasm_uncatchable_symbol(),
10251cb0ef41Sopenharmony_ci                           isolate->factory()->true_value(), i::NONE);
10261cb0ef41Sopenharmony_ci  return implement<Trap>::type::make(store, exception);
10271cb0ef41Sopenharmony_ci}
10281cb0ef41Sopenharmony_ci
10291cb0ef41Sopenharmony_ciauto Trap::message() const -> Message {
10301cb0ef41Sopenharmony_ci  auto isolate = impl(this)->isolate();
10311cb0ef41Sopenharmony_ci  i::HandleScope handle_scope(isolate);
10321cb0ef41Sopenharmony_ci
10331cb0ef41Sopenharmony_ci  i::Handle<i::JSMessageObject> message =
10341cb0ef41Sopenharmony_ci      isolate->CreateMessage(impl(this)->v8_object(), nullptr);
10351cb0ef41Sopenharmony_ci  i::Handle<i::String> result = i::MessageHandler::GetMessage(isolate, message);
10361cb0ef41Sopenharmony_ci  result = i::String::Flatten(isolate, result);  // For performance.
10371cb0ef41Sopenharmony_ci  int length = 0;
10381cb0ef41Sopenharmony_ci  std::unique_ptr<char[]> utf8 =
10391cb0ef41Sopenharmony_ci      result->ToCString(i::DISALLOW_NULLS, i::FAST_STRING_TRAVERSAL, &length);
10401cb0ef41Sopenharmony_ci  return vec<byte_t>::adopt(length, utf8.release());
10411cb0ef41Sopenharmony_ci}
10421cb0ef41Sopenharmony_ci
10431cb0ef41Sopenharmony_cinamespace {
10441cb0ef41Sopenharmony_ci
10451cb0ef41Sopenharmony_ciown<Instance> GetInstance(StoreImpl* store,
10461cb0ef41Sopenharmony_ci                          i::Handle<i::WasmInstanceObject> instance);
10471cb0ef41Sopenharmony_ci
10481cb0ef41Sopenharmony_ciown<Frame> CreateFrameFromInternal(i::Handle<i::FixedArray> frames, int index,
10491cb0ef41Sopenharmony_ci                                   i::Isolate* isolate, StoreImpl* store) {
10501cb0ef41Sopenharmony_ci  i::Handle<i::CallSiteInfo> frame(i::CallSiteInfo::cast(frames->get(index)),
10511cb0ef41Sopenharmony_ci                                   isolate);
10521cb0ef41Sopenharmony_ci  i::Handle<i::WasmInstanceObject> instance(frame->GetWasmInstance(), isolate);
10531cb0ef41Sopenharmony_ci  uint32_t func_index = frame->GetWasmFunctionIndex();
10541cb0ef41Sopenharmony_ci  size_t module_offset = i::CallSiteInfo::GetSourcePosition(frame);
10551cb0ef41Sopenharmony_ci  size_t func_offset = module_offset - i::wasm::GetWasmFunctionOffset(
10561cb0ef41Sopenharmony_ci                                           instance->module(), func_index);
10571cb0ef41Sopenharmony_ci  return own<Frame>(seal<Frame>(new (std::nothrow) FrameImpl(
10581cb0ef41Sopenharmony_ci      GetInstance(store, instance), func_index, func_offset, module_offset)));
10591cb0ef41Sopenharmony_ci}
10601cb0ef41Sopenharmony_ci
10611cb0ef41Sopenharmony_ci}  // namespace
10621cb0ef41Sopenharmony_ci
10631cb0ef41Sopenharmony_ciown<Frame> Trap::origin() const {
10641cb0ef41Sopenharmony_ci  i::Isolate* isolate = impl(this)->isolate();
10651cb0ef41Sopenharmony_ci  i::HandleScope handle_scope(isolate);
10661cb0ef41Sopenharmony_ci
10671cb0ef41Sopenharmony_ci  i::Handle<i::FixedArray> frames =
10681cb0ef41Sopenharmony_ci      isolate->GetSimpleStackTrace(impl(this)->v8_object());
10691cb0ef41Sopenharmony_ci  if (frames->length() == 0) {
10701cb0ef41Sopenharmony_ci    return own<Frame>();
10711cb0ef41Sopenharmony_ci  }
10721cb0ef41Sopenharmony_ci  return CreateFrameFromInternal(frames, 0, isolate, impl(this)->store());
10731cb0ef41Sopenharmony_ci}
10741cb0ef41Sopenharmony_ci
10751cb0ef41Sopenharmony_ciownvec<Frame> Trap::trace() const {
10761cb0ef41Sopenharmony_ci  i::Isolate* isolate = impl(this)->isolate();
10771cb0ef41Sopenharmony_ci  i::HandleScope handle_scope(isolate);
10781cb0ef41Sopenharmony_ci
10791cb0ef41Sopenharmony_ci  i::Handle<i::FixedArray> frames =
10801cb0ef41Sopenharmony_ci      isolate->GetSimpleStackTrace(impl(this)->v8_object());
10811cb0ef41Sopenharmony_ci  int num_frames = frames->length();
10821cb0ef41Sopenharmony_ci  // {num_frames} can be 0; the code below can handle that case.
10831cb0ef41Sopenharmony_ci  ownvec<Frame> result = ownvec<Frame>::make_uninitialized(num_frames);
10841cb0ef41Sopenharmony_ci  for (int i = 0; i < num_frames; i++) {
10851cb0ef41Sopenharmony_ci    result[i] =
10861cb0ef41Sopenharmony_ci        CreateFrameFromInternal(frames, i, isolate, impl(this)->store());
10871cb0ef41Sopenharmony_ci  }
10881cb0ef41Sopenharmony_ci  return result;
10891cb0ef41Sopenharmony_ci}
10901cb0ef41Sopenharmony_ci
10911cb0ef41Sopenharmony_ci// Foreign Objects
10921cb0ef41Sopenharmony_ci
10931cb0ef41Sopenharmony_citemplate <>
10941cb0ef41Sopenharmony_cistruct implement<Foreign> {
10951cb0ef41Sopenharmony_ci  using type = RefImpl<Foreign, i::JSReceiver>;
10961cb0ef41Sopenharmony_ci};
10971cb0ef41Sopenharmony_ci
10981cb0ef41Sopenharmony_ciForeign::~Foreign() = default;
10991cb0ef41Sopenharmony_ci
11001cb0ef41Sopenharmony_ciauto Foreign::copy() const -> own<Foreign> { return impl(this)->copy(); }
11011cb0ef41Sopenharmony_ci
11021cb0ef41Sopenharmony_ciauto Foreign::make(Store* store_abs) -> own<Foreign> {
11031cb0ef41Sopenharmony_ci  StoreImpl* store = impl(store_abs);
11041cb0ef41Sopenharmony_ci  i::Isolate* isolate = store->i_isolate();
11051cb0ef41Sopenharmony_ci  i::HandleScope handle_scope(isolate);
11061cb0ef41Sopenharmony_ci
11071cb0ef41Sopenharmony_ci  i::Handle<i::JSObject> obj =
11081cb0ef41Sopenharmony_ci      isolate->factory()->NewJSObject(isolate->object_function());
11091cb0ef41Sopenharmony_ci  return implement<Foreign>::type::make(store, obj);
11101cb0ef41Sopenharmony_ci}
11111cb0ef41Sopenharmony_ci
11121cb0ef41Sopenharmony_ci// Modules
11131cb0ef41Sopenharmony_ci
11141cb0ef41Sopenharmony_citemplate <>
11151cb0ef41Sopenharmony_cistruct implement<Module> {
11161cb0ef41Sopenharmony_ci  using type = RefImpl<Module, i::WasmModuleObject>;
11171cb0ef41Sopenharmony_ci};
11181cb0ef41Sopenharmony_ci
11191cb0ef41Sopenharmony_ciModule::~Module() = default;
11201cb0ef41Sopenharmony_ci
11211cb0ef41Sopenharmony_ciauto Module::copy() const -> own<Module> { return impl(this)->copy(); }
11221cb0ef41Sopenharmony_ci
11231cb0ef41Sopenharmony_ciauto Module::validate(Store* store_abs, const vec<byte_t>& binary) -> bool {
11241cb0ef41Sopenharmony_ci  i::wasm::ModuleWireBytes bytes(
11251cb0ef41Sopenharmony_ci      {reinterpret_cast<const uint8_t*>(binary.get()), binary.size()});
11261cb0ef41Sopenharmony_ci  i::Isolate* isolate = impl(store_abs)->i_isolate();
11271cb0ef41Sopenharmony_ci  i::wasm::WasmFeatures features = i::wasm::WasmFeatures::FromIsolate(isolate);
11281cb0ef41Sopenharmony_ci  return i::wasm::GetWasmEngine()->SyncValidate(isolate, features, bytes);
11291cb0ef41Sopenharmony_ci}
11301cb0ef41Sopenharmony_ci
11311cb0ef41Sopenharmony_ciauto Module::make(Store* store_abs, const vec<byte_t>& binary) -> own<Module> {
11321cb0ef41Sopenharmony_ci  StoreImpl* store = impl(store_abs);
11331cb0ef41Sopenharmony_ci  i::Isolate* isolate = store->i_isolate();
11341cb0ef41Sopenharmony_ci  i::HandleScope scope(isolate);
11351cb0ef41Sopenharmony_ci  CheckAndHandleInterrupts(isolate);
11361cb0ef41Sopenharmony_ci  i::wasm::ModuleWireBytes bytes(
11371cb0ef41Sopenharmony_ci      {reinterpret_cast<const uint8_t*>(binary.get()), binary.size()});
11381cb0ef41Sopenharmony_ci  i::wasm::WasmFeatures features = i::wasm::WasmFeatures::FromIsolate(isolate);
11391cb0ef41Sopenharmony_ci  i::wasm::ErrorThrower thrower(isolate, "ignored");
11401cb0ef41Sopenharmony_ci  i::Handle<i::WasmModuleObject> module;
11411cb0ef41Sopenharmony_ci  if (!i::wasm::GetWasmEngine()
11421cb0ef41Sopenharmony_ci           ->SyncCompile(isolate, features, &thrower, bytes)
11431cb0ef41Sopenharmony_ci           .ToHandle(&module)) {
11441cb0ef41Sopenharmony_ci    thrower.Reset();  // The API provides no way to expose the error.
11451cb0ef41Sopenharmony_ci    return nullptr;
11461cb0ef41Sopenharmony_ci  }
11471cb0ef41Sopenharmony_ci  return implement<Module>::type::make(store, module);
11481cb0ef41Sopenharmony_ci}
11491cb0ef41Sopenharmony_ci
11501cb0ef41Sopenharmony_ciauto Module::imports() const -> ownvec<ImportType> {
11511cb0ef41Sopenharmony_ci  const i::wasm::NativeModule* native_module =
11521cb0ef41Sopenharmony_ci      impl(this)->v8_object()->native_module();
11531cb0ef41Sopenharmony_ci  const i::wasm::WasmModule* module = native_module->module();
11541cb0ef41Sopenharmony_ci  const v8::base::Vector<const uint8_t> wire_bytes =
11551cb0ef41Sopenharmony_ci      native_module->wire_bytes();
11561cb0ef41Sopenharmony_ci  const std::vector<i::wasm::WasmImport>& import_table = module->import_table;
11571cb0ef41Sopenharmony_ci  size_t size = import_table.size();
11581cb0ef41Sopenharmony_ci  ownvec<ImportType> imports = ownvec<ImportType>::make_uninitialized(size);
11591cb0ef41Sopenharmony_ci  for (uint32_t i = 0; i < size; i++) {
11601cb0ef41Sopenharmony_ci    const i::wasm::WasmImport& imp = import_table[i];
11611cb0ef41Sopenharmony_ci    Name module_name = GetNameFromWireBytes(imp.module_name, wire_bytes);
11621cb0ef41Sopenharmony_ci    Name name = GetNameFromWireBytes(imp.field_name, wire_bytes);
11631cb0ef41Sopenharmony_ci    own<ExternType> type = GetImportExportType(module, imp.kind, imp.index);
11641cb0ef41Sopenharmony_ci    imports[i] = ImportType::make(std::move(module_name), std::move(name),
11651cb0ef41Sopenharmony_ci                                  std::move(type));
11661cb0ef41Sopenharmony_ci  }
11671cb0ef41Sopenharmony_ci  return imports;
11681cb0ef41Sopenharmony_ci}
11691cb0ef41Sopenharmony_ci
11701cb0ef41Sopenharmony_ciownvec<ExportType> ExportsImpl(i::Handle<i::WasmModuleObject> module_obj) {
11711cb0ef41Sopenharmony_ci  const i::wasm::NativeModule* native_module = module_obj->native_module();
11721cb0ef41Sopenharmony_ci  const i::wasm::WasmModule* module = native_module->module();
11731cb0ef41Sopenharmony_ci  const v8::base::Vector<const uint8_t> wire_bytes =
11741cb0ef41Sopenharmony_ci      native_module->wire_bytes();
11751cb0ef41Sopenharmony_ci  const std::vector<i::wasm::WasmExport>& export_table = module->export_table;
11761cb0ef41Sopenharmony_ci  size_t size = export_table.size();
11771cb0ef41Sopenharmony_ci  ownvec<ExportType> exports = ownvec<ExportType>::make_uninitialized(size);
11781cb0ef41Sopenharmony_ci  for (uint32_t i = 0; i < size; i++) {
11791cb0ef41Sopenharmony_ci    const i::wasm::WasmExport& exp = export_table[i];
11801cb0ef41Sopenharmony_ci    Name name = GetNameFromWireBytes(exp.name, wire_bytes);
11811cb0ef41Sopenharmony_ci    own<ExternType> type = GetImportExportType(module, exp.kind, exp.index);
11821cb0ef41Sopenharmony_ci    exports[i] = ExportType::make(std::move(name), std::move(type));
11831cb0ef41Sopenharmony_ci  }
11841cb0ef41Sopenharmony_ci  return exports;
11851cb0ef41Sopenharmony_ci}
11861cb0ef41Sopenharmony_ci
11871cb0ef41Sopenharmony_ciauto Module::exports() const -> ownvec<ExportType> {
11881cb0ef41Sopenharmony_ci  return ExportsImpl(impl(this)->v8_object());
11891cb0ef41Sopenharmony_ci}
11901cb0ef41Sopenharmony_ci
11911cb0ef41Sopenharmony_ciauto Module::serialize() const -> vec<byte_t> {
11921cb0ef41Sopenharmony_ci  i::wasm::NativeModule* native_module =
11931cb0ef41Sopenharmony_ci      impl(this)->v8_object()->native_module();
11941cb0ef41Sopenharmony_ci  v8::base::Vector<const uint8_t> wire_bytes = native_module->wire_bytes();
11951cb0ef41Sopenharmony_ci  size_t binary_size = wire_bytes.size();
11961cb0ef41Sopenharmony_ci  // We can only serialize after top-tier compilation (TurboFan) finished.
11971cb0ef41Sopenharmony_ci  native_module->compilation_state()->WaitForTopTierFinished();
11981cb0ef41Sopenharmony_ci  i::wasm::WasmSerializer serializer(native_module);
11991cb0ef41Sopenharmony_ci  size_t serial_size = serializer.GetSerializedNativeModuleSize();
12001cb0ef41Sopenharmony_ci  size_t size_size = i::wasm::LEBHelper::sizeof_u64v(binary_size);
12011cb0ef41Sopenharmony_ci  vec<byte_t> buffer =
12021cb0ef41Sopenharmony_ci      vec<byte_t>::make_uninitialized(size_size + binary_size + serial_size);
12031cb0ef41Sopenharmony_ci  byte_t* ptr = buffer.get();
12041cb0ef41Sopenharmony_ci  i::wasm::LEBHelper::write_u64v(reinterpret_cast<uint8_t**>(&ptr),
12051cb0ef41Sopenharmony_ci                                 binary_size);
12061cb0ef41Sopenharmony_ci  std::memcpy(ptr, wire_bytes.begin(), binary_size);
12071cb0ef41Sopenharmony_ci  ptr += binary_size;
12081cb0ef41Sopenharmony_ci  if (!serializer.SerializeNativeModule(
12091cb0ef41Sopenharmony_ci          {reinterpret_cast<uint8_t*>(ptr), serial_size})) {
12101cb0ef41Sopenharmony_ci    buffer.reset();
12111cb0ef41Sopenharmony_ci  }
12121cb0ef41Sopenharmony_ci  return buffer;
12131cb0ef41Sopenharmony_ci}
12141cb0ef41Sopenharmony_ci
12151cb0ef41Sopenharmony_ciauto Module::deserialize(Store* store_abs, const vec<byte_t>& serialized)
12161cb0ef41Sopenharmony_ci    -> own<Module> {
12171cb0ef41Sopenharmony_ci  StoreImpl* store = impl(store_abs);
12181cb0ef41Sopenharmony_ci  i::Isolate* isolate = store->i_isolate();
12191cb0ef41Sopenharmony_ci  i::HandleScope handle_scope(isolate);
12201cb0ef41Sopenharmony_ci  const byte_t* ptr = serialized.get();
12211cb0ef41Sopenharmony_ci  uint64_t binary_size = ReadLebU64(&ptr);
12221cb0ef41Sopenharmony_ci  ptrdiff_t size_size = ptr - serialized.get();
12231cb0ef41Sopenharmony_ci  size_t serial_size = serialized.size() - size_size - binary_size;
12241cb0ef41Sopenharmony_ci  i::Handle<i::WasmModuleObject> module_obj;
12251cb0ef41Sopenharmony_ci  size_t data_size = static_cast<size_t>(binary_size);
12261cb0ef41Sopenharmony_ci  if (!i::wasm::DeserializeNativeModule(
12271cb0ef41Sopenharmony_ci           isolate,
12281cb0ef41Sopenharmony_ci           {reinterpret_cast<const uint8_t*>(ptr + data_size), serial_size},
12291cb0ef41Sopenharmony_ci           {reinterpret_cast<const uint8_t*>(ptr), data_size}, {})
12301cb0ef41Sopenharmony_ci           .ToHandle(&module_obj)) {
12311cb0ef41Sopenharmony_ci    return nullptr;
12321cb0ef41Sopenharmony_ci  }
12331cb0ef41Sopenharmony_ci  return implement<Module>::type::make(store, module_obj);
12341cb0ef41Sopenharmony_ci}
12351cb0ef41Sopenharmony_ci
12361cb0ef41Sopenharmony_ci// TODO(v8): do better when V8 can do better.
12371cb0ef41Sopenharmony_citemplate <>
12381cb0ef41Sopenharmony_cistruct implement<Shared<Module>> {
12391cb0ef41Sopenharmony_ci  using type = vec<byte_t>;
12401cb0ef41Sopenharmony_ci};
12411cb0ef41Sopenharmony_ci
12421cb0ef41Sopenharmony_citemplate <>
12431cb0ef41Sopenharmony_ciShared<Module>::~Shared() {
12441cb0ef41Sopenharmony_ci  impl(this)->~vec();
12451cb0ef41Sopenharmony_ci}
12461cb0ef41Sopenharmony_ci
12471cb0ef41Sopenharmony_citemplate <>
12481cb0ef41Sopenharmony_civoid Shared<Module>::operator delete(void* p) {
12491cb0ef41Sopenharmony_ci  ::operator delete(p);
12501cb0ef41Sopenharmony_ci}
12511cb0ef41Sopenharmony_ci
12521cb0ef41Sopenharmony_ciauto Module::share() const -> own<Shared<Module>> {
12531cb0ef41Sopenharmony_ci  auto shared = seal<Shared<Module>>(new vec<byte_t>(serialize()));
12541cb0ef41Sopenharmony_ci  return make_own(shared);
12551cb0ef41Sopenharmony_ci}
12561cb0ef41Sopenharmony_ci
12571cb0ef41Sopenharmony_ciauto Module::obtain(Store* store, const Shared<Module>* shared) -> own<Module> {
12581cb0ef41Sopenharmony_ci  return Module::deserialize(store, *impl(shared));
12591cb0ef41Sopenharmony_ci}
12601cb0ef41Sopenharmony_ci
12611cb0ef41Sopenharmony_ci// Externals
12621cb0ef41Sopenharmony_ci
12631cb0ef41Sopenharmony_citemplate <>
12641cb0ef41Sopenharmony_cistruct implement<Extern> {
12651cb0ef41Sopenharmony_ci  using type = RefImpl<Extern, i::JSReceiver>;
12661cb0ef41Sopenharmony_ci};
12671cb0ef41Sopenharmony_ci
12681cb0ef41Sopenharmony_ciExtern::~Extern() = default;
12691cb0ef41Sopenharmony_ci
12701cb0ef41Sopenharmony_ciauto Extern::copy() const -> own<Extern> { return impl(this)->copy(); }
12711cb0ef41Sopenharmony_ci
12721cb0ef41Sopenharmony_ciauto Extern::kind() const -> ExternKind {
12731cb0ef41Sopenharmony_ci  i::Handle<i::JSReceiver> obj = impl(this)->v8_object();
12741cb0ef41Sopenharmony_ci  if (i::WasmExportedFunction::IsWasmExportedFunction(*obj)) {
12751cb0ef41Sopenharmony_ci    return wasm::EXTERN_FUNC;
12761cb0ef41Sopenharmony_ci  }
12771cb0ef41Sopenharmony_ci  if (obj->IsWasmGlobalObject()) return wasm::EXTERN_GLOBAL;
12781cb0ef41Sopenharmony_ci  if (obj->IsWasmTableObject()) return wasm::EXTERN_TABLE;
12791cb0ef41Sopenharmony_ci  if (obj->IsWasmMemoryObject()) return wasm::EXTERN_MEMORY;
12801cb0ef41Sopenharmony_ci  UNREACHABLE();
12811cb0ef41Sopenharmony_ci}
12821cb0ef41Sopenharmony_ci
12831cb0ef41Sopenharmony_ciauto Extern::type() const -> own<ExternType> {
12841cb0ef41Sopenharmony_ci  switch (kind()) {
12851cb0ef41Sopenharmony_ci    case EXTERN_FUNC:
12861cb0ef41Sopenharmony_ci      return func()->type();
12871cb0ef41Sopenharmony_ci    case EXTERN_GLOBAL:
12881cb0ef41Sopenharmony_ci      return global()->type();
12891cb0ef41Sopenharmony_ci    case EXTERN_TABLE:
12901cb0ef41Sopenharmony_ci      return table()->type();
12911cb0ef41Sopenharmony_ci    case EXTERN_MEMORY:
12921cb0ef41Sopenharmony_ci      return memory()->type();
12931cb0ef41Sopenharmony_ci  }
12941cb0ef41Sopenharmony_ci}
12951cb0ef41Sopenharmony_ci
12961cb0ef41Sopenharmony_ciauto Extern::func() -> Func* {
12971cb0ef41Sopenharmony_ci  return kind() == EXTERN_FUNC ? static_cast<Func*>(this) : nullptr;
12981cb0ef41Sopenharmony_ci}
12991cb0ef41Sopenharmony_ci
13001cb0ef41Sopenharmony_ciauto Extern::global() -> Global* {
13011cb0ef41Sopenharmony_ci  return kind() == EXTERN_GLOBAL ? static_cast<Global*>(this) : nullptr;
13021cb0ef41Sopenharmony_ci}
13031cb0ef41Sopenharmony_ci
13041cb0ef41Sopenharmony_ciauto Extern::table() -> Table* {
13051cb0ef41Sopenharmony_ci  return kind() == EXTERN_TABLE ? static_cast<Table*>(this) : nullptr;
13061cb0ef41Sopenharmony_ci}
13071cb0ef41Sopenharmony_ci
13081cb0ef41Sopenharmony_ciauto Extern::memory() -> Memory* {
13091cb0ef41Sopenharmony_ci  return kind() == EXTERN_MEMORY ? static_cast<Memory*>(this) : nullptr;
13101cb0ef41Sopenharmony_ci}
13111cb0ef41Sopenharmony_ci
13121cb0ef41Sopenharmony_ciauto Extern::func() const -> const Func* {
13131cb0ef41Sopenharmony_ci  return kind() == EXTERN_FUNC ? static_cast<const Func*>(this) : nullptr;
13141cb0ef41Sopenharmony_ci}
13151cb0ef41Sopenharmony_ci
13161cb0ef41Sopenharmony_ciauto Extern::global() const -> const Global* {
13171cb0ef41Sopenharmony_ci  return kind() == EXTERN_GLOBAL ? static_cast<const Global*>(this) : nullptr;
13181cb0ef41Sopenharmony_ci}
13191cb0ef41Sopenharmony_ci
13201cb0ef41Sopenharmony_ciauto Extern::table() const -> const Table* {
13211cb0ef41Sopenharmony_ci  return kind() == EXTERN_TABLE ? static_cast<const Table*>(this) : nullptr;
13221cb0ef41Sopenharmony_ci}
13231cb0ef41Sopenharmony_ci
13241cb0ef41Sopenharmony_ciauto Extern::memory() const -> const Memory* {
13251cb0ef41Sopenharmony_ci  return kind() == EXTERN_MEMORY ? static_cast<const Memory*>(this) : nullptr;
13261cb0ef41Sopenharmony_ci}
13271cb0ef41Sopenharmony_ci
13281cb0ef41Sopenharmony_ciauto extern_to_v8(const Extern* ex) -> i::Handle<i::JSReceiver> {
13291cb0ef41Sopenharmony_ci  return impl(ex)->v8_object();
13301cb0ef41Sopenharmony_ci}
13311cb0ef41Sopenharmony_ci
13321cb0ef41Sopenharmony_ci// Function Instances
13331cb0ef41Sopenharmony_ci
13341cb0ef41Sopenharmony_citemplate <>
13351cb0ef41Sopenharmony_cistruct implement<Func> {
13361cb0ef41Sopenharmony_ci  using type = RefImpl<Func, i::JSFunction>;
13371cb0ef41Sopenharmony_ci};
13381cb0ef41Sopenharmony_ci
13391cb0ef41Sopenharmony_ciFunc::~Func() = default;
13401cb0ef41Sopenharmony_ci
13411cb0ef41Sopenharmony_ciauto Func::copy() const -> own<Func> { return impl(this)->copy(); }
13421cb0ef41Sopenharmony_ci
13431cb0ef41Sopenharmony_cistruct FuncData {
13441cb0ef41Sopenharmony_ci  Store* store;
13451cb0ef41Sopenharmony_ci  own<FuncType> type;
13461cb0ef41Sopenharmony_ci  enum Kind { kCallback, kCallbackWithEnv } kind;
13471cb0ef41Sopenharmony_ci  union {
13481cb0ef41Sopenharmony_ci    Func::callback callback;
13491cb0ef41Sopenharmony_ci    Func::callback_with_env callback_with_env;
13501cb0ef41Sopenharmony_ci  };
13511cb0ef41Sopenharmony_ci  void (*finalizer)(void*);
13521cb0ef41Sopenharmony_ci  void* env;
13531cb0ef41Sopenharmony_ci
13541cb0ef41Sopenharmony_ci  FuncData(Store* store, const FuncType* type, Kind kind)
13551cb0ef41Sopenharmony_ci      : store(store),
13561cb0ef41Sopenharmony_ci        type(type->copy()),
13571cb0ef41Sopenharmony_ci        kind(kind),
13581cb0ef41Sopenharmony_ci        finalizer(nullptr),
13591cb0ef41Sopenharmony_ci        env(nullptr) {}
13601cb0ef41Sopenharmony_ci
13611cb0ef41Sopenharmony_ci  ~FuncData() {
13621cb0ef41Sopenharmony_ci    if (finalizer) (*finalizer)(env);
13631cb0ef41Sopenharmony_ci  }
13641cb0ef41Sopenharmony_ci
13651cb0ef41Sopenharmony_ci  static i::Address v8_callback(i::Address host_data_foreign, i::Address argv);
13661cb0ef41Sopenharmony_ci};
13671cb0ef41Sopenharmony_ci
13681cb0ef41Sopenharmony_cinamespace {
13691cb0ef41Sopenharmony_ci
13701cb0ef41Sopenharmony_ci// TODO(jkummerow): Generalize for WasmExportedFunction and WasmCapiFunction.
13711cb0ef41Sopenharmony_ciclass SignatureHelper : public i::AllStatic {
13721cb0ef41Sopenharmony_ci public:
13731cb0ef41Sopenharmony_ci  // Use an invalid type as a marker separating params and results.
13741cb0ef41Sopenharmony_ci  static constexpr i::wasm::ValueType kMarker = i::wasm::kWasmVoid;
13751cb0ef41Sopenharmony_ci
13761cb0ef41Sopenharmony_ci  static i::Handle<i::PodArray<i::wasm::ValueType>> Serialize(
13771cb0ef41Sopenharmony_ci      i::Isolate* isolate, FuncType* type) {
13781cb0ef41Sopenharmony_ci    int sig_size =
13791cb0ef41Sopenharmony_ci        static_cast<int>(type->params().size() + type->results().size() + 1);
13801cb0ef41Sopenharmony_ci    i::Handle<i::PodArray<i::wasm::ValueType>> sig =
13811cb0ef41Sopenharmony_ci        i::PodArray<i::wasm::ValueType>::New(isolate, sig_size,
13821cb0ef41Sopenharmony_ci                                             i::AllocationType::kOld);
13831cb0ef41Sopenharmony_ci    int index = 0;
13841cb0ef41Sopenharmony_ci    // TODO(jkummerow): Consider making vec<> range-based for-iterable.
13851cb0ef41Sopenharmony_ci    for (size_t i = 0; i < type->results().size(); i++) {
13861cb0ef41Sopenharmony_ci      sig->set(index++, WasmValKindToV8(type->results()[i]->kind()));
13871cb0ef41Sopenharmony_ci    }
13881cb0ef41Sopenharmony_ci    // {sig->set} needs to take the address of its second parameter,
13891cb0ef41Sopenharmony_ci    // so we can't pass in the static const kMarker directly.
13901cb0ef41Sopenharmony_ci    i::wasm::ValueType marker = kMarker;
13911cb0ef41Sopenharmony_ci    sig->set(index++, marker);
13921cb0ef41Sopenharmony_ci    for (size_t i = 0; i < type->params().size(); i++) {
13931cb0ef41Sopenharmony_ci      sig->set(index++, WasmValKindToV8(type->params()[i]->kind()));
13941cb0ef41Sopenharmony_ci    }
13951cb0ef41Sopenharmony_ci    return sig;
13961cb0ef41Sopenharmony_ci  }
13971cb0ef41Sopenharmony_ci
13981cb0ef41Sopenharmony_ci  static own<FuncType> Deserialize(i::PodArray<i::wasm::ValueType> sig) {
13991cb0ef41Sopenharmony_ci    int result_arity = ResultArity(sig);
14001cb0ef41Sopenharmony_ci    int param_arity = sig.length() - result_arity - 1;
14011cb0ef41Sopenharmony_ci    ownvec<ValType> results = ownvec<ValType>::make_uninitialized(result_arity);
14021cb0ef41Sopenharmony_ci    ownvec<ValType> params = ownvec<ValType>::make_uninitialized(param_arity);
14031cb0ef41Sopenharmony_ci
14041cb0ef41Sopenharmony_ci    int i = 0;
14051cb0ef41Sopenharmony_ci    for (; i < result_arity; ++i) {
14061cb0ef41Sopenharmony_ci      results[i] = ValType::make(V8ValueTypeToWasm(sig.get(i)));
14071cb0ef41Sopenharmony_ci    }
14081cb0ef41Sopenharmony_ci    i++;  // Skip marker.
14091cb0ef41Sopenharmony_ci    for (int p = 0; i < sig.length(); ++i, ++p) {
14101cb0ef41Sopenharmony_ci      params[p] = ValType::make(V8ValueTypeToWasm(sig.get(i)));
14111cb0ef41Sopenharmony_ci    }
14121cb0ef41Sopenharmony_ci    return FuncType::make(std::move(params), std::move(results));
14131cb0ef41Sopenharmony_ci  }
14141cb0ef41Sopenharmony_ci
14151cb0ef41Sopenharmony_ci  static int ResultArity(i::PodArray<i::wasm::ValueType> sig) {
14161cb0ef41Sopenharmony_ci    int count = 0;
14171cb0ef41Sopenharmony_ci    for (; count < sig.length(); count++) {
14181cb0ef41Sopenharmony_ci      if (sig.get(count) == kMarker) return count;
14191cb0ef41Sopenharmony_ci    }
14201cb0ef41Sopenharmony_ci    UNREACHABLE();
14211cb0ef41Sopenharmony_ci  }
14221cb0ef41Sopenharmony_ci
14231cb0ef41Sopenharmony_ci  static int ParamArity(i::PodArray<i::wasm::ValueType> sig) {
14241cb0ef41Sopenharmony_ci    return sig.length() - ResultArity(sig) - 1;
14251cb0ef41Sopenharmony_ci  }
14261cb0ef41Sopenharmony_ci
14271cb0ef41Sopenharmony_ci  static i::PodArray<i::wasm::ValueType> GetSig(
14281cb0ef41Sopenharmony_ci      i::Handle<i::JSFunction> function) {
14291cb0ef41Sopenharmony_ci    return i::WasmCapiFunction::cast(*function).GetSerializedSignature();
14301cb0ef41Sopenharmony_ci  }
14311cb0ef41Sopenharmony_ci};
14321cb0ef41Sopenharmony_ci
14331cb0ef41Sopenharmony_ci// Explicit instantiation makes the linker happy for component builds of
14341cb0ef41Sopenharmony_ci// wasm_api_tests.
14351cb0ef41Sopenharmony_ciconstexpr i::wasm::ValueType SignatureHelper::kMarker;
14361cb0ef41Sopenharmony_ci
14371cb0ef41Sopenharmony_ciauto make_func(Store* store_abs, FuncData* data) -> own<Func> {
14381cb0ef41Sopenharmony_ci  auto store = impl(store_abs);
14391cb0ef41Sopenharmony_ci  i::Isolate* isolate = store->i_isolate();
14401cb0ef41Sopenharmony_ci  i::HandleScope handle_scope(isolate);
14411cb0ef41Sopenharmony_ci  CheckAndHandleInterrupts(isolate);
14421cb0ef41Sopenharmony_ci  i::Handle<i::Managed<FuncData>> embedder_data =
14431cb0ef41Sopenharmony_ci      i::Managed<FuncData>::FromRawPtr(isolate, sizeof(FuncData), data);
14441cb0ef41Sopenharmony_ci  i::Handle<i::WasmCapiFunction> function = i::WasmCapiFunction::New(
14451cb0ef41Sopenharmony_ci      isolate, reinterpret_cast<i::Address>(&FuncData::v8_callback),
14461cb0ef41Sopenharmony_ci      embedder_data, SignatureHelper::Serialize(isolate, data->type.get()));
14471cb0ef41Sopenharmony_ci  i::WasmApiFunctionRef::cast(
14481cb0ef41Sopenharmony_ci      function->shared().wasm_capi_function_data().internal().ref())
14491cb0ef41Sopenharmony_ci      .set_callable(*function);
14501cb0ef41Sopenharmony_ci  auto func = implement<Func>::type::make(store, function);
14511cb0ef41Sopenharmony_ci  return func;
14521cb0ef41Sopenharmony_ci}
14531cb0ef41Sopenharmony_ci
14541cb0ef41Sopenharmony_ci}  // namespace
14551cb0ef41Sopenharmony_ci
14561cb0ef41Sopenharmony_ciauto Func::make(Store* store, const FuncType* type, Func::callback callback)
14571cb0ef41Sopenharmony_ci    -> own<Func> {
14581cb0ef41Sopenharmony_ci  auto data = new FuncData(store, type, FuncData::kCallback);
14591cb0ef41Sopenharmony_ci  data->callback = callback;
14601cb0ef41Sopenharmony_ci  return make_func(store, data);
14611cb0ef41Sopenharmony_ci}
14621cb0ef41Sopenharmony_ci
14631cb0ef41Sopenharmony_ciauto Func::make(Store* store, const FuncType* type, callback_with_env callback,
14641cb0ef41Sopenharmony_ci                void* env, void (*finalizer)(void*)) -> own<Func> {
14651cb0ef41Sopenharmony_ci  auto data = new FuncData(store, type, FuncData::kCallbackWithEnv);
14661cb0ef41Sopenharmony_ci  data->callback_with_env = callback;
14671cb0ef41Sopenharmony_ci  data->env = env;
14681cb0ef41Sopenharmony_ci  data->finalizer = finalizer;
14691cb0ef41Sopenharmony_ci  return make_func(store, data);
14701cb0ef41Sopenharmony_ci}
14711cb0ef41Sopenharmony_ci
14721cb0ef41Sopenharmony_ciauto Func::type() const -> own<FuncType> {
14731cb0ef41Sopenharmony_ci  i::Handle<i::JSFunction> func = impl(this)->v8_object();
14741cb0ef41Sopenharmony_ci  if (i::WasmCapiFunction::IsWasmCapiFunction(*func)) {
14751cb0ef41Sopenharmony_ci    return SignatureHelper::Deserialize(SignatureHelper::GetSig(func));
14761cb0ef41Sopenharmony_ci  }
14771cb0ef41Sopenharmony_ci  DCHECK(i::WasmExportedFunction::IsWasmExportedFunction(*func));
14781cb0ef41Sopenharmony_ci  i::Handle<i::WasmExportedFunction> function =
14791cb0ef41Sopenharmony_ci      i::Handle<i::WasmExportedFunction>::cast(func);
14801cb0ef41Sopenharmony_ci  return FunctionSigToFuncType(
14811cb0ef41Sopenharmony_ci      function->instance().module()->functions[function->function_index()].sig);
14821cb0ef41Sopenharmony_ci}
14831cb0ef41Sopenharmony_ci
14841cb0ef41Sopenharmony_ciauto Func::param_arity() const -> size_t {
14851cb0ef41Sopenharmony_ci  i::Handle<i::JSFunction> func = impl(this)->v8_object();
14861cb0ef41Sopenharmony_ci  if (i::WasmCapiFunction::IsWasmCapiFunction(*func)) {
14871cb0ef41Sopenharmony_ci    return SignatureHelper::ParamArity(SignatureHelper::GetSig(func));
14881cb0ef41Sopenharmony_ci  }
14891cb0ef41Sopenharmony_ci  DCHECK(i::WasmExportedFunction::IsWasmExportedFunction(*func));
14901cb0ef41Sopenharmony_ci  i::Handle<i::WasmExportedFunction> function =
14911cb0ef41Sopenharmony_ci      i::Handle<i::WasmExportedFunction>::cast(func);
14921cb0ef41Sopenharmony_ci  const i::wasm::FunctionSig* sig =
14931cb0ef41Sopenharmony_ci      function->instance().module()->functions[function->function_index()].sig;
14941cb0ef41Sopenharmony_ci  return sig->parameter_count();
14951cb0ef41Sopenharmony_ci}
14961cb0ef41Sopenharmony_ci
14971cb0ef41Sopenharmony_ciauto Func::result_arity() const -> size_t {
14981cb0ef41Sopenharmony_ci  i::Handle<i::JSFunction> func = impl(this)->v8_object();
14991cb0ef41Sopenharmony_ci  if (i::WasmCapiFunction::IsWasmCapiFunction(*func)) {
15001cb0ef41Sopenharmony_ci    return SignatureHelper::ResultArity(SignatureHelper::GetSig(func));
15011cb0ef41Sopenharmony_ci  }
15021cb0ef41Sopenharmony_ci  DCHECK(i::WasmExportedFunction::IsWasmExportedFunction(*func));
15031cb0ef41Sopenharmony_ci  i::Handle<i::WasmExportedFunction> function =
15041cb0ef41Sopenharmony_ci      i::Handle<i::WasmExportedFunction>::cast(func);
15051cb0ef41Sopenharmony_ci  const i::wasm::FunctionSig* sig =
15061cb0ef41Sopenharmony_ci      function->instance().module()->functions[function->function_index()].sig;
15071cb0ef41Sopenharmony_ci  return sig->return_count();
15081cb0ef41Sopenharmony_ci}
15091cb0ef41Sopenharmony_ci
15101cb0ef41Sopenharmony_cinamespace {
15111cb0ef41Sopenharmony_ci
15121cb0ef41Sopenharmony_ciown<Ref> V8RefValueToWasm(StoreImpl* store, i::Handle<i::Object> value) {
15131cb0ef41Sopenharmony_ci  if (value->IsNull(store->i_isolate())) return nullptr;
15141cb0ef41Sopenharmony_ci  return implement<Ref>::type::make(store,
15151cb0ef41Sopenharmony_ci                                    i::Handle<i::JSReceiver>::cast(value));
15161cb0ef41Sopenharmony_ci}
15171cb0ef41Sopenharmony_ci
15181cb0ef41Sopenharmony_cii::Handle<i::Object> WasmRefToV8(i::Isolate* isolate, const Ref* ref) {
15191cb0ef41Sopenharmony_ci  if (ref == nullptr) return i::ReadOnlyRoots(isolate).null_value_handle();
15201cb0ef41Sopenharmony_ci  return impl(ref)->v8_object();
15211cb0ef41Sopenharmony_ci}
15221cb0ef41Sopenharmony_ci
15231cb0ef41Sopenharmony_civoid PrepareFunctionData(i::Isolate* isolate,
15241cb0ef41Sopenharmony_ci                         i::Handle<i::WasmExportedFunctionData> function_data,
15251cb0ef41Sopenharmony_ci                         const i::wasm::FunctionSig* sig,
15261cb0ef41Sopenharmony_ci                         const i::wasm::WasmModule* module) {
15271cb0ef41Sopenharmony_ci  // If the data is already populated, return immediately.
15281cb0ef41Sopenharmony_ci  if (function_data->c_wrapper_code() != *BUILTIN_CODE(isolate, Illegal)) {
15291cb0ef41Sopenharmony_ci    return;
15301cb0ef41Sopenharmony_ci  }
15311cb0ef41Sopenharmony_ci  // Compile wrapper code.
15321cb0ef41Sopenharmony_ci  i::Handle<i::CodeT> wrapper_code =
15331cb0ef41Sopenharmony_ci      i::compiler::CompileCWasmEntry(isolate, sig, module);
15341cb0ef41Sopenharmony_ci  function_data->set_c_wrapper_code(*wrapper_code);
15351cb0ef41Sopenharmony_ci  // Compute packed args size.
15361cb0ef41Sopenharmony_ci  function_data->set_packed_args_size(
15371cb0ef41Sopenharmony_ci      i::wasm::CWasmArgumentsPacker::TotalSize(sig));
15381cb0ef41Sopenharmony_ci}
15391cb0ef41Sopenharmony_ci
15401cb0ef41Sopenharmony_civoid PushArgs(const i::wasm::FunctionSig* sig, const Val args[],
15411cb0ef41Sopenharmony_ci              i::wasm::CWasmArgumentsPacker* packer, StoreImpl* store) {
15421cb0ef41Sopenharmony_ci  for (size_t i = 0; i < sig->parameter_count(); i++) {
15431cb0ef41Sopenharmony_ci    i::wasm::ValueType type = sig->GetParam(i);
15441cb0ef41Sopenharmony_ci    switch (type.kind()) {
15451cb0ef41Sopenharmony_ci      case i::wasm::kI32:
15461cb0ef41Sopenharmony_ci        packer->Push(args[i].i32());
15471cb0ef41Sopenharmony_ci        break;
15481cb0ef41Sopenharmony_ci      case i::wasm::kI64:
15491cb0ef41Sopenharmony_ci        packer->Push(args[i].i64());
15501cb0ef41Sopenharmony_ci        break;
15511cb0ef41Sopenharmony_ci      case i::wasm::kF32:
15521cb0ef41Sopenharmony_ci        packer->Push(args[i].f32());
15531cb0ef41Sopenharmony_ci        break;
15541cb0ef41Sopenharmony_ci      case i::wasm::kF64:
15551cb0ef41Sopenharmony_ci        packer->Push(args[i].f64());
15561cb0ef41Sopenharmony_ci        break;
15571cb0ef41Sopenharmony_ci      case i::wasm::kRef:
15581cb0ef41Sopenharmony_ci      case i::wasm::kOptRef:
15591cb0ef41Sopenharmony_ci        // TODO(7748): Make sure this works for all heap types.
15601cb0ef41Sopenharmony_ci        packer->Push(WasmRefToV8(store->i_isolate(), args[i].ref())->ptr());
15611cb0ef41Sopenharmony_ci        break;
15621cb0ef41Sopenharmony_ci      case i::wasm::kRtt:
15631cb0ef41Sopenharmony_ci      case i::wasm::kS128:
15641cb0ef41Sopenharmony_ci        // TODO(7748): Implement.
15651cb0ef41Sopenharmony_ci        UNIMPLEMENTED();
15661cb0ef41Sopenharmony_ci      case i::wasm::kI8:
15671cb0ef41Sopenharmony_ci      case i::wasm::kI16:
15681cb0ef41Sopenharmony_ci      case i::wasm::kVoid:
15691cb0ef41Sopenharmony_ci      case i::wasm::kBottom:
15701cb0ef41Sopenharmony_ci        UNREACHABLE();
15711cb0ef41Sopenharmony_ci    }
15721cb0ef41Sopenharmony_ci  }
15731cb0ef41Sopenharmony_ci}
15741cb0ef41Sopenharmony_ci
15751cb0ef41Sopenharmony_civoid PopArgs(const i::wasm::FunctionSig* sig, Val results[],
15761cb0ef41Sopenharmony_ci             i::wasm::CWasmArgumentsPacker* packer, StoreImpl* store) {
15771cb0ef41Sopenharmony_ci  packer->Reset();
15781cb0ef41Sopenharmony_ci  for (size_t i = 0; i < sig->return_count(); i++) {
15791cb0ef41Sopenharmony_ci    i::wasm::ValueType type = sig->GetReturn(i);
15801cb0ef41Sopenharmony_ci    switch (type.kind()) {
15811cb0ef41Sopenharmony_ci      case i::wasm::kI32:
15821cb0ef41Sopenharmony_ci        results[i] = Val(packer->Pop<int32_t>());
15831cb0ef41Sopenharmony_ci        break;
15841cb0ef41Sopenharmony_ci      case i::wasm::kI64:
15851cb0ef41Sopenharmony_ci        results[i] = Val(packer->Pop<int64_t>());
15861cb0ef41Sopenharmony_ci        break;
15871cb0ef41Sopenharmony_ci      case i::wasm::kF32:
15881cb0ef41Sopenharmony_ci        results[i] = Val(packer->Pop<float>());
15891cb0ef41Sopenharmony_ci        break;
15901cb0ef41Sopenharmony_ci      case i::wasm::kF64:
15911cb0ef41Sopenharmony_ci        results[i] = Val(packer->Pop<double>());
15921cb0ef41Sopenharmony_ci        break;
15931cb0ef41Sopenharmony_ci      case i::wasm::kRef:
15941cb0ef41Sopenharmony_ci      case i::wasm::kOptRef: {
15951cb0ef41Sopenharmony_ci        // TODO(7748): Make sure this works for all heap types.
15961cb0ef41Sopenharmony_ci        i::Address raw = packer->Pop<i::Address>();
15971cb0ef41Sopenharmony_ci        i::Handle<i::Object> obj(i::Object(raw), store->i_isolate());
15981cb0ef41Sopenharmony_ci        results[i] = Val(V8RefValueToWasm(store, obj));
15991cb0ef41Sopenharmony_ci        break;
16001cb0ef41Sopenharmony_ci      }
16011cb0ef41Sopenharmony_ci      case i::wasm::kRtt:
16021cb0ef41Sopenharmony_ci      case i::wasm::kS128:
16031cb0ef41Sopenharmony_ci        // TODO(7748): Implement.
16041cb0ef41Sopenharmony_ci        UNIMPLEMENTED();
16051cb0ef41Sopenharmony_ci      case i::wasm::kI8:
16061cb0ef41Sopenharmony_ci      case i::wasm::kI16:
16071cb0ef41Sopenharmony_ci      case i::wasm::kVoid:
16081cb0ef41Sopenharmony_ci      case i::wasm::kBottom:
16091cb0ef41Sopenharmony_ci        UNREACHABLE();
16101cb0ef41Sopenharmony_ci    }
16111cb0ef41Sopenharmony_ci  }
16121cb0ef41Sopenharmony_ci}
16131cb0ef41Sopenharmony_ci
16141cb0ef41Sopenharmony_ciown<Trap> CallWasmCapiFunction(i::WasmCapiFunctionData data, const Val args[],
16151cb0ef41Sopenharmony_ci                               Val results[]) {
16161cb0ef41Sopenharmony_ci  FuncData* func_data = i::Managed<FuncData>::cast(data.embedder_data()).raw();
16171cb0ef41Sopenharmony_ci  if (func_data->kind == FuncData::kCallback) {
16181cb0ef41Sopenharmony_ci    return (func_data->callback)(args, results);
16191cb0ef41Sopenharmony_ci  }
16201cb0ef41Sopenharmony_ci  DCHECK(func_data->kind == FuncData::kCallbackWithEnv);
16211cb0ef41Sopenharmony_ci  return (func_data->callback_with_env)(func_data->env, args, results);
16221cb0ef41Sopenharmony_ci}
16231cb0ef41Sopenharmony_ci
16241cb0ef41Sopenharmony_cii::Handle<i::JSReceiver> GetProperException(
16251cb0ef41Sopenharmony_ci    i::Isolate* isolate, i::Handle<i::Object> maybe_exception) {
16261cb0ef41Sopenharmony_ci  if (maybe_exception->IsJSReceiver()) {
16271cb0ef41Sopenharmony_ci    return i::Handle<i::JSReceiver>::cast(maybe_exception);
16281cb0ef41Sopenharmony_ci  }
16291cb0ef41Sopenharmony_ci  i::MaybeHandle<i::String> maybe_string =
16301cb0ef41Sopenharmony_ci      i::Object::ToString(isolate, maybe_exception);
16311cb0ef41Sopenharmony_ci  i::Handle<i::String> string = isolate->factory()->empty_string();
16321cb0ef41Sopenharmony_ci  if (!maybe_string.ToHandle(&string)) {
16331cb0ef41Sopenharmony_ci    // If converting the {maybe_exception} to string threw another exception,
16341cb0ef41Sopenharmony_ci    // just give up and leave {string} as the empty string.
16351cb0ef41Sopenharmony_ci    isolate->clear_pending_exception();
16361cb0ef41Sopenharmony_ci  }
16371cb0ef41Sopenharmony_ci  // {NewError} cannot fail when its input is a plain String, so we always
16381cb0ef41Sopenharmony_ci  // get an Error object here.
16391cb0ef41Sopenharmony_ci  return i::Handle<i::JSReceiver>::cast(
16401cb0ef41Sopenharmony_ci      isolate->factory()->NewError(isolate->error_function(), string));
16411cb0ef41Sopenharmony_ci}
16421cb0ef41Sopenharmony_ci
16431cb0ef41Sopenharmony_ci}  // namespace
16441cb0ef41Sopenharmony_ci
16451cb0ef41Sopenharmony_ciauto Func::call(const Val args[], Val results[]) const -> own<Trap> {
16461cb0ef41Sopenharmony_ci  auto func = impl(this);
16471cb0ef41Sopenharmony_ci  auto store = func->store();
16481cb0ef41Sopenharmony_ci  auto isolate = store->i_isolate();
16491cb0ef41Sopenharmony_ci  i::HandleScope handle_scope(isolate);
16501cb0ef41Sopenharmony_ci  i::Object raw_function_data =
16511cb0ef41Sopenharmony_ci      func->v8_object()->shared().function_data(v8::kAcquireLoad);
16521cb0ef41Sopenharmony_ci
16531cb0ef41Sopenharmony_ci  // WasmCapiFunctions can be called directly.
16541cb0ef41Sopenharmony_ci  if (raw_function_data.IsWasmCapiFunctionData()) {
16551cb0ef41Sopenharmony_ci    return CallWasmCapiFunction(
16561cb0ef41Sopenharmony_ci        i::WasmCapiFunctionData::cast(raw_function_data), args, results);
16571cb0ef41Sopenharmony_ci  }
16581cb0ef41Sopenharmony_ci
16591cb0ef41Sopenharmony_ci  DCHECK(raw_function_data.IsWasmExportedFunctionData());
16601cb0ef41Sopenharmony_ci  i::Handle<i::WasmExportedFunctionData> function_data(
16611cb0ef41Sopenharmony_ci      i::WasmExportedFunctionData::cast(raw_function_data), isolate);
16621cb0ef41Sopenharmony_ci  i::Handle<i::WasmInstanceObject> instance(function_data->instance(), isolate);
16631cb0ef41Sopenharmony_ci  int function_index = function_data->function_index();
16641cb0ef41Sopenharmony_ci  // Caching {sig} would give a ~10% reduction in overhead.
16651cb0ef41Sopenharmony_ci  const i::wasm::FunctionSig* sig =
16661cb0ef41Sopenharmony_ci      instance->module()->functions[function_index].sig;
16671cb0ef41Sopenharmony_ci  PrepareFunctionData(isolate, function_data, sig, instance->module());
16681cb0ef41Sopenharmony_ci  i::Handle<i::CodeT> wrapper_code(function_data->c_wrapper_code(), isolate);
16691cb0ef41Sopenharmony_ci  i::Address call_target = function_data->internal().foreign_address();
16701cb0ef41Sopenharmony_ci
16711cb0ef41Sopenharmony_ci  i::wasm::CWasmArgumentsPacker packer(function_data->packed_args_size());
16721cb0ef41Sopenharmony_ci  PushArgs(sig, args, &packer, store);
16731cb0ef41Sopenharmony_ci
16741cb0ef41Sopenharmony_ci  i::Handle<i::Object> object_ref = instance;
16751cb0ef41Sopenharmony_ci  if (function_index <
16761cb0ef41Sopenharmony_ci      static_cast<int>(instance->module()->num_imported_functions)) {
16771cb0ef41Sopenharmony_ci    object_ref = i::handle(
16781cb0ef41Sopenharmony_ci        instance->imported_function_refs().get(function_index), isolate);
16791cb0ef41Sopenharmony_ci    if (object_ref->IsWasmApiFunctionRef()) {
16801cb0ef41Sopenharmony_ci      i::JSFunction jsfunc = i::JSFunction::cast(
16811cb0ef41Sopenharmony_ci          i::WasmApiFunctionRef::cast(*object_ref).callable());
16821cb0ef41Sopenharmony_ci      i::Object data = jsfunc.shared().function_data(v8::kAcquireLoad);
16831cb0ef41Sopenharmony_ci      if (data.IsWasmCapiFunctionData()) {
16841cb0ef41Sopenharmony_ci        return CallWasmCapiFunction(i::WasmCapiFunctionData::cast(data), args,
16851cb0ef41Sopenharmony_ci                                    results);
16861cb0ef41Sopenharmony_ci      }
16871cb0ef41Sopenharmony_ci      // TODO(jkummerow): Imported and then re-exported JavaScript functions
16881cb0ef41Sopenharmony_ci      // are not supported yet. If we support C-API + JavaScript, we'll need
16891cb0ef41Sopenharmony_ci      // to call those here.
16901cb0ef41Sopenharmony_ci      UNIMPLEMENTED();
16911cb0ef41Sopenharmony_ci    } else {
16921cb0ef41Sopenharmony_ci      // A WasmFunction from another module.
16931cb0ef41Sopenharmony_ci      DCHECK(object_ref->IsWasmInstanceObject());
16941cb0ef41Sopenharmony_ci    }
16951cb0ef41Sopenharmony_ci  }
16961cb0ef41Sopenharmony_ci
16971cb0ef41Sopenharmony_ci  i::Execution::CallWasm(isolate, wrapper_code, call_target, object_ref,
16981cb0ef41Sopenharmony_ci                         packer.argv());
16991cb0ef41Sopenharmony_ci
17001cb0ef41Sopenharmony_ci  if (isolate->has_pending_exception()) {
17011cb0ef41Sopenharmony_ci    i::Handle<i::Object> exception(isolate->pending_exception(), isolate);
17021cb0ef41Sopenharmony_ci    isolate->clear_pending_exception();
17031cb0ef41Sopenharmony_ci    return implement<Trap>::type::make(store,
17041cb0ef41Sopenharmony_ci                                       GetProperException(isolate, exception));
17051cb0ef41Sopenharmony_ci  }
17061cb0ef41Sopenharmony_ci
17071cb0ef41Sopenharmony_ci  PopArgs(sig, results, &packer, store);
17081cb0ef41Sopenharmony_ci  return nullptr;
17091cb0ef41Sopenharmony_ci}
17101cb0ef41Sopenharmony_ci
17111cb0ef41Sopenharmony_cii::Address FuncData::v8_callback(i::Address host_data_foreign,
17121cb0ef41Sopenharmony_ci                                 i::Address argv) {
17131cb0ef41Sopenharmony_ci  FuncData* self =
17141cb0ef41Sopenharmony_ci      i::Managed<FuncData>::cast(i::Object(host_data_foreign)).raw();
17151cb0ef41Sopenharmony_ci  StoreImpl* store = impl(self->store);
17161cb0ef41Sopenharmony_ci  i::Isolate* isolate = store->i_isolate();
17171cb0ef41Sopenharmony_ci  i::HandleScope scope(isolate);
17181cb0ef41Sopenharmony_ci
17191cb0ef41Sopenharmony_ci  const ownvec<ValType>& param_types = self->type->params();
17201cb0ef41Sopenharmony_ci  const ownvec<ValType>& result_types = self->type->results();
17211cb0ef41Sopenharmony_ci
17221cb0ef41Sopenharmony_ci  int num_param_types = static_cast<int>(param_types.size());
17231cb0ef41Sopenharmony_ci  int num_result_types = static_cast<int>(result_types.size());
17241cb0ef41Sopenharmony_ci
17251cb0ef41Sopenharmony_ci  std::unique_ptr<Val[]> params(new Val[num_param_types]);
17261cb0ef41Sopenharmony_ci  std::unique_ptr<Val[]> results(new Val[num_result_types]);
17271cb0ef41Sopenharmony_ci  i::Address p = argv;
17281cb0ef41Sopenharmony_ci  for (int i = 0; i < num_param_types; ++i) {
17291cb0ef41Sopenharmony_ci    switch (param_types[i]->kind()) {
17301cb0ef41Sopenharmony_ci      case I32:
17311cb0ef41Sopenharmony_ci        params[i] = Val(v8::base::ReadUnalignedValue<int32_t>(p));
17321cb0ef41Sopenharmony_ci        p += 4;
17331cb0ef41Sopenharmony_ci        break;
17341cb0ef41Sopenharmony_ci      case I64:
17351cb0ef41Sopenharmony_ci        params[i] = Val(v8::base::ReadUnalignedValue<int64_t>(p));
17361cb0ef41Sopenharmony_ci        p += 8;
17371cb0ef41Sopenharmony_ci        break;
17381cb0ef41Sopenharmony_ci      case F32:
17391cb0ef41Sopenharmony_ci        params[i] = Val(v8::base::ReadUnalignedValue<float32_t>(p));
17401cb0ef41Sopenharmony_ci        p += 4;
17411cb0ef41Sopenharmony_ci        break;
17421cb0ef41Sopenharmony_ci      case F64:
17431cb0ef41Sopenharmony_ci        params[i] = Val(v8::base::ReadUnalignedValue<float64_t>(p));
17441cb0ef41Sopenharmony_ci        p += 8;
17451cb0ef41Sopenharmony_ci        break;
17461cb0ef41Sopenharmony_ci      case ANYREF:
17471cb0ef41Sopenharmony_ci      case FUNCREF: {
17481cb0ef41Sopenharmony_ci        i::Address raw = v8::base::ReadUnalignedValue<i::Address>(p);
17491cb0ef41Sopenharmony_ci        p += sizeof(raw);
17501cb0ef41Sopenharmony_ci        i::Handle<i::Object> obj(i::Object(raw), isolate);
17511cb0ef41Sopenharmony_ci        params[i] = Val(V8RefValueToWasm(store, obj));
17521cb0ef41Sopenharmony_ci        break;
17531cb0ef41Sopenharmony_ci      }
17541cb0ef41Sopenharmony_ci    }
17551cb0ef41Sopenharmony_ci  }
17561cb0ef41Sopenharmony_ci
17571cb0ef41Sopenharmony_ci  own<Trap> trap;
17581cb0ef41Sopenharmony_ci  if (self->kind == kCallbackWithEnv) {
17591cb0ef41Sopenharmony_ci    trap = self->callback_with_env(self->env, params.get(), results.get());
17601cb0ef41Sopenharmony_ci  } else {
17611cb0ef41Sopenharmony_ci    trap = self->callback(params.get(), results.get());
17621cb0ef41Sopenharmony_ci  }
17631cb0ef41Sopenharmony_ci
17641cb0ef41Sopenharmony_ci  if (trap) {
17651cb0ef41Sopenharmony_ci    isolate->Throw(*impl(trap.get())->v8_object());
17661cb0ef41Sopenharmony_ci    i::Object ex = isolate->pending_exception();
17671cb0ef41Sopenharmony_ci    isolate->clear_pending_exception();
17681cb0ef41Sopenharmony_ci    return ex.ptr();
17691cb0ef41Sopenharmony_ci  }
17701cb0ef41Sopenharmony_ci
17711cb0ef41Sopenharmony_ci  p = argv;
17721cb0ef41Sopenharmony_ci  for (int i = 0; i < num_result_types; ++i) {
17731cb0ef41Sopenharmony_ci    switch (result_types[i]->kind()) {
17741cb0ef41Sopenharmony_ci      case I32:
17751cb0ef41Sopenharmony_ci        v8::base::WriteUnalignedValue(p, results[i].i32());
17761cb0ef41Sopenharmony_ci        p += 4;
17771cb0ef41Sopenharmony_ci        break;
17781cb0ef41Sopenharmony_ci      case I64:
17791cb0ef41Sopenharmony_ci        v8::base::WriteUnalignedValue(p, results[i].i64());
17801cb0ef41Sopenharmony_ci        p += 8;
17811cb0ef41Sopenharmony_ci        break;
17821cb0ef41Sopenharmony_ci      case F32:
17831cb0ef41Sopenharmony_ci        v8::base::WriteUnalignedValue(p, results[i].f32());
17841cb0ef41Sopenharmony_ci        p += 4;
17851cb0ef41Sopenharmony_ci        break;
17861cb0ef41Sopenharmony_ci      case F64:
17871cb0ef41Sopenharmony_ci        v8::base::WriteUnalignedValue(p, results[i].f64());
17881cb0ef41Sopenharmony_ci        p += 8;
17891cb0ef41Sopenharmony_ci        break;
17901cb0ef41Sopenharmony_ci      case ANYREF:
17911cb0ef41Sopenharmony_ci      case FUNCREF: {
17921cb0ef41Sopenharmony_ci        v8::base::WriteUnalignedValue(
17931cb0ef41Sopenharmony_ci            p, WasmRefToV8(isolate, results[i].ref())->ptr());
17941cb0ef41Sopenharmony_ci        p += sizeof(i::Address);
17951cb0ef41Sopenharmony_ci        break;
17961cb0ef41Sopenharmony_ci      }
17971cb0ef41Sopenharmony_ci    }
17981cb0ef41Sopenharmony_ci  }
17991cb0ef41Sopenharmony_ci  return i::kNullAddress;
18001cb0ef41Sopenharmony_ci}
18011cb0ef41Sopenharmony_ci
18021cb0ef41Sopenharmony_ci// Global Instances
18031cb0ef41Sopenharmony_ci
18041cb0ef41Sopenharmony_citemplate <>
18051cb0ef41Sopenharmony_cistruct implement<Global> {
18061cb0ef41Sopenharmony_ci  using type = RefImpl<Global, i::WasmGlobalObject>;
18071cb0ef41Sopenharmony_ci};
18081cb0ef41Sopenharmony_ci
18091cb0ef41Sopenharmony_ciGlobal::~Global() = default;
18101cb0ef41Sopenharmony_ci
18111cb0ef41Sopenharmony_ciauto Global::copy() const -> own<Global> { return impl(this)->copy(); }
18121cb0ef41Sopenharmony_ci
18131cb0ef41Sopenharmony_ciauto Global::make(Store* store_abs, const GlobalType* type, const Val& val)
18141cb0ef41Sopenharmony_ci    -> own<Global> {
18151cb0ef41Sopenharmony_ci  StoreImpl* store = impl(store_abs);
18161cb0ef41Sopenharmony_ci  i::Isolate* isolate = store->i_isolate();
18171cb0ef41Sopenharmony_ci  i::HandleScope handle_scope(isolate);
18181cb0ef41Sopenharmony_ci  CheckAndHandleInterrupts(isolate);
18191cb0ef41Sopenharmony_ci
18201cb0ef41Sopenharmony_ci  DCHECK_EQ(type->content()->kind(), val.kind());
18211cb0ef41Sopenharmony_ci
18221cb0ef41Sopenharmony_ci  i::wasm::ValueType i_type = WasmValKindToV8(type->content()->kind());
18231cb0ef41Sopenharmony_ci  bool is_mutable = (type->mutability() == VAR);
18241cb0ef41Sopenharmony_ci  const int32_t offset = 0;
18251cb0ef41Sopenharmony_ci  i::Handle<i::WasmGlobalObject> obj =
18261cb0ef41Sopenharmony_ci      i::WasmGlobalObject::New(isolate, i::Handle<i::WasmInstanceObject>(),
18271cb0ef41Sopenharmony_ci                               i::MaybeHandle<i::JSArrayBuffer>(),
18281cb0ef41Sopenharmony_ci                               i::MaybeHandle<i::FixedArray>(), i_type, offset,
18291cb0ef41Sopenharmony_ci                               is_mutable)
18301cb0ef41Sopenharmony_ci          .ToHandleChecked();
18311cb0ef41Sopenharmony_ci
18321cb0ef41Sopenharmony_ci  auto global = implement<Global>::type::make(store, obj);
18331cb0ef41Sopenharmony_ci  assert(global);
18341cb0ef41Sopenharmony_ci  global->set(val);
18351cb0ef41Sopenharmony_ci  return global;
18361cb0ef41Sopenharmony_ci}
18371cb0ef41Sopenharmony_ci
18381cb0ef41Sopenharmony_ciauto Global::type() const -> own<GlobalType> {
18391cb0ef41Sopenharmony_ci  i::Handle<i::WasmGlobalObject> v8_global = impl(this)->v8_object();
18401cb0ef41Sopenharmony_ci  ValKind kind = V8ValueTypeToWasm(v8_global->type());
18411cb0ef41Sopenharmony_ci  Mutability mutability = v8_global->is_mutable() ? VAR : CONST;
18421cb0ef41Sopenharmony_ci  return GlobalType::make(ValType::make(kind), mutability);
18431cb0ef41Sopenharmony_ci}
18441cb0ef41Sopenharmony_ci
18451cb0ef41Sopenharmony_ciauto Global::get() const -> Val {
18461cb0ef41Sopenharmony_ci  i::Handle<i::WasmGlobalObject> v8_global = impl(this)->v8_object();
18471cb0ef41Sopenharmony_ci  switch (v8_global->type().kind()) {
18481cb0ef41Sopenharmony_ci    case i::wasm::kI32:
18491cb0ef41Sopenharmony_ci      return Val(v8_global->GetI32());
18501cb0ef41Sopenharmony_ci    case i::wasm::kI64:
18511cb0ef41Sopenharmony_ci      return Val(v8_global->GetI64());
18521cb0ef41Sopenharmony_ci    case i::wasm::kF32:
18531cb0ef41Sopenharmony_ci      return Val(v8_global->GetF32());
18541cb0ef41Sopenharmony_ci    case i::wasm::kF64:
18551cb0ef41Sopenharmony_ci      return Val(v8_global->GetF64());
18561cb0ef41Sopenharmony_ci    case i::wasm::kRef:
18571cb0ef41Sopenharmony_ci    case i::wasm::kOptRef: {
18581cb0ef41Sopenharmony_ci      // TODO(7748): Make sure this works for all heap types.
18591cb0ef41Sopenharmony_ci      StoreImpl* store = impl(this)->store();
18601cb0ef41Sopenharmony_ci      i::HandleScope scope(store->i_isolate());
18611cb0ef41Sopenharmony_ci      return Val(V8RefValueToWasm(store, v8_global->GetRef()));
18621cb0ef41Sopenharmony_ci    }
18631cb0ef41Sopenharmony_ci    case i::wasm::kRtt:
18641cb0ef41Sopenharmony_ci    case i::wasm::kS128:
18651cb0ef41Sopenharmony_ci      // TODO(7748): Implement these.
18661cb0ef41Sopenharmony_ci      UNIMPLEMENTED();
18671cb0ef41Sopenharmony_ci    case i::wasm::kI8:
18681cb0ef41Sopenharmony_ci    case i::wasm::kI16:
18691cb0ef41Sopenharmony_ci    case i::wasm::kVoid:
18701cb0ef41Sopenharmony_ci    case i::wasm::kBottom:
18711cb0ef41Sopenharmony_ci      UNREACHABLE();
18721cb0ef41Sopenharmony_ci  }
18731cb0ef41Sopenharmony_ci}
18741cb0ef41Sopenharmony_ci
18751cb0ef41Sopenharmony_civoid Global::set(const Val& val) {
18761cb0ef41Sopenharmony_ci  i::Handle<i::WasmGlobalObject> v8_global = impl(this)->v8_object();
18771cb0ef41Sopenharmony_ci  switch (val.kind()) {
18781cb0ef41Sopenharmony_ci    case I32:
18791cb0ef41Sopenharmony_ci      return v8_global->SetI32(val.i32());
18801cb0ef41Sopenharmony_ci    case I64:
18811cb0ef41Sopenharmony_ci      return v8_global->SetI64(val.i64());
18821cb0ef41Sopenharmony_ci    case F32:
18831cb0ef41Sopenharmony_ci      return v8_global->SetF32(val.f32());
18841cb0ef41Sopenharmony_ci    case F64:
18851cb0ef41Sopenharmony_ci      return v8_global->SetF64(val.f64());
18861cb0ef41Sopenharmony_ci    case ANYREF:
18871cb0ef41Sopenharmony_ci      return v8_global->SetExternRef(
18881cb0ef41Sopenharmony_ci          WasmRefToV8(impl(this)->store()->i_isolate(), val.ref()));
18891cb0ef41Sopenharmony_ci    case FUNCREF: {
18901cb0ef41Sopenharmony_ci      i::Isolate* isolate = impl(this)->store()->i_isolate();
18911cb0ef41Sopenharmony_ci      bool result =
18921cb0ef41Sopenharmony_ci          v8_global->SetFuncRef(isolate, WasmRefToV8(isolate, val.ref()));
18931cb0ef41Sopenharmony_ci      DCHECK(result);
18941cb0ef41Sopenharmony_ci      USE(result);
18951cb0ef41Sopenharmony_ci      return;
18961cb0ef41Sopenharmony_ci    }
18971cb0ef41Sopenharmony_ci    default:
18981cb0ef41Sopenharmony_ci      // TODO(wasm+): support new value types
18991cb0ef41Sopenharmony_ci      UNREACHABLE();
19001cb0ef41Sopenharmony_ci  }
19011cb0ef41Sopenharmony_ci}
19021cb0ef41Sopenharmony_ci
19031cb0ef41Sopenharmony_ci// Table Instances
19041cb0ef41Sopenharmony_ci
19051cb0ef41Sopenharmony_citemplate <>
19061cb0ef41Sopenharmony_cistruct implement<Table> {
19071cb0ef41Sopenharmony_ci  using type = RefImpl<Table, i::WasmTableObject>;
19081cb0ef41Sopenharmony_ci};
19091cb0ef41Sopenharmony_ci
19101cb0ef41Sopenharmony_ciTable::~Table() = default;
19111cb0ef41Sopenharmony_ci
19121cb0ef41Sopenharmony_ciauto Table::copy() const -> own<Table> { return impl(this)->copy(); }
19131cb0ef41Sopenharmony_ci
19141cb0ef41Sopenharmony_ciauto Table::make(Store* store_abs, const TableType* type, const Ref* ref)
19151cb0ef41Sopenharmony_ci    -> own<Table> {
19161cb0ef41Sopenharmony_ci  StoreImpl* store = impl(store_abs);
19171cb0ef41Sopenharmony_ci  i::Isolate* isolate = store->i_isolate();
19181cb0ef41Sopenharmony_ci  i::HandleScope scope(isolate);
19191cb0ef41Sopenharmony_ci  CheckAndHandleInterrupts(isolate);
19201cb0ef41Sopenharmony_ci
19211cb0ef41Sopenharmony_ci  // Get "element".
19221cb0ef41Sopenharmony_ci  i::wasm::ValueType i_type;
19231cb0ef41Sopenharmony_ci  switch (type->element()->kind()) {
19241cb0ef41Sopenharmony_ci    case FUNCREF:
19251cb0ef41Sopenharmony_ci      i_type = i::wasm::kWasmFuncRef;
19261cb0ef41Sopenharmony_ci      break;
19271cb0ef41Sopenharmony_ci    case ANYREF:
19281cb0ef41Sopenharmony_ci      // See Engine::make().
19291cb0ef41Sopenharmony_ci      i_type = i::wasm::kWasmAnyRef;
19301cb0ef41Sopenharmony_ci      break;
19311cb0ef41Sopenharmony_ci    default:
19321cb0ef41Sopenharmony_ci      UNREACHABLE();
19331cb0ef41Sopenharmony_ci  }
19341cb0ef41Sopenharmony_ci
19351cb0ef41Sopenharmony_ci  const Limits& limits = type->limits();
19361cb0ef41Sopenharmony_ci  uint32_t minimum = limits.min;
19371cb0ef41Sopenharmony_ci  if (minimum > i::wasm::max_table_init_entries()) return nullptr;
19381cb0ef41Sopenharmony_ci  uint32_t maximum = limits.max;
19391cb0ef41Sopenharmony_ci  bool has_maximum = false;
19401cb0ef41Sopenharmony_ci  if (maximum != Limits(0).max) {
19411cb0ef41Sopenharmony_ci    has_maximum = true;
19421cb0ef41Sopenharmony_ci    if (maximum < minimum) return nullptr;
19431cb0ef41Sopenharmony_ci    if (maximum > i::wasm::max_table_init_entries()) return nullptr;
19441cb0ef41Sopenharmony_ci  }
19451cb0ef41Sopenharmony_ci
19461cb0ef41Sopenharmony_ci  i::Handle<i::FixedArray> backing_store;
19471cb0ef41Sopenharmony_ci  i::Handle<i::WasmTableObject> table_obj = i::WasmTableObject::New(
19481cb0ef41Sopenharmony_ci      isolate, i::Handle<i::WasmInstanceObject>(), i_type, minimum, has_maximum,
19491cb0ef41Sopenharmony_ci      maximum, &backing_store, isolate->factory()->null_value());
19501cb0ef41Sopenharmony_ci
19511cb0ef41Sopenharmony_ci  if (ref) {
19521cb0ef41Sopenharmony_ci    i::Handle<i::JSReceiver> init = impl(ref)->v8_object();
19531cb0ef41Sopenharmony_ci    DCHECK(i::wasm::max_table_init_entries() <= i::kMaxInt);
19541cb0ef41Sopenharmony_ci    for (int i = 0; i < static_cast<int>(minimum); i++) {
19551cb0ef41Sopenharmony_ci      // This doesn't call WasmTableObject::Set because the table has
19561cb0ef41Sopenharmony_ci      // just been created, so it can't be imported by any instances
19571cb0ef41Sopenharmony_ci      // yet that might require updating.
19581cb0ef41Sopenharmony_ci      DCHECK_EQ(table_obj->dispatch_tables().length(), 0);
19591cb0ef41Sopenharmony_ci      backing_store->set(i, *init);
19601cb0ef41Sopenharmony_ci    }
19611cb0ef41Sopenharmony_ci  }
19621cb0ef41Sopenharmony_ci  return implement<Table>::type::make(store, table_obj);
19631cb0ef41Sopenharmony_ci}
19641cb0ef41Sopenharmony_ci
19651cb0ef41Sopenharmony_ciauto Table::type() const -> own<TableType> {
19661cb0ef41Sopenharmony_ci  i::Handle<i::WasmTableObject> table = impl(this)->v8_object();
19671cb0ef41Sopenharmony_ci  uint32_t min = table->current_length();
19681cb0ef41Sopenharmony_ci  uint32_t max;
19691cb0ef41Sopenharmony_ci  if (!table->maximum_length().ToUint32(&max)) max = 0xFFFFFFFFu;
19701cb0ef41Sopenharmony_ci  ValKind kind;
19711cb0ef41Sopenharmony_ci  switch (table->type().heap_representation()) {
19721cb0ef41Sopenharmony_ci    case i::wasm::HeapType::kFunc:
19731cb0ef41Sopenharmony_ci      kind = FUNCREF;
19741cb0ef41Sopenharmony_ci      break;
19751cb0ef41Sopenharmony_ci    case i::wasm::HeapType::kAny:
19761cb0ef41Sopenharmony_ci      kind = ANYREF;
19771cb0ef41Sopenharmony_ci      break;
19781cb0ef41Sopenharmony_ci    default:
19791cb0ef41Sopenharmony_ci      UNREACHABLE();
19801cb0ef41Sopenharmony_ci  }
19811cb0ef41Sopenharmony_ci  return TableType::make(ValType::make(kind), Limits(min, max));
19821cb0ef41Sopenharmony_ci}
19831cb0ef41Sopenharmony_ci
19841cb0ef41Sopenharmony_ciauto Table::get(size_t index) const -> own<Ref> {
19851cb0ef41Sopenharmony_ci  i::Handle<i::WasmTableObject> table = impl(this)->v8_object();
19861cb0ef41Sopenharmony_ci  if (index >= static_cast<size_t>(table->current_length())) return own<Ref>();
19871cb0ef41Sopenharmony_ci  i::Isolate* isolate = table->GetIsolate();
19881cb0ef41Sopenharmony_ci  i::HandleScope handle_scope(isolate);
19891cb0ef41Sopenharmony_ci  i::Handle<i::Object> result =
19901cb0ef41Sopenharmony_ci      i::WasmTableObject::Get(isolate, table, static_cast<uint32_t>(index));
19911cb0ef41Sopenharmony_ci  // TODO(jkummerow): If we support both JavaScript and the C-API at the same
19921cb0ef41Sopenharmony_ci  // time, we need to handle Smis and other JS primitives here.
19931cb0ef41Sopenharmony_ci  if (result->IsWasmInternalFunction()) {
19941cb0ef41Sopenharmony_ci    result = handle(
19951cb0ef41Sopenharmony_ci        i::Handle<i::WasmInternalFunction>::cast(result)->external(), isolate);
19961cb0ef41Sopenharmony_ci  }
19971cb0ef41Sopenharmony_ci  DCHECK(result->IsNull(isolate) || result->IsJSReceiver());
19981cb0ef41Sopenharmony_ci  return V8RefValueToWasm(impl(this)->store(), result);
19991cb0ef41Sopenharmony_ci}
20001cb0ef41Sopenharmony_ci
20011cb0ef41Sopenharmony_ciauto Table::set(size_t index, const Ref* ref) -> bool {
20021cb0ef41Sopenharmony_ci  i::Handle<i::WasmTableObject> table = impl(this)->v8_object();
20031cb0ef41Sopenharmony_ci  if (index >= static_cast<size_t>(table->current_length())) return false;
20041cb0ef41Sopenharmony_ci  i::Isolate* isolate = table->GetIsolate();
20051cb0ef41Sopenharmony_ci  i::HandleScope handle_scope(isolate);
20061cb0ef41Sopenharmony_ci  i::Handle<i::Object> obj = WasmRefToV8(isolate, ref);
20071cb0ef41Sopenharmony_ci  // TODO(7748): Generalize the condition if other table types are allowed.
20081cb0ef41Sopenharmony_ci  if ((table->type() == i::wasm::kWasmFuncRef || table->type().has_index()) &&
20091cb0ef41Sopenharmony_ci      !obj->IsNull()) {
20101cb0ef41Sopenharmony_ci    obj = i::WasmInternalFunction::FromExternal(obj, isolate).ToHandleChecked();
20111cb0ef41Sopenharmony_ci  }
20121cb0ef41Sopenharmony_ci  i::WasmTableObject::Set(isolate, table, static_cast<uint32_t>(index), obj);
20131cb0ef41Sopenharmony_ci  return true;
20141cb0ef41Sopenharmony_ci}
20151cb0ef41Sopenharmony_ci
20161cb0ef41Sopenharmony_ci// TODO(jkummerow): Having Table::size_t shadowing "std" size_t is ugly.
20171cb0ef41Sopenharmony_ciauto Table::size() const -> size_t {
20181cb0ef41Sopenharmony_ci  return impl(this)->v8_object()->current_length();
20191cb0ef41Sopenharmony_ci}
20201cb0ef41Sopenharmony_ci
20211cb0ef41Sopenharmony_ciauto Table::grow(size_t delta, const Ref* ref) -> bool {
20221cb0ef41Sopenharmony_ci  i::Handle<i::WasmTableObject> table = impl(this)->v8_object();
20231cb0ef41Sopenharmony_ci  i::Isolate* isolate = table->GetIsolate();
20241cb0ef41Sopenharmony_ci  i::HandleScope scope(isolate);
20251cb0ef41Sopenharmony_ci  i::Handle<i::Object> obj = WasmRefToV8(isolate, ref);
20261cb0ef41Sopenharmony_ci  // TODO(7748): Generalize the condition if other table types are allowed.
20271cb0ef41Sopenharmony_ci  if ((table->type() == i::wasm::kWasmFuncRef || table->type().has_index()) &&
20281cb0ef41Sopenharmony_ci      !obj->IsNull()) {
20291cb0ef41Sopenharmony_ci    obj = i::WasmInternalFunction::FromExternal(obj, isolate).ToHandleChecked();
20301cb0ef41Sopenharmony_ci  }
20311cb0ef41Sopenharmony_ci  int result = i::WasmTableObject::Grow(isolate, table,
20321cb0ef41Sopenharmony_ci                                        static_cast<uint32_t>(delta), obj);
20331cb0ef41Sopenharmony_ci  return result >= 0;
20341cb0ef41Sopenharmony_ci}
20351cb0ef41Sopenharmony_ci
20361cb0ef41Sopenharmony_ci// Memory Instances
20371cb0ef41Sopenharmony_ci
20381cb0ef41Sopenharmony_citemplate <>
20391cb0ef41Sopenharmony_cistruct implement<Memory> {
20401cb0ef41Sopenharmony_ci  using type = RefImpl<Memory, i::WasmMemoryObject>;
20411cb0ef41Sopenharmony_ci};
20421cb0ef41Sopenharmony_ci
20431cb0ef41Sopenharmony_ciMemory::~Memory() = default;
20441cb0ef41Sopenharmony_ci
20451cb0ef41Sopenharmony_ciauto Memory::copy() const -> own<Memory> { return impl(this)->copy(); }
20461cb0ef41Sopenharmony_ci
20471cb0ef41Sopenharmony_ciauto Memory::make(Store* store_abs, const MemoryType* type) -> own<Memory> {
20481cb0ef41Sopenharmony_ci  StoreImpl* store = impl(store_abs);
20491cb0ef41Sopenharmony_ci  i::Isolate* isolate = store->i_isolate();
20501cb0ef41Sopenharmony_ci  i::HandleScope scope(isolate);
20511cb0ef41Sopenharmony_ci  CheckAndHandleInterrupts(isolate);
20521cb0ef41Sopenharmony_ci
20531cb0ef41Sopenharmony_ci  const Limits& limits = type->limits();
20541cb0ef41Sopenharmony_ci  uint32_t minimum = limits.min;
20551cb0ef41Sopenharmony_ci  // The max_mem_pages limit is only spec'ed for JS embeddings, so we'll
20561cb0ef41Sopenharmony_ci  // directly use the maximum pages limit here.
20571cb0ef41Sopenharmony_ci  if (minimum > i::wasm::kSpecMaxMemoryPages) return nullptr;
20581cb0ef41Sopenharmony_ci  uint32_t maximum = limits.max;
20591cb0ef41Sopenharmony_ci  if (maximum != Limits(0).max) {
20601cb0ef41Sopenharmony_ci    if (maximum < minimum) return nullptr;
20611cb0ef41Sopenharmony_ci    if (maximum > i::wasm::kSpecMaxMemoryPages) return nullptr;
20621cb0ef41Sopenharmony_ci  }
20631cb0ef41Sopenharmony_ci  // TODO(wasm+): Support shared memory.
20641cb0ef41Sopenharmony_ci  i::SharedFlag shared = i::SharedFlag::kNotShared;
20651cb0ef41Sopenharmony_ci  i::Handle<i::WasmMemoryObject> memory_obj;
20661cb0ef41Sopenharmony_ci  if (!i::WasmMemoryObject::New(isolate, minimum, maximum, shared)
20671cb0ef41Sopenharmony_ci           .ToHandle(&memory_obj)) {
20681cb0ef41Sopenharmony_ci    return own<Memory>();
20691cb0ef41Sopenharmony_ci  }
20701cb0ef41Sopenharmony_ci  return implement<Memory>::type::make(store, memory_obj);
20711cb0ef41Sopenharmony_ci}
20721cb0ef41Sopenharmony_ci
20731cb0ef41Sopenharmony_ciauto Memory::type() const -> own<MemoryType> {
20741cb0ef41Sopenharmony_ci  i::Handle<i::WasmMemoryObject> memory = impl(this)->v8_object();
20751cb0ef41Sopenharmony_ci  uint32_t min = static_cast<uint32_t>(memory->array_buffer().byte_length() /
20761cb0ef41Sopenharmony_ci                                       i::wasm::kWasmPageSize);
20771cb0ef41Sopenharmony_ci  uint32_t max =
20781cb0ef41Sopenharmony_ci      memory->has_maximum_pages() ? memory->maximum_pages() : 0xFFFFFFFFu;
20791cb0ef41Sopenharmony_ci  return MemoryType::make(Limits(min, max));
20801cb0ef41Sopenharmony_ci}
20811cb0ef41Sopenharmony_ci
20821cb0ef41Sopenharmony_ciauto Memory::data() const -> byte_t* {
20831cb0ef41Sopenharmony_ci  return reinterpret_cast<byte_t*>(
20841cb0ef41Sopenharmony_ci      impl(this)->v8_object()->array_buffer().backing_store());
20851cb0ef41Sopenharmony_ci}
20861cb0ef41Sopenharmony_ci
20871cb0ef41Sopenharmony_ciauto Memory::data_size() const -> size_t {
20881cb0ef41Sopenharmony_ci  return impl(this)->v8_object()->array_buffer().byte_length();
20891cb0ef41Sopenharmony_ci}
20901cb0ef41Sopenharmony_ci
20911cb0ef41Sopenharmony_ciauto Memory::size() const -> pages_t {
20921cb0ef41Sopenharmony_ci  return static_cast<pages_t>(
20931cb0ef41Sopenharmony_ci      impl(this)->v8_object()->array_buffer().byte_length() /
20941cb0ef41Sopenharmony_ci      i::wasm::kWasmPageSize);
20951cb0ef41Sopenharmony_ci}
20961cb0ef41Sopenharmony_ci
20971cb0ef41Sopenharmony_ciauto Memory::grow(pages_t delta) -> bool {
20981cb0ef41Sopenharmony_ci  i::Handle<i::WasmMemoryObject> memory = impl(this)->v8_object();
20991cb0ef41Sopenharmony_ci  i::Isolate* isolate = memory->GetIsolate();
21001cb0ef41Sopenharmony_ci  i::HandleScope handle_scope(isolate);
21011cb0ef41Sopenharmony_ci  int32_t old = i::WasmMemoryObject::Grow(isolate, memory, delta);
21021cb0ef41Sopenharmony_ci  return old != -1;
21031cb0ef41Sopenharmony_ci}
21041cb0ef41Sopenharmony_ci
21051cb0ef41Sopenharmony_ci// Module Instances
21061cb0ef41Sopenharmony_ci
21071cb0ef41Sopenharmony_citemplate <>
21081cb0ef41Sopenharmony_cistruct implement<Instance> {
21091cb0ef41Sopenharmony_ci  using type = RefImpl<Instance, i::WasmInstanceObject>;
21101cb0ef41Sopenharmony_ci};
21111cb0ef41Sopenharmony_ci
21121cb0ef41Sopenharmony_ciInstance::~Instance() = default;
21131cb0ef41Sopenharmony_ci
21141cb0ef41Sopenharmony_ciauto Instance::copy() const -> own<Instance> { return impl(this)->copy(); }
21151cb0ef41Sopenharmony_ci
21161cb0ef41Sopenharmony_ciown<Instance> Instance::make(Store* store_abs, const Module* module_abs,
21171cb0ef41Sopenharmony_ci                             const Extern* const imports[], own<Trap>* trap) {
21181cb0ef41Sopenharmony_ci  StoreImpl* store = impl(store_abs);
21191cb0ef41Sopenharmony_ci  const implement<Module>::type* module = impl(module_abs);
21201cb0ef41Sopenharmony_ci  i::Isolate* isolate = store->i_isolate();
21211cb0ef41Sopenharmony_ci  i::HandleScope handle_scope(isolate);
21221cb0ef41Sopenharmony_ci  CheckAndHandleInterrupts(isolate);
21231cb0ef41Sopenharmony_ci
21241cb0ef41Sopenharmony_ci  DCHECK_EQ(module->v8_object()->GetIsolate(), isolate);
21251cb0ef41Sopenharmony_ci
21261cb0ef41Sopenharmony_ci  if (trap) *trap = nullptr;
21271cb0ef41Sopenharmony_ci  ownvec<ImportType> import_types = module_abs->imports();
21281cb0ef41Sopenharmony_ci  i::Handle<i::JSObject> imports_obj =
21291cb0ef41Sopenharmony_ci      isolate->factory()->NewJSObject(isolate->object_function());
21301cb0ef41Sopenharmony_ci  for (size_t i = 0; i < import_types.size(); ++i) {
21311cb0ef41Sopenharmony_ci    ImportType* type = import_types[i].get();
21321cb0ef41Sopenharmony_ci    i::Handle<i::String> module_str = VecToString(isolate, type->module());
21331cb0ef41Sopenharmony_ci    i::Handle<i::String> name_str = VecToString(isolate, type->name());
21341cb0ef41Sopenharmony_ci
21351cb0ef41Sopenharmony_ci    i::Handle<i::JSObject> module_obj;
21361cb0ef41Sopenharmony_ci    i::LookupIterator module_it(isolate, imports_obj, module_str,
21371cb0ef41Sopenharmony_ci                                i::LookupIterator::OWN_SKIP_INTERCEPTOR);
21381cb0ef41Sopenharmony_ci    if (i::JSObject::HasProperty(&module_it).ToChecked()) {
21391cb0ef41Sopenharmony_ci      module_obj = i::Handle<i::JSObject>::cast(
21401cb0ef41Sopenharmony_ci          i::Object::GetProperty(&module_it).ToHandleChecked());
21411cb0ef41Sopenharmony_ci    } else {
21421cb0ef41Sopenharmony_ci      module_obj = isolate->factory()->NewJSObject(isolate->object_function());
21431cb0ef41Sopenharmony_ci      ignore(
21441cb0ef41Sopenharmony_ci          i::Object::SetProperty(isolate, imports_obj, module_str, module_obj));
21451cb0ef41Sopenharmony_ci    }
21461cb0ef41Sopenharmony_ci    ignore(i::Object::SetProperty(isolate, module_obj, name_str,
21471cb0ef41Sopenharmony_ci                                  impl(imports[i])->v8_object()));
21481cb0ef41Sopenharmony_ci  }
21491cb0ef41Sopenharmony_ci  i::wasm::ErrorThrower thrower(isolate, "instantiation");
21501cb0ef41Sopenharmony_ci  i::MaybeHandle<i::WasmInstanceObject> instance_obj =
21511cb0ef41Sopenharmony_ci      i::wasm::GetWasmEngine()->SyncInstantiate(
21521cb0ef41Sopenharmony_ci          isolate, &thrower, module->v8_object(), imports_obj,
21531cb0ef41Sopenharmony_ci          i::MaybeHandle<i::JSArrayBuffer>());
21541cb0ef41Sopenharmony_ci  if (trap) {
21551cb0ef41Sopenharmony_ci    if (thrower.error()) {
21561cb0ef41Sopenharmony_ci      *trap = implement<Trap>::type::make(
21571cb0ef41Sopenharmony_ci          store, GetProperException(isolate, thrower.Reify()));
21581cb0ef41Sopenharmony_ci      DCHECK(!thrower.error());                   // Reify() called Reset().
21591cb0ef41Sopenharmony_ci      DCHECK(!isolate->has_pending_exception());  // Hasn't been thrown yet.
21601cb0ef41Sopenharmony_ci      return own<Instance>();
21611cb0ef41Sopenharmony_ci    } else if (isolate->has_pending_exception()) {
21621cb0ef41Sopenharmony_ci      i::Handle<i::Object> maybe_exception(isolate->pending_exception(),
21631cb0ef41Sopenharmony_ci                                           isolate);
21641cb0ef41Sopenharmony_ci      *trap = implement<Trap>::type::make(
21651cb0ef41Sopenharmony_ci          store, GetProperException(isolate, maybe_exception));
21661cb0ef41Sopenharmony_ci      isolate->clear_pending_exception();
21671cb0ef41Sopenharmony_ci      return own<Instance>();
21681cb0ef41Sopenharmony_ci    }
21691cb0ef41Sopenharmony_ci  } else if (instance_obj.is_null()) {
21701cb0ef41Sopenharmony_ci    // If no {trap} output is specified, silently swallow all errors.
21711cb0ef41Sopenharmony_ci    thrower.Reset();
21721cb0ef41Sopenharmony_ci    isolate->clear_pending_exception();
21731cb0ef41Sopenharmony_ci    return own<Instance>();
21741cb0ef41Sopenharmony_ci  }
21751cb0ef41Sopenharmony_ci  return implement<Instance>::type::make(store, instance_obj.ToHandleChecked());
21761cb0ef41Sopenharmony_ci}
21771cb0ef41Sopenharmony_ci
21781cb0ef41Sopenharmony_cinamespace {
21791cb0ef41Sopenharmony_ci
21801cb0ef41Sopenharmony_ciown<Instance> GetInstance(StoreImpl* store,
21811cb0ef41Sopenharmony_ci                          i::Handle<i::WasmInstanceObject> instance) {
21821cb0ef41Sopenharmony_ci  return implement<Instance>::type::make(store, instance);
21831cb0ef41Sopenharmony_ci}
21841cb0ef41Sopenharmony_ci
21851cb0ef41Sopenharmony_ci}  // namespace
21861cb0ef41Sopenharmony_ci
21871cb0ef41Sopenharmony_ciauto Instance::exports() const -> ownvec<Extern> {
21881cb0ef41Sopenharmony_ci  const implement<Instance>::type* instance = impl(this);
21891cb0ef41Sopenharmony_ci  StoreImpl* store = instance->store();
21901cb0ef41Sopenharmony_ci  i::Isolate* isolate = store->i_isolate();
21911cb0ef41Sopenharmony_ci  i::HandleScope handle_scope(isolate);
21921cb0ef41Sopenharmony_ci  CheckAndHandleInterrupts(isolate);
21931cb0ef41Sopenharmony_ci  i::Handle<i::WasmInstanceObject> instance_obj = instance->v8_object();
21941cb0ef41Sopenharmony_ci  i::Handle<i::WasmModuleObject> module_obj(instance_obj->module_object(),
21951cb0ef41Sopenharmony_ci                                            isolate);
21961cb0ef41Sopenharmony_ci  i::Handle<i::JSObject> exports_obj(instance_obj->exports_object(), isolate);
21971cb0ef41Sopenharmony_ci
21981cb0ef41Sopenharmony_ci  ownvec<ExportType> export_types = ExportsImpl(module_obj);
21991cb0ef41Sopenharmony_ci  ownvec<Extern> exports =
22001cb0ef41Sopenharmony_ci      ownvec<Extern>::make_uninitialized(export_types.size());
22011cb0ef41Sopenharmony_ci  if (!exports) return ownvec<Extern>::invalid();
22021cb0ef41Sopenharmony_ci
22031cb0ef41Sopenharmony_ci  for (size_t i = 0; i < export_types.size(); ++i) {
22041cb0ef41Sopenharmony_ci    auto& name = export_types[i]->name();
22051cb0ef41Sopenharmony_ci    i::Handle<i::String> name_str = VecToString(isolate, name);
22061cb0ef41Sopenharmony_ci    i::Handle<i::Object> obj =
22071cb0ef41Sopenharmony_ci        i::Object::GetProperty(isolate, exports_obj, name_str)
22081cb0ef41Sopenharmony_ci            .ToHandleChecked();
22091cb0ef41Sopenharmony_ci
22101cb0ef41Sopenharmony_ci    const ExternType* type = export_types[i]->type();
22111cb0ef41Sopenharmony_ci    switch (type->kind()) {
22121cb0ef41Sopenharmony_ci      case EXTERN_FUNC: {
22131cb0ef41Sopenharmony_ci        DCHECK(i::WasmExportedFunction::IsWasmExportedFunction(*obj));
22141cb0ef41Sopenharmony_ci        exports[i] = implement<Func>::type::make(
22151cb0ef41Sopenharmony_ci            store, i::Handle<i::WasmExportedFunction>::cast(obj));
22161cb0ef41Sopenharmony_ci      } break;
22171cb0ef41Sopenharmony_ci      case EXTERN_GLOBAL: {
22181cb0ef41Sopenharmony_ci        exports[i] = implement<Global>::type::make(
22191cb0ef41Sopenharmony_ci            store, i::Handle<i::WasmGlobalObject>::cast(obj));
22201cb0ef41Sopenharmony_ci      } break;
22211cb0ef41Sopenharmony_ci      case EXTERN_TABLE: {
22221cb0ef41Sopenharmony_ci        exports[i] = implement<Table>::type::make(
22231cb0ef41Sopenharmony_ci            store, i::Handle<i::WasmTableObject>::cast(obj));
22241cb0ef41Sopenharmony_ci      } break;
22251cb0ef41Sopenharmony_ci      case EXTERN_MEMORY: {
22261cb0ef41Sopenharmony_ci        exports[i] = implement<Memory>::type::make(
22271cb0ef41Sopenharmony_ci            store, i::Handle<i::WasmMemoryObject>::cast(obj));
22281cb0ef41Sopenharmony_ci      } break;
22291cb0ef41Sopenharmony_ci    }
22301cb0ef41Sopenharmony_ci  }
22311cb0ef41Sopenharmony_ci
22321cb0ef41Sopenharmony_ci  return exports;
22331cb0ef41Sopenharmony_ci}
22341cb0ef41Sopenharmony_ci
22351cb0ef41Sopenharmony_ci///////////////////////////////////////////////////////////////////////////////
22361cb0ef41Sopenharmony_ci
22371cb0ef41Sopenharmony_ci}  // namespace wasm
22381cb0ef41Sopenharmony_ci
22391cb0ef41Sopenharmony_ci// BEGIN FILE wasm-c.cc
22401cb0ef41Sopenharmony_ci
22411cb0ef41Sopenharmony_ciextern "C" {
22421cb0ef41Sopenharmony_ci
22431cb0ef41Sopenharmony_ci///////////////////////////////////////////////////////////////////////////////
22441cb0ef41Sopenharmony_ci// Auxiliaries
22451cb0ef41Sopenharmony_ci
22461cb0ef41Sopenharmony_ci// Backing implementation
22471cb0ef41Sopenharmony_ci
22481cb0ef41Sopenharmony_ciextern "C++" {
22491cb0ef41Sopenharmony_ci
22501cb0ef41Sopenharmony_citemplate <class T>
22511cb0ef41Sopenharmony_cistruct borrowed_vec {
22521cb0ef41Sopenharmony_ci  wasm::vec<T> it;
22531cb0ef41Sopenharmony_ci  explicit borrowed_vec(wasm::vec<T>&& v) : it(std::move(v)) {}
22541cb0ef41Sopenharmony_ci  borrowed_vec(borrowed_vec<T>&& that) : it(std::move(that.it)) {}
22551cb0ef41Sopenharmony_ci  ~borrowed_vec() { it.release(); }
22561cb0ef41Sopenharmony_ci};
22571cb0ef41Sopenharmony_ci
22581cb0ef41Sopenharmony_ci}  // extern "C++"
22591cb0ef41Sopenharmony_ci
22601cb0ef41Sopenharmony_ci#define WASM_DEFINE_OWN(name, Name)                                            \
22611cb0ef41Sopenharmony_ci  struct wasm_##name##_t : Name {};                                            \
22621cb0ef41Sopenharmony_ci                                                                               \
22631cb0ef41Sopenharmony_ci  void wasm_##name##_delete(wasm_##name##_t* x) { delete x; }                  \
22641cb0ef41Sopenharmony_ci                                                                               \
22651cb0ef41Sopenharmony_ci  extern "C++" inline auto hide_##name(Name* x)->wasm_##name##_t* {            \
22661cb0ef41Sopenharmony_ci    return static_cast<wasm_##name##_t*>(x);                                   \
22671cb0ef41Sopenharmony_ci  }                                                                            \
22681cb0ef41Sopenharmony_ci  extern "C++" inline auto hide_##name(const Name* x)                          \
22691cb0ef41Sopenharmony_ci      ->const wasm_##name##_t* {                                               \
22701cb0ef41Sopenharmony_ci    return static_cast<const wasm_##name##_t*>(x);                             \
22711cb0ef41Sopenharmony_ci  }                                                                            \
22721cb0ef41Sopenharmony_ci  extern "C++" inline auto reveal_##name(wasm_##name##_t* x)->Name* {          \
22731cb0ef41Sopenharmony_ci    return x;                                                                  \
22741cb0ef41Sopenharmony_ci  }                                                                            \
22751cb0ef41Sopenharmony_ci  extern "C++" inline auto reveal_##name(const wasm_##name##_t* x)             \
22761cb0ef41Sopenharmony_ci      ->const Name* {                                                          \
22771cb0ef41Sopenharmony_ci    return x;                                                                  \
22781cb0ef41Sopenharmony_ci  }                                                                            \
22791cb0ef41Sopenharmony_ci  extern "C++" inline auto get_##name(wasm::own<Name>& x)->wasm_##name##_t* {  \
22801cb0ef41Sopenharmony_ci    return hide_##name(x.get());                                               \
22811cb0ef41Sopenharmony_ci  }                                                                            \
22821cb0ef41Sopenharmony_ci  extern "C++" inline auto get_##name(const wasm::own<Name>& x)                \
22831cb0ef41Sopenharmony_ci      ->const wasm_##name##_t* {                                               \
22841cb0ef41Sopenharmony_ci    return hide_##name(x.get());                                               \
22851cb0ef41Sopenharmony_ci  }                                                                            \
22861cb0ef41Sopenharmony_ci  extern "C++" inline auto release_##name(wasm::own<Name>&& x)                 \
22871cb0ef41Sopenharmony_ci      ->wasm_##name##_t* {                                                     \
22881cb0ef41Sopenharmony_ci    return hide_##name(x.release());                                           \
22891cb0ef41Sopenharmony_ci  }                                                                            \
22901cb0ef41Sopenharmony_ci  extern "C++" inline auto adopt_##name(wasm_##name##_t* x)->wasm::own<Name> { \
22911cb0ef41Sopenharmony_ci    return make_own(x);                                                        \
22921cb0ef41Sopenharmony_ci  }
22931cb0ef41Sopenharmony_ci
22941cb0ef41Sopenharmony_ci// Vectors
22951cb0ef41Sopenharmony_ci
22961cb0ef41Sopenharmony_ci#ifdef V8_GC_MOLE
22971cb0ef41Sopenharmony_ci#define ASSERT_VEC_BASE_SIZE(name, Name, vec, ptr_or_none)
22981cb0ef41Sopenharmony_ci
22991cb0ef41Sopenharmony_ci#else
23001cb0ef41Sopenharmony_ci#define ASSERT_VEC_BASE_SIZE(name, Name, vec, ptr_or_none)                 \
23011cb0ef41Sopenharmony_ci  static_assert(sizeof(wasm_##name##_vec_t) == sizeof(vec<Name>),          \
23021cb0ef41Sopenharmony_ci                "C/C++ incompatibility");                                  \
23031cb0ef41Sopenharmony_ci  static_assert(                                                           \
23041cb0ef41Sopenharmony_ci      sizeof(wasm_##name##_t ptr_or_none) == sizeof(vec<Name>::elem_type), \
23051cb0ef41Sopenharmony_ci      "C/C++ incompatibility");
23061cb0ef41Sopenharmony_ci#endif
23071cb0ef41Sopenharmony_ci
23081cb0ef41Sopenharmony_ci#define WASM_DEFINE_VEC_BASE(name, Name, vec, ptr_or_none)                     \
23091cb0ef41Sopenharmony_ci  ASSERT_VEC_BASE_SIZE(name, Name, vec, ptr_or_none)                           \
23101cb0ef41Sopenharmony_ci  extern "C++" inline auto hide_##name##_vec(vec<Name>& v)                     \
23111cb0ef41Sopenharmony_ci      ->wasm_##name##_vec_t* {                                                 \
23121cb0ef41Sopenharmony_ci    return reinterpret_cast<wasm_##name##_vec_t*>(&v);                         \
23131cb0ef41Sopenharmony_ci  }                                                                            \
23141cb0ef41Sopenharmony_ci  extern "C++" inline auto hide_##name##_vec(const vec<Name>& v)               \
23151cb0ef41Sopenharmony_ci      ->const wasm_##name##_vec_t* {                                           \
23161cb0ef41Sopenharmony_ci    return reinterpret_cast<const wasm_##name##_vec_t*>(&v);                   \
23171cb0ef41Sopenharmony_ci  }                                                                            \
23181cb0ef41Sopenharmony_ci  extern "C++" inline auto hide_##name##_vec(vec<Name>::elem_type* v)          \
23191cb0ef41Sopenharmony_ci      ->wasm_##name##_t ptr_or_none* {                                         \
23201cb0ef41Sopenharmony_ci    return reinterpret_cast<wasm_##name##_t ptr_or_none*>(v);                  \
23211cb0ef41Sopenharmony_ci  }                                                                            \
23221cb0ef41Sopenharmony_ci  extern "C++" inline auto hide_##name##_vec(const vec<Name>::elem_type* v)    \
23231cb0ef41Sopenharmony_ci      ->wasm_##name##_t ptr_or_none const* {                                   \
23241cb0ef41Sopenharmony_ci    return reinterpret_cast<wasm_##name##_t ptr_or_none const*>(v);            \
23251cb0ef41Sopenharmony_ci  }                                                                            \
23261cb0ef41Sopenharmony_ci  extern "C++" inline auto reveal_##name##_vec(wasm_##name##_t ptr_or_none* v) \
23271cb0ef41Sopenharmony_ci      ->vec<Name>::elem_type* {                                                \
23281cb0ef41Sopenharmony_ci    return reinterpret_cast<vec<Name>::elem_type*>(v);                         \
23291cb0ef41Sopenharmony_ci  }                                                                            \
23301cb0ef41Sopenharmony_ci  extern "C++" inline auto reveal_##name##_vec(                                \
23311cb0ef41Sopenharmony_ci      wasm_##name##_t ptr_or_none const* v)                                    \
23321cb0ef41Sopenharmony_ci      ->const vec<Name>::elem_type* {                                          \
23331cb0ef41Sopenharmony_ci    return reinterpret_cast<const vec<Name>::elem_type*>(v);                   \
23341cb0ef41Sopenharmony_ci  }                                                                            \
23351cb0ef41Sopenharmony_ci  extern "C++" inline auto get_##name##_vec(vec<Name>& v)                      \
23361cb0ef41Sopenharmony_ci      ->wasm_##name##_vec_t {                                                  \
23371cb0ef41Sopenharmony_ci    wasm_##name##_vec_t v2 = {v.size(), hide_##name##_vec(v.get())};           \
23381cb0ef41Sopenharmony_ci    return v2;                                                                 \
23391cb0ef41Sopenharmony_ci  }                                                                            \
23401cb0ef41Sopenharmony_ci  extern "C++" inline auto get_##name##_vec(const vec<Name>& v)                \
23411cb0ef41Sopenharmony_ci      ->const wasm_##name##_vec_t {                                            \
23421cb0ef41Sopenharmony_ci    wasm_##name##_vec_t v2 = {                                                 \
23431cb0ef41Sopenharmony_ci        v.size(),                                                              \
23441cb0ef41Sopenharmony_ci        const_cast<wasm_##name##_t ptr_or_none*>(hide_##name##_vec(v.get()))}; \
23451cb0ef41Sopenharmony_ci    return v2;                                                                 \
23461cb0ef41Sopenharmony_ci  }                                                                            \
23471cb0ef41Sopenharmony_ci  extern "C++" inline auto release_##name##_vec(vec<Name>&& v)                 \
23481cb0ef41Sopenharmony_ci      ->wasm_##name##_vec_t {                                                  \
23491cb0ef41Sopenharmony_ci    wasm_##name##_vec_t v2 = {v.size(), hide_##name##_vec(v.release())};       \
23501cb0ef41Sopenharmony_ci    return v2;                                                                 \
23511cb0ef41Sopenharmony_ci  }                                                                            \
23521cb0ef41Sopenharmony_ci  extern "C++" inline auto adopt_##name##_vec(wasm_##name##_vec_t* v)          \
23531cb0ef41Sopenharmony_ci      ->vec<Name> {                                                            \
23541cb0ef41Sopenharmony_ci    return vec<Name>::adopt(v->size, reveal_##name##_vec(v->data));            \
23551cb0ef41Sopenharmony_ci  }                                                                            \
23561cb0ef41Sopenharmony_ci  extern "C++" inline auto borrow_##name##_vec(const wasm_##name##_vec_t* v)   \
23571cb0ef41Sopenharmony_ci      ->borrowed_vec<vec<Name>::elem_type> {                                   \
23581cb0ef41Sopenharmony_ci    return borrowed_vec<vec<Name>::elem_type>(                                 \
23591cb0ef41Sopenharmony_ci        vec<Name>::adopt(v->size, reveal_##name##_vec(v->data)));              \
23601cb0ef41Sopenharmony_ci  }                                                                            \
23611cb0ef41Sopenharmony_ci                                                                               \
23621cb0ef41Sopenharmony_ci  void wasm_##name##_vec_new_uninitialized(wasm_##name##_vec_t* out,           \
23631cb0ef41Sopenharmony_ci                                           size_t size) {                      \
23641cb0ef41Sopenharmony_ci    *out = release_##name##_vec(vec<Name>::make_uninitialized(size));          \
23651cb0ef41Sopenharmony_ci  }                                                                            \
23661cb0ef41Sopenharmony_ci  void wasm_##name##_vec_new_empty(wasm_##name##_vec_t* out) {                 \
23671cb0ef41Sopenharmony_ci    wasm_##name##_vec_new_uninitialized(out, 0);                               \
23681cb0ef41Sopenharmony_ci  }                                                                            \
23691cb0ef41Sopenharmony_ci                                                                               \
23701cb0ef41Sopenharmony_ci  void wasm_##name##_vec_delete(wasm_##name##_vec_t* v) {                      \
23711cb0ef41Sopenharmony_ci    adopt_##name##_vec(v);                                                     \
23721cb0ef41Sopenharmony_ci  }
23731cb0ef41Sopenharmony_ci
23741cb0ef41Sopenharmony_ci// Vectors with no ownership management of elements
23751cb0ef41Sopenharmony_ci#define WASM_DEFINE_VEC_PLAIN(name, Name)                           \
23761cb0ef41Sopenharmony_ci  WASM_DEFINE_VEC_BASE(name, Name,                                  \
23771cb0ef41Sopenharmony_ci                       wasm::vec, ) /* NOLINT(whitespace/parens) */ \
23781cb0ef41Sopenharmony_ci                                                                    \
23791cb0ef41Sopenharmony_ci  void wasm_##name##_vec_new(wasm_##name##_vec_t* out, size_t size, \
23801cb0ef41Sopenharmony_ci                             const wasm_##name##_t data[]) {        \
23811cb0ef41Sopenharmony_ci    auto v2 = wasm::vec<Name>::make_uninitialized(size);            \
23821cb0ef41Sopenharmony_ci    if (v2.size() != 0) {                                           \
23831cb0ef41Sopenharmony_ci      memcpy(v2.get(), data, size * sizeof(wasm_##name##_t));       \
23841cb0ef41Sopenharmony_ci    }                                                               \
23851cb0ef41Sopenharmony_ci    *out = release_##name##_vec(std::move(v2));                     \
23861cb0ef41Sopenharmony_ci  }                                                                 \
23871cb0ef41Sopenharmony_ci                                                                    \
23881cb0ef41Sopenharmony_ci  void wasm_##name##_vec_copy(wasm_##name##_vec_t* out,             \
23891cb0ef41Sopenharmony_ci                              wasm_##name##_vec_t* v) {             \
23901cb0ef41Sopenharmony_ci    wasm_##name##_vec_new(out, v->size, v->data);                   \
23911cb0ef41Sopenharmony_ci  }
23921cb0ef41Sopenharmony_ci
23931cb0ef41Sopenharmony_ci// Vectors that own their elements
23941cb0ef41Sopenharmony_ci#define WASM_DEFINE_VEC_OWN(name, Name)                             \
23951cb0ef41Sopenharmony_ci  WASM_DEFINE_VEC_BASE(name, Name, wasm::ownvec, *)                 \
23961cb0ef41Sopenharmony_ci                                                                    \
23971cb0ef41Sopenharmony_ci  void wasm_##name##_vec_new(wasm_##name##_vec_t* out, size_t size, \
23981cb0ef41Sopenharmony_ci                             wasm_##name##_t* const data[]) {       \
23991cb0ef41Sopenharmony_ci    auto v2 = wasm::ownvec<Name>::make_uninitialized(size);         \
24001cb0ef41Sopenharmony_ci    for (size_t i = 0; i < v2.size(); ++i) {                        \
24011cb0ef41Sopenharmony_ci      v2[i] = adopt_##name(data[i]);                                \
24021cb0ef41Sopenharmony_ci    }                                                               \
24031cb0ef41Sopenharmony_ci    *out = release_##name##_vec(std::move(v2));                     \
24041cb0ef41Sopenharmony_ci  }                                                                 \
24051cb0ef41Sopenharmony_ci                                                                    \
24061cb0ef41Sopenharmony_ci  void wasm_##name##_vec_copy(wasm_##name##_vec_t* out,             \
24071cb0ef41Sopenharmony_ci                              wasm_##name##_vec_t* v) {             \
24081cb0ef41Sopenharmony_ci    auto v2 = wasm::ownvec<Name>::make_uninitialized(v->size);      \
24091cb0ef41Sopenharmony_ci    for (size_t i = 0; i < v2.size(); ++i) {                        \
24101cb0ef41Sopenharmony_ci      v2[i] = adopt_##name(wasm_##name##_copy(v->data[i]));         \
24111cb0ef41Sopenharmony_ci    }                                                               \
24121cb0ef41Sopenharmony_ci    *out = release_##name##_vec(std::move(v2));                     \
24131cb0ef41Sopenharmony_ci  }
24141cb0ef41Sopenharmony_ci
24151cb0ef41Sopenharmony_ciextern "C++" {
24161cb0ef41Sopenharmony_citemplate <class T>
24171cb0ef41Sopenharmony_ciinline auto is_empty(T* p) -> bool {
24181cb0ef41Sopenharmony_ci  return !p;
24191cb0ef41Sopenharmony_ci}
24201cb0ef41Sopenharmony_ci}
24211cb0ef41Sopenharmony_ci
24221cb0ef41Sopenharmony_ci// Byte vectors
24231cb0ef41Sopenharmony_ci
24241cb0ef41Sopenharmony_ciusing byte = byte_t;
24251cb0ef41Sopenharmony_ciWASM_DEFINE_VEC_PLAIN(byte, byte)
24261cb0ef41Sopenharmony_ci
24271cb0ef41Sopenharmony_ci///////////////////////////////////////////////////////////////////////////////
24281cb0ef41Sopenharmony_ci// Runtime Environment
24291cb0ef41Sopenharmony_ci
24301cb0ef41Sopenharmony_ci// Configuration
24311cb0ef41Sopenharmony_ci
24321cb0ef41Sopenharmony_ciWASM_DEFINE_OWN(config, wasm::Config)
24331cb0ef41Sopenharmony_ci
24341cb0ef41Sopenharmony_ciwasm_config_t* wasm_config_new() {
24351cb0ef41Sopenharmony_ci  return release_config(wasm::Config::make());
24361cb0ef41Sopenharmony_ci}
24371cb0ef41Sopenharmony_ci
24381cb0ef41Sopenharmony_ci// Engine
24391cb0ef41Sopenharmony_ci
24401cb0ef41Sopenharmony_ciWASM_DEFINE_OWN(engine, wasm::Engine)
24411cb0ef41Sopenharmony_ci
24421cb0ef41Sopenharmony_ciwasm_engine_t* wasm_engine_new() {
24431cb0ef41Sopenharmony_ci  return release_engine(wasm::Engine::make());
24441cb0ef41Sopenharmony_ci}
24451cb0ef41Sopenharmony_ci
24461cb0ef41Sopenharmony_ciwasm_engine_t* wasm_engine_new_with_config(wasm_config_t* config) {
24471cb0ef41Sopenharmony_ci  return release_engine(wasm::Engine::make(adopt_config(config)));
24481cb0ef41Sopenharmony_ci}
24491cb0ef41Sopenharmony_ci
24501cb0ef41Sopenharmony_ci// Stores
24511cb0ef41Sopenharmony_ci
24521cb0ef41Sopenharmony_ciWASM_DEFINE_OWN(store, wasm::Store)
24531cb0ef41Sopenharmony_ci
24541cb0ef41Sopenharmony_ciwasm_store_t* wasm_store_new(wasm_engine_t* engine) {
24551cb0ef41Sopenharmony_ci  return release_store(wasm::Store::make(engine));
24561cb0ef41Sopenharmony_ci}
24571cb0ef41Sopenharmony_ci
24581cb0ef41Sopenharmony_ci///////////////////////////////////////////////////////////////////////////////
24591cb0ef41Sopenharmony_ci// Type Representations
24601cb0ef41Sopenharmony_ci
24611cb0ef41Sopenharmony_ci// Type attributes
24621cb0ef41Sopenharmony_ci
24631cb0ef41Sopenharmony_ciextern "C++" inline auto hide_mutability(wasm::Mutability mutability)
24641cb0ef41Sopenharmony_ci    -> wasm_mutability_t {
24651cb0ef41Sopenharmony_ci  return static_cast<wasm_mutability_t>(mutability);
24661cb0ef41Sopenharmony_ci}
24671cb0ef41Sopenharmony_ci
24681cb0ef41Sopenharmony_ciextern "C++" inline auto reveal_mutability(wasm_mutability_t mutability)
24691cb0ef41Sopenharmony_ci    -> wasm::Mutability {
24701cb0ef41Sopenharmony_ci  return static_cast<wasm::Mutability>(mutability);
24711cb0ef41Sopenharmony_ci}
24721cb0ef41Sopenharmony_ci
24731cb0ef41Sopenharmony_ciextern "C++" inline auto hide_limits(const wasm::Limits& limits)
24741cb0ef41Sopenharmony_ci    -> const wasm_limits_t* {
24751cb0ef41Sopenharmony_ci  return reinterpret_cast<const wasm_limits_t*>(&limits);
24761cb0ef41Sopenharmony_ci}
24771cb0ef41Sopenharmony_ci
24781cb0ef41Sopenharmony_ciextern "C++" inline auto reveal_limits(wasm_limits_t limits) -> wasm::Limits {
24791cb0ef41Sopenharmony_ci  return wasm::Limits(limits.min, limits.max);
24801cb0ef41Sopenharmony_ci}
24811cb0ef41Sopenharmony_ci
24821cb0ef41Sopenharmony_ciextern "C++" inline auto hide_valkind(wasm::ValKind kind) -> wasm_valkind_t {
24831cb0ef41Sopenharmony_ci  return static_cast<wasm_valkind_t>(kind);
24841cb0ef41Sopenharmony_ci}
24851cb0ef41Sopenharmony_ci
24861cb0ef41Sopenharmony_ciextern "C++" inline auto reveal_valkind(wasm_valkind_t kind) -> wasm::ValKind {
24871cb0ef41Sopenharmony_ci  return static_cast<wasm::ValKind>(kind);
24881cb0ef41Sopenharmony_ci}
24891cb0ef41Sopenharmony_ci
24901cb0ef41Sopenharmony_ciextern "C++" inline auto hide_externkind(wasm::ExternKind kind)
24911cb0ef41Sopenharmony_ci    -> wasm_externkind_t {
24921cb0ef41Sopenharmony_ci  return static_cast<wasm_externkind_t>(kind);
24931cb0ef41Sopenharmony_ci}
24941cb0ef41Sopenharmony_ci
24951cb0ef41Sopenharmony_ciextern "C++" inline auto reveal_externkind(wasm_externkind_t kind)
24961cb0ef41Sopenharmony_ci    -> wasm::ExternKind {
24971cb0ef41Sopenharmony_ci  return static_cast<wasm::ExternKind>(kind);
24981cb0ef41Sopenharmony_ci}
24991cb0ef41Sopenharmony_ci
25001cb0ef41Sopenharmony_ci// Generic
25011cb0ef41Sopenharmony_ci
25021cb0ef41Sopenharmony_ci#define WASM_DEFINE_TYPE(name, Name)                        \
25031cb0ef41Sopenharmony_ci  WASM_DEFINE_OWN(name, Name)                               \
25041cb0ef41Sopenharmony_ci  WASM_DEFINE_VEC_OWN(name, Name)                           \
25051cb0ef41Sopenharmony_ci                                                            \
25061cb0ef41Sopenharmony_ci  wasm_##name##_t* wasm_##name##_copy(wasm_##name##_t* t) { \
25071cb0ef41Sopenharmony_ci    return release_##name(t->copy());                       \
25081cb0ef41Sopenharmony_ci  }
25091cb0ef41Sopenharmony_ci
25101cb0ef41Sopenharmony_ci// Value Types
25111cb0ef41Sopenharmony_ci
25121cb0ef41Sopenharmony_ciWASM_DEFINE_TYPE(valtype, wasm::ValType)
25131cb0ef41Sopenharmony_ci
25141cb0ef41Sopenharmony_ciwasm_valtype_t* wasm_valtype_new(wasm_valkind_t k) {
25151cb0ef41Sopenharmony_ci  return release_valtype(wasm::ValType::make(reveal_valkind(k)));
25161cb0ef41Sopenharmony_ci}
25171cb0ef41Sopenharmony_ci
25181cb0ef41Sopenharmony_ciwasm_valkind_t wasm_valtype_kind(const wasm_valtype_t* t) {
25191cb0ef41Sopenharmony_ci  return hide_valkind(t->kind());
25201cb0ef41Sopenharmony_ci}
25211cb0ef41Sopenharmony_ci
25221cb0ef41Sopenharmony_ci// Function Types
25231cb0ef41Sopenharmony_ci
25241cb0ef41Sopenharmony_ciWASM_DEFINE_TYPE(functype, wasm::FuncType)
25251cb0ef41Sopenharmony_ci
25261cb0ef41Sopenharmony_ciwasm_functype_t* wasm_functype_new(wasm_valtype_vec_t* params,
25271cb0ef41Sopenharmony_ci                                   wasm_valtype_vec_t* results) {
25281cb0ef41Sopenharmony_ci  return release_functype(wasm::FuncType::make(adopt_valtype_vec(params),
25291cb0ef41Sopenharmony_ci                                               adopt_valtype_vec(results)));
25301cb0ef41Sopenharmony_ci}
25311cb0ef41Sopenharmony_ci
25321cb0ef41Sopenharmony_ciconst wasm_valtype_vec_t* wasm_functype_params(const wasm_functype_t* ft) {
25331cb0ef41Sopenharmony_ci  return hide_valtype_vec(ft->params());
25341cb0ef41Sopenharmony_ci}
25351cb0ef41Sopenharmony_ci
25361cb0ef41Sopenharmony_ciconst wasm_valtype_vec_t* wasm_functype_results(const wasm_functype_t* ft) {
25371cb0ef41Sopenharmony_ci  return hide_valtype_vec(ft->results());
25381cb0ef41Sopenharmony_ci}
25391cb0ef41Sopenharmony_ci
25401cb0ef41Sopenharmony_ci// Global Types
25411cb0ef41Sopenharmony_ci
25421cb0ef41Sopenharmony_ciWASM_DEFINE_TYPE(globaltype, wasm::GlobalType)
25431cb0ef41Sopenharmony_ci
25441cb0ef41Sopenharmony_ciwasm_globaltype_t* wasm_globaltype_new(wasm_valtype_t* content,
25451cb0ef41Sopenharmony_ci                                       wasm_mutability_t mutability) {
25461cb0ef41Sopenharmony_ci  return release_globaltype(wasm::GlobalType::make(
25471cb0ef41Sopenharmony_ci      adopt_valtype(content), reveal_mutability(mutability)));
25481cb0ef41Sopenharmony_ci}
25491cb0ef41Sopenharmony_ci
25501cb0ef41Sopenharmony_ciconst wasm_valtype_t* wasm_globaltype_content(const wasm_globaltype_t* gt) {
25511cb0ef41Sopenharmony_ci  return hide_valtype(gt->content());
25521cb0ef41Sopenharmony_ci}
25531cb0ef41Sopenharmony_ci
25541cb0ef41Sopenharmony_ciwasm_mutability_t wasm_globaltype_mutability(const wasm_globaltype_t* gt) {
25551cb0ef41Sopenharmony_ci  return hide_mutability(gt->mutability());
25561cb0ef41Sopenharmony_ci}
25571cb0ef41Sopenharmony_ci
25581cb0ef41Sopenharmony_ci// Table Types
25591cb0ef41Sopenharmony_ci
25601cb0ef41Sopenharmony_ciWASM_DEFINE_TYPE(tabletype, wasm::TableType)
25611cb0ef41Sopenharmony_ci
25621cb0ef41Sopenharmony_ciwasm_tabletype_t* wasm_tabletype_new(wasm_valtype_t* element,
25631cb0ef41Sopenharmony_ci                                     const wasm_limits_t* limits) {
25641cb0ef41Sopenharmony_ci  return release_tabletype(
25651cb0ef41Sopenharmony_ci      wasm::TableType::make(adopt_valtype(element), reveal_limits(*limits)));
25661cb0ef41Sopenharmony_ci}
25671cb0ef41Sopenharmony_ci
25681cb0ef41Sopenharmony_ciconst wasm_valtype_t* wasm_tabletype_element(const wasm_tabletype_t* tt) {
25691cb0ef41Sopenharmony_ci  return hide_valtype(tt->element());
25701cb0ef41Sopenharmony_ci}
25711cb0ef41Sopenharmony_ci
25721cb0ef41Sopenharmony_ciconst wasm_limits_t* wasm_tabletype_limits(const wasm_tabletype_t* tt) {
25731cb0ef41Sopenharmony_ci  return hide_limits(tt->limits());
25741cb0ef41Sopenharmony_ci}
25751cb0ef41Sopenharmony_ci
25761cb0ef41Sopenharmony_ci// Memory Types
25771cb0ef41Sopenharmony_ci
25781cb0ef41Sopenharmony_ciWASM_DEFINE_TYPE(memorytype, wasm::MemoryType)
25791cb0ef41Sopenharmony_ci
25801cb0ef41Sopenharmony_ciwasm_memorytype_t* wasm_memorytype_new(const wasm_limits_t* limits) {
25811cb0ef41Sopenharmony_ci  return release_memorytype(wasm::MemoryType::make(reveal_limits(*limits)));
25821cb0ef41Sopenharmony_ci}
25831cb0ef41Sopenharmony_ci
25841cb0ef41Sopenharmony_ciconst wasm_limits_t* wasm_memorytype_limits(const wasm_memorytype_t* mt) {
25851cb0ef41Sopenharmony_ci  return hide_limits(mt->limits());
25861cb0ef41Sopenharmony_ci}
25871cb0ef41Sopenharmony_ci
25881cb0ef41Sopenharmony_ci// Extern Types
25891cb0ef41Sopenharmony_ci
25901cb0ef41Sopenharmony_ciWASM_DEFINE_TYPE(externtype, wasm::ExternType)
25911cb0ef41Sopenharmony_ci
25921cb0ef41Sopenharmony_ciwasm_externkind_t wasm_externtype_kind(const wasm_externtype_t* et) {
25931cb0ef41Sopenharmony_ci  return hide_externkind(et->kind());
25941cb0ef41Sopenharmony_ci}
25951cb0ef41Sopenharmony_ci
25961cb0ef41Sopenharmony_ciwasm_externtype_t* wasm_functype_as_externtype(wasm_functype_t* ft) {
25971cb0ef41Sopenharmony_ci  return hide_externtype(static_cast<wasm::ExternType*>(ft));
25981cb0ef41Sopenharmony_ci}
25991cb0ef41Sopenharmony_ciwasm_externtype_t* wasm_globaltype_as_externtype(wasm_globaltype_t* gt) {
26001cb0ef41Sopenharmony_ci  return hide_externtype(static_cast<wasm::ExternType*>(gt));
26011cb0ef41Sopenharmony_ci}
26021cb0ef41Sopenharmony_ciwasm_externtype_t* wasm_tabletype_as_externtype(wasm_tabletype_t* tt) {
26031cb0ef41Sopenharmony_ci  return hide_externtype(static_cast<wasm::ExternType*>(tt));
26041cb0ef41Sopenharmony_ci}
26051cb0ef41Sopenharmony_ciwasm_externtype_t* wasm_memorytype_as_externtype(wasm_memorytype_t* mt) {
26061cb0ef41Sopenharmony_ci  return hide_externtype(static_cast<wasm::ExternType*>(mt));
26071cb0ef41Sopenharmony_ci}
26081cb0ef41Sopenharmony_ci
26091cb0ef41Sopenharmony_ciconst wasm_externtype_t* wasm_functype_as_externtype_const(
26101cb0ef41Sopenharmony_ci    const wasm_functype_t* ft) {
26111cb0ef41Sopenharmony_ci  return hide_externtype(static_cast<const wasm::ExternType*>(ft));
26121cb0ef41Sopenharmony_ci}
26131cb0ef41Sopenharmony_ciconst wasm_externtype_t* wasm_globaltype_as_externtype_const(
26141cb0ef41Sopenharmony_ci    const wasm_globaltype_t* gt) {
26151cb0ef41Sopenharmony_ci  return hide_externtype(static_cast<const wasm::ExternType*>(gt));
26161cb0ef41Sopenharmony_ci}
26171cb0ef41Sopenharmony_ciconst wasm_externtype_t* wasm_tabletype_as_externtype_const(
26181cb0ef41Sopenharmony_ci    const wasm_tabletype_t* tt) {
26191cb0ef41Sopenharmony_ci  return hide_externtype(static_cast<const wasm::ExternType*>(tt));
26201cb0ef41Sopenharmony_ci}
26211cb0ef41Sopenharmony_ciconst wasm_externtype_t* wasm_memorytype_as_externtype_const(
26221cb0ef41Sopenharmony_ci    const wasm_memorytype_t* mt) {
26231cb0ef41Sopenharmony_ci  return hide_externtype(static_cast<const wasm::ExternType*>(mt));
26241cb0ef41Sopenharmony_ci}
26251cb0ef41Sopenharmony_ci
26261cb0ef41Sopenharmony_ciwasm_functype_t* wasm_externtype_as_functype(wasm_externtype_t* et) {
26271cb0ef41Sopenharmony_ci  return et->kind() == wasm::EXTERN_FUNC
26281cb0ef41Sopenharmony_ci             ? hide_functype(
26291cb0ef41Sopenharmony_ci                   static_cast<wasm::FuncType*>(reveal_externtype(et)))
26301cb0ef41Sopenharmony_ci             : nullptr;
26311cb0ef41Sopenharmony_ci}
26321cb0ef41Sopenharmony_ciwasm_globaltype_t* wasm_externtype_as_globaltype(wasm_externtype_t* et) {
26331cb0ef41Sopenharmony_ci  return et->kind() == wasm::EXTERN_GLOBAL
26341cb0ef41Sopenharmony_ci             ? hide_globaltype(
26351cb0ef41Sopenharmony_ci                   static_cast<wasm::GlobalType*>(reveal_externtype(et)))
26361cb0ef41Sopenharmony_ci             : nullptr;
26371cb0ef41Sopenharmony_ci}
26381cb0ef41Sopenharmony_ciwasm_tabletype_t* wasm_externtype_as_tabletype(wasm_externtype_t* et) {
26391cb0ef41Sopenharmony_ci  return et->kind() == wasm::EXTERN_TABLE
26401cb0ef41Sopenharmony_ci             ? hide_tabletype(
26411cb0ef41Sopenharmony_ci                   static_cast<wasm::TableType*>(reveal_externtype(et)))
26421cb0ef41Sopenharmony_ci             : nullptr;
26431cb0ef41Sopenharmony_ci}
26441cb0ef41Sopenharmony_ciwasm_memorytype_t* wasm_externtype_as_memorytype(wasm_externtype_t* et) {
26451cb0ef41Sopenharmony_ci  return et->kind() == wasm::EXTERN_MEMORY
26461cb0ef41Sopenharmony_ci             ? hide_memorytype(
26471cb0ef41Sopenharmony_ci                   static_cast<wasm::MemoryType*>(reveal_externtype(et)))
26481cb0ef41Sopenharmony_ci             : nullptr;
26491cb0ef41Sopenharmony_ci}
26501cb0ef41Sopenharmony_ci
26511cb0ef41Sopenharmony_ciconst wasm_functype_t* wasm_externtype_as_functype_const(
26521cb0ef41Sopenharmony_ci    const wasm_externtype_t* et) {
26531cb0ef41Sopenharmony_ci  return et->kind() == wasm::EXTERN_FUNC
26541cb0ef41Sopenharmony_ci             ? hide_functype(
26551cb0ef41Sopenharmony_ci                   static_cast<const wasm::FuncType*>(reveal_externtype(et)))
26561cb0ef41Sopenharmony_ci             : nullptr;
26571cb0ef41Sopenharmony_ci}
26581cb0ef41Sopenharmony_ciconst wasm_globaltype_t* wasm_externtype_as_globaltype_const(
26591cb0ef41Sopenharmony_ci    const wasm_externtype_t* et) {
26601cb0ef41Sopenharmony_ci  return et->kind() == wasm::EXTERN_GLOBAL
26611cb0ef41Sopenharmony_ci             ? hide_globaltype(
26621cb0ef41Sopenharmony_ci                   static_cast<const wasm::GlobalType*>(reveal_externtype(et)))
26631cb0ef41Sopenharmony_ci             : nullptr;
26641cb0ef41Sopenharmony_ci}
26651cb0ef41Sopenharmony_ciconst wasm_tabletype_t* wasm_externtype_as_tabletype_const(
26661cb0ef41Sopenharmony_ci    const wasm_externtype_t* et) {
26671cb0ef41Sopenharmony_ci  return et->kind() == wasm::EXTERN_TABLE
26681cb0ef41Sopenharmony_ci             ? hide_tabletype(
26691cb0ef41Sopenharmony_ci                   static_cast<const wasm::TableType*>(reveal_externtype(et)))
26701cb0ef41Sopenharmony_ci             : nullptr;
26711cb0ef41Sopenharmony_ci}
26721cb0ef41Sopenharmony_ciconst wasm_memorytype_t* wasm_externtype_as_memorytype_const(
26731cb0ef41Sopenharmony_ci    const wasm_externtype_t* et) {
26741cb0ef41Sopenharmony_ci  return et->kind() == wasm::EXTERN_MEMORY
26751cb0ef41Sopenharmony_ci             ? hide_memorytype(
26761cb0ef41Sopenharmony_ci                   static_cast<const wasm::MemoryType*>(reveal_externtype(et)))
26771cb0ef41Sopenharmony_ci             : nullptr;
26781cb0ef41Sopenharmony_ci}
26791cb0ef41Sopenharmony_ci
26801cb0ef41Sopenharmony_ci// Import Types
26811cb0ef41Sopenharmony_ci
26821cb0ef41Sopenharmony_ciWASM_DEFINE_TYPE(importtype, wasm::ImportType)
26831cb0ef41Sopenharmony_ci
26841cb0ef41Sopenharmony_ciwasm_importtype_t* wasm_importtype_new(wasm_name_t* module, wasm_name_t* name,
26851cb0ef41Sopenharmony_ci                                       wasm_externtype_t* type) {
26861cb0ef41Sopenharmony_ci  return release_importtype(wasm::ImportType::make(
26871cb0ef41Sopenharmony_ci      adopt_byte_vec(module), adopt_byte_vec(name), adopt_externtype(type)));
26881cb0ef41Sopenharmony_ci}
26891cb0ef41Sopenharmony_ci
26901cb0ef41Sopenharmony_ciconst wasm_name_t* wasm_importtype_module(const wasm_importtype_t* it) {
26911cb0ef41Sopenharmony_ci  return hide_byte_vec(it->module());
26921cb0ef41Sopenharmony_ci}
26931cb0ef41Sopenharmony_ci
26941cb0ef41Sopenharmony_ciconst wasm_name_t* wasm_importtype_name(const wasm_importtype_t* it) {
26951cb0ef41Sopenharmony_ci  return hide_byte_vec(it->name());
26961cb0ef41Sopenharmony_ci}
26971cb0ef41Sopenharmony_ci
26981cb0ef41Sopenharmony_ciconst wasm_externtype_t* wasm_importtype_type(const wasm_importtype_t* it) {
26991cb0ef41Sopenharmony_ci  return hide_externtype(it->type());
27001cb0ef41Sopenharmony_ci}
27011cb0ef41Sopenharmony_ci
27021cb0ef41Sopenharmony_ci// Export Types
27031cb0ef41Sopenharmony_ci
27041cb0ef41Sopenharmony_ciWASM_DEFINE_TYPE(exporttype, wasm::ExportType)
27051cb0ef41Sopenharmony_ci
27061cb0ef41Sopenharmony_ciwasm_exporttype_t* wasm_exporttype_new(wasm_name_t* name,
27071cb0ef41Sopenharmony_ci                                       wasm_externtype_t* type) {
27081cb0ef41Sopenharmony_ci  return release_exporttype(
27091cb0ef41Sopenharmony_ci      wasm::ExportType::make(adopt_byte_vec(name), adopt_externtype(type)));
27101cb0ef41Sopenharmony_ci}
27111cb0ef41Sopenharmony_ci
27121cb0ef41Sopenharmony_ciconst wasm_name_t* wasm_exporttype_name(const wasm_exporttype_t* et) {
27131cb0ef41Sopenharmony_ci  return hide_byte_vec(et->name());
27141cb0ef41Sopenharmony_ci}
27151cb0ef41Sopenharmony_ci
27161cb0ef41Sopenharmony_ciconst wasm_externtype_t* wasm_exporttype_type(const wasm_exporttype_t* et) {
27171cb0ef41Sopenharmony_ci  return hide_externtype(et->type());
27181cb0ef41Sopenharmony_ci}
27191cb0ef41Sopenharmony_ci
27201cb0ef41Sopenharmony_ci///////////////////////////////////////////////////////////////////////////////
27211cb0ef41Sopenharmony_ci// Runtime Values
27221cb0ef41Sopenharmony_ci
27231cb0ef41Sopenharmony_ci// References
27241cb0ef41Sopenharmony_ci
27251cb0ef41Sopenharmony_ci#define WASM_DEFINE_REF_BASE(name, Name)                             \
27261cb0ef41Sopenharmony_ci  WASM_DEFINE_OWN(name, Name)                                        \
27271cb0ef41Sopenharmony_ci                                                                     \
27281cb0ef41Sopenharmony_ci  wasm_##name##_t* wasm_##name##_copy(const wasm_##name##_t* t) {    \
27291cb0ef41Sopenharmony_ci    return release_##name(t->copy());                                \
27301cb0ef41Sopenharmony_ci  }                                                                  \
27311cb0ef41Sopenharmony_ci                                                                     \
27321cb0ef41Sopenharmony_ci  bool wasm_##name##_same(const wasm_##name##_t* t1,                 \
27331cb0ef41Sopenharmony_ci                          const wasm_##name##_t* t2) {               \
27341cb0ef41Sopenharmony_ci    return t1->same(t2);                                             \
27351cb0ef41Sopenharmony_ci  }                                                                  \
27361cb0ef41Sopenharmony_ci                                                                     \
27371cb0ef41Sopenharmony_ci  void* wasm_##name##_get_host_info(const wasm_##name##_t* r) {      \
27381cb0ef41Sopenharmony_ci    return r->get_host_info();                                       \
27391cb0ef41Sopenharmony_ci  }                                                                  \
27401cb0ef41Sopenharmony_ci  void wasm_##name##_set_host_info(wasm_##name##_t* r, void* info) { \
27411cb0ef41Sopenharmony_ci    r->set_host_info(info);                                          \
27421cb0ef41Sopenharmony_ci  }                                                                  \
27431cb0ef41Sopenharmony_ci  void wasm_##name##_set_host_info_with_finalizer(                   \
27441cb0ef41Sopenharmony_ci      wasm_##name##_t* r, void* info, void (*finalizer)(void*)) {    \
27451cb0ef41Sopenharmony_ci    r->set_host_info(info, finalizer);                               \
27461cb0ef41Sopenharmony_ci  }
27471cb0ef41Sopenharmony_ci
27481cb0ef41Sopenharmony_ci#define WASM_DEFINE_REF(name, Name)                                        \
27491cb0ef41Sopenharmony_ci  WASM_DEFINE_REF_BASE(name, Name)                                         \
27501cb0ef41Sopenharmony_ci                                                                           \
27511cb0ef41Sopenharmony_ci  wasm_ref_t* wasm_##name##_as_ref(wasm_##name##_t* r) {                   \
27521cb0ef41Sopenharmony_ci    return hide_ref(static_cast<wasm::Ref*>(reveal_##name(r)));            \
27531cb0ef41Sopenharmony_ci  }                                                                        \
27541cb0ef41Sopenharmony_ci  wasm_##name##_t* wasm_ref_as_##name(wasm_ref_t* r) {                     \
27551cb0ef41Sopenharmony_ci    return hide_##name(static_cast<Name*>(reveal_ref(r)));                 \
27561cb0ef41Sopenharmony_ci  }                                                                        \
27571cb0ef41Sopenharmony_ci                                                                           \
27581cb0ef41Sopenharmony_ci  const wasm_ref_t* wasm_##name##_as_ref_const(const wasm_##name##_t* r) { \
27591cb0ef41Sopenharmony_ci    return hide_ref(static_cast<const wasm::Ref*>(reveal_##name(r)));      \
27601cb0ef41Sopenharmony_ci  }                                                                        \
27611cb0ef41Sopenharmony_ci  const wasm_##name##_t* wasm_ref_as_##name##_const(const wasm_ref_t* r) { \
27621cb0ef41Sopenharmony_ci    return hide_##name(static_cast<const Name*>(reveal_ref(r)));           \
27631cb0ef41Sopenharmony_ci  }
27641cb0ef41Sopenharmony_ci
27651cb0ef41Sopenharmony_ci#define WASM_DEFINE_SHARABLE_REF(name, Name) \
27661cb0ef41Sopenharmony_ci  WASM_DEFINE_REF(name, Name)                \
27671cb0ef41Sopenharmony_ci  WASM_DEFINE_OWN(shared_##name, wasm::Shared<Name>)
27681cb0ef41Sopenharmony_ci
27691cb0ef41Sopenharmony_ciWASM_DEFINE_REF_BASE(ref, wasm::Ref)
27701cb0ef41Sopenharmony_ci
27711cb0ef41Sopenharmony_ci// Values
27721cb0ef41Sopenharmony_ci
27731cb0ef41Sopenharmony_ciextern "C++" {
27741cb0ef41Sopenharmony_ci
27751cb0ef41Sopenharmony_ciinline auto is_empty(wasm_val_t v) -> bool {
27761cb0ef41Sopenharmony_ci  return !is_ref(reveal_valkind(v.kind)) || !v.of.ref;
27771cb0ef41Sopenharmony_ci}
27781cb0ef41Sopenharmony_ci
27791cb0ef41Sopenharmony_ciinline auto hide_val(wasm::Val v) -> wasm_val_t {
27801cb0ef41Sopenharmony_ci  wasm_val_t v2 = {hide_valkind(v.kind()), {}};
27811cb0ef41Sopenharmony_ci  switch (v.kind()) {
27821cb0ef41Sopenharmony_ci    case wasm::I32:
27831cb0ef41Sopenharmony_ci      v2.of.i32 = v.i32();
27841cb0ef41Sopenharmony_ci      break;
27851cb0ef41Sopenharmony_ci    case wasm::I64:
27861cb0ef41Sopenharmony_ci      v2.of.i64 = v.i64();
27871cb0ef41Sopenharmony_ci      break;
27881cb0ef41Sopenharmony_ci    case wasm::F32:
27891cb0ef41Sopenharmony_ci      v2.of.f32 = v.f32();
27901cb0ef41Sopenharmony_ci      break;
27911cb0ef41Sopenharmony_ci    case wasm::F64:
27921cb0ef41Sopenharmony_ci      v2.of.f64 = v.f64();
27931cb0ef41Sopenharmony_ci      break;
27941cb0ef41Sopenharmony_ci    case wasm::ANYREF:
27951cb0ef41Sopenharmony_ci    case wasm::FUNCREF:
27961cb0ef41Sopenharmony_ci      v2.of.ref = hide_ref(v.ref());
27971cb0ef41Sopenharmony_ci      break;
27981cb0ef41Sopenharmony_ci    default:
27991cb0ef41Sopenharmony_ci      UNREACHABLE();
28001cb0ef41Sopenharmony_ci  }
28011cb0ef41Sopenharmony_ci  return v2;
28021cb0ef41Sopenharmony_ci}
28031cb0ef41Sopenharmony_ci
28041cb0ef41Sopenharmony_ciinline auto release_val(wasm::Val v) -> wasm_val_t {
28051cb0ef41Sopenharmony_ci  wasm_val_t v2 = {hide_valkind(v.kind()), {}};
28061cb0ef41Sopenharmony_ci  switch (v.kind()) {
28071cb0ef41Sopenharmony_ci    case wasm::I32:
28081cb0ef41Sopenharmony_ci      v2.of.i32 = v.i32();
28091cb0ef41Sopenharmony_ci      break;
28101cb0ef41Sopenharmony_ci    case wasm::I64:
28111cb0ef41Sopenharmony_ci      v2.of.i64 = v.i64();
28121cb0ef41Sopenharmony_ci      break;
28131cb0ef41Sopenharmony_ci    case wasm::F32:
28141cb0ef41Sopenharmony_ci      v2.of.f32 = v.f32();
28151cb0ef41Sopenharmony_ci      break;
28161cb0ef41Sopenharmony_ci    case wasm::F64:
28171cb0ef41Sopenharmony_ci      v2.of.f64 = v.f64();
28181cb0ef41Sopenharmony_ci      break;
28191cb0ef41Sopenharmony_ci    case wasm::ANYREF:
28201cb0ef41Sopenharmony_ci    case wasm::FUNCREF:
28211cb0ef41Sopenharmony_ci      v2.of.ref = release_ref(v.release_ref());
28221cb0ef41Sopenharmony_ci      break;
28231cb0ef41Sopenharmony_ci    default:
28241cb0ef41Sopenharmony_ci      UNREACHABLE();
28251cb0ef41Sopenharmony_ci  }
28261cb0ef41Sopenharmony_ci  return v2;
28271cb0ef41Sopenharmony_ci}
28281cb0ef41Sopenharmony_ci
28291cb0ef41Sopenharmony_ciinline auto adopt_val(wasm_val_t v) -> wasm::Val {
28301cb0ef41Sopenharmony_ci  switch (reveal_valkind(v.kind)) {
28311cb0ef41Sopenharmony_ci    case wasm::I32:
28321cb0ef41Sopenharmony_ci      return wasm::Val(v.of.i32);
28331cb0ef41Sopenharmony_ci    case wasm::I64:
28341cb0ef41Sopenharmony_ci      return wasm::Val(v.of.i64);
28351cb0ef41Sopenharmony_ci    case wasm::F32:
28361cb0ef41Sopenharmony_ci      return wasm::Val(v.of.f32);
28371cb0ef41Sopenharmony_ci    case wasm::F64:
28381cb0ef41Sopenharmony_ci      return wasm::Val(v.of.f64);
28391cb0ef41Sopenharmony_ci    case wasm::ANYREF:
28401cb0ef41Sopenharmony_ci    case wasm::FUNCREF:
28411cb0ef41Sopenharmony_ci      return wasm::Val(adopt_ref(v.of.ref));
28421cb0ef41Sopenharmony_ci    default:
28431cb0ef41Sopenharmony_ci      UNREACHABLE();
28441cb0ef41Sopenharmony_ci  }
28451cb0ef41Sopenharmony_ci}
28461cb0ef41Sopenharmony_ci
28471cb0ef41Sopenharmony_cistruct borrowed_val {
28481cb0ef41Sopenharmony_ci  wasm::Val it;
28491cb0ef41Sopenharmony_ci  explicit borrowed_val(wasm::Val&& v) : it(std::move(v)) {}
28501cb0ef41Sopenharmony_ci  borrowed_val(borrowed_val&& that) : it(std::move(that.it)) {}
28511cb0ef41Sopenharmony_ci  ~borrowed_val() {
28521cb0ef41Sopenharmony_ci    if (it.is_ref()) it.release_ref().release();
28531cb0ef41Sopenharmony_ci  }
28541cb0ef41Sopenharmony_ci};
28551cb0ef41Sopenharmony_ci
28561cb0ef41Sopenharmony_ciinline auto borrow_val(const wasm_val_t* v) -> borrowed_val {
28571cb0ef41Sopenharmony_ci  wasm::Val v2;
28581cb0ef41Sopenharmony_ci  switch (reveal_valkind(v->kind)) {
28591cb0ef41Sopenharmony_ci    case wasm::I32:
28601cb0ef41Sopenharmony_ci      v2 = wasm::Val(v->of.i32);
28611cb0ef41Sopenharmony_ci      break;
28621cb0ef41Sopenharmony_ci    case wasm::I64:
28631cb0ef41Sopenharmony_ci      v2 = wasm::Val(v->of.i64);
28641cb0ef41Sopenharmony_ci      break;
28651cb0ef41Sopenharmony_ci    case wasm::F32:
28661cb0ef41Sopenharmony_ci      v2 = wasm::Val(v->of.f32);
28671cb0ef41Sopenharmony_ci      break;
28681cb0ef41Sopenharmony_ci    case wasm::F64:
28691cb0ef41Sopenharmony_ci      v2 = wasm::Val(v->of.f64);
28701cb0ef41Sopenharmony_ci      break;
28711cb0ef41Sopenharmony_ci    case wasm::ANYREF:
28721cb0ef41Sopenharmony_ci    case wasm::FUNCREF:
28731cb0ef41Sopenharmony_ci      v2 = wasm::Val(adopt_ref(v->of.ref));
28741cb0ef41Sopenharmony_ci      break;
28751cb0ef41Sopenharmony_ci    default:
28761cb0ef41Sopenharmony_ci      UNREACHABLE();
28771cb0ef41Sopenharmony_ci  }
28781cb0ef41Sopenharmony_ci  return borrowed_val(std::move(v2));
28791cb0ef41Sopenharmony_ci}
28801cb0ef41Sopenharmony_ci
28811cb0ef41Sopenharmony_ci}  // extern "C++"
28821cb0ef41Sopenharmony_ci
28831cb0ef41Sopenharmony_ciWASM_DEFINE_VEC_BASE(val, wasm::Val, wasm::vec, )
28841cb0ef41Sopenharmony_ci
28851cb0ef41Sopenharmony_civoid wasm_val_vec_new(wasm_val_vec_t* out, size_t size,
28861cb0ef41Sopenharmony_ci                      wasm_val_t const data[]) {
28871cb0ef41Sopenharmony_ci  auto v2 = wasm::vec<wasm::Val>::make_uninitialized(size);
28881cb0ef41Sopenharmony_ci  for (size_t i = 0; i < v2.size(); ++i) {
28891cb0ef41Sopenharmony_ci    v2[i] = adopt_val(data[i]);
28901cb0ef41Sopenharmony_ci  }
28911cb0ef41Sopenharmony_ci  *out = release_val_vec(std::move(v2));
28921cb0ef41Sopenharmony_ci}
28931cb0ef41Sopenharmony_ci
28941cb0ef41Sopenharmony_civoid wasm_val_vec_copy(wasm_val_vec_t* out, wasm_val_vec_t* v) {
28951cb0ef41Sopenharmony_ci  auto v2 = wasm::vec<wasm::Val>::make_uninitialized(v->size);
28961cb0ef41Sopenharmony_ci  for (size_t i = 0; i < v2.size(); ++i) {
28971cb0ef41Sopenharmony_ci    wasm_val_t val;
28981cb0ef41Sopenharmony_ci    wasm_val_copy(&v->data[i], &val);
28991cb0ef41Sopenharmony_ci    v2[i] = adopt_val(val);
29001cb0ef41Sopenharmony_ci  }
29011cb0ef41Sopenharmony_ci  *out = release_val_vec(std::move(v2));
29021cb0ef41Sopenharmony_ci}
29031cb0ef41Sopenharmony_ci
29041cb0ef41Sopenharmony_civoid wasm_val_delete(wasm_val_t* v) {
29051cb0ef41Sopenharmony_ci  if (is_ref(reveal_valkind(v->kind))) {
29061cb0ef41Sopenharmony_ci    adopt_ref(v->of.ref);
29071cb0ef41Sopenharmony_ci  }
29081cb0ef41Sopenharmony_ci}
29091cb0ef41Sopenharmony_ci
29101cb0ef41Sopenharmony_civoid wasm_val_copy(wasm_val_t* out, const wasm_val_t* v) {
29111cb0ef41Sopenharmony_ci  *out = *v;
29121cb0ef41Sopenharmony_ci  if (is_ref(reveal_valkind(v->kind))) {
29131cb0ef41Sopenharmony_ci    out->of.ref = v->of.ref ? release_ref(v->of.ref->copy()) : nullptr;
29141cb0ef41Sopenharmony_ci  }
29151cb0ef41Sopenharmony_ci}
29161cb0ef41Sopenharmony_ci
29171cb0ef41Sopenharmony_ci///////////////////////////////////////////////////////////////////////////////
29181cb0ef41Sopenharmony_ci// Runtime Objects
29191cb0ef41Sopenharmony_ci
29201cb0ef41Sopenharmony_ci// Frames
29211cb0ef41Sopenharmony_ci
29221cb0ef41Sopenharmony_ciWASM_DEFINE_OWN(frame, wasm::Frame)
29231cb0ef41Sopenharmony_ciWASM_DEFINE_VEC_OWN(frame, wasm::Frame)
29241cb0ef41Sopenharmony_ci
29251cb0ef41Sopenharmony_ciwasm_frame_t* wasm_frame_copy(const wasm_frame_t* frame) {
29261cb0ef41Sopenharmony_ci  return release_frame(frame->copy());
29271cb0ef41Sopenharmony_ci}
29281cb0ef41Sopenharmony_ci
29291cb0ef41Sopenharmony_ciwasm_instance_t* wasm_frame_instance(const wasm_frame_t* frame);
29301cb0ef41Sopenharmony_ci// Defined below along with wasm_instance_t.
29311cb0ef41Sopenharmony_ci
29321cb0ef41Sopenharmony_ciuint32_t wasm_frame_func_index(const wasm_frame_t* frame) {
29331cb0ef41Sopenharmony_ci  return reveal_frame(frame)->func_index();
29341cb0ef41Sopenharmony_ci}
29351cb0ef41Sopenharmony_ci
29361cb0ef41Sopenharmony_cisize_t wasm_frame_func_offset(const wasm_frame_t* frame) {
29371cb0ef41Sopenharmony_ci  return reveal_frame(frame)->func_offset();
29381cb0ef41Sopenharmony_ci}
29391cb0ef41Sopenharmony_ci
29401cb0ef41Sopenharmony_cisize_t wasm_frame_module_offset(const wasm_frame_t* frame) {
29411cb0ef41Sopenharmony_ci  return reveal_frame(frame)->module_offset();
29421cb0ef41Sopenharmony_ci}
29431cb0ef41Sopenharmony_ci
29441cb0ef41Sopenharmony_ci// Traps
29451cb0ef41Sopenharmony_ci
29461cb0ef41Sopenharmony_ciWASM_DEFINE_REF(trap, wasm::Trap)
29471cb0ef41Sopenharmony_ci
29481cb0ef41Sopenharmony_ciwasm_trap_t* wasm_trap_new(wasm_store_t* store, const wasm_message_t* message) {
29491cb0ef41Sopenharmony_ci  auto message_ = borrow_byte_vec(message);
29501cb0ef41Sopenharmony_ci  return release_trap(wasm::Trap::make(store, message_.it));
29511cb0ef41Sopenharmony_ci}
29521cb0ef41Sopenharmony_ci
29531cb0ef41Sopenharmony_civoid wasm_trap_message(const wasm_trap_t* trap, wasm_message_t* out) {
29541cb0ef41Sopenharmony_ci  *out = release_byte_vec(reveal_trap(trap)->message());
29551cb0ef41Sopenharmony_ci}
29561cb0ef41Sopenharmony_ci
29571cb0ef41Sopenharmony_ciwasm_frame_t* wasm_trap_origin(const wasm_trap_t* trap) {
29581cb0ef41Sopenharmony_ci  return release_frame(reveal_trap(trap)->origin());
29591cb0ef41Sopenharmony_ci}
29601cb0ef41Sopenharmony_ci
29611cb0ef41Sopenharmony_civoid wasm_trap_trace(const wasm_trap_t* trap, wasm_frame_vec_t* out) {
29621cb0ef41Sopenharmony_ci  *out = release_frame_vec(reveal_trap(trap)->trace());
29631cb0ef41Sopenharmony_ci}
29641cb0ef41Sopenharmony_ci
29651cb0ef41Sopenharmony_ci// Foreign Objects
29661cb0ef41Sopenharmony_ci
29671cb0ef41Sopenharmony_ciWASM_DEFINE_REF(foreign, wasm::Foreign)
29681cb0ef41Sopenharmony_ci
29691cb0ef41Sopenharmony_ciwasm_foreign_t* wasm_foreign_new(wasm_store_t* store) {
29701cb0ef41Sopenharmony_ci  return release_foreign(wasm::Foreign::make(store));
29711cb0ef41Sopenharmony_ci}
29721cb0ef41Sopenharmony_ci
29731cb0ef41Sopenharmony_ci// Modules
29741cb0ef41Sopenharmony_ci
29751cb0ef41Sopenharmony_ciWASM_DEFINE_SHARABLE_REF(module, wasm::Module)
29761cb0ef41Sopenharmony_ci
29771cb0ef41Sopenharmony_cibool wasm_module_validate(wasm_store_t* store, const wasm_byte_vec_t* binary) {
29781cb0ef41Sopenharmony_ci  auto binary_ = borrow_byte_vec(binary);
29791cb0ef41Sopenharmony_ci  return wasm::Module::validate(store, binary_.it);
29801cb0ef41Sopenharmony_ci}
29811cb0ef41Sopenharmony_ci
29821cb0ef41Sopenharmony_ciwasm_module_t* wasm_module_new(wasm_store_t* store,
29831cb0ef41Sopenharmony_ci                               const wasm_byte_vec_t* binary) {
29841cb0ef41Sopenharmony_ci  auto binary_ = borrow_byte_vec(binary);
29851cb0ef41Sopenharmony_ci  return release_module(wasm::Module::make(store, binary_.it));
29861cb0ef41Sopenharmony_ci}
29871cb0ef41Sopenharmony_ci
29881cb0ef41Sopenharmony_civoid wasm_module_imports(const wasm_module_t* module,
29891cb0ef41Sopenharmony_ci                         wasm_importtype_vec_t* out) {
29901cb0ef41Sopenharmony_ci  *out = release_importtype_vec(reveal_module(module)->imports());
29911cb0ef41Sopenharmony_ci}
29921cb0ef41Sopenharmony_ci
29931cb0ef41Sopenharmony_civoid wasm_module_exports(const wasm_module_t* module,
29941cb0ef41Sopenharmony_ci                         wasm_exporttype_vec_t* out) {
29951cb0ef41Sopenharmony_ci  *out = release_exporttype_vec(reveal_module(module)->exports());
29961cb0ef41Sopenharmony_ci}
29971cb0ef41Sopenharmony_ci
29981cb0ef41Sopenharmony_civoid wasm_module_serialize(const wasm_module_t* module, wasm_byte_vec_t* out) {
29991cb0ef41Sopenharmony_ci  *out = release_byte_vec(reveal_module(module)->serialize());
30001cb0ef41Sopenharmony_ci}
30011cb0ef41Sopenharmony_ci
30021cb0ef41Sopenharmony_ciwasm_module_t* wasm_module_deserialize(wasm_store_t* store,
30031cb0ef41Sopenharmony_ci                                       const wasm_byte_vec_t* binary) {
30041cb0ef41Sopenharmony_ci  auto binary_ = borrow_byte_vec(binary);
30051cb0ef41Sopenharmony_ci  return release_module(wasm::Module::deserialize(store, binary_.it));
30061cb0ef41Sopenharmony_ci}
30071cb0ef41Sopenharmony_ci
30081cb0ef41Sopenharmony_ciwasm_shared_module_t* wasm_module_share(const wasm_module_t* module) {
30091cb0ef41Sopenharmony_ci  return release_shared_module(reveal_module(module)->share());
30101cb0ef41Sopenharmony_ci}
30111cb0ef41Sopenharmony_ci
30121cb0ef41Sopenharmony_ciwasm_module_t* wasm_module_obtain(wasm_store_t* store,
30131cb0ef41Sopenharmony_ci                                  const wasm_shared_module_t* shared) {
30141cb0ef41Sopenharmony_ci  return release_module(wasm::Module::obtain(store, shared));
30151cb0ef41Sopenharmony_ci}
30161cb0ef41Sopenharmony_ci
30171cb0ef41Sopenharmony_ci// Function Instances
30181cb0ef41Sopenharmony_ci
30191cb0ef41Sopenharmony_ciWASM_DEFINE_REF(func, wasm::Func)
30201cb0ef41Sopenharmony_ci
30211cb0ef41Sopenharmony_ciextern "C++" {
30221cb0ef41Sopenharmony_ci
30231cb0ef41Sopenharmony_ciauto wasm_callback(void* env, const wasm::Val args[], wasm::Val results[])
30241cb0ef41Sopenharmony_ci    -> wasm::own<wasm::Trap> {
30251cb0ef41Sopenharmony_ci  auto f = reinterpret_cast<wasm_func_callback_t>(env);
30261cb0ef41Sopenharmony_ci  return adopt_trap(f(hide_val_vec(args), hide_val_vec(results)));
30271cb0ef41Sopenharmony_ci}
30281cb0ef41Sopenharmony_ci
30291cb0ef41Sopenharmony_cistruct wasm_callback_env_t {
30301cb0ef41Sopenharmony_ci  wasm_func_callback_with_env_t callback;
30311cb0ef41Sopenharmony_ci  void* env;
30321cb0ef41Sopenharmony_ci  void (*finalizer)(void*);
30331cb0ef41Sopenharmony_ci};
30341cb0ef41Sopenharmony_ci
30351cb0ef41Sopenharmony_ciauto wasm_callback_with_env(void* env, const wasm::Val args[],
30361cb0ef41Sopenharmony_ci                            wasm::Val results[]) -> wasm::own<wasm::Trap> {
30371cb0ef41Sopenharmony_ci  auto t = static_cast<wasm_callback_env_t*>(env);
30381cb0ef41Sopenharmony_ci  return adopt_trap(
30391cb0ef41Sopenharmony_ci      t->callback(t->env, hide_val_vec(args), hide_val_vec(results)));
30401cb0ef41Sopenharmony_ci}
30411cb0ef41Sopenharmony_ci
30421cb0ef41Sopenharmony_civoid wasm_callback_env_finalizer(void* env) {
30431cb0ef41Sopenharmony_ci  auto t = static_cast<wasm_callback_env_t*>(env);
30441cb0ef41Sopenharmony_ci  if (t->finalizer) t->finalizer(t->env);
30451cb0ef41Sopenharmony_ci  delete t;
30461cb0ef41Sopenharmony_ci}
30471cb0ef41Sopenharmony_ci
30481cb0ef41Sopenharmony_ci}  // extern "C++"
30491cb0ef41Sopenharmony_ci
30501cb0ef41Sopenharmony_ciwasm_func_t* wasm_func_new(wasm_store_t* store, const wasm_functype_t* type,
30511cb0ef41Sopenharmony_ci                           wasm_func_callback_t callback) {
30521cb0ef41Sopenharmony_ci  return release_func(wasm::Func::make(store, type, wasm_callback,
30531cb0ef41Sopenharmony_ci                                       reinterpret_cast<void*>(callback)));
30541cb0ef41Sopenharmony_ci}
30551cb0ef41Sopenharmony_ci
30561cb0ef41Sopenharmony_ciwasm_func_t* wasm_func_new_with_env(wasm_store_t* store,
30571cb0ef41Sopenharmony_ci                                    const wasm_functype_t* type,
30581cb0ef41Sopenharmony_ci                                    wasm_func_callback_with_env_t callback,
30591cb0ef41Sopenharmony_ci                                    void* env, void (*finalizer)(void*)) {
30601cb0ef41Sopenharmony_ci  auto env2 = new wasm_callback_env_t{callback, env, finalizer};
30611cb0ef41Sopenharmony_ci  return release_func(wasm::Func::make(store, type, wasm_callback_with_env,
30621cb0ef41Sopenharmony_ci                                       env2, wasm_callback_env_finalizer));
30631cb0ef41Sopenharmony_ci}
30641cb0ef41Sopenharmony_ci
30651cb0ef41Sopenharmony_ciwasm_functype_t* wasm_func_type(const wasm_func_t* func) {
30661cb0ef41Sopenharmony_ci  return release_functype(func->type());
30671cb0ef41Sopenharmony_ci}
30681cb0ef41Sopenharmony_ci
30691cb0ef41Sopenharmony_cisize_t wasm_func_param_arity(const wasm_func_t* func) {
30701cb0ef41Sopenharmony_ci  return func->param_arity();
30711cb0ef41Sopenharmony_ci}
30721cb0ef41Sopenharmony_ci
30731cb0ef41Sopenharmony_cisize_t wasm_func_result_arity(const wasm_func_t* func) {
30741cb0ef41Sopenharmony_ci  return func->result_arity();
30751cb0ef41Sopenharmony_ci}
30761cb0ef41Sopenharmony_ci
30771cb0ef41Sopenharmony_ciwasm_trap_t* wasm_func_call(const wasm_func_t* func, const wasm_val_t args[],
30781cb0ef41Sopenharmony_ci                            wasm_val_t results[]) {
30791cb0ef41Sopenharmony_ci  return release_trap(
30801cb0ef41Sopenharmony_ci      func->call(reveal_val_vec(args), reveal_val_vec(results)));
30811cb0ef41Sopenharmony_ci}
30821cb0ef41Sopenharmony_ci
30831cb0ef41Sopenharmony_ci// Global Instances
30841cb0ef41Sopenharmony_ci
30851cb0ef41Sopenharmony_ciWASM_DEFINE_REF(global, wasm::Global)
30861cb0ef41Sopenharmony_ci
30871cb0ef41Sopenharmony_ciwasm_global_t* wasm_global_new(wasm_store_t* store,
30881cb0ef41Sopenharmony_ci                               const wasm_globaltype_t* type,
30891cb0ef41Sopenharmony_ci                               const wasm_val_t* val) {
30901cb0ef41Sopenharmony_ci  auto val_ = borrow_val(val);
30911cb0ef41Sopenharmony_ci  return release_global(wasm::Global::make(store, type, val_.it));
30921cb0ef41Sopenharmony_ci}
30931cb0ef41Sopenharmony_ci
30941cb0ef41Sopenharmony_ciwasm_globaltype_t* wasm_global_type(const wasm_global_t* global) {
30951cb0ef41Sopenharmony_ci  return release_globaltype(global->type());
30961cb0ef41Sopenharmony_ci}
30971cb0ef41Sopenharmony_ci
30981cb0ef41Sopenharmony_civoid wasm_global_get(const wasm_global_t* global, wasm_val_t* out) {
30991cb0ef41Sopenharmony_ci  *out = release_val(global->get());
31001cb0ef41Sopenharmony_ci}
31011cb0ef41Sopenharmony_ci
31021cb0ef41Sopenharmony_civoid wasm_global_set(wasm_global_t* global, const wasm_val_t* val) {
31031cb0ef41Sopenharmony_ci  auto val_ = borrow_val(val);
31041cb0ef41Sopenharmony_ci  global->set(val_.it);
31051cb0ef41Sopenharmony_ci}
31061cb0ef41Sopenharmony_ci
31071cb0ef41Sopenharmony_ci// Table Instances
31081cb0ef41Sopenharmony_ci
31091cb0ef41Sopenharmony_ciWASM_DEFINE_REF(table, wasm::Table)
31101cb0ef41Sopenharmony_ci
31111cb0ef41Sopenharmony_ciwasm_table_t* wasm_table_new(wasm_store_t* store, const wasm_tabletype_t* type,
31121cb0ef41Sopenharmony_ci                             wasm_ref_t* ref) {
31131cb0ef41Sopenharmony_ci  return release_table(wasm::Table::make(store, type, ref));
31141cb0ef41Sopenharmony_ci}
31151cb0ef41Sopenharmony_ci
31161cb0ef41Sopenharmony_ciwasm_tabletype_t* wasm_table_type(const wasm_table_t* table) {
31171cb0ef41Sopenharmony_ci  return release_tabletype(table->type());
31181cb0ef41Sopenharmony_ci}
31191cb0ef41Sopenharmony_ci
31201cb0ef41Sopenharmony_ciwasm_ref_t* wasm_table_get(const wasm_table_t* table, wasm_table_size_t index) {
31211cb0ef41Sopenharmony_ci  return release_ref(table->get(index));
31221cb0ef41Sopenharmony_ci}
31231cb0ef41Sopenharmony_ci
31241cb0ef41Sopenharmony_cibool wasm_table_set(wasm_table_t* table, wasm_table_size_t index,
31251cb0ef41Sopenharmony_ci                    wasm_ref_t* ref) {
31261cb0ef41Sopenharmony_ci  return table->set(index, ref);
31271cb0ef41Sopenharmony_ci}
31281cb0ef41Sopenharmony_ci
31291cb0ef41Sopenharmony_ciwasm_table_size_t wasm_table_size(const wasm_table_t* table) {
31301cb0ef41Sopenharmony_ci  return table->size();
31311cb0ef41Sopenharmony_ci}
31321cb0ef41Sopenharmony_ci
31331cb0ef41Sopenharmony_cibool wasm_table_grow(wasm_table_t* table, wasm_table_size_t delta,
31341cb0ef41Sopenharmony_ci                     wasm_ref_t* ref) {
31351cb0ef41Sopenharmony_ci  return table->grow(delta, ref);
31361cb0ef41Sopenharmony_ci}
31371cb0ef41Sopenharmony_ci
31381cb0ef41Sopenharmony_ci// Memory Instances
31391cb0ef41Sopenharmony_ci
31401cb0ef41Sopenharmony_ciWASM_DEFINE_REF(memory, wasm::Memory)
31411cb0ef41Sopenharmony_ci
31421cb0ef41Sopenharmony_ciwasm_memory_t* wasm_memory_new(wasm_store_t* store,
31431cb0ef41Sopenharmony_ci                               const wasm_memorytype_t* type) {
31441cb0ef41Sopenharmony_ci  return release_memory(wasm::Memory::make(store, type));
31451cb0ef41Sopenharmony_ci}
31461cb0ef41Sopenharmony_ci
31471cb0ef41Sopenharmony_ciwasm_memorytype_t* wasm_memory_type(const wasm_memory_t* memory) {
31481cb0ef41Sopenharmony_ci  return release_memorytype(memory->type());
31491cb0ef41Sopenharmony_ci}
31501cb0ef41Sopenharmony_ci
31511cb0ef41Sopenharmony_ciwasm_byte_t* wasm_memory_data(wasm_memory_t* memory) { return memory->data(); }
31521cb0ef41Sopenharmony_ci
31531cb0ef41Sopenharmony_cisize_t wasm_memory_data_size(const wasm_memory_t* memory) {
31541cb0ef41Sopenharmony_ci  return memory->data_size();
31551cb0ef41Sopenharmony_ci}
31561cb0ef41Sopenharmony_ci
31571cb0ef41Sopenharmony_ciwasm_memory_pages_t wasm_memory_size(const wasm_memory_t* memory) {
31581cb0ef41Sopenharmony_ci  return memory->size();
31591cb0ef41Sopenharmony_ci}
31601cb0ef41Sopenharmony_ci
31611cb0ef41Sopenharmony_cibool wasm_memory_grow(wasm_memory_t* memory, wasm_memory_pages_t delta) {
31621cb0ef41Sopenharmony_ci  return memory->grow(delta);
31631cb0ef41Sopenharmony_ci}
31641cb0ef41Sopenharmony_ci
31651cb0ef41Sopenharmony_ci// Externals
31661cb0ef41Sopenharmony_ci
31671cb0ef41Sopenharmony_ciWASM_DEFINE_REF(extern, wasm::Extern)
31681cb0ef41Sopenharmony_ciWASM_DEFINE_VEC_OWN(extern, wasm::Extern)
31691cb0ef41Sopenharmony_ci
31701cb0ef41Sopenharmony_ciwasm_externkind_t wasm_extern_kind(const wasm_extern_t* external) {
31711cb0ef41Sopenharmony_ci  return hide_externkind(external->kind());
31721cb0ef41Sopenharmony_ci}
31731cb0ef41Sopenharmony_ciwasm_externtype_t* wasm_extern_type(const wasm_extern_t* external) {
31741cb0ef41Sopenharmony_ci  return release_externtype(external->type());
31751cb0ef41Sopenharmony_ci}
31761cb0ef41Sopenharmony_ci
31771cb0ef41Sopenharmony_ciwasm_extern_t* wasm_func_as_extern(wasm_func_t* func) {
31781cb0ef41Sopenharmony_ci  return hide_extern(static_cast<wasm::Extern*>(reveal_func(func)));
31791cb0ef41Sopenharmony_ci}
31801cb0ef41Sopenharmony_ciwasm_extern_t* wasm_global_as_extern(wasm_global_t* global) {
31811cb0ef41Sopenharmony_ci  return hide_extern(static_cast<wasm::Extern*>(reveal_global(global)));
31821cb0ef41Sopenharmony_ci}
31831cb0ef41Sopenharmony_ciwasm_extern_t* wasm_table_as_extern(wasm_table_t* table) {
31841cb0ef41Sopenharmony_ci  return hide_extern(static_cast<wasm::Extern*>(reveal_table(table)));
31851cb0ef41Sopenharmony_ci}
31861cb0ef41Sopenharmony_ciwasm_extern_t* wasm_memory_as_extern(wasm_memory_t* memory) {
31871cb0ef41Sopenharmony_ci  return hide_extern(static_cast<wasm::Extern*>(reveal_memory(memory)));
31881cb0ef41Sopenharmony_ci}
31891cb0ef41Sopenharmony_ci
31901cb0ef41Sopenharmony_ciconst wasm_extern_t* wasm_func_as_extern_const(const wasm_func_t* func) {
31911cb0ef41Sopenharmony_ci  return hide_extern(static_cast<const wasm::Extern*>(reveal_func(func)));
31921cb0ef41Sopenharmony_ci}
31931cb0ef41Sopenharmony_ciconst wasm_extern_t* wasm_global_as_extern_const(const wasm_global_t* global) {
31941cb0ef41Sopenharmony_ci  return hide_extern(static_cast<const wasm::Extern*>(reveal_global(global)));
31951cb0ef41Sopenharmony_ci}
31961cb0ef41Sopenharmony_ciconst wasm_extern_t* wasm_table_as_extern_const(const wasm_table_t* table) {
31971cb0ef41Sopenharmony_ci  return hide_extern(static_cast<const wasm::Extern*>(reveal_table(table)));
31981cb0ef41Sopenharmony_ci}
31991cb0ef41Sopenharmony_ciconst wasm_extern_t* wasm_memory_as_extern_const(const wasm_memory_t* memory) {
32001cb0ef41Sopenharmony_ci  return hide_extern(static_cast<const wasm::Extern*>(reveal_memory(memory)));
32011cb0ef41Sopenharmony_ci}
32021cb0ef41Sopenharmony_ci
32031cb0ef41Sopenharmony_ciwasm_func_t* wasm_extern_as_func(wasm_extern_t* external) {
32041cb0ef41Sopenharmony_ci  return hide_func(external->func());
32051cb0ef41Sopenharmony_ci}
32061cb0ef41Sopenharmony_ciwasm_global_t* wasm_extern_as_global(wasm_extern_t* external) {
32071cb0ef41Sopenharmony_ci  return hide_global(external->global());
32081cb0ef41Sopenharmony_ci}
32091cb0ef41Sopenharmony_ciwasm_table_t* wasm_extern_as_table(wasm_extern_t* external) {
32101cb0ef41Sopenharmony_ci  return hide_table(external->table());
32111cb0ef41Sopenharmony_ci}
32121cb0ef41Sopenharmony_ciwasm_memory_t* wasm_extern_as_memory(wasm_extern_t* external) {
32131cb0ef41Sopenharmony_ci  return hide_memory(external->memory());
32141cb0ef41Sopenharmony_ci}
32151cb0ef41Sopenharmony_ci
32161cb0ef41Sopenharmony_ciconst wasm_func_t* wasm_extern_as_func_const(const wasm_extern_t* external) {
32171cb0ef41Sopenharmony_ci  return hide_func(external->func());
32181cb0ef41Sopenharmony_ci}
32191cb0ef41Sopenharmony_ciconst wasm_global_t* wasm_extern_as_global_const(
32201cb0ef41Sopenharmony_ci    const wasm_extern_t* external) {
32211cb0ef41Sopenharmony_ci  return hide_global(external->global());
32221cb0ef41Sopenharmony_ci}
32231cb0ef41Sopenharmony_ciconst wasm_table_t* wasm_extern_as_table_const(const wasm_extern_t* external) {
32241cb0ef41Sopenharmony_ci  return hide_table(external->table());
32251cb0ef41Sopenharmony_ci}
32261cb0ef41Sopenharmony_ciconst wasm_memory_t* wasm_extern_as_memory_const(
32271cb0ef41Sopenharmony_ci    const wasm_extern_t* external) {
32281cb0ef41Sopenharmony_ci  return hide_memory(external->memory());
32291cb0ef41Sopenharmony_ci}
32301cb0ef41Sopenharmony_ci
32311cb0ef41Sopenharmony_ci// Module Instances
32321cb0ef41Sopenharmony_ci
32331cb0ef41Sopenharmony_ciWASM_DEFINE_REF(instance, wasm::Instance)
32341cb0ef41Sopenharmony_ci
32351cb0ef41Sopenharmony_ciwasm_instance_t* wasm_instance_new(wasm_store_t* store,
32361cb0ef41Sopenharmony_ci                                   const wasm_module_t* module,
32371cb0ef41Sopenharmony_ci                                   const wasm_extern_t* const imports[],
32381cb0ef41Sopenharmony_ci                                   wasm_trap_t** trap) {
32391cb0ef41Sopenharmony_ci  wasm::own<wasm::Trap> error;
32401cb0ef41Sopenharmony_ci  wasm_instance_t* instance = release_instance(wasm::Instance::make(
32411cb0ef41Sopenharmony_ci      store, module, reinterpret_cast<const wasm::Extern* const*>(imports),
32421cb0ef41Sopenharmony_ci      &error));
32431cb0ef41Sopenharmony_ci  if (trap) *trap = hide_trap(error.release());
32441cb0ef41Sopenharmony_ci  return instance;
32451cb0ef41Sopenharmony_ci}
32461cb0ef41Sopenharmony_ci
32471cb0ef41Sopenharmony_civoid wasm_instance_exports(const wasm_instance_t* instance,
32481cb0ef41Sopenharmony_ci                           wasm_extern_vec_t* out) {
32491cb0ef41Sopenharmony_ci  *out = release_extern_vec(instance->exports());
32501cb0ef41Sopenharmony_ci}
32511cb0ef41Sopenharmony_ci
32521cb0ef41Sopenharmony_ciwasm_instance_t* wasm_frame_instance(const wasm_frame_t* frame) {
32531cb0ef41Sopenharmony_ci  return hide_instance(reveal_frame(frame)->instance());
32541cb0ef41Sopenharmony_ci}
32551cb0ef41Sopenharmony_ci
32561cb0ef41Sopenharmony_ci#undef WASM_DEFINE_OWN
32571cb0ef41Sopenharmony_ci#undef WASM_DEFINE_VEC_BASE
32581cb0ef41Sopenharmony_ci#undef WASM_DEFINE_VEC_PLAIN
32591cb0ef41Sopenharmony_ci#undef WASM_DEFINE_VEC_OWN
32601cb0ef41Sopenharmony_ci#undef WASM_DEFINE_TYPE
32611cb0ef41Sopenharmony_ci#undef WASM_DEFINE_REF_BASE
32621cb0ef41Sopenharmony_ci#undef WASM_DEFINE_REF
32631cb0ef41Sopenharmony_ci#undef WASM_DEFINE_SHARABLE_REF
32641cb0ef41Sopenharmony_ci
32651cb0ef41Sopenharmony_ci}  // extern "C"
3266