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