Skip to content

Commit

Permalink
Adding feature detection table publish script
Browse files Browse the repository at this point in the history
  • Loading branch information
kelnishi committed Nov 18, 2024
1 parent 12ff17e commit 35007d2
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 5 deletions.
5 changes: 4 additions & 1 deletion Feature.Detect/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,7 @@ temp/


#generated files
/generated-wasm/**
/generated-wasm/**

#test run
/TestResults/**
15 changes: 14 additions & 1 deletion Feature.Detect/FeatureJson/FeatureJson.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
// * limitations under the License.
// */

using System.Text;
using System.Text.Json.Serialization;
using Microsoft.Extensions.Primitives;

namespace Feature.Detect.FeatureJson;

Expand All @@ -25,6 +27,9 @@ public class FeatureJson

public string? Path { get; set; }

[JsonPropertyName("id")]
public string? Id { get; set; }

[JsonPropertyName("module")]
public string? Module { get; set; }

Expand All @@ -42,7 +47,15 @@ public class FeatureJson

public override string ToString()
{
return $"Name: {Name}\n Proposal: {Proposal}\n Features: {string.Join(", ", Features ?? new List<string>())}\n Module: {Module}\n Options: {Options}";
var feats = (Features ?? new List<string>()).Select(f => $"\"{f}\"");
var sb = new StringBuilder();
sb.Append("{")
.Append("\"Name\": \"").Append(Name).Append("\",\n")
.Append("\"Proposal\": \"").Append(Proposal).Append("\",\n")
.Append("\"Features\": [").Append(string.Join(", ", feats)).Append("],\n")
.Append("\"Id\": \"").Append(Id).Append("\"\n")
.Append("}");
return sb.ToString();
}

}
Expand Down
6 changes: 6 additions & 0 deletions Feature.Detect/build_feature_detect.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,9 @@ for dir in "$PARENT_DIR"/*/; do
node convert_detector.mjs "$dir" "$OUTPUT_DIR"
fi
done

#run detection
dotnet test --logger "trx;LogFileName=TestResults.trx"

#publish support matrix
node trx-to-markdown.js TestResults/TestResults.trx ../features.md
5 changes: 5 additions & 0 deletions Feature.Detect/convert_detector.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ async function processWatFile(watPath, outputBasePath) {
const metadata = {
source: 'wat2wasm',
timestamp: new Date().toISOString(),
id: outputFileName,
module: outputFilename,
...proposalInfo,
};
Expand Down Expand Up @@ -150,6 +151,7 @@ const handler = {
// console.log(`Checking presence of property "${String(prop)}" in WebAssembly`);
writeMetadata({
source: `"${String(prop)}" in WebAssembly`,
id: outputFileName,
}, indexPath);

// Return the result of the default behavior
Expand All @@ -165,6 +167,7 @@ webAssemblyProxy.Module = function(bufferSource) {
const outfile = writeWasmBuffer(bufferSource, 'Module', indexPath);
writeMetadata({
source: 'WebAssembly.Module',
id: outputFileName,
module: outfile,
}, indexPath);

Expand All @@ -177,6 +180,7 @@ webAssemblyProxy.instantiate = function(bufferSource, importObject, options) {

const metadata = {
source: 'WebAssembly.instantiate',
id: outputFileName,
module: outfile,
options: options || {},
};
Expand All @@ -191,6 +195,7 @@ webAssemblyProxy.validate = function(bufferSource) {

const metadata = {
source: 'WebAssembly.validate',
id: outputFileName,
module: outfile,
};

Expand Down
4 changes: 3 additions & 1 deletion Feature.Detect/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"dependencies": {
"wabt": "^1.0.36"
"he": "^1.2.0",
"wabt": "^1.0.36",
"xml2js": "^0.6.2"
}
}
84 changes: 84 additions & 0 deletions Feature.Detect/trx-to-markdown.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
const fs = require('fs').promises;
const xml2js = require('xml2js');
const path = require('path');
const he = require("he");

class TrxToMarkdown {
constructor() {
this.parser = new xml2js.Parser();
}

async convertFile(inputPath, outputPath) {
try {
const xmlData = await fs.readFile(inputPath, 'utf8');
const result = await this.parser.parseStringPromise(xmlData);
const markdown = this.generateMarkdown(result);
await fs.writeFile(outputPath, markdown);
console.log(`Successfully converted ${inputPath} to ${outputPath}`);
} catch (error) {
console.error('Error converting file:', error);
throw error;
}
}

generateMarkdown(trxData) {
const testRun = trxData.TestRun;
const results = testRun.Results[0].UnitTestResult;

let tests = [];
results.forEach(result => {
const test = result['$'];
const jsonStartIndex = test.testName.indexOf('{');
const jsonString = test.testName.slice(jsonStartIndex, -1);

function decodeHtmlEntities(str) {
const he = require('he');
return he.decode(str);
}

const json = decodeHtmlEntities(jsonString);
const testDef = JSON.parse(json);
testDef['outcome'] = test.outcome;

tests.push(testDef);
});

let markdown = [];

markdown.push(`|Proposal |Features| |`);
markdown.push(`|------|-------|----|`);

tests.sort((a, b) => (a.Id || '').localeCompare(b.Id || ''));

tests.forEach(testDef => {
markdown.push(`|[${testDef['Name']}](${testDef['Proposal']})|${testDef['Features']}|${testDef['outcome'] === 'Failed'?'❌':'✅'}|`);
});

return markdown.join('\n');
}
}

// CLI implementation
async function main() {
if (process.argv.length !== 4) {
console.log('Usage: node trx-to-markdown.js <input.trx> <output.md>');
process.exit(1);
}

const inputFile = process.argv[2];
const outputFile = process.argv[3];

try {
const converter = new TrxToMarkdown();
await converter.convertFile(inputFile, outputFile);
} catch (error) {
console.error('Conversion failed:', error);
process.exit(1);
}
}

if (require.main === module) {
main();
}

module.exports = TrxToMarkdown;
37 changes: 35 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ The chapters and sections from the spec are commented throughout the source code
- [Interop Bindings](#interop-bindings)
- [Customization](#customization)
- [Roadmap](#roadmap)
- [WebAssembly Feature Extensions](#webassembly-feature-extensions)
- [License](#license)

## Features
Expand Down Expand Up @@ -180,7 +181,6 @@ Custom Instruction implementations can be patched in by replacing or inheriting
The current TODO list includes:
- **Unity Package Install**: A Unity Asset Store install option.
- **ExecAsync**: Thread scheduling and advanced gas metering.
- **Wasm Garbage Collection**: Support wasm-gc and heaptypes.
- **Text Format Parsing**: Add support for WebAssembly text format.
Expand All @@ -190,7 +190,40 @@ The current TODO list includes:
- **Unity Bindings for SDL**: Implement SDL2 with Unity bindings.
- **Instantiation-time Optimization**: Improvements like superinstruction threading and selective inlining for better performance.
- **JavaScript Proxy Bindings**: Maybe support common JS env functions.
- **Phase 5 WASM Extensions**: Upcoming features as WebAssembly evolves.
## WebAssembly Feature Extensions
I started building WACS based on the WebAssembly Core 2 spec, so some of these are already supported.
I'll be implementing and adding support for as many phase 5 features as I can. Depends mostly on complexity and non-javascriptiness.
Here's what's supported so far.
Harnessed results from [wasm-feature-detect](https://github.com/GoogleChromeLabs/wasm-feature-detect) as compares to [other runtimes](https://webassembly.org/features/):
|Proposal |Features| |
|------|-------|----|
|[BigInt integration](https://github.com/WebAssembly/JS-BigInt-integration)||✅|
|[Bulk memory operations](https://github.com/webassembly/bulk-memory-operations)||✅|
|[Legacy Exception Handling](https://github.com/WebAssembly/exception-handling)|exceptions|❌|
|[Exception Handling with exnref](https://github.com/WebAssembly/exception-handling)|exceptions|❌|
|[Extented Const Expressesions](https://github.com/WebAssembly/extended-const)|extended_const|❌|
|[Garbage Collection](https://github.com/WebAssembly/gc)|gc|❌|
|[JS String Builtins Proposal for WebAssembly](https://github.com/WebAssembly/js-string-builtins)||❌|
|[JavaScript Promise Integration](https://github.com/WebAssembly/js-promise-integration)|jspi|❌|
|[Memory64](https://github.com/WebAssembly/memory64)|memory64|❌|
|[Multiple Memories](https://github.com/WebAssembly/multi-memory)|multi-memory|❌|
|[Multi-value](https://github.com/WebAssembly/multi-value)|multi_value|✅|
|[Importable/Exportable mutable globals]()||✅|
|[Reference Types](https://github.com/WebAssembly/reference-types)||✅|
|[Relaxed SIMD](https://github.com/webassembly/relaxed-simd)|relaxed_simd|❌|
|[Non-trapping float-to-int conversions](https://github.com/WebAssembly/nontrapping-float-to-int-conversions)||✅|
|[Sign-extension operators](https://github.com/WebAssembly/sign-extension-ops)||✅|
|[Fixed-Width SIMD](https://github.com/webassembly/simd)||✅|
|[Streaming Compilation](https://webassembly.github.io/spec/web-api/index.html#streaming-modules)|streaming_compilation|❌|
|[Tail call](https://github.com/webassembly/tail-call)|tail_call|❌|
|[Threads](https://github.com/webassembly/threads)|threads|❌|
|[Type Reflection](https://github.com/WebAssembly/js-types)|type-reflection|❌|
|[Typed function references](https://github.com/WebAssembly/function-references)|function-references|❌|
This table was generated with the Feature.Detect test harness.
## Sponsorship & Collaboration
Expand Down
24 changes: 24 additions & 0 deletions features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
|Proposal |Features| |
|------|-------|----|
|[BigInt integration](https://github.com/WebAssembly/JS-BigInt-integration)|||
|[Bulk memory operations](https://github.com/webassembly/bulk-memory-operations)|||
|[Legacy Exception Handling](https://github.com/WebAssembly/exception-handling)|exceptions||
|[Exception Handling with exnref](https://github.com/WebAssembly/exception-handling)|exceptions||
|[Extented Const Expressesions](https://github.com/WebAssembly/extended-const)|extended_const||
|[Garbage Collection](https://github.com/WebAssembly/gc)|gc||
|[JS String Builtins Proposal for WebAssembly](https://github.com/WebAssembly/js-string-builtins)|||
|[JavaScript Promise Integration](https://github.com/WebAssembly/js-promise-integration)|jspi||
|[Memory64](https://github.com/WebAssembly/memory64)|memory64||
|[Multiple Memories](https://github.com/WebAssembly/multi-memory)|multi-memory||
|[Multi-value](https://github.com/WebAssembly/multi-value)|multi_value||
|[Importable/Exportable mutable globals]()|||
|[Reference Types](https://github.com/WebAssembly/reference-types)|||
|[Relaxed SIMD](https://github.com/webassembly/relaxed-simd)|relaxed_simd||
|[Non-trapping float-to-int conversions](https://github.com/WebAssembly/nontrapping-float-to-int-conversions)|||
|[Sign-extension operators](https://github.com/WebAssembly/sign-extension-ops)|||
|[Fixed-Width SIMD](https://github.com/webassembly/simd)|||
|[Streaming Compilation](https://webassembly.github.io/spec/web-api/index.html#streaming-modules)|streaming_compilation||
|[Tail call](https://github.com/webassembly/tail-call)|tail_call||
|[Threads](https://github.com/webassembly/threads)|threads||
|[Type Reflection](https://github.com/WebAssembly/js-types)|type-reflection||
|[Typed function references](https://github.com/WebAssembly/function-references)|function-references||

0 comments on commit 35007d2

Please sign in to comment.