mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 16:26:38 +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 _packageJs = Uri.parse('package:js/js.dart');
|
||||||
final _jsWasm = Uri.parse('dart:js_wasm');
|
|
||||||
final _internalJs = Uri.parse('dart:_js_annotations');
|
final _internalJs = Uri.parse('dart:_js_annotations');
|
||||||
final _jsHelper = Uri.parse('dart:_js_helper');
|
final _jsHelper = Uri.parse('dart:_js_helper');
|
||||||
|
|
||||||
bool _isAnyInteropUri(Uri uri) =>
|
bool _isAnyInteropUri(Uri uri) => uri == _packageJs || uri == _internalJs;
|
||||||
uri == _packageJs || uri == _internalJs || uri == _jsWasm;
|
|
||||||
|
|
||||||
/// Returns true if [value] is the interop annotation whose class is
|
/// Returns true if [value] is the interop annotation whose class is
|
||||||
/// [annotationClassName] from `package:js` or from `dart:_js_annotations`.
|
/// [annotationClassName] from `package:js` or from `dart:_js_annotations`.
|
||||||
|
|
|
@ -78,11 +78,11 @@ class JsUtilWasmOptimizer extends Transformer {
|
||||||
_jsifyRawTarget = _coreTypes.index
|
_jsifyRawTarget = _coreTypes.index
|
||||||
.getTopLevelProcedure('dart:_js_helper', 'jsifyRaw'),
|
.getTopLevelProcedure('dart:_js_helper', 'jsifyRaw'),
|
||||||
_wrapDartCallbackTarget = _coreTypes.index
|
_wrapDartCallbackTarget = _coreTypes.index
|
||||||
.getTopLevelProcedure('dart:js_util_wasm', '_wrapDartCallback'),
|
.getTopLevelProcedure('dart:_js_helper', '_wrapDartCallback'),
|
||||||
_newObjectTarget =
|
_newObjectTarget =
|
||||||
_coreTypes.index.getTopLevelProcedure('dart:js_util', 'newObject'),
|
_coreTypes.index.getTopLevelProcedure('dart:js_util', 'newObject'),
|
||||||
_allowInteropTarget = _coreTypes.index
|
_allowInteropTarget =
|
||||||
.getTopLevelProcedure('dart:js_util_wasm', 'allowInterop'),
|
_coreTypes.index.getTopLevelProcedure('dart:js', 'allowInterop'),
|
||||||
_wasmAnyRefClass = _coreTypes.index.getClass('dart:wasm', 'WasmAnyRef'),
|
_wasmAnyRefClass = _coreTypes.index.getClass('dart:wasm', 'WasmAnyRef'),
|
||||||
_objectClass = _coreTypes.objectClass,
|
_objectClass = _coreTypes.objectClass,
|
||||||
_pragmaClass = _coreTypes.pragmaClass,
|
_pragmaClass = _coreTypes.pragmaClass,
|
||||||
|
@ -283,8 +283,10 @@ class JsUtilWasmOptimizer extends Transformer {
|
||||||
StaticInvocation _allowInterop(
|
StaticInvocation _allowInterop(
|
||||||
Procedure node, FunctionType type, Expression argument) {
|
Procedure node, FunctionType type, Expression argument) {
|
||||||
String callbackTrampolineName = _createCallbackTrampoline(node, type);
|
String callbackTrampolineName = _createCallbackTrampoline(node, type);
|
||||||
return StaticInvocation(_wrapDartCallbackTarget,
|
return StaticInvocation(
|
||||||
Arguments([argument, StringLiteral(callbackTrampolineName)]));
|
_wrapDartCallbackTarget,
|
||||||
|
Arguments([argument, StringLiteral(callbackTrampolineName)],
|
||||||
|
types: [type]));
|
||||||
}
|
}
|
||||||
|
|
||||||
StaticGet get _globalThis => StaticGet(_globalThisMember);
|
StaticGet get _globalThis => StaticGet(_globalThisMember);
|
||||||
|
|
|
@ -50,9 +50,8 @@ class WasmTarget extends Target {
|
||||||
'dart:_js_helper',
|
'dart:_js_helper',
|
||||||
'dart:typed_data',
|
'dart:typed_data',
|
||||||
'dart:nativewrappers',
|
'dart:nativewrappers',
|
||||||
|
'dart:js',
|
||||||
'dart:js_util',
|
'dart:js_util',
|
||||||
'dart:js_util_wasm',
|
|
||||||
'dart:js_wasm',
|
|
||||||
'dart:wasm',
|
'dart:wasm',
|
||||||
'dart:developer',
|
'dart:developer',
|
||||||
];
|
];
|
||||||
|
@ -62,9 +61,8 @@ class WasmTarget extends Target {
|
||||||
'dart:_js_helper',
|
'dart:_js_helper',
|
||||||
'dart:collection',
|
'dart:collection',
|
||||||
'dart:typed_data',
|
'dart:typed_data',
|
||||||
|
'dart:js',
|
||||||
'dart:js_util',
|
'dart:js_util',
|
||||||
'dart:js_util_wasm',
|
|
||||||
'dart:js_wasm',
|
|
||||||
'dart:wasm',
|
'dart:wasm',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -107,7 +105,7 @@ class WasmTarget extends Target {
|
||||||
ChangedStructureNotifier? changedStructureNotifier}) {
|
ChangedStructureNotifier? changedStructureNotifier}) {
|
||||||
List<Library>? transitiveImportingJSInterop =
|
List<Library>? transitiveImportingJSInterop =
|
||||||
jsInteropHelper.calculateTransitiveImportsOfJsInteropIfUsed(
|
jsInteropHelper.calculateTransitiveImportsOfJsInteropIfUsed(
|
||||||
component, Uri.parse("dart:js_wasm"));
|
component, Uri.parse("package:js/js.dart"));
|
||||||
if (transitiveImportingJSInterop == null) {
|
if (transitiveImportingJSInterop == null) {
|
||||||
logger?.call("Skipped JS interop transformations");
|
logger?.call("Skipped JS interop transformations");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -87,9 +87,21 @@ external WasmAnyRef? setPropertyRaw(
|
||||||
external WasmAnyRef? callMethodVarArgsRaw(
|
external WasmAnyRef? callMethodVarArgsRaw(
|
||||||
WasmAnyRef o, WasmAnyRef method, WasmAnyRef? args);
|
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) {
|
WasmAnyRef? jsifyRaw(Object? object) {
|
||||||
if (object == null) {
|
if (object == null) {
|
||||||
return 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) {
|
} else if (object is JSValue) {
|
||||||
return object.toAnyRef();
|
return object.toAnyRef();
|
||||||
} else if (object is String) {
|
} 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")
|
@pragma("wasm:export", "\$listLength")
|
||||||
double _listLength(List list) => list.length.toDouble();
|
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
|
# 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.
|
# BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
js_util_sdk_sources = [
|
js_util_sdk_sources = [ "js_util.dart" ]
|
||||||
"js_util.dart",
|
|
||||||
"js_util_wasm.dart",
|
|
||||||
]
|
|
||||||
|
|
|
@ -235,17 +235,14 @@
|
||||||
"isolate": {
|
"isolate": {
|
||||||
"uri": "isolate/isolate.dart"
|
"uri": "isolate/isolate.dart"
|
||||||
},
|
},
|
||||||
|
"js": {
|
||||||
|
"uri": "js/js.dart",
|
||||||
|
"patches": "_internal/wasm/lib/js_patch.dart"
|
||||||
|
},
|
||||||
"js_util": {
|
"js_util": {
|
||||||
"uri": "js_util/js_util.dart",
|
"uri": "js_util/js_util.dart",
|
||||||
"patches": "_internal/wasm/lib/js_util_patch.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": {
|
"math": {
|
||||||
"uri": "math/math.dart",
|
"uri": "math/math.dart",
|
||||||
"patches": "_internal/wasm/lib/math_patch.dart"
|
"patches": "_internal/wasm/lib/math_patch.dart"
|
||||||
|
|
|
@ -218,14 +218,12 @@ wasm:
|
||||||
uri: "html/dartium/nativewrappers.dart"
|
uri: "html/dartium/nativewrappers.dart"
|
||||||
isolate:
|
isolate:
|
||||||
uri: isolate/isolate.dart
|
uri: isolate/isolate.dart
|
||||||
|
js:
|
||||||
|
uri: js/js.dart
|
||||||
|
patches: _internal/wasm/lib/js_patch.dart
|
||||||
js_util:
|
js_util:
|
||||||
uri: js_util/js_util.dart
|
uri: js_util/js_util.dart
|
||||||
patches: _internal/wasm/lib/js_util_patch.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:
|
math:
|
||||||
uri: math/math.dart
|
uri: math/math.dart
|
||||||
patches: _internal/wasm/lib/math_patch.dart
|
patches: _internal/wasm/lib/math_patch.dart
|
||||||
|
|
|
@ -3,11 +3,10 @@
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
import 'dart:js_util';
|
import 'dart:js_util';
|
||||||
import 'dart:js_util_wasm';
|
|
||||||
import 'dart:js_wasm';
|
|
||||||
import 'dart:wasm';
|
import 'dart:wasm';
|
||||||
|
|
||||||
import 'package:expect/expect.dart';
|
import 'package:expect/expect.dart';
|
||||||
|
import 'package:js/js.dart';
|
||||||
|
|
||||||
@JS()
|
@JS()
|
||||||
external void eval(String code);
|
external void eval(String code);
|
||||||
|
@ -17,8 +16,7 @@ typedef SumStringCallback = String Function(String a, String b);
|
||||||
@JS()
|
@JS()
|
||||||
@staticInterop
|
@staticInterop
|
||||||
class DartFromJSCallbackHelper {
|
class DartFromJSCallbackHelper {
|
||||||
// TODO(joshualitt): Update [allowInterop] to return a function.
|
external factory DartFromJSCallbackHelper.factory(SumStringCallback summer);
|
||||||
external factory DartFromJSCallbackHelper.factory(Object summer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension DartFromJSCallbackHelperMethods on DartFromJSCallbackHelper {
|
extension DartFromJSCallbackHelperMethods on DartFromJSCallbackHelper {
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
import 'dart:js_util';
|
import 'dart:js_util';
|
||||||
import 'dart:js_wasm';
|
|
||||||
|
|
||||||
import 'package:expect/expect.dart';
|
import 'package:expect/expect.dart';
|
||||||
|
import 'package:js/js.dart';
|
||||||
|
|
||||||
@JS()
|
@JS()
|
||||||
external void eval(String code);
|
external void eval(String code);
|
||||||
|
|
|
@ -2,10 +2,8 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// 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.
|
// 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:expect/expect.dart';
|
||||||
|
import 'package:js/js.dart';
|
||||||
|
|
||||||
@JS()
|
@JS()
|
||||||
external void eval(String code);
|
external void eval(String code);
|
||||||
|
|
Loading…
Reference in a new issue