Merge branch 'main' of github.com:camillobruni/JetStream into 2024-11-22_driver_prep
diff --git a/JetStreamDriver.js b/JetStreamDriver.js
index 1fb279b..281e103 100644
--- a/JetStreamDriver.js
+++ b/JetStreamDriver.js
@@ -229,8 +229,9 @@
         this.counter.failedPreloadResources = 0;
     }
 
-    addPlan(plan, BenchmarkClass = DefaultBenchmark) {
-        this.benchmarks.push(new BenchmarkClass(plan));
+    addBenchmark(benchmark) {
+        this.benchmarks.push(benchmark);
+        benchmark.fetchResources();
     }
 
     async start() {
@@ -281,7 +282,7 @@
         }
 
         const allScores = [];
-        for (let benchmark of this.benchmarks)
+        for (const benchmark of this.benchmarks)
             allScores.push(benchmark.score);
 
         categoryScores = new Map;
@@ -536,13 +537,14 @@
     constructor(plan)
     {
         this.plan = plan;
+        this.testGroup = plan.testGroup;
+
         this.iterations = getIterationCount(plan);
         this.isAsync = !!plan.isAsync;
 
         this.scripts = null;
 
         this._resourcesPromise = null;
-        this.fetchResources();
     }
 
     get name() { return this.plan.name; }
@@ -1379,10 +1381,9 @@
 const WSLGroup = Symbol.for("WSL");
 const WTBGroup = Symbol.for("WTB");
 
-
-const testPlans = [
+const BENCHMARKS = [
     // ARES
-    {
+    new DefaultBenchmark({
         name: "Air",
         files: [
             "./ARES-6/Air/symbols.js"
@@ -1408,8 +1409,8 @@
             , "./ARES-6/Air/benchmark.js"
         ],
         testGroup: ARESGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "Basic",
         files: [
             "./ARES-6/Basic/ast.js"
@@ -1424,8 +1425,8 @@
             , "./ARES-6/Basic/benchmark.js"
         ],
         testGroup: ARESGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "ML",
         files: [
             "./ARES-6/ml/index.js"
@@ -1433,8 +1434,8 @@
         ],
         iterations: 60,
         testGroup: ARESGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "Babylon",
         files: [
             "./ARES-6/Babylon/index.js"
@@ -1447,9 +1448,9 @@
             babylonBlob: "./ARES-6/Babylon/babylon-blob.js"
         },
         testGroup: ARESGroup
-    },
+    }),
     // CDJS
-    {
+    new DefaultBenchmark({
         name: "cdjs",
         files: [
             "./cdjs/constants.js"
@@ -1468,9 +1469,9 @@
         iterations: 60,
         worstCaseCount: 3,
         testGroup: CDJSGroup
-    },
+    }),
     // CodeLoad
-    {
+    new DefaultBenchmark({
         name: "first-inspector-code-load",
         files: [
             "./code-load/code-first-load.js"
@@ -1479,8 +1480,8 @@
             inspectorPayloadBlob: "./code-load/inspector-payload-minified.js"
         },
         testGroup: CodeLoadGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "multi-inspector-code-load",
         files: [
             "./code-load/code-multi-load.js"
@@ -1489,49 +1490,49 @@
             inspectorPayloadBlob: "./code-load/inspector-payload-minified.js"
         },
         testGroup: CodeLoadGroup
-    },
+    }),
     // Octane
-    {
+    new DefaultBenchmark({
         name: "Box2D",
         files: [
             "./Octane/box2d.js"
         ],
         deterministicRandom: true,
         testGroup: OctaneGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "octane-code-load",
         files: [
             "./Octane/code-first-load.js"
         ],
         deterministicRandom: true,
         testGroup: OctaneGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "crypto",
         files: [
             "./Octane/crypto.js"
         ],
         deterministicRandom: true,
         testGroup: OctaneGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "delta-blue",
         files: [
             "./Octane/deltablue.js"
         ],
         deterministicRandom: true,
         testGroup: OctaneGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "earley-boyer",
         files: [
             "./Octane/earley-boyer.js"
         ],
         deterministicRandom: true,
         testGroup: OctaneGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "gbemu",
         files: [
             "./Octane/gbemu-part1.js"
@@ -1539,8 +1540,8 @@
         ],
         deterministicRandom: true,
         testGroup: OctaneGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "mandreel",
         files: [
             "./Octane/mandreel.js"
@@ -1548,55 +1549,55 @@
         iterations: 80,
         deterministicRandom: true,
         testGroup: OctaneGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "navier-stokes",
         files: [
             "./Octane/navier-stokes.js"
         ],
         deterministicRandom: true,
         testGroup: OctaneGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "pdfjs",
         files: [
             "./Octane/pdfjs.js"
         ],
         deterministicRandom: true,
         testGroup: OctaneGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "raytrace",
         files: [
             "./Octane/raytrace.js"
         ],
         testGroup: OctaneGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "regexp",
         files: [
             "./Octane/regexp.js"
         ],
         deterministicRandom: true,
         testGroup: OctaneGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "richards",
         files: [
             "./Octane/richards.js"
         ],
         deterministicRandom: true,
         testGroup: OctaneGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "splay",
         files: [
             "./Octane/splay.js"
         ],
         deterministicRandom: true,
         testGroup: OctaneGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "typescript",
         files: [
             "./Octane/typescript-compiler.js"
@@ -1607,8 +1608,8 @@
         worstCaseCount: 2,
         deterministicRandom: true,
         testGroup: OctaneGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "octane-zlib",
         files: [
             "./Octane/zlib-data.js"
@@ -1618,9 +1619,9 @@
         worstCaseCount: 2,
         deterministicRandom: true,
         testGroup: OctaneGroup
-    },
+    }),
     // RexBench
-    {
+    new DefaultBenchmark({
         name: "FlightPlanner",
         files: [
             "./RexBench/FlightPlanner/airways.js"
@@ -1630,8 +1631,8 @@
             , "./RexBench/FlightPlanner/benchmark.js"
         ],
         testGroup: RexBenchGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "OfflineAssembler",
         files: [
             "./RexBench/OfflineAssembler/registers.js"
@@ -1648,8 +1649,8 @@
         ],
         iterations: 80,
         testGroup: RexBenchGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "UniPoker",
         files: [
             "./RexBench/UniPoker/poker.js"
@@ -1658,71 +1659,69 @@
         ],
         deterministicRandom: true,
         testGroup: RexBenchGroup
-    },
+    }),
     // Simple
-    {
+    new DefaultBenchmark({
         name: "hash-map",
         files: [
             "./simple/hash-map.js"
         ],
         testGroup: SimpleGroup
-    },
-    {
+    }),
+    new AsyncBenchmark({
         name: "doxbee-promise",
         files: [
             "./simple/doxbee-promise.js",
         ],
-        benchmarkClass: AsyncBenchmark,
         testGroup: SimpleGroup,
-    },
-    {
+    }),
+    new AsyncBenchmark({
         name: "doxbee-async",
         files: [
             "./simple/doxbee-async.js",
         ],
-        benchmarkClass: AsyncBenchmark,
         testGroup: SimpleGroup,
-    },
+    }),
     // SeaMonster
-    {
+    new DefaultBenchmark({
         name: "ai-astar",
         files: [
             "./SeaMonster/ai-astar.js"
         ],
         testGroup: SeaMonsterGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "gaussian-blur",
         files: [
             "./SeaMonster/gaussian-blur.js"
         ],
         testGroup: SeaMonsterGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "stanford-crypto-aes",
         files: [
             "./SeaMonster/sjlc.js"
             , "./SeaMonster/stanford-crypto-aes.js"
         ],
         testGroup: SeaMonsterGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "stanford-crypto-pbkdf2",
         files: [
             "./SeaMonster/sjlc.js"
             , "./SeaMonster/stanford-crypto-pbkdf2.js"
         ],
         testGroup: SeaMonsterGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "stanford-crypto-sha256",
         files: [
             "./SeaMonster/sjlc.js"
             , "./SeaMonster/stanford-crypto-sha256.js"
         ],
         testGroup: SeaMonsterGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "json-stringify-inspector",
         files: [
             "./SeaMonster/inspector-json-payload.js"
@@ -1731,8 +1730,8 @@
         iterations: 20,
         worstCaseCount: 2,
         testGroup: SeaMonsterGroup
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "json-parse-inspector",
         files: [
             "./SeaMonster/inspector-json-payload.js"
@@ -1741,9 +1740,9 @@
         iterations: 20,
         worstCaseCount: 2,
         testGroup: SeaMonsterGroup
-    },
+    }),
     // BigInt
-    {
+    new AsyncBenchmark({
         name: "bigint-noble-bls12-381",
         files: [
             "./bigint/web-crypto-sham.js",
@@ -1752,22 +1751,20 @@
         ],
         iterations: 4,
         worstCaseCount: 1,
-        benchmarkClass: AsyncBenchmark,
         deterministicRandom: true,
         testGroup: BigIntNobleGroup,
-    },
-    {
+    }),
+    new AsyncBenchmark({
         name: "bigint-noble-secp256k1",
         files: [
             "./bigint/web-crypto-sham.js",
             "./bigint/noble-secp256k1-bundle.js",
             "./bigint/noble-benchmark.js",
         ],
-        benchmarkClass: AsyncBenchmark,
         deterministicRandom: true,
         testGroup: BigIntNobleGroup,
-    },
-    {
+    }),
+    new AsyncBenchmark({
         name: "bigint-noble-ed25519",
         files: [
             "./bigint/web-crypto-sham.js",
@@ -1775,11 +1772,10 @@
             "./bigint/noble-benchmark.js",
         ],
         iterations: 30,
-        benchmarkClass: AsyncBenchmark,
         deterministicRandom: true,
         testGroup: BigIntNobleGroup,
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "bigint-paillier",
         files: [
             "./bigint/web-crypto-sham.js",
@@ -1790,8 +1786,8 @@
         worstCaseCount: 2,
         deterministicRandom: true,
         testGroup: BigIntMiscGroup,
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "bigint-bigdenary",
         files: [
             "./bigint/bigdenary-bundle.js",
@@ -1800,9 +1796,9 @@
         iterations: 160,
         worstCaseCount: 16,
         testGroup: BigIntMiscGroup,
-    },
+    }),
     // Proxy
-    {
+    new AsyncBenchmark({
         name: "proxy-mobx",
         files: [
             "./proxy/common.js",
@@ -1813,8 +1809,8 @@
         worstCaseCount: defaultWorstCaseCount * 3,
         benchmarkClass: AsyncBenchmark,
         testGroup: ProxyGroup,
-    },
-    {
+    }),
+    new AsyncBenchmark({
         name: "proxy-vue",
         files: [
             "./proxy/common.js",
@@ -1823,24 +1819,24 @@
         ],
         benchmarkClass: AsyncBenchmark,
         testGroup: ProxyGroup,
-    },
+    }),
     // Class fields
-    {
+    new DefaultBenchmark({
         name: "raytrace-public-class-fields",
         files: [
             "./class-fields/raytrace-public-class-fields.js",
         ],
         testGroup: ClassFieldsGroup,
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "raytrace-private-class-fields",
         files: [
             "./class-fields/raytrace-private-class-fields.js",
         ],
         testGroup: ClassFieldsGroup,
-    },
+    }),
     // Generators
-    {
+    new AsyncBenchmark({
         name: "async-fs",
         files: [
             "./generators/async-file-system.js",
@@ -1848,10 +1844,9 @@
         iterations: 80,
         worstCaseCount: 6,
         deterministicRandom: true,
-        benchmarkClass: AsyncBenchmark,
         testGroup: GeneratorsGroup,
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "sync-fs",
         files: [
             "./generators/sync-file-system.js",
@@ -1860,23 +1855,23 @@
         worstCaseCount: 6,
         deterministicRandom: true,
         testGroup: GeneratorsGroup,
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "lazy-collections",
         files: [
             "./generators/lazy-collections.js",
         ],
         testGroup: GeneratorsGroup,
-    },
-    {
+    }),
+    new DefaultBenchmark({
         name: "js-tokens",
         files: [
             "./generators/js-tokens.js",
         ],
         testGroup: GeneratorsGroup,
-    },
+    }),
     // Wasm
-    {
+    new WasmLegacyBenchmark({
         name: "HashSet-wasm",
         files: [
             "./wasm/HashSet.js"
@@ -1884,10 +1879,9 @@
         preload: {
             wasmBinary: "./wasm/HashSet.wasm"
         },
-        benchmarkClass: WasmLegacyBenchmark,
         testGroup: WasmGroup
-    },
-    {
+    }),
+    new WasmEMCCBenchmark({
         name: "tsf-wasm",
         files: [
             "./wasm/TSF/build/tsf.js",
@@ -1896,12 +1890,11 @@
         preload: {
             wasmBinary: "./wasm/TSF/build/tsf.wasm"
         },
-        benchmarkClass: WasmEMCCBenchmark,
         iterations: 15,
         worstCaseCount: 2,
         testGroup: WasmGroup
-    },
-    {
+    }),
+    new WasmLegacyBenchmark({
         name: "quicksort-wasm",
         files: [
             "./wasm/quicksort.js"
@@ -1909,10 +1902,9 @@
         preload: {
             wasmBinary: "./wasm/quicksort.wasm"
         },
-        benchmarkClass: WasmLegacyBenchmark,
         testGroup: WasmGroup
-    },
-    {
+    }),
+    new WasmEMCCBenchmark({
         name: "gcc-loops-wasm",
         files: [
             "./wasm/gcc-loops/build/gcc-loops.js",
@@ -1921,11 +1913,10 @@
         preload: {
             wasmBinary: "./wasm/gcc-loops/build/gcc-loops.wasm"
         },
-        benchmarkClass: WasmEMCCBenchmark,
         iterations: 50,
         testGroup: WasmGroup
-    },
-    {
+    }),
+    new WasmLegacyBenchmark({
         name: "richards-wasm",
         files: [
             "./wasm/richards.js"
@@ -1933,10 +1924,9 @@
         preload: {
             wasmBinary: "./wasm/richards.wasm"
         },
-        benchmarkClass: WasmLegacyBenchmark,
         testGroup: WasmGroup
-    },
-    {
+    }),
+    new WasmLegacyBenchmark({
         name: "sqlite3-wasm",
         files: [
             "./sqlite3/polyfills.js",
@@ -1948,8 +1938,8 @@
         },
         benchmarkClass: WasmLegacyBenchmark,
         testGroup: WasmGroup
-    },
-    {
+    }),
+    new WasmEMCCBenchmark({
         name: "tfjs-wasm",
         files: [
             "./wasm/tfjs/tfjs-model-helpers.js",
@@ -1965,13 +1955,12 @@
         preload: {
             tfjsBackendWasmBlob: "./wasm/tfjs/tfjs-backend-wasm.wasm",
         },
-        benchmarkClass: WasmEMCCBenchmark,
         iterations: 15,
         worstCaseCount: 2,
         deterministicRandom: true,
         testGroup: WasmGroup
-    },
-    {
+    }),
+    new WasmEMCCBenchmark({
         name: "tfjs-wasm-simd",
         files: [
             "./wasm/tfjs/tfjs-model-helpers.js",
@@ -1987,13 +1976,12 @@
         preload: {
             tfjsBackendWasmSimdBlob: "./wasm/tfjs/tfjs-backend-wasm-simd.wasm",
         },
-        benchmarkClass: WasmEMCCBenchmark,
         iterations: 40,
         worstCaseCount: 3,
         deterministicRandom: true,
         testGroup: WasmGroup
-    },
-    {
+    }),
+    new WasmLegacyBenchmark({
         name: "argon2-wasm",
         files: [
             "./wasm/argon2-bundle.js",
@@ -2003,10 +1991,9 @@
         preload: {
             argon2WasmBlob: "./wasm/argon2.wasm",
         },
-        benchmarkClass: WasmLegacyBenchmark,
         testGroup: WasmGroup
-    },
-    {
+    }),
+    new WasmLegacyBenchmark({
         name: "argon2-wasm-simd",
         files: [
             "./wasm/argon2-bundle.js",
@@ -2016,11 +2003,10 @@
         preload: {
             argon2WasmSimdBlob: "./wasm/argon2-simd.wasm",
         },
-        benchmarkClass: WasmLegacyBenchmark,
         testGroup: WasmGroup
-    },
+    }),
     // WorkerTests
-    {
+    new AsyncBenchmark({
         name: "bomb-workers",
         files: [
             "./worker/bomb.js"
@@ -2054,10 +2040,9 @@
             , stringUnpackCode: "./worker/bomb-subtests/string-unpack-code.js"
             , regexpDNA: "./worker/bomb-subtests/regexp-dna.js"
         },
-        benchmarkClass: AsyncBenchmark,
         testGroup: WorkerTestsGroup
-    },
-    {
+    }),
+    new AsyncBenchmark({
         name: "segmentation",
         files: [
             "./worker/segmentation.js"
@@ -2067,18 +2052,16 @@
         },
         iterations: 36,
         worstCaseCount: 3,
-        benchmarkClass: AsyncBenchmark,
         testGroup: WorkerTestsGroup
-    },
+    }),
     // WSL
-    {
+    new WSLBenchmark({
         name: "WSL",
         files: ["./WSL/Node.js" ,"./WSL/Type.js" ,"./WSL/ReferenceType.js" ,"./WSL/Value.js" ,"./WSL/Expression.js" ,"./WSL/Rewriter.js" ,"./WSL/Visitor.js" ,"./WSL/CreateLiteral.js" ,"./WSL/CreateLiteralType.js" ,"./WSL/PropertyAccessExpression.js" ,"./WSL/AddressSpace.js" ,"./WSL/AnonymousVariable.js" ,"./WSL/ArrayRefType.js" ,"./WSL/ArrayType.js" ,"./WSL/Assignment.js" ,"./WSL/AutoWrapper.js" ,"./WSL/Block.js" ,"./WSL/BoolLiteral.js" ,"./WSL/Break.js" ,"./WSL/CallExpression.js" ,"./WSL/CallFunction.js" ,"./WSL/Check.js" ,"./WSL/CheckLiteralTypes.js" ,"./WSL/CheckLoops.js" ,"./WSL/CheckRecursiveTypes.js" ,"./WSL/CheckRecursion.js" ,"./WSL/CheckReturns.js" ,"./WSL/CheckUnreachableCode.js" ,"./WSL/CheckWrapped.js" ,"./WSL/Checker.js" ,"./WSL/CloneProgram.js" ,"./WSL/CommaExpression.js" ,"./WSL/ConstexprFolder.js" ,"./WSL/ConstexprTypeParameter.js" ,"./WSL/Continue.js" ,"./WSL/ConvertPtrToArrayRefExpression.js" ,"./WSL/DereferenceExpression.js" ,"./WSL/DoWhileLoop.js" ,"./WSL/DotExpression.js" ,"./WSL/DoubleLiteral.js" ,"./WSL/DoubleLiteralType.js" ,"./WSL/EArrayRef.js" ,"./WSL/EBuffer.js" ,"./WSL/EBufferBuilder.js" ,"./WSL/EPtr.js" ,"./WSL/EnumLiteral.js" ,"./WSL/EnumMember.js" ,"./WSL/EnumType.js" ,"./WSL/EvaluationCommon.js" ,"./WSL/Evaluator.js" ,"./WSL/ExpressionFinder.js" ,"./WSL/ExternalOrigin.js" ,"./WSL/Field.js" ,"./WSL/FindHighZombies.js" ,"./WSL/FlattenProtocolExtends.js" ,"./WSL/FlattenedStructOffsetGatherer.js" ,"./WSL/FloatLiteral.js" ,"./WSL/FloatLiteralType.js" ,"./WSL/FoldConstexprs.js" ,"./WSL/ForLoop.js" ,"./WSL/Func.js" ,"./WSL/FuncDef.js" ,"./WSL/FuncInstantiator.js" ,"./WSL/FuncParameter.js" ,"./WSL/FunctionLikeBlock.js" ,"./WSL/HighZombieFinder.js" ,"./WSL/IdentityExpression.js" ,"./WSL/IfStatement.js" ,"./WSL/IndexExpression.js" ,"./WSL/InferTypesForCall.js" ,"./WSL/Inline.js" ,"./WSL/Inliner.js" ,"./WSL/InstantiateImmediates.js" ,"./WSL/IntLiteral.js" ,"./WSL/IntLiteralType.js" ,"./WSL/Intrinsics.js" ,"./WSL/LateChecker.js" ,"./WSL/Lexer.js" ,"./WSL/LexerToken.js" ,"./WSL/LiteralTypeChecker.js" ,"./WSL/LogicalExpression.js" ,"./WSL/LogicalNot.js" ,"./WSL/LoopChecker.js" ,"./WSL/MakeArrayRefExpression.js" ,"./WSL/MakePtrExpression.js" ,"./WSL/NameContext.js" ,"./WSL/NameFinder.js" ,"./WSL/NameResolver.js" ,"./WSL/NativeFunc.js" ,"./WSL/NativeFuncInstance.js" ,"./WSL/NativeType.js" ,"./WSL/NativeTypeInstance.js" ,"./WSL/NormalUsePropertyResolver.js" ,"./WSL/NullLiteral.js" ,"./WSL/NullType.js" ,"./WSL/OriginKind.js" ,"./WSL/OverloadResolutionFailure.js" ,"./WSL/Parse.js" ,"./WSL/Prepare.js" ,"./WSL/Program.js" ,"./WSL/ProgramWithUnnecessaryThingsRemoved.js" ,"./WSL/PropertyResolver.js" ,"./WSL/Protocol.js" ,"./WSL/ProtocolDecl.js" ,"./WSL/ProtocolFuncDecl.js" ,"./WSL/ProtocolRef.js" ,"./WSL/PtrType.js" ,"./WSL/ReadModifyWriteExpression.js" ,"./WSL/RecursionChecker.js" ,"./WSL/RecursiveTypeChecker.js" ,"./WSL/ResolveNames.js" ,"./WSL/ResolveOverloadImpl.js" ,"./WSL/ResolveProperties.js" ,"./WSL/ResolveTypeDefs.js" ,"./WSL/Return.js" ,"./WSL/ReturnChecker.js" ,"./WSL/ReturnException.js" ,"./WSL/StandardLibrary.js" ,"./WSL/StatementCloner.js" ,"./WSL/StructLayoutBuilder.js" ,"./WSL/StructType.js" ,"./WSL/Substitution.js" ,"./WSL/SwitchCase.js" ,"./WSL/SwitchStatement.js" ,"./WSL/SynthesizeEnumFunctions.js" ,"./WSL/SynthesizeStructAccessors.js" ,"./WSL/TrapStatement.js" ,"./WSL/TypeDef.js" ,"./WSL/TypeDefResolver.js" ,"./WSL/TypeOrVariableRef.js" ,"./WSL/TypeParameterRewriter.js" ,"./WSL/TypeRef.js" ,"./WSL/TypeVariable.js" ,"./WSL/TypeVariableTracker.js" ,"./WSL/TypedValue.js" ,"./WSL/UintLiteral.js" ,"./WSL/UintLiteralType.js" ,"./WSL/UnificationContext.js" ,"./WSL/UnreachableCodeChecker.js" ,"./WSL/VariableDecl.js" ,"./WSL/VariableRef.js" ,"./WSL/VisitingSet.js" ,"./WSL/WSyntaxError.js" ,"./WSL/WTrapError.js" ,"./WSL/WTypeError.js" ,"./WSL/WhileLoop.js" ,"./WSL/WrapChecker.js", "./WSL/Test.js"],
-        benchmarkClass: WSLBenchmark,
         testGroup: WSLGroup
-    },
+    }),
     // 8bitbench
-    {
+    new WasmLegacyBenchmark({
         name: "8bitbench-wasm",
         files: [
             "./8bitbench/lib/fast-text-encoding-1.0.3/text.js",
@@ -2090,9 +2073,8 @@
             romBinary: "./8bitbench/assets/program.bin"
         },
         async: true,
-        benchmarkClass: WasmLegacyBenchmark,
         testGroup: WasmGroup
-    }
+    })
 ];
 
 // LuaJSFight tests
@@ -2103,17 +2085,17 @@
     , "string_lists"
 ];
 for (const test of luaJSFightTests) {
-    testPlans.push({
+    BENCHMARKS.push(new DefaultBenchmark({
         name: `${test}-LJF`,
         files: [
             `./LuaJSFight/${test}.js`
         ],
         testGroup: LuaJSFightGroup
-    });
+    }));
 }
 
 // SunSpider tests
-const sunSpiderTests = [
+const SUNSPIDER_TESTS = [
     "3d-cube"
     , "3d-raytrace"
     , "base64"
@@ -2127,18 +2109,18 @@
     , "string-unpack-code"
     , "tagcloud"
 ];
-for (const test of sunSpiderTests) {
-    testPlans.push({
+for (const test of SUNSPIDER_TESTS) {
+    BENCHMARKS.push(new DefaultBenchmark({
         name: `${test}-SP`,
         files: [
             `./SunSpider/${test}.js`
         ],
         testGroup: SunSpiderGroup
-    });
+    }));
 }
 
 // WTB (Web Tooling Benchmark) tests
-const WTBTests = [
+const WTB_TESTS = [
     "acorn"
     , "babylon"
     , "chai"
@@ -2149,8 +2131,8 @@
     , "prepack"
     , "uglify-js"
 ];
-for (const name of WTBTests) {
-    testPlans.push({
+for (const name of WTB_TESTS) {
+    BENCHMARKS.push(new DefaultBenchmark({
         name: `${name}-wtb`,
         files: [
             isInBrowser ? "./web-tooling-benchmark/browser.js" : "./web-tooling-benchmark/cli.js"
@@ -2159,69 +2141,67 @@
         iterations: 5,
         worstCaseCount: 1,
         testGroup: WTBGroup
-    });
+    }));
 }
 
 
-const testsByName = new Map();
-const testsByGroup = new Map();
+const benchmarksByName = new Map();
+const benchmarksByGroup = new Map();
 
-for (const plan of testPlans) {
-    const testName = plan.name;
+for (const benchmark of BENCHMARKS) {
+    const testName = benchmark.name;
 
-    if (testsByName.has(plan.name))
+    if (benchmarksByName.has(benchmark.name))
         throw "Duplicate test plan with name \"" + testName + "\"";
     else
-        testsByName.set(testName, plan);
+        benchmarksByName.set(testName, benchmark);
 
-        const group = plan.testGroup;
+    const group = benchmark.testGroup;
 
-    if (testsByGroup.has(group))
-        testsByGroup.get(group).push(testName);
+    if (benchmarksByGroup.has(group))
+        benchmarksByGroup.get(group).push(testName);
     else
-        testsByGroup.set(group, [testName]);
+        benchmarksByGroup.set(group, [testName]);
 }
 
 this.JetStream = new Driver();
 
-function addTestByName(testName)
+function enableBenchmarksByName(testName)
 {
-    let plan = testsByName.get(testName);
+    const benchmark = benchmarksByName.get(testName);
 
-    if (plan)
-        JetStream.addPlan(plan, plan.benchmarkClass);
+    if (benchmark)
+        JetStream.addBenchmark(benchmark);
     else
         throw "Couldn't find test named \"" +  testName + "\"";
 }
 
-function addTestsByGroup(group)
+function enableBenchmarksByGroup(groupSymbol)
 {
-    let testList = testsByGroup.get(group);
+    const benchmarkNames = benchmarksByGroup.get(groupSymbol);
 
-    if (!testList)
-        throw "Couldn't find test group named: \"" + Symbol.keyFor(group) + "\"";
+    if (!benchmarkNames)
+        throw "Couldn't find test group named: \"" + Symbol.keyFor(groupSymbol) + "\"";
 
-    for (let testName of testList)
-        addTestByName(testName);
+    for (let name of benchmarkNames)
+        enableBenchmarksByName(name);
 }
 
 function processTestList(testList)
 {
-    let tests = [];
+    const benchmarkNames = [];
 
     if (testList instanceof Array)
-        tests = testList;
+        benchmarkNames = testList;
     else
-        tests = testList.split(/[\s,]/);
+        benchmarkNames = testList.split(/[\s,]/);
 
-    for (const testName of tests) {
-        const groupTest = testsByGroup.get(Symbol.for(testName));
-
-        if (groupTest) {
-            for (const testName of groupTest)
-                addTestByName(testName);
-        } else
-            addTestByName(testName);
+    for (const name of benchmarkNames) {
+        const groupSymbol = Symbol.for(name);
+        if (benchmarksByGroup.has(groupSymbol))
+            enableBenchmarksByGroup(groupSymbol)
+        else
+            enableBenchmarksByName(name);
     }
 }
 
@@ -2271,53 +2251,53 @@
     processTestList(customTestList);
 } else {
     if (runARES)
-        addTestsByGroup(ARESGroup);
+        enableBenchmarksByGroup(ARESGroup);
 
     if (runCDJS)
-        addTestsByGroup(CDJSGroup);
+        enableBenchmarksByGroup(CDJSGroup);
 
     if (runCodeLoad)
-        addTestsByGroup(CodeLoadGroup);
+        enableBenchmarksByGroup(CodeLoadGroup);
 
     if (runOctane)
-        addTestsByGroup(OctaneGroup);
+        enableBenchmarksByGroup(OctaneGroup);
 
     if (runRexBench)
-        addTestsByGroup(RexBenchGroup);
+        enableBenchmarksByGroup(RexBenchGroup);
 
     if (runSeaMonster)
-        addTestsByGroup(SeaMonsterGroup);
+        enableBenchmarksByGroup(SeaMonsterGroup);
 
     if (runSimple)
-        addTestsByGroup(SimpleGroup);
+        enableBenchmarksByGroup(SimpleGroup);
 
     if (runSunSpider)
-        addTestsByGroup(SunSpiderGroup);
+        enableBenchmarksByGroup(SunSpiderGroup);
 
     if (runBigIntNoble)
-        addTestsByGroup(BigIntNobleGroup);
+        enableBenchmarksByGroup(BigIntNobleGroup);
 
     if (runBigIntMisc)
-        addTestsByGroup(BigIntMiscGroup);
+        enableBenchmarksByGroup(BigIntMiscGroup);
 
     if (runProxy)
-        addTestsByGroup(ProxyGroup);
+        enableBenchmarksByGroup(ProxyGroup);
 
     if (runClassFields)
-        addTestsByGroup(ClassFieldsGroup);
+        enableBenchmarksByGroup(ClassFieldsGroup);
 
     if (runGenerators)
-        addTestsByGroup(GeneratorsGroup);
+        enableBenchmarksByGroup(GeneratorsGroup);
 
     if (runWasm)
-        addTestsByGroup(WasmGroup);
+        enableBenchmarksByGroup(WasmGroup);
 
     if (runWorkerTests)
-        addTestsByGroup(WorkerTestsGroup);
+        enableBenchmarksByGroup(WorkerTestsGroup);
 
     if (runWSL)
-        addTestsByGroup(WSLGroup);
+        enableBenchmarksByGroup(WSLGroup);
 
     if (runWTB)
-        addTestsByGroup(WTBGroup);
+        enableBenchmarksByGroup(WTBGroup);
 }