Skip to content
Open
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
14 changes: 11 additions & 3 deletions include/wabt/binary-reader-logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,20 @@ class BinaryReaderLogging : public BinaryReaderDelegate {

Result BeginTypeSection(Offset size) override;
Result OnTypeCount(Index count) override;
Result OnRecursiveType(Index first_type_index, Index type_count) override;
Result OnFuncType(Index index,
Index param_count,
Type* param_types,
Index result_count,
Type* result_types) override;
Result OnStructType(Index index, Index field_count, TypeMut* fields) override;
Result OnArrayType(Index index, TypeMut field) override;
Type* result_types,
GCTypeExtension* gc_ext) override;
Result OnStructType(Index index,
Index field_count,
TypeMut* fields,
GCTypeExtension* gc_ext) override;
Result OnArrayType(Index index,
TypeMut field,
GCTypeExtension* gc_ext) override;
Result EndTypeSection() override;

Result BeginImportSection(Offset size) override;
Expand Down Expand Up @@ -432,6 +439,7 @@ class BinaryReaderLogging : public BinaryReaderDelegate {
void LogType(Type type);
void LogTypes(Index type_count, Type* types);
void LogTypes(TypeVector& types);
void LogGCInfo(GCTypeExtension* gc_ext);
void LogField(TypeMut field);

Stream* stream_;
Expand Down
15 changes: 12 additions & 3 deletions include/wabt/binary-reader-nop.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,29 @@ class BinaryReaderNop : public BinaryReaderDelegate {

/* Type section */
Result BeginTypeSection(Offset size) override { return Result::Ok; }
Result OnRecursiveType(Index first_type_index, Index type_count) override {
return Result::Ok;
}
Result OnTypeCount(Index count) override { return Result::Ok; }
Result OnFuncType(Index index,
Index param_count,
Type* param_types,
Index result_count,
Type* result_types) override {
Type* result_types,
GCTypeExtension* gc_ext) override {
return Result::Ok;
}
Result OnStructType(Index index,
Index field_count,
TypeMut* fields) override {
TypeMut* fields,
GCTypeExtension* gc_ext) override {
return Result::Ok;
}
Result OnArrayType(Index index,
TypeMut field,
GCTypeExtension* gc_ext) override {
return Result::Ok;
}
Result OnArrayType(Index index, TypeMut field) override { return Result::Ok; }
Result EndTypeSection() override { return Result::Ok; }

/* Import section */
Expand Down
20 changes: 16 additions & 4 deletions include/wabt/binary-reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,20 @@ struct ReadBinaryOptions {
bool skip_function_bodies = false;
};

// TODO: Move somewhere else?
// TODO: Move both TypeMut and GCTypeInformation somewhere else?
struct TypeMut {
Type type;
bool mutable_;
};
using TypeMutVector = std::vector<TypeMut>;

// Garbage Collector specific type information
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a core part of the patch. It contains the (sub ...) part of the type. It is declared as a structure, because it is not mandatory.

struct GCTypeExtension {
bool is_final_sub_type;
Index sub_type_count;
Index* sub_types;
};

struct CatchClause {
CatchKind kind;
Index tag;
Expand Down Expand Up @@ -104,15 +111,20 @@ class BinaryReaderDelegate {
/* Type section */
virtual Result BeginTypeSection(Offset size) = 0;
virtual Result OnTypeCount(Index count) = 0;
virtual Result OnRecursiveType(Index first_type_index, Index type_count) = 0;
virtual Result OnFuncType(Index index,
Index param_count,
Type* param_types,
Index result_count,
Type* result_types) = 0;
Type* result_types,
GCTypeExtension* gc_ext) = 0;
virtual Result OnStructType(Index index,
Index field_count,
TypeMut* fields) = 0;
virtual Result OnArrayType(Index index, TypeMut field) = 0;
TypeMut* fields,
GCTypeExtension* gc_ext) = 0;
virtual Result OnArrayType(Index index,
TypeMut field,
GCTypeExtension* gc_ext) = 0;
virtual Result EndTypeSection() = 0;

/* Import section */
Expand Down
25 changes: 24 additions & 1 deletion include/wabt/interp/interp-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,30 @@ inline bool FuncType::classof(const ExternType* type) {
}

inline FuncType::FuncType(ValueTypes params, ValueTypes results)
: ExternType(ExternKind::Func), params(params), results(results), func_types(nullptr) {}
: ExternType(ExternKind::Func),
kind(FuncType::TypeKind::Func),
canonical_index(kInvalidIndex),
canonical_sub_index(kInvalidIndex),
is_final_sub_type(true),
recursive_start(0),
recursive_count(0),
params(params),
results(results),
func_types(nullptr) {}

inline FuncType::FuncType(TypeKind kind, ValueTypes params, ValueTypes results)
: ExternType(ExternKind::Func),
kind(kind),
canonical_index(kInvalidIndex),
canonical_sub_index(kInvalidIndex),
is_final_sub_type(true),
recursive_start(0),
recursive_count(0),
params(params),
results(results),
func_types(nullptr) {
assert((kind == TypeKind::Struct || kind == TypeKind::Array) && params.size() == results.size());
}

//// TableType ////
// static
Expand Down
23 changes: 23 additions & 0 deletions include/wabt/interp/interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,14 +178,37 @@ struct FuncType : ExternType {
static const ExternKind skind = ExternKind::Func;
static bool classof(const ExternType* type);

enum class TypeKind {
Func,
Struct,
Array,
};

// To simplify the implementation, FuncType may also represent
// Struct and Array types. To do this, the mutability is stored
// in results, which must have the same size as params.
// This implementation might change in the future.
static const Type::Enum Mutable = Type::I32;
static const Type::Enum Immutable = Type::I64;

explicit FuncType(ValueTypes params, ValueTypes results);
explicit FuncType(TypeKind kind, ValueTypes params, ValueTypes results);

std::unique_ptr<ExternType> Clone() const override;

friend Result Match(const FuncType& expected,
const FuncType& actual,
std::string* out_msg);

TypeKind kind;
// These two are needed for fast dynamic type comparison.
Index canonical_index;
Index canonical_sub_index;
// These three are needed for type equality comparisons
// across different modules (import/export validation).
bool is_final_sub_type;
Index recursive_start;
Index recursive_count;
ValueTypes params;
ValueTypes results;
// When params or results contain references, the referenced
Expand Down
51 changes: 43 additions & 8 deletions include/wabt/ir.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,19 @@ enum class TypeEntryKind {
Array,
};

struct TypeEntryGCTypeExtension {
TypeEntryGCTypeExtension(bool is_final_sub_type)
: is_final_sub_type(is_final_sub_type) {}

void InitSubTypes(Index* sub_type_list, Index sub_type_count);

bool is_final_sub_type;
// The binary/text format allows any number of subtypes,
// so parsers must handle them. The validator rejects
// lists which size is greater than 1.
VarVector sub_types;
};

class TypeEntry {
public:
WABT_DISALLOW_COPY_AND_ASSIGN(TypeEntry);
Expand All @@ -307,12 +320,17 @@ class TypeEntry {

Location loc;
std::string name;
TypeEntryGCTypeExtension gc_ext;

protected:
explicit TypeEntry(TypeEntryKind kind,
bool is_final_sub_type,
std::string_view name = std::string_view(),
const Location& loc = Location())
: loc(loc), name(name), kind_(kind) {}
: loc(loc),
name(name),
gc_ext(is_final_sub_type),
kind_(kind) {}

TypeEntryKind kind_;
};
Expand All @@ -323,8 +341,8 @@ class FuncType : public TypeEntry {
return entry->kind() == TypeEntryKind::Func;
}

explicit FuncType(std::string_view name = std::string_view())
: TypeEntry(TypeEntryKind::Func, name) {}
explicit FuncType(bool is_final_sub_type, std::string_view name = std::string_view())
: TypeEntry(TypeEntryKind::Func, is_final_sub_type, name) {}

Index GetNumParams() const { return sig.GetNumParams(); }
Index GetNumResults() const { return sig.GetNumResults(); }
Expand Down Expand Up @@ -353,8 +371,8 @@ class StructType : public TypeEntry {
return entry->kind() == TypeEntryKind::Struct;
}

explicit StructType(std::string_view name = std::string_view())
: TypeEntry(TypeEntryKind::Struct) {}
explicit StructType(bool is_final_sub_type, std::string_view name = std::string_view())
: TypeEntry(TypeEntryKind::Struct, is_final_sub_type, name) {}

std::vector<Field> fields;
};
Expand All @@ -365,12 +383,19 @@ class ArrayType : public TypeEntry {
return entry->kind() == TypeEntryKind::Array;
}

explicit ArrayType(std::string_view name = std::string_view())
: TypeEntry(TypeEntryKind::Array) {}
explicit ArrayType(bool is_final_sub_type, std::string_view name = std::string_view())
: TypeEntry(TypeEntryKind::Array, is_final_sub_type, name) {}

Field field;
};

struct RecursiveRange {
Index first_type_index;
Index type_count;

Index EndTypeIndex() const { return first_type_index + type_count; }
};

struct FuncDeclaration {
Index GetNumParams() const { return sig.GetNumParams(); }
Index GetNumResults() const { return sig.GetNumResults(); }
Expand Down Expand Up @@ -1107,7 +1132,8 @@ enum class ModuleFieldType {
Memory,
DataSegment,
Start,
Tag
Tag,
EmptyRec
};

class ModuleField : public intrusive_list_base<ModuleField> {
Expand Down Expand Up @@ -1234,6 +1260,12 @@ class TagModuleField : public ModuleFieldMixin<ModuleFieldType::Tag> {
Tag tag;
};

class EmptyRecModuleField : public ModuleFieldMixin<ModuleFieldType::EmptyRec> {
public:
explicit EmptyRecModuleField(const Location& loc = Location())
: ModuleFieldMixin<ModuleFieldType::EmptyRec>(loc) {}
};

class StartModuleField : public ModuleFieldMixin<ModuleFieldType::Start> {
public:
explicit StartModuleField(Var start = Var(), const Location& loc = Location())
Expand Down Expand Up @@ -1293,6 +1325,7 @@ struct Module {
void AppendField(std::unique_ptr<ExportModuleField>);
void AppendField(std::unique_ptr<FuncModuleField>);
void AppendField(std::unique_ptr<TypeModuleField>);
void AppendField(std::unique_ptr<EmptyRecModuleField>);
void AppendField(std::unique_ptr<GlobalModuleField>);
void AppendField(std::unique_ptr<ImportModuleField>);
void AppendField(std::unique_ptr<MemoryModuleField>);
Expand All @@ -1319,6 +1352,8 @@ struct Module {
std::vector<Import*> imports;
std::vector<Export*> exports;
std::vector<TypeEntry*> types;
// Ordered list of recursive ranges.
std::vector<RecursiveRange> recursive_ranges;
std::vector<Table*> tables;
std::vector<ElemSegment*> elem_segments;
std::vector<Memory*> memories;
Expand Down
Loading
Loading