blob: 0ce54a34b586b73aebc23b0dd82f1df133dba311 [file] [log] [blame]
// 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.
import 'dart:wasm';
import 'package:expect/expect.dart';
@pragma("wasm:import", "Object.create")
external WasmAnyRef createObject(WasmAnyRef? prototype);
@pragma("wasm:import", "Array.of")
external WasmAnyRef singularArray(WasmAnyRef element);
@pragma("wasm:import", "Reflect.apply")
external WasmAnyRef apply(
WasmFuncRef target, WasmAnyRef thisArgument, WasmAnyRef argumentsList);
WasmAnyRef? anyRef;
WasmEqRef? eqRef;
WasmDataRef? dataRef;
int funCount = 0;
void fun(WasmEqRef arg) {
funCount++;
Expect.equals("Dart object", arg.toObject());
}
test() {
// Some test objects
Object dartObject1 = "1";
Object dartObject2 = true;
Object dartObject3 = Object();
WasmAnyRef jsObject1 = createObject(null);
// A JS object is not a Dart object.
Expect.isFalse(jsObject1.isObject);
// A Wasm ref can be null and can be checked for null.
WasmAnyRef? jsObject2 = null;
Expect.isTrue(jsObject2 == null);
// Upcast Dart objects to Wasm refs and put them in fields.
anyRef = WasmAnyRef.fromObject(dartObject1);
eqRef = WasmEqRef.fromObject(dartObject2);
dataRef = WasmDataRef.fromObject(dartObject3);
// Dart objects are Dart objects.
Expect.isTrue(anyRef!.isObject);
Expect.isTrue(eqRef!.isObject);
Expect.isTrue(dataRef!.isObject);
// Casting back yields the original objects.
Expect.identical(dartObject1, anyRef!.toObject());
Expect.identical(dartObject2, eqRef!.toObject());
Expect.identical(dartObject3, dataRef!.toObject());
// Casting a JS object to a Dart object throws.
Object o;
Expect.throws(() {
o = jsObject1.toObject();
}, (_) => true);
// Integer and float conversions
Expect.equals(1, 1.toWasmI32().toIntSigned());
Expect.equals(-2, (-2).toWasmI32().toIntSigned());
Expect.equals(3, 3.toWasmI32().toIntUnsigned());
Expect.notEquals(-4, (-4).toWasmI32().toIntUnsigned());
Expect.equals(5, 5.toWasmI64().toInt());
Expect.equals(6.0, 6.0.toWasmF32().toDouble());
Expect.notEquals(7.1, 7.1.toWasmF32().toDouble());
Expect.equals(8.0, 8.0.toWasmF64().toDouble());
// Create a typed function reference for a Dart function and call it, both
// directly and from JS.
var dartObjectRef = WasmEqRef.fromObject("Dart object");
var ff = WasmFunction.fromFunction(fun);
ff.call(dartObjectRef);
apply(ff, createObject(null), singularArray(dartObjectRef));
// Cast a typed function reference to a `funcref` and back.
WasmFuncRef funcref = WasmFuncRef.fromWasmFunction(ff);
var ff2 = WasmFunction<void Function(WasmEqRef)>.fromFuncRef(funcref);
ff2.call(dartObjectRef);
// Create a typed function reference from an import and call it.
var createObjectFun = WasmFunction.fromFunction(createObject);
WasmAnyRef jsObject3 = createObjectFun.call(null);
Expect.isFalse(jsObject3.isObject);
Expect.equals(3, funCount);
}
main() {
try {
test();
} catch (e, s) {
print(e);
print(s);
rethrow;
}
}