LibWasm: Parse and validate array types

This patch makes this parse
```wat
(module
  (type $a (array i32))
)
```
This commit is contained in:
Marcus Nilsson 2026-02-08 19:09:18 +01:00 committed by Ali Mohammad Pur
parent 27a66c33c5
commit 21c827e8af
7 changed files with 59 additions and 5 deletions

View file

@ -43,6 +43,9 @@ ErrorOr<void, ValidationError> Validator::validate(Module& module)
},
[&](StructType const& struct_) {
m_context.structs.append(struct_);
},
[&](ArrayType const& array) {
m_context.arrays.append(array);
});
} else {
return Errors::invalid("TypeIndex"sv);
@ -362,8 +365,9 @@ ErrorOr<void, ValidationError> Validator::validate(ValueType const& type)
ErrorOr<void, ValidationError> Validator::validate(TypeSection::Type const& type)
{
return type.description().visit(
[&](FunctionType const& function) -> ErrorOr<void, ValidationError> { return validate(function); },
[&](StructType const& struct_) -> ErrorOr<void, ValidationError> { return validate(struct_); });
[&](FunctionType const& function) { return validate(function); },
[&](StructType const& struct_) { return validate(struct_); },
[&](ArrayType const& array) { return validate(array); });
}
ErrorOr<void, ValidationError> Validator::validate(FunctionType const& type)
@ -388,6 +392,11 @@ ErrorOr<void, ValidationError> Validator::validate(StructType const& type)
return {};
}
ErrorOr<void, ValidationError> Validator::validate(ArrayType const& array)
{
return validate(array.type().type());
}
ErrorOr<void, ValidationError> Validator::validate(GlobalType const& type)
{
return validate(type.type());

View file

@ -25,6 +25,7 @@ struct Context {
COWVector<TypeSection::Type> types;
COWVector<FunctionType> functions;
COWVector<StructType> structs;
COWVector<ArrayType> arrays;
COWVector<TableType> tables;
COWVector<MemoryType> memories;
COWVector<GlobalType> globals;
@ -304,6 +305,7 @@ public:
ErrorOr<FunctionType, ValidationError> validate(BlockType const&);
ErrorOr<void, ValidationError> validate(FunctionType const&);
ErrorOr<void, ValidationError> validate(StructType const&);
ErrorOr<void, ValidationError> validate(ArrayType const&);
ErrorOr<void, ValidationError> validate(TableType const&);
ErrorOr<void, ValidationError> validate(MemoryType const&);
ErrorOr<void, ValidationError> validate(GlobalType const&);

View file

@ -35,6 +35,7 @@ static constexpr auto non_nullable_reference_tag_tag = 0x64;
// Composite
static constexpr auto struct_tag = 0x5f;
static constexpr auto array_tag = 0x5e;
// Function
static constexpr auto function_signature_tag = 0x60;

View file

@ -198,6 +198,15 @@ ParseResult<StructType> StructType::parse(ConstrainedStream& stream)
return StructType { fields };
}
ParseResult<ArrayType> ArrayType::parse(ConstrainedStream& stream)
{
ScopeLogger<WASM_BINPARSER_DEBUG> logger("ArrayType"sv);
auto type = TRY(FieldType::parse(stream));
return ArrayType { type };
}
ParseResult<Limits> Limits::parse(ConstrainedStream& stream)
{
ScopeLogger<WASM_BINPARSER_DEBUG> logger("Limits"sv);
@ -1026,6 +1035,8 @@ ParseResult<TypeSection::Type> TypeSection::Type::parse(ConstrainedStream& strea
return Type { TRY(FunctionType::parse(stream)) };
case Constants::struct_tag:
return Type { TRY(StructType::parse(stream)) };
case Constants::array_tag:
return Type { TRY(ArrayType::parse(stream)) };
default:
return ParseError::InvalidTag;
}

View file

@ -732,7 +732,8 @@ void Printer::print(Wasm::TypeSection::Type const& type)
{
type.description().visit(
[&](Wasm::FunctionType const& func) { print(func); },
[&](Wasm::StructType const& struct_) { print(struct_); });
[&](Wasm::StructType const& struct_) { print(struct_); },
[&](Wasm::ArrayType const& array) { print(array); });
}
void Printer::print(Wasm::StructType const& struct_)
@ -755,6 +756,18 @@ void Printer::print(Wasm::StructType const& struct_)
print(")\n");
}
void Printer::print(Wasm::ArrayType const& array)
{
print_indent();
print("(type array \n");
{
TemporaryChange change { m_indent, m_indent + 1 };
print(array.type());
}
print_indent();
print(")\n");
}
void Printer::print(Wasm::FieldType const& type)
{
print_indent();

View file

@ -61,6 +61,7 @@ struct WASM_API Printer {
void print(Wasm::TypeSection const&);
void print(Wasm::TypeSection::Type const&);
void print(Wasm::StructType const&);
void print(Wasm::ArrayType const&);
void print(Wasm::FieldType const&);
void print(Wasm::ValueType const&);
void print(Wasm::TagType const&);

View file

@ -303,6 +303,22 @@ private:
Vector<FieldType> m_fields;
};
// https://webassembly.github.io/spec/core/bikeshed/#composite-types%E2%91%A0
class ArrayType {
public:
ArrayType(FieldType type)
: m_type(type)
{
}
auto& type() const { return m_type; }
static ParseResult<ArrayType> parse(ConstrainedStream& stream);
private:
FieldType m_type;
};
// https://webassembly.github.io/memory64/core/bikeshed/#address-type%E2%91%A0
enum class AddressType : u8 {
I32,
@ -805,7 +821,7 @@ class TypeSection {
public:
class Type {
private:
using TypeDesc = Variant<FunctionType, StructType>;
using TypeDesc = Variant<FunctionType, StructType, ArrayType>;
public:
Type(TypeDesc type)
@ -826,7 +842,8 @@ public:
{
return m_description.visit(
[](FunctionType const&) -> ByteString { return "function type"; },
[](StructType const&) -> ByteString { return "struct type"; });
[](StructType const&) -> ByteString { return "struct type"; },
[](ArrayType const&) -> ByteString { return "array type"; });
}
static ParseResult<Type> parse(ConstrainedStream& stream);