diff options
-rwxr-xr-x | check.py | 2 | ||||
-rw-r--r-- | src/tools/fuzzing.h | 199 | ||||
-rw-r--r-- | test/passes/translate-to-fuzz.txt | 1860 |
3 files changed, 967 insertions, 1094 deletions
@@ -313,7 +313,7 @@ def run_wasm_reduce_tests(): before = os.stat('a.wasm').st_size run_command(WASM_REDUCE + ['a.wasm', '--command=%s b.wasm --fuzz-exec' % WASM_OPT[0], '-t', 'b.wasm', '-w', 'c.wasm']) after = os.stat('c.wasm').st_size - assert after < 0.333 * before, [before, after] + assert after < 0.6 * before, [before, after] def run_spec_tests(): diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index fe31290d6..8fa2e08fa 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -26,7 +26,10 @@ high chance for set at start of loop */ #include <wasm-builder.h> +#include <ir/find_all.h> #include <ir/literal-utils.h> +#include <ir/manipulation.h> +#include <ir/utils.h> namespace wasm { @@ -392,11 +395,18 @@ private: } else { func->body = make(bodyType); } + // Recombinations create duplicate code patterns. + recombine(func); + // Mutations add random small changes, which can subtly break duplicate code + // patterns. + mutate(func); + // TODO: liveness operations on gets, with some prob alter a get to one with + // more possible sets + // Recombination, mutation, etc. can break validation; fix things up after. + fixLabels(func); + // Add hang limit checks after all other operations on the function body. if (HANG_LIMIT > 0) { - func->body = builder.makeSequence( - makeHangLimitCheck(), - func->body - ); + addHangLimitChecks(func); } assert(breakableStack.empty()); assert(hangStack.empty()); @@ -420,6 +430,181 @@ private: return func; } + void addHangLimitChecks(Function* func) { + // loop limit + FindAll<Loop> loops(func->body); + for (auto* loop : loops.list) { + loop->body = builder.makeSequence( + makeHangLimitCheck(), + loop->body + ); + } + // recursion limit + func->body = builder.makeSequence( + makeHangLimitCheck(), + func->body + ); + } + + void recombine(Function* func) { + // Don't always do this. + if (oneIn(2)) return; + // First, scan and group all expressions by type. + struct Scanner : public PostWalker<Scanner, UnifiedExpressionVisitor<Scanner>> { + // A map of all expressions, categorized by type. + std::map<Type, std::vector<Expression*>> exprsByType; + + void visitExpression(Expression* curr) { + exprsByType[curr->type].push_back(curr); + } + }; + Scanner scanner; + scanner.walk(func->body); + // Potentially trim the list of possible picks, so replacements are more likely + // to collide. + for (auto& pair : scanner.exprsByType) { + if (oneIn(2)) continue; + auto& list = pair.second; + std::vector<Expression*> trimmed; + size_t num = upToSquared(list.size()); + for (size_t i = 0; i < num; i++) { + trimmed.push_back(vectorPick(list)); + } + if (trimmed.empty()) { + trimmed.push_back(vectorPick(list)); + } + list.swap(trimmed); + } + // Replace them with copies, to avoid a copy into one altering another copy + for (auto& pair : scanner.exprsByType) { + for (auto*& item : pair.second) { + item = ExpressionManipulator::copy(item, wasm); + } + } + // Second, with some probability replace an item with another item having + // the same type. (This is not always valid due to nesting of labels, but + // we'll fix that up later.) + struct Modder : public PostWalker<Modder, UnifiedExpressionVisitor<Modder>> { + Module& wasm; + Scanner& scanner; + TranslateToFuzzReader& parent; + + Modder(Module& wasm, Scanner& scanner, TranslateToFuzzReader& parent) : wasm(wasm), scanner(scanner), parent(parent) {} + + void visitExpression(Expression* curr) { + if (parent.oneIn(10)) { + // Replace it! + auto& candidates = scanner.exprsByType[curr->type]; + assert(!candidates.empty()); // this expression itself must be there + replaceCurrent(ExpressionManipulator::copy(parent.vectorPick(candidates), wasm)); + } + } + }; + Modder modder(wasm, scanner, *this); + modder.walk(func->body); + } + + void mutate(Function* func) { + // Don't always do this. + if (oneIn(2)) return; + struct Modder : public PostWalker<Modder, UnifiedExpressionVisitor<Modder>> { + Module& wasm; + TranslateToFuzzReader& parent; + + Modder(Module& wasm, TranslateToFuzzReader& parent) : wasm(wasm), parent(parent) {} + + void visitExpression(Expression* curr) { + if (parent.oneIn(10)) { + // Replace it! + // (This is not always valid due to nesting of labels, but + // we'll fix that up later.) + replaceCurrent(parent.make(curr->type)); + } + } + }; + Modder modder(wasm, *this); + modder.walk(func->body); + } + + // Fix up changes that may have broken validation - types are correct in our + // modding, but not necessarily labels. + void fixLabels(Function* func) { + struct Fixer : public ControlFlowWalker<Fixer> { + Module& wasm; + TranslateToFuzzReader& parent; + + Fixer(Module& wasm, TranslateToFuzzReader& parent) : wasm(wasm), parent(parent) {} + + // Track seen names to find duplication, which is invalid. + std::set<Name> seen; + + void visitBlock(Block* curr) { + if (curr->name.is()) { + if (seen.count(curr->name)) { + replace(); + } else { + seen.insert(curr->name); + } + } + } + + void visitLoop(Loop* curr) { + if (curr->name.is()) { + if (seen.count(curr->name)) { + replace(); + } else { + seen.insert(curr->name); + } + } + } + + void visitSwitch(Switch* curr) { + for (auto name : curr->targets) { + if (replaceIfInvalid(name)) return; + } + replaceIfInvalid(curr->default_); + } + + void visitBreak(Break* curr) { + replaceIfInvalid(curr->name); + } + + bool replaceIfInvalid(Name target) { + if (!hasBreakTarget(target)) { + // There is no valid parent, replace with something trivially safe. + replace(); + return true; + } + return false; + } + + void replace() { + replaceCurrent(parent.makeTrivial(getCurrent()->type)); + } + + bool hasBreakTarget(Name name) { + if (controlFlowStack.empty()) return false; + Index i = controlFlowStack.size() - 1; + while (1) { + auto* curr = controlFlowStack[i]; + if (Block* block = curr->template dynCast<Block>()) { + if (name == block->name) return true; + } else if (Loop* loop = curr->template dynCast<Loop>()) { + if (name == loop->name) return true; + } else { + // an if, ignorable + assert(curr->template is<If>()); + } + if (i == 0) return false; + i--; + } + } + }; + Fixer fixer(wasm, *this); + fixer.walk(func->body); + ReFinalize().walkFunctionInModule(func, &wasm); + } + // the fuzzer external interface sends in zeros (simpler to compare // across invocations from JS or wasm-opt etc.). Add invocations in // the wasm, so they run everywhere @@ -651,12 +836,6 @@ private: } breakableStack.pop_back(); hangStack.pop_back(); - if (HANG_LIMIT > 0) { - ret->body = builder.makeSequence( - makeHangLimitCheck(), - ret->body - ); - } ret->finalize(); return ret; } diff --git a/test/passes/translate-to-fuzz.txt b/test/passes/translate-to-fuzz.txt index 85df534d0..c1febc37d 100644 --- a/test/passes/translate-to-fuzz.txt +++ b/test/passes/translate-to-fuzz.txt @@ -1,20 +1,25 @@ (module (type $FUNCSIG$i (func (result i32))) + (type $FUNCSIG$vjifiiji (func (param i64 i32 f32 i32 i32 i64 i32))) + (type $FUNCSIG$jdfiid (func (param f64 f32 i32 i32 f64) (result i64))) (type $FUNCSIG$v (func)) - (type $FUNCSIG$ifj (func (param f32 i64) (result i32))) (memory $0 (shared 1 1)) (data (i32.const 0) "n\00\05E\00\00\00\00") - (table $0 4 anyfunc) - (elem (i32.const 0) $func_2 $func_4 $func_5 $func_8) + (table $0 2 2 anyfunc) + (elem (i32.const 0) $func_2 $func_14) (global $global$0 (mut f32) (f32.const 536870912)) (global $global$1 (mut f32) (f32.const 2147483648)) (global $global$2 (mut f64) (f64.const -1048576)) (global $global$3 (mut f64) (f64.const 23643)) (global $hangLimit (mut i32) (i32.const 10)) (export "func_0" (func $func_0)) - (export "func_2_invoker" (func $func_2_invoker)) - (export "func_4" (func $func_4)) - (export "func_5" (func $func_5)) + (export "func_1" (func $func_1)) + (export "func_3" (func $func_3)) + (export "func_3_invoker" (func $func_3_invoker)) + (export "func_5_invoker" (func $func_5_invoker)) + (export "func_7_invoker" (func $func_7_invoker)) + (export "func_10_invoker" (func $func_10_invoker)) + (export "func_13" (func $func_13)) (export "hangLimitInitializer" (func $hangLimitInitializer)) (func $func_0 (; 0 ;) (type $FUNCSIG$i) (result i32) (local $0 i32) @@ -44,12 +49,7 @@ (get_local $0) ) ) - (func $func_1 (; 1 ;) (param $0 f64) (param $1 f64) - (local $2 f64) - (local $3 i32) - (local $4 i32) - (local $5 f32) - (local $6 i32) + (func $func_1 (; 1 ;) (type $FUNCSIG$vjifiiji) (param $0 i64) (param $1 i32) (param $2 f32) (param $3 i32) (param $4 i32) (param $5 i64) (param $6 i32) (block (if (i32.eqz @@ -64,80 +64,33 @@ ) ) ) - (block $label$0 - (block $label$1 - (br_if $label$0 - (loop $label$2 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block $label$3 (result i32) - (block $label$4 - (loop $label$5 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (nop) - ) - (set_local $3 - (get_local $4) - ) - ) - (i32.const 1964724085) - ) - ) - ) - (i64.store offset=22 align=2 - (i32.and - (tee_local $3 - (get_local $3) - ) - (i32.const 15) - ) - (i64.const 8796093022208) - ) + (drop + (i32.atomic.store16 offset=22 + (return) + (get_local $1) ) ) ) - (func $func_2 (; 2 ;) (param $0 i32) (param $1 f64) (param $2 i64) (result f32) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i64) + (func $func_2 (; 2 ;) (type $FUNCSIG$v) + (local $0 f64) + (local $1 f32) + (local $2 i64) + (local $3 f64) + (local $4 f64) + (local $5 f64) + (local $6 f32) (local $7 i32) - (local $8 i64) + (local $8 i32) (local $9 f64) - (local $10 i32) + (local $10 f64) + (local $11 f64) + (local $12 i64) (block (if (i32.eqz (get_global $hangLimit) ) - (return - (f32.const 20550) - ) + (return) ) (set_global $hangLimit (i32.sub @@ -146,106 +99,45 @@ ) ) ) - (f32.load offset=3 align=1 - (i32.and - (block $label$0 (result i32) - (set_local $9 - (if (result f64) - (tee_local $4 - (i32.const 318767360) - ) - (block $label$1 (result f64) - (return - (f32.const -8796093022208) - ) - ) - (block $label$2 (result f64) - (set_local $8 - (i64.const 562949953421312) - ) - (return - (f32.const 12849) + (block $label$0 + (set_local $12 + (tee_local $2 + (tee_local $2 + (tee_local $12 + (tee_local $2 + (tee_local $2 + (get_local $12) ) ) ) ) - (return - (f32.const 288230376151711744) - ) ) - (i32.const 15) ) - ) - ) - (func $func_2_invoker (; 3 ;) (type $FUNCSIG$v) - (drop - (call $func_2 - (i32.const 1091126348) - (f64.const 576460752303423488) - (i64.const 127) - ) - ) - ) - (func $func_4 (; 4 ;) (type $FUNCSIG$ifj) (param $0 f32) (param $1 i64) (result i32) - (local $2 i64) - (block - (if + (br_if $label$0 (i32.eqz - (get_global $hangLimit) - ) - (return - (i32.const -72) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) + (i32.const 2004815888) ) ) ) - (i32.const -16777216) ) - (func $func_5 (; 5 ;) (type $FUNCSIG$v) - (local $0 f32) - (local $1 f64) - (local $2 f32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block $label$0 - (f64.store offset=22 align=2 - (i32.const -33554432) - (f64.const 32125) - ) - (call $func_5) - ) - ) - (func $func_6 (; 6 ;) (result f32) - (local $0 f32) - (local $1 f64) - (local $2 i64) - (local $3 f32) - (local $4 f64) + (func $func_3 (; 3 ;) (type $FUNCSIG$jdfiid) (param $0 f64) (param $1 f32) (param $2 i32) (param $3 i32) (param $4 f64) (result i64) (local $5 i32) + (local $6 i64) + (local $7 f64) + (local $8 f64) + (local $9 i64) + (local $10 f64) + (local $11 i64) + (local $12 f32) + (local $13 i32) + (local $14 f64) (block (if (i32.eqz (get_global $hangLimit) ) (return - (get_local $3) + (i64.const 6) ) ) (set_global $hangLimit @@ -255,503 +147,29 @@ ) ) ) - (loop $label$0 (result f32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f32.const -9223372036854775808) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block (result f32) - (block $label$1 - (br_if $label$0 - (i32.eqz - (loop $label$2 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f32.const -9223372036854775808) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block (result i32) - (block $label$3 - (set_local $2 - (i64.const -4294967296) - ) - (loop $label$4 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $0) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block - (block $label$5 - (block $label$6 - (if - (tee_local $5 - (i32.const 0) - ) - (block $label$7 - (set_local $2 - (if (result i64) - (if (result i32) - (get_local $5) - (block $label$8 (result i32) - (loop $label$9 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $3) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block - (block $label$10 - (set_local $5 - (get_local $5) - ) - (loop $label$11 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f32.const 10224159) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (if - (get_local $5) - (set_local $1 - (loop $label$12 (result f64) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f32.const 33554432) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block (result f64) - (set_local $5 - (get_local $5) - ) - (br_if $label$12 - (get_local $5) - ) - (f64.const 4294967287) - ) - ) - ) - (set_local $4 - (tee_local $4 - (f64.const 1.0166542203434788e-128) - ) - ) - ) - ) - ) - (br_if $label$9 - (i32.const -65536) - ) - (if - (get_local $5) - (set_local $1 - (loop $label$13 (result f64) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f32.const 1.8506835061833649e-13) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (f64.const -16384) - ) - ) - (set_local $0 - (call $func_6) - ) - ) - ) - ) - (br $label$5) - ) - (block $label$14 (result i32) - (block $label$15 - (br_if $label$1 - (i32.const -32768) - ) - (br_if $label$2 - (get_local $5) - ) - ) - (tee_local $5 - (loop $label$16 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $3) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block (result i32) - (set_local $2 - (get_local $2) - ) - (br_if $label$16 - (i32.eqz - (get_local $5) - ) - ) - (br_if $label$14 - (i32.const -128) - (i32.eqz - (i32.const -76) - ) - ) - ) - ) - ) - ) - ) - (loop $label$17 (result i64) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f32.const 9223372036854775808) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block (result i64) - (block $label$18 - (loop $label$19 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $3) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (set_local $0 - (tee_local $3 - (get_local $0) - ) - ) - ) - (loop $label$20 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $3) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (nop) - ) - ) - (br_if $label$17 - (i32.eqz - (call $func_4 - (get_local $0) - (tee_local $2 - (tee_local $2 - (i64.const 144115188075855872) - ) - ) - ) - ) - ) - (get_local $2) - ) - ) - (block $label$22 (result i64) - (br_if $label$3 - (i32.eqz - (i32.const 127) - ) - ) - (br $label$1) - ) - ) - ) - (set_local $2 - (i64.const 65534) - ) - ) - (nop) - ) - (set_local $3 - (f32.const 992448126130323456) - ) - ) - (set_local $3 - (f32.const 119) - ) - ) - (br_if $label$4 - (i32.const -2147483648) - ) - (set_local $5 - (get_local $5) - ) - ) - ) - ) - (br_if $label$2 - (i32.eqz - (i32.const -78) - ) - ) - (if (result i32) - (i32.eqz - (i32.const 128) - ) - (i32.const 247) - (block $label$23 (result i32) - (loop $label$24 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f32.const 4.610071063378019e-28) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block $label$25 - (set_local $4 - (tee_local $1 - (tee_local $4 - (tee_local $1 - (f64.const -512) - ) - ) - ) - ) - (set_local $2 - (i64.const 2147483647) - ) - ) - ) - (tee_local $5 - (tee_local $5 - (br_if $label$23 - (get_local $5) - (tee_local $5 - (tee_local $5 - (tee_local $5 - (tee_local $5 - (i32.const -13) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - (set_local $3 - (get_local $3) - ) - ) - (br_if $label$0 - (i32.ge_s - (i32.const -4194304) - (block $label$27 (result i32) - (if - (get_local $5) - (set_local $4 - (loop $label$28 (result f64) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f32.const 8) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (tee_local $4 - (if (result f64) - (i32.eqz - (i32.trunc_u/f64 - (f64.const -4294967294) - ) - ) - (get_local $4) - (block $label$29 (result f64) - (set_local $4 - (f64.const 2097152) - ) - (br $label$28) - ) - ) - ) - ) - ) - (block $label$30 - (nop) - (br_if $label$30 - (i32.atomic.rmw8_u.sub offset=3 - (i32.and - (br_if $label$27 - (get_local $5) - (tee_local $5 - (get_local $5) - ) - ) - (i32.const 15) - ) - (tee_local $5 - (get_local $5) - ) - ) - ) - ) - ) - (get_local $5) - ) - ) - ) - (f32.const 1) + (block $label$0 (result i64) + (i64.const 1785357419) + ) + ) + (func $func_3_invoker (; 4 ;) (type $FUNCSIG$v) + (drop + (call $func_3 + (f64.const 8) + (f32.const 5.044674471569341e-44) + (i32.const 128) + (i32.const 65525) + (f64.const 2147483647) ) ) ) - (func $func_7 (; 7 ;) (result f32) - (local $0 i32) - (local $1 f64) - (local $2 f32) - (local $3 f64) - (local $4 i32) - (local $5 f32) - (local $6 i64) - (local $7 i64) + (func $func_5 (; 5 ;) (result f64) (block (if (i32.eqz (get_global $hangLimit) ) (return - (f32.const 2147483648) + (f64.const -4611686018427387904) ) ) (set_global $hangLimit @@ -761,18 +179,21 @@ ) ) ) - (block $label$0 (result f32) - (get_local $2) + (f64.const -1.1754943508222875e-38) + ) + (func $func_5_invoker (; 6 ;) (type $FUNCSIG$v) + (drop + (call $func_5) ) ) - (func $func_8 (; 8 ;) (param $0 f64) (param $1 f32) (param $2 i32) (param $3 f64) (result f64) + (func $func_7 (; 7 ;) (param $0 i32) (result i64) (block (if (i32.eqz (get_global $hangLimit) ) (return - (get_local $0) + (i64.const 0) ) ) (set_global $hangLimit @@ -782,14 +203,14 @@ ) ) ) - (loop $label$0 (result f64) + (loop $label$0 (result i64) (block (if (i32.eqz (get_global $hangLimit) ) (return - (get_local $0) + (i64.const 769) ) ) (set_global $hangLimit @@ -799,114 +220,56 @@ ) ) ) - (block (result f64) + (block $label$1 (result i64) (nop) - (br_if $label$0 - (i32.eqz - (loop $label$1 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f64.const 72) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) + (loop $label$2 (result i64) + (block + (if + (i32.eqz + (get_global $hangLimit) ) - (block (result i32) - (block $label$2 - (set_local $2 - (loop $label$3 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $3) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block $label$4 (result i32) - (br $label$1) - ) + (return + (i64.const -2048) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (block (result i64) + (block $label$3 + (nop) + (block $label$4 + (nop) + (nop) + (nop) + ) + ) + (br_if $label$2 + (i32.eqz + (if (result i32) + (i32.const 256) + (block $label$5 (result i32) + (br_if $label$2 + (get_local $0) ) - ) - (loop $label$5 - (block - (if + (if (result i32) + (if (result i32) (i32.eqz - (get_global $hangLimit) - ) - (return - (f64.const 137438953472) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) + (i32.const 1821) ) - ) - ) - (block - (block $label$6 - (set_local $2 - (get_local $2) - ) - (loop $label$7 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $0) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (br_if $label$5 - (block $label$8 (result i32) - (set_local $0 - (f64.const -4) - ) - (br $label$5) - ) - ) - ) - ) - (br_if $label$5 - (i32.const 1785357419) - ) - (set_local $2 - (if (result i32) - (loop $label$9 (result i32) + (block $label$6 (result i32) + (loop $label$7 (block (if (i32.eqz (get_global $hangLimit) ) (return - (get_local $0) + (i64.const 471139612) ) ) (set_global $hangLimit @@ -916,19 +279,80 @@ ) ) ) - (block (result i32) - (block $label$10 - (set_local $2 - (i32.const 514) + (nop) + ) + (tee_local $0 + (tee_local $0 + (loop $label$8 (result i32) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (i64.const 1448499994801557011) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) ) - (set_local $2 - (get_local $2) + (block $label$9 (result i32) + (set_local $0 + (tee_local $0 + (if (result i32) + (get_local $0) + (i32.const -32767) + (i32.const -96) + ) + ) + ) + (br_if $label$9 + (i32.const 28798) + (i32.const 7766) + ) ) ) - (br_if $label$9 - (block $label$11 (result i32) - (br_if $label$5 + ) + ) + ) + (block $label$10 (result i32) + (br_if $label$0 + (i32.eqz + (br_if $label$10 + (br_if $label$10 + (tee_local $0 + (tee_local $0 + (i32.const -32768) + ) + ) + (if (result i32) (i32.eqz + (get_local $0) + ) + (br_if $label$5 + (loop $label$13 (result i32) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (i64.const 4611686018427387904) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (i32.const -127) + ) (loop $label$12 (result i32) (block (if @@ -936,7 +360,7 @@ (get_global $hangLimit) ) (return - (f64.const 2.573976383481498e-159) + (i64.const 1088542939510032975) ) ) (set_global $hangLimit @@ -946,38 +370,28 @@ ) ) ) - (block $label$13 (result i32) + (block (result i32) (nop) - (br $label$9) + (br_if $label$12 + (i32.eqz + (i32.const -2147483647) + ) + ) + (i32.const 370416410) ) ) ) - ) - (br $label$0) - ) - ) - (block $label$14 (result i32) - (set_local $0 - (tee_local $0 - (get_local $0) - ) - ) - (br_if $label$14 - (tee_local $2 - (i32.const -127) - ) - (block $label$15 (result i32) - (if - (get_local $2) - (block $label$16 - (loop $label$17 + (block $label$14 (result i32) + (nop) + (block $label$15 (result i32) + (loop $label$16 (block (if (i32.eqz (get_global $hangLimit) ) (return - (get_local $0) + (i64.const 539505204) ) ) (set_global $hangLimit @@ -987,133 +401,157 @@ ) ) ) - (block - (set_local $3 - (get_local $3) - ) - (br_if $label$17 - (i32.eqz - (block $label$18 (result i32) - (set_local $0 - (f64.const 7) - ) - (loop $label$19 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f64.const -nan:0xfffffffffffee) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block (result i32) - (set_local $0 - (get_local $3) - ) - (br_if $label$19 - (get_local $2) - ) - (i32.const -255) - ) - ) - ) - ) - ) - (set_local $3 - (f64.const 0.0056707351085018) + (br_if $label$2 + (i32.eqz + (i32.const -127) ) ) ) - (block $label$20 - (nop) - (nop) - ) + (get_local $0) ) - (block $label$21 - (br_if $label$2 - (get_local $2) - ) - (set_local $1 - (get_local $1) + ) + ) + ) + (if (result i32) + (br_if $label$5 + (i32.const 18) + (tee_local $0 + (br_if $label$10 + (i32.const 843467308) + (i32.eqz + (get_local $0) ) ) ) - (br $label$1) + ) + (block $label$11 + (set_local $0 + (tee_local $0 + (i32.const 64) + ) + ) + (br $label$2) + ) + (tee_local $0 + (tee_local $0 + (tee_local $0 + (get_local $0) + ) + ) ) ) ) ) ) - (block $label$22 (result i32) - (if - (i32.eqz - (i32.const -32768) - ) - (set_local $1 - (tee_local $1 - (call $deNan32 - (select - (tee_local $1 - (block $label$26 (result f32) - (set_local $2 - (i32.const 19027) + (tee_local $0 + (br_if $label$5 + (br_if $label$5 + (get_local $0) + (loop $label$22 (result i32) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (i64.const -65535) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (block (result i32) + (block $label$23 + (br_if $label$0 + (i32.eqz + (get_local $0) + ) + ) + (br_if $label$23 + (i32.eqz + (block $label$24 (result i32) + (nop) + (i32.const 67) ) - (br $label$5) ) ) - (f32.const 1540) - (loop $label$23 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f64.const 34359738368) - ) + ) + (br_if $label$22 + (i32.eqz + (br_if $label$5 + (tee_local $0 + (i32.const -512) ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) + (i32.eqz + (get_local $0) ) ) - (block (result i32) - (block $label$24 - (set_local $3 - (f64.const -512) + ) + ) + (if (result i32) + (i32.eqz + (block $label$25 (result i32) + (nop) + (get_local $0) + ) + ) + (block $label$26 + (loop $label$27 + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (i64.const 35994423) + ) ) - (set_local $0 - (get_local $3) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) ) ) - (br_if $label$23 - (i32.eqz - (tee_local $2 - (br_if $label$22 - (i32.const 4) - (get_local $2) - ) + (block + (nop) + (br_if $label$27 + (i32.eqz + (i32.const 6918) ) ) + (nop) ) - (loop $label$25 (result i32) + ) + (br $label$0) + ) + (tee_local $0 + (tee_local $0 + (i32.const -32768) + ) + ) + ) + ) + ) + ) + (i32.eqz + (tee_local $0 + (if (result i32) + (i32.eqz + (if (result i32) + (i32.eqz + (loop $label$17 (result i32) (block (if (i32.eqz (get_global $hangLimit) ) (return - (f64.const 28) + (i64.const -62) ) ) (set_global $hangLimit @@ -1123,70 +561,23 @@ ) ) ) - (i32.const -50) + (block (result i32) + (nop) + (br_if $label$17 + (get_local $0) + ) + (get_local $0) + ) ) ) - ) - ) - ) - ) - ) - (block $label$28 - (nop) - (set_local $2 - (br_if $label$22 - (i32.const -2147483647) - (i32.eqz - (get_local $2) - ) - ) - ) - ) - ) - (if (result i32) - (i32.eqz - (block $label$29 (result i32) - (tee_local $2 - (tee_local $2 - (tee_local $2 - (tee_local $2 - (i32.const -65535) - ) - ) - ) - ) - ) - ) - (block $label$30 (result i32) - (set_local $2 - (loop $label$31 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f64.const -3402823466385288598117041e14) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block $label$32 (result i32) - (br_if $label$22 - (get_local $2) - (loop $label$33 (result i32) + (loop $label$18 (result i32) (block (if (i32.eqz (get_global $hangLimit) ) (return - (f64.const 17672) + (i64.const -9223372036854775806) ) ) (set_global $hangLimit @@ -1196,46 +587,27 @@ ) ) ) - (block (result i32) - (block $label$34 - (nop) - ) - (br_if $label$33 - (i32.eqz - (tee_local $2 - (i32.const 6) - ) - ) - ) - (get_local $2) + (i32.const 255) + ) + (block $label$19 + (call_indirect (type $FUNCSIG$v) + (i32.const 0) + ) + (return + (i64.const 65535) ) ) ) ) - ) - ) - (br_if $label$22 - (tee_local $2 - (i32.const 32) - ) - (i32.eqz - (get_local $2) - ) - ) - ) - (br_if $label$22 - (get_local $2) - (i32.eqz - (i32.lt_u - (get_local $2) - (tee_local $2 - (tee_local $2 - (if (result i32) - (i32.const -16) - (i32.const -32768) - (tee_local $2 - (get_local $2) - ) + (i32.const -4) + (block $label$20 (result i32) + (nop) + (block $label$21 (result i32) + (set_local $0 + (get_local $0) + ) + (tee_local $0 + (get_local $0) ) ) ) @@ -1244,18 +616,53 @@ ) ) ) - (block $label$35 (result i32) - (set_local $1 - (tee_local $1 - (tee_local $1 - (loop $label$36 (result f32) + ) + ) + (block $label$28 (result i32) + (nop) + (get_local $0) + ) + (tee_local $0 + (i32.const 508566559) + ) + ) + ) + (block $label$29 (result i32) + (set_local $0 + (loop $label$30 (result i32) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (i64.const -9223372036854775808) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (block (result i32) + (block $label$31 + (nop) + (nop) + ) + (br_if $label$30 + (i32.eqz + (block $label$32 + (if + (loop $label$33 (result i32) (block (if (i32.eqz (get_global $hangLimit) ) (return - (f64.const 2147483648) + (i64.const 549755813888) ) ) (set_global $hangLimit @@ -1265,162 +672,449 @@ ) ) ) - (block (result f32) - (if - (if (result i32) - (i32.eqz - (i32.const -112) - ) - (i32.const 67108864) - (loop $label$37 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f64.const 20054) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block (result i32) - (nop) - (br_if $label$37 - (i32.eqz - (i32.const 486999634) - ) + (block (result i32) + (block $label$34 + (nop) + (set_local $0 + (call $func_0) + ) + ) + (br_if $label$33 + (i32.eqz + (tee_local $0 + (tee_local $0 + (tee_local $0 + (i32.const -82) ) - (i32.const 134217728) ) ) ) - (block $label$38 - (set_local $2 - (get_local $2) - ) - (br_if $label$36 - (i32.const 341772310) - ) - ) - (block $label$39 - (loop $label$40 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $0) + ) + (tee_local $0 + (tee_local $0 + (tee_local $0 + (loop $label$35 (result i32) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (i64.const 107) + ) ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) ) ) + (get_local $0) ) - (nop) ) + ) + ) + ) + ) + (block $label$36 + (nop) + (tee_local $0 + (loop $label$37 + (block (if (i32.eqz - (tee_local $2 - (get_local $2) - ) + (get_global $hangLimit) ) - (set_local $3 - (get_local $3) + (return + (i64.const 1465604153) ) - (set_local $2 - (i32.const 2147483647) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) ) ) ) - ) - (br_if $label$36 - (i32.load16_s offset=22 - (i32.and - (br_if $label$35 - (i32.const -128) - (i32.eqz - (i32.const 4096) + (block $label$38 + (if + (i32.eqz + (get_local $0) + ) + (block $label$39 + (nop) + (nop) + ) + (block $label$40 + (nop) + (set_local $0 + (i32.const 1728316281) ) ) - (i32.const 15) ) + (br $label$30) ) ) - (tee_local $1 - (tee_local $1 - (loop $label$41 (result f32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $0) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) + ) + ) + (nop) + ) + (br $label$0) + ) + ) + ) + (tee_local $0 + (tee_local $0 + (tee_local $0 + (tee_local $0 + (tee_local $0 + (tee_local $0 + (loop $label$41 (result i32) + (block + (if + (i32.eqz + (get_global $hangLimit) ) - (block (result f32) - (br_if $label$5 - (i32.eqz - (i32.const -131072) - ) - ) - (br_if $label$41 - (i32.const 425480269) - ) - (f32.const -nan:0x7fffe7) + (return + (i64.const 8) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) ) ) ) + (block (result i32) + (set_local $0 + (tee_local $0 + (i32.const 0) + ) + ) + (br_if $label$41 + (tee_local $0 + (get_local $0) + ) + ) + (get_local $0) + ) ) ) ) ) ) ) - (i32.const -83) ) ) ) ) + (loop $label$42 (result i32) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (i64.const 0) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$43 (result i32) + (nop) + (tee_local $0 + (i32.const 3340) + ) + ) + ) ) ) - (br_if $label$1 - (i32.eqz - (i32.const -128) + ) + ) + (i64.const -4) + ) + ) + ) + ) + ) + (func $func_7_invoker (; 8 ;) (type $FUNCSIG$v) + (drop + (call $func_7 + (i32.const 0) + ) + ) + (drop + (call $func_7 + (i32.const -255) + ) + ) + ) + (func $func_9 (; 9 ;) (result f32) + (local $0 f64) + (local $1 i32) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (f32.const 4294967296) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (f32.const 68719476736) + ) + (func $func_10 (; 10 ;) (param $0 i32) (param $1 i64) (param $2 f32) (param $3 f64) (param $4 i64) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (set_local $3 + (f64.const -4294967295) + ) + ) + (func $func_10_invoker (; 11 ;) (type $FUNCSIG$v) + (call $func_10 + (i32.const 1162756672) + (i64.const 437523221) + (f32.const 520298272) + (f64.const 3402823466385288598117041e14) + (i64.const 8249322886954774645) + ) + (call $func_10 + (i32.const 1448498774) + (i64.const 9223372036854775807) + (f32.const 514) + (f64.const -3402823466385288598117041e14) + (i64.const 1152921504606846976) + ) + (call $func_10 + (i32.const 256) + (i64.const -4) + (f32.const -1) + (f64.const 3402823466385288598117041e14) + (i64.const 9187062989043925010) + ) + ) + (func $func_12 (; 12 ;) (result f64) + (local $0 f64) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (get_local $0) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$0 (result f64) + (set_local $0 + (f64.const -3402823466385288598117041e14) + ) + (nop) + (tee_local $0 + (tee_local $0 + (f64.const -1797693134862315708145274e284) + ) + ) + ) + ) + (func $func_13 (; 13 ;) (type $FUNCSIG$v) + (local $0 f64) + (local $1 f32) + (local $2 i64) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (set_local $0 + (f64.const -18446744073709551615) + ) + ) + (func $func_14 (; 14 ;) (result i32) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (i32.const 22043) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (i32.const -1073741824) + ) + (func $func_15 (; 15 ;) (result i64) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (i64.const 1231244158900898823) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$0 + (nop) + (i32.trunc_s/f32 + (f64.store offset=1 align=2 + (i32.and + (i32.const -127) + (i32.const 15) + ) + (i32.store offset=2 align=2 + (if + (i32.const -32768) + (block $label$24 + (nop) + (if + (i32.const -4) + (block $label$25 + (call $func_3_invoker) + (if + (i32.eqz + (if + (i32.const 386274323) + (block $label$26 + (if + (i32.const 403838992) + (block $label$27 + (nop) + (br_if $label$27 + (i32.eqz + (i32.const -18) + ) + ) + ) + (block $label$28 + (nop) + (block $label$29 + (nop) + (nop) + ) + ) + ) + (return + (i64.const 8995) + ) + ) + (block $label$30 + (nop) + (return + (i64.const 6287390439797901652) + ) + ) + ) + ) + (block $label$31 + (nop) + (return + (i64.const -9223372036854775807) + ) + ) + (return + (i64.const -144115188075855872) + ) + ) + ) + (block $label$32 + (block $label$33 + (nop) + (nop) + ) + (return + (i64.const -2305843009213693952) + ) ) ) - (i32.const 1) + ) + (block $label$34 + (if + (i32.const 0) + (nop) + (block $label$35 + (if + (i32.const 50) + (block $label$36 + (nop) + ) + (block $label$37 + (nop) + ) + ) + (nop) + ) + ) + (return + (i64.const -89) + ) ) ) + (i32.const -4096) ) ) - (get_local $0) ) ) ) - (func $hangLimitInitializer (; 9 ;) + (func $hangLimitInitializer (; 16 ;) (set_global $hangLimit (i32.const 10) ) ) - (func $deNan32 (; 10 ;) (param $0 f32) (result f32) + (func $deNan32 (; 17 ;) (param $0 f32) (result f32) (if (result f32) (f32.eq (get_local $0) @@ -1430,7 +1124,7 @@ (f32.const 0) ) ) - (func $deNan64 (; 11 ;) (param $0 f64) (result f64) + (func $deNan64 (; 18 ;) (param $0 f64) (result f64) (if (result f64) (f64.eq (get_local $0) |