diff --git a/include/wasm.hh b/include/wasm.hh index 597c10f..acd29ee 100644 --- a/include/wasm.hh +++ b/include/wasm.hh @@ -180,12 +180,20 @@ public: // Ownership -template using own = std::unique_ptr; -template using ownvec = vec>; +class destroyer { +public: + template + void operator()(T* ptr) { + ptr->destroy(); + } +}; -template -auto make_own(T* x) -> own { return own(x); } +template using own = std::unique_ptr; +template using ownvec = vec>; +template own make_own(T* ptr) { + return own(ptr); +} /////////////////////////////////////////////////////////////////////////////// // Runtime Environment @@ -193,11 +201,14 @@ auto make_own(T* x) -> own { return own(x); } // Configuration class WASM_API_EXTERN Config { -public: - Config() = delete; - ~Config(); - void operator delete(void*); + friend class destroyer; + void destroy(); + +protected: + Config() = default; + ~Config() = default; +public: static auto make() -> own; // Implementations may provide custom methods for manipulating Configs. @@ -207,11 +218,14 @@ public: // Engine class WASM_API_EXTERN Engine { -public: - Engine() = delete; - ~Engine(); - void operator delete(void*); + friend class destroyer; + void destroy(); +protected: + Engine() = default; + ~Engine() = default; + +public: static auto make(own&& = Config::make()) -> own; }; @@ -219,11 +233,14 @@ public: // Store class WASM_API_EXTERN Store { -public: - Store() = delete; - ~Store(); - void operator delete(void*); + friend class destroyer; + void destroy(); +protected: + Store() = default; + ~Store() = default; + +public: static auto make(Engine*) -> own; }; @@ -256,11 +273,14 @@ inline bool is_ref(ValKind k) { return k >= ValKind::ANYREF; } class WASM_API_EXTERN ValType { -public: - ValType() = delete; - ~ValType(); - void operator delete(void*); + friend class destroyer; + void destroy(); +protected: + ValType() = default; + ~ValType() = default; + +public: static auto make(ValKind) -> own; auto copy() const -> own; @@ -282,11 +302,14 @@ class TableType; class MemoryType; class WASM_API_EXTERN ExternType { -public: - ExternType() = delete; - ~ExternType(); - void operator delete(void*); + friend class destroyer; + void destroy(); +protected: + ExternType() = default; + ~ExternType() = default; + +public: auto copy() const-> own; auto kind() const -> ExternKind; @@ -306,10 +329,14 @@ public: // Function Types class WASM_API_EXTERN FuncType : public ExternType { -public: - FuncType() = delete; - ~FuncType(); + friend class destroyer; + void destroy(); + +protected: + FuncType() = default; + ~FuncType() = default; +public: static auto make( ownvec&& params = ownvec::make(), ownvec&& results = ownvec::make() @@ -325,10 +352,14 @@ public: // Global Types class WASM_API_EXTERN GlobalType : public ExternType { -public: - GlobalType() = delete; - ~GlobalType(); + friend class destroyer; + void destroy(); + +protected: + GlobalType() = default; + ~GlobalType() = default; +public: static auto make(own&&, Mutability) -> own; auto copy() const -> own; @@ -340,10 +371,14 @@ public: // Table Types class WASM_API_EXTERN TableType : public ExternType { -public: - TableType() = delete; - ~TableType(); + friend class destroyer; + void destroy(); + +protected: + TableType() = default; + ~TableType() = default; +public: static auto make(own&&, Limits) -> own; auto copy() const -> own; @@ -355,10 +390,14 @@ public: // Memory Types class WASM_API_EXTERN MemoryType : public ExternType { -public: - MemoryType() = delete; - ~MemoryType(); + friend class destroyer; + void destroy(); + +protected: + MemoryType() = default; + ~MemoryType() = default; +public: static auto make(Limits) -> own; auto copy() const -> own; @@ -371,11 +410,14 @@ public: using Name = vec; class WASM_API_EXTERN ImportType { -public: - ImportType() = delete; - ~ImportType(); - void operator delete(void*); + friend class destroyer; + void destroy(); + +protected: + ImportType() = default; + ~ImportType() = default; +public: static auto make(Name&& module, Name&& name, own&&) -> own; auto copy() const -> own; @@ -389,11 +431,14 @@ public: // Export Types class WASM_API_EXTERN ExportType { -public: - ExportType() = delete; - ~ExportType(); - void operator delete(void*); + friend class destroyer; + void destroy(); +protected: + ExportType() = default; + ~ExportType() = default; + +public: static auto make(Name&&, own&&) -> own; auto copy() const -> own; @@ -408,11 +453,14 @@ public: // References class WASM_API_EXTERN Ref { -public: - Ref() = delete; - ~Ref(); - void operator delete(void*); + friend class destroyer; + void destroy(); +protected: + Ref() = default; + ~Ref() = default; + +public: auto copy() const -> own; auto same(const Ref*) const -> bool; @@ -464,7 +512,7 @@ public: void reset() { if (is_ref() && impl_.ref) { - delete impl_.ref; + destroyer()(impl_.ref); impl_.ref = nullptr; } } @@ -479,7 +527,7 @@ public: auto operator=(Val&& that) -> Val& { reset(that); return *this; - } + } auto kind() const -> ValKind { return kind_; } auto i32() const -> int32_t { assert(kind_ == ValKind::I32); return impl_.i32; } @@ -546,11 +594,14 @@ using Message = vec; // null terminated class Instance; class WASM_API_EXTERN Frame { -public: - Frame() = delete; - ~Frame(); - void operator delete(void*); + friend class destroyer; + void destroy(); + +protected: + Frame() = default; + ~Frame() = default; +public: auto copy() const -> own; auto instance() const -> Instance*; @@ -560,10 +611,14 @@ public: }; class WASM_API_EXTERN Trap : public Ref { -public: - Trap() = delete; - ~Trap(); + friend class destroyer; + void destroy(); + +protected: + Trap() = default; + ~Trap() = default; +public: static auto make(Store*, const Message& msg) -> own; auto copy() const -> own; @@ -573,24 +628,19 @@ public: }; -// Shared objects +// Modules -template -class WASM_API_EXTERN Shared { -public: - Shared() = delete; - ~Shared(); - void operator delete(void*); -}; +template class WASM_API_EXTERN Shared; +class WASM_API_EXTERN Module : public Ref { + friend class destroyer; + void destroy(); -// Modules +protected: + Module() = default; + ~Module() = default; -class WASM_API_EXTERN Module : public Ref { public: - Module() = delete; - ~Module(); - static auto validate(Store*, const vec& binary) -> bool; static auto make(Store*, const vec& binary) -> own; auto copy() const -> own; @@ -606,13 +656,30 @@ public: }; +// Shared objects + +template<> +class WASM_API_EXTERN Shared { + friend class destroyer; + void destroy(); + +protected: + Shared() = default; + ~Shared() = default; +}; + + // Foreign Objects class WASM_API_EXTERN Foreign : public Ref { -public: - Foreign() = delete; - ~Foreign(); + friend class destroyer; + void destroy(); + +protected: + Foreign() = default; + ~Foreign() = default; +public: static auto make(Store*) -> own; auto copy() const -> own; }; @@ -626,10 +693,14 @@ class Table; class Memory; class WASM_API_EXTERN Extern : public Ref { -public: - Extern() = delete; - ~Extern(); + friend class destroyer; + void destroy(); + +protected: + Extern() = default; + ~Extern() = default; +public: auto copy() const -> own; auto kind() const -> ExternKind; @@ -650,10 +721,14 @@ public: // Function Instances class WASM_API_EXTERN Func : public Extern { -public: - Func() = delete; - ~Func(); + friend class destroyer; + void destroy(); + +protected: + Func() = default; + ~Func() = default; +public: using callback = auto (*)(const vec&, vec&) -> own; using callback_with_env = auto (*)(void*, const vec&, vec&) -> own; @@ -673,10 +748,14 @@ public: // Global Instances class WASM_API_EXTERN Global : public Extern { -public: - Global() = delete; - ~Global(); + friend class destroyer; + void destroy(); +protected: + Global() = default; + ~Global() = default; + + public: static auto make(Store*, const GlobalType*, const Val&) -> own; auto copy() const -> own; @@ -689,10 +768,14 @@ public: // Table Instances class WASM_API_EXTERN Table : public Extern { -public: - Table() = delete; - ~Table(); + friend class destroyer; + void destroy(); + +protected: + Table() = default; + ~Table() = default; +public: using size_t = uint32_t; static auto make( @@ -710,10 +793,14 @@ public: // Memory Instances class WASM_API_EXTERN Memory : public Extern { -public: - Memory() = delete; - ~Memory(); + friend class destroyer; + void destroy(); +protected: + Memory() = default; + ~Memory() = default; + +public: static auto make(Store*, const MemoryType*) -> own; auto copy() const -> own; @@ -732,10 +819,14 @@ public: // Module Instances class WASM_API_EXTERN Instance : public Ref { -public: - Instance() = delete; - ~Instance(); + friend class destroyer; + void destroy(); +protected: + Instance() = default; + ~Instance() = default; + +public: static auto make( Store*, const Module*, const vec&, own* = nullptr ) -> own; diff --git a/src/wasm-v8.cc b/src/wasm-v8.cc index b58aaf4..1b84301 100644 --- a/src/wasm-v8.cc +++ b/src/wasm-v8.cc @@ -6,6 +6,7 @@ #include "libplatform/libplatform.h" #include +#include #ifdef WASM_API_DEBUG #include @@ -45,22 +46,12 @@ template struct implement; template auto impl(C* x) -> typename implement ::type* { - return reinterpret_cast::type*>(x); + return static_cast::type*>(x); } template auto impl(const C* x) -> const typename implement::type* { - return reinterpret_cast::type*>(x); -} - -template -auto seal(typename implement ::type* x) -> C* { - return reinterpret_cast(x); -} - -template -auto seal(const typename implement ::type* x) -> const C* { - return reinterpret_cast(x); + return static_cast::type*>(x); } @@ -175,6 +166,15 @@ struct Stats { } }; +template struct categorize; +template<> struct categorize { static const auto value = Stats::FUNC; }; +template<> struct categorize { static const auto value = Stats::GLOBAL; }; +template<> struct categorize { static const auto value = Stats::TABLE; }; +template<> struct categorize { static const auto value = Stats::MEMORY; }; +template<> struct categorize { static const auto value = Stats::MODULE; }; +template<> struct categorize { static const auto value = Stats::INSTANCE; }; +template<> struct categorize { static const auto value = Stats::TRAP; }; + #ifdef WASM_API_DEBUG const char* Stats::name[STRONG_COUNT] = { "byte_t", "Config", "Engine", "Store", "Frame", @@ -240,7 +240,7 @@ DEFINE_VEC(Val, vec, VAL) // Configuration -struct ConfigImpl { +struct ConfigImpl : Config { ConfigImpl() { stats.make(Stats::CONFIG, this); } ~ConfigImpl() { stats.free(Stats::CONFIG, this); } }; @@ -248,22 +248,18 @@ struct ConfigImpl { template<> struct implement { using type = ConfigImpl; }; -Config::~Config() { - impl(this)->~ConfigImpl(); -} - -void Config::operator delete(void *p) { - ::operator delete(p); +void Config::destroy() { + delete impl(this); } auto Config::make() -> own { - return own(seal(new(std::nothrow) ConfigImpl())); + return own(new(std::nothrow) ConfigImpl()); } // Engine -struct EngineImpl { +struct EngineImpl : Engine { static bool created; std::unique_ptr platform; @@ -286,12 +282,8 @@ bool EngineImpl::created = false; template<> struct implement { using type = EngineImpl; }; -Engine::~Engine() { - impl(this)->~EngineImpl(); -} - -void Engine::operator delete(void *p) { - ::operator delete(p); +void Engine::destroy() { + delete impl(this); } auto Engine::make(own&& config) -> own { @@ -309,7 +301,7 @@ auto Engine::make(own&& config) -> own { engine->platform = v8::platform::NewDefaultPlatform(); v8::V8::InitializePlatform(engine->platform.get()); v8::V8::Initialize(); - return make_own(seal(engine)); + return own(engine); } @@ -334,11 +326,11 @@ enum v8_function_t { V8_F_COUNT, }; -class StoreImpl { +struct StoreImpl : Store { friend own Store::make(Engine*); v8::Isolate::CreateParams create_params_; - v8::Isolate *isolate_; + v8::Isolate* isolate_; v8::Eternal context_; v8::Eternal strings_[V8_S_COUNT]; v8::Eternal symbols_[V8_Y_COUNT]; @@ -347,7 +339,6 @@ class StoreImpl { v8::Eternal callback_symbol_; v8::Persistent* handle_pool_ = nullptr; // TODO: use v8::Value -public: StoreImpl() { stats.make(Stats::STORE, this); } @@ -426,16 +417,12 @@ class StoreImpl { template<> struct implement { using type = StoreImpl; }; -Store::~Store() { - impl(this)->~StoreImpl(); -} - -void Store::operator delete(void *p) { - ::operator delete(p); +void Store::destroy() { + delete impl(this); } auto Store::make(Engine*) -> own { - auto store = make_own(new(std::nothrow) StoreImpl()); + auto store = own(new(std::nothrow) StoreImpl()); if (!store) return own(); // Create isolate. @@ -532,7 +519,7 @@ auto Store::make(Engine*) -> own { store->context()->Enter(); isolate->SetData(0, store.get()); - return make_own(seal(store.release())); + return store; }; @@ -541,10 +528,11 @@ auto Store::make(Engine*) -> own { // Value Types -struct ValTypeImpl { +struct ValTypeImpl : ValType { ValKind kind; ValTypeImpl(ValKind kind) : kind(kind) {} + ~ValTypeImpl() {} }; template<> struct implement { using type = ValTypeImpl; }; @@ -557,12 +545,10 @@ ValTypeImpl* valtype_anyref = new ValTypeImpl(ValKind::ANYREF); ValTypeImpl* valtype_funcref = new ValTypeImpl(ValKind::FUNCREF); -ValType::~ValType() { +void ValType::destroy() { stats.free(Stats::VALTYPE, this); } -void ValType::operator delete(void*) {} - auto ValType::make(ValKind k) -> own { ValTypeImpl* valtype; switch (k) { @@ -576,9 +562,8 @@ auto ValType::make(ValKind k) -> own { // TODO(wasm+): support new value types assert(false); }; - auto result = seal(valtype); - stats.make(Stats::VALTYPE, result); - return own(result); + stats.make(Stats::VALTYPE, valtype); + return own(valtype); } auto ValType::copy() const -> own { @@ -592,23 +577,27 @@ auto ValType::kind() const -> ValKind { // Extern Types -struct ExternTypeImpl { +struct ExternTypeKind { ExternKind kind; - - explicit ExternTypeImpl(ExternKind kind) : kind(kind) {} - virtual ~ExternTypeImpl() {} }; -template<> struct implement { using type = ExternTypeImpl; }; - - -ExternType::~ExternType() { - impl(this)->~ExternTypeImpl(); +auto ExternType::kind() const -> ExternKind { + return reinterpret_cast(this)->kind; } -void ExternType::operator delete(void *p) { - ::operator delete(p); -} +template +struct ExternTypeImpl : Base, ExternTypeKind { + ExternTypeImpl(ExternKind kind) : ExternTypeKind{kind} {} +}; + +static_assert(std::is_standard_layout>::value, + "FuncType*, ExternType* and ExternTypeKind are not pointer-interconvertible."); +static_assert(std::is_standard_layout>::value, + "GlobalType*, ExternType* and ExternTypeKind are not pointer-interconvertible."); +static_assert(std::is_standard_layout>::value, + "TableType*, ExternType* and ExternTypeKind are not pointer-interconvertible."); +static_assert(std::is_standard_layout>::value, + "MemoryType*, ExternType* and ExternTypeKind are not pointer-interconvertible."); auto ExternType::copy() const -> own { switch (kind()) { @@ -619,20 +608,17 @@ auto ExternType::copy() const -> own { } } -auto ExternType::kind() const -> ExternKind { - return impl(this)->kind; -} - // Function Types -struct FuncTypeImpl : ExternTypeImpl { +struct FuncTypeImpl : ExternTypeImpl { ownvec params; ownvec results; FuncTypeImpl(ownvec& params, ownvec& results) : ExternTypeImpl(ExternKind::FUNC), - params(std::move(params)), results(std::move(results)) + params(std::move(params)), + results(std::move(results)) { stats.make(Stats::FUNCTYPE, this); } @@ -645,13 +631,14 @@ struct FuncTypeImpl : ExternTypeImpl { template<> struct implement { using type = FuncTypeImpl; }; -FuncType::~FuncType() {} +void FuncType::destroy() { + delete impl(this); +} auto FuncType::make(ownvec&& params, ownvec&& results) -> own { return params && results - ? own( - seal(new(std::nothrow) FuncTypeImpl(params, results))) + ? own(new(std::nothrow) FuncTypeImpl(params, results)) : own(); } @@ -670,26 +657,27 @@ auto FuncType::results() const -> const ownvec& { auto ExternType::func() -> FuncType* { return kind() == ExternKind::FUNC - ? seal(static_cast(impl(this))) + ? static_cast(this) : nullptr; } auto ExternType::func() const -> const FuncType* { return kind() == ExternKind::FUNC - ? seal(static_cast(impl(this))) + ? static_cast(this) : nullptr; } // Global Types -struct GlobalTypeImpl : ExternTypeImpl { +struct GlobalTypeImpl : ExternTypeImpl { own content; Mutability mutability; GlobalTypeImpl(own& content, Mutability mutability) : ExternTypeImpl(ExternKind::GLOBAL), - content(std::move(content)), mutability(mutability) + content(std::move(content)), + mutability(mutability) { stats.make(Stats::GLOBALTYPE, this); } @@ -702,14 +690,15 @@ struct GlobalTypeImpl : ExternTypeImpl { template<> struct implement { using type = GlobalTypeImpl; }; -GlobalType::~GlobalType() {} +void GlobalType::destroy() { + delete impl(this); +} auto GlobalType::make( own&& content, Mutability mutability ) -> own { return content - ? own( - seal(new(std::nothrow) GlobalTypeImpl(content, mutability))) + ? own(new(std::nothrow) GlobalTypeImpl(content, mutability)) : own(); } @@ -728,25 +717,27 @@ auto GlobalType::mutability() const -> Mutability { auto ExternType::global() -> GlobalType* { return kind() == ExternKind::GLOBAL - ? seal(static_cast(impl(this))) + ? static_cast(this) : nullptr; } auto ExternType::global() const -> const GlobalType* { return kind() == ExternKind::GLOBAL - ? seal(static_cast(impl(this))) + ? static_cast(this) : nullptr; } // Table Types -struct TableTypeImpl : ExternTypeImpl { +struct TableTypeImpl : ExternTypeImpl { own element; Limits limits; TableTypeImpl(own& element, Limits limits) : - ExternTypeImpl(ExternKind::TABLE), element(std::move(element)), limits(limits) + ExternTypeImpl(ExternKind::TABLE), + element(std::move(element)), + limits(limits) { stats.make(Stats::TABLETYPE, this); } @@ -759,12 +750,14 @@ struct TableTypeImpl : ExternTypeImpl { template<> struct implement { using type = TableTypeImpl; }; -TableType::~TableType() {} +void TableType::destroy() { + delete impl(this); +} auto TableType::make(own&& element, Limits limits) -> own { return element ? own( - seal(new(std::nothrow) TableTypeImpl(element, limits))) + new(std::nothrow) TableTypeImpl(element, limits)) : own(); } @@ -783,24 +776,25 @@ auto TableType::limits() const -> const Limits& { auto ExternType::table() -> TableType* { return kind() == ExternKind::TABLE - ? seal(static_cast(impl(this))) + ? static_cast(this) : nullptr; } auto ExternType::table() const -> const TableType* { return kind() == ExternKind::TABLE - ? seal(static_cast(impl(this))) + ? static_cast(this) : nullptr; } // Memory Types -struct MemoryTypeImpl : ExternTypeImpl { +struct MemoryTypeImpl : ExternTypeImpl { Limits limits; MemoryTypeImpl(Limits limits) : - ExternTypeImpl(ExternKind::MEMORY), limits(limits) + ExternTypeImpl(ExternKind::MEMORY), + limits(limits) { stats.make(Stats::MEMORYTYPE, this); } @@ -813,11 +807,12 @@ struct MemoryTypeImpl : ExternTypeImpl { template<> struct implement { using type = MemoryTypeImpl; }; -MemoryType::~MemoryType() {} +void MemoryType::destroy() { + delete impl(this); +} auto MemoryType::make(Limits limits) -> own { - return own( - seal(new(std::nothrow) MemoryTypeImpl(limits))); + return own(new(std::nothrow) MemoryTypeImpl(limits)); } auto MemoryType::copy() const -> own { @@ -831,20 +826,29 @@ auto MemoryType::limits() const -> const Limits& { auto ExternType::memory() -> MemoryType* { return kind() == ExternKind::MEMORY - ? seal(static_cast(impl(this))) + ? static_cast(this) : nullptr; } auto ExternType::memory() const -> const MemoryType* { return kind() == ExternKind::MEMORY - ? seal(static_cast(impl(this))) + ? static_cast(this) : nullptr; } +void ExternType::destroy() { + switch (kind()) { + case ExternKind::FUNC: delete static_cast(this); break; + case ExternKind::GLOBAL: delete static_cast(this); break; + case ExternKind::TABLE: delete static_cast(this); break; + case ExternKind::MEMORY: delete static_cast(this); break; + } +} + // Import Types -struct ImportTypeImpl { +struct ImportTypeImpl : ImportType { Name module; Name name; own type; @@ -863,20 +867,15 @@ struct ImportTypeImpl { template<> struct implement { using type = ImportTypeImpl; }; -ImportType::~ImportType() { - impl(this)->~ImportTypeImpl(); -} - -void ImportType::operator delete(void *p) { - ::operator delete(p); +void ImportType::destroy() { + delete impl(this); } auto ImportType::make( Name&& module, Name&& name, own&& type ) -> own { return module && name && type - ? own( - seal(new(std::nothrow) ImportTypeImpl(module, name, type))) + ? own(new(std::nothrow) ImportTypeImpl(module, name, type)) : own(); } @@ -899,7 +898,7 @@ auto ImportType::type() const -> const ExternType* { // Export Types -struct ExportTypeImpl { +struct ExportTypeImpl : ExportType { Name name; own type; @@ -917,20 +916,15 @@ struct ExportTypeImpl { template<> struct implement { using type = ExportTypeImpl; }; -ExportType::~ExportType() { - impl(this)->~ExportTypeImpl(); -} - -void ExportType::operator delete(void *p) { - ::operator delete(p); +void ExportType::destroy() { + delete impl(this); } auto ExportType::make( Name&& name, own&& type ) -> own { return name && type - ? own( - seal(new(std::nothrow) ExportTypeImpl(name, type))) + ? own(new(std::nothrow) ExportTypeImpl(name, type)) : own(); } @@ -1028,10 +1022,13 @@ auto memorytype_to_v8( // References template -class RefImpl : public v8::Persistent { -public: - RefImpl() = delete; - ~RefImpl() = delete; +struct RefImpl : Ref, v8::Persistent { + RefImpl() = default; + ~RefImpl() { + stats.free(Stats::categorize(*this), this); + v8::HandleScope handle_scope(this->isolate()); + this->store()->free_handle(this); + } static auto make(StoreImpl* store, v8::Local obj) -> own { static_assert(sizeof(RefImpl) == sizeof(v8::Persistent), @@ -1040,7 +1037,7 @@ class RefImpl : public v8::Persistent { if (!self) return nullptr; self->Reset(store->isolate(), obj); stats.make(Stats::categorize(*self), self); - return make_own(seal(self)); + return own(self); } auto copy() const -> own { @@ -1082,17 +1079,24 @@ class RefImpl : public v8::Persistent { } }; +static_assert(std::is_standard_layout>::value, + "incompatible object layout"); +static_assert(std::is_standard_layout>::value, + "incompatible object layout"); +static_assert(std::is_standard_layout>::value, + "incompatible object layout"); +static_assert(std::is_standard_layout>::value, + "incompatible object layout"); +static_assert(std::is_standard_layout>::value, + "incompatible object layout"); + template<> struct implement { using type = RefImpl; }; -Ref::~Ref() { - stats.free(Stats::categorize(*impl(this)), this); - v8::HandleScope handle_scope(impl(this)->isolate()); - impl(this)->store()->free_handle(impl(this)); +void Ref::destroy() { + impl(this)->~RefImpl(); } -void Ref::operator delete(void *p) {} - auto Ref::copy() const -> own { return impl(this)->copy(); } @@ -1173,7 +1177,7 @@ auto v8_to_val( // Frames -struct FrameImpl { +struct FrameImpl : Frame { FrameImpl( own&& instance, uint32_t func_index, size_t func_offset, size_t module_offset @@ -1197,19 +1201,15 @@ struct FrameImpl { template<> struct implement { using type = FrameImpl; }; -Frame::~Frame() { - impl(this)->~FrameImpl(); -} - -void Frame::operator delete(void *p) { - ::operator delete(p); +void Frame::destroy() { + delete impl(this); } auto Frame::copy() const -> own { auto self = impl(this); - return own(seal(new(std::nothrow) FrameImpl( + return own(new(std::nothrow) FrameImpl( self->instance->copy(), self->func_index, self->func_offset, - self->module_offset))); + self->module_offset)); } auto Frame::instance() const -> Instance* { @@ -1234,7 +1234,9 @@ auto Frame::module_offset() const -> size_t { template<> struct implement { using type = RefImpl; }; -Trap::~Trap() {} +void Trap::destroy() { + impl(this)->~RefImpl(); +} auto Trap::copy() const -> own { return impl(this)->copy(); @@ -1277,7 +1279,9 @@ auto Trap::trace() const -> ownvec { template<> struct implement { using type = RefImpl; }; -Foreign::~Foreign() {} +void Foreign::destroy() { + impl(this)->~RefImpl(); +} auto Foreign::copy() const -> own { return impl(this)->copy(); @@ -1298,7 +1302,9 @@ auto Foreign::make(Store* store_abs) -> own { template<> struct implement { using type = RefImpl; }; -Module::~Module() {} +void Module::destroy() { + impl(this)->~RefImpl(); +} auto Module::copy() const -> own { return impl(this)->copy(); @@ -1453,23 +1459,25 @@ auto Module::deserialize(Store* store_abs, const vec& serialized) -> own // TODO(v8): do better when V8 can do better. -template<> struct implement> { using type = vec; }; -template<> -Shared::~Shared() { - stats.free(Stats::MODULE, this, Stats::SHARED); - impl(this)->~vec(); -} +template +struct SharedImpl : Shared, vec { + void destroy() { + stats.free(categorize::value, this, Stats::SHARED); + delete this; + } +}; -template<> -void Shared::operator delete(void* p) { - ::operator delete(p); +template<> struct implement> { using type = SharedImpl; }; + +void Shared::destroy() { + impl(this)->destroy(); } auto Module::share() const -> own> { - auto shared = seal>(new vec(serialize())); + auto shared = static_cast*>(new vec(serialize())); stats.make(Stats::MODULE, shared, Stats::SHARED); - return make_own(shared); + return own>(shared); } auto Module::obtain(Store* store, const Shared* shared) -> own { @@ -1484,7 +1492,9 @@ auto Module::obtain(Store* store, const Shared* shared) -> own { template<> struct implement { using type = RefImpl; }; -Extern::~Extern() {} +void Extern::destroy() { + impl(this)->~RefImpl(); +} auto Extern::copy() const -> own { return impl(this)->copy(); @@ -1546,7 +1556,9 @@ auto extern_to_v8(const Extern* ex) -> v8::Local { template<> struct implement { using type = RefImpl; }; -Func::~Func() {} +void Func::destroy() { + impl(this)->~RefImpl(); +} auto Func::copy() const -> own { return impl(this)->copy(); @@ -1800,7 +1812,9 @@ void FuncData::finalize_func_data(void* data) { template<> struct implement { using type = RefImpl; }; -Global::~Global() {} +void Global::destroy() { + impl(this)->~RefImpl(); +} auto Global::copy() const -> own { return impl(this)->copy(); @@ -1886,7 +1900,9 @@ void Global::set(const Val& val) { template<> struct implement
{ using type = RefImpl
; }; -Table::~Table() {} +void Table::destroy() { + impl(this)->~RefImpl
(); +} auto Table::copy() const -> own
{ return impl(this)->copy(); @@ -1959,7 +1975,9 @@ auto Table::grow(size_t delta, const Ref* ref) -> bool { template<> struct implement { using type = RefImpl; }; -Memory::~Memory() {} +void Memory::destroy() { + impl(this)->~RefImpl(); +} auto Memory::copy() const -> own { return impl(this)->copy(); @@ -2013,7 +2031,9 @@ auto Memory::grow(pages_t delta) -> bool { template<> struct implement { using type = RefImpl; }; -Instance::~Instance() {} +void Instance::destroy() { + impl(this)->~RefImpl(); +} auto Instance::copy() const -> own { return impl(this)->copy();