#include "src/wasm/c-api.h"
#include <cstring>
#include <iomanip>
#include <iostream>
#include "include/libplatform/libplatform.h"
#include "include/v8-initialization.h"
#include "src/api/api-inl.h"
#include "src/builtins/builtins.h"
#include "src/compiler/wasm-compiler.h"
#include "src/flags/flags.h"
#include "src/objects/call-site-info-inl.h"
#include "src/objects/js-collection-inl.h"
#include "src/objects/managed-inl.h"
#include "src/wasm/leb-helper.h"
#include "src/wasm/module-instantiate.h"
#include "src/wasm/serialized-signature-inl.h"
#include "src/wasm/signature-hashing.h"
#include "src/wasm/wasm-arguments.h"
#include "src/wasm/wasm-constants.h"
#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-objects.h"
#include "src/wasm/wasm-result.h"
#include "src/wasm/wasm-serialization.h"
#include "third_party/wasm-api/wasm.h"
#ifdef ENABLE_VTUNE_JIT_INTERFACE
#include "src/third_party/vtune/v8-vtune.h"
#endif
#ifdef WASM_API_DEBUG
#error "WASM_API_DEBUG is unsupported"
#endif
#define DUMP_COUNTERS …
namespace wasm {
namespace {
PtrComprCageAccessScope;
auto ReadLebU64(const byte_t** pos) -> uint64_t { … }
ValKind V8ValueTypeToWasm(i::wasm::ValueType v8_valtype) { … }
i::wasm::ValueType WasmValKindToV8(ValKind kind) { … }
Name GetNameFromWireBytes(const i::wasm::WireBytesRef& ref,
v8::base::Vector<const uint8_t> wire_bytes) { … }
own<FuncType> FunctionSigToFuncType(const i::wasm::FunctionSig* sig) { … }
own<ExternType> GetImportExportType(const i::wasm::WasmModule* module,
const i::wasm::ImportExportKindCode kind,
const uint32_t index) { … }
}
[[noreturn]] void WASM_UNIMPLEMENTED(const char* s) { … }
template <class T>
void ignore(T) { … }
template <class C>
struct implement;
template <class C>
auto impl(C* x) -> typename implement<C>::type* { … }
template <class C>
auto impl(const C* x) -> const typename implement<C>::type* { … }
template <class C>
auto seal(typename implement<C>::type* x) -> C* { … }
template <class C>
auto seal(const typename implement<C>::type* x) -> const C* { … }
struct ConfigImpl { … };
template <>
struct implement<Config> { … };
Config::~Config() { … }
void Config::operator delete(void* p) { … }
auto Config::make() -> own<Config> { … }
#if DUMP_COUNTERS
class Counter {
public:
static const int kMaxNameSize = 64;
int32_t* Bind(const char* name, bool is_histogram) {
int i;
for (i = 0; i < kMaxNameSize - 1 && name[i]; i++) {
name_[i] = static_cast<char>(name[i]);
}
name_[i] = '\0';
is_histogram_ = is_histogram;
return ptr();
}
int32_t* ptr() { return &count_; }
int32_t count() { return count_; }
int32_t sample_total() { return sample_total_; }
bool is_histogram() { return is_histogram_; }
void AddSample(int32_t sample) {
count_++;
sample_total_ += sample;
}
private:
int32_t count_;
int32_t sample_total_;
bool is_histogram_;
uint8_t name_[kMaxNameSize];
};
class CounterCollection {
public:
CounterCollection() = default;
Counter* GetNextCounter() {
if (counters_in_use_ == kMaxCounters) return nullptr;
return &counters_[counters_in_use_++];
}
private:
static const unsigned kMaxCounters = 512;
uint32_t counters_in_use_{0};
Counter counters_[kMaxCounters];
};
using CounterMap = std::unordered_map<std::string, Counter*>;
#endif
struct EngineImpl { … };
bool EngineImpl::created = …;
#if DUMP_COUNTERS
CounterCollection EngineImpl::counters_;
CounterMap* EngineImpl::counter_map_;
#endif
template <>
struct implement<Engine> { … };
Engine::~Engine() { … }
void Engine::operator delete(void* p) { … }
auto Engine::make(own<Config>&& config) -> own<Engine> { … }
void CheckAndHandleInterrupts(i::Isolate* isolate) { … }
StoreImpl::~StoreImpl() { … }
struct ManagedData { … };
void StoreImpl::SetHostInfo(i::Handle<i::Object> object, void* info,
void (*finalizer)(void*)) { … }
void* StoreImpl::GetHostInfo(i::Handle<i::Object> key) { … }
template <>
struct implement<Store> { … };
Store::~Store() { … }
void Store::operator delete(void* p) { … }
auto Store::make(Engine*) -> own<Store> { … }
struct ValTypeImpl { … };
template <>
struct implement<ValType> { … };
ValTypeImpl* valtype_i32 = …;
ValTypeImpl* valtype_i64 = …;
ValTypeImpl* valtype_f32 = …;
ValTypeImpl* valtype_f64 = …;
ValTypeImpl* valtype_externref = …;
ValTypeImpl* valtype_funcref = …;
ValType::~ValType() = default;
void ValType::operator delete(void*) { … }
own<ValType> ValType::make(ValKind k) { … }
auto ValType::copy() const -> own<ValType> { … }
auto ValType::kind() const -> ValKind { … }
struct ExternTypeImpl { … };
template <>
struct implement<ExternType> { … };
ExternType::~ExternType() { … }
void ExternType::operator delete(void* p) { … }
auto ExternType::copy() const -> own<ExternType> { … }
auto ExternType::kind() const -> ExternKind { … }
struct FuncTypeImpl : ExternTypeImpl { … };
template <>
struct implement<FuncType> { … };
FuncType::~FuncType() = default;
auto FuncType::make(ownvec<ValType>&& params, ownvec<ValType>&& results)
-> own<FuncType> { … }
auto FuncType::copy() const -> own<FuncType> { … }
auto FuncType::params() const -> const ownvec<ValType>& { … }
auto FuncType::results() const -> const ownvec<ValType>& { … }
auto ExternType::func() -> FuncType* { … }
auto ExternType::func() const -> const FuncType* { … }
struct GlobalTypeImpl : ExternTypeImpl { … };
template <>
struct implement<GlobalType> { … };
GlobalType::~GlobalType() = default;
auto GlobalType::make(own<ValType>&& content, Mutability mutability)
-> own<GlobalType> { … }
auto GlobalType::copy() const -> own<GlobalType> { … }
auto GlobalType::content() const -> const ValType* { … }
auto GlobalType::mutability() const -> Mutability { … }
auto ExternType::global() -> GlobalType* { … }
auto ExternType::global() const -> const GlobalType* { … }
struct TableTypeImpl : ExternTypeImpl { … };
template <>
struct implement<TableType> { … };
TableType::~TableType() = default;
auto TableType::make(own<ValType>&& element, Limits limits) -> own<TableType> { … }
auto TableType::copy() const -> own<TableType> { … }
auto TableType::element() const -> const ValType* { … }
auto TableType::limits() const -> const Limits& { … }
auto ExternType::table() -> TableType* { … }
auto ExternType::table() const -> const TableType* { … }
struct MemoryTypeImpl : ExternTypeImpl { … };
template <>
struct implement<MemoryType> { … };
MemoryType::~MemoryType() = default;
auto MemoryType::make(Limits limits) -> own<MemoryType> { … }
auto MemoryType::copy() const -> own<MemoryType> { … }
auto MemoryType::limits() const -> const Limits& { … }
auto ExternType::memory() -> MemoryType* { … }
auto ExternType::memory() const -> const MemoryType* { … }
struct ImportTypeImpl { … };
template <>
struct implement<ImportType> { … };
ImportType::~ImportType() { … }
void ImportType::operator delete(void* p) { … }
auto ImportType::make(Name&& module, Name&& name, own<ExternType>&& type)
-> own<ImportType> { … }
auto ImportType::copy() const -> own<ImportType> { … }
auto ImportType::module() const -> const Name& { … }
auto ImportType::name() const -> const Name& { … }
auto ImportType::type() const -> const ExternType* { … }
struct ExportTypeImpl { … };
template <>
struct implement<ExportType> { … };
ExportType::~ExportType() { … }
void ExportType::operator delete(void* p) { … }
auto ExportType::make(Name&& name, own<ExternType>&& type) -> own<ExportType> { … }
auto ExportType::copy() const -> own<ExportType> { … }
auto ExportType::name() const -> const Name& { … }
auto ExportType::type() const -> const ExternType* { … }
i::Handle<i::String> VecToString(i::Isolate* isolate,
const vec<byte_t>& chars) { … }
template <class Ref, class JSType>
class RefImpl { … };
template <>
struct implement<Ref> { … };
Ref::~Ref() { … }
void Ref::operator delete(void* p) { … }
auto Ref::copy() const -> own<Ref> { … }
auto Ref::same(const Ref* that) const -> bool { … }
auto Ref::get_host_info() const -> void* { … }
void Ref::set_host_info(void* info, void (*finalizer)(void*)) { … }
namespace {
struct FrameImpl { … };
}
template <>
struct implement<Frame> { … };
Frame::~Frame() { … }
void Frame::operator delete(void* p) { … }
own<Frame> Frame::copy() const { … }
Instance* Frame::instance() const { … }
uint32_t Frame::func_index() const { … }
size_t Frame::func_offset() const { … }
size_t Frame::module_offset() const { … }
template <>
struct implement<Trap> { … };
Trap::~Trap() = default;
auto Trap::copy() const -> own<Trap> { … }
auto Trap::make(Store* store_abs, const Message& message) -> own<Trap> { … }
auto Trap::message() const -> Message { … }
namespace {
own<Instance> GetInstance(StoreImpl* store,
i::Handle<i::WasmInstanceObject> instance);
own<Frame> CreateFrameFromInternal(i::DirectHandle<i::FixedArray> frames,
int index, i::Isolate* isolate,
StoreImpl* store) { … }
}
own<Frame> Trap::origin() const { … }
ownvec<Frame> Trap::trace() const { … }
template <>
struct implement<Foreign> { … };
Foreign::~Foreign() = default;
auto Foreign::copy() const -> own<Foreign> { … }
auto Foreign::make(Store* store_abs) -> own<Foreign> { … }
template <>
struct implement<Module> { … };
Module::~Module() = default;
auto Module::copy() const -> own<Module> { … }
auto Module::validate(Store* store_abs, const vec<byte_t>& binary) -> bool { … }
auto Module::make(Store* store_abs, const vec<byte_t>& binary) -> own<Module> { … }
auto Module::imports() const -> ownvec<ImportType> { … }
ownvec<ExportType> ExportsImpl(
i::DirectHandle<i::WasmModuleObject> module_obj) { … }
auto Module::exports() const -> ownvec<ExportType> { … }
auto Module::serialize() const -> vec<byte_t> { … }
auto Module::deserialize(Store* store_abs, const vec<byte_t>& serialized)
-> own<Module> { … }
template <>
struct implement<Shared<Module>> { … };
template <>
Shared<Module>::~Shared() {
impl(this)->~vec();
}
template <>
void Shared<Module>::operator delete(void* p) {
::operator delete(p);
}
auto Module::share() const -> own<Shared<Module>> { … }
auto Module::obtain(Store* store, const Shared<Module>* shared) -> own<Module> { … }
template <>
struct implement<Extern> { … };
Extern::~Extern() = default;
auto Extern::copy() const -> own<Extern> { … }
auto Extern::kind() const -> ExternKind { … }
auto Extern::type() const -> own<ExternType> { … }
auto Extern::func() -> Func* { … }
auto Extern::global() -> Global* { … }
auto Extern::table() -> Table* { … }
auto Extern::memory() -> Memory* { … }
auto Extern::func() const -> const Func* { … }
auto Extern::global() const -> const Global* { … }
auto Extern::table() const -> const Table* { … }
auto Extern::memory() const -> const Memory* { … }
auto extern_to_v8(const Extern* ex) -> i::Handle<i::JSReceiver> { … }
template <>
struct implement<Func> { … };
Func::~Func() = default;
auto Func::copy() const -> own<Func> { … }
struct FuncData { … };
namespace {
class SignatureHelper : public i::AllStatic { … };
auto make_func(Store* store_abs, std::shared_ptr<FuncData> data) -> own<Func> { … }
}
auto Func::make(Store* store, const FuncType* type, Func::callback callback)
-> own<Func> { … }
auto Func::make(Store* store, const FuncType* type, callback_with_env callback,
void* env, void (*finalizer)(void*)) -> own<Func> { … }
auto Func::type() const -> own<FuncType> { … }
auto Func::param_arity() const -> size_t { … }
auto Func::result_arity() const -> size_t { … }
namespace {
own<Ref> V8RefValueToWasm(StoreImpl* store, i::Handle<i::Object> value) { … }
i::Handle<i::Object> WasmRefToV8(i::Isolate* isolate, const Ref* ref) { … }
void PrepareFunctionData(
i::Isolate* isolate,
i::DirectHandle<i::WasmExportedFunctionData> function_data,
const i::wasm::FunctionSig* sig, const i::wasm::WasmModule* module) { … }
void PushArgs(const i::wasm::FunctionSig* sig, const Val args[],
i::wasm::CWasmArgumentsPacker* packer, StoreImpl* store) { … }
void PopArgs(const i::wasm::FunctionSig* sig, Val results[],
i::wasm::CWasmArgumentsPacker* packer, StoreImpl* store) { … }
own<Trap> CallWasmCapiFunction(i::Tagged<i::WasmCapiFunctionData> data,
const Val args[], Val results[]) { … }
i::Handle<i::JSReceiver> GetProperException(
i::Isolate* isolate, i::Handle<i::Object> maybe_exception) { … }
}
auto Func::call(const Val args[], Val results[]) const -> own<Trap> { … }
i::Address FuncData::v8_callback(i::Address host_data_foreign,
i::Address argv) { … }
template <>
struct implement<Global> { … };
Global::~Global() = default;
auto Global::copy() const -> own<Global> { … }
auto Global::make(Store* store_abs, const GlobalType* type, const Val& val)
-> own<Global> { … }
auto Global::type() const -> own<GlobalType> { … }
auto Global::get() const -> Val { … }
void Global::set(const Val& val) { … }
template <>
struct implement<Table> { … };
Table::~Table() = default;
auto Table::copy() const -> own<Table> { … }
auto Table::make(Store* store_abs, const TableType* type, const Ref* ref)
-> own<Table> { … }
auto Table::type() const -> own<TableType> { … }
auto Table::get(size_t index) const -> own<Ref> { … }
auto Table::set(size_t index, const Ref* ref) -> bool { … }
auto Table::size() const -> size_t { … }
auto Table::grow(size_t delta, const Ref* ref) -> bool { … }
template <>
struct implement<Memory> { … };
Memory::~Memory() = default;
auto Memory::copy() const -> own<Memory> { … }
auto Memory::make(Store* store_abs, const MemoryType* type) -> own<Memory> { … }
auto Memory::type() const -> own<MemoryType> { … }
auto Memory::data() const -> byte_t* { … }
auto Memory::data_size() const -> size_t { … }
auto Memory::size() const -> pages_t { … }
auto Memory::grow(pages_t delta) -> bool { … }
template <>
struct implement<Instance> { … };
Instance::~Instance() = default;
auto Instance::copy() const -> own<Instance> { … }
own<Instance> Instance::make(Store* store_abs, const Module* module_abs,
const Extern* const imports[], own<Trap>* trap) { … }
namespace {
own<Instance> GetInstance(StoreImpl* store,
i::Handle<i::WasmInstanceObject> instance) { … }
}
auto Instance::exports() const -> ownvec<Extern> { … }
}
extern …