LibWasm+LibWeb: Stub wasm-gc's heap reference types

WPT inserts these into all modules regardless of whether they're used,
so let's just parse and ignore them.
This commit is contained in:
Ali Mohammad Pur 2025-10-14 17:21:33 +02:00 committed by Ali Mohammad Pur
parent 33d2959a4c
commit 92c0cbc453
Notes: github-actions[bot] 2025-10-14 23:28:44 +00:00
8 changed files with 57 additions and 4 deletions

View file

@ -99,6 +99,10 @@ public:
// ref.null exnref
m_value = u128(0, 4);
break;
case ValueType::UnsupportedHeapReference:
// ref.null (todo)
m_value = u128(0, 5);
break;
}
}

View file

@ -19,6 +19,20 @@ static constexpr auto v128_tag = 0x7b;
static constexpr auto function_reference_tag = 0x70;
static constexpr auto extern_reference_tag = 0x6f;
// wasm-gc references
static constexpr auto array_reference_tag = 0x6a;
static constexpr auto struct_reference_tag = 0x6b;
static constexpr auto i31_reference_tag = 0x6c;
static constexpr auto eq_reference_tag = 0x6d;
static constexpr auto any_reference_tag = 0x6e;
static constexpr auto none_reference_tag = 0x71;
static constexpr auto noextern_reference_tag = 0x72;
static constexpr auto nofunc_reference_tag = 0x73;
static constexpr auto noexn_heap_reference_tag = 0x74;
static constexpr auto nullable_reference_tag_tag = 0x63;
static constexpr auto non_nullable_reference_tag_tag = 0x64;
// Function
static constexpr auto function_signature_tag = 0x60;

View file

@ -118,6 +118,22 @@ ParseResult<ValueType> ValueType::parse(Stream& stream)
return ValueType(FunctionReference);
case Constants::extern_reference_tag:
return ValueType(ExternReference);
case Constants::array_reference_tag:
case Constants::struct_reference_tag:
case Constants::i31_reference_tag:
case Constants::eq_reference_tag:
case Constants::any_reference_tag:
case Constants::none_reference_tag:
case Constants::noextern_reference_tag:
case Constants::nofunc_reference_tag:
case Constants::noexn_heap_reference_tag:
// FIXME: Implement these when we support wasm-gc properly.
return ValueType(UnsupportedHeapReference);
case Constants::nullable_reference_tag_tag:
case Constants::non_nullable_reference_tag_tag:
tag = TRY_READ(stream, u8, ParseError::ExpectedKindTag);
(void)tag;
return ValueType(UnsupportedHeapReference);
default:
return ParseError::InvalidTag;
}

View file

@ -760,6 +760,9 @@ void Printer::print(Wasm::Value const& value, Wasm::ValueType const& type)
[](Wasm::Reference::Exception const&) { return ByteString("exception"); },
[](auto const& ref) { return ByteString::number(ref.address.value()); }));
break;
case ValueType::UnsupportedHeapReference:
print("unsupported-heap-ref");
break;
}
TemporaryChange<size_t> change { m_indent, 0 };
}

View file

@ -169,6 +169,7 @@ public:
FunctionReference,
ExternReference,
ExceptionReference,
UnsupportedHeapReference, // Stub for wasm-gc proposal's reference types.
};
explicit ValueType(Kind kind)
@ -178,7 +179,7 @@ public:
bool operator==(ValueType const&) const = default;
auto is_reference() const { return m_kind == ExternReference || m_kind == FunctionReference; }
auto is_reference() const { return m_kind == ExternReference || m_kind == FunctionReference || m_kind == UnsupportedHeapReference; }
auto is_vector() const { return m_kind == V128; }
auto is_numeric() const { return !is_reference() && !is_vector(); }
auto kind() const { return m_kind; }
@ -204,6 +205,8 @@ public:
return "externref";
case ExceptionReference:
return "exnref";
case UnsupportedHeapReference:
return "todo.heapref";
}
VERIFY_NOT_REACHED();
}

View file

@ -621,6 +621,8 @@ JS::ThrowCompletionOr<Wasm::Value> to_webassembly_value(JS::VM& vm, JS::Value va
return Wasm::Value(Wasm::ValueType { Wasm::ValueType::Kind::ExceptionReference });
case Wasm::ValueType::V128:
return vm.throw_completion<JS::TypeError>("Cannot convert a vector value to a javascript value"sv);
case Wasm::ValueType::UnsupportedHeapReference:
return vm.throw_completion<JS::TypeError>("Unsupported heap reference"sv);
}
VERIFY_NOT_REACHED();
@ -640,6 +642,8 @@ Wasm::Value default_webassembly_value(JS::VM& vm, Wasm::ValueType type)
return MUST(to_webassembly_value(vm, JS::js_undefined(), type));
case Wasm::ValueType::ExceptionReference:
return Wasm::Value(type);
case Wasm::ValueType::UnsupportedHeapReference:
return Wasm::Value(type);
}
VERIFY_NOT_REACHED();
}
@ -685,6 +689,7 @@ JS::Value to_js_value(JS::VM& vm, Wasm::Value& wasm_value, Wasm::ValueType type)
}
case Wasm::ValueType::V128:
case Wasm::ValueType::ExceptionReference:
case Wasm::ValueType::UnsupportedHeapReference:
VERIFY_NOT_REACHED();
}
VERIFY_NOT_REACHED();

View file

@ -314,13 +314,16 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::get_export)
}
case Wasm::ValueType::FunctionReference:
case Wasm::ValueType::ExternReference:
case Wasm::ValueType::ExceptionReference:
case Wasm::ValueType::ExceptionReference: {
auto ref = global->value().to<Wasm::Reference>();
return ref.ref().visit(
[&](Wasm::Reference::Null const&) -> JS::Value { return JS::js_null(); },
[](Wasm::Reference::Exception const&) -> JS::Value { return JS::js_undefined(); },
[&](auto const& ref) -> JS::Value { return JS::Value(static_cast<double>(ref.address.value())); });
}
case Wasm::ValueType::UnsupportedHeapReference:
return vm.throw_completion<JS::TypeError>("Unsupported heap reference"sv);
}
}
return vm.throw_completion<JS::TypeError>(TRY_OR_THROW_OOM(vm, String::formatted("'{}' does not refer to a function or a global", name)));
}
@ -406,6 +409,8 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::wasm_invoke)
else
return vm.throw_completion<JS::TypeError>("Exception references are not supported"sv);
break;
case Wasm::ValueType::Kind::UnsupportedHeapReference:
return vm.throw_completion<JS::TypeError>("GC Heap references are not supported"sv);
}
}
@ -420,7 +425,7 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::wasm_invoke)
if (result.values().is_empty())
return JS::js_null();
auto to_js_value = [&](Wasm::Value const& value, Wasm::ValueType type) {
auto to_js_value = [&](Wasm::Value const& value, Wasm::ValueType type) -> JS::ThrowCompletionOr<JS::Value> {
switch (type.kind()) {
case Wasm::ValueType::I32:
return JS::Value(static_cast<double>(value.to<i32>()));
@ -442,6 +447,8 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::wasm_invoke)
return (value.to<Wasm::Reference>()).ref().visit([&](Wasm::Reference::Null) { return JS::js_null(); }, [&](Wasm::Reference::Exception) { return JS::Value(); }, [&](auto const& ref) { return JS::Value(static_cast<double>(ref.address.value())); });
case Wasm::ValueType::ExceptionReference:
return JS::js_null();
case Wasm::ValueType::UnsupportedHeapReference:
return vm.throw_completion<JS::TypeError>("Unsupported heap reference"sv);
}
VERIFY_NOT_REACHED();
};
@ -452,6 +459,6 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::wasm_invoke)
size_t i = 0;
return JS::Array::create_from<Wasm::Value>(*vm.current_realm(), result.values(), [&](Wasm::Value value) {
auto value_type = type->results()[i++];
return to_js_value(value, value_type);
return MUST(to_js_value(value, value_type));
});
}

View file

@ -234,6 +234,7 @@ static ErrorOr<ParsedValue> parse_value(StringView spec)
case Wasm::ValueType::FunctionReference:
case Wasm::ValueType::ExternReference:
case Wasm::ValueType::ExceptionReference:
case Wasm::ValueType::UnsupportedHeapReference:
VERIFY_NOT_REACHED();
}
last_value = parsed.value.value();