From a85157e2331f5ca008c330f545604959b5fc4f84 Mon Sep 17 00:00:00 2001 From: Aske Simon Christensen Date: Fri, 19 Aug 2022 07:11:18 +0000 Subject: [PATCH] [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 Reviewed-by: Joshua Litt --- pkg/dart2wasm/lib/intrinsics.dart | 23 ++++++++++++++++++++++ pkg/wasm_builder/lib/src/instructions.dart | 16 +++++++++++++++ sdk/lib/wasm/wasm_types.dart | 6 ------ 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/pkg/dart2wasm/lib/intrinsics.dart b/pkg/dart2wasm/lib/intrinsics.dart index 098c19f1058c..fbc75b91a491 100644 --- a/pkg/dart2wasm/lib/intrinsics.dart +++ b/pkg/dart2wasm/lib/intrinsics.dart @@ -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; } diff --git a/pkg/wasm_builder/lib/src/instructions.dart b/pkg/wasm_builder/lib/src/instructions.dart index 69c210bf2418..639657a713f9 100644 --- a/pkg/wasm_builder/lib/src/instructions.dart +++ b/pkg/wasm_builder/lib/src/instructions.dart @@ -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. diff --git a/sdk/lib/wasm/wasm_types.dart b/sdk/lib/wasm/wasm_types.dart index cda6ba43024d..b95e26d11851 100644 --- a/sdk/lib/wasm/wasm_types.dart +++ b/sdk/lib/wasm/wasm_types.dart @@ -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.