mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 09:43:08 +00:00
[dart2wasm] Use WasmExternRef
for JS interop.
Change-Id: I01138d48ba9cc67954ef086968af90dae173fda9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/257880 Reviewed-by: Aske Simon Christensen <askesc@google.com> Commit-Queue: Joshua Litt <joshualitt@google.com>
This commit is contained in:
parent
e4643b54df
commit
708264289d
5 changed files with 170 additions and 166 deletions
|
@ -51,7 +51,7 @@ class JsUtilWasmOptimizer extends Transformer {
|
|||
final Procedure _newObjectTarget;
|
||||
final Procedure _wrapDartFunctionTarget;
|
||||
final Procedure _allowInteropTarget;
|
||||
final Class _wasmAnyRefClass;
|
||||
final Class _wasmExternRefClass;
|
||||
final Class _objectClass;
|
||||
final Class _pragmaClass;
|
||||
final Field _pragmaName;
|
||||
|
@ -84,7 +84,8 @@ class JsUtilWasmOptimizer extends Transformer {
|
|||
_coreTypes.index.getTopLevelProcedure('dart:js_util', 'newObject'),
|
||||
_allowInteropTarget =
|
||||
_coreTypes.index.getTopLevelProcedure('dart:js', 'allowInterop'),
|
||||
_wasmAnyRefClass = _coreTypes.index.getClass('dart:wasm', 'WasmAnyRef'),
|
||||
_wasmExternRefClass =
|
||||
_coreTypes.index.getClass('dart:wasm', 'WasmExternRef'),
|
||||
_objectClass = _coreTypes.objectClass,
|
||||
_pragmaClass = _coreTypes.pragmaClass,
|
||||
_pragmaName = _coreTypes.pragmaName,
|
||||
|
@ -255,8 +256,8 @@ class JsUtilWasmOptimizer extends Transformer {
|
|||
// be exported from Wasm to JS so it can be called from JS. The argument
|
||||
// returned from the supplied callback will be converted with `jsifyRaw` to
|
||||
// a native JS value before being returned to JS.
|
||||
DartType nullableWasmAnyRefType =
|
||||
_wasmAnyRefClass.getThisType(_coreTypes, Nullability.nullable);
|
||||
DartType nullableWasmExternRefType =
|
||||
_wasmExternRefClass.getThisType(_coreTypes, Nullability.nullable);
|
||||
final String libraryName = _library.name ?? 'Unnamed';
|
||||
final functionTrampolineName =
|
||||
'|_functionTrampoline${_functionTrampolineN++}For$libraryName';
|
||||
|
@ -275,7 +276,7 @@ class JsUtilWasmOptimizer extends Transformer {
|
|||
functionType: function),
|
||||
]))),
|
||||
positionalParameters: positionalParameters,
|
||||
returnType: nullableWasmAnyRefType)
|
||||
returnType: nullableWasmExternRefType)
|
||||
..fileOffset = fileOffset,
|
||||
isStatic: true,
|
||||
fileUri: node.fileUri)
|
||||
|
|
|
@ -1408,7 +1408,7 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
|
|||
|
||||
@override
|
||||
w.ValueType visitEqualsNull(EqualsNull node, w.ValueType expectedType) {
|
||||
wrap(node.expression, const w.RefType.any(nullable: true));
|
||||
wrap(node.expression, const w.RefType.top(nullable: true));
|
||||
b.ref_is_null();
|
||||
return w.NumType.i32;
|
||||
}
|
||||
|
|
|
@ -14,77 +14,77 @@ part 'regexp_helper.dart';
|
|||
|
||||
/// [JSValue] is the root of the JS interop object hierarchy.
|
||||
class JSValue {
|
||||
final WasmAnyRef _ref;
|
||||
final WasmExternRef _ref;
|
||||
|
||||
JSValue(this._ref);
|
||||
|
||||
// Currently we always explictly box JS ref's in [JSValue] objects. In the
|
||||
// future, we will want to leave these values unboxed when possible, even when
|
||||
// they are nullable.
|
||||
static JSValue? box(WasmAnyRef? ref) =>
|
||||
static JSValue? box(WasmExternRef? ref) =>
|
||||
isDartNull(ref) ? null : JSValue(ref!);
|
||||
|
||||
@override
|
||||
bool operator ==(Object that) =>
|
||||
that is JSValue && areEqualInJS(_ref, that._ref);
|
||||
|
||||
WasmAnyRef toAnyRef() => _ref;
|
||||
WasmExternRef toExternRef() => _ref;
|
||||
String toString() => jsStringToDartString(_ref);
|
||||
List<Object?> toObjectList() => toDartList(_ref);
|
||||
Object toObject() => jsObjectToDartObject(_ref);
|
||||
}
|
||||
|
||||
extension DoubleToJS on double {
|
||||
WasmAnyRef toAnyRef() => toJSNumber(this);
|
||||
JSValue toJS() => JSValue(toAnyRef());
|
||||
WasmExternRef toExternRef() => toJSNumber(this)!;
|
||||
JSValue toJS() => JSValue(toExternRef());
|
||||
}
|
||||
|
||||
extension StringToJS on String {
|
||||
WasmAnyRef toAnyRef() => jsStringFromDartString(this);
|
||||
JSValue toJS() => JSValue(toAnyRef());
|
||||
WasmExternRef toExternRef() => jsStringFromDartString(this)!;
|
||||
JSValue toJS() => JSValue(toExternRef());
|
||||
}
|
||||
|
||||
extension ListOfObjectToJS on List<Object?> {
|
||||
WasmAnyRef toAnyRef() => jsArrayFromDartList(this);
|
||||
JSValue toJS() => JSValue(toAnyRef());
|
||||
WasmExternRef toExternRef() => jsArrayFromDartList(this)!;
|
||||
JSValue toJS() => JSValue(toExternRef());
|
||||
}
|
||||
|
||||
extension ObjectToJS on Object {
|
||||
WasmAnyRef toAnyRef() => jsObjectFromDartObject(this);
|
||||
JSValue toJS() => JSValue(toAnyRef());
|
||||
WasmExternRef toExternRef() => jsObjectFromDartObject(this);
|
||||
JSValue toJS() => JSValue(toExternRef());
|
||||
}
|
||||
|
||||
// For now both `null` and `undefined` in JS map to `null` in Dart.
|
||||
bool isDartNull(WasmAnyRef? ref) => ref == null || isJSUndefined(ref);
|
||||
bool isDartNull(WasmExternRef? ref) => ref == null || isJSUndefined(ref);
|
||||
|
||||
/// A [JSArray] is a wrapper for a native JSArray.
|
||||
class JSArray extends JSValue {
|
||||
JSArray(WasmAnyRef ref) : super(ref);
|
||||
JSArray(WasmExternRef ref) : super(ref);
|
||||
|
||||
static JSArray? box(WasmAnyRef? ref) =>
|
||||
static JSArray? box(WasmExternRef? ref) =>
|
||||
isDartNull(ref) ? null : JSArray(ref!);
|
||||
|
||||
JSValue? pop() =>
|
||||
JSValue.box(callMethodVarArgsRaw(_ref, 'pop'.toAnyRef(), [].toAnyRef()));
|
||||
JSValue? pop() => JSValue.box(
|
||||
callMethodVarArgsRaw(_ref, 'pop'.toExternRef(), [].toExternRef()));
|
||||
JSValue? operator [](int index) =>
|
||||
JSValue.box(getPropertyRaw(_ref, intToJSNumber(index)));
|
||||
void operator []=(int index, JSValue? value) =>
|
||||
setPropertyRaw(_ref, intToJSNumber(index), value?.toAnyRef());
|
||||
setPropertyRaw(_ref, intToJSNumber(index), value?.toExternRef());
|
||||
int get length =>
|
||||
toDartNumber(getPropertyRaw(_ref, 'length'.toAnyRef())!).floor();
|
||||
toDartNumber(getPropertyRaw(_ref, 'length'.toExternRef())!).floor();
|
||||
}
|
||||
|
||||
/// A [JSObject] is a wrapper for any JS object literal.
|
||||
class JSObject extends JSValue {
|
||||
JSObject(WasmAnyRef ref) : super(ref);
|
||||
JSObject(WasmExternRef ref) : super(ref);
|
||||
|
||||
static JSObject? box(WasmAnyRef? ref) =>
|
||||
static JSObject? box(WasmExternRef? ref) =>
|
||||
isDartNull(ref) ? null : JSObject(ref!);
|
||||
|
||||
JSValue? operator [](String key) =>
|
||||
JSValue.box(getPropertyRaw(_ref, key.toAnyRef()));
|
||||
JSValue.box(getPropertyRaw(_ref, key.toExternRef()));
|
||||
void operator []=(String key, JSValue? value) =>
|
||||
setPropertyRaw(_ref, key.toAnyRef(), value?.toAnyRef());
|
||||
setPropertyRaw(_ref, key.toExternRef(), value?.toExternRef());
|
||||
}
|
||||
|
||||
class JSArrayIteratorAdapter<T> extends Iterator<T> {
|
||||
|
@ -103,7 +103,7 @@ class JSArrayIteratorAdapter<T> extends Iterator<T> {
|
|||
}
|
||||
|
||||
@override
|
||||
T get current => dartifyRaw(array[index]?.toAnyRef()) as T;
|
||||
T get current => dartifyRaw(array[index]?.toExternRef()) as T;
|
||||
}
|
||||
|
||||
/// [JSArrayIterableAdapter] lazily adapts a [JSArray] to Dart's [Iterable]
|
||||
|
@ -121,195 +121,197 @@ class JSArrayIterableAdapter<T> extends EfficientLengthIterable<T> {
|
|||
}
|
||||
|
||||
// Convert to double to avoid converting to [BigInt] in the case of int64.
|
||||
WasmAnyRef intToJSNumber(int i) => toJSNumber(i.toDouble());
|
||||
WasmExternRef intToJSNumber(int i) => toJSNumber(i.toDouble())!;
|
||||
|
||||
WasmAnyRef? getConstructorString(String constructor) =>
|
||||
getPropertyRaw(globalThisRaw(), constructor.toAnyRef());
|
||||
WasmExternRef? getConstructorString(String constructor) =>
|
||||
getPropertyRaw(globalThisRaw(), constructor.toExternRef());
|
||||
|
||||
Object jsObjectToDartObject(WasmAnyRef ref) => unsafeCastOpaque<Object>(ref);
|
||||
Object jsObjectToDartObject(WasmExternRef? ref) =>
|
||||
unsafeCastOpaque<Object>(ref.internalize());
|
||||
|
||||
WasmAnyRef jsObjectFromDartObject(Object object) =>
|
||||
unsafeCastOpaque<WasmAnyRef>(object);
|
||||
WasmExternRef jsObjectFromDartObject(Object object) =>
|
||||
unsafeCastOpaque<WasmAnyRef>(object).externalize();
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSUndefined")
|
||||
external bool isJSUndefined(WasmAnyRef? o);
|
||||
external bool isJSUndefined(WasmExternRef? o);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSBoolean")
|
||||
external bool isJSBoolean(WasmAnyRef? o);
|
||||
external bool isJSBoolean(WasmExternRef? o);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSNumber")
|
||||
external bool isJSNumber(WasmAnyRef? o);
|
||||
external bool isJSNumber(WasmExternRef? o);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSBigInt")
|
||||
external bool isJSBigInt(WasmAnyRef? o);
|
||||
external bool isJSBigInt(WasmExternRef? o);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSString")
|
||||
external bool isJSString(WasmAnyRef? o);
|
||||
external bool isJSString(WasmExternRef? o);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSSymbol")
|
||||
external bool isJSSymbol(WasmAnyRef? o);
|
||||
external bool isJSSymbol(WasmExternRef? o);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSFunction")
|
||||
external bool isJSFunction(WasmAnyRef? o);
|
||||
external bool isJSFunction(WasmExternRef? o);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSInt8Array")
|
||||
external bool isJSInt8Array(WasmAnyRef object);
|
||||
external bool isJSInt8Array(WasmExternRef? object);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSUint8Array")
|
||||
external bool isJSUint8Array(WasmAnyRef object);
|
||||
external bool isJSUint8Array(WasmExternRef? object);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSUint8ClampedArray")
|
||||
external bool isJSUint8ClampedArray(WasmAnyRef object);
|
||||
external bool isJSUint8ClampedArray(WasmExternRef? object);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSInt16Array")
|
||||
external bool isJSInt16Array(WasmAnyRef object);
|
||||
external bool isJSInt16Array(WasmExternRef? object);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSUint16Array")
|
||||
external bool isJSUint16Array(WasmAnyRef object);
|
||||
external bool isJSUint16Array(WasmExternRef? object);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSInt32Array")
|
||||
external bool isJSInt32Array(WasmAnyRef object);
|
||||
external bool isJSInt32Array(WasmExternRef? object);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSUint32Array")
|
||||
external bool isJSUint32Array(WasmAnyRef object);
|
||||
external bool isJSUint32Array(WasmExternRef? object);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSFloat32Array")
|
||||
external bool isJSFloat32Array(WasmAnyRef object);
|
||||
external bool isJSFloat32Array(WasmExternRef? object);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSFloat64Array")
|
||||
external bool isJSFloat64Array(WasmAnyRef object);
|
||||
external bool isJSFloat64Array(WasmExternRef? object);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSArrayBuffer")
|
||||
external bool isJSArrayBuffer(WasmAnyRef object);
|
||||
external bool isJSArrayBuffer(WasmExternRef? object);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSDataView")
|
||||
external bool isJSDataView(WasmAnyRef object);
|
||||
external bool isJSDataView(WasmExternRef? object);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSArray")
|
||||
external bool isJSArray(WasmAnyRef? o);
|
||||
external bool isJSArray(WasmExternRef? o);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSWrappedDartFunction")
|
||||
external bool isJSWrappedDartFunction(WasmAnyRef? o);
|
||||
external bool isJSWrappedDartFunction(WasmExternRef? o);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSObject")
|
||||
external bool isJSObject(WasmAnyRef? o);
|
||||
external bool isJSObject(WasmExternRef? o);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSSimpleObject")
|
||||
external bool isJSSimpleObject(WasmAnyRef? o);
|
||||
external bool isJSSimpleObject(WasmExternRef? o);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.isJSRegExp")
|
||||
external bool isJSRegExp(WasmAnyRef object);
|
||||
external bool isJSRegExp(WasmExternRef? object);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.areEqualInJS")
|
||||
external bool areEqualInJS(WasmAnyRef? l, WasmAnyRef? r);
|
||||
external bool areEqualInJS(WasmExternRef? l, WasmExternRef? r);
|
||||
|
||||
// The JS runtime will run helpful conversion routines between refs and bool /
|
||||
// double. In the longer term hopefully we can find a way to avoid the round
|
||||
// trip.
|
||||
@pragma("wasm:import", "dart2wasm.roundtrip")
|
||||
external double toDartNumber(WasmAnyRef ref);
|
||||
external double toDartNumber(WasmExternRef? ref);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.roundtrip")
|
||||
external WasmAnyRef toJSNumber(double d);
|
||||
external WasmExternRef? toJSNumber(double d);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.roundtrip")
|
||||
external bool toDartBool(WasmAnyRef ref);
|
||||
external bool toDartBool(WasmExternRef? ref);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.toJSBoolean")
|
||||
external WasmAnyRef toJSBoolean(bool b);
|
||||
external WasmExternRef? toJSBoolean(bool b);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.objectLength")
|
||||
external double objectLength(WasmAnyRef ref);
|
||||
external double objectLength(WasmExternRef? ref);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.objectReadIndex")
|
||||
external WasmAnyRef? objectReadIndex(WasmAnyRef ref, int index);
|
||||
external WasmExternRef? objectReadIndex(WasmExternRef? ref, int index);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.unwrapJSWrappedDartFunction")
|
||||
external Object? unwrapJSWrappedDartFunction(WasmAnyRef f);
|
||||
external Object? unwrapJSWrappedDartFunction(WasmExternRef? f);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.int8ArrayFromDartInt8List")
|
||||
external WasmAnyRef jsInt8ArrayFromDartInt8List(Int8List list);
|
||||
external WasmExternRef? jsInt8ArrayFromDartInt8List(Int8List list);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.uint8ArrayFromDartUint8List")
|
||||
external WasmAnyRef jsUint8ArrayFromDartUint8List(Uint8List list);
|
||||
external WasmExternRef? jsUint8ArrayFromDartUint8List(Uint8List list);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.uint8ClampedArrayFromDartUint8ClampedList")
|
||||
external WasmAnyRef jsUint8ClampedArrayFromDartUint8ClampedList(
|
||||
external WasmExternRef? jsUint8ClampedArrayFromDartUint8ClampedList(
|
||||
Uint8ClampedList list);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.int16ArrayFromDartInt16List")
|
||||
external WasmAnyRef jsInt16ArrayFromDartInt16List(Int16List list);
|
||||
external WasmExternRef? jsInt16ArrayFromDartInt16List(Int16List list);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.uint16ArrayFromDartUint16List")
|
||||
external WasmAnyRef jsUint16ArrayFromDartUint16List(Uint16List list);
|
||||
external WasmExternRef? jsUint16ArrayFromDartUint16List(Uint16List list);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.int32ArrayFromDartInt32List")
|
||||
external WasmAnyRef jsInt32ArrayFromDartInt32List(Int32List list);
|
||||
external WasmExternRef? jsInt32ArrayFromDartInt32List(Int32List list);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.uint32ArrayFromDartUint32List")
|
||||
external WasmAnyRef jsUint32ArrayFromDartUint32List(Uint32List list);
|
||||
external WasmExternRef? jsUint32ArrayFromDartUint32List(Uint32List list);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.float32ArrayFromDartFloat32List")
|
||||
external WasmAnyRef jsFloat32ArrayFromDartFloat32List(Float32List list);
|
||||
external WasmExternRef? jsFloat32ArrayFromDartFloat32List(Float32List list);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.float64ArrayFromDartFloat64List")
|
||||
external WasmAnyRef jsFloat64ArrayFromDartFloat64List(Float64List list);
|
||||
external WasmExternRef? jsFloat64ArrayFromDartFloat64List(Float64List list);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.dataViewFromDartByteData")
|
||||
external WasmAnyRef jsDataViewFromDartByteData(
|
||||
external WasmExternRef? jsDataViewFromDartByteData(
|
||||
ByteData data, double byteLength);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.arrayFromDartList")
|
||||
external WasmAnyRef jsArrayFromDartList(List<Object?> list);
|
||||
external WasmExternRef? jsArrayFromDartList(List<Object?> list);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.stringFromDartString")
|
||||
external WasmAnyRef jsStringFromDartString(String string);
|
||||
external WasmExternRef? jsStringFromDartString(String string);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.stringToDartString")
|
||||
external String jsStringToDartString(WasmAnyRef string);
|
||||
external String jsStringToDartString(WasmExternRef? string);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.eval")
|
||||
external void evalRaw(WasmAnyRef code);
|
||||
external void evalRaw(WasmExternRef? code);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.newObject")
|
||||
external WasmAnyRef newObjectRaw();
|
||||
external WasmExternRef? newObjectRaw();
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.newArray")
|
||||
external WasmAnyRef newArrayRaw();
|
||||
external WasmExternRef? newArrayRaw();
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.globalThis")
|
||||
external WasmAnyRef globalThisRaw();
|
||||
external WasmExternRef? globalThisRaw();
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.callConstructorVarArgs")
|
||||
external WasmAnyRef callConstructorVarArgsRaw(WasmAnyRef o, WasmAnyRef args);
|
||||
external WasmExternRef? callConstructorVarArgsRaw(
|
||||
WasmExternRef? o, WasmExternRef? args);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.safeCallConstructorVarArgs")
|
||||
external WasmAnyRef safeCallConstructorVarArgsRaw(
|
||||
WasmAnyRef o, WasmAnyRef args);
|
||||
external WasmExternRef? safeCallConstructorVarArgsRaw(
|
||||
WasmExternRef? o, WasmExternRef? args);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.hasProperty")
|
||||
external bool hasPropertyRaw(WasmAnyRef o, WasmAnyRef name);
|
||||
external bool hasPropertyRaw(WasmExternRef? o, WasmExternRef? name);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.getProperty")
|
||||
external WasmAnyRef? getPropertyRaw(WasmAnyRef o, WasmAnyRef name);
|
||||
external WasmExternRef? getPropertyRaw(WasmExternRef? o, WasmExternRef? name);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.setProperty")
|
||||
external WasmAnyRef? setPropertyRaw(
|
||||
WasmAnyRef o, WasmAnyRef name, WasmAnyRef? value);
|
||||
external WasmExternRef? setPropertyRaw(
|
||||
WasmExternRef? o, WasmExternRef? name, WasmExternRef? value);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.callMethodVarArgs")
|
||||
external WasmAnyRef? callMethodVarArgsRaw(
|
||||
WasmAnyRef o, WasmAnyRef method, WasmAnyRef? args);
|
||||
external WasmExternRef? callMethodVarArgsRaw(
|
||||
WasmExternRef? o, WasmExternRef? method, WasmExternRef? args);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.stringify")
|
||||
external String stringify(WasmAnyRef? object);
|
||||
external String stringify(WasmExternRef? object);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.objectKeys")
|
||||
external WasmAnyRef objectKeysRaw(WasmAnyRef? o);
|
||||
external WasmExternRef? objectKeysRaw(WasmExternRef? o);
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.promiseThen")
|
||||
external void promiseThen(
|
||||
WasmAnyRef promise, WasmAnyRef successFunc, WasmAnyRef failureFunc);
|
||||
external void promiseThen(WasmExternRef? promise, WasmExternRef? successFunc,
|
||||
WasmExternRef? failureFunc);
|
||||
|
||||
// Currently, `allowInterop` returns a Function type. This is unfortunate for
|
||||
// Dart2wasm because it means arbitrary Dart functions can flow to JS util
|
||||
|
@ -319,14 +321,14 @@ external void promiseThen(
|
|||
// NOTE: We are not currently replacing functions returned from JS.
|
||||
Map<Function, JSValue> functionToJSWrapper = {};
|
||||
|
||||
WasmAnyRef jsArrayBufferFromDartByteBuffer(ByteBuffer buffer) {
|
||||
WasmExternRef? jsArrayBufferFromDartByteBuffer(ByteBuffer buffer) {
|
||||
ByteData byteData = ByteData.view(buffer);
|
||||
WasmAnyRef dataView =
|
||||
WasmExternRef? dataView =
|
||||
jsDataViewFromDartByteData(byteData, byteData.lengthInBytes.toDouble());
|
||||
return getPropertyRaw(dataView, 'buffer'.toAnyRef())!;
|
||||
return getPropertyRaw(dataView, 'buffer'.toExternRef());
|
||||
}
|
||||
|
||||
WasmAnyRef? jsifyRaw(Object? object) {
|
||||
WasmExternRef? jsifyRaw(Object? object) {
|
||||
if (object == null) {
|
||||
return null;
|
||||
} else if (object is bool) {
|
||||
|
@ -334,9 +336,9 @@ WasmAnyRef? jsifyRaw(Object? object) {
|
|||
} else if (object is Function) {
|
||||
assert(functionToJSWrapper.containsKey(object),
|
||||
'Must call `allowInterop` on functions before they flow to JS');
|
||||
return functionToJSWrapper[object]?.toAnyRef();
|
||||
return functionToJSWrapper[object]?.toExternRef();
|
||||
} else if (object is JSValue) {
|
||||
return object.toAnyRef();
|
||||
return object.toExternRef();
|
||||
} else if (object is String) {
|
||||
return jsStringFromDartString(object);
|
||||
} else if (object is Int8List) {
|
||||
|
@ -374,9 +376,9 @@ WasmAnyRef? jsifyRaw(Object? object) {
|
|||
/// cast error for certain oddball types(I think undefined, but need to dig
|
||||
/// deeper).
|
||||
@pragma("wasm:export", "\$dartifyRaw")
|
||||
Object? dartifyExported(WasmAnyRef? ref) => dartifyRaw(ref);
|
||||
Object? dartifyExported(WasmExternRef? ref) => dartifyRaw(ref);
|
||||
|
||||
Object? dartifyRaw(WasmAnyRef? ref) {
|
||||
Object? dartifyRaw(WasmExternRef? ref) {
|
||||
if (ref == null) {
|
||||
return null;
|
||||
} else if (isJSUndefined(ref)) {
|
||||
|
@ -426,112 +428,114 @@ Object? dartifyRaw(WasmAnyRef? ref) {
|
|||
}
|
||||
}
|
||||
|
||||
Int8List toDartInt8List(WasmAnyRef ref) =>
|
||||
Int8List toDartInt8List(WasmExternRef? ref) =>
|
||||
jsIntTypedArrayToDartIntTypedData(ref, (size) => Int8List(size))
|
||||
as Int8List;
|
||||
|
||||
Uint8List toDartUint8List(WasmAnyRef ref) =>
|
||||
Uint8List toDartUint8List(WasmExternRef? ref) =>
|
||||
jsIntTypedArrayToDartIntTypedData(ref, (size) => Uint8List(size))
|
||||
as Uint8List;
|
||||
|
||||
Uint8ClampedList toDartUint8ClampedList(WasmAnyRef ref) =>
|
||||
Uint8ClampedList toDartUint8ClampedList(WasmExternRef? ref) =>
|
||||
jsIntTypedArrayToDartIntTypedData(ref, (size) => Uint8ClampedList(size))
|
||||
as Uint8ClampedList;
|
||||
|
||||
Int16List toDartInt16List(WasmAnyRef ref) =>
|
||||
Int16List toDartInt16List(WasmExternRef? ref) =>
|
||||
jsIntTypedArrayToDartIntTypedData(ref, (size) => Int16List(size))
|
||||
as Int16List;
|
||||
|
||||
Uint16List toDartUint16List(WasmAnyRef ref) =>
|
||||
Uint16List toDartUint16List(WasmExternRef? ref) =>
|
||||
jsIntTypedArrayToDartIntTypedData(ref, (size) => Uint16List(size))
|
||||
as Uint16List;
|
||||
|
||||
Int32List toDartInt32List(WasmAnyRef ref) =>
|
||||
Int32List toDartInt32List(WasmExternRef? ref) =>
|
||||
jsIntTypedArrayToDartIntTypedData(ref, (size) => Int32List(size))
|
||||
as Int32List;
|
||||
|
||||
Uint32List toDartUint32List(WasmAnyRef ref) =>
|
||||
Uint32List toDartUint32List(WasmExternRef? ref) =>
|
||||
jsIntTypedArrayToDartIntTypedData(ref, (size) => Uint32List(size))
|
||||
as Uint32List;
|
||||
|
||||
Float32List toDartFloat32List(WasmAnyRef ref) =>
|
||||
Float32List toDartFloat32List(WasmExternRef? ref) =>
|
||||
jsFloatTypedArrayToDartFloatTypedData(ref, (size) => Float32List(size))
|
||||
as Float32List;
|
||||
|
||||
Float64List toDartFloat64List(WasmAnyRef ref) =>
|
||||
Float64List toDartFloat64List(WasmExternRef? ref) =>
|
||||
jsFloatTypedArrayToDartFloatTypedData(ref, (size) => Float64List(size))
|
||||
as Float64List;
|
||||
|
||||
ByteBuffer toDartByteBuffer(WasmAnyRef ref) =>
|
||||
ByteBuffer toDartByteBuffer(WasmExternRef? ref) =>
|
||||
toDartByteData(callConstructorVarArgsRaw(
|
||||
getConstructorString('DataView')!, [JSValue(ref)].toAnyRef()))
|
||||
getConstructorString('DataView'), [JSValue.box(ref)].toExternRef()))
|
||||
.buffer;
|
||||
|
||||
ByteData toDartByteData(WasmAnyRef ref) {
|
||||
ByteData toDartByteData(WasmExternRef? ref) {
|
||||
int length =
|
||||
toDartNumber(getPropertyRaw(ref, 'byteLength'.toAnyRef())!).toInt();
|
||||
toDartNumber(getPropertyRaw(ref, 'byteLength'.toExternRef())).toInt();
|
||||
ByteData data = ByteData(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
data.setUint8(
|
||||
i,
|
||||
toDartNumber(callMethodVarArgsRaw(
|
||||
ref, 'getUint8'.toAnyRef(), [i].toAnyRef())!)
|
||||
ref, 'getUint8'.toExternRef(), [i].toExternRef()))
|
||||
.toInt());
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
List<double> jsFloatTypedArrayToDartFloatTypedData(
|
||||
WasmAnyRef ref, List<double> makeTypedData(int size)) {
|
||||
WasmExternRef? ref, List<double> makeTypedData(int size)) {
|
||||
int length = objectLength(ref).toInt();
|
||||
List<double> list = makeTypedData(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
list[i] = toDartNumber(objectReadIndex(ref, i)!);
|
||||
list[i] = toDartNumber(objectReadIndex(ref, i));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
List<int> jsIntTypedArrayToDartIntTypedData(
|
||||
WasmAnyRef ref, List<int> makeTypedData(int size)) {
|
||||
WasmExternRef? ref, List<int> makeTypedData(int size)) {
|
||||
int length = objectLength(ref).toInt();
|
||||
List<int> list = makeTypedData(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
list[i] = toDartNumber(objectReadIndex(ref, i)!).toInt();
|
||||
list[i] = toDartNumber(objectReadIndex(ref, i)).toInt();
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
List<Object?> toDartList(WasmAnyRef ref) => List<Object?>.generate(
|
||||
List<Object?> toDartList(WasmExternRef? ref) => List<Object?>.generate(
|
||||
objectLength(ref).round(), (int n) => dartifyRaw(objectReadIndex(ref, n)));
|
||||
|
||||
@pragma("wasm:import", "dart2wasm.wrapDartFunction")
|
||||
external WasmAnyRef _wrapDartFunctionRaw(
|
||||
WasmAnyRef dartFunction, WasmAnyRef trampolineName);
|
||||
external WasmExternRef? _wrapDartFunctionRaw(
|
||||
WasmExternRef? dartFunction, WasmExternRef? trampolineName);
|
||||
|
||||
F _wrapDartFunction<F extends Function>(F f, String trampolineName) {
|
||||
if (functionToJSWrapper.containsKey(f)) {
|
||||
return f;
|
||||
}
|
||||
JSValue wrappedFunction = JSValue(_wrapDartFunctionRaw(
|
||||
f.toJS().toAnyRef(), trampolineName.toJS().toAnyRef()));
|
||||
f.toJS().toExternRef(), trampolineName.toJS().toExternRef())!);
|
||||
functionToJSWrapper[f] = wrappedFunction;
|
||||
return f;
|
||||
}
|
||||
|
||||
/// Returns the JS constructor object for a given [String].
|
||||
WasmAnyRef getConstructorRaw(String name) =>
|
||||
getPropertyRaw(globalThisRaw(), name.toAnyRef())!;
|
||||
WasmExternRef? getConstructorRaw(String name) =>
|
||||
getPropertyRaw(globalThisRaw(), name.toExternRef());
|
||||
|
||||
/// Equivalent to `Object.keys(object)`.
|
||||
JSArray objectKeys(JSValue object) => JSArray(callMethodVarArgsRaw(
|
||||
getConstructorRaw('Object'), 'keys'.toAnyRef(), [object].toAnyRef())!);
|
||||
getConstructorRaw('Object'),
|
||||
'keys'.toExternRef(),
|
||||
[object].toExternRef())!);
|
||||
|
||||
/// Methods used by the wasm runtime.
|
||||
@pragma("wasm:export", "\$listLength")
|
||||
double _listLength(List list) => list.length.toDouble();
|
||||
|
||||
@pragma("wasm:export", "\$listRead")
|
||||
WasmAnyRef? _listRead(List<Object?> list, double index) =>
|
||||
WasmExternRef? _listRead(List<Object?> list, double index) =>
|
||||
jsifyRaw(list[index.toInt()]);
|
||||
|
||||
@pragma("wasm:export", "\$byteDataGetUint8")
|
||||
|
|
|
@ -47,8 +47,8 @@ dynamic jsify(Object? object) {
|
|||
convertedObjects[o] = convertedMap;
|
||||
for (final key in o.keys) {
|
||||
JSValue convertedKey = convert(key) as JSValue;
|
||||
setPropertyRaw(convertedMap.toAnyRef(), convertedKey.toAnyRef(),
|
||||
(convert(o[key]) as JSValue).toAnyRef());
|
||||
setPropertyRaw(convertedMap.toExternRef(), convertedKey.toExternRef(),
|
||||
(convert(o[key]) as JSValue).toExternRef());
|
||||
}
|
||||
return convertedMap;
|
||||
} else if (o is Iterable) {
|
||||
|
@ -68,37 +68,36 @@ dynamic jsify(Object? object) {
|
|||
}
|
||||
|
||||
@patch
|
||||
Object get globalThis => JSValue(globalThisRaw());
|
||||
Object get globalThis => JSValue(globalThisRaw()!);
|
||||
|
||||
@patch
|
||||
T newObject<T>() => JSValue(newObjectRaw()) as T;
|
||||
T newObject<T>() => JSValue(newObjectRaw()!) as T;
|
||||
|
||||
JSValue _newArray() => JSValue(newArrayRaw());
|
||||
JSValue _newArray() => JSValue(newArrayRaw()!);
|
||||
|
||||
@patch
|
||||
bool hasProperty(Object o, String name) =>
|
||||
hasPropertyRaw(jsifyRaw(o)!, name.toJS().toAnyRef());
|
||||
hasPropertyRaw(jsifyRaw(o)!, name.toJS().toExternRef());
|
||||
|
||||
@patch
|
||||
T getProperty<T>(Object o, String name) =>
|
||||
dartifyRaw(getPropertyRaw(jsifyRaw(o)!, name.toJS().toAnyRef())) as T;
|
||||
dartifyRaw(getPropertyRaw(jsifyRaw(o)!, name.toJS().toExternRef())) as T;
|
||||
|
||||
@patch
|
||||
T setProperty<T>(Object o, String name, T? value) => dartifyRaw(
|
||||
setPropertyRaw(jsifyRaw(o)!, name.toJS().toAnyRef(), jsifyRaw(value))) as T;
|
||||
T setProperty<T>(Object o, String name, T? value) => dartifyRaw(setPropertyRaw(
|
||||
jsifyRaw(o)!, name.toJS().toExternRef(), jsifyRaw(value))) as T;
|
||||
|
||||
@patch
|
||||
T callMethod<T>(Object o, String method, List<Object?> args) =>
|
||||
dartifyRaw(callMethodVarArgsRaw(
|
||||
jsifyRaw(o)!, method.toJS().toAnyRef(), args.toJS().toAnyRef())) as T;
|
||||
dartifyRaw(callMethodVarArgsRaw(jsifyRaw(o)!, method.toJS().toExternRef(),
|
||||
args.toJS().toExternRef())) as T;
|
||||
|
||||
@patch
|
||||
bool instanceof(Object? o, Object type) => throw 'unimplemented';
|
||||
|
||||
@patch
|
||||
T callConstructor<T>(Object o, List<Object?> args) =>
|
||||
dartifyRaw(callConstructorVarArgsRaw(jsifyRaw(o)!, args.toJS().toAnyRef()))!
|
||||
as T;
|
||||
T callConstructor<T>(Object o, List<Object?> args) => dartifyRaw(
|
||||
callConstructorVarArgsRaw(jsifyRaw(o)!, args.toJS().toExternRef()))! as T;
|
||||
|
||||
@patch
|
||||
T add<T>(Object? first, Object? second) => throw 'unimplemented';
|
||||
|
@ -192,7 +191,7 @@ Object? dartify(Object? object) {
|
|||
return o;
|
||||
}
|
||||
|
||||
WasmAnyRef ref = o.toAnyRef();
|
||||
WasmExternRef ref = o.toExternRef();
|
||||
if (isJSBoolean(ref) ||
|
||||
isJSNumber(ref) ||
|
||||
isJSString(ref) ||
|
||||
|
@ -225,7 +224,7 @@ Object? dartify(Object? object) {
|
|||
Object? key = keys[i];
|
||||
if (key != null) {
|
||||
dartMap[key] = convert(
|
||||
JSValue.box(getPropertyRaw(ref, (key as String).toAnyRef())));
|
||||
JSValue.box(getPropertyRaw(ref, (key as String).toExternRef())));
|
||||
}
|
||||
}
|
||||
return dartMap;
|
||||
|
|
|
@ -15,39 +15,39 @@ part of dart._js_helper;
|
|||
external String quoteStringForRegExp(String string);
|
||||
|
||||
class JSNativeMatch extends JSArray {
|
||||
JSNativeMatch(WasmAnyRef ref) : super(ref);
|
||||
JSNativeMatch(WasmExternRef ref) : super(ref);
|
||||
|
||||
static JSNativeMatch? box(WasmAnyRef? ref) =>
|
||||
static JSNativeMatch? box(WasmExternRef? ref) =>
|
||||
isDartNull(ref) ? null : JSNativeMatch(ref!);
|
||||
|
||||
String get input => jsStringToDartString(
|
||||
getPropertyRaw(this.toAnyRef(), 'input'.toAnyRef())!);
|
||||
getPropertyRaw(this.toExternRef(), 'input'.toExternRef())!);
|
||||
int get index =>
|
||||
toDartNumber(getPropertyRaw(this.toAnyRef(), 'index'.toAnyRef())!)
|
||||
toDartNumber(getPropertyRaw(this.toExternRef(), 'index'.toExternRef())!)
|
||||
.floor();
|
||||
JSObject? get groups =>
|
||||
JSObject.box(getPropertyRaw(this.toAnyRef(), 'groups'.toAnyRef()));
|
||||
JSObject.box(getPropertyRaw(this.toExternRef(), 'groups'.toExternRef()));
|
||||
}
|
||||
|
||||
class JSNativeRegExp extends JSValue {
|
||||
JSNativeRegExp(WasmAnyRef ref) : super(ref);
|
||||
JSNativeRegExp(WasmExternRef ref) : super(ref);
|
||||
|
||||
JSNativeMatch? exec(String string) => JSNativeMatch.box(callMethodVarArgsRaw(
|
||||
this.toAnyRef(), 'exec'.toAnyRef(), [string].toAnyRef()));
|
||||
this.toExternRef(), 'exec'.toExternRef(), [string].toExternRef()));
|
||||
bool test(String string) => toDartBool(callMethodVarArgsRaw(
|
||||
this.toAnyRef(), 'test'.toAnyRef(), [string].toAnyRef())!);
|
||||
this.toExternRef(), 'test'.toExternRef(), [string].toExternRef())!);
|
||||
String get flags => jsStringToDartString(
|
||||
getPropertyRaw(this.toAnyRef(), 'flags'.toAnyRef())!);
|
||||
bool get multiline =>
|
||||
toDartBool(getPropertyRaw(this.toAnyRef(), 'multiline'.toAnyRef())!);
|
||||
bool get ignoreCase =>
|
||||
toDartBool(getPropertyRaw(this.toAnyRef(), 'ignoreCase'.toAnyRef())!);
|
||||
getPropertyRaw(this.toExternRef(), 'flags'.toExternRef())!);
|
||||
bool get multiline => toDartBool(
|
||||
getPropertyRaw(this.toExternRef(), 'multiline'.toExternRef())!);
|
||||
bool get ignoreCase => toDartBool(
|
||||
getPropertyRaw(this.toExternRef(), 'ignoreCase'.toExternRef())!);
|
||||
bool get unicode =>
|
||||
toDartBool(getPropertyRaw(this.toAnyRef(), 'unicode'.toAnyRef())!);
|
||||
toDartBool(getPropertyRaw(this.toExternRef(), 'unicode'.toExternRef())!);
|
||||
bool get dotAll =>
|
||||
toDartBool(getPropertyRaw(this.toAnyRef(), 'dotAll'.toAnyRef())!);
|
||||
toDartBool(getPropertyRaw(this.toExternRef(), 'dotAll'.toExternRef())!);
|
||||
set lastIndex(int start) => setPropertyRaw(
|
||||
this.toAnyRef(), 'lastIndex'.toAnyRef(), intToJSNumber(start));
|
||||
this.toExternRef(), 'lastIndex'.toExternRef(), intToJSNumber(start));
|
||||
}
|
||||
|
||||
class JSSyntaxRegExp implements RegExp {
|
||||
|
@ -99,9 +99,9 @@ class JSSyntaxRegExp implements RegExp {
|
|||
String modifiers = '$m$i$u$s$g';
|
||||
// The call to create the regexp is wrapped in a try catch so we can
|
||||
// reformat the exception if need be.
|
||||
WasmAnyRef result = safeCallConstructorVarArgsRaw(
|
||||
getConstructorRaw('RegExp'), [source, modifiers].toAnyRef());
|
||||
if (isJSRegExp(result)) return JSNativeRegExp(result);
|
||||
WasmExternRef? result = safeCallConstructorVarArgsRaw(
|
||||
getConstructorRaw('RegExp'), [source, modifiers].toExternRef());
|
||||
if (isJSRegExp(result)) return JSNativeRegExp(result!);
|
||||
// The returned value is the stringified JavaScript exception. Turn it into
|
||||
// a Dart exception.
|
||||
String errorMessage = jsStringToDartString(result);
|
||||
|
@ -194,7 +194,7 @@ class _MatchImplementation implements RegExpMatch {
|
|||
if (groups != null) {
|
||||
JSValue? result = groups[name];
|
||||
if (result != null ||
|
||||
hasPropertyRaw(groups.toAnyRef(), name.toAnyRef())) {
|
||||
hasPropertyRaw(groups.toExternRef(), name.toExternRef())) {
|
||||
return result?.toString();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue