v8/test/mjsunit/wasm/gc-js-interop-async.js
Matthias Liedtke 4893b1c0bd [wasm-gc] Basic JS interop handling for wasm objects
This change tests all JavaScript language constructs and builtins in
combination with the unwrapped Wasm objects.
For JavaScript, excluding some basic introspection (e.g.
`Object.isExtensible`) WebAssembly GC objects are treated opaque.
They can be passed around freely but don't allow any access to
properties, elements etc.

This behavior is currently exposed only if the `wasm-gc-js-interop`
flag is set.

Bug: v8:7748
Change-Id: If0dc368f99d4097e3eaf53edde4e244e3081e334
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3879616
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Matthias Liedtke <mliedtke@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83299}
2022-09-19 11:26:21 +00:00

69 lines
3.0 KiB
JavaScript

// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --experimental-wasm-gc --wasm-gc-js-interop --allow-natives-syntax
d8.file.execute('test/mjsunit/wasm/gc-js-interop-helpers.js');
let {struct, array} = CreateWasmObjects();
for (const wasm_obj of [struct, array]) {
repeated(() => assertThrowsAsync(Promise.all(wasm_obj), TypeError));
repeated(() => Promise.all([wasm_obj]));
repeated(() => assertThrowsAsync(Promise.allSettled(wasm_obj), TypeError));
repeated(
() => Promise.allSettled([wasm_obj])
.then((info) => assertEquals('fulfilled', info[0].status)));
repeated(() => assertThrowsAsync(Promise.any(wasm_obj), TypeError));
repeated(() => Promise.any([wasm_obj]));
repeated(() => assertThrowsAsync(Promise.race(wasm_obj), TypeError));
repeated(() => Promise.race([wasm_obj]));
// Using wasm objects in Promise.resolve and Promise.reject should work as
// for any other object.
repeated(
() => (new Promise((resolve, reject) => resolve(wasm_obj)))
.then((v) => assertSame(wasm_obj, v)));
repeated(
() => (new Promise((resolve, reject) => reject(wasm_obj)))
.then(() => assertUnreachable())
.catch((v) => assertSame(wasm_obj, v)));
// Wasm objects can also be passed as a result in a then chain.
repeated(
() => (new Promise((resolve) => resolve({})))
.then(() => wasm_obj)
.then((v) => assertSame(wasm_obj, v)));
// If the `then` argument isn't a callback, it will simply be replaced with
// an identity function (x) => x.
repeated(
() => (new Promise((resolve) => resolve({})))
.then(wasm_obj) // The value itself doesn't have any impact.
.then((v) => assertEquals({}, v), () => assertUnreachable()));
// If the `catch` argument isn't a callback, it will be replaced with a
// thrower function (x) => { throw x; }.
repeated(
() => (new Promise((resolve, reject) => reject({})))
.then(() => null)
.catch(wasm_obj) // The value itself doesn't have any impact.
.then(() => assertUnreachable(), (v) => assertEquals({}, v)));
// `finally(wasm_obj)` behaves just like `then(wasm_obj, wasm_obj)`
repeated(
() => (new Promise((resolve, reject) => resolve({})))
.finally(wasm_obj)
.then((v) => assertEquals({}, v), () => assertUnreachable()));
repeated(
() => (new Promise((resolve, reject) => reject({})))
.finally(wasm_obj)
.then(() => assertUnreachable(), (v) => assertEquals({}, v)));
// Ensure no statement re-assigned wasm_obj by accident.
assertTrue(wasm_obj == struct || wasm_obj == array);
}
repeated(async function testAsync() {
for (let wasm_obj of [struct, array]) {
let async_wasm_obj = await wasm_obj;
assertSame(wasm_obj, async_wasm_obj);
}
});