diff --git a/test/fixtures/wpt/FileAPI/BlobURL/cross-partition-navigation.tentative.https.html b/test/fixtures/wpt/FileAPI/BlobURL/cross-partition-navigation.tentative.https.html
new file mode 100644
index 00000000000000..cdfa145a838c15
--- /dev/null
+++ b/test/fixtures/wpt/FileAPI/BlobURL/cross-partition-navigation.tentative.https.html
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/fixtures/wpt/FileAPI/BlobURL/cross-partition.tentative.https.html b/test/fixtures/wpt/FileAPI/BlobURL/cross-partition.tentative.https.html
index 11d9787b8873a8..5cdaad5f0af2d5 100644
--- a/test/fixtures/wpt/FileAPI/BlobURL/cross-partition.tentative.https.html
+++ b/test/fixtures/wpt/FileAPI/BlobURL/cross-partition.tentative.https.html
@@ -71,6 +71,8 @@
"/resources/common.js");
await importScript("/html/anonymous-iframe/resources/common.js");
await importScript("/common/utils.js");
+
+ // dispatcher.js has already been loaded by the popup this is running in.
await send("${response_queue_uuid}", newIframe("${iframe_origin}"));
`;
@@ -86,15 +88,15 @@
const not_same_site_popup_uuid = newPopup(t, cross_site_origin);
await send(not_same_site_popup_uuid,
add_iframe_js(same_site_origin, response_queue_uuid));
- const iframe_1_uuid = await receive(response_queue_uuid);
+ const cross_site_iframe_uuid = await receive(response_queue_uuid);
// Create a same-origin iframe in a same-site popup.
const same_origin_popup_uuid = newPopup(t, same_site_origin);
await send(same_origin_popup_uuid,
add_iframe_js(same_site_origin, response_queue_uuid));
- const iframe_2_uuid = await receive(response_queue_uuid);
+ const same_site_iframe_uuid = await receive(response_queue_uuid);
- return [iframe_1_uuid, iframe_2_uuid];
+ return [cross_site_iframe_uuid, same_site_iframe_uuid];
}
// Tests revoking blob URL for same and cross partition iframes.
@@ -114,11 +116,11 @@
// Creates same and cross partition iframes.
const response_queue_uuid = token();
- const [iframe_1_uuid, iframe_2_uuid] =
+ const [cross_site_iframe_uuid, same_site_iframe_uuid] =
await create_test_iframes(t, response_queue_uuid);
// Attempt to revoke blob URL in cross partition iframe.
- await send(iframe_1_uuid, can_blob_url_be_revoked_js(blob_url, response_queue_uuid));
+ await send(cross_site_iframe_uuid, can_blob_url_be_revoked_js(blob_url, response_queue_uuid));
var response_1 = await receive(response_queue_uuid);
if (response_1 !== js_finished) {
reject(response_1);
@@ -129,7 +131,7 @@
}
// Attempt to revoke blob URL in same partition iframe.
- await send(iframe_2_uuid, can_blob_url_be_revoked_js(blob_url, response_queue_uuid));
+ await send(same_site_iframe_uuid, can_blob_url_be_revoked_js(blob_url, response_queue_uuid));
var response_2 = await receive(response_queue_uuid);
if (response_2 !== js_finished) {
reject(response_2);
@@ -160,6 +162,8 @@
"/resources/common.js");
await importScript("/html/anonymous-iframe/resources/common.js");
await importScript("/common/utils.js");
+
+ // dispatcher.js has already been loaded by the popup this is running in.
const newWorker = ${newWorker};
await send("${response_queue_uuid}", newWorker("${origin}"));
`;
@@ -170,13 +174,13 @@
try {
const response_queue_uuid = token();
- const [iframe_1_uuid, iframe_2_uuid] =
+ const [cross_site_iframe_uuid, same_site_iframe_uuid] =
await create_test_iframes(t, response_queue_uuid);
- await send(iframe_1_uuid, create_dedicated_worker_js(same_site_origin, response_queue_uuid));
+ await send(cross_site_iframe_uuid, create_dedicated_worker_js(same_site_origin, response_queue_uuid));
const worker_1_uuid = await receive(response_queue_uuid);
- await send(iframe_2_uuid, create_dedicated_worker_js(same_site_origin, response_queue_uuid));
+ await send(same_site_iframe_uuid, create_dedicated_worker_js(same_site_origin, response_queue_uuid));
const worker_2_uuid = await receive(response_queue_uuid);
const blob = new Blob(["blob data"], {type : "text/plain"});
@@ -223,6 +227,8 @@
"/resources/common.js");
await importScript("/html/anonymous-iframe/resources/common.js");
await importScript("/common/utils.js");
+
+ // dispatcher.js has already been loaded by the popup this is running in.
const newSharedWorker = ${newSharedWorker};
await send("${response_queue_uuid}", newSharedWorker("${origin}"));
`;
@@ -233,15 +239,15 @@
try {
const response_queue_uuid = token();
- const [iframe_1_uuid, iframe_2_uuid] =
+ const [cross_site_iframe_uuid, same_site_iframe_uuid] =
await create_test_iframes(t, response_queue_uuid);
// Create a shared worker in the cross-top-level-site iframe.
- await send(iframe_1_uuid, create_shared_worker_js(same_site_origin, response_queue_uuid));
+ await send(cross_site_iframe_uuid, create_shared_worker_js(same_site_origin, response_queue_uuid));
const worker_1_uuid = await receive(response_queue_uuid);
// Create a shared worker in the same-top-level-site iframe.
- await send(iframe_2_uuid, create_shared_worker_js(same_site_origin, response_queue_uuid));
+ await send(same_site_iframe_uuid, create_shared_worker_js(same_site_origin, response_queue_uuid));
const worker_2_uuid = await receive(response_queue_uuid);
const blob = new Blob(["blob data"], {type : "text/plain"});
@@ -293,6 +299,8 @@
"/resources/common.js");
await importScript("/html/anonymous-iframe/resources/common.js");
await importScript("/common/utils.js");
+
+ // dispatcher.js has already been loaded by the popup this is running in.
const newServiceWorker = ${newServiceWorker};
await send("${response_queue_uuid}", await newServiceWorker("${origin}"));
`;
@@ -303,11 +311,11 @@
try {
const response_queue_uuid = token();
- const [iframe_1_uuid, iframe_2_uuid] =
+ const [cross_site_iframe_uuid, same_site_iframe_uuid] =
await create_test_iframes(t, response_queue_uuid);
// Create a service worker in either iframe.
- await send(iframe_1_uuid, create_service_worker_js(same_site_origin, response_queue_uuid));
+ await send(cross_site_iframe_uuid, create_service_worker_js(same_site_origin, response_queue_uuid));
var worker_1_uuid = await receive(response_queue_uuid);
t.add_cleanup(() =>
send(worker_1_uuid, "self.registration.unregister();"));
@@ -347,18 +355,18 @@
// Creates same and cross partition iframes.
const response_queue_uuid = token();
- const [iframe_1_uuid, iframe_2_uuid] =
+ const [cross_site_iframe_uuid, same_site_iframe_uuid] =
await create_test_iframes(t, response_queue_uuid);
// Attempt to fetch blob URL in cross partition iframe.
- await send(iframe_1_uuid, can_blob_url_be_fetched_js(blob_url, response_queue_uuid));
+ await send(cross_site_iframe_uuid, can_blob_url_be_fetched_js(blob_url, response_queue_uuid));
var response_1 = await receive(response_queue_uuid);
if (response_1 !== fetch_unsuccessful_response) {
reject(`Blob URL was fetched in not-same-top-level-site iframe: ${response_1}`);
}
// Attempt to fetch blob URL in same partition iframe.
- await send(iframe_2_uuid, can_blob_url_be_fetched_js(blob_url, response_queue_uuid));
+ await send(same_site_iframe_uuid, can_blob_url_be_fetched_js(blob_url, response_queue_uuid));
var response_2 = await receive(response_queue_uuid);
if (response_2 !== fetch_successful_response) {
reject(`Blob URL wasn't fetched in same-top-level-site iframe: ${response_2}`);
@@ -378,15 +386,15 @@
const response_queue_uuid = token();
// Creates same and cross partition iframes.
- const [iframe_1_uuid, iframe_2_uuid] =
+ const [cross_site_iframe_uuid, same_site_iframe_uuid] =
await create_test_iframes(t, response_queue_uuid);
// Creates a dedicated worker in the cross-top-level-site iframe.
- await send(iframe_1_uuid, create_dedicated_worker_js(same_site_origin, response_queue_uuid));
+ await send(cross_site_iframe_uuid, create_dedicated_worker_js(same_site_origin, response_queue_uuid));
const worker_1_uuid = await receive(response_queue_uuid);
// Creates a dedicated worker in the same-top-level-site iframe.
- await send(iframe_2_uuid, create_dedicated_worker_js(same_site_origin, response_queue_uuid));
+ await send(same_site_iframe_uuid, create_dedicated_worker_js(same_site_origin, response_queue_uuid));
const worker_2_uuid = await receive(response_queue_uuid);
const blob = new Blob(["blob data"], {type : "text/plain"});
@@ -420,15 +428,15 @@
try {
const response_queue_uuid = token();
- const [iframe_1_uuid, iframe_2_uuid] =
+ const [cross_site_iframe_uuid, same_site_iframe_uuid] =
await create_test_iframes(t, response_queue_uuid);
// Create a shared worker in the cross-top-level-site iframe.
- await send(iframe_1_uuid, create_shared_worker_js(same_site_origin, response_queue_uuid));
+ await send(cross_site_iframe_uuid, create_shared_worker_js(same_site_origin, response_queue_uuid));
const worker_1_uuid = await receive(response_queue_uuid);
// Create a shared worker in the same-top-level-site iframe.
- await send(iframe_2_uuid, create_shared_worker_js(same_site_origin, response_queue_uuid));
+ await send(same_site_iframe_uuid, create_shared_worker_js(same_site_origin, response_queue_uuid));
const worker_2_uuid = await receive(response_queue_uuid);
const blob = new Blob(["blob data"], {type : "text/plain"});
@@ -462,7 +470,7 @@
try {
const response_queue_uuid = token();
- const [iframe_1_uuid, iframe_2_uuid] =
+ const [cross_site_iframe_uuid, same_site_iframe_uuid] =
await create_test_iframes(t, response_queue_uuid);
const blob = new Blob(["blob data"], {type : "text/plain"});
@@ -470,7 +478,7 @@
t.add_cleanup(() => window.URL.revokeObjectURL(blob_url));
// Create a service worker in cross-top-level-site iframe.
- await send(iframe_1_uuid, create_service_worker_js(same_site_origin, response_queue_uuid));
+ await send(cross_site_iframe_uuid, create_service_worker_js(same_site_origin, response_queue_uuid));
var worker_1_uuid = await receive(response_queue_uuid);
t.add_cleanup(() =>
send(worker_1_uuid, "self.registration.unregister();"));
@@ -483,7 +491,7 @@
}
// Create a service worker in same-top-level-site iframe.
- await send(iframe_2_uuid, create_service_worker_js(same_site_origin, response_queue_uuid));
+ await send(same_site_iframe_uuid, create_service_worker_js(same_site_origin, response_queue_uuid));
var worker_2_uuid = await receive(response_queue_uuid);
t.add_cleanup(() =>
send(worker_2_uuid, "self.registration.unregister();"));
diff --git a/test/fixtures/wpt/README.md b/test/fixtures/wpt/README.md
index a4775df1accec5..cbcf0edbeffa56 100644
--- a/test/fixtures/wpt/README.md
+++ b/test/fixtures/wpt/README.md
@@ -13,24 +13,24 @@ Last update:
- common: https://github.com/web-platform-tests/wpt/tree/d8da9d4d1d/common
- compression: https://github.com/web-platform-tests/wpt/tree/da8d6860b2/compression
- console: https://github.com/web-platform-tests/wpt/tree/e48251b778/console
-- dom/abort: https://github.com/web-platform-tests/wpt/tree/07a9d09a8f/dom/abort
+- dom/abort: https://github.com/web-platform-tests/wpt/tree/0143fe244b/dom/abort
- dom/events: https://github.com/web-platform-tests/wpt/tree/0a811c5161/dom/events
- encoding: https://github.com/web-platform-tests/wpt/tree/5aa50dd415/encoding
- fetch/data-urls/resources: https://github.com/web-platform-tests/wpt/tree/7c79d998ff/fetch/data-urls/resources
-- FileAPI: https://github.com/web-platform-tests/wpt/tree/1d5fb397da/FileAPI
+- FileAPI: https://github.com/web-platform-tests/wpt/tree/40a4e28f25/FileAPI
- hr-time: https://github.com/web-platform-tests/wpt/tree/614e81711c/hr-time
- html/webappapis/atob: https://github.com/web-platform-tests/wpt/tree/f267e1dca6/html/webappapis/atob
- html/webappapis/microtask-queuing: https://github.com/web-platform-tests/wpt/tree/22ecfc9bac/html/webappapis/microtask-queuing
- html/webappapis/structured-clone: https://github.com/web-platform-tests/wpt/tree/c29dcddf37/html/webappapis/structured-clone
- html/webappapis/timers: https://github.com/web-platform-tests/wpt/tree/7a0548ac47/html/webappapis/timers
-- interfaces: https://github.com/web-platform-tests/wpt/tree/ab18bf796b/interfaces
+- interfaces: https://github.com/web-platform-tests/wpt/tree/4a48b52da3/interfaces
- performance-timeline: https://github.com/web-platform-tests/wpt/tree/94caab7038/performance-timeline
-- resource-timing: https://github.com/web-platform-tests/wpt/tree/95e7763ca9/resource-timing
-- resources: https://github.com/web-platform-tests/wpt/tree/ff5b1bc4db/resources
-- streams: https://github.com/web-platform-tests/wpt/tree/b5f2d0c48a/streams
-- url: https://github.com/web-platform-tests/wpt/tree/30de089033/url
+- resource-timing: https://github.com/web-platform-tests/wpt/tree/7bb012885c/resource-timing
+- resources: https://github.com/web-platform-tests/wpt/tree/d9f17001dc/resources
+- streams: https://github.com/web-platform-tests/wpt/tree/699dbdae30/streams
+- url: https://github.com/web-platform-tests/wpt/tree/08519e73d1/url
- user-timing: https://github.com/web-platform-tests/wpt/tree/5ae85bf826/user-timing
-- wasm/jsapi: https://github.com/web-platform-tests/wpt/tree/140f5c80fd/wasm/jsapi
+- wasm/jsapi: https://github.com/web-platform-tests/wpt/tree/f427091001/wasm/jsapi
- wasm/webapi: https://github.com/web-platform-tests/wpt/tree/28456b73ca/wasm/webapi
- WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/6748a0a246/WebCryptoAPI
- webidl/ecmascript-binding/es-exceptions: https://github.com/web-platform-tests/wpt/tree/a370aad338/webidl/ecmascript-binding/es-exceptions
diff --git a/test/fixtures/wpt/dom/abort/crashtests/any-on-abort.html b/test/fixtures/wpt/dom/abort/crashtests/any-on-abort.html
new file mode 100644
index 00000000000000..07a0f0bd3c2ba6
--- /dev/null
+++ b/test/fixtures/wpt/dom/abort/crashtests/any-on-abort.html
@@ -0,0 +1,11 @@
+
+
+
diff --git a/test/fixtures/wpt/dom/abort/resources/abort-signal-any-tests.js b/test/fixtures/wpt/dom/abort/resources/abort-signal-any-tests.js
index 929ee8a2e61ab4..8f897c934e87ea 100644
--- a/test/fixtures/wpt/dom/abort/resources/abort-signal-any-tests.js
+++ b/test/fixtures/wpt/dom/abort/resources/abort-signal-any-tests.js
@@ -221,4 +221,20 @@ function abortSignalAnyTests(signalInterface, controllerInterface) {
assert_true(signal.aborted);
assert_equals(signal.reason, "reason 1");
}, `Dependent signals for ${desc} are aborted correctly for reentrant aborts ${suffix}`);
+
+ test(t => {
+ const source = signalInterface.abort();
+ const dependent = signalInterface.any([source]);
+ assert_true(source.reason instanceof DOMException);
+ assert_equals(source.reason, dependent.reason);
+ }, `Dependent signals for ${desc} should use the same DOMException instance from the already aborted source signal ${suffix}`);
+
+ test(t => {
+ const controller = new controllerInterface();
+ const source = controller.signal;
+ const dependent = signalInterface.any([source]);
+ controller.abort();
+ assert_true(source.reason instanceof DOMException);
+ assert_equals(source.reason, dependent.reason);
+ }, `Dependent signals for ${desc} should use the same DOMException instance from the source signal being aborted later ${suffix}`);
}
diff --git a/test/fixtures/wpt/interfaces/html.idl b/test/fixtures/wpt/interfaces/html.idl
index f7ad9ac2ddead5..25e1f8a4ca058e 100644
--- a/test/fixtures/wpt/interfaces/html.idl
+++ b/test/fixtures/wpt/interfaces/html.idl
@@ -125,6 +125,7 @@ interface HTMLElement : Element {
[CEReactions] attribute boolean spellcheck;
[CEReactions] attribute DOMString writingSuggestions;
[CEReactions] attribute DOMString autocapitalize;
+ [CEReactions] attribute boolean autocorrect;
[CEReactions] attribute [LegacyNullToEmptyString] DOMString innerText;
[CEReactions] attribute [LegacyNullToEmptyString] DOMString outerText;
diff --git a/test/fixtures/wpt/resource-timing/content-type-parsing.html b/test/fixtures/wpt/resource-timing/content-type-minimization.html
similarity index 65%
rename from test/fixtures/wpt/resource-timing/content-type-parsing.html
rename to test/fixtures/wpt/resource-timing/content-type-minimization.html
index c0081eb4137d9f..d7dbc2cc9f3b6a 100644
--- a/test/fixtures/wpt/resource-timing/content-type-parsing.html
+++ b/test/fixtures/wpt/resource-timing/content-type-minimization.html
@@ -1,6 +1,7 @@
+
This test validates the parsing of content-type of resources.
@@ -28,31 +29,33 @@
return "compatible";
}
-// Test for content-type parsing.
-const run_content_type_parsing_tests = (json_entries) => {
+// Test for mime-type minimization
+const run_mime_type_mimization_tests = (json_entries) => {
json_entries.forEach( (json_entry, i) => {
promise_test(async t => {
- let url = "/fetch/content-type/resources/content-type.py?single_header&";
- json_entry.contentType.forEach(val => {
- url += "value=" + encodeURIComponent(val) + "&";
- });
+ let identifier = Math.floor(Math.random() * 1000000000);
+ let url = `/fetch/content-type/resources/content-type.py?single_header&value=`+ encodeURIComponent(json_entry.input) + `&identifier=${identifier}`;
fetch(url);
const entry = await new Promise(resolve => new PerformanceObserver((entryList, observer) => {
- observer.disconnect();
- resolve(entryList.getEntries()[0]);
+ entryList.getEntries().forEach(e => {
+ if (e.name.includes(identifier)) {
+ resolve(e);
+ observer.disconnect();
+ }
+ });
}).observe({entryTypes: ['resource']}));
- assert_equals(entry.contentType, json_entry["mimeType"]);
- }, "content-type " + i + " : " + json_entry.contentType);
+ assert_equals(entry.contentType, json_entry.output);
+ }, "mime-type-minimized " + i + " : " + json_entry.input);
});
}
// Test for mime-type parsing.
-const run_mime_type_parsing_tests = (json_entries) => {
+const run_mime_type_parsing_and_minimization_tests = (json_entries) => {
json_entries.forEach( (val, i) => {
if(typeof val === "string" || val.navigable === undefined || isByteCompatible(val.input) !== "compatible") {
return;
}
- const output = val.output === null ? "" : val.output
+ const minimizedMIMEType = val.minimizedMIMEType;
promise_test(async t => {
let url = `/fetch/content-type/resources/content-type.py?single_header&value=${val.input}`;
fetch(url);
@@ -60,16 +63,16 @@
observer.disconnect();
resolve(entryList.getEntries()[0]);
}).observe({entryTypes: ['resource']}));
- assert_equals(entry.contentType, output);
+ assert_equals(entry.contentType, minimizedMIMEType);
}, "mime-type " + i + " : " + val.input);
});
}
Promise.all([
- fetch("/fetch/content-type/resources/content-types.json"),
+ fetch("/mimesniff/mime-types/resources/mime-types-minimized.json"),
fetch("/mimesniff/mime-types/resources/mime-types.json")
- ]).then(([res, res2]) => res.json().then(run_content_type_parsing_tests)
- .then(() => res2.json().then(run_mime_type_parsing_tests)));
+ ]).then(([res, res2]) => res.json().then(run_mime_type_mimization_tests)
+ .then(() => res2.json().then(run_mime_type_parsing_and_minimization_tests)));
diff --git a/test/fixtures/wpt/resource-timing/content-type.html b/test/fixtures/wpt/resource-timing/content-type.html
index 5a09a9114f2c28..654e083e14aa1f 100644
--- a/test/fixtures/wpt/resource-timing/content-type.html
+++ b/test/fixtures/wpt/resource-timing/content-type.html
@@ -42,11 +42,10 @@
}
const resource_loaders_and_types = [
- [load.font, ["font/woff", "font/otf"]],
[load.image, ["image/png", "image/jpg"]],
- [load.script, ["application/javascript", "text/javascript"]],
+ [load.script, ["text/javascript"]],
[load.stylesheet, ["text/css"]],
- [load.xhr_async, ["application/x-gzip", "application/pdf"]],
+ [load.xhr_async, ["image/png", "image/jpg"]],
[load.iframe, ["text/html"]]
];
@@ -77,7 +76,7 @@
const resource_loaders_with_attrs_and_types = [
[load.image_with_attrs, ["image/gif", "image/jpeg"]],
- [load.script_with_attrs, ["application/javascript", "text/javascript"]],
+ [load.script_with_attrs, ["text/javascript"]],
[load.stylesheet_with_attrs, ["text/css"]],
]
diff --git a/test/fixtures/wpt/resources/testdriver.js b/test/fixtures/wpt/resources/testdriver.js
index 985dbb0e4030aa..e737a6ee659f05 100644
--- a/test/fixtures/wpt/resources/testdriver.js
+++ b/test/fixtures/wpt/resources/testdriver.js
@@ -1128,7 +1128,7 @@
* deleted hosts.
*
* Matches the `Run Bounce Tracking Mitigations
- * https://privacycg.github.io/nav-tracking-mitigations/#run-bounce-tracking-mitigations-command`_
+ * `_
* WebDriver command.
*
* @param {WindowProxy} [context=null] - Browsing context in which to
diff --git a/test/fixtures/wpt/streams/readable-byte-streams/tee.any.js b/test/fixtures/wpt/streams/readable-byte-streams/tee.any.js
index 7dd5ba3f3fb013..60d82b9cf6a1fd 100644
--- a/test/fixtures/wpt/streams/readable-byte-streams/tee.any.js
+++ b/test/fixtures/wpt/streams/readable-byte-streams/tee.any.js
@@ -934,3 +934,36 @@ promise_test(async () => {
assert_typed_array_equals(result4.value, new Uint8Array([0]).subarray(0, 0), 'second chunk from branch2 should be correct');
}, 'ReadableStream teeing with byte source: respond() and close() while both branches are pulling');
+
+promise_test(async t => {
+ let pullCount = 0;
+ const arrayBuffer = new Uint8Array([0x01, 0x02, 0x03]).buffer;
+ const enqueuedChunk = new Uint8Array(arrayBuffer, 2);
+ assert_equals(enqueuedChunk.length, 1);
+ assert_equals(enqueuedChunk.byteOffset, 2);
+ const rs = new ReadableStream({
+ type: 'bytes',
+ pull(c) {
+ ++pullCount;
+ if (pullCount === 1) {
+ c.enqueue(enqueuedChunk);
+ }
+ }
+ });
+
+ const [branch1, branch2] = rs.tee();
+ const reader1 = branch1.getReader();
+ const reader2 = branch2.getReader();
+
+ const [result1, result2] = await Promise.all([reader1.read(), reader2.read()]);
+ assert_equals(result1.done, false, 'reader1 done');
+ assert_equals(result2.done, false, 'reader2 done');
+
+ const view1 = result1.value;
+ const view2 = result2.value;
+ // The first stream has the transferred buffer, but the second stream has the
+ // cloned buffer.
+ const underlying = new Uint8Array([0x01, 0x02, 0x03]).buffer;
+ assert_typed_array_equals(view1, new Uint8Array(underlying, 2), 'reader1 value');
+ assert_typed_array_equals(view2, new Uint8Array([0x03]), 'reader2 value');
+}, 'ReadableStream teeing with byte source: reading an array with a byte offset should clone correctly');
diff --git a/test/fixtures/wpt/streams/readable-streams/crashtests/from-cross-realm.https.html b/test/fixtures/wpt/streams/readable-streams/crashtests/from-cross-realm.https.html
new file mode 100644
index 00000000000000..58a4371186ece7
--- /dev/null
+++ b/test/fixtures/wpt/streams/readable-streams/crashtests/from-cross-realm.https.html
@@ -0,0 +1,18 @@
+
+
+
diff --git a/test/fixtures/wpt/url/resources/urltestdata.json b/test/fixtures/wpt/url/resources/urltestdata.json
index 91fcca2c3c2557..9dbe5456a96950 100644
--- a/test/fixtures/wpt/url/resources/urltestdata.json
+++ b/test/fixtures/wpt/url/resources/urltestdata.json
@@ -9643,6 +9643,201 @@
"search": "",
"hash": ""
},
+ {
+ "input": "android://x:0/a",
+ "base": null,
+ "href": "android://x:0/a",
+ "origin": "null",
+ "protocol": "android:",
+ "username": "",
+ "password": "",
+ "host": "x:0",
+ "hostname": "x",
+ "port": "0",
+ "pathname": "/a",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "drivefs://x:0/a",
+ "base": null,
+ "href": "drivefs://x:0/a",
+ "origin": "null",
+ "protocol": "drivefs:",
+ "username": "",
+ "password": "",
+ "host": "x:0",
+ "hostname": "x",
+ "port": "0",
+ "pathname": "/a",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "chromeos-steam://x:0/a",
+ "base": null,
+ "href": "chromeos-steam://x:0/a",
+ "origin": "null",
+ "protocol": "chromeos-steam:",
+ "username": "",
+ "password": "",
+ "host": "x:0",
+ "hostname": "x",
+ "port": "0",
+ "pathname": "/a",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "steam://x:0/a",
+ "base": null,
+ "href": "steam://x:0/a",
+ "origin": "null",
+ "protocol": "steam:",
+ "username": "",
+ "password": "",
+ "host": "x:0",
+ "hostname": "x",
+ "port": "0",
+ "pathname": "/a",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "materialized-view://x:0/a",
+ "base": null,
+ "href": "materialized-view://x:0/a",
+ "origin": "null",
+ "protocol": "materialized-view:",
+ "username": "",
+ "password": "",
+ "host": "x:0",
+ "hostname": "x",
+ "port": "0",
+ "pathname": "/a",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "android-app://x:0",
+ "base": null,
+ "href": "android-app://x:0",
+ "origin": "null",
+ "protocol": "android-app:",
+ "username": "",
+ "password": "",
+ "host": "x:0",
+ "hostname": "x",
+ "port": "0",
+ "pathname": "",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "chrome-distiller://x:0",
+ "base": null,
+ "href": "chrome-distiller://x:0",
+ "origin": "null",
+ "protocol": "chrome-distiller:",
+ "username": "",
+ "password": "",
+ "host": "x:0",
+ "hostname": "x",
+ "port": "0",
+ "pathname": "",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "chrome-extension://x:0",
+ "base": null,
+ "href": "chrome-extension://x:0",
+ "origin": "null",
+ "protocol": "chrome-extension:",
+ "username": "",
+ "password": "",
+ "host": "x:0",
+ "hostname": "x",
+ "port": "0",
+ "pathname": "",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "chrome-native://x:0",
+ "base": null,
+ "href": "chrome-native://x:0",
+ "origin": "null",
+ "protocol": "chrome-native:",
+ "username": "",
+ "password": "",
+ "host": "x:0",
+ "hostname": "x",
+ "port": "0",
+ "pathname": "",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "chrome-resource://x:0",
+ "base": null,
+ "href": "chrome-resource://x:0",
+ "origin": "null",
+ "protocol": "chrome-resource:",
+ "username": "",
+ "password": "",
+ "host": "x:0",
+ "hostname": "x",
+ "port": "0",
+ "pathname": "",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "chrome-search://x:0",
+ "base": null,
+ "href": "chrome-search://x:0",
+ "origin": "null",
+ "protocol": "chrome-search:",
+ "username": "",
+ "password": "",
+ "host": "x:0",
+ "hostname": "x",
+ "port": "0",
+ "pathname": "",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "fuchsia-dir://x:0",
+ "base": null,
+ "href": "fuchsia-dir://x:0",
+ "origin": "null",
+ "protocol": "fuchsia-dir:",
+ "username": "",
+ "password": "",
+ "host": "x:0",
+ "hostname": "x",
+ "port": "0",
+ "pathname": "",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "isolated-app://x:0",
+ "base": null,
+ "href": "isolated-app://x:0",
+ "origin": "null",
+ "protocol": "isolated-app:",
+ "username": "",
+ "password": "",
+ "host": "x:0",
+ "hostname": "x",
+ "port": "0",
+ "pathname": "",
+ "search": "",
+ "hash": ""
+ },
"Scheme relative path starting with multiple slashes",
{
"input": "///test",
diff --git a/test/fixtures/wpt/versions.json b/test/fixtures/wpt/versions.json
index 0744eb780de83a..a5d99fb4b1f807 100644
--- a/test/fixtures/wpt/versions.json
+++ b/test/fixtures/wpt/versions.json
@@ -12,7 +12,7 @@
"path": "console"
},
"dom/abort": {
- "commit": "07a9d09a8fbe95c2c2b439b6a88ef2499543133d",
+ "commit": "0143fe244b3d622441717ce630e0114eb204f9a7",
"path": "dom/abort"
},
"dom/events": {
@@ -28,7 +28,7 @@
"path": "fetch/data-urls/resources"
},
"FileAPI": {
- "commit": "1d5fb397da74f1afda7402602fec4255086d7a91",
+ "commit": "40a4e28f25db15d9f832ed02242a5f93240cfb38",
"path": "FileAPI"
},
"hr-time": {
@@ -52,7 +52,7 @@
"path": "html/webappapis/timers"
},
"interfaces": {
- "commit": "ab18bf796b7826552ed35b63594ff7f21e5c537c",
+ "commit": "4a48b52da3ab94049b772fe95c48fa53f654de5b",
"path": "interfaces"
},
"performance-timeline": {
@@ -60,19 +60,19 @@
"path": "performance-timeline"
},
"resource-timing": {
- "commit": "95e7763ca921c3e72d38311dc443c9505d6baec9",
+ "commit": "7bb012885ce064e8af126a277325b9091694afbf",
"path": "resource-timing"
},
"resources": {
- "commit": "ff5b1bc4dbcb933e6449413ab02ced5d3203b503",
+ "commit": "d9f17001dc685f563af09c4b2ef0b97921e5839b",
"path": "resources"
},
"streams": {
- "commit": "b5f2d0c48acd328036ac20101458a323cc084de7",
+ "commit": "699dbdae30ffe5e3628f4d088353ef80fcc2e37f",
"path": "streams"
},
"url": {
- "commit": "30de0890335d1b5547e25260393668d74755b006",
+ "commit": "08519e73d164a716152176a2a64417f4d58e5ea3",
"path": "url"
},
"user-timing": {
@@ -80,7 +80,7 @@
"path": "user-timing"
},
"wasm/jsapi": {
- "commit": "140f5c80fd2f1b31fc35026f200175ececbfd2d9",
+ "commit": "f427091001d8e21333c4a7ed1bfa10379f1f767d",
"path": "wasm/jsapi"
},
"wasm/webapi": {
diff --git a/test/fixtures/wpt/wasm/jsapi/js-string/basic.tentative.any.js b/test/fixtures/wpt/wasm/jsapi/js-string/basic.tentative.any.js
new file mode 100644
index 00000000000000..de4a21c976b583
--- /dev/null
+++ b/test/fixtures/wpt/wasm/jsapi/js-string/basic.tentative.any.js
@@ -0,0 +1,383 @@
+// META: global=window,dedicatedworker,jsshell,shadowrealm
+// META: script=/wasm/jsapi/assertions.js
+// META: script=/wasm/jsapi/wasm-module-builder.js
+// META: script=/wasm/jsapi/js-string/polyfill.js
+
+// Generate two sets of exports, one from a polyfill implementation and another
+// from the builtins provided by the host.
+let polyfillExports;
+let builtinExports;
+setup(() => {
+ // Compile a module that exports a function for each builtin that will call
+ // it. We could just generate a module that re-exports the builtins, but that
+ // would not catch any special codegen that could happen when direct calling
+ // a known builtin function from wasm.
+ const builder = new WasmModuleBuilder();
+ const arrayIndex = builder.addArray(kWasmI16, true, kNoSuperType, true);
+ const builtins = [
+ {
+ name: "test",
+ params: [kWasmExternRef],
+ results: [kWasmI32],
+ },
+ {
+ name: "cast",
+ params: [kWasmExternRef],
+ results: [wasmRefType(kWasmExternRef)],
+ },
+ {
+ name: "fromCharCodeArray",
+ params: [wasmRefNullType(arrayIndex), kWasmI32, kWasmI32],
+ results: [wasmRefType(kWasmExternRef)],
+ },
+ {
+ name: "intoCharCodeArray",
+ params: [kWasmExternRef, wasmRefNullType(arrayIndex), kWasmI32],
+ results: [kWasmI32],
+ },
+ {
+ name: "fromCharCode",
+ params: [kWasmI32],
+ results: [wasmRefType(kWasmExternRef)],
+ },
+ {
+ name: "fromCodePoint",
+ params: [kWasmI32],
+ results: [wasmRefType(kWasmExternRef)],
+ },
+ {
+ name: "charCodeAt",
+ params: [kWasmExternRef, kWasmI32],
+ results: [kWasmI32],
+ },
+ {
+ name: "codePointAt",
+ params: [kWasmExternRef, kWasmI32],
+ results: [kWasmI32],
+ },
+ {
+ name: "length",
+ params: [kWasmExternRef],
+ results: [kWasmI32],
+ },
+ {
+ name: "concat",
+ params: [kWasmExternRef, kWasmExternRef],
+ results: [wasmRefType(kWasmExternRef)],
+ },
+ {
+ name: "substring",
+ params: [kWasmExternRef, kWasmI32, kWasmI32],
+ results: [wasmRefType(kWasmExternRef)],
+ },
+ {
+ name: "equals",
+ params: [kWasmExternRef, kWasmExternRef],
+ results: [kWasmI32],
+ },
+ {
+ name: "compare",
+ params: [kWasmExternRef, kWasmExternRef],
+ results: [kWasmI32],
+ },
+ ];
+
+ // Add a function type for each builtin
+ for (let builtin of builtins) {
+ builtin.type = builder.addType({
+ params: builtin.params,
+ results: builtin.results
+ });
+ }
+
+ // Add an import for each builtin
+ for (let builtin of builtins) {
+ builtin.importFuncIndex = builder.addImport(
+ "wasm:js-string",
+ builtin.name,
+ builtin.type);
+ }
+
+ // Generate an exported function to call the builtin
+ for (let builtin of builtins) {
+ let func = builder.addFunction(builtin.name + "Imp", builtin.type);
+ func.addLocals(builtin.params.length);
+ let body = [];
+ for (let i = 0; i < builtin.params.length; i++) {
+ body.push(kExprLocalGet);
+ body.push(...wasmSignedLeb(i));
+ }
+ body.push(kExprCallFunction);
+ body.push(...wasmSignedLeb(builtin.importFuncIndex));
+ func.addBody(body);
+ func.exportAs(builtin.name);
+ }
+
+ const buffer = builder.toBuffer();
+
+ // Instantiate this module using the builtins from the host
+ const builtinModule = new WebAssembly.Module(buffer, {
+ builtins: ["js-string"]
+ });
+ const builtinInstance = new WebAssembly.Instance(builtinModule, {});
+ builtinExports = builtinInstance.exports;
+
+ // Instantiate this module using the polyfill module
+ const polyfillModule = new WebAssembly.Module(buffer);
+ const polyfillInstance = new WebAssembly.Instance(polyfillModule, {
+ "wasm:js-string": polyfillImports
+ });
+ polyfillExports = polyfillInstance.exports;
+});
+
+// A helper function to assert that the behavior of two functions are the
+// same.
+function assert_same_behavior(funcA, funcB, ...params) {
+ let resultA;
+ let errA = null;
+ try {
+ resultA = funcA(...params);
+ } catch (err) {
+ errA = err;
+ }
+
+ let resultB;
+ let errB = null;
+ try {
+ resultB = funcB(...params);
+ } catch (err) {
+ errB = err;
+ }
+
+ if (errA || errB) {
+ assert_equals(errA === null, errB === null, errA ? errA.message : errB.message);
+ assert_equals(Object.getPrototypeOf(errA), Object.getPrototypeOf(errB));
+ }
+ assert_equals(resultA, resultB);
+
+ if (errA) {
+ throw errA;
+ }
+ return resultA;
+}
+
+function assert_throws_if(func, shouldThrow, constructor) {
+ let error = null;
+ try {
+ func();
+ } catch (e) {
+ error = e;
+ }
+ assert_equals(error !== null, shouldThrow, "shouldThrow mismatch");
+ if (shouldThrow && error !== null) {
+ assert_true(error instanceof constructor);
+ }
+}
+
+// Constant values used in the tests below
+const testStrings = [
+ "",
+ "a",
+ "1",
+ "ab",
+ "hello, world",
+ "\n",
+ "☺",
+ "☺☺",
+ String.fromCodePoint(0x10000, 0x10001)
+];
+const testCharCodes = [1, 2, 3, 10, 0x7f, 0xff, 0xfffe, 0xffff];
+const testCodePoints = [1, 2, 3, 10, 0x7f, 0xff, 0xfffe, 0xffff, 0x10000, 0x10001];
+const testExternRefValues = [
+ null,
+ undefined,
+ true,
+ false,
+ {x:1337},
+ ["abracadabra"],
+ 13.37,
+ -0,
+ 0x7fffffff + 0.1,
+ -0x7fffffff - 0.1,
+ 0x80000000 + 0.1,
+ -0x80000000 - 0.1,
+ 0xffffffff + 0.1,
+ -0xffffffff - 0.1,
+ Number.EPSILON,
+ Number.MAX_SAFE_INTEGER,
+ Number.MIN_SAFE_INTEGER,
+ Number.MIN_VALUE,
+ Number.MAX_VALUE,
+ Number.NaN,
+ "hi",
+ 37n,
+ new Number(42),
+ new Boolean(true),
+ Symbol("status"),
+ () => 1337,
+];
+
+// Test that `test` and `cast` work on various JS values. Run all the
+// other builtins and assert that they also perform equivalent type
+// checks.
+test(() => {
+ for (let a of testExternRefValues) {
+ let isString = assert_same_behavior(
+ builtinExports['test'],
+ polyfillExports['test'],
+ a
+ );
+
+ assert_throws_if(() => assert_same_behavior(
+ builtinExports['cast'],
+ polyfillExports['cast'],
+ a
+ ), !isString, WebAssembly.RuntimeError);
+
+ let arrayMutI16 = helperExports.createArrayMutI16(10);
+ assert_throws_if(() => assert_same_behavior(
+ builtinExports['intoCharCodeArray'],
+ polyfillExports['intoCharCodeArray'],
+ a, arrayMutI16, 0
+ ), !isString, WebAssembly.RuntimeError);
+
+ assert_throws_if(() => assert_same_behavior(
+ builtinExports['charCodeAt'],
+ polyfillExports['charCodeAt'],
+ a, 0
+ ), !isString, WebAssembly.RuntimeError);
+
+ assert_throws_if(() => assert_same_behavior(
+ builtinExports['codePointAt'],
+ polyfillExports['codePointAt'],
+ a, 0
+ ), !isString, WebAssembly.RuntimeError);
+
+ assert_throws_if(() => assert_same_behavior(
+ builtinExports['length'],
+ polyfillExports['length'],
+ a
+ ), !isString, WebAssembly.RuntimeError);
+
+ assert_throws_if(() => assert_same_behavior(
+ builtinExports['concat'],
+ polyfillExports['concat'],
+ a, a
+ ), !isString, WebAssembly.RuntimeError);
+
+ assert_throws_if(() => assert_same_behavior(
+ builtinExports['substring'],
+ polyfillExports['substring'],
+ a, 0, 0
+ ), !isString, WebAssembly.RuntimeError);
+
+ assert_throws_if(() => assert_same_behavior(
+ builtinExports['equals'],
+ polyfillExports['equals'],
+ a, a
+ ), a !== null && !isString, WebAssembly.RuntimeError);
+
+ assert_throws_if(() => assert_same_behavior(
+ builtinExports['compare'],
+ polyfillExports['compare'],
+ a, a
+ ), !isString, WebAssembly.RuntimeError);
+ }
+});
+
+// Test that `fromCharCode` works on various char codes
+test(() => {
+ for (let a of testCharCodes) {
+ assert_same_behavior(
+ builtinExports['fromCharCode'],
+ polyfillExports['fromCharCode'],
+ a
+ );
+ }
+});
+
+// Test that `fromCodePoint` works on various code points
+test(() => {
+ for (let a of testCodePoints) {
+ assert_same_behavior(
+ builtinExports['fromCodePoint'],
+ polyfillExports['fromCodePoint'],
+ a
+ );
+ }
+});
+
+// Perform tests on various strings
+test(() => {
+ for (let a of testStrings) {
+ let length = assert_same_behavior(
+ builtinExports['length'],
+ polyfillExports['length'],
+ a
+ );
+
+ for (let i = 0; i < length; i++) {
+ let charCode = assert_same_behavior(
+ builtinExports['charCodeAt'],
+ polyfillExports['charCodeAt'],
+ a, i
+ );
+ }
+
+ for (let i = 0; i < length; i++) {
+ let charCode = assert_same_behavior(
+ builtinExports['codePointAt'],
+ polyfillExports['codePointAt'],
+ a, i
+ );
+ }
+
+ let arrayMutI16 = helperExports.createArrayMutI16(length);
+ assert_same_behavior(
+ builtinExports['intoCharCodeArray'],
+ polyfillExports['intoCharCodeArray'],
+ a, arrayMutI16, 0
+ );
+
+ assert_same_behavior(
+ builtinExports['fromCharCodeArray'],
+ polyfillExports['fromCharCodeArray'],
+ arrayMutI16, 0, length
+ );
+
+ for (let i = 0; i < length; i++) {
+ for (let j = 0; j < length; j++) {
+ assert_same_behavior(
+ builtinExports['substring'],
+ polyfillExports['substring'],
+ a, i, j
+ );
+ }
+ }
+ }
+});
+
+// Test various binary operations
+test(() => {
+ for (let a of testStrings) {
+ for (let b of testStrings) {
+ assert_same_behavior(
+ builtinExports['concat'],
+ polyfillExports['concat'],
+ a, b
+ );
+
+ assert_same_behavior(
+ builtinExports['equals'],
+ polyfillExports['equals'],
+ a, b
+ );
+
+ assert_same_behavior(
+ builtinExports['compare'],
+ polyfillExports['compare'],
+ a, b
+ );
+ }
+ }
+});
diff --git a/test/fixtures/wpt/wasm/jsapi/js-string/constants.tentative.any.js b/test/fixtures/wpt/wasm/jsapi/js-string/constants.tentative.any.js
new file mode 100644
index 00000000000000..ef391a90b7ae7c
--- /dev/null
+++ b/test/fixtures/wpt/wasm/jsapi/js-string/constants.tentative.any.js
@@ -0,0 +1,61 @@
+// META: global=window,dedicatedworker,jsshell,shadowrealm
+// META: script=/wasm/jsapi/wasm-module-builder.js
+
+// Instantiate a module with an imported global and return the global.
+function instantiateImportedGlobal(module, name, type, mutable, importedStringConstants) {
+ let builder = new WasmModuleBuilder();
+ builder.addImportedGlobal(module, name, type, mutable);
+ builder.addExportOfKind("global", kExternalGlobal, 0);
+ let bytes = builder.toBuffer();
+ let mod = new WebAssembly.Module(bytes, { importedStringConstants });
+ let instance = new WebAssembly.Instance(mod, {});
+ return instance.exports["global"];
+}
+
+const badGlobalTypes = [
+ [kWasmAnyRef, false],
+ [kWasmAnyRef, true],
+ [wasmRefType(kWasmAnyRef), false],
+ [wasmRefType(kWasmAnyRef), true],
+ [kWasmFuncRef, false],
+ [kWasmFuncRef, true],
+ [wasmRefType(kWasmFuncRef), false],
+ [wasmRefType(kWasmFuncRef), true],
+ [kWasmExternRef, true],
+ [wasmRefType(kWasmExternRef), true],
+];
+for ([type, mutable] of badGlobalTypes) {
+ test(() => {
+ assert_throws_js(WebAssembly.CompileError,
+ () => instantiateImportedGlobal("'", "constant", type, mutable, "'"),
+ "type mismatch");
+ });
+}
+
+const goodGlobalTypes = [
+ [kWasmExternRef, false],
+ [wasmRefType(kWasmExternRef), false],
+];
+const constants = [
+ '',
+ '\0',
+ '0',
+ '0'.repeat(100000),
+ '\uD83D\uDE00',
+];
+const namespaces = [
+ "",
+ "'",
+ "strings"
+];
+
+for (let namespace of namespaces) {
+ for (let constant of constants) {
+ for ([type, mutable] of goodGlobalTypes) {
+ test(() => {
+ let result = instantiateImportedGlobal(namespace, constant, type, mutable, namespace);
+ assert_equals(result.value, constant);
+ });
+ }
+ }
+}
diff --git a/test/fixtures/wpt/wasm/jsapi/js-string/imports.tentative.any.js b/test/fixtures/wpt/wasm/jsapi/js-string/imports.tentative.any.js
new file mode 100644
index 00000000000000..c357760befb6c3
--- /dev/null
+++ b/test/fixtures/wpt/wasm/jsapi/js-string/imports.tentative.any.js
@@ -0,0 +1,26 @@
+// META: global=window,dedicatedworker,jsshell,shadowrealm
+// META: script=/wasm/jsapi/wasm-module-builder.js
+
+test(() => {
+ let builder = new WasmModuleBuilder();
+
+ // Import a string constant
+ builder.addImportedGlobal("constants", "constant", kWasmExternRef, false);
+
+ // Import a builtin function
+ builder.addImport(
+ "wasm:js-string",
+ "test",
+ {params: [kWasmExternRef], results: [kWasmI32]});
+
+ let buffer = builder.toBuffer();
+ let module = new WebAssembly.Module(buffer, {
+ builtins: ["js-string"],
+ importedStringConstants: "constants"
+ });
+ let imports = WebAssembly.Module.imports(module);
+
+ // All imports that refer to a builtin module are suppressed from import
+ // reflection.
+ assert_equals(imports.length, 0);
+});
diff --git a/test/fixtures/wpt/wasm/jsapi/js-string/polyfill.js b/test/fixtures/wpt/wasm/jsapi/js-string/polyfill.js
new file mode 100644
index 00000000000000..7a00d4285d7a26
--- /dev/null
+++ b/test/fixtures/wpt/wasm/jsapi/js-string/polyfill.js
@@ -0,0 +1,170 @@
+// Generate some helper functions for manipulating (array (mut i16)) from JS
+let helperExports;
+{
+ const builder = new WasmModuleBuilder();
+ const arrayIndex = builder.addArray(kWasmI16, true, kNoSuperType, true);
+
+ builder
+ .addFunction("createArrayMutI16", {
+ params: [kWasmI32],
+ results: [kWasmAnyRef]
+ })
+ .addBody([
+ kExprLocalGet,
+ ...wasmSignedLeb(0),
+ ...GCInstr(kExprArrayNewDefault),
+ ...wasmSignedLeb(arrayIndex)
+ ])
+ .exportFunc();
+
+ builder
+ .addFunction("arrayLength", {
+ params: [kWasmArrayRef],
+ results: [kWasmI32]
+ })
+ .addBody([
+ kExprLocalGet,
+ ...wasmSignedLeb(0),
+ ...GCInstr(kExprArrayLen)
+ ])
+ .exportFunc();
+
+ builder
+ .addFunction("arraySet", {
+ params: [wasmRefNullType(arrayIndex), kWasmI32, kWasmI32],
+ results: []
+ })
+ .addBody([
+ kExprLocalGet,
+ ...wasmSignedLeb(0),
+ kExprLocalGet,
+ ...wasmSignedLeb(1),
+ kExprLocalGet,
+ ...wasmSignedLeb(2),
+ ...GCInstr(kExprArraySet),
+ ...wasmSignedLeb(arrayIndex)
+ ])
+ .exportFunc();
+
+ builder
+ .addFunction("arrayGet", {
+ params: [wasmRefNullType(arrayIndex), kWasmI32],
+ results: [kWasmI32]
+ })
+ .addBody([
+ kExprLocalGet,
+ ...wasmSignedLeb(0),
+ kExprLocalGet,
+ ...wasmSignedLeb(1),
+ ...GCInstr(kExprArrayGetU),
+ ...wasmSignedLeb(arrayIndex)
+ ])
+ .exportFunc();
+
+ let bytes = builder.toBuffer();
+ let module = new WebAssembly.Module(bytes);
+ let instance = new WebAssembly.Instance(module);
+
+ helperExports = instance.exports;
+}
+
+function throwIfNotString(a) {
+ if (typeof a !== "string") {
+ throw new WebAssembly.RuntimeError();
+ }
+}
+
+this.polyfillImports = {
+ test: (string) => {
+ if (string === null ||
+ typeof string !== "string") {
+ return 0;
+ }
+ return 1;
+ },
+ cast: (string) => {
+ throwIfNotString(string);
+ return string;
+ },
+ fromCharCodeArray: (array, arrayStart, arrayCount) => {
+ arrayStart >>>= 0;
+ arrayCount >>>= 0;
+ let length = helperExports.arrayLength(array);
+ if (BigInt(arrayStart) + BigInt(arrayCount) > BigInt(length)) {
+ throw new WebAssembly.RuntimeError();
+ }
+ let result = '';
+ for (let i = arrayStart; i < arrayStart + arrayCount; i++) {
+ result += String.fromCharCode(helperExports.arrayGet(array, i));
+ }
+ return result;
+ },
+ intoCharCodeArray: (string, arr, arrayStart) => {
+ arrayStart >>>= 0;
+ throwIfNotString(string);
+ let arrLength = helperExports.arrayLength(arr);
+ let stringLength = string.length;
+ if (BigInt(arrayStart) + BigInt(stringLength) > BigInt(arrLength)) {
+ throw new WebAssembly.RuntimeError();
+ }
+ for (let i = 0; i < stringLength; i++) {
+ helperExports.arraySet(arr, arrayStart + i, string[i].charCodeAt(0));
+ }
+ return stringLength;
+ },
+ fromCharCode: (charCode) => {
+ charCode >>>= 0;
+ return String.fromCharCode(charCode);
+ },
+ fromCodePoint: (codePoint) => {
+ codePoint >>>= 0;
+ return String.fromCodePoint(codePoint);
+ },
+ charCodeAt: (string, stringIndex) => {
+ stringIndex >>>= 0;
+ throwIfNotString(string);
+ if (stringIndex >= string.length)
+ throw new WebAssembly.RuntimeError();
+ return string.charCodeAt(stringIndex);
+ },
+ codePointAt: (string, stringIndex) => {
+ stringIndex >>>= 0;
+ throwIfNotString(string);
+ if (stringIndex >= string.length)
+ throw new WebAssembly.RuntimeError();
+ return string.codePointAt(stringIndex);
+ },
+ length: (string) => {
+ throwIfNotString(string);
+ return string.length;
+ },
+ concat: (stringA, stringB) => {
+ throwIfNotString(stringA);
+ throwIfNotString(stringB);
+ return stringA + stringB;
+ },
+ substring: (string, startIndex, endIndex) => {
+ startIndex >>>= 0;
+ endIndex >>>= 0;
+ throwIfNotString(string);
+ if (startIndex > string.length,
+ endIndex > string.length,
+ endIndex < startIndex) {
+ return "";
+ }
+ return string.substring(startIndex, endIndex);
+ },
+ equals: (stringA, stringB) => {
+ if (stringA !== null) throwIfNotString(stringA);
+ if (stringB !== null) throwIfNotString(stringB);
+ return stringA === stringB;
+ },
+ compare: (stringA, stringB) => {
+ throwIfNotString(stringA);
+ throwIfNotString(stringB);
+ if (stringA < stringB) {
+ return -1;
+ }
+ return stringA === stringB ? 0 : 1;
+ },
+};
diff --git a/test/fixtures/wpt/wasm/jsapi/table/constructor.any.js b/test/fixtures/wpt/wasm/jsapi/table/constructor.any.js
index 51b1070d413586..1143bab72a26ce 100644
--- a/test/fixtures/wpt/wasm/jsapi/table/constructor.any.js
+++ b/test/fixtures/wpt/wasm/jsapi/table/constructor.any.js
@@ -206,3 +206,8 @@ test(() => {
assert_throws_js(TypeError, () => new WebAssembly.Table(argument, "cannot be used as a wasm function"));
assert_throws_js(TypeError, () => new WebAssembly.Table(argument, 37));
}, "initialize anyfunc table with a bad default value");
+
+test(() => {
+ assert_throws_js(RangeError, () =>
+ new WebAssembly.Table({ "element": "anyfunc", "initial": 3, "maximum": 2 }, 37));
+}, "initialize anyfunc table with a bad default value and a bad descriptor");
diff --git a/test/fixtures/wpt/wasm/jsapi/wasm-module-builder.js b/test/fixtures/wpt/wasm/jsapi/wasm-module-builder.js
index 1d8db0a6e6fd71..90ccc954a5dba3 100644
--- a/test/fixtures/wpt/wasm/jsapi/wasm-module-builder.js
+++ b/test/fixtures/wpt/wasm/jsapi/wasm-module-builder.js
@@ -105,6 +105,10 @@ let kWasmF32 = 0x7d;
let kWasmF64 = 0x7c;
let kWasmS128 = 0x7b;
+// Packed storage types
+let kWasmI8 = 0x78;
+let kWasmI16 = 0x77;
+
// These are defined as negative integers to distinguish them from positive type
// indices.
let kWasmNullFuncRef = -0x0d;
@@ -1152,7 +1156,7 @@ class WasmModuleBuilder {
section.emit_string(imp.name || '');
section.emit_u8(imp.kind);
if (imp.kind == kExternalFunction) {
- section.emit_u32v(imp.type_index);
+ section.emit_u32v(imp.type);
} else if (imp.kind == kExternalGlobal) {
section.emit_type(imp.type);
section.emit_u8(imp.mutable);
diff --git a/test/wpt/status/FileAPI/blob.json b/test/wpt/status/FileAPI/blob.json
index 8ea03bbc019992..2cdc267f0af840 100644
--- a/test/wpt/status/FileAPI/blob.json
+++ b/test/wpt/status/FileAPI/blob.json
@@ -17,6 +17,7 @@
"ArrayBuffer elements of the blobParts array should be supported.",
"Passing typed arrays as elements of the blobParts array should work.",
"Passing a Float64Array as element of the blobParts array should work.",
+ "Passing a Float16Array as element of the blobParts array should work.",
"Passing BigInt typed arrays as elements of the blobParts array should work.",
"Array with two blobs",
"Array with two buffers",
diff --git a/test/wpt/status/WebCryptoAPI.json b/test/wpt/status/WebCryptoAPI.json
new file mode 100644
index 00000000000000..3cc9a4a838a6f8
--- /dev/null
+++ b/test/wpt/status/WebCryptoAPI.json
@@ -0,0 +1,16 @@
+{
+ "algorithm-discards-context.https.window.js": {
+ "skip": "Not relevant in Node.js context"
+ },
+ "historical.any.js": {
+ "skip": "Not relevant in Node.js context"
+ },
+ "getRandomValues.any.js": {
+ "fail": {
+ "note": "These types do not exist in Node.js",
+ "expected": [
+ "Float16 arrays"
+ ]
+ }
+ }
+}
diff --git a/test/wpt/status/html/webappapis/timers.json b/test/wpt/status/html/webappapis/timers.json
index 21e77a089d5ca7..ee467f5384d03f 100644
--- a/test/wpt/status/html/webappapis/timers.json
+++ b/test/wpt/status/html/webappapis/timers.json
@@ -1,5 +1,8 @@
{
"negative-settimeout.any.js": {
"skip": "unreliable in Node.js; Refs: https://github.com/nodejs/node/issues/37672"
+ },
+ "evil-spec-example.any.js": {
+ "skip": "Node.js does not support a string as a parameter to setTimeout"
}
}
diff --git a/test/wpt/status/performance-timeline.json b/test/wpt/status/performance-timeline.json
index 73e1aad56cf707..5ce28d5730767a 100644
--- a/test/wpt/status/performance-timeline.json
+++ b/test/wpt/status/performance-timeline.json
@@ -7,6 +7,9 @@
]
}
},
+ "droppedentriescount.any.js": {
+ "skip": "Node.js cannot open files with query params"
+ },
"idlharness.any.js": {
"fail": {
"note": "not implemented",
@@ -21,5 +24,55 @@
},
"webtiming-resolution.any.js": {
"skip": "flaky"
+ },
+ "not-restored-reasons/performance-navigation-timing-attributes.tentative.window.js": {
+ "skip": "Depends on HTML WebPlatformTests"
+ },
+ "not-restored-reasons/performance-navigation-timing-bfcache-reasons-stay.tentative.window.js": {
+ "skip": "Depends on HTML WebPlatformTests"
+ },
+ "not-restored-reasons/performance-navigation-timing-bfcache.tentative.window.js": {
+ "skip": "Depends on HTML WebPlatformTests"
+ },
+ "not-restored-reasons/performance-navigation-timing-cross-origin-bfcache.tentative.window.js": {
+ "skip": "Depends on HTML WebPlatformTests"
+ },
+ "not-restored-reasons/performance-navigation-timing-fetch.tentative.window.js": {
+ "skip": "Depends on HTML WebPlatformTests"
+ },
+ "not-restored-reasons/performance-navigation-timing-iframes-without-attributes.tentative.window.js": {
+ "skip": "Depends on HTML WebPlatformTests"
+ },
+ "not-restored-reasons/performance-navigation-timing-lock.https.tentative.window.js": {
+ "skip": "Depends on HTML WebPlatformTests"
+ },
+ "not-restored-reasons/performance-navigation-timing-navigation-failure.tentative.window.js": {
+ "skip": "Depends on HTML WebPlatformTests"
+ },
+ "not-restored-reasons/performance-navigation-timing-not-bfcached.tentative.window.js": {
+ "skip": "Depends on HTML WebPlatformTests"
+ },
+ "not-restored-reasons/performance-navigation-timing-redirect-on-history.tentative.window.js": {
+ "skip": "Depends on HTML WebPlatformTests"
+ },
+ "not-restored-reasons/performance-navigation-timing-reload.tentative.window.js": {
+ "skip": "Depends on HTML WebPlatformTests"
+ },
+ "not-restored-reasons/performance-navigation-timing-same-origin-bfcache.tentative.window.js": {
+ "skip": "Depends on HTML WebPlatformTests"
+ },
+ "not-restored-reasons/performance-navigation-timing-same-origin-replace.tentative.window.js": {
+ "skip": "Depends on HTML WebPlatformTests"
+ },
+ "idlharness-shadowrealm.window.js": {
+ "skip": "Requires ShadowRealm"
+ },
+ "not-restored-reasons/abort-block-bfcache.window.js": {
+ "fail": {
+ "note": "Requires 'window.stop()'",
+ "expected": [
+ "aborting a parser should block bfcache."
+ ]
+ }
}
}
diff --git a/test/wpt/status/resource-timing.json b/test/wpt/status/resource-timing.json
index f40f8fe51da117..a0dbbb764362af 100644
--- a/test/wpt/status/resource-timing.json
+++ b/test/wpt/status/resource-timing.json
@@ -20,6 +20,9 @@
"buffered-flag.any.js": {
"skip": "Browser-specific test"
},
+ "delivery-type.tentative.any.js": {
+ "skip": "Browser-specific test"
+ },
"idlharness.any.js": {
"fail": {
"expected": [
diff --git a/test/wpt/status/webstorage.json b/test/wpt/status/webstorage.json
index 4ecdb2721bd24b..10171601480aad 100644
--- a/test/wpt/status/webstorage.json
+++ b/test/wpt/status/webstorage.json
@@ -8,6 +8,9 @@
"localstorage-cross-origin-iframe.tentative.https.window.js": {
"skip": "iframes are not supported in Node.js."
},
+ "localstorage-cross-origin-iframe.https.window.js": {
+ "skip": "iframes are not supported in Node.js."
+ },
"storage_local_window_open.window.js": {
"skip": "window.open() is not supported in Node.js."
},