LibWasm: Remove all gc, function-refs and EH test exceptions

This commit is contained in:
Ali Mohammad Pur 2026-06-11 09:06:47 +02:00 committed by Ali Mohammad Pur
parent 8a74f52571
commit 530c95fde5
4 changed files with 38 additions and 221 deletions

View file

@ -147,6 +147,8 @@ ErrorOr<void, ValidationError> Validator::validate(Module& module)
}
for (auto& segment : module.global_section().entries())
scan_expression_for_function_indices(segment.expression());
for (auto& table : module.table_section().tables())
scan_expression_for_function_indices(table.initializer());
TRY(validate(module.import_section()));
TRY(validate(module.export_section()));
@ -328,6 +330,9 @@ ErrorOr<void, ValidationError> Validator::validate(DataSection const& section)
ErrorOr<void, ValidationError> Validator::validate(ElementSection const& section)
{
for (auto& segment : section.segments()) {
// https://webassembly.github.io/spec/core/valid/modules.html#element-segments
// - The reference type elemtype is valid.
TRY(validate(segment.type));
TRY(segment.mode.visit(
[](ElementSection::Declarative const&) -> ErrorOr<void, ValidationError> { return {}; },
[](ElementSection::Passive const&) -> ErrorOr<void, ValidationError> { return {}; },
@ -419,6 +424,9 @@ ErrorOr<void, ValidationError> Validator::validate(CodeSection const& section)
function_validator.m_context.locals.extend(function_type.parameters());
function_validator.m_context.current_function_parameter_count = function_type.parameters().size();
for (auto& local : function.locals()) {
// https://webassembly.github.io/spec/core/valid/modules.html#functions
// The locals' value types must be valid (in particular, type uses must exist).
TRY(function_validator.validate(local.type()));
for (size_t i = 0; i < local.n(); ++i)
function_validator.m_context.locals.append(local.type());
}
@ -1629,14 +1637,15 @@ VALIDATE_INSTRUCTION(select_typed)
if (required_types.size() != 1)
return Errors::invalid("select types"sv, "exactly one type"sv, required_types);
// https://webassembly.github.io/spec/core/valid/instructions.html#parametric-instructions
// select t: valid with [t t i32] -> [t] if the value type t is valid; both operands must
// match the annotated type.
TRY(validate(required_types.first()));
TRY(stack.take<ValueType::I32>());
auto arg0_type = TRY(stack.take_last());
auto arg1_type = TRY(stack.take_last());
TRY(stack.take(required_types.first()));
TRY(stack.take(required_types.first()));
if (arg0_type != arg1_type || arg0_type != required_types.first())
return Errors::invalid("select argument types"sv, Vector { required_types.first(), required_types.first() }, Vector { arg0_type, arg1_type });
stack.append(arg0_type.is_known ? arg0_type : arg1_type);
stack.append(required_types.first());
return {};
}
@ -1772,12 +1781,11 @@ VALIDATE_INSTRUCTION(table_copy)
auto lhs_table = TRY(validate(args.lhs));
auto rhs_table = TRY(validate(args.rhs));
if (lhs_table.element_type() != rhs_table.element_type())
// https://webassembly.github.io/spec/core/valid/instructions.html#table-instructions
// table.copy x y: the source table's reference type rt2 must match the destination's rt1.
if (!matches_reference_type(rhs_table.element_type(), lhs_table.element_type(), m_context.type_context()))
return Errors::non_conforming_types("table.copy"sv, lhs_table.element_type(), rhs_table.element_type());
if (!lhs_table.element_type().is_reference())
return Errors::invalid("table.copy element type"sv, "a reference type"sv, lhs_table.element_type());
auto const lhs_at = lhs_table.limits().address_value_type();
auto const rhs_at = rhs_table.limits().address_value_type();
auto const size_type = ValueType(lhs_at.kind() == ValueType::I32 || rhs_at.kind() == ValueType::I32 ? ValueType::I32 : ValueType::I64);
@ -1798,7 +1806,10 @@ VALIDATE_INSTRUCTION(table_init)
auto& element_type = m_context.elements[args.element_index.value()];
if (table.element_type() != element_type)
// https://webassembly.github.io/spec/core/valid/instructions.html#table-instructions
// table.init x y: "The element segment C.elems[y] must match the reference type rt" of the
// table C.tables[x].
if (!matches_reference_type(element_type, table.element_type(), m_context.type_context()))
return Errors::non_conforming_types("table.init"sv, table.element_type(), element_type);
TRY((stack.take<ValueType::I32, ValueType::I32>()));
@ -2662,7 +2673,10 @@ VALIDATE_INSTRUCTION(call_indirect)
auto table = TRY(validate(args.table));
TRY(validate(args.type));
if (table.element_type().kind() != ValueType::FunctionReference)
// https://webassembly.github.io/spec/core/valid/instructions.html#control-instructions
// call_indirect x y: "The table C.tables[x] must be of the form (at lim rt), and rt must
// match (ref null func)."
if (!matches_reference_type(table.element_type(), ValueType(ValueType::FunctionReference), m_context.type_context()))
return Errors::invalid("table element type for call.indirect"sv, "a function reference"sv, table.element_type());
auto& type = m_context.types[args.type.value()];
@ -2708,7 +2722,8 @@ VALIDATE_INSTRUCTION(return_call_indirect)
TRY(validate(args.type));
auto& table = m_context.tables[args.table.value()];
if (table.element_type().kind() != ValueType::FunctionReference)
// See call_indirect: rt must match (ref null func).
if (!matches_reference_type(table.element_type(), ValueType(ValueType::FunctionReference), m_context.type_context()))
return Errors::invalid("table element type for call.indirect"sv, "a function reference"sv, table.element_type());
auto& type = m_context.types[args.type.value()];

View file

@ -1571,7 +1571,11 @@ ParseResult<ElementSection::Element> ElementSection::Element::parse(ConstrainedS
mode = Active { table_index, move(expression) };
}
auto type = ValueType(ValueType::FunctionReference);
// https://webassembly.github.io/spec/core/binary/modules.html#element-section
// elemkind ::= 0x00 => (ref func)
// Segments listing function indices have the non-nullable type (ref func) (flags 0-3);
// the flag-4 expression shorthand has type funcref, i.e. (ref null func).
auto type = has_exprs ? ValueType(ValueType::FunctionReference) : ValueType(ValueType::FunctionReference, false);
if (has_passive || has_explicit_index) {
if (has_exprs) {
type = TRY(ValueType::parse(stream));
@ -1582,7 +1586,7 @@ ParseResult<ElementSection::Element> ElementSection::Element::parse(ConstrainedS
if (extern_ != 0x00) {
return ParseError::InvalidType;
}
type = ValueType(ValueType::FunctionReference);
type = ValueType(ValueType::FunctionReference, false);
}
}

View file

@ -1,208 +1,2 @@
module array.0
module array.12
module array.2
module array.5
module array.6
module array.7
module array.8
module array_copy.4
module array_fill.3
module array_init_data.2
module array_init_data.3
module array_init_elem.3
module array_new_data.0
module array_new_data.1
module array_new_data.2
module array_new_data.3
module array_new_data.4
module array_new_elem.0
module array_new_elem.1
module array_new_elem.2
module array_new_elem.3
module br_on_cast.0
module br_on_cast.1
module br_on_cast.2
module br_on_cast_fail.0
module br_on_cast_fail.1
module br_on_cast_fail.2
module br_on_non_null.0
module br_on_non_null.1
module br_on_non_null.2
module br_on_null.0
module br_on_null.1
module br_on_null.2
module br_table.0
module call_ref.0
module call_ref.1
module call_ref.2
module call_ref.3
module elem.2
module elem.31
module elem.47
module elem.48
module elem.49
module elem.50
module elem.51
module elem.52
module elem.53
module elem.54
module elem.57
module elem.58
module elem.59
module elem.60
module elem.61
module elem.62
module extern.0
module func.21
module global.50
module i31.0
module i31.1
module i31.3
module i31.4
module i31.5
module i31.6
module instance.0
module instance.1
module instance.2
module instance.3
module instance.4
module linking.10
module linking.9
module local_init.0
module local_init.1
module local_init.2
module local_init.4
module local_init.5
module ref.1
module ref.12
module ref.2
module ref.4
module ref.5
module ref.6
module ref.8
module ref_as_non_null.0
module ref_as_non_null.2
module ref_cast.0
module ref_cast.1
module ref_eq.0
module ref_is_null.0
module ref_null.0
module ref_null.1
module ref_test.0
module ref_test.1
module relaxed_dot_product.0
module relaxed_madd_nmadd.0
module return_call_ref.0
module return_call_ref.1
module return_call_ref.10
module return_call_ref.8
module return_call_ref.9
module select.0
module struct.0
module struct.10
module struct.2
module struct.5
module struct.7
module struct.9
module table-sub.0
module table.13
module table.14
module table.15
module table.29
module table.30
module table.31
module table.32
module table.33
module table.34
module table.35
module table.36
module table64.11
module tag.2
module tag.4
module tag.5
module throw.0
module throw_ref.0
module try_table.1
module try_table.13
module try_table.2
module try_table.5
module type-canon.0
module type-canon.1
module type-equivalence.0
module type-equivalence.1
module type-equivalence.13
module type-equivalence.14
module type-equivalence.15
module type-equivalence.16
module type-equivalence.17
module type-equivalence.18
module type-equivalence.19
module type-equivalence.2
module type-equivalence.20
module type-equivalence.21
module type-equivalence.3
module type-equivalence.4
module type-equivalence.5
module type-equivalence.7
module type-equivalence.8
module type-equivalence.9
module type-rec.0
module type-rec.1
module type-rec.13
module type-rec.14
module type-rec.17
module type-rec.18
module type-rec.19
module type-rec.20
module type-rec.3
module type-rec.4
module type-rec.7
module type-rec.8
module type-subtyping.0
module type-subtyping.1
module type-subtyping.11
module type-subtyping.12
module type-subtyping.13
module type-subtyping.14
module type-subtyping.17
module type-subtyping.18
module type-subtyping.19
module type-subtyping.2
module type-subtyping.20
module type-subtyping.21
module type-subtyping.22
module type-subtyping.23
module type-subtyping.24
module type-subtyping.25
module type-subtyping.26
module type-subtyping.27
module type-subtyping.28
module type-subtyping.29
module type-subtyping.3
module type-subtyping.30
module type-subtyping.34
module type-subtyping.37
module type-subtyping.38
module type-subtyping.39
module type-subtyping.4
module type-subtyping.40
module type-subtyping.41
module type-subtyping.43
module type-subtyping.44
module type-subtyping.45
module type-subtyping.46
module type-subtyping.47
module type-subtyping.48
module type-subtyping.49
module type-subtyping.5
module type-subtyping.50
module type-subtyping.51
module type-subtyping.53
module type-subtyping.6
module type-subtyping.7
module type-subtyping.76
module type-subtyping.8
module type-subtyping.9
module unreached-valid.0
module unreached-valid.2
test local_init.5

View file

@ -115,6 +115,10 @@ private:
auto table_address = m_machine.store().allocate(table_type);
s_spec_test_namespace.set({ "spectest", "table", table_type }, Wasm::ExternValue { *table_address });
Wasm::TableType table64_type { Wasm::ValueType(Wasm::ValueType::FunctionReference), Wasm::Limits(Wasm::AddressType::I64, 10, 20) };
auto table64_address = m_machine.store().allocate(table64_type);
s_spec_test_namespace.set({ "spectest", "table64", table64_type }, Wasm::ExternValue { *table64_address });
Wasm::MemoryType memory_type { Wasm::Limits(Wasm::AddressType::I32, 1, 2) };
auto memory_address = m_machine.store().allocate(memory_type);
s_spec_test_namespace.set({ "spectest", "memory", memory_type }, Wasm::ExternValue { *memory_address });