diff options
-rw-r--r-- | src/passes/Flatten.cpp | 16 | ||||
-rw-r--r-- | test/binaryen.js/kitchen-sink.js | 2 | ||||
-rw-r--r-- | test/binaryen.js/kitchen-sink.js.txt | 4 | ||||
-rw-r--r-- | test/passes/flatten.txt | 121 | ||||
-rw-r--r-- | test/passes/flatten.wast | 5 | ||||
-rw-r--r-- | test/passes/inlining.txt | 2 | ||||
-rw-r--r-- | test/passes/inlining.wast | 2 |
7 files changed, 110 insertions, 42 deletions
diff --git a/src/passes/Flatten.cpp b/src/passes/Flatten.cpp index 00130838e..53fd6a02b 100644 --- a/src/passes/Flatten.cpp +++ b/src/passes/Flatten.cpp @@ -46,6 +46,8 @@ // anything else is written to a local earlier. // 2. Disallow block, loop, and if return values, i.e., do not use // control flow to pass around values. +// 3. Disallow tee_local, setting a local is always done in a set_local +// on a non-nested-expression location. // #include <wasm.h> @@ -185,7 +187,19 @@ struct Flatten : public WalkerPass<ExpressionStackWalker<Flatten, UnifiedExpress ourPreludes.swap(iter->second); } // special handling - if (auto* br = curr->dynCast<Break>()) { + if (auto* set = curr->dynCast<SetLocal>()) { + if (set->isTee()) { + // we disallow tee_local + if (set->value->type == unreachable) { + replaceCurrent(set->value); // trivial, no set happens + } else { + // use a set in a prelude + a get + set->setTee(false); + ourPreludes.push_back(set); + replaceCurrent(builder.makeGetLocal(set->index, set->value->type)); + } + } + } else if (auto* br = curr->dynCast<Break>()) { if (br->value) { auto type = br->value->type; if (isConcreteWasmType(type)) { diff --git a/test/binaryen.js/kitchen-sink.js b/test/binaryen.js/kitchen-sink.js index bd55dc8a0..3205de702 100644 --- a/test/binaryen.js/kitchen-sink.js +++ b/test/binaryen.js/kitchen-sink.js @@ -214,7 +214,7 @@ function test_core() { console.log("getExpressionType=" + Binaryen.getExpressionType(valueList[3])); console.log(Binaryen.emitText(valueList[3])); // test printing a standalone expression console.log(Binaryen.getConstValueI32(module.i32.const(5))); - console.log(Binaryen.getConstValueI64(module.i64.const(6, 7))); + console.log(JSON.stringify(Binaryen.getConstValueI64(module.i64.const(6, 7)))); console.log(Binaryen.getConstValueF32(module.f32.const(8.5))); console.log(Binaryen.getConstValueF64(module.f64.const(9.5))); diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt index d097e9a7f..f585d28d8 100644 --- a/test/binaryen.js/kitchen-sink.js.txt +++ b/test/binaryen.js/kitchen-sink.js.txt @@ -38,7 +38,7 @@ getExpressionType=3 ) 5 -{ low: 6, high: 7 } +{"low":6,"high":7} 8.5 9.5 (module @@ -1403,7 +1403,7 @@ getExpressionType=3 expressions[248] = BinaryenConst(the_module, BinaryenLiteralInt64(30064771078)); BinaryenConstGetValueI64Low(expressions[248]); BinaryenConstGetValueI64High(expressions[248]); -{ low: 6, high: 7 } +{"low":6,"high":7} expressions[249] = BinaryenConst(the_module, BinaryenLiteralFloat32(8.5)); BinaryenConstGetValueF32(expressions[249]); 8.5 diff --git a/test/passes/flatten.txt b/test/passes/flatten.txt index 946c45ebe..c09305cb8 100644 --- a/test/passes/flatten.txt +++ b/test/passes/flatten.txt @@ -112,10 +112,11 @@ (local $6 i32) (local $7 i32) (block $block + (set_local $x + (i32.const 0) + ) (set_local $1 - (tee_local $x - (i32.const 0) - ) + (get_local $x) ) (set_local $2 (get_local $1) @@ -125,10 +126,11 @@ (get_local $2) ) (block $block1 + (set_local $x + (i32.const 1) + ) (set_local $4 - (tee_local $x - (i32.const 1) - ) + (get_local $x) ) (set_local $5 (get_local $4) @@ -160,10 +162,11 @@ (local $9 i32) (block $block (block $block2 + (set_local $x + (i32.const 0) + ) (set_local $1 - (tee_local $x - (i32.const 0) - ) + (get_local $x) ) (set_local $2 (get_local $1) @@ -173,10 +176,11 @@ (get_local $2) ) (block $block3 + (set_local $x + (i32.const 1) + ) (set_local $4 - (tee_local $x - (i32.const 1) - ) + (get_local $x) ) (set_local $5 (get_local $4) @@ -240,10 +244,11 @@ ) (br $outer) (unreachable) + (set_local $x + (i32.const 3) + ) (set_local $5 - (tee_local $x - (i32.const 3) - ) + (get_local $x) ) (set_local $6 (get_local $5) @@ -344,10 +349,11 @@ (get_local $2) ) (nop) + (set_local $x + (i32.const 2) + ) (set_local $3 - (tee_local $x - (i32.const 2) - ) + (get_local $x) ) (set_local $1 (get_local $3) @@ -362,10 +368,11 @@ (get_local $4) ) (nop) + (set_local $x + (i32.const 5) + ) (set_local $5 - (tee_local $x - (i32.const 5) - ) + (get_local $x) ) (set_local $1 (i32.const 4) @@ -380,15 +387,17 @@ (get_local $6) ) (nop) + (set_local $x + (i32.const 6) + ) (set_local $7 - (tee_local $x - (i32.const 6) - ) + (get_local $x) + ) + (set_local $x + (i32.const 7) ) (set_local $8 - (tee_local $x - (i32.const 7) - ) + (get_local $x) ) (set_local $1 (get_local $7) @@ -556,10 +565,11 @@ (local $6 i32) (local $7 i32) (block $label$1 + (set_local $x + (i32.const 1) + ) (set_local $1 - (tee_local $x - (i32.const 1) - ) + (get_local $x) ) (block $label$2 (set_local $x @@ -612,10 +622,11 @@ (set_local $1 (get_local $var$0) ) + (set_local $var$0 + (f32.const -137438953472) + ) (set_local $2 - (tee_local $var$0 - (f32.const -137438953472) - ) + (get_local $var$0) ) (set_local $3 (get_local $var$0) @@ -1128,9 +1139,7 @@ (i32.const 11) (block (unreachable) - (tee_local $x - (unreachable) - ) + (unreachable) (unreachable) ) ) @@ -2399,4 +2408,44 @@ (get_local $9) ) ) + (func $tees (; 41 ;) (type $ii) (param $x i32) (param $y i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (block + (set_local $x + (i32.const 1) + ) + (set_local $2 + (get_local $x) + ) + (drop + (get_local $2) + ) + (nop) + (unreachable) + (unreachable) + (drop + (unreachable) + ) + (unreachable) + (set_local $x + (i32.const 2) + ) + (set_local $3 + (get_local $x) + ) + (set_local $y + (get_local $3) + ) + (set_local $4 + (get_local $y) + ) + (drop + (get_local $4) + ) + (nop) + ) + (unreachable) + ) ) diff --git a/test/passes/flatten.wast b/test/passes/flatten.wast index 35b009939..6b71158f6 100644 --- a/test/passes/flatten.wast +++ b/test/passes/flatten.wast @@ -1011,4 +1011,9 @@ ) ) ) + (func $tees (param $x i32) (param $y i32) + (drop (tee_local $x (i32.const 1))) + (drop (tee_local $x (unreachable))) + (drop (tee_local $y (tee_local $x (i32.const 2)))) + ) ) diff --git a/test/passes/inlining.txt b/test/passes/inlining.txt index 67604971d..8a195b96d 100644 --- a/test/passes/inlining.txt +++ b/test/passes/inlining.txt @@ -225,7 +225,7 @@ (memory $0 0) (func $0 (; 0 ;) (type $1) (block $__inlined_func$1 - (call_indirect $T + (call_indirect (type $T) (if (result i32) (i32.const 0) (unreachable) diff --git a/test/passes/inlining.wast b/test/passes/inlining.wast index f68fb6703..eda8b9cc1 100644 --- a/test/passes/inlining.wast +++ b/test/passes/inlining.wast @@ -152,7 +152,7 @@ (call $1) ) (func $1 - (call_indirect $T + (call_indirect (type $T) (if (result i32) ;; if copy must preserve the forced type (i32.const 0) (unreachable) |