Skip to content

[dart2wasm] High overhead getting JS wrapper for WasmGC objects in new interop API #55183

@mkustermann

Description

@mkustermann

The current way to pass Dart objects to JavaScript with the new interop API is this via Object.toJSBox:

@patch
extension ObjectToJSBoxedDartObject on Object {
  @patch
  JSBoxedDartObject get toJSBox {
    if (this is JSValue) {
      throw 'Attempting to box non-Dart object.';
    }
    final box = JSObject();
    js_helper.JS<WasmExternRef?>('(o,s,v) => o[s] = v', box.toExternRef,
        _jsBoxedDartObjectProperty.toExternRef, jsObjectFromDartObject(this));
    return box as JSBoxedDartObject;
  }
}

The reasoning behind it seems to be safety when mixing dart objects from different dart applications running in the same browser context:

/// Embedded global property for wrapped Dart objects passed via JS interop.
///
/// This is a Symbol so that different Dart applications don't share Dart
/// objects from different Dart runtimes. We expect all [JSBoxedDartObject]s to
/// have this Symbol.

=> Our main user of Dart2Wasm is Flutter4Web where almost certainly only one Dart app runs
=> This makes us pay a high price for something that's very uncommon.

We need to change this. Either

  • ignore that (multi-dart-app) aspect entirely (and leave it up to app developers to not mix objects across apps)
  • we make it some sort of opt-in (e.g. compiler flag)
  • provide public APIs users can use that are faster and don't have this overhead (if a user knows they aren't going to mix objects from different Dart apps)

Interestingly enough js_util.jsify() is high overhead due to many type tests and recursive behavior, but it does not perform the complex mechanism of obtaining JS wrappers. Instead it makes the simple & fast way to get JS wrapper, namely WasmAnyRef.fromObject(object).externalize().toJS.

/cc @srujzs

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-dart2wasmIssues for the dart2wasm compiler.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions