[dart2wasm] Convert to/from externref via Wasm instructions

This adds support for the newly added `extern.externalize` and
`extern.internalize` instructions and uses these for converting to/from
`externref` instead of a JS round-trip.

Change-Id: If18d8f44ddf013d4c26bf1597be91bcd0db41c5a
Cq-Include-Trybots: luci.dart.try:dart2wasm-linux-x64-d8-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/255462
Commit-Queue: Aske Simon Christensen <askesc@google.com>
Reviewed-by: Joshua Litt <joshualitt@google.com>
This commit is contained in:
Aske Simon Christensen 2022-08-19 07:11:18 +00:00 committed by Commit Bot
parent 1638b75d77
commit a85157e233
3 changed files with 39 additions and 6 deletions

View file

@ -1007,6 +1007,29 @@ class Intrinsifier {
}
}
// dart:wasm static functions
if (node.target.enclosingLibrary.name == "dart.wasm") {
Expression value = node.arguments.positional.single;
switch (name) {
case "_externalizeNonNullable":
codeGen.wrap(value, w.RefType.any(nullable: false));
b.extern_externalize();
return w.RefType.extern(nullable: false);
case "_externalizeNullable":
codeGen.wrap(value, w.RefType.any(nullable: true));
b.extern_externalize();
return w.RefType.extern(nullable: true);
case "_internalizeNonNullable":
codeGen.wrap(value, w.RefType.extern(nullable: false));
b.extern_internalize();
return w.RefType.any(nullable: false);
case "_internalizeNullable":
codeGen.wrap(value, w.RefType.extern(nullable: true));
b.extern_internalize();
return w.RefType.any(nullable: true);
}
}
return null;
}

View file

@ -1251,6 +1251,22 @@ class Instructions with SerializerMixin {
_writeLabel(label);
}
/// Emit an `extern.internalize` instruction.
void extern_internalize() {
assert(_verifyTypesFun(const [RefType.extern(nullable: true)],
(inputs) => [RefType.any(nullable: inputs.single.nullable)],
trace: ['extern.internalize']));
writeBytes(const [0xFB, 0x70]);
}
/// Emit an `extern.externalize` instruction.
void extern_externalize() {
assert(_verifyTypesFun(const [RefType.any(nullable: true)],
(inputs) => [RefType.extern(nullable: inputs.single.nullable)],
trace: ['extern.externalize']));
writeBytes(const [0xFB, 0x71]);
}
// Numeric instructions
/// Emit an `i32.const` instruction.

View file

@ -52,15 +52,9 @@ extension InternalizeNullable on WasmExternRef? {
WasmAnyRef? internalize() => _internalizeNullable(this);
}
// TODO(askesc): Add intrinsics for these when the `extern.externalize` and
// `extern.internalize` instructions are implemented in V8.
@pragma("wasm:import", "dart2wasm.roundtrip")
external WasmExternRef _externalizeNonNullable(WasmAnyRef ref);
@pragma("wasm:import", "dart2wasm.roundtrip")
external WasmExternRef? _externalizeNullable(WasmAnyRef? ref);
@pragma("wasm:import", "dart2wasm.roundtrip")
external WasmAnyRef _internalizeNonNullable(WasmExternRef ref);
@pragma("wasm:import", "dart2wasm.roundtrip")
external WasmAnyRef? _internalizeNullable(WasmExternRef? ref);
/// The Wasm `funcref` type.