Skip to content

Add new compound Rtt type #3076

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Aug 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 96 additions & 24 deletions src/wasm-type.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,6 @@

namespace wasm {

struct Tuple;
struct Signature;
struct Struct;
struct Array;

typedef std::vector<class Type> TypeList;

class Type {
// The `id` uniquely represents each type, so type equality is just a
// comparison of the ids. For basic types the `id` is just the `BasicID`
Expand Down Expand Up @@ -73,16 +66,14 @@ class Type {
Type(std::initializer_list<Type>);

// Construct from tuple description
explicit Type(const Tuple&);

// Construct from signature description
explicit Type(const Signature, bool nullable);
explicit Type(const struct Tuple&);

// Construct from struct description
explicit Type(const Struct&, bool nullable);
// Construct from a heap type description. Also covers construction from
// Signature, Struct or Array via implicit conversion to HeapType.
explicit Type(const struct HeapType&, bool nullable);

// Construct from array description
explicit Type(const Array&, bool nullable);
// Construct from rtt description
explicit Type(const struct Rtt&);

// Predicates
// Compound Concrete
Expand All @@ -96,16 +87,18 @@ class Type {
// │ f32 ║ x │ │ x │ x │ F │ │ F_loat
// │ f64 ║ x │ │ x │ x │ F │ │ V_ector
// │ v128 ║ x │ │ x │ x │ V │ ┘
// ├─────────────╫───┼───┼───┼───┤───────┤
// │ funcref ║ x │ │ x │ x │ f │ ┐ Ref
// │ externref ║ x │ │ x │ x │ │ │ f_unc
// │ nullref ║ x │ │ x │ x │ │ │
// │ exnref ║ x │ │ x │ x │ │ │
// ├─────────────╫───┼───┼───┼───┤───────┤ │
// │ Signature ║ │ x │ x │ x │ f │ │
// │ Struct ║ │ x │ x │ x │ │ │
// │ Array ║ │ x │ x │ x │ │ ┘
// ├─ Aliases ───╫───┼───┼───┼───┤───────┤
// │ funcref ║ x │ │ x │ x │ f n │ ┐ Ref
// │ externref ║ x │ │ x │ x │ f? n │ │ f_unc, n_ullable
// │ anyref ║ x │ │ x │ x │ f? n │ │ ┐
// │ eqref ║ x │ │ x │ x │ n │ │ │ TODO (GC)
// │ i31ref ║ x │ │ x │ x │ │ │ ┘
// │ nullref ║ x │ │ x │ x │ f? n │ │ ◄ TODO (removed)
// │ exnref ║ x │ │ x │ x │ n │ │
// ├─ Compound ──╫───┼───┼───┼───┤───────┤ │
// │ Ref ║ │ x │ x │ x │ f? n? │◄┘
// │ Tuple ║ │ x │ │ x │ │
// │ Rtt ║ │ x │ x │ x │ │
// └─────────────╨───┴───┴───┴───┴───────┘
constexpr bool isBasic() const { return id <= _last_basic_id; }
constexpr bool isCompound() const { return id > _last_basic_id; }
Expand All @@ -118,6 +111,7 @@ class Type {
bool isSingle() const { return isConcrete() && !isTuple(); }
bool isRef() const;
bool isNullable() const;
bool isRtt() const;

private:
template<bool (Type::*pred)() const> bool hasPredicate() {
Expand Down Expand Up @@ -227,6 +221,8 @@ struct ResultType {
std::string toString() const;
};

typedef std::vector<Type> TypeList;

struct Tuple {
TypeList types;
Tuple() : types() {}
Expand Down Expand Up @@ -303,6 +299,72 @@ struct Array {
std::string toString() const;
};

struct HeapType {
enum Kind {
FuncKind,
ExternKind,
AnyKind,
EqKind,
I31Kind,
ExnKind,
_last_basic_kind = ExnKind,
SignatureKind,
StructKind,
ArrayKind,
} kind;
union {
Signature signature;
Struct struct_;
Array array;
};
HeapType(Kind kind) : kind(kind) { assert(kind <= _last_basic_kind); }
HeapType(const Signature& signature)
: kind(SignatureKind), signature(signature) {}
HeapType(Signature&& signature)
: kind(SignatureKind), signature(std::move(signature)) {}
HeapType(const Struct& struct_) : kind(StructKind), struct_(struct_) {}
HeapType(Struct&& struct_) : kind(StructKind), struct_(std::move(struct_)) {}
HeapType(const Array& array) : kind(ArrayKind), array(array) {}
HeapType(Array&& array) : kind(ArrayKind), array(std::move(array)) {}
HeapType(const HeapType& other);
~HeapType();

bool isSignature() const { return kind == SignatureKind; }
Signature getSignature() const {
assert(isSignature() && "Not a signature");
return signature;
}
bool isStruct() const { return kind == StructKind; }
Struct getStruct() const {
assert(isStruct() && "Not a struct");
return struct_;
}
bool isArray() const { return kind == ArrayKind; }
Array getArray() const {
assert(isArray() && "Not an array");
return array;
}

bool operator==(const HeapType& other) const;
bool operator!=(const HeapType& other) const { return !(*this == other); }
HeapType& operator=(const HeapType& other);
std::string toString() const;
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to move the less trivial methods into the .cpp file. I'm thinking roughly anything with a switch in it. My goal there would be consistency with where the TypeInfo methods are placed.


struct Rtt {
uint32_t depth;
HeapType heapType;
Rtt(uint32_t depth, const HeapType& heapType)
: depth(depth), heapType(heapType) {}
Rtt(uint32_t depth, HeapType&& heapType)
: depth(depth), heapType(std::move(heapType)) {}
bool operator==(const Rtt& other) const {
return depth == other.depth && heapType == other.heapType;
}
bool operator!=(const Rtt& other) const { return !(*this == other); }
std::string toString() const;
};

std::ostream& operator<<(std::ostream&, Type);
std::ostream& operator<<(std::ostream&, ParamType);
std::ostream& operator<<(std::ostream&, ResultType);
Expand All @@ -311,6 +373,8 @@ std::ostream& operator<<(std::ostream&, Signature);
std::ostream& operator<<(std::ostream&, Field);
std::ostream& operator<<(std::ostream&, Struct);
std::ostream& operator<<(std::ostream&, Array);
std::ostream& operator<<(std::ostream&, HeapType);
std::ostream& operator<<(std::ostream&, Rtt);

} // namespace wasm

Expand Down Expand Up @@ -340,6 +404,14 @@ template<> class hash<wasm::Array> {
public:
size_t operator()(const wasm::Array&) const;
};
template<> class hash<wasm::HeapType> {
public:
size_t operator()(const wasm::HeapType&) const;
};
template<> class hash<wasm::Rtt> {
public:
size_t operator()(const wasm::Rtt&) const;
};

} // namespace std

Expand Down
Loading