summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/fuzz_opt.py6
-rw-r--r--src/passes/CMakeLists.txt1
-rw-r--r--src/passes/EncloseWorld.cpp155
-rw-r--r--src/passes/pass.cpp3
-rw-r--r--src/passes/passes.h1
-rw-r--r--src/tools/fuzzing/fuzzing.cpp37
-rw-r--r--src/tools/wasm-reduce.cpp1
-rw-r--r--test/lit/help/wasm-metadce.test3
-rw-r--r--test/lit/help/wasm-opt.test3
-rw-r--r--test/lit/help/wasm2js.test3
-rw-r--r--test/lit/passes/enclose-world.wast237
-rw-r--r--test/passes/fuzz_metrics_passes_noprint.bin.txt58
-rw-r--r--test/passes/translate-to-fuzz_all-features_metrics_noprint.txt72
13 files changed, 497 insertions, 83 deletions
diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py
index cd583e026..4fc92f367 100755
--- a/scripts/fuzz_opt.py
+++ b/scripts/fuzz_opt.py
@@ -225,6 +225,11 @@ def randomize_fuzz_settings():
# optimizations we use to create any other wasm file.
FUZZ_OPTS += ['--dce']
+ # Enclose the world much of the time when fuzzing closed-world, so that many
+ # types are private and hence optimizable.
+ if CLOSED_WORLD and random.random() < 0.5:
+ GEN_ARGS += ['--enclose-world']
+
print('randomized settings (NaNs, OOB, legalize):', NANS, OOB, LEGALIZE)
@@ -1790,6 +1795,7 @@ opt_choices = [
("--dce",),
("--directize",),
("--discard-global-effects",),
+ ("--enclose-world",),
("--flatten", "--dfo",),
("--duplicate-function-elimination",),
("--flatten",),
diff --git a/src/passes/CMakeLists.txt b/src/passes/CMakeLists.txt
index e46163406..6b78e487d 100644
--- a/src/passes/CMakeLists.txt
+++ b/src/passes/CMakeLists.txt
@@ -35,6 +35,7 @@ set(passes_SOURCES
DuplicateImportElimination.cpp
DuplicateFunctionElimination.cpp
DWARF.cpp
+ EncloseWorld.cpp
ExtractFunction.cpp
Flatten.cpp
FuncCastEmulation.cpp
diff --git a/src/passes/EncloseWorld.cpp b/src/passes/EncloseWorld.cpp
new file mode 100644
index 000000000..5c6b70546
--- /dev/null
+++ b/src/passes/EncloseWorld.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2024 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// "Closes" the world, in the sense of making it more compatible with the
+// --closed-world flag, in a potentially destructive manner. This is mainly
+// useful for fuzzing (in that a random module is usually very incomptable with
+// closed world, with most types being public and hence unoptimizable, but
+// running this pass makes as many as we can fully private).
+//
+// The fixup we do is to find references sent out/received in, and to
+// externalize / internalize them. For example, this export:
+//
+// (func $refs (export "refs") (param $x (ref $X)) (result (ref $Y))
+//
+// would have the following function exported in its place:
+//
+// (func $refs-closed (export "refs") (param $x externref) (result externref)
+// (extern.convert_any
+// (call $refs
+// (ref.cast (ref $X)
+// (any.convert_extern
+// (local.get $x))))))
+//
+
+#include "ir/names.h"
+#include "pass.h"
+#include "wasm-builder.h"
+#include "wasm.h"
+
+namespace wasm {
+
+namespace {
+
+struct EncloseWorld : public Pass {
+ void run(Module* module) override {
+ // Handle exports.
+ // TODO: Non-function exports.
+ std::vector<std::unique_ptr<Export>> newExports;
+ for (auto& ex : module->exports) {
+ if (ex->kind == ExternalKind::Function) {
+ auto* func = module->getFunction(ex->value);
+ // If this opens up types, replace it with an enclosed stub.
+ if (opensTypes(func)) {
+ auto stubName = makeStubStubForExport(func, module);
+ ex->value = stubName;
+ }
+ }
+ }
+ for (auto& ex : newExports) {
+ module->addExport(std::move(ex));
+ }
+
+ // TODO: Handle imports.
+ }
+
+private:
+ // Whether a type is an "open" ref, that is, a type that closed-world would
+ // consider to keep things public and prevent some amount of closed-world
+ // optimizations.
+ bool isOpenRef(Type t) {
+ // Only externref keeps things closed, and we must ignore things that
+ // cannot be converted to/from it (like funcrefs), so we can just check for
+ // the top type being any.
+ return t.isRef() && t.getHeapType().getTop() == HeapType::any;
+ }
+
+ // Whether a function causes types to be open.
+ bool opensTypes(Function* func) {
+ for (const auto& param : func->getParams()) {
+ if (isOpenRef(param)) {
+ return true;
+ }
+ }
+ // TODO: Handle tuple results.
+ return isOpenRef(func->getResults());
+ }
+
+ // Make an enclosed stub function for an exported function, and return its
+ // name.
+ Name makeStubStubForExport(Function* func, Module* module) {
+ // Pick a valid name for the stub we are about to create.
+ auto stubName = Names::getValidFunctionName(
+ *module, std::string("stub$") + func->name.toString());
+
+ // Create the stub.
+ Builder builder(*module);
+
+ // The stub's body is just a call to the original function, but with some
+ // conversions to/from externref.
+ std::vector<Expression*> params;
+
+ auto externref = Type(HeapType::ext, Nullable);
+
+ // Handle params.
+ std::vector<Type> stubParams;
+ for (const auto& param : func->getParams()) {
+ if (!isOpenRef(param)) {
+ // A normal parameter. Just pass it to the original function.
+ auto* get = builder.makeLocalGet(stubParams.size(), param);
+ params.push_back(get);
+ stubParams.push_back(param);
+ } else {
+ // A type we must fix up: receive as an externref and then internalize
+ // and cast before sending to the original function.
+ auto* get = builder.makeLocalGet(stubParams.size(), externref);
+ auto* interned = builder.makeRefAs(AnyConvertExtern, get);
+ // This cast may be trivial, but we leave it to the optimizer to remove.
+ auto* cast = builder.makeRefCast(interned, param);
+ params.push_back(cast);
+ stubParams.push_back(externref);
+ }
+ }
+
+ auto* call = builder.makeCall(func->name, params, func->getResults());
+
+ // Generate the stub's type.
+ auto oldResults = func->getResults();
+ Type resultsType = isOpenRef(oldResults) ? externref : oldResults;
+ auto type = Signature(Type(stubParams), resultsType);
+
+ // Handle the results and make the body.
+ Expression* body;
+ if (!isOpenRef(oldResults)) {
+ // Just use the call.
+ body = call;
+ } else {
+ // Fix up the call's result.
+ body = builder.makeRefAs(ExternConvertAny, call);
+ }
+
+ module->addFunction(builder.makeFunction(stubName, type, {}, body));
+
+ return stubName;
+ }
+};
+
+} // anonymous namespace
+
+Pass* createEncloseWorldPass() { return new EncloseWorld(); }
+
+} // namespace wasm
diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp
index 4be24cebf..7f6985e0f 100644
--- a/src/passes/pass.cpp
+++ b/src/passes/pass.cpp
@@ -159,6 +159,9 @@ void PassRegistry::registerPasses() {
registerPass("emit-target-features",
"emit the target features section in the output",
createEmitTargetFeaturesPass);
+ registerPass("enclose-world",
+ "modify the wasm (destructively) for closed-world",
+ createEncloseWorldPass);
registerPass("extract-function",
"leaves just one function (useful for debugging)",
createExtractFunctionPass);
diff --git a/src/passes/passes.h b/src/passes/passes.h
index aadd26d41..b313b3431 100644
--- a/src/passes/passes.h
+++ b/src/passes/passes.h
@@ -46,6 +46,7 @@ Pass* createDWARFDumpPass();
Pass* createDuplicateImportEliminationPass();
Pass* createDuplicateFunctionEliminationPass();
Pass* createEmitTargetFeaturesPass();
+Pass* createEncloseWorldPass();
Pass* createExtractFunctionPass();
Pass* createExtractFunctionIndexPass();
Pass* createFlattenPass();
diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp
index ed653ef6b..135e50393 100644
--- a/src/tools/fuzzing/fuzzing.cpp
+++ b/src/tools/fuzzing/fuzzing.cpp
@@ -62,6 +62,17 @@ void TranslateToFuzzReader::pickPasses(OptimizationOptions& options) {
// things like ClusterFuzz, where we are using Binaryen to fuzz other things
// than itself). As a result, the list of passes here is different from
// fuzz_opt.py.
+
+ // Enclose the world, some of the time. We do this before picking any other
+ // passes so that we make the initial fuzz contents more optimizable by
+ // closed-world passes later. Note that we do this regardless of whether we
+ // are in closed-world mode or not, as it is good to get this variety
+ // regardless.
+ if (oneIn(2)) {
+ options.passes.push_back("enclose-world");
+ }
+
+ // Main selection of passes.
while (options.passes.size() < 20 && !random.finished() && !oneIn(3)) {
switch (upTo(42)) {
case 0:
@@ -1075,30 +1086,14 @@ Function* TranslateToFuzzReader::addFunction() {
// Add hang limit checks after all other operations on the function body.
wasm.addFunction(std::move(allocation));
// Export some functions, but not all (to allow inlining etc.). Try to export
- // at least one, though, to keep each testcase interesting. Only functions
- // with valid params and returns can be exported because the trap fuzzer
- // depends on that (TODO: fix this).
- auto validExportType = [](Type t) {
- if (!t.isRef()) {
- return true;
- }
- auto heapType = t.getHeapType();
- return heapType == HeapType::ext || heapType == HeapType::func ||
- heapType == HeapType::string;
- };
+ // at least one, though, to keep each testcase interesting. Avoid non-
+ // nullable params, as those cannot be constructed by the fuzzer on the
+ // outside.
bool validExportParams =
std::all_of(paramType.begin(), paramType.end(), [&](Type t) {
- return validExportType(t) && t.isDefaultable();
+ return t.isDefaultable();
});
- // Note: spec discussions around JS API integration are still ongoing, and it
- // is not clear if we should allow nondefaultable types in exports or not
- // (in imports, we cannot allow them in the fuzzer anyhow, since it can't
- // construct such values in JS to send over to the wasm from the fuzzer
- // harness).
- bool validExportResults =
- std::all_of(resultType.begin(), resultType.end(), validExportType);
- if (validExportParams && validExportResults &&
- (numAddedFunctions == 0 || oneIn(2)) &&
+ if (validExportParams && (numAddedFunctions == 0 || oneIn(2)) &&
!wasm.getExportOrNull(func->name)) {
auto* export_ = new Export;
export_->name = func->name;
diff --git a/src/tools/wasm-reduce.cpp b/src/tools/wasm-reduce.cpp
index 8d9858b78..026825118 100644
--- a/src/tools/wasm-reduce.cpp
+++ b/src/tools/wasm-reduce.cpp
@@ -275,6 +275,7 @@ struct Reducer
"--dae-optimizing",
"--dce",
"--duplicate-function-elimination",
+ "--enclose-world",
"--gto",
"--inlining",
"--inlining-optimizing",
diff --git a/test/lit/help/wasm-metadce.test b/test/lit/help/wasm-metadce.test
index 4dc03883a..e44e51a16 100644
--- a/test/lit/help/wasm-metadce.test
+++ b/test/lit/help/wasm-metadce.test
@@ -143,6 +143,9 @@
;; CHECK-NEXT: --emit-target-features emit the target features section
;; CHECK-NEXT: in the output
;; CHECK-NEXT:
+;; CHECK-NEXT: --enclose-world modify the wasm (destructively)
+;; CHECK-NEXT: for closed-world
+;; CHECK-NEXT:
;; CHECK-NEXT: --extract-function leaves just one function (useful
;; CHECK-NEXT: for debugging)
;; CHECK-NEXT:
diff --git a/test/lit/help/wasm-opt.test b/test/lit/help/wasm-opt.test
index 62a30a770..5c978ee81 100644
--- a/test/lit/help/wasm-opt.test
+++ b/test/lit/help/wasm-opt.test
@@ -152,6 +152,9 @@
;; CHECK-NEXT: --emit-target-features emit the target features section
;; CHECK-NEXT: in the output
;; CHECK-NEXT:
+;; CHECK-NEXT: --enclose-world modify the wasm (destructively)
+;; CHECK-NEXT: for closed-world
+;; CHECK-NEXT:
;; CHECK-NEXT: --extract-function leaves just one function (useful
;; CHECK-NEXT: for debugging)
;; CHECK-NEXT:
diff --git a/test/lit/help/wasm2js.test b/test/lit/help/wasm2js.test
index e2a450bc8..c1dd0401d 100644
--- a/test/lit/help/wasm2js.test
+++ b/test/lit/help/wasm2js.test
@@ -106,6 +106,9 @@
;; CHECK-NEXT: --emit-target-features emit the target features section
;; CHECK-NEXT: in the output
;; CHECK-NEXT:
+;; CHECK-NEXT: --enclose-world modify the wasm (destructively)
+;; CHECK-NEXT: for closed-world
+;; CHECK-NEXT:
;; CHECK-NEXT: --extract-function leaves just one function (useful
;; CHECK-NEXT: for debugging)
;; CHECK-NEXT:
diff --git a/test/lit/passes/enclose-world.wast b/test/lit/passes/enclose-world.wast
new file mode 100644
index 000000000..0077c27be
--- /dev/null
+++ b/test/lit/passes/enclose-world.wast
@@ -0,0 +1,237 @@
+;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
+
+;; RUN: foreach %s %t wasm-opt --enclose-world -all -S -o - | filecheck %s
+
+(module
+ ;; CHECK: (type $A (struct))
+ (type $A (struct))
+ ;; CHECK: (type $B (struct (field i32)))
+ (type $B (struct (field i32)))
+ ;; CHECK: (type $2 (func (param externref)))
+
+ ;; CHECK: (type $3 (func (result externref)))
+
+ ;; CHECK: (type $4 (func (param anyref) (result anyref)))
+
+ ;; CHECK: (type $5 (func (param externref) (result externref)))
+
+ ;; CHECK: (type $C (struct (field i32) (field f64)))
+ (type $C (struct (field i32 f64)))
+
+ ;; CHECK: (type $7 (func (param i32) (result f64)))
+
+ ;; CHECK: (type $8 (func (param anyref)))
+
+ ;; CHECK: (type $9 (func (result anyref)))
+
+ ;; CHECK: (type $10 (func (param (ref $A) (ref null $B)) (result (ref $C))))
+
+ ;; CHECK: (type $11 (func (param i32 (ref $A) funcref)))
+
+ ;; CHECK: (type $12 (func (param externref externref) (result externref)))
+
+ ;; CHECK: (type $13 (func (param i32 externref funcref)))
+
+ ;; CHECK: (export "normal" (func $normal))
+
+ ;; CHECK: (export "externref-param" (func $externref-param))
+
+ ;; CHECK: (export "externref-result" (func $externref-result))
+
+ ;; CHECK: (export "anyref-param" (func $stub$anyref-param))
+
+ ;; CHECK: (export "anyref-result" (func $stub$anyref-result))
+
+ ;; CHECK: (export "anyref-both" (func $stub$anyref-both))
+
+ ;; CHECK: (export "anyref-both-dupe" (func $stub$anyref-both-dupe))
+
+ ;; CHECK: (export "many" (func $stub$many))
+
+ ;; CHECK: (export "mixed" (func $stub$mixed))
+
+ ;; CHECK: (func $normal (type $7) (param $x i32) (result f64)
+ ;; CHECK-NEXT: (f64.const 3.14159)
+ ;; CHECK-NEXT: )
+ (func $normal (export "normal") (param $x i32) (result f64)
+ ;; A normal function which we do not need to do anything with.
+ (f64.const 3.14159)
+ )
+
+ ;; CHECK: (func $externref-param (type $2) (param $x externref)
+ ;; CHECK-NEXT: )
+ (func $externref-param (export "externref-param") (param $x externref)
+ ;; An externref param is fine, we don't need to do anything.
+ )
+
+ ;; CHECK: (func $externref-result (type $3) (result externref)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $externref-result (export "externref-result") (result externref)
+ ;; An externref result is also fine.
+ (unreachable)
+ )
+
+ ;; CHECK: (func $anyref-param (type $8) (param $x anyref)
+ ;; CHECK-NEXT: )
+ (func $anyref-param (export "anyref-param") (param $x anyref)
+ ;; An anyref requires a fixup. We will call this from a stub that has an
+ ;; externref param, which calls this.
+ )
+
+ ;; CHECK: (func $anyref-result (type $9) (result anyref)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $anyref-result (export "anyref-result") (result anyref)
+ ;; An anyref result also requires a fixup.
+ (unreachable)
+ )
+
+ ;; CHECK: (func $anyref-both (type $4) (param $x anyref) (result anyref)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $anyref-both (export "anyref-both") (param $x anyref) (result anyref)
+ ;; Here we must fix up both the param and the result.
+ (unreachable)
+ )
+
+ ;; CHECK: (func $anyref-both-dupe (type $4) (param $x anyref) (result anyref)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $anyref-both-dupe (export "anyref-both-dupe") (param $x anyref) (result anyref)
+ ;; Identical to the above function, and should be fixed up in the same
+ ;; manner. In theory we could use the same stub for both, but we leave that
+ ;; for the optimizer.
+ (unreachable)
+ )
+
+ ;; CHECK: (func $many (type $10) (param $a (ref $A)) (param $b (ref null $B)) (result (ref $C))
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $many (export "many") (param $a (ref $A)) (param $b (ref null $B)) (result (ref $C))
+ ;; Various declared types are used, and must be fixed up.
+ (unreachable)
+ )
+
+ ;; CHECK: (func $mixed (type $11) (param $a i32) (param $b (ref $A)) (param $c funcref)
+ ;; CHECK-NEXT: )
+ (func $mixed (export "mixed") (param $a i32) (param $b (ref $A)) (param $c funcref)
+ ;; One param needs to be fixed, two others do not: we can ignore i32 and
+ ;; funcref.
+ )
+)
+
+;; CHECK: (func $stub$anyref-param (type $2) (param $0 externref)
+;; CHECK-NEXT: (call $anyref-param
+;; CHECK-NEXT: (ref.cast anyref
+;; CHECK-NEXT: (any.convert_extern
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+
+;; CHECK: (func $stub$anyref-result (type $3) (result externref)
+;; CHECK-NEXT: (extern.convert_any
+;; CHECK-NEXT: (call $anyref-result)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+
+;; CHECK: (func $stub$anyref-both (type $5) (param $0 externref) (result externref)
+;; CHECK-NEXT: (extern.convert_any
+;; CHECK-NEXT: (call $anyref-both
+;; CHECK-NEXT: (ref.cast anyref
+;; CHECK-NEXT: (any.convert_extern
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+
+;; CHECK: (func $stub$anyref-both-dupe (type $5) (param $0 externref) (result externref)
+;; CHECK-NEXT: (extern.convert_any
+;; CHECK-NEXT: (call $anyref-both-dupe
+;; CHECK-NEXT: (ref.cast anyref
+;; CHECK-NEXT: (any.convert_extern
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+
+;; CHECK: (func $stub$many (type $12) (param $0 externref) (param $1 externref) (result externref)
+;; CHECK-NEXT: (extern.convert_any
+;; CHECK-NEXT: (call $many
+;; CHECK-NEXT: (ref.cast (ref $A)
+;; CHECK-NEXT: (any.convert_extern
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (ref.cast (ref null $B)
+;; CHECK-NEXT: (any.convert_extern
+;; CHECK-NEXT: (local.get $1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+
+;; CHECK: (func $stub$mixed (type $13) (param $0 i32) (param $1 externref) (param $2 funcref)
+;; CHECK-NEXT: (call $mixed
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (ref.cast (ref $A)
+;; CHECK-NEXT: (any.convert_extern
+;; CHECK-NEXT: (local.get $1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $2)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+(module
+ ;; Two exports of a single function that needs fixups. We could reuse a
+ ;; single stub, but we leave that for the optimizer.
+
+ (export "a" (func $anyref-both))
+
+ (export "b" (func $anyref-both))
+
+ ;; CHECK: (type $0 (func (param externref) (result externref)))
+
+ ;; CHECK: (type $1 (func (param anyref) (result anyref)))
+
+ ;; CHECK: (export "a" (func $stub$anyref-both))
+
+ ;; CHECK: (export "b" (func $stub$anyref-both_2))
+
+ ;; CHECK: (func $anyref-both (type $1) (param $x anyref) (result anyref)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $anyref-both (param $x anyref) (result anyref)
+ (unreachable)
+ )
+)
+;; CHECK: (func $stub$anyref-both (type $0) (param $0 externref) (result externref)
+;; CHECK-NEXT: (extern.convert_any
+;; CHECK-NEXT: (call $anyref-both
+;; CHECK-NEXT: (ref.cast anyref
+;; CHECK-NEXT: (any.convert_extern
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+
+;; CHECK: (func $stub$anyref-both_2 (type $0) (param $0 externref) (result externref)
+;; CHECK-NEXT: (extern.convert_any
+;; CHECK-NEXT: (call $anyref-both
+;; CHECK-NEXT: (ref.cast anyref
+;; CHECK-NEXT: (any.convert_extern
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
diff --git a/test/passes/fuzz_metrics_passes_noprint.bin.txt b/test/passes/fuzz_metrics_passes_noprint.bin.txt
index b4d67bab0..5e0dbfe07 100644
--- a/test/passes/fuzz_metrics_passes_noprint.bin.txt
+++ b/test/passes/fuzz_metrics_passes_noprint.bin.txt
@@ -1,35 +1,35 @@
Metrics
total
- [exports] : 23
- [funcs] : 34
- [globals] : 30
+ [exports] : 50
+ [funcs] : 64
+ [globals] : 24
[imports] : 5
[memories] : 1
- [memory-data] : 17
- [table-data] : 6
+ [memory-data] : 15
+ [table-data] : 16
[tables] : 1
[tags] : 0
- [total] : 9415
- [vars] : 105
- Binary : 726
- Block : 1537
- Break : 331
- Call : 306
- CallIndirect : 10
- Const : 1479
- Drop : 83
- GlobalGet : 778
- GlobalSet : 584
- If : 531
- Load : 164
- LocalGet : 774
- LocalSet : 570
- Loop : 244
- Nop : 105
- RefFunc : 6
- Return : 94
- Select : 70
- Store : 86
- Switch : 2
- Unary : 654
- Unreachable : 281
+ [total] : 6973
+ [vars] : 223
+ Binary : 534
+ Block : 1168
+ Break : 228
+ Call : 282
+ CallIndirect : 38
+ Const : 1083
+ Drop : 115
+ GlobalGet : 580
+ GlobalSet : 444
+ If : 354
+ Load : 113
+ LocalGet : 501
+ LocalSet : 367
+ Loop : 148
+ Nop : 99
+ RefFunc : 16
+ Return : 91
+ Select : 53
+ Store : 70
+ Switch : 1
+ Unary : 466
+ Unreachable : 222
diff --git a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt
index a77708b2e..8df9d033c 100644
--- a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt
+++ b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt
@@ -1,48 +1,54 @@
Metrics
total
- [exports] : 6
- [funcs] : 12
+ [exports] : 9
+ [funcs] : 10
[globals] : 4
[imports] : 8
[memories] : 1
[memory-data] : 112
- [table-data] : 3
+ [table-data] : 2
[tables] : 1
- [tags] : 0
- [total] : 608
- [vars] : 48
- ArrayNew : 5
+ [tags] : 1
+ [total] : 682
+ [vars] : 37
+ ArrayLen : 1
+ ArrayNew : 7
ArrayNewFixed : 5
- Binary : 75
- Block : 80
- BrOn : 5
- Break : 4
- Call : 21
- CallRef : 1
- Const : 113
+ ArraySet : 1
+ AtomicNotify : 1
+ Binary : 79
+ Block : 72
+ BrOn : 4
+ Break : 7
+ Call : 19
+ Const : 149
Drop : 15
- GlobalGet : 39
- GlobalSet : 36
- If : 21
- Load : 17
- LocalGet : 45
- LocalSet : 20
+ GlobalGet : 35
+ GlobalSet : 32
+ If : 20
+ Load : 20
+ LocalGet : 55
+ LocalSet : 26
Loop : 7
- Nop : 7
- RefAs : 2
+ MemoryFill : 1
+ Nop : 9
+ Pop : 1
+ RefAs : 1
+ RefCast : 1
RefEq : 1
- RefFunc : 9
- RefI31 : 1
- RefIsNull : 1
+ RefFunc : 17
+ RefI31 : 2
+ RefIsNull : 2
RefNull : 8
Return : 5
- Select : 2
+ SIMDExtract : 3
Store : 1
- StringConst : 4
- StringEq : 1
- StringMeasure : 2
- StructNew : 13
- TupleExtract : 1
+ StringConst : 3
+ StringMeasure : 1
+ StringWTF16Get : 1
+ StructNew : 23
+ Try : 1
+ TupleExtract : 3
TupleMake : 4
- Unary : 19
- Unreachable : 18
+ Unary : 23
+ Unreachable : 16