Bug 1861722: add constant instructions extern.internalize and extern.externalize. r=rhunt

Differential Revision: https://phabricator.services.mozilla.com/D193041
This commit is contained in:
Jerome Vouillon 2023-11-08 18:33:42 +00:00
parent 3711a00967
commit b25527083a
2 changed files with 58 additions and 0 deletions

View file

@ -94,6 +94,30 @@ assertEq(wasmGcReadField(wasmGcReadField(result, 1), 1), 4);
assertEq(wasmGcReadField(wasmGcReadField(result, 2), 0), 5);
assertEq(wasmGcReadField(wasmGcReadField(result, 2), 1), 6);
// extern.internalize and extern.externalize
let {testString, testArray} = wasmEvalText(`(module
(type $array (array i32))
(import "env" "s" (global $s (ref extern)))
(global $s' (ref extern) (extern.externalize (extern.internalize (global.get $s))))
(func (export "testString") (result (ref extern))
(global.get $s'))
(global $a (ref $array) (array.new_fixed $array 1 (i32.const 0)))
(global $a' (ref any) (extern.internalize (extern.externalize (global.get $a))))
(func (export "testArray") (result i32)
(ref.eq (global.get $a) (ref.cast (ref eq) (global.get $a'))))
)`, {env:{s:"abc"}}).exports;
assertEq(testString(), 'abc');
assertEq(testArray(), 1);
wasmFailValidateText(`(module
(global $g (ref extern) (extern.externalize (extern.internalize (ref.null extern))))
)`, /expected/);
wasmFailValidateText(`(module
(global $g (ref extern) (extern.internalize (extern.externalize (ref.null any))))
)`, /expected/);
// Simple table initialization
{
const { t1, t2, t1init } = wasmEvalText(`(module

View file

@ -231,6 +231,18 @@ class MOZ_STACK_CLASS InitExprInterpreter {
return pushRef(RefType::i31().asNonNullable(),
AnyRef::fromUint32Truncate(value));
}
bool evalExternInternalize(JSContext* cx) {
AnyRef ref = stack.back().ref();
stack.popBack();
return pushRef(RefType::extern_(), ref);
}
bool evalExternExternalize(JSContext* cx) {
AnyRef ref = stack.back().ref();
stack.popBack();
return pushRef(RefType::any(), ref);
}
#endif // ENABLE_WASM_GC
};
@ -390,6 +402,12 @@ bool InitExprInterpreter::evaluate(JSContext* cx, Decoder& d) {
case uint32_t(GcOp::RefI31): {
CHECK(evalI31New(cx));
}
case uint32_t(GcOp::ExternInternalize): {
CHECK(evalExternInternalize(cx));
}
case uint32_t(GcOp::ExternExternalize): {
CHECK(evalExternExternalize(cx));
}
default: {
MOZ_CRASH();
}
@ -600,6 +618,22 @@ bool wasm::DecodeConstantExpression(Decoder& d, ModuleEnvironment* env,
}
break;
}
case uint32_t(GcOp::ExternInternalize): {
Nothing value;
if (!iter.readRefConversion(RefType::extern_(), RefType::any(),
&value)) {
return false;
}
break;
}
case uint32_t(GcOp::ExternExternalize): {
Nothing value;
if (!iter.readRefConversion(RefType::any(), RefType::extern_(),
&value)) {
return false;
}
break;
}
default: {
return iter.unrecognizedOpcode(&op);
}