mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 16:37:43 +00:00
[dart2wasm] Wire up stubbed out dart:js on dart2wasm
Change-Id: Ia06db4b1b2f3d07278819936842a4185cc9a45f8 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/247329 Reviewed-by: Srujan Gaddam <srujzs@google.com> Commit-Queue: Joshua Litt <joshualitt@google.com>
This commit is contained in:
parent
3e17635bca
commit
3fd96e2cb8
|
@ -60,12 +60,10 @@ List<String> getNativeNames(Annotatable a) {
|
|||
}
|
||||
|
||||
final _packageJs = Uri.parse('package:js/js.dart');
|
||||
final _jsWasm = Uri.parse('dart:js_wasm');
|
||||
final _internalJs = Uri.parse('dart:_js_annotations');
|
||||
final _jsHelper = Uri.parse('dart:_js_helper');
|
||||
|
||||
bool _isAnyInteropUri(Uri uri) =>
|
||||
uri == _packageJs || uri == _internalJs || uri == _jsWasm;
|
||||
bool _isAnyInteropUri(Uri uri) => uri == _packageJs || uri == _internalJs;
|
||||
|
||||
/// Returns true if [value] is the interop annotation whose class is
|
||||
/// [annotationClassName] from `package:js` or from `dart:_js_annotations`.
|
||||
|
|
|
@ -78,11 +78,11 @@ class JsUtilWasmOptimizer extends Transformer {
|
|||
_jsifyRawTarget = _coreTypes.index
|
||||
.getTopLevelProcedure('dart:_js_helper', 'jsifyRaw'),
|
||||
_wrapDartCallbackTarget = _coreTypes.index
|
||||
.getTopLevelProcedure('dart:js_util_wasm', '_wrapDartCallback'),
|
||||
.getTopLevelProcedure('dart:_js_helper', '_wrapDartCallback'),
|
||||
_newObjectTarget =
|
||||
_coreTypes.index.getTopLevelProcedure('dart:js_util', 'newObject'),
|
||||
_allowInteropTarget = _coreTypes.index
|
||||
.getTopLevelProcedure('dart:js_util_wasm', 'allowInterop'),
|
||||
_allowInteropTarget =
|
||||
_coreTypes.index.getTopLevelProcedure('dart:js', 'allowInterop'),
|
||||
_wasmAnyRefClass = _coreTypes.index.getClass('dart:wasm', 'WasmAnyRef'),
|
||||
_objectClass = _coreTypes.objectClass,
|
||||
_pragmaClass = _coreTypes.pragmaClass,
|
||||
|
@ -283,8 +283,10 @@ class JsUtilWasmOptimizer extends Transformer {
|
|||
StaticInvocation _allowInterop(
|
||||
Procedure node, FunctionType type, Expression argument) {
|
||||
String callbackTrampolineName = _createCallbackTrampoline(node, type);
|
||||
return StaticInvocation(_wrapDartCallbackTarget,
|
||||
Arguments([argument, StringLiteral(callbackTrampolineName)]));
|
||||
return StaticInvocation(
|
||||
_wrapDartCallbackTarget,
|
||||
Arguments([argument, StringLiteral(callbackTrampolineName)],
|
||||
types: [type]));
|
||||
}
|
||||
|
||||
StaticGet get _globalThis => StaticGet(_globalThisMember);
|
||||
|
|
|
@ -50,9 +50,8 @@ class WasmTarget extends Target {
|
|||
'dart:_js_helper',
|
||||
'dart:typed_data',
|
||||
'dart:nativewrappers',
|
||||
'dart:js',
|
||||
'dart:js_util',
|
||||
'dart:js_util_wasm',
|
||||
'dart:js_wasm',
|
||||
'dart:wasm',
|
||||
'dart:developer',
|
||||
];
|
||||
|
@ -62,9 +61,8 @@ class WasmTarget extends Target {
|
|||
'dart:_js_helper',
|
||||
'dart:collection',
|
||||
'dart:typed_data',
|
||||
'dart:js',
|
||||
'dart:js_util',
|
||||
'dart:js_util_wasm',
|
||||
'dart:js_wasm',
|
||||
'dart:wasm',
|
||||
];
|
||||
|
||||
|
@ -107,7 +105,7 @@ class WasmTarget extends Target {
|
|||
ChangedStructureNotifier? changedStructureNotifier}) {
|
||||
List<Library>? transitiveImportingJSInterop =
|
||||
jsInteropHelper.calculateTransitiveImportsOfJsInteropIfUsed(
|
||||
component, Uri.parse("dart:js_wasm"));
|
||||
component, Uri.parse("package:js/js.dart"));
|
||||
if (transitiveImportingJSInterop == null) {
|
||||
logger?.call("Skipped JS interop transformations");
|
||||
} else {
|
||||
|
|
|
@ -87,9 +87,21 @@ external WasmAnyRef? setPropertyRaw(
|
|||
external WasmAnyRef? callMethodVarArgsRaw(
|
||||
WasmAnyRef o, WasmAnyRef method, WasmAnyRef? args);
|
||||
|
||||
// Currently, `allowInterop` returns a Function type. This is unfortunate for
|
||||
// Dart2wasm because it means arbitrary Dart functions can flow to JS util
|
||||
// calls. Our only solutions is to cache every function called with
|
||||
// `allowInterop` and to replace them with the wrapped variant when they flow
|
||||
// to JS.
|
||||
// NOTE: We are not currently replacing functions returned from JS.
|
||||
Map<Function, JSValue> functionToJSWrapper = {};
|
||||
|
||||
WasmAnyRef? jsifyRaw(Object? object) {
|
||||
if (object == null) {
|
||||
return null;
|
||||
} else if (object is Function) {
|
||||
assert(functionToJSWrapper.containsKey(object),
|
||||
'Must call `allowInterop` on functions before they flow to JS');
|
||||
return functionToJSWrapper[object]?.toAnyRef();
|
||||
} else if (object is JSValue) {
|
||||
return object.toAnyRef();
|
||||
} else if (object is String) {
|
||||
|
@ -101,7 +113,21 @@ WasmAnyRef? jsifyRaw(Object? object) {
|
|||
}
|
||||
}
|
||||
|
||||
/// js_util_wasm methods used by the wasm runtime.
|
||||
@pragma("wasm:import", "dart2wasm.wrapDartCallback")
|
||||
external WasmAnyRef _wrapDartCallbackRaw(
|
||||
WasmAnyRef callback, WasmAnyRef trampolineName);
|
||||
|
||||
F _wrapDartCallback<F extends Function>(F f, String trampolineName) {
|
||||
if (functionToJSWrapper.containsKey(f)) {
|
||||
return f;
|
||||
}
|
||||
JSValue wrappedFunction = JSValue(_wrapDartCallbackRaw(
|
||||
f.toJS().toAnyRef(), trampolineName.toJS().toAnyRef()));
|
||||
functionToJSWrapper[f] = wrappedFunction;
|
||||
return f;
|
||||
}
|
||||
|
||||
/// Methods used by the wasm runtime.
|
||||
@pragma("wasm:export", "\$listLength")
|
||||
double _listLength(List list) => list.length.toDouble();
|
||||
|
||||
|
|
120
sdk/lib/_internal/wasm/lib/js_patch.dart
Normal file
120
sdk/lib/_internal/wasm/lib/js_patch.dart
Normal file
|
@ -0,0 +1,120 @@
|
|||
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// This library is only supported on dart2wasm because of [allowInterop].
|
||||
|
||||
library dart.js;
|
||||
|
||||
import 'dart:_internal' show patch;
|
||||
import 'dart:_js_helper';
|
||||
import 'dart:collection' show ListMixin;
|
||||
import 'dart:wasm';
|
||||
|
||||
@patch
|
||||
JsObject get context => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
class JsObject {
|
||||
// No argument empty constructor to support inheritance.
|
||||
JsObject._() {
|
||||
throw UnimplementedError;
|
||||
}
|
||||
|
||||
@patch
|
||||
factory JsObject(JsFunction constructor, [List? arguments]) =>
|
||||
throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
factory JsObject.fromBrowserObject(Object object) => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
factory JsObject.jsify(Object object) => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
dynamic operator [](Object property) => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
void operator []=(Object property, Object? value) => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
bool operator ==(Object other) => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
bool hasProperty(Object property) => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
void deleteProperty(Object property) => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
bool instanceof(JsFunction type) => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
String toString() => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
dynamic callMethod(Object method, [List? args]) => throw UnimplementedError;
|
||||
}
|
||||
|
||||
@patch
|
||||
class JsFunction extends JsObject {
|
||||
@patch
|
||||
factory JsFunction.withThis(Function f) => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
dynamic apply(List args, {thisArg}) => throw UnimplementedError;
|
||||
}
|
||||
|
||||
@patch
|
||||
class JsArray<E> extends JsObject with ListMixin<E> {
|
||||
@patch
|
||||
factory JsArray() => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
factory JsArray.from(Iterable<E> other) => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
E operator [](Object index) => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
void operator []=(Object index, E value) => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
int get length => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
void set length(int length) => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
void add(E value) => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
void addAll(Iterable<E> iterable) => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
void insert(int index, E element) => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
E removeAt(int index) => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
E removeLast() => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
void removeRange(int start, int end) => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
void setRange(int start, int end, Iterable<E> iterable,
|
||||
[int skipCount = 0]) =>
|
||||
throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
void sort([int compare(E a, E b)?]) => throw UnimplementedError;
|
||||
}
|
||||
|
||||
/// This will be lowered to a a call to `_wrapDartCallback`.
|
||||
@patch
|
||||
F allowInterop<F extends Function>(F f) => throw UnimplementedError;
|
||||
|
||||
@patch
|
||||
Function allowInteropCaptureThis(Function f) => throw UnimplementedError;
|
|
@ -1,21 +0,0 @@
|
|||
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
library dart.js_util_wasm;
|
||||
|
||||
import "dart:_internal";
|
||||
import "dart:_js_helper";
|
||||
import "dart:wasm";
|
||||
|
||||
@patch
|
||||
Object allowInterop<F extends Function>(F f) => throw 'unreachable';
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.wrapDartCallback")
|
||||
external WasmAnyRef _wrapDartCallbackRaw(
|
||||
WasmAnyRef callback, WasmAnyRef trampolineName);
|
||||
|
||||
JSValue? _wrapDartCallback(Object callback, String trampolineName) {
|
||||
return JSValue(_wrapDartCallbackRaw(
|
||||
callback.toJS().toAnyRef(), trampolineName.toJS().toAnyRef()));
|
||||
}
|
|
@ -2,7 +2,4 @@
|
|||
# for details. All rights reserved. Use of this source code is governed by a
|
||||
# BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
js_util_sdk_sources = [
|
||||
"js_util.dart",
|
||||
"js_util_wasm.dart",
|
||||
]
|
||||
js_util_sdk_sources = [ "js_util.dart" ]
|
||||
|
|
|
@ -235,17 +235,14 @@
|
|||
"isolate": {
|
||||
"uri": "isolate/isolate.dart"
|
||||
},
|
||||
"js": {
|
||||
"uri": "js/js.dart",
|
||||
"patches": "_internal/wasm/lib/js_patch.dart"
|
||||
},
|
||||
"js_util": {
|
||||
"uri": "js_util/js_util.dart",
|
||||
"patches": "_internal/wasm/lib/js_util_patch.dart"
|
||||
},
|
||||
"js_util_wasm": {
|
||||
"uri": "js_util/js_util_wasm.dart",
|
||||
"patches": "_internal/wasm/lib/js_util_wasm_patch.dart"
|
||||
},
|
||||
"js_wasm": {
|
||||
"uri": "js/js_wasm.dart"
|
||||
},
|
||||
"math": {
|
||||
"uri": "math/math.dart",
|
||||
"patches": "_internal/wasm/lib/math_patch.dart"
|
||||
|
|
|
@ -218,14 +218,12 @@ wasm:
|
|||
uri: "html/dartium/nativewrappers.dart"
|
||||
isolate:
|
||||
uri: isolate/isolate.dart
|
||||
js:
|
||||
uri: js/js.dart
|
||||
patches: _internal/wasm/lib/js_patch.dart
|
||||
js_util:
|
||||
uri: js_util/js_util.dart
|
||||
patches: _internal/wasm/lib/js_util_patch.dart
|
||||
js_util_wasm:
|
||||
uri: js_util/js_util_wasm.dart
|
||||
patches: _internal/wasm/lib/js_util_wasm_patch.dart
|
||||
js_wasm:
|
||||
uri: js/js_wasm.dart
|
||||
math:
|
||||
uri: math/math.dart
|
||||
patches: _internal/wasm/lib/math_patch.dart
|
||||
|
|
|
@ -3,11 +3,10 @@
|
|||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'dart:js_util';
|
||||
import 'dart:js_util_wasm';
|
||||
import 'dart:js_wasm';
|
||||
import 'dart:wasm';
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:js/js.dart';
|
||||
|
||||
@JS()
|
||||
external void eval(String code);
|
||||
|
@ -17,8 +16,7 @@ typedef SumStringCallback = String Function(String a, String b);
|
|||
@JS()
|
||||
@staticInterop
|
||||
class DartFromJSCallbackHelper {
|
||||
// TODO(joshualitt): Update [allowInterop] to return a function.
|
||||
external factory DartFromJSCallbackHelper.factory(Object summer);
|
||||
external factory DartFromJSCallbackHelper.factory(SumStringCallback summer);
|
||||
}
|
||||
|
||||
extension DartFromJSCallbackHelperMethods on DartFromJSCallbackHelper {
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'dart:js_util';
|
||||
import 'dart:js_wasm';
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:js/js.dart';
|
||||
|
||||
@JS()
|
||||
external void eval(String code);
|
||||
|
|
|
@ -2,10 +2,8 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'dart:js_util_wasm';
|
||||
import 'dart:js_wasm';
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:js/js.dart';
|
||||
|
||||
@JS()
|
||||
external void eval(String code);
|
||||
|
|
Loading…
Reference in a new issue