LibWasm: Properly read and validate limits for I64 memories and tables

Since memory64 got merged into the spec the minimum value for limits
is now actualy 64-bit and the maximum sizes for memories and tables
for I64 address types were increased.

Fixes 5 tests in memory64.wast nad 8 tests in table64.wast on WPT.
This commit is contained in:
Undefine 2025-10-19 16:38:49 +02:00 committed by Ali Mohammad Pur
parent 692195ae88
commit 07c86542b6
3 changed files with 12 additions and 8 deletions

View File

@ -277,12 +277,14 @@ ErrorOr<void, ValidationError> Validator::validate(CodeSection const& section)
ErrorOr<void, ValidationError> Validator::validate(TableType const& type)
{
return validate(type.limits(), (1ull << 32) - 1);
Optional<u64> bound = type.limits().address_type() == AddressType::I64 ? Optional<u64> {} : (1ull << 32) - 1;
return validate(type.limits(), bound);
}
ErrorOr<void, ValidationError> Validator::validate(MemoryType const& type)
{
return validate(type.limits(), 1 << 16);
u64 bound = type.limits().address_type() == AddressType::I64 ? 1ull << 48 : 1ull << 16;
return validate(type.limits(), bound);
}
ErrorOr<void, ValidationError> Validator::validate(Wasm::TagType const& tag_type)
@ -315,10 +317,12 @@ ErrorOr<FunctionType, ValidationError> Validator::validate(BlockType const& type
return Errors::invalid("BlockType"sv);
}
ErrorOr<void, ValidationError> Validator::validate(Limits const& limits, u64 bound)
ErrorOr<void, ValidationError> Validator::validate(Limits const& limits, Optional<u64> bound)
{
auto check_bound = [bound](auto value) {
return static_cast<u64>(value) <= bound;
if (!bound.has_value())
return true;
return static_cast<u64>(value) <= bound.value();
};
if (!check_bound(limits.min()))

View File

@ -296,7 +296,7 @@ public:
ErrorOr<void, ValidationError> validate_instruction(Instruction const&, Stack& stack, bool& is_constant);
// Types
ErrorOr<void, ValidationError> validate(Limits const&, u64 bound); // n <= bound && m? <= bound
ErrorOr<void, ValidationError> validate(Limits const&, Optional<u64> bound); // n <= bound && m? <= bound
ErrorOr<FunctionType, ValidationError> validate(BlockType const&);
ErrorOr<void, ValidationError> validate(FunctionType const&) { return {}; }
ErrorOr<void, ValidationError> validate(TableType const&);

View File

@ -173,10 +173,10 @@ ParseResult<Limits> Limits::parse(ConstrainedStream& stream)
auto address_type = (flag & 0b00000100) ? AddressType::I64 : AddressType::I32;
auto min_or_error = stream.read_value<LEB128<u32>>();
auto min_or_error = stream.read_value<LEB128<u64>>();
if (min_or_error.is_error())
return with_eof_check(stream, ParseError::ExpectedSize);
size_t min = min_or_error.release_value();
u64 min = min_or_error.release_value();
Optional<u64> max;
if (flag & 1) {
@ -186,7 +186,7 @@ ParseResult<Limits> Limits::parse(ConstrainedStream& stream)
max = value_or_error.release_value();
}
return Limits { address_type, static_cast<u64>(min), move(max) };
return Limits { address_type, min, move(max) };
}
ParseResult<MemoryType> MemoryType::parse(ConstrainedStream& stream)