Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added WebAssembly features #452

Merged
merged 6 commits into from
Jun 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions custom/wasm.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"features": {
"BigInt-to-i64-integration": {
"wfd-key": "bigInt"
},
Comment on lines +3 to +5
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think that we should just simplify this to be "bcd-key": "wfd-key"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No strong preference. I did it this way so that in the future, we can add more configuration fields, but that might not be necessary.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured that was the case, but I wasn't sure if you had any configuration options in mind -- I'll leave the format as-is just in case!

"bulk-memory-operations": {
"wfd-key": "bulkMemory"
},
"extended-constant-expressions": {
"wfd-key": "extendedConst"
},
"multi-value": {
"wfd-key": "multiValue"
},
"mutable-globals": {
"wfd-key": "mutableGlobals"
},
"reference-types": {
"wfd-key": "referenceTypes"
},
"non-trapping-float-to-int-conversions": {
"wfd-key": "saturatedFloatToInt"
},
"sign-extension-operations": {
"wfd-key": "signExtensions"
},
"fixed-width-SIMD": {
"wfd-key": "simd"
},
"tail-calls": {
"wfd-key": "tailCall"
},
"exception-handling": {
"wfd-key": "exceptions"
},
"garbage-collection": {
"wfd-key": "gc"
},
"memory64": {
"wfd-key": "memory64"
},
"relaxed-SIMD": {
"wfd-key": "relaxedSimd"
},
"threads-and-atomics": {
"wfd-key": "threads"
}
}
}
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"slugify": "1.6.6",
"ua-parser-js": "1.0.35",
"unique-string": "3.0.0",
"wasm-feature-detect": "^1.5.1",
"winston": "3.9.0",
"yargs": "17.7.2"
},
Expand Down
5 changes: 5 additions & 0 deletions prepare-resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ const copyResources = async () => {
['@mdi/font/fonts/materialdesignicons-webfont.woff2', 'fonts'],
['highlight.js/styles/stackoverflow-dark.css', 'resources/highlight.js'],
['highlight.js/styles/stackoverflow-light.css', 'resources/highlight.js'],
[
'wasm-feature-detect/dist/umd/index.js',
'resources',
'wasm-feature-detect.js',
],
];
for (const [srcInModules, destInGenerated, newFilename] of resources) {
const src = fileURLToPath(
Expand Down
157 changes: 128 additions & 29 deletions static/resources/harness.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

/* global console, document, window, location, navigator, XMLHttpRequest,
self, Worker, Promise, setTimeout, clearTimeout, MessageChannel,
SharedWorker, hljs */
SharedWorker, hljs, wasmFeatureDetect */

// This harness should work on as old browsers as possible and shouldn't depend
// on any modern JavaScript features.
Expand Down Expand Up @@ -500,6 +500,26 @@
return { result: null, message: "Detection methods are not supported" };
}

/**
* Test a web assembly feature for support, using the `wasm-feature-detect` Node package
*
* feature (string): The web assembly feature name as defined in `wasm-feature-detect`
*
* returns (TestResult): Whether the web assembly feature is supported
*/
function testWasmFeature(feature) {
if (!("wasmFeatureDetect" in self)) {
return { result: null, message: "Failed to load wasm-feature-detect" };
}
if (!(feature in wasmFeatureDetect)) {
return {
result: false,
message: feature + " is not present in wasm-feature-detect"
};
}
return wasmFeatureDetect[feature]();
}

/**
* Once a test is evaluated and run, it calls this function with the result.
* This function then compiles a result object from the given result value,
Expand Down Expand Up @@ -960,6 +980,76 @@
}
}

/**
* Run all of the pending tests under the WebAssembly exposure if any
*
* callback (function): The callback to call once function completes
*
* returns (void)
* callback (TestResults): The processed result of the tests
*
*/
function runWebAssembly(callback) {
var fallback = function (message, value) {
/* c8 ignore start */
var results = [];
for (var i = 0; i < pending.WebAssembly.length; i++) {
var result = {
name: pending.WebAssembly[i].name,
result: value,
message: message,
info: {
exposure: "WebAssembly"
}
};

if (pending.WebAssembly[i].info !== undefined) {
result.info = Object.assign(
{},
result.info,
pending.WebAssembly[i].info
);
}

results.push(result);
}

callback(results);
/* c8 ignore stop */
};

if (pending.WebAssembly) {
updateStatus("Running tests for Web Assembly...");
if ("WebAssembly" in self) {
try {
// Load wasm-feature-detect
var wfdScript = document.createElement("script");
wfdScript.src = "/resources/wasm-feature-detect.js";
document.body.appendChild(wfdScript);

wfdScript.onload = function () {
runTests(pending.WebAssembly, callback);
};

wfdScript.onError = function () {
// If anything fails with loading, set all WASM features to null
fallback("Failed to load wasm-feature-detect", null);
};
} catch (e) {
// If anything fails with loading, set all WASM features to null
fallback("Failed to load wasm-feature-detect", null);
}
} else {
/* c8 ignore start */
updateStatus("No web assembly support, skipping WebAssembly tests");
fallback("No web assembly support", false);
/* c8 ignore stop */
}
} else {
callback([]);
}
}

/**
* Load all resources
*
Expand Down Expand Up @@ -1128,40 +1218,48 @@
state.timedout = true;
}, 20000);

runWindow(function (results) {
allresults = allresults.concat(results);

runWorker(function (results) {
allresults = allresults.concat(results);
var scopes = [
runWindow,
runWorker,
runSharedWorker,
runServiceWorker,
runWebAssembly
];
var currentScope = 0;

var allFinished = function () {
pending = {};
state.completed = true;
state.timedout = false;
clearTimeout(timeout);

runSharedWorker(function (results) {
allresults = allresults.concat(results);
for (var i = 0; i < cleanupFunctions.length; i++) {
cleanupFunctions[i]();
}

runServiceWorker(function (results) {
allresults = allresults.concat(results);
if ("serviceWorker" in navigator) {
window.__workerCleanup();
}

pending = {};
state.completed = true;
state.timedout = false;
clearTimeout(timeout);
if (typeof onComplete == "function") {
onComplete(allresults);
} else {
report(allresults, hideResults);
}
};

for (var i = 0; i < cleanupFunctions.length; i++) {
cleanupFunctions[i]();
}
var scopeFinished = function (results) {
allresults = allresults.concat(results);
currentScope++;

if ("serviceWorker" in navigator) {
window.__workerCleanup();
}
if (currentScope >= scopes.length) {
allFinished();
} else {
scopes[currentScope](scopeFinished);
}
};

if (typeof onComplete == "function") {
onComplete(allresults);
} else {
report(allresults, hideResults);
}
});
});
});
});
scopes[0](scopeFinished);
}

/**
Expand Down Expand Up @@ -1581,6 +1679,7 @@
testObjectName: testObjectName,
testOptionParam: testOptionParam,
testCSSProperty: testCSSProperty,
testWasmFeature: testWasmFeature,
addInstance: addInstance,
addTest: addTest,
addCleanup: addCleanup,
Expand Down
6 changes: 6 additions & 0 deletions test-builder/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import customIDL from '../custom/idl/index.js';
import {build as buildAPI} from './api.js';
import {build as buildCSS} from './css.js';
import {build as buildJS} from './javascript.js';
import {build as buildWasm} from './webassembly.js';
import {customTests} from './common.js';

import type {IDLFiles} from '../types/types.js';
Expand All @@ -26,6 +27,9 @@ const customCSS = await fs.readJson(
const customJS = await fs.readJson(
new URL('../custom/js.json', import.meta.url),
);
const customWasm = await fs.readJson(
new URL('../custom/wasm.json', import.meta.url),
);

/* c8 ignore start */
const build = async (customIDL: IDLFiles, customCSS) => {
Expand All @@ -35,11 +39,13 @@ const build = async (customIDL: IDLFiles, customCSS) => {
const APITests = buildAPI(specIDLs, customIDL);
const CSSTests = buildCSS(specCSS, customCSS);
const JSTests = buildJS(customJS);
const WasmTests = buildWasm(customWasm);
const tests = Object.assign(
{__resources: customTests.__resources},
APITests,
CSSTests,
JSTests,
WasmTests,
);

await fs.writeJson(new URL('../tests.json', import.meta.url), tests);
Expand Down
27 changes: 27 additions & 0 deletions test-builder/webassembly.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// mdn-bcd-collector: test-builder/webassembly.ts
// Functions directly related to building all of the WebAssembly tests
//
// © Gooborg Studios, Google LLC, Mozilla Corporation, Apple Inc
// See the LICENSE file for copyright details
//

import {compileTest} from './common.js';

const build = (customWasm) => {
const features = Object.entries(customWasm.features) as any[];

const tests = {};
for (const [feature, details] of features) {
const path = ['webassembly', 'features', feature].join('.');
tests[path] = compileTest({
raw: {
// 'wfd-key' stands for 'wasm-feature-detect key'
code: `bcd.testWasmFeature('${details['wfd-key']}')`,
},
exposure: ['WebAssembly'],
});
}
return tests;
};
export {build};
7 changes: 6 additions & 1 deletion types/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ import type * as WebIDL2 from 'webidl2';

export type InternalSupportStatement = SupportStatement | 'mirror';

export type Exposure = 'Window' | 'Worker' | 'SharedWorker' | 'ServiceWorker';
export type Exposure =
| 'Window'
| 'Worker'
| 'SharedWorker'
| 'ServiceWorker'
| 'WebAssembly';

export type Resource =
| {
Expand Down