1
0
mirror of https://github.com/dart-lang/sdk synced 2024-07-03 00:08:46 +00:00

[dart2wasm] Add concrete box and symbol for JSBoxedDartObject

The current implementation externalizes and internalizes the Dart
value instead of adding a box and using a runtime-specific symbol.
This makes the implementation consistent with the JS backends.

Change-Id: Iefa382f742bc819b18dfe27ca33741b12473ee39
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/347222
Commit-Queue: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
Srujan Gaddam 2024-01-23 23:39:49 +00:00 committed by Commit Queue
parent b4be031505
commit a6e8759888
3 changed files with 31 additions and 2 deletions

View File

@ -12,6 +12,15 @@
[pub-security-advisories]: https://dart.dev/go/pub-security-advisories
### Libraries
#### `dart:js_interop`
- On dart2wasm, `JSBoxedDartObject` now is an actual JS object that wraps the
opaque Dart value instead of only externalizing the value. Like the JS
backends, you'll now get a more useful error when trying to use it in another
Dart runtime.
## 3.3.0
### Language

View File

@ -94,11 +94,27 @@ extension FunctionToJSExportedDartFunction on Function {
'by the interop transformer.');
}
/// 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.
final JSSymbol _jsBoxedDartObjectProperty = _boxNonNullable<JSSymbol>(
js_helper.JS<WasmExternRef?>('() => Symbol("jsBoxedDartObjectProperty")'));
/// [JSBoxedDartObject] <-> [Object]
@patch
extension JSBoxedDartObjectToObject on JSBoxedDartObject {
@patch
Object get toDart => jsObjectToDartObject(toExternRef);
Object get toDart {
final val = js_helper.JS<WasmExternRef?>('(o,s) => o[s]', this.toExternRef,
_jsBoxedDartObjectProperty.toExternRef);
if (isDartNull(val)) {
throw 'Expected a wrapped Dart object, but got a JS object or a wrapped '
'Dart object from a separate runtime instead.';
}
return jsObjectToDartObject(val);
}
}
@patch
@ -108,7 +124,10 @@ extension ObjectToJSBoxedDartObject on Object {
if (this is JSValue) {
throw 'Attempting to box non-Dart object.';
}
return _boxNonNullable<JSBoxedDartObject>(jsObjectFromDartObject(this));
final box = JSObject();
js_helper.JS<WasmExternRef?>('(o,s,v) => o[s] = v', box.toExternRef,
_jsBoxedDartObjectProperty.toExternRef, jsObjectFromDartObject(this));
return box as JSBoxedDartObject;
}
}

View File

@ -173,6 +173,7 @@ void syncTests() {
expect(edo is JSBoxedDartObject, true);
expect(confuse(edo) is JSBoxedDartObject, true);
expect(((edo as JSBoxedDartObject).toDart as DartObject).foo, 'bar');
expect(edo.instanceOfString('Object'), true);
// Functions should be boxed without assertInterop.
final concat = (String a, String b) => a + b;
edo = concat.toJSBox;