Bug 1316554: Render series of blocks as inline blocks; r=luke
authorBenjamin Bouvier <benj@benj.me>
Tue, 22 Nov 2016 12:30:36 +0100
changeset 324096 5f23873d0c91d0d2d647166d7d6491d388f4825e
parent 324095 67ff8b138c460ae6d44a0e9f82f30ce9600729a1
child 324097 9789423a63aba19ca6b5fecb97f4dacbb1fc0181
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersluke
bugs1316554
milestone53.0a1
Bug 1316554: Render series of blocks as inline blocks; r=luke MozReview-Commit-ID: DpbTMvjzMgW
js/src/jit-test/tests/wasm/full-cycle.js
js/src/jit-test/tests/wasm/to-text.js
js/src/wasm/WasmBinaryToText.cpp
--- a/js/src/jit-test/tests/wasm/full-cycle.js
+++ b/js/src/jit-test/tests/wasm/full-cycle.js
@@ -104,8 +104,40 @@ wasmFullPass(`(module
         i32.add
         set_global $g
     )
     (start $start)
     (func (export "run") (result i32)
         get_global $g
     )
 )`, 1);
+
+// Branch table.
+for (let [p, result] of [
+    [0, 7],
+    [1, 6],
+    [2, 4],
+    [42, 4]
+]) {
+    wasmFullPass(`(module
+        (func (export "run") (result i32) (param $p i32) (local $n i32)
+            i32.const 0
+            set_local $n
+            block $c block $b block $a
+                get_local $p
+                br_table $a $b $c
+            end $a
+                get_local $n
+                i32.const 1
+                i32.add
+                set_local $n
+            end $b
+                get_local $n
+                i32.const 2
+                i32.add
+                set_local $n
+            end $c
+            get_local $n
+            i32.const 4
+            i32.add
+        )
+    )`, result, {}, p);
+}
--- a/js/src/jit-test/tests/wasm/to-text.js
+++ b/js/src/jit-test/tests/wasm/to-text.js
@@ -6,21 +6,21 @@ try {
 } catch (e) {
     caught = true;
 }
 assertEq(caught, true);
 
 assertErrorMessage(() => wasmBinaryToText(wasmTextToBinary(`(module (func (result i32) (f32.const 13.37)))`)), WebAssembly.CompileError, /type mismatch/);
 
 function runTest(code) {
-  var expected = wasmTextToBinary(code);
-  var s = wasmBinaryToText(expected);
-  print("TEXT: " + s);
-  var roundtrip = wasmTextToBinary(s);
-  assertDeepEq(expected, roundtrip);
+    var expected = wasmTextToBinary(code);
+    var s = wasmBinaryToText(expected);
+    print("TEXT: " + s);
+    var roundtrip = wasmTextToBinary(s);
+    assertDeepEq(expected, roundtrip);
 }
 
 // Smoke test
 runTest(`
 (module
   (func (param i32) (result f64)
      (local $l f32)
      (block
@@ -254,8 +254,36 @@ runTest(`
       if
       end
      else
      end
     end
    )
   (export "" 0)
 )`);
+
+// Branch table.
+runTest(`(module
+    (func (export "run") (param $p i32) (local $n i32)
+        i32.const 0
+        set_local $n
+        loop $outer
+            block $c block $b block $a
+                loop $inner
+                    get_local $p
+                    br_table $b $a $c $inner $outer
+                end $inner
+            end $a
+                get_local $n
+                i32.const 1
+                i32.add
+                set_local $n
+            end $b
+                block
+                    get_local $n
+                    i32.const 2
+                    i32.add
+                    set_local $n
+                end
+            end $c
+        end $outer
+    )
+)`);
--- a/js/src/wasm/WasmBinaryToText.cpp
+++ b/js/src/wasm/WasmBinaryToText.cpp
@@ -37,21 +37,26 @@ using mozilla::IsNegativeZero;
 
 struct WasmRenderContext
 {
     JSContext* cx;
     AstModule* module;
     WasmPrintBuffer& buffer;
     GeneratedSourceMap* maybeSourceMap;
     uint32_t indent;
-
     uint32_t currentFuncIndex;
 
-    WasmRenderContext(JSContext* cx, AstModule* module, WasmPrintBuffer& buffer, GeneratedSourceMap* sourceMap)
-      : cx(cx), module(module), buffer(buffer), maybeSourceMap(sourceMap), indent(0), currentFuncIndex(0)
+    WasmRenderContext(JSContext* cx, AstModule* module, WasmPrintBuffer& buffer,
+                      GeneratedSourceMap* sourceMap)
+      : cx(cx),
+        module(module),
+        buffer(buffer),
+        maybeSourceMap(sourceMap),
+        indent(0),
+        currentFuncIndex(0)
     {}
 
     StringBuffer& sb() { return buffer.stringBuffer(); }
 };
 
 /*****************************************************************************/
 // utilities
 
@@ -423,57 +428,75 @@ RenderSetGlobal(WasmRenderContext& c, As
 
     MAP_AST_EXPR(c, sg);
     if (!c.buffer.append("set_global "))
         return false;
     return RenderRef(c, sg.global());
 }
 
 static bool
-RenderExprList(WasmRenderContext& c, const AstExprVector& exprs)
+RenderExprList(WasmRenderContext& c, const AstExprVector& exprs, uint32_t startAt = 0)
 {
-    for (uint32_t i = 0; i < exprs.length(); i++) {
+    for (uint32_t i = startAt; i < exprs.length(); i++) {
         if (!RenderExpr(c, *exprs[i]))
             return false;
     }
     return true;
 }
 
 static bool
-RenderBlock(WasmRenderContext& c, AstBlock& block)
+RenderBlock(WasmRenderContext& c, AstBlock& block, bool isInline = false)
 {
-    if (!RenderIndent(c))
+    if (!isInline && !RenderIndent(c))
         return false;
 
     MAP_AST_EXPR(c, block);
     if (block.op() == Op::Block) {
         if (!c.buffer.append("block"))
             return false;
     } else if (block.op() == Op::Loop) {
         if (!c.buffer.append("loop"))
             return false;
     } else {
         return Fail(c, "unexpected block kind");
     }
 
     if (!RenderBlockNameAndSignature(c, block.name(), block.type()))
         return false;
 
+    uint32_t startAtSubExpr = 0;
+
+    // If there is a stack of blocks, print them all inline.
+    if (block.op() == Op::Block &&
+        block.exprs().length() &&
+        block.exprs()[0]->kind() == AstExprKind::Block &&
+        block.exprs()[0]->as<AstBlock>().op() == Op::Block)
+    {
+        if (!c.buffer.append(' '))
+            return false;
+
+        // Render the first inner expr (block) at the same indent level, but
+        // next instructions one level further.
+        if (!RenderBlock(c, block.exprs()[0]->as<AstBlock>(), /* isInline */ true))
+            return false;
+
+        startAtSubExpr = 1;
+    }
+
     if (!c.buffer.append('\n'))
         return false;
 
     c.indent++;
-    if (!RenderExprList(c, block.exprs()))
+    if (!RenderExprList(c, block.exprs(), startAtSubExpr))
         return false;
     c.indent--;
 
-    if (!RenderIndent(c))
-        return false;
-
-    return c.buffer.append("end");
+    return RenderIndent(c) &&
+           c.buffer.append("end ") &&
+           RenderName(c, block.name());
 }
 
 static bool
 RenderFirst(WasmRenderContext& c, AstFirst& first)
 {
     return RenderExprList(c, first.exprs());
 }