diff --git a/example/reflect.cc b/example/reflect.cc index f71c359..a700805 100644 --- a/example/reflect.cc +++ b/example/reflect.cc @@ -60,6 +60,9 @@ auto operator<<(std::ostream& out, const wasm::ExternType& type) -> std::ostream case wasm::ExternKind::MEMORY: { out << "memory " << type.memory()->limits(); } break; + case wasm::ExternKind::TAG: { + out << "tag " << type.tag()->functype()->params(); + } break; } return out; } diff --git a/include/wasm.h b/include/wasm.h index b7f227a..41f7fa3 100644 --- a/include/wasm.h +++ b/include/wasm.h @@ -247,6 +247,15 @@ WASM_API_EXTERN own wasm_memorytype_t* wasm_memorytype_new(const wasm_limits_t*) WASM_API_EXTERN const wasm_limits_t* wasm_memorytype_limits(const wasm_memorytype_t*); +// Tag Types + +WASM_DECLARE_TYPE(tagtype) + +WASM_API_EXTERN own wasm_tagtype_t* wasm_tagtype_new(own wasm_functype_t*); + +WASM_API_EXTERN const wasm_functype_t* wasm_tagtype_functype(const wasm_tagtype_t*); + + // Extern Types WASM_DECLARE_TYPE(externtype) @@ -257,6 +266,7 @@ enum wasm_externkind_enum { WASM_EXTERN_GLOBAL, WASM_EXTERN_TABLE, WASM_EXTERN_MEMORY, + WASM_EXTERN_TAG, }; WASM_API_EXTERN wasm_externkind_t wasm_externtype_kind(const wasm_externtype_t*); @@ -265,21 +275,25 @@ WASM_API_EXTERN wasm_externtype_t* wasm_functype_as_externtype(wasm_functype_t*) WASM_API_EXTERN wasm_externtype_t* wasm_globaltype_as_externtype(wasm_globaltype_t*); WASM_API_EXTERN wasm_externtype_t* wasm_tabletype_as_externtype(wasm_tabletype_t*); WASM_API_EXTERN wasm_externtype_t* wasm_memorytype_as_externtype(wasm_memorytype_t*); +WASM_API_EXTERN wasm_externtype_t* wasm_tagtype_as_externtype(wasm_tagtype_t*); WASM_API_EXTERN wasm_functype_t* wasm_externtype_as_functype(wasm_externtype_t*); WASM_API_EXTERN wasm_globaltype_t* wasm_externtype_as_globaltype(wasm_externtype_t*); WASM_API_EXTERN wasm_tabletype_t* wasm_externtype_as_tabletype(wasm_externtype_t*); WASM_API_EXTERN wasm_memorytype_t* wasm_externtype_as_memorytype(wasm_externtype_t*); +WASM_API_EXTERN wasm_tagtype_t* wasm_externtype_as_tagtype(wasm_externtype_t*); WASM_API_EXTERN const wasm_externtype_t* wasm_functype_as_externtype_const(const wasm_functype_t*); WASM_API_EXTERN const wasm_externtype_t* wasm_globaltype_as_externtype_const(const wasm_globaltype_t*); WASM_API_EXTERN const wasm_externtype_t* wasm_tabletype_as_externtype_const(const wasm_tabletype_t*); WASM_API_EXTERN const wasm_externtype_t* wasm_memorytype_as_externtype_const(const wasm_memorytype_t*); +WASM_API_EXTERN const wasm_externtype_t* wasm_tagtype_as_externtype_const(const wasm_tagtype_t*); WASM_API_EXTERN const wasm_functype_t* wasm_externtype_as_functype_const(const wasm_externtype_t*); WASM_API_EXTERN const wasm_globaltype_t* wasm_externtype_as_globaltype_const(const wasm_externtype_t*); WASM_API_EXTERN const wasm_tabletype_t* wasm_externtype_as_tabletype_const(const wasm_externtype_t*); WASM_API_EXTERN const wasm_memorytype_t* wasm_externtype_as_memorytype_const(const wasm_externtype_t*); +WASM_API_EXTERN const wasm_tagtype_t* wasm_externtype_as_tagtype_const(const wasm_externtype_t*); // Import Types diff --git a/include/wasm.hh b/include/wasm.hh index c98a1f4..047c6cf 100644 --- a/include/wasm.hh +++ b/include/wasm.hh @@ -294,13 +294,14 @@ public: // External Types enum class ExternKind : uint8_t { - FUNC, GLOBAL, TABLE, MEMORY + FUNC, GLOBAL, TABLE, MEMORY, TAG }; class FuncType; class GlobalType; class TableType; class MemoryType; +class TagType; class WASM_API_EXTERN ExternType { friend class destroyer; @@ -319,11 +320,13 @@ public: auto global() -> GlobalType*; auto table() -> TableType*; auto memory() -> MemoryType*; + auto tag() -> TagType*; auto func() const -> const FuncType*; auto global() const -> const GlobalType*; auto table() const -> const TableType*; auto memory() const -> const MemoryType*; + auto tag() const -> const TagType*; }; @@ -406,6 +409,24 @@ public: }; +// Tag Types + +class WASM_API_EXTERN TagType : public ExternType { + friend class destroyer; + void destroy(); + +protected: + TagType() = default; + ~TagType() = default; + +public: + static auto make(own&&) -> own; + auto copy() const -> own; + + auto functype() const -> const FuncType*; +}; + + // Import Types using Name = vec; diff --git a/src/wasm-v8.cc b/src/wasm-v8.cc index e7246b1..ca7703c 100644 --- a/src/wasm-v8.cc +++ b/src/wasm-v8.cc @@ -590,6 +590,7 @@ auto ExternType::copy() const -> own { case ExternKind::GLOBAL: return global()->copy(); case ExternKind::TABLE: return table()->copy(); case ExternKind::MEMORY: return memory()->copy(); + case ExternKind::TAG: return tag()->copy(); } } @@ -809,6 +810,36 @@ auto MemoryType::limits() const -> const Limits& { } +// Tag Types + +struct TagTypeImpl : ExternTypeImpl { + own functype; + + explicit TagTypeImpl(own&& functype_) : + ExternTypeImpl(ExternKind::TAG), + functype(std::move(functype_)) + {} +}; + +template<> struct implement { using type = TagTypeImpl; }; + +void TagType::destroy() { + delete impl(this); +} + +auto TagType::make(own&& functype) -> own { + return own(new(std::nothrow) TagTypeImpl(std::move(functype))); +} + +auto TagType::copy() const -> own { + return TagType::make(impl(this)->functype->copy()); +} + +auto TagType::functype() const -> const FuncType* { + return impl(this)->functype.get(); +} + + auto ExternType::memory() -> MemoryType* { return kind() == ExternKind::MEMORY ? static_cast(this) @@ -821,12 +852,25 @@ auto ExternType::memory() const -> const MemoryType* { : nullptr; } +auto ExternType::tag() -> TagType* { + return kind() == ExternKind::TAG + ? static_cast(this) + : nullptr; +} + +auto ExternType::tag() const -> const TagType* { + return kind() == ExternKind::TAG + ? 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; + case ExternKind::TAG: delete static_cast(this); break; } } @@ -1499,6 +1543,7 @@ auto Extern::type() const -> own { case ExternKind::GLOBAL: return global()->type(); case ExternKind::TABLE: return table()->type(); case ExternKind::MEMORY: return memory()->type(); + case ExternKind::TAG: return nullptr; } } @@ -2134,6 +2179,9 @@ auto Instance::exports() const -> ownvec { assert(wasm_v8::extern_kind(obj) == wasm_v8::EXTERN_MEMORY); exports[i] = RefImpl::make(store, obj); } break; + case ExternKind::TAG: { + // Tags are not yet supported as first-class externs in the V8 backend. + } break; } }