Skip to content

Commit

Permalink
[dart2wasm] Convert to/from externref via Wasm instructions
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Joshua Litt <[email protected]>
  • Loading branch information
askeksa authored and Commit Bot committed Aug 19, 2022
1 parent 1638b75 commit a85157e
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 6 deletions.
23 changes: 23 additions & 0 deletions pkg/dart2wasm/lib/intrinsics.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
16 changes: 16 additions & 0 deletions pkg/wasm_builder/lib/src/instructions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
6 changes: 0 additions & 6 deletions sdk/lib/wasm/wasm_types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit a85157e

Please sign in to comment.