Bug 1384723 - Remove experimental WebAssembly text support. r?sunfish draft
authorYury Delendik <ydelendik@mozilla.com>
Wed, 26 Jul 2017 16:00:21 -0500
changeset 620661 4ca26cb481d23919ba1d932c5a0a0fe1f3c2c423
parent 616915 36f95aeb4c77f7cf3b3366583008cd6e4b6b1dba
child 640780 9c1d5026009ecc51ccb4b57c05f1a277c578cb5a
push id72125
push userydelendik@mozilla.com
push dateThu, 03 Aug 2017 19:34:57 +0000
reviewerssunfish
bugs1384723
milestone56.0a1
Bug 1384723 - Remove experimental WebAssembly text support. r?sunfish MozReview-Commit-ID: EKwttlC5MCt
js/src/builtin/TestingFunctions.cpp
js/src/jit-test/tests/wasm/to-text-experimental.js
js/src/moz.build
js/src/wasm/WasmBinaryToExperimentalText.cpp
js/src/wasm/WasmBinaryToExperimentalText.h
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -43,17 +43,16 @@
 #include "vm/GlobalObject.h"
 #include "vm/Interpreter.h"
 #include "vm/ProxyObject.h"
 #include "vm/SavedStacks.h"
 #include "vm/Stack.h"
 #include "vm/StringBuffer.h"
 #include "vm/TraceLogging.h"
 #include "wasm/AsmJS.h"
-#include "wasm/WasmBinaryToExperimentalText.h"
 #include "wasm/WasmBinaryToText.h"
 #include "wasm/WasmJS.h"
 #include "wasm/WasmModule.h"
 #include "wasm/WasmSignalHandlers.h"
 #include "wasm/WasmTextToBinary.h"
 
 #include "jscntxtinlines.h"
 #include "jsobjinlines.h"
@@ -604,34 +603,23 @@ WasmBinaryToText(JSContext* cx, unsigned
 
     Vector<uint8_t> copy(cx);
     if (code->bufferUnshared()->hasInlineData()) {
         if (!copy.append(bytes, length))
             return false;
         bytes = copy.begin();
     }
 
-    bool experimental = false;
     if (args.length() > 1) {
-        JSString* opt = JS::ToString(cx, args[1]);
-        if (!opt)
-            return false;
-        bool match;
-        if (!JS_StringEqualsAscii(cx, opt, "experimental", &match))
-            return false;
-        experimental = match;
+        JS_ReportErrorASCII(cx, "wasm text format selection is not supported");
+        return false;
     }
 
     StringBuffer buffer(cx);
-    bool ok;
-    if (experimental)
-        ok = wasm::BinaryToExperimentalText(cx, bytes, length, buffer);
-    else
-        ok = wasm::BinaryToText(cx, bytes, length, buffer);
-
+    bool ok = wasm::BinaryToText(cx, bytes, length, buffer);
     if (!ok) {
         if (!cx->isExceptionPending())
             JS_ReportErrorASCII(cx, "wasm binary to text print error");
         return false;
     }
 
     JSString* result = buffer.finishString();
     if (!result)
deleted file mode 100644
--- a/js/src/jit-test/tests/wasm/to-text-experimental.js
+++ /dev/null
@@ -1,222 +0,0 @@
-assertErrorMessage(() => wasmBinaryToText(wasmTextToBinary(`(module (func (result i32) (f32.const 13.37)))`), 'experimental'), WebAssembly.CompileError, /type mismatch/);
-
-function runTest(code, expected) {
-  var binary = wasmTextToBinary(code);
-  var s = wasmBinaryToText(binary, "experimental");
-  s = s.replace(/\s+/g, ' ');
-  print("TEXT: " + s);
-  assertEq(s, expected);
-}
-
-// Smoke test
-runTest(`
-(module
-  (func (param i32) (result f64)
-     (local $l f32)
-     (block
-        (set_local $l (f32.const 0.0))
-        (loop $exit $cont
-           (br_if $exit (get_local 0))
-           (br 2)
-        )
-        (drop (if f64 (i32.const 1)
-           (f64.min (f64.neg (f64.const 1)) (f64.const 0))
-           (f64.add (f64.const 0.5) (f64.load offset=0 (i32.const 0)) )
-        ))
-     )
-     (i32.store16 (i32.const 8) (i32.const 128))
-
-     (return (f64.const 0))
-  )
-  (export "test" 0)
-  (memory 1 10)
-)`,
-"type $type0 of function (i32) : (f64); " +
-"export $func0 as \"test\"; " +
-"function $func0($var0: i32) : (f64) {" +
-" var $var1: f32; { $var1 = 0.0f; { loop { br_if ($var0) $label0; br $label1; } $label0: };" +
-" if (1) { f64.min(-1.0, 0.0) } else { 0.5 + f64[0] }; $label1: };" +
-" i32:16[8] = 128; return 0.0; "+
-"} memory 1, 10 {} ");
-
-wasmFailValidateText(
-`(module
-  (func (param i32) (result f64)
-     (local $l f32)
-     (block
-        (set_local $l (f32.const 0.0))
-        (loop $cont
-           (br_if $cont (get_local 0))
-           (br 2)
-        )
-        (drop (if f64 (i32.const 1)
-           (f64.min (f64.neg (f64.const 1)) (f64.const 0))
-           (f64.add (f64.const 0.5) (f64.load offset=0 (i32.const 0)) )
-        ))
-     )
-     (i32.store16 (i32.const 8) (i32.const 128))
-
-     (return (f64.const 0))
-  )
-  (export "test" 0)
-  (memory 1 10)
-)`, emptyStackError);
-
-// function calls
-runTest(`
-(module
-  (type $type1 (func (param i32) (result i32)))
-  (import $import1 "mod" "test" (param f32) (result f32))
-  (table anyfunc (elem $func1 $func2))
-  (func $func1 (param i32) (param f32) (nop))
-  (func $func2 (param i32) (result i32) (get_local 0))
-  (func $test
-    (call $func1
-      (call_indirect $type1 (i32.const 2) (i32.const 1))
-      (call $import1 (f32.const 1.0))
-    )
-  )
-  (export "test" $test)
-  (memory 1 65535)
-)`,
-"type $type0 of function (i32) : (i32); " +
-"type $type1 of function (f32) : (f32); " +
-"type $type2 of function (i32, f32) : (); " +
-"type $type3 of function () : (); " +
-"import \"test\" as $import0 from \"mod\" typeof function (f32) : (f32); " +
-"table [$func1, $func2]; export $func3 as \"test\"; " +
-"function $func1($var0: i32, $var1: f32) : () { nop; } " +
-"function $func2($var0: i32) : (i32) { $var0 } " +
-"function $func3() : () {" +
-" call $func1 (call_indirect $type0 (2) [1], call $import0 (1.0f)) " +
-"} memory 1, 65535 {} ");
-
-// precedence
-runTest(`
-(module
-  (func $test
-    (local $0 i32) (local $1 f64) (local $2 f64)
-    (drop (i32.add (i32.mul (i32.mul (i32.const 1) (i32.const 2)) (i32.const 3))
-                   (i32.mul (i32.const 4)  (i32.mul (i32.const 5) (i32.const 6)))))
-    (drop (i32.mul (i32.add (i32.add (i32.const 1) (i32.const 2)) (i32.const 3))
-                   (i32.add (i32.const 4)  (i32.add (i32.const 5) (i32.const 6)))))
-    (drop (i32.add (i32.const 0) (i32.sub (i32.const 1) (i32.mul (i32.const 2) (i32.div_s (i32.const 3) (i32.const 4))))))
-    (drop (i32.sub (i32.add (i32.const 0) (i32.const 1)) (i32.div_s (i32.mul (i32.const 2) (i32.const 3)) (i32.const 4))))
-    (i32.store8 (i32.const 8) (i32.or (i32.const 0)
-      (i32.xor (i32.const 1) (i32.and (i32.const 2) (i32.eq (i32.const 3)
-      (i32.lt_u (i32.const 4) (i32.shr_u (i32.const 5) (i32.add (i32.const 6)
-      (i32.mul (i32.const 7) (i32.eqz (i32.load16_u (get_local $0))))))))))))
-    (drop (f64.load (i32.trunc_u/f64 (f64.neg (f64.mul (f64.const 0.0)
-      (f64.add (f64.const 1.0) (f64.convert_s/i32 (i32.lt_s (i32.const 6)
-      (f64.eq (f64.const 7.0) (tee_local $2 (tee_local $1 (f64.const 9.0))))))))))))
-    (f64.store (i32.const 8) (tee_local $1 (f64.const 9.0)))
-    (unreachable)
-  )
-  (export "test" $test)
-  (memory 0 0)
-)`,
-"type $type0 of function () : (); " +
-"export $func0 as \"test\"; " +
-"function $func0() : () {" +
-" var $var0: i32, $var1: f64, $var2: f64;" +
-" 1 * 2 * 3 + 4 * (5 * 6);" +
-" (1 + 2 + 3) * (4 + (5 + 6));" +
-" 0 + (1 - 2 * (3 /s 4));" +
-" 0 + 1 - 2 * 3 /s 4;" +
-" i32:8[8] = 0 | 1 ^ 2 & 3 == 4 <u 5 >>u 6 + 7 * !i32:16u[$var0];" +
-" f64[i32.trunc_u/f64(-(0.0 * (1.0 + f64.convert_s/i32(6 <s (7.0 == ($var2 = $var1 = 9.0))))))];" +
-" f64[8] = $var1 = 9.0;" +
-" unreachable; " +
-"} memory 0, 0 {} ");
-
-// more stack-machine code that isn't directly representable as an AST
-runTest(`
-(module
-   (func (result i32)
-     (local $x i32)
-     i32.const 100
-     set_local $x
-     i32.const 200
-     set_local $x
-     i32.const 400
-     set_local $x
-     i32.const 2
-     i32.const 16
-     nop
-     set_local $x
-     i32.const 3
-     i32.const 17
-     set_local $x
-     i32.const 18
-     set_local $x
-     i32.lt_s
-     if i32
-       i32.const 101
-       set_local $x
-       i32.const 8
-       i32.const 102
-       set_local $x
-     else
-       i32.const 103
-       set_local $x
-       i32.const 900
-       i32.const 104
-       set_local $x
-       i32.const 105
-       set_local $x
-     end
-     i32.const 107
-     set_local $x
-     get_local $x
-     i32.add
-     i32.const 106
-     set_local $x
-   )
-   (export "" 0)
-)`,
-"type $type0 of function () : (i32); export $func0 as \"\"; function $func0() : (i32) { var $var0: i32; $var0 = 100; $var0 = 200; $var0 = 400; first(first(if (first(2, ($var0 = first(16, nop))) <s first(3, ($var0 = 17), ($var0 = 18))) { $var0 = 101; first(8, $var0 = 102) } else { $var0 = 103; first(900, $var0 = 104, $var0 = 105) }, ($var0 = 107)) + $var0, $var0 = 106) } ");
-
-// more stack-machine code that isn't directly representable as an AST
-runTest(`
-(module
-   (func $return_void)
-
-   (func (result i32)
-     (local $x i32)
-     i32.const 0
-     block
-       i32.const 1
-       set_local $x
-     end
-     i32.const 2
-     set_local $x
-     i32.const 3
-     loop
-       i32.const 4
-       set_local $x
-     end
-     i32.const 5
-     set_local $x
-     i32.add
-     call $return_void
-   )
-   (export "" 0)
-)`,
-"type $type0 of function () : (); type $type1 of function () : (i32); export $func0 as \"\"; function $func0() : () { } function $func1() : (i32) { var $var0: i32; first(first(0, { $var0 = 1; }, ($var0 = 2)) + first(3, loop { $var0 = 4; }, ($var0 = 5)), call $func0 ()) } ");
-
-runTest(`
-(module
-  (func $func
-    block $block
-      i32.const 0
-      if
-        i32.const 0
-        if
-        end
-      else
-      end
-    end
-  )
-  (export "" 0)
-)`,
-"type $type0 of function () : (); export $func0 as \"\"; function $func0() : () { { if (0) { if (0) { }; }; } } ");
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -361,17 +361,16 @@ UNIFIED_SOURCES += [
     'vm/Unicode.cpp',
     'vm/Value.cpp',
     'vm/WeakMapPtr.cpp',
     'vm/Xdr.cpp',
     'wasm/AsmJS.cpp',
     'wasm/WasmBaselineCompile.cpp',
     'wasm/WasmBinaryIterator.cpp',
     'wasm/WasmBinaryToAST.cpp',
-    'wasm/WasmBinaryToExperimentalText.cpp',
     'wasm/WasmBinaryToText.cpp',
     'wasm/WasmBuiltins.cpp',
     'wasm/WasmCode.cpp',
     'wasm/WasmCompartment.cpp',
     'wasm/WasmCompile.cpp',
     'wasm/WasmDebug.cpp',
     'wasm/WasmFrameIterator.cpp',
     'wasm/WasmGenerator.cpp',
deleted file mode 100644
--- a/js/src/wasm/WasmBinaryToExperimentalText.cpp
+++ /dev/null
@@ -1,1915 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- *
- * Copyright 2015 Mozilla Foundation
- *
- * 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.
- */
-
-#include "wasm/WasmBinaryToExperimentalText.h"
-
-#include "mozilla/CheckedInt.h"
-
-#include "jsnum.h"
-#include "jsprf.h"
-
-#include "vm/ArrayBufferObject.h"
-#include "vm/StringBuffer.h"
-#include "wasm/WasmAST.h"
-#include "wasm/WasmBinaryToAST.h"
-#include "wasm/WasmDebug.h"
-#include "wasm/WasmTextUtils.h"
-#include "wasm/WasmTypes.h"
-
-using namespace js;
-using namespace js::wasm;
-
-using mozilla::CheckedInt;
-using mozilla::IsInfinite;
-using mozilla::IsNaN;
-using mozilla::IsNegativeZero;
-
-enum PrintOperatorPrecedence
-{
-    ExpressionPrecedence = 0,
-    AssignmentPrecedence = 1,
-    StoreOperatorPrecedence = 1,
-    BitwiseOrPrecedence = 4,
-    BitwiseXorPrecedence = 5,
-    BitwiseAndPrecedence = 6,
-    EqualityPrecedence = 7,
-    ComparisonPrecedence = 8,
-    BitwiseShiftPrecedence = 9,
-    AdditionPrecedence = 10,
-    MultiplicationPrecedence = 11,
-    NegatePrecedence = 12,
-    EqzPrecedence = 12,
-    OperatorPrecedence = 15,
-    LoadOperatorPrecedence = 15,
-    CallPrecedence = 15,
-    GroupPrecedence = 16,
-};
-
-struct WasmPrintContext
-{
-    JSContext* cx;
-    AstModule* module;
-    WasmPrintBuffer& buffer;
-    const ExperimentalTextFormatting& f;
-    GeneratedSourceMap* maybeSourceMap;
-    uint32_t indent;
-
-    uint32_t currentFuncIndex;
-    PrintOperatorPrecedence currentPrecedence;
-
-    WasmPrintContext(JSContext* cx, AstModule* module, WasmPrintBuffer& buffer,
-                     const ExperimentalTextFormatting& f, GeneratedSourceMap* wasmSourceMap_)
-      : cx(cx),
-        module(module),
-        buffer(buffer),
-        f(f),
-        maybeSourceMap(wasmSourceMap_),
-        indent(0),
-        currentFuncIndex(0),
-        currentPrecedence(PrintOperatorPrecedence::ExpressionPrecedence)
-    {}
-
-    StringBuffer& sb() { return buffer.stringBuffer(); }
-};
-
-/*****************************************************************************/
-// utilities
-
-static bool
-IsDropValueExpr(AstExpr& expr)
-{
-    // Based on AST information, determines if the expression does not return a value.
-    // TODO infer presence of a return value for rest kinds of expressions from
-    // the function return type.
-    switch (expr.kind()) {
-      case AstExprKind::Branch:
-        return !expr.as<AstBranch>().maybeValue();
-      case AstExprKind::BranchTable:
-        return !expr.as<AstBranchTable>().maybeValue();
-      case AstExprKind::If:
-        return !expr.as<AstIf>().hasElse();
-      case AstExprKind::Nop:
-      case AstExprKind::Drop:
-      case AstExprKind::Unreachable:
-      case AstExprKind::Return:
-      case AstExprKind::SetLocal:
-      case AstExprKind::Store:
-        return true;
-      default:
-        return false;
-    }
-}
-
-static bool
-PrintIndent(WasmPrintContext& c)
-{
-    for (uint32_t i = 0; i < c.indent; i++) {
-        if (!c.buffer.append("  "))
-            return false;
-    }
-    return true;
-}
-
-static bool
-PrintInt32(WasmPrintContext& c, int32_t num, bool printSign = false)
-{
-    // Negative sign will be printed, printing '+' for non-negative values.
-    if (printSign && num >= 0) {
-        if (!c.buffer.append("+"))
-            return false;
-    }
-    return NumberValueToStringBuffer(c.cx, Int32Value(num), c.buffer.stringBuffer());
-}
-
-static bool
-PrintInt64(WasmPrintContext& c, int64_t num)
-{
-    if (num < 0 && !c.buffer.append("-"))
-        return false;
-    if (!num)
-        return c.buffer.append("0");
-
-    uint64_t abs = mozilla::Abs(num);
-    uint64_t n = abs;
-    uint64_t pow = 1;
-    while (n) {
-        pow *= 10;
-        n /= 10;
-    }
-    pow /= 10;
-
-    n = abs;
-    while (pow) {
-        if (!c.buffer.append((char16_t)(u'0' + n / pow)))
-            return false;
-        n -= (n / pow) * pow;
-        pow /= 10;
-    }
-
-    return true;
-}
-
-static bool
-PrintDouble(WasmPrintContext& c, double d)
-{
-    if (IsNegativeZero(d))
-        return c.buffer.append("-0.0");
-    if (IsNaN(d))
-        return RenderNaN(c.sb(), d);
-    if (IsInfinite(d)) {
-        if (d > 0)
-            return c.buffer.append("infinity");
-        return c.buffer.append("-infinity");
-    }
-
-    uint32_t startLength = c.buffer.length();
-    if (!NumberValueToStringBuffer(c.cx, DoubleValue(d), c.buffer.stringBuffer()))
-        return false;
-    MOZ_ASSERT(startLength < c.buffer.length());
-
-    // Checking if we need to end number with '.0'.
-    for (uint32_t i = c.buffer.length() - 1; i >= startLength; i--) {
-        char16_t ch = c.buffer.getChar(i);
-        if (ch == '.' || ch == 'e')
-            return true;
-    }
-    return c.buffer.append(".0");
-}
-
-static bool
-PrintFloat32(WasmPrintContext& c, float f)
-{
-    if (IsNaN(f))
-        return RenderNaN(c.sb(), f) && c.buffer.append(".f");
-    return PrintDouble(c, double(f)) &&
-           c.buffer.append("f");
-}
-
-static bool
-PrintEscapedString(WasmPrintContext& c, const AstName& s)
-{
-    size_t length = s.length();
-    const char16_t* p = s.begin();
-    for (size_t i = 0; i < length; i++) {
-        char16_t byte = p[i];
-        switch (byte) {
-          case '\n':
-            if (!c.buffer.append("\\n"))
-                return false;
-            break;
-          case '\r':
-            if (!c.buffer.append("\\0d"))
-                return false;
-            break;
-          case '\t':
-            if (!c.buffer.append("\\t"))
-                return false;
-            break;
-          case '\f':
-            if (!c.buffer.append("\\0c"))
-                return false;
-            break;
-          case '\b':
-            if (!c.buffer.append("\\08"))
-                return false;
-            break;
-          case '\\':
-            if (!c.buffer.append("\\\\"))
-                return false;
-            break;
-          case '"' :
-            if (!c.buffer.append("\\\""))
-                return false;
-            break;
-          case '\'':
-            if (!c.buffer.append("\\'"))
-                return false;
-            break;
-          default:
-            if (byte >= 32 && byte < 127) {
-                if (!c.buffer.append((char)byte))
-                    return false;
-            } else {
-                char digit1 = byte / 16, digit2 = byte % 16;
-                if (!c.buffer.append("\\"))
-                    return false;
-                if (!c.buffer.append((char)(digit1 < 10 ? digit1 + '0' : digit1 - 10 + 'a')))
-                    return false;
-                if (!c.buffer.append((char)(digit2 < 10 ? digit2 + '0' : digit2 - 10 + 'a')))
-                    return false;
-            }
-            break;
-        }
-    }
-    return true;
-}
-
-static bool
-PrintExprType(WasmPrintContext& c, ExprType type)
-{
-    switch (type) {
-      case ExprType::Void: return true; // ignoring void
-      case ExprType::I32: return c.buffer.append("i32");
-      case ExprType::I64: return c.buffer.append("i64");
-      case ExprType::F32: return c.buffer.append("f32");
-      case ExprType::F64: return c.buffer.append("f64");
-      default:;
-    }
-
-    MOZ_CRASH("bad type");
-}
-
-static bool
-PrintValType(WasmPrintContext& c, ValType type)
-{
-    return PrintExprType(c, ToExprType(type));
-}
-
-static bool
-PrintName(WasmPrintContext& c, const AstName& name)
-{
-    return c.buffer.append(name.begin(), name.end());
-}
-
-static bool
-PrintRef(WasmPrintContext& c, const AstRef& ref)
-{
-    if (ref.name().empty())
-        return PrintInt32(c, ref.index());
-
-    return PrintName(c, ref.name());
-}
-
-static bool
-PrintExpr(WasmPrintContext& c, AstExpr& expr);
-
-static bool
-PrintBlockLevelExpr(WasmPrintContext& c, AstExpr& expr, bool isLast)
-{
-    if (!PrintIndent(c))
-        return false;
-    if (!PrintExpr(c, expr))
-        return false;
-    if (!isLast || IsDropValueExpr(expr)) {
-        if (!c.buffer.append(';'))
-            return false;
-    }
-    return c.buffer.append('\n');
-}
-
-/*****************************************************************************/
-// binary format parsing and rendering
-
-static bool
-PrintNop(WasmPrintContext& c)
-{
-    return c.buffer.append("nop");
-}
-
-static bool
-PrintDrop(WasmPrintContext& c, AstDrop& drop)
-{
-    if (!PrintExpr(c, drop.value()))
-        return false;
-
-    return true;
-}
-
-static bool
-PrintUnreachable(WasmPrintContext& c, AstUnreachable& unreachable)
-{
-    return c.buffer.append("unreachable");
-}
-
-static bool
-PrintCallArgs(WasmPrintContext& c, const AstExprVector& args)
-{
-    PrintOperatorPrecedence lastPrecedence = c.currentPrecedence;
-    c.currentPrecedence = ExpressionPrecedence;
-
-    if (!c.buffer.append("("))
-        return false;
-    for (uint32_t i = 0; i < args.length(); i++) {
-        if (!PrintExpr(c, *args[i]))
-            return false;
-        if (i + 1 == args.length())
-            break;
-        if (!c.buffer.append(", "))
-            return false;
-    }
-    if (!c.buffer.append(")"))
-        return false;
-
-    c.currentPrecedence = lastPrecedence;
-    return true;
-}
-
-static bool
-PrintCall(WasmPrintContext& c, AstCall& call)
-{
-    if (call.op() == Op::Call) {
-        if (!c.buffer.append("call "))
-            return false;
-    } else {
-        return false;
-    }
-
-    if (!PrintRef(c, call.func()))
-        return false;
-
-    if (!c.buffer.append(" "))
-        return false;
-
-    if (!PrintCallArgs(c, call.args()))
-        return false;
-
-    return true;
-}
-
-static bool
-PrintCallIndirect(WasmPrintContext& c, AstCallIndirect& call)
-{
-    if (!c.buffer.append("call_indirect "))
-        return false;
-    if (!PrintRef(c, call.sig()))
-        return false;
-
-    if (!c.buffer.append(' '))
-        return false;
-
-    if (!PrintCallArgs(c, call.args()))
-        return false;
-
-    if (!c.buffer.append(" ["))
-        return false;
-
-    PrintOperatorPrecedence lastPrecedence = c.currentPrecedence;
-    c.currentPrecedence = ExpressionPrecedence;
-
-    if (!PrintExpr(c, *call.index()))
-        return false;
-
-    c.currentPrecedence = lastPrecedence;
-
-    if (!c.buffer.append(']'))
-        return false;
-    return true;
-}
-
-static bool
-PrintConst(WasmPrintContext& c, AstConst& cst)
-{
-    switch (ToExprType(cst.val().type())) {
-      case ExprType::I32:
-        if (!PrintInt32(c, (uint32_t)cst.val().i32()))
-            return false;
-        break;
-      case ExprType::I64:
-        if (!PrintInt64(c, (uint32_t)cst.val().i64()))
-            return false;
-        if (!c.buffer.append("i64"))
-            return false;
-        break;
-      case ExprType::F32:
-        if (!PrintFloat32(c, cst.val().f32()))
-            return false;
-        break;
-      case ExprType::F64:
-        if (!PrintDouble(c, cst.val().f64()))
-            return false;
-        break;
-      default:
-        return false;
-    }
-    return true;
-}
-
-static bool
-PrintGetLocal(WasmPrintContext& c, AstGetLocal& gl)
-{
-    if (!PrintRef(c, gl.local()))
-        return false;
-    return true;
-}
-
-static bool
-PrintSetLocal(WasmPrintContext& c, AstSetLocal& sl)
-{
-    PrintOperatorPrecedence lastPrecedence = c.currentPrecedence;
-
-    if (!c.f.reduceParens || lastPrecedence > AssignmentPrecedence) {
-        if (!c.buffer.append("("))
-            return false;
-    }
-
-    if (!PrintRef(c, sl.local()))
-        return false;
-    if (!c.buffer.append(" = "))
-        return false;
-
-    c.currentPrecedence = AssignmentPrecedence;
-
-    if (!PrintExpr(c, sl.value()))
-        return false;
-
-    if (!c.f.reduceParens || lastPrecedence > AssignmentPrecedence) {
-        if (!c.buffer.append(")"))
-            return false;
-    }
-
-    c.currentPrecedence = lastPrecedence;
-    return true;
-}
-
-static bool
-PrintTeeLocal(WasmPrintContext& c, AstTeeLocal& sl)
-{
-    PrintOperatorPrecedence lastPrecedence = c.currentPrecedence;
-
-    if (!c.f.reduceParens || lastPrecedence > AssignmentPrecedence) {
-        if (!c.buffer.append("("))
-            return false;
-    }
-
-    if (!PrintRef(c, sl.local()))
-        return false;
-    if (!c.buffer.append(" = "))
-        return false;
-
-    c.currentPrecedence = AssignmentPrecedence;
-
-    if (!PrintExpr(c, sl.value()))
-        return false;
-
-    if (!c.f.reduceParens || lastPrecedence > AssignmentPrecedence) {
-        if (!c.buffer.append(")"))
-            return false;
-    }
-
-    c.currentPrecedence = lastPrecedence;
-    return true;
-}
-
-static bool
-PrintGetGlobal(WasmPrintContext& c, AstGetGlobal& gg)
-{
-    return PrintRef(c, gg.global());
-}
-
-static bool
-PrintSetGlobal(WasmPrintContext& c, AstSetGlobal& sg)
-{
-    PrintOperatorPrecedence lastPrecedence = c.currentPrecedence;
-
-    if (!c.f.reduceParens || lastPrecedence > AssignmentPrecedence) {
-        if (!c.buffer.append("("))
-            return false;
-    }
-
-    if (!PrintRef(c, sg.global()))
-        return false;
-    if (!c.buffer.append(" = "))
-        return false;
-
-    c.currentPrecedence = AssignmentPrecedence;
-
-    if (!PrintExpr(c, sg.value()))
-        return false;
-
-    if (!c.f.reduceParens || lastPrecedence > AssignmentPrecedence) {
-        if (!c.buffer.append(")"))
-            return false;
-    }
-
-    c.currentPrecedence = lastPrecedence;
-    return true;
-}
-
-static bool
-PrintExprList(WasmPrintContext& c, const AstExprVector& exprs, uint32_t startFrom = 0)
-{
-    for (uint32_t i = startFrom; i < exprs.length(); i++) {
-        if (!PrintBlockLevelExpr(c, *exprs[i], i + 1 == exprs.length()))
-            return false;
-    }
-    return true;
-}
-
-static bool
-PrintGroupedBlock(WasmPrintContext& c, AstBlock& block)
-{
-    uint32_t skip = 0;
-    if (block.exprs().length() > 0 &&
-        block.exprs()[0]->kind() == AstExprKind::Block) {
-        if (!PrintGroupedBlock(c, *static_cast<AstBlock*>(block.exprs()[0])))
-            return false;
-        skip = 1;
-    }
-    c.indent++;
-    if (!PrintExprList(c, block.exprs(), skip))
-        return false;
-    c.indent--;
-    if (!PrintIndent(c))
-        return false;
-
-    // If no br/br_if/br_table refer this block, use some non-existent label.
-    if (block.name().empty())
-        return c.buffer.append("$label:\n");
-
-    if (!PrintName(c, block.name()))
-        return false;
-    if (!c.buffer.append(":\n"))
-        return false;
-    return true;
-}
-
-static bool
-PrintBlockName(WasmPrintContext& c, const AstName& name) {
-    if (name.empty())
-        return true;
-
-    if (!PrintIndent(c))
-        return false;
-    if (!PrintName(c, name))
-        return false;
-    return c.buffer.append(":\n");
-}
-
-static bool
-PrintBlock(WasmPrintContext& c, AstBlock& block)
-{
-    PrintOperatorPrecedence lastPrecedence = c.currentPrecedence;
-    if (block.op() == Op::Block) {
-        if (!c.buffer.append("{\n"))
-            return false;
-    } else if (block.op() == Op::Loop) {
-        if (!c.buffer.append("loop"))
-            return false;
-        if (!block.name().empty()) {
-            if (!c.buffer.append(" "))
-                return false;
-            if (!PrintName(c, block.name()))
-                return false;
-        }
-        if (!c.buffer.append(" {\n"))
-            return false;
-    } else
-        return false;
-
-    c.currentPrecedence = ExpressionPrecedence;
-
-    bool skip = 0;
-    if (c.f.groupBlocks && block.op() == Op::Block &&
-        block.exprs().length() > 0 && block.exprs()[0]->kind() == AstExprKind::Block)
-    {
-        AstBlock* innerBlock = static_cast<AstBlock*>(block.exprs()[0]);
-        if (innerBlock->op() == Op::Block) {
-            if (!PrintGroupedBlock(c, *innerBlock))
-                return false;
-            skip = 1;
-            if (block.exprs().length() == 1 && block.name().empty()) {
-              // Special case to resolve ambiguity in parsing of optional end block label.
-              if (!PrintIndent(c))
-                  return false;
-              if (!c.buffer.append("$exit$:\n"))
-                  return false;
-            }
-        }
-    }
-
-    c.indent++;
-    if (!PrintExprList(c, block.exprs(), skip))
-        return false;
-    c.indent--;
-    c.currentPrecedence = lastPrecedence;
-
-    if (block.op() != Op::Loop) {
-        if (!PrintBlockName(c, block.name()))
-          return false;
-    }
-
-    if (!PrintIndent(c))
-        return false;
-
-    return c.buffer.append("}");
-}
-
-static bool
-PrintUnaryOperator(WasmPrintContext& c, AstUnaryOperator& unary)
-{
-    PrintOperatorPrecedence lastPrecedence = c.currentPrecedence;
-
-    const char* opStr;
-    const char* prefixStr = nullptr;
-    PrintOperatorPrecedence precedence = OperatorPrecedence;
-    switch (unary.op()) {
-      case Op::I32Clz:     opStr = "i32.clz"; break;
-      case Op::I32Ctz:     opStr = "i32.ctz"; break;
-      case Op::I32Popcnt:  opStr = "i32.popcnt"; break;
-      case Op::I64Clz:     opStr = "i64.clz"; break;
-      case Op::I64Ctz:     opStr = "i64.ctz"; break;
-      case Op::I64Popcnt:  opStr = "i64.popcnt"; break;
-      case Op::F32Abs:     opStr = "f32.abs"; break;
-      case Op::F32Neg:     opStr = "f32.neg"; prefixStr = "-"; precedence = NegatePrecedence; break;
-      case Op::F32Ceil:    opStr = "f32.ceil"; break;
-      case Op::F32Floor:   opStr = "f32.floor"; break;
-      case Op::F32Sqrt:    opStr = "f32.sqrt"; break;
-      case Op::F32Trunc:   opStr = "f32.trunc"; break;
-      case Op::F32Nearest: opStr = "f32.nearest"; break;
-      case Op::F64Abs:     opStr = "f64.abs"; break;
-      case Op::F64Neg:     opStr = "f64.neg"; prefixStr = "-"; precedence = NegatePrecedence; break;
-      case Op::F64Ceil:    opStr = "f64.ceil"; break;
-      case Op::F64Floor:   opStr = "f64.floor"; break;
-      case Op::F64Sqrt:    opStr = "f64.sqrt"; break;
-      default: return false;
-    }
-
-    if (c.f.allowAsciiOperators && prefixStr) {
-        if (!c.f.reduceParens || lastPrecedence > precedence) {
-            if (!c.buffer.append("("))
-                return false;
-        }
-
-        c.currentPrecedence = precedence;
-        if (!c.buffer.append(prefixStr, strlen(prefixStr)))
-            return false;
-        if (!PrintExpr(c, *unary.operand()))
-            return false;
-
-        if (!c.f.reduceParens || lastPrecedence > precedence) {
-          if (!c.buffer.append(")"))
-              return false;
-        }
-    } else {
-        if (!c.buffer.append(opStr, strlen(opStr)))
-            return false;
-        if (!c.buffer.append("("))
-            return false;
-
-        c.currentPrecedence = ExpressionPrecedence;
-        if (!PrintExpr(c, *unary.operand()))
-            return false;
-
-        if (!c.buffer.append(")"))
-            return false;
-    }
-    c.currentPrecedence = lastPrecedence;
-
-    return true;
-}
-
-static bool
-PrintBinaryOperator(WasmPrintContext& c, AstBinaryOperator& binary)
-{
-    PrintOperatorPrecedence lastPrecedence = c.currentPrecedence;
-
-    const char* opStr;
-    const char* infixStr = nullptr;
-    PrintOperatorPrecedence precedence;
-    switch (binary.op()) {
-      case Op::I32Add:      opStr = "i32.add"; infixStr = "+"; precedence = AdditionPrecedence; break;
-      case Op::I32Sub:      opStr = "i32.sub"; infixStr = "-"; precedence = AdditionPrecedence; break;
-      case Op::I32Mul:      opStr = "i32.mul"; infixStr = "*"; precedence = MultiplicationPrecedence; break;
-      case Op::I32DivS:     opStr = "i32.div_s"; infixStr = "/s"; precedence = MultiplicationPrecedence; break;
-      case Op::I32DivU:     opStr = "i32.div_u"; infixStr = "/u"; precedence = MultiplicationPrecedence; break;
-      case Op::I32RemS:     opStr = "i32.rem_s"; infixStr = "%s"; precedence = MultiplicationPrecedence; break;
-      case Op::I32RemU:     opStr = "i32.rem_u"; infixStr = "%u"; precedence = MultiplicationPrecedence; break;
-      case Op::I32And:      opStr = "i32.and"; infixStr = "&"; precedence = BitwiseAndPrecedence; break;
-      case Op::I32Or:       opStr = "i32.or"; infixStr = "|"; precedence = BitwiseOrPrecedence; break;
-      case Op::I32Xor:      opStr = "i32.xor"; infixStr = "^"; precedence = BitwiseXorPrecedence; break;
-      case Op::I32Shl:      opStr = "i32.shl"; infixStr = "<<"; precedence = BitwiseShiftPrecedence; break;
-      case Op::I32ShrS:     opStr = "i32.shr_s"; infixStr = ">>s"; precedence = BitwiseShiftPrecedence; break;
-      case Op::I32ShrU:     opStr = "i32.shr_u"; infixStr = ">>u"; precedence = BitwiseShiftPrecedence; break;
-      case Op::I64Add:      opStr = "i64.add"; infixStr = "+"; precedence = AdditionPrecedence; break;
-      case Op::I64Sub:      opStr = "i64.sub"; infixStr = "-"; precedence = AdditionPrecedence; break;
-      case Op::I64Mul:      opStr = "i64.mul"; infixStr = "*"; precedence = MultiplicationPrecedence; break;
-      case Op::I64DivS:     opStr = "i64.div_s"; infixStr = "/s"; precedence = MultiplicationPrecedence; break;
-      case Op::I64DivU:     opStr = "i64.div_u"; infixStr = "/u"; precedence = MultiplicationPrecedence; break;
-      case Op::I64RemS:     opStr = "i64.rem_s"; infixStr = "%s"; precedence = MultiplicationPrecedence; break;
-      case Op::I64RemU:     opStr = "i64.rem_u"; infixStr = "%u"; precedence = MultiplicationPrecedence; break;
-      case Op::I64And:      opStr = "i64.and"; infixStr = "&"; precedence = BitwiseAndPrecedence; break;
-      case Op::I64Or:       opStr = "i64.or"; infixStr = "|"; precedence = BitwiseOrPrecedence; break;
-      case Op::I64Xor:      opStr = "i64.xor"; infixStr = "^"; precedence = BitwiseXorPrecedence; break;
-      case Op::I64Shl:      opStr = "i64.shl"; infixStr = "<<"; precedence = BitwiseShiftPrecedence; break;
-      case Op::I64ShrS:     opStr = "i64.shr_s"; infixStr = ">>s"; precedence = BitwiseShiftPrecedence; break;
-      case Op::I64ShrU:     opStr = "i64.shr_u"; infixStr = ">>u"; precedence = BitwiseShiftPrecedence; break;
-      case Op::F32Add:      opStr = "f32.add"; infixStr = "+"; precedence = AdditionPrecedence; break;
-      case Op::F32Sub:      opStr = "f32.sub"; infixStr = "-"; precedence = AdditionPrecedence; break;
-      case Op::F32Mul:      opStr = "f32.mul"; infixStr = "*"; precedence = MultiplicationPrecedence; break;
-      case Op::F32Div:      opStr = "f32.div"; infixStr = "/"; precedence = MultiplicationPrecedence; break;
-      case Op::F32Min:      opStr = "f32.min"; precedence = OperatorPrecedence; break;
-      case Op::F32Max:      opStr = "f32.max"; precedence = OperatorPrecedence; break;
-      case Op::F32CopySign: opStr = "f32.copysign"; precedence = OperatorPrecedence; break;
-      case Op::F64Add:      opStr = "f64.add"; infixStr = "+"; precedence = AdditionPrecedence; break;
-      case Op::F64Sub:      opStr = "f64.sub"; infixStr = "-"; precedence = AdditionPrecedence; break;
-      case Op::F64Mul:      opStr = "f64.mul"; infixStr = "*"; precedence = MultiplicationPrecedence; break;
-      case Op::F64Div:      opStr = "f64.div"; infixStr = "/"; precedence = MultiplicationPrecedence; break;
-      case Op::F64Min:      opStr = "f64.min"; precedence = OperatorPrecedence; break;
-      case Op::F64Max:      opStr = "f64.max"; precedence = OperatorPrecedence; break;
-      case Op::F64CopySign: opStr = "f64.copysign"; precedence = OperatorPrecedence; break;
-      default: return false;
-    }
-
-    if (c.f.allowAsciiOperators && infixStr) {
-        if (!c.f.reduceParens || lastPrecedence > precedence) {
-            if (!c.buffer.append("("))
-                return false;
-        }
-
-        c.currentPrecedence = precedence;
-        if (!PrintExpr(c, *binary.lhs()))
-            return false;
-        if (!c.buffer.append(" "))
-            return false;
-        if (!c.buffer.append(infixStr, strlen(infixStr)))
-            return false;
-        if (!c.buffer.append(" "))
-            return false;
-        // case of  A / (B / C)
-        c.currentPrecedence = (PrintOperatorPrecedence)(precedence + 1);
-
-        if (!PrintExpr(c, *binary.rhs()))
-            return false;
-        if (!c.f.reduceParens || lastPrecedence > precedence) {
-            if (!c.buffer.append(")"))
-                return false;
-        }
-    } else {
-        if (!c.buffer.append(opStr, strlen(opStr)))
-            return false;
-        if (!c.buffer.append("("))
-            return false;
-
-        c.currentPrecedence = ExpressionPrecedence;
-        if (!PrintExpr(c, *binary.lhs()))
-            return false;
-        if (!c.buffer.append(", "))
-            return false;
-        if (!PrintExpr(c, *binary.rhs()))
-            return false;
-
-        if (!c.buffer.append(")"))
-            return false;
-    }
-    c.currentPrecedence = lastPrecedence;
-
-    return true;
-}
-
-static bool
-PrintTernaryOperator(WasmPrintContext& c, AstTernaryOperator& ternary)
-{
-    PrintOperatorPrecedence lastPrecedence = c.currentPrecedence;
-
-    const char* opStr;
-    switch (ternary.op()) {
-      case Op::Select: opStr = "select"; break;
-      default: return false;
-    }
-
-    if (!c.buffer.append(opStr, strlen(opStr)))
-        return false;
-    if (!c.buffer.append("("))
-        return false;
-
-    c.currentPrecedence = ExpressionPrecedence;
-    if (!PrintExpr(c, *ternary.op0()))
-        return false;
-    if (!c.buffer.append(", "))
-        return false;
-    if (!PrintExpr(c, *ternary.op1()))
-        return false;
-    if (!c.buffer.append(", "))
-        return false;
-    if (!PrintExpr(c, *ternary.op2()))
-        return false;
-
-    if (!c.buffer.append(")"))
-        return false;
-    c.currentPrecedence = lastPrecedence;
-
-    return true;
-}
-
-static bool
-PrintComparisonOperator(WasmPrintContext& c, AstComparisonOperator& comp)
-{
-    PrintOperatorPrecedence lastPrecedence = c.currentPrecedence;
-
-    const char* opStr;
-    const char* infixStr = nullptr;
-    PrintOperatorPrecedence precedence;
-    switch (comp.op()) {
-      case Op::I32Eq:  opStr = "i32.eq"; infixStr = "=="; precedence = EqualityPrecedence; break;
-      case Op::I32Ne:  opStr = "i32.ne"; infixStr = "!="; precedence = EqualityPrecedence; break;
-      case Op::I32LtS: opStr = "i32.lt_s"; infixStr = "<s"; precedence = ComparisonPrecedence; break;
-      case Op::I32LtU: opStr = "i32.lt_u"; infixStr = "<u"; precedence = ComparisonPrecedence; break;
-      case Op::I32LeS: opStr = "i32.le_s"; infixStr = "<=s"; precedence = ComparisonPrecedence; break;
-      case Op::I32LeU: opStr = "i32.le_u"; infixStr = "<=u"; precedence = ComparisonPrecedence; break;
-      case Op::I32GtS: opStr = "i32.gt_s"; infixStr = ">s"; precedence = ComparisonPrecedence; break;
-      case Op::I32GtU: opStr = "i32.gt_u"; infixStr = ">u"; precedence = ComparisonPrecedence; break;
-      case Op::I32GeS: opStr = "i32.ge_s"; infixStr = ">=s"; precedence = ComparisonPrecedence; break;
-      case Op::I32GeU: opStr = "i32.ge_u"; infixStr = ">=u"; precedence = ComparisonPrecedence; break;
-      case Op::I64Eq:  opStr = "i64.eq"; infixStr = "=="; precedence = EqualityPrecedence; break;
-      case Op::I64Ne:  opStr = "i64.ne"; infixStr = "!="; precedence = EqualityPrecedence; break;
-      case Op::I64LtS: opStr = "i64.lt_s"; infixStr = "<s"; precedence = ComparisonPrecedence; break;
-      case Op::I64LtU: opStr = "i64.lt_u"; infixStr = "<u"; precedence = ComparisonPrecedence; break;
-      case Op::I64LeS: opStr = "i64.le_s"; infixStr = "<=s"; precedence = ComparisonPrecedence; break;
-      case Op::I64LeU: opStr = "i64.le_u"; infixStr = "<=u"; precedence = ComparisonPrecedence; break;
-      case Op::I64GtS: opStr = "i64.gt_s"; infixStr = ">s"; precedence = ComparisonPrecedence; break;
-      case Op::I64GtU: opStr = "i64.gt_u"; infixStr = ">u"; precedence = ComparisonPrecedence; break;
-      case Op::I64GeS: opStr = "i64.ge_s"; infixStr = ">=s"; precedence = ComparisonPrecedence; break;
-      case Op::I64GeU: opStr = "i64.ge_u"; infixStr = ">=u"; precedence = ComparisonPrecedence; break;
-      case Op::F32Eq:  opStr = "f32.eq"; infixStr = "=="; precedence = EqualityPrecedence; break;
-      case Op::F32Ne:  opStr = "f32.ne"; infixStr = "!="; precedence = EqualityPrecedence; break;
-      case Op::F32Lt:  opStr = "f32.lt"; infixStr = "<"; precedence = ComparisonPrecedence; break;
-      case Op::F32Le:  opStr = "f32.le"; infixStr = "<="; precedence = ComparisonPrecedence; break;
-      case Op::F32Gt:  opStr = "f32.gt"; infixStr = ">"; precedence = ComparisonPrecedence; break;
-      case Op::F32Ge:  opStr = "f32.ge"; infixStr = ">="; precedence = ComparisonPrecedence; break;
-      case Op::F64Eq:  opStr = "f64.eq"; infixStr = "=="; precedence = ComparisonPrecedence; break;
-      case Op::F64Ne:  opStr = "f64.ne"; infixStr = "!="; precedence = EqualityPrecedence; break;
-      case Op::F64Lt:  opStr = "f64.lt"; infixStr = "<"; precedence = EqualityPrecedence; break;
-      case Op::F64Le:  opStr = "f64.le"; infixStr = "<="; precedence = ComparisonPrecedence; break;
-      case Op::F64Gt:  opStr = "f64.gt"; infixStr = ">"; precedence = ComparisonPrecedence; break;
-      case Op::F64Ge:  opStr = "f64.ge"; infixStr = ">="; precedence = ComparisonPrecedence; break;
-      default: return false;
-    }
-
-    if (c.f.allowAsciiOperators && infixStr) {
-        if (!c.f.reduceParens || lastPrecedence > precedence) {
-            if (!c.buffer.append("("))
-                return false;
-        }
-        c.currentPrecedence = precedence;
-        if (!PrintExpr(c, *comp.lhs()))
-            return false;
-        if (!c.buffer.append(" "))
-            return false;
-        if (!c.buffer.append(infixStr, strlen(infixStr)))
-            return false;
-        if (!c.buffer.append(" "))
-            return false;
-        // case of  A == (B == C)
-        c.currentPrecedence = (PrintOperatorPrecedence)(precedence + 1);
-        if (!PrintExpr(c, *comp.rhs()))
-            return false;
-        if (!c.f.reduceParens || lastPrecedence > precedence) {
-            if (!c.buffer.append(")"))
-                return false;
-        }
-    } else {
-        if (!c.buffer.append(opStr, strlen(opStr)))
-            return false;
-        c.currentPrecedence = ExpressionPrecedence;
-        if (!c.buffer.append("("))
-            return false;
-        if (!PrintExpr(c, *comp.lhs()))
-            return false;
-        if (!c.buffer.append(", "))
-            return false;
-        if (!PrintExpr(c, *comp.rhs()))
-            return false;
-        if (!c.buffer.append(")"))
-            return false;
-    }
-    c.currentPrecedence = lastPrecedence;
-
-    return true;
-}
-
-static bool
-PrintConversionOperator(WasmPrintContext& c, AstConversionOperator& conv)
-{
-    PrintOperatorPrecedence lastPrecedence = c.currentPrecedence;
-
-    const char* opStr;
-    const char* prefixStr = nullptr;
-    PrintOperatorPrecedence precedence = ExpressionPrecedence;
-    switch (conv.op()) {
-      case Op::I32Eqz:            opStr = "i32.eqz"; prefixStr = "!"; precedence = EqzPrecedence; break;
-      case Op::I32WrapI64:        opStr = "i32.wrap/i64"; break;
-      case Op::I32TruncSF32:      opStr = "i32.trunc_s/f32"; break;
-      case Op::I32TruncUF32:      opStr = "i32.trunc_u/f32"; break;
-      case Op::I32ReinterpretF32: opStr = "i32.reinterpret/f32"; break;
-      case Op::I32TruncSF64:      opStr = "i32.trunc_s/f64"; break;
-      case Op::I32TruncUF64:      opStr = "i32.trunc_u/f64"; break;
-      case Op::I64Eqz:            opStr = "i64.eqz"; prefixStr = "!"; precedence = EqzPrecedence; break;
-      case Op::I64ExtendSI32:     opStr = "i64.extend_s/i32"; break;
-      case Op::I64ExtendUI32:     opStr = "i64.extend_u/i32"; break;
-      case Op::I64TruncSF32:      opStr = "i64.trunc_s/f32"; break;
-      case Op::I64TruncUF32:      opStr = "i64.trunc_u/f32"; break;
-      case Op::I64TruncSF64:      opStr = "i64.trunc_s/f64"; break;
-      case Op::I64TruncUF64:      opStr = "i64.trunc_u/f64"; break;
-      case Op::I64ReinterpretF64: opStr = "i64.reinterpret/f64"; break;
-      case Op::F32ConvertSI32:    opStr = "f32.convert_s/i32"; break;
-      case Op::F32ConvertUI32:    opStr = "f32.convert_u/i32"; break;
-      case Op::F32ReinterpretI32: opStr = "f32.reinterpret/i32"; break;
-      case Op::F32ConvertSI64:    opStr = "f32.convert_s/i64"; break;
-      case Op::F32ConvertUI64:    opStr = "f32.convert_u/i64"; break;
-      case Op::F32DemoteF64:      opStr = "f32.demote/f64"; break;
-      case Op::F64ConvertSI32:    opStr = "f64.convert_s/i32"; break;
-      case Op::F64ConvertUI32:    opStr = "f64.convert_u/i32"; break;
-      case Op::F64ConvertSI64:    opStr = "f64.convert_s/i64"; break;
-      case Op::F64ConvertUI64:    opStr = "f64.convert_u/i64"; break;
-      case Op::F64ReinterpretI64: opStr = "f64.reinterpret/i64"; break;
-      case Op::F64PromoteF32:     opStr = "f64.promote/f32"; break;
-      default: return false;
-    }
-
-    if (c.f.allowAsciiOperators && prefixStr) {
-        if (!c.f.reduceParens || lastPrecedence > precedence) {
-            if (!c.buffer.append("("))
-                return false;
-        }
-
-        c.currentPrecedence = precedence;
-        if (!c.buffer.append(prefixStr, strlen(prefixStr)))
-            return false;
-        if (!PrintExpr(c, *conv.operand()))
-            return false;
-
-        if (!c.f.reduceParens || lastPrecedence > precedence) {
-          if (!c.buffer.append(")"))
-              return false;
-        }
-    } else {
-        if (!c.buffer.append(opStr, strlen(opStr)))
-            return false;
-        if (!c.buffer.append("("))
-            return false;
-
-        c.currentPrecedence = ExpressionPrecedence;
-        if (!PrintExpr(c, *conv.operand()))
-            return false;
-
-        if (!c.buffer.append(")"))
-            return false;
-    }
-    c.currentPrecedence = lastPrecedence;
-
-    return true;
-}
-
-static bool
-PrintIf(WasmPrintContext& c, AstIf& if_)
-{
-    PrintOperatorPrecedence lastPrecedence = c.currentPrecedence;
-
-    c.currentPrecedence = ExpressionPrecedence;
-    if (!c.buffer.append("if ("))
-        return false;
-    if (!PrintExpr(c, if_.cond()))
-        return false;
-
-    if (!c.buffer.append(") {\n"))
-        return false;
-
-    c.indent++;
-    if (!PrintExprList(c, if_.thenExprs()))
-        return false;
-    c.indent--;
-
-    if (!PrintBlockName(c, if_.name()))
-        return false;
-
-    if (if_.hasElse()) {
-        if (!PrintIndent(c))
-            return false;
-        if (!c.buffer.append("} else {\n"))
-            return false;
-
-        c.indent++;
-        if (!PrintExprList(c, if_.elseExprs()))
-            return false;
-        c.indent--;
-        if (!PrintBlockName(c, if_.name()))
-            return false;
-    }
-
-    if (!PrintIndent(c))
-        return false;
-
-    c.currentPrecedence = lastPrecedence;
-
-    return c.buffer.append("}");
-}
-
-static bool
-PrintLoadStoreAddress(WasmPrintContext& c, const AstLoadStoreAddress& lsa, uint32_t defaultAlignLog2)
-{
-    PrintOperatorPrecedence lastPrecedence = c.currentPrecedence;
-
-    c.currentPrecedence = ExpressionPrecedence;
-
-    if (!c.buffer.append("["))
-        return false;
-    if (!PrintExpr(c, lsa.base()))
-        return false;
-
-    if (lsa.offset() != 0) {
-        if (!c.buffer.append(", "))
-            return false;
-        if (!PrintInt32(c, lsa.offset(), true))
-            return false;
-    }
-    if (!c.buffer.append("]"))
-        return false;
-
-    uint32_t alignLog2 = lsa.flags();
-    if (defaultAlignLog2 != alignLog2) {
-        if (!c.buffer.append(", align="))
-            return false;
-        if (!PrintInt32(c, 1 << alignLog2))
-            return false;
-    }
-
-    c.currentPrecedence = lastPrecedence;
-    return true;
-}
-
-static bool
-PrintLoad(WasmPrintContext& c, AstLoad& load)
-{
-    PrintOperatorPrecedence lastPrecedence = c.currentPrecedence;
-
-    c.currentPrecedence = LoadOperatorPrecedence;
-    if (!c.f.reduceParens || lastPrecedence > LoadOperatorPrecedence) {
-        if (!c.buffer.append("("))
-            return false;
-    }
-
-    uint32_t defaultAlignLog2;
-    switch (load.op()) {
-      case Op::I32Load8S:
-        if (!c.buffer.append("i32:8s"))
-            return false;
-        defaultAlignLog2 = 0;
-        break;
-      case Op::I64Load8S:
-        if (!c.buffer.append("i64:8s"))
-            return false;
-        defaultAlignLog2 = 0;
-        break;
-      case Op::I32Load8U:
-        if (!c.buffer.append("i32:8u"))
-            return false;
-        defaultAlignLog2 = 0;
-        break;
-      case Op::I64Load8U:
-        if (!c.buffer.append("i64:8u"))
-            return false;
-        defaultAlignLog2 = 0;
-        break;
-      case Op::I32Load16S:
-        if (!c.buffer.append("i32:16s"))
-            return false;
-        defaultAlignLog2 = 1;
-        break;
-      case Op::I64Load16S:
-        if (!c.buffer.append("i64:16s"))
-            return false;
-        defaultAlignLog2 = 1;
-        break;
-      case Op::I32Load16U:
-        if (!c.buffer.append("i32:16u"))
-            return false;
-        defaultAlignLog2 = 1;
-        break;
-      case Op::I64Load16U:
-        if (!c.buffer.append("i64:16u"))
-            return false;
-        defaultAlignLog2 = 1;
-        break;
-      case Op::I64Load32S:
-        if (!c.buffer.append("i64:32s"))
-            return false;
-        defaultAlignLog2 = 2;
-        break;
-      case Op::I64Load32U:
-        if (!c.buffer.append("i64:32u"))
-            return false;
-        defaultAlignLog2 = 2;
-        break;
-      case Op::I32Load:
-        if (!c.buffer.append("i32"))
-            return false;
-        defaultAlignLog2 = 2;
-        break;
-      case Op::I64Load:
-        if (!c.buffer.append("i64"))
-            return false;
-        defaultAlignLog2 = 3;
-        break;
-      case Op::F32Load:
-        if (!c.buffer.append("f32"))
-            return false;
-        defaultAlignLog2 = 2;
-        break;
-      case Op::F64Load:
-        if (!c.buffer.append("f64"))
-            return false;
-        defaultAlignLog2 = 3;
-        break;
-      default:
-        return false;
-    }
-
-    if (!PrintLoadStoreAddress(c, load.address(), defaultAlignLog2))
-        return false;
-
-    if (!c.f.reduceParens || lastPrecedence > LoadOperatorPrecedence) {
-        if (!c.buffer.append(")"))
-            return false;
-    }
-    c.currentPrecedence = lastPrecedence;
-
-    return true;
-}
-
-static bool
-PrintStore(WasmPrintContext& c, AstStore& store)
-{
-    PrintOperatorPrecedence lastPrecedence = c.currentPrecedence;
-
-    c.currentPrecedence = StoreOperatorPrecedence;
-    if (!c.f.reduceParens || lastPrecedence > StoreOperatorPrecedence) {
-        if (!c.buffer.append("("))
-            return false;
-    }
-
-    uint32_t defaultAlignLog2;
-    switch (store.op()) {
-      case Op::I32Store8:
-        if (!c.buffer.append("i32:8"))
-            return false;
-        defaultAlignLog2 = 0;
-        break;
-      case Op::I64Store8:
-        if (!c.buffer.append("i64:8"))
-            return false;
-        defaultAlignLog2 = 0;
-        break;
-      case Op::I32Store16:
-        if (!c.buffer.append("i32:16"))
-            return false;
-        defaultAlignLog2 = 1;
-        break;
-      case Op::I64Store16:
-        if (!c.buffer.append("i64:16"))
-            return false;
-        defaultAlignLog2 = 1;
-        break;
-      case Op::I64Store32:
-        if (!c.buffer.append("i64:32"))
-            return false;
-        defaultAlignLog2 = 2;
-        break;
-      case Op::I32Store:
-        if (!c.buffer.append("i32"))
-            return false;
-        defaultAlignLog2 = 2;
-        break;
-      case Op::I64Store:
-        if (!c.buffer.append("i64"))
-            return false;
-        defaultAlignLog2 = 3;
-        break;
-      case Op::F32Store:
-        if (!c.buffer.append("f32"))
-            return false;
-        defaultAlignLog2 = 2;
-        break;
-      case Op::F64Store:
-        if (!c.buffer.append("f64"))
-            return false;
-        defaultAlignLog2 = 3;
-        break;
-      default:
-        return false;
-    }
-
-    if (!PrintLoadStoreAddress(c, store.address(), defaultAlignLog2))
-        return false;
-
-    if (!c.buffer.append(" = "))
-        return false;
-
-    if (!PrintExpr(c, store.value()))
-        return false;
-
-    if (!c.f.reduceParens || lastPrecedence > StoreOperatorPrecedence) {
-        if (!c.buffer.append(")"))
-            return false;
-    }
-
-    c.currentPrecedence = lastPrecedence;
-    return true;
-}
-
-static bool
-PrintBranch(WasmPrintContext& c, AstBranch& branch)
-{
-    Op op = branch.op();
-    MOZ_ASSERT(op == Op::BrIf || op == Op::Br);
-
-    if (op == Op::BrIf ? !c.buffer.append("br_if ") : !c.buffer.append("br "))
-        return false;
-
-    if (op == Op::BrIf || branch.maybeValue()) {
-        if (!c.buffer.append('('))
-            return false;
-    }
-
-    if (op == Op::BrIf) {
-        if (!PrintExpr(c, branch.cond()))
-            return false;
-    }
-
-    if (branch.maybeValue()) {
-        if (!c.buffer.append(", "))
-            return false;
-
-        if (!PrintExpr(c, *(branch.maybeValue())))
-            return false;
-    }
-
-    if (op == Op::BrIf || branch.maybeValue()) {
-        if (!c.buffer.append(") "))
-            return false;
-    }
-
-    if (!PrintRef(c, branch.target()))
-        return false;
-
-    return true;
-}
-
-static bool
-PrintBrTable(WasmPrintContext& c, AstBranchTable& table)
-{
-    if (!c.buffer.append("br_table "))
-        return false;
-
-    if (!c.buffer.append('('))
-        return false;
-
-    // Index
-    if (!PrintExpr(c, table.index()))
-        return false;
-
-    if (table.maybeValue()) {
-      if (!c.buffer.append(", "))
-          return false;
-
-      if (!PrintExpr(c, *(table.maybeValue())))
-          return false;
-    }
-
-    if (!c.buffer.append(") "))
-        return false;
-
-    uint32_t tableLength = table.table().length();
-    if (tableLength > 0) {
-        if (!c.buffer.append("["))
-            return false;
-        for (uint32_t i = 0; i < tableLength; i++) {
-            if (!PrintRef(c, table.table()[i]))
-                return false;
-            if (i + 1 == tableLength)
-                break;
-            if (!c.buffer.append(", "))
-                return false;
-        }
-        if (!c.buffer.append("], "))
-            return false;
-    }
-
-    if (!PrintRef(c, table.def()))
-        return false;
-
-    return true;
-}
-
-static bool
-PrintReturn(WasmPrintContext& c, AstReturn& ret)
-{
-    if (!c.buffer.append("return"))
-        return false;
-
-    if (ret.maybeExpr()) {
-        if (!c.buffer.append(" "))
-            return false;
-        if (!PrintExpr(c, *(ret.maybeExpr())))
-            return false;
-    }
-
-    return true;
-}
-
-static bool
-PrintFirst(WasmPrintContext& c, AstFirst& first)
-{
-    if (!c.buffer.append("first("))
-        return false;
-
-    for (uint32_t i = 0; i < first.exprs().length(); i++) {
-        if (!PrintExpr(c, *first.exprs()[i]))
-            return false;
-        if (i + 1 == first.exprs().length())
-            break;
-        if (!c.buffer.append(", "))
-            return false;
-    }
-
-    if (!c.buffer.append(")"))
-        return false;
-
-    return true;
-}
-
-static bool
-PrintCurrentMemory(WasmPrintContext& c, AstCurrentMemory& cm)
-{
-    return c.buffer.append("current_memory");
-}
-
-static bool
-PrintGrowMemory(WasmPrintContext& c, AstGrowMemory& gm)
-{
-    if (!c.buffer.append("grow_memory("))
-        return false;
-
-    PrintOperatorPrecedence lastPrecedence = c.currentPrecedence;
-    c.currentPrecedence = ExpressionPrecedence;
-
-    if (!PrintExpr(c, *gm.operand()))
-        return false;
-
-    if (!c.buffer.append(")"))
-        return false;
-
-    c.currentPrecedence = lastPrecedence;
-    return true;
-}
-
-static bool
-PrintExpr(WasmPrintContext& c, AstExpr& expr)
-{
-    if (c.maybeSourceMap) {
-        uint32_t lineno = c.buffer.lineno();
-        uint32_t column = c.buffer.column();
-        if (!c.maybeSourceMap->exprlocs().emplaceBack(lineno, column, expr.offset()))
-            return false;
-    }
-
-    switch (expr.kind()) {
-      case AstExprKind::Nop:
-        return PrintNop(c);
-      case AstExprKind::Drop:
-        return PrintDrop(c, expr.as<AstDrop>());
-      case AstExprKind::Unreachable:
-        return PrintUnreachable(c, expr.as<AstUnreachable>());
-      case AstExprKind::Call:
-        return PrintCall(c, expr.as<AstCall>());
-      case AstExprKind::CallIndirect:
-        return PrintCallIndirect(c, expr.as<AstCallIndirect>());
-      case AstExprKind::Const:
-        return PrintConst(c, expr.as<AstConst>());
-      case AstExprKind::GetLocal:
-        return PrintGetLocal(c, expr.as<AstGetLocal>());
-      case AstExprKind::SetLocal:
-        return PrintSetLocal(c, expr.as<AstSetLocal>());
-      case AstExprKind::TeeLocal:
-        return PrintTeeLocal(c, expr.as<AstTeeLocal>());
-      case AstExprKind::GetGlobal:
-        return PrintGetGlobal(c, expr.as<AstGetGlobal>());
-      case AstExprKind::SetGlobal:
-        return PrintSetGlobal(c, expr.as<AstSetGlobal>());
-      case AstExprKind::Block:
-        return PrintBlock(c, expr.as<AstBlock>());
-      case AstExprKind::If:
-        return PrintIf(c, expr.as<AstIf>());
-      case AstExprKind::UnaryOperator:
-        return PrintUnaryOperator(c, expr.as<AstUnaryOperator>());
-      case AstExprKind::BinaryOperator:
-        return PrintBinaryOperator(c, expr.as<AstBinaryOperator>());
-      case AstExprKind::TernaryOperator:
-        return PrintTernaryOperator(c, expr.as<AstTernaryOperator>());
-      case AstExprKind::ComparisonOperator:
-        return PrintComparisonOperator(c, expr.as<AstComparisonOperator>());
-      case AstExprKind::ConversionOperator:
-        return PrintConversionOperator(c, expr.as<AstConversionOperator>());
-      case AstExprKind::Load:
-        return PrintLoad(c, expr.as<AstLoad>());
-      case AstExprKind::Store:
-        return PrintStore(c, expr.as<AstStore>());
-      case AstExprKind::Branch:
-        return PrintBranch(c, expr.as<AstBranch>());
-      case AstExprKind::BranchTable:
-        return PrintBrTable(c, expr.as<AstBranchTable>());
-      case AstExprKind::Return:
-        return PrintReturn(c, expr.as<AstReturn>());
-      case AstExprKind::First:
-        return PrintFirst(c, expr.as<AstFirst>());
-      case AstExprKind::CurrentMemory:
-        return PrintCurrentMemory(c, expr.as<AstCurrentMemory>());
-      case AstExprKind::GrowMemory:
-        return PrintGrowMemory(c, expr.as<AstGrowMemory>());
-      case AstExprKind::Pop:
-        return true;
-    }
-
-    MOZ_CRASH("Bad AstExprKind");
-}
-
-static bool
-PrintSignature(WasmPrintContext& c, const AstSig& sig, const AstNameVector* maybeLocals = nullptr)
-{
-    uint32_t paramsNum = sig.args().length();
-
-    if (!c.buffer.append("("))
-        return false;
-    if (maybeLocals) {
-      for (uint32_t i = 0; i < paramsNum; i++) {
-          const AstName& name = (*maybeLocals)[i];
-          if (!name.empty()) {
-              if (!PrintName(c, name))
-                  return false;
-              if (!c.buffer.append(": "))
-                  return false;
-          }
-          ValType arg = sig.args()[i];
-          if (!PrintValType(c, arg))
-              return false;
-          if (i + 1 == paramsNum)
-              break;
-          if (!c.buffer.append(", "))
-              return false;
-      }
-    } else if (paramsNum > 0) {
-      for (uint32_t i = 0; i < paramsNum; i++) {
-          ValType arg = sig.args()[i];
-          if (!PrintValType(c, arg))
-              return false;
-          if (i + 1 == paramsNum)
-              break;
-          if (!c.buffer.append(", "))
-              return false;
-      }
-    }
-    if (!c.buffer.append(") : ("))
-        return false;
-    if (sig.ret() != ExprType::Void) {
-        if (!PrintExprType(c, sig.ret()))
-            return false;
-    }
-    if (!c.buffer.append(")"))
-        return false;
-    return true;
-}
-
-static bool
-PrintTypeSection(WasmPrintContext& c, const AstModule::SigVector& sigs)
-{
-    uint32_t numSigs = sigs.length();
-    if (!numSigs)
-        return true;
-
-    for (uint32_t sigIndex = 0; sigIndex < numSigs; sigIndex++) {
-        const AstSig* sig = sigs[sigIndex];
-        if (!PrintIndent(c))
-            return false;
-        if (!c.buffer.append("type "))
-            return false;
-        if (!sig->name().empty()) {
-          if (!PrintName(c, sig->name()))
-              return false;
-          if (!c.buffer.append(" of "))
-              return false;
-        }
-        if (!c.buffer.append("function "))
-            return false;
-        if (!PrintSignature(c, *sig))
-            return false;
-        if (!c.buffer.append(";\n"))
-            return false;
-    }
-
-    if (!c.buffer.append("\n"))
-        return false;
-
-    return true;
-}
-
-static bool
-PrintTableSection(WasmPrintContext& c, const AstModule& module)
-{
-    if (module.elemSegments().empty())
-        return true;
-
-    const AstElemSegment& segment = *module.elemSegments()[0];
-
-    if (!c.buffer.append("table ["))
-        return false;
-
-    for (uint32_t i = 0; i < segment.elems().length(); i++) {
-        const AstRef& elem = segment.elems()[i];
-        uint32_t index = elem.index();
-        AstName name = index < module.funcImportNames().length()
-                           ? module.funcImportNames()[index]
-                           : module.funcs()[index - module.funcImportNames().length()]->name();
-        if (name.empty()) {
-            if (!PrintInt32(c, index))
-                return false;
-        } else {
-          if (!PrintName(c, name))
-              return false;
-        }
-        if (i + 1 == segment.elems().length())
-            break;
-        if (!c.buffer.append(", "))
-            return false;
-    }
-
-    if (!c.buffer.append("];\n\n"))
-        return false;
-
-    return true;
-}
-
-static bool
-PrintImport(WasmPrintContext& c, AstImport& import, const AstModule::SigVector& sigs)
-{
-    const AstSig* sig = sigs[import.funcSig().index()];
-    if (!PrintIndent(c))
-        return false;
-    if (!c.buffer.append("import "))
-        return false;
-    if (!c.buffer.append("\""))
-        return false;
-
-    const AstName& fieldName = import.field();
-    if (!PrintEscapedString(c, fieldName))
-        return false;
-
-    if (!c.buffer.append("\" as "))
-        return false;
-
-    if (!PrintName(c, import.name()))
-        return false;
-
-    if (!c.buffer.append(" from \""))
-        return false;
-
-    const AstName& moduleName = import.module();
-    if (!PrintEscapedString(c, moduleName))
-        return false;
-
-    if (!c.buffer.append("\" typeof function "))
-        return false;
-
-    if (!PrintSignature(c, *sig))
-        return false;
-    if (!c.buffer.append(";\n"))
-        return false;
-
-    return true;
-}
-
-
-static bool
-PrintImportSection(WasmPrintContext& c, const AstModule::ImportVector& imports, const AstModule::SigVector& sigs)
-{
-    uint32_t numImports = imports.length();
-
-    for (uint32_t i = 0; i < numImports; i++) {
-        if (!PrintImport(c, *imports[i], sigs))
-            return false;
-    }
-
-    if (numImports) {
-      if (!c.buffer.append("\n"))
-          return false;
-    }
-
-    return true;
-}
-
-static bool
-PrintExport(WasmPrintContext& c, AstExport& export_,
-            const AstModule::NameVector& funcImportNames,
-            const AstModule::FuncVector& funcs)
-{
-    if (!PrintIndent(c))
-        return false;
-    if (!c.buffer.append("export "))
-        return false;
-    if (export_.kind() == DefinitionKind::Memory) {
-        if (!c.buffer.append("memory"))
-          return false;
-    } else {
-        uint32_t index = export_.ref().index();
-        AstName name = index < funcImportNames.length()
-                           ? funcImportNames[index]
-                           : funcs[index - funcImportNames.length()]->name();
-        if (name.empty()) {
-            if (!PrintInt32(c, index))
-                return false;
-        } else {
-            if (!PrintName(c, name))
-                return false;
-        }
-    }
-    if (!c.buffer.append(" as \""))
-        return false;
-    if (!PrintEscapedString(c, export_.name()))
-        return false;
-    if (!c.buffer.append("\";\n"))
-        return false;
-
-    return true;
-}
-
-static bool
-PrintExportSection(WasmPrintContext& c, const AstModule::ExportVector& exports,
-                   const AstModule::NameVector& funcImportNames,
-                   const AstModule::FuncVector& funcs)
-{
-    uint32_t numExports = exports.length();
-    for (uint32_t i = 0; i < numExports; i++) {
-        if (!PrintExport(c, *exports[i], funcImportNames, funcs))
-            return false;
-    }
-    if (numExports) {
-      if (!c.buffer.append("\n"))
-          return false;
-    }
-    return true;
-}
-
-static bool
-PrintFunctionBody(WasmPrintContext& c, AstFunc& func, const AstModule::SigVector& sigs)
-{
-    const AstSig* sig = sigs[func.sig().index()];
-    c.indent++;
-
-    uint32_t argsNum = sig->args().length();
-    uint32_t localsNum = func.vars().length();
-    if (localsNum > 0) {
-        if (!PrintIndent(c))
-            return false;
-        if (!c.buffer.append("var "))
-            return false;
-        for (uint32_t i = 0; i < localsNum; i++) {
-            const AstName& name = func.locals()[argsNum + i];
-            if (!name.empty()) {
-              if (!PrintName(c, name))
-                  return false;
-              if (!c.buffer.append(": "))
-                  return false;
-            }
-            ValType local = func.vars()[i];
-            if (!PrintValType(c, local))
-                return false;
-            if (i + 1 == localsNum)
-                break;
-            if (!c.buffer.append(", "))
-                return false;
-        }
-        if (!c.buffer.append(";\n"))
-            return false;
-    }
-
-
-    uint32_t exprsNum = func.body().length();
-    for (uint32_t i = 0; i < exprsNum; i++) {
-      if (!PrintBlockLevelExpr(c, *func.body()[i], i + 1 == exprsNum))
-          return false;
-    }
-
-    c.indent--;
-
-    if (c.maybeSourceMap) {
-        if (!c.maybeSourceMap->exprlocs().emplaceBack(c.buffer.lineno(), c.buffer.column(), func.endOffset()))
-            return false;
-    }
-    return true;
-}
-
-static bool
-PrintCodeSection(WasmPrintContext& c, const AstModule::FuncVector& funcs, const AstModule::SigVector& sigs)
-{
-    uint32_t numFuncBodies = funcs.length();
-    for (uint32_t funcIndex = 0; funcIndex < numFuncBodies; funcIndex++) {
-        AstFunc* func = funcs[funcIndex];
-        uint32_t sigIndex = func->sig().index();
-        AstSig* sig = sigs[sigIndex];
-
-        if (!PrintIndent(c))
-            return false;
-        if (!c.buffer.append("function "))
-            return false;
-        if (!func->name().empty()) {
-          if (!PrintName(c, func->name()))
-              return false;
-        }
-
-        if (!PrintSignature(c, *sig, &(func->locals())))
-            return false;
-        if (!c.buffer.append(" {\n"))
-            return false;
-
-        c.currentFuncIndex = funcIndex;
-
-        if (!PrintFunctionBody(c, *func, sigs))
-            return false;
-
-        if (!PrintIndent(c))
-            return false;
-        if (!c.buffer.append("}\n\n"))
-            return false;
-    }
-
-   return true;
-}
-
-static bool
-PrintDataSection(WasmPrintContext& c, const AstModule& module)
-{
-    if (!module.hasMemory())
-        return true;
-
-    MOZ_ASSERT(module.memories().length() == 1, "NYI: several memories");
-
-    if (!PrintIndent(c))
-        return false;
-    if (!c.buffer.append("memory "))
-        return false;
-
-    const Limits& memory = module.memories()[0].limits;
-    MOZ_ASSERT(memory.initial % PageSize == 0);
-    if (!PrintInt32(c, memory.initial / PageSize))
-        return false;
-
-    if (memory.maximum) {
-        MOZ_ASSERT(*memory.maximum % PageSize == 0);
-        if (!c.buffer.append(", "))
-            return false;
-        if (!PrintInt32(c, *memory.maximum / PageSize))
-            return false;
-    }
-
-    c.indent++;
-
-    uint32_t numSegments = module.dataSegments().length();
-    if (!numSegments) {
-        if (!c.buffer.append(" {}\n\n"))
-            return false;
-        return true;
-    }
-    if (!c.buffer.append(" {\n"))
-        return false;
-
-    for (uint32_t i = 0; i < numSegments; i++) {
-        const AstDataSegment* segment = module.dataSegments()[i];
-        if (!PrintIndent(c))
-            return false;
-        if (!c.buffer.append("segment "))
-            return false;
-        if (!PrintInt32(c, segment->offset()->as<AstConst>().val().i32()))
-            return false;
-        if (!c.buffer.append("\n"))
-            return false;
-
-        c.indent++;
-        for (const AstName& fragment : segment->fragments()) {
-            if (!PrintIndent(c))
-                return false;
-            if (!c.buffer.append("\""))
-                return false;
-            if (!PrintEscapedString(c, fragment))
-                return false;
-            if (!c.buffer.append("\"\n"))
-                return false;
-        }
-        c.indent--;
-
-        if (!PrintIndent(c))
-            return false;
-        if (!c.buffer.append(";\n"))
-            return false;
-    }
-
-    c.indent--;
-    if (!c.buffer.append("}\n\n"))
-        return false;
-
-    return true;
-}
-
-static bool
-PrintModule(WasmPrintContext& c, AstModule& module)
-{
-    if (!PrintTypeSection(c, module.sigs()))
-        return false;
-
-    if (!PrintImportSection(c, module.imports(), module.sigs()))
-        return false;
-
-    if (!PrintTableSection(c, module))
-        return false;
-
-    if (!PrintExportSection(c, module.exports(), module.funcImportNames(), module.funcs()))
-        return false;
-
-    if (!PrintCodeSection(c, module.funcs(), module.sigs()))
-        return false;
-
-    if (!PrintDataSection(c, module))
-        return false;
-
-    return true;
-}
-
-/*****************************************************************************/
-// Top-level functions
-
-bool
-wasm::BinaryToExperimentalText(JSContext* cx, const uint8_t* bytes, size_t length,
-                               StringBuffer& buffer, const ExperimentalTextFormatting& formatting,
-                               GeneratedSourceMap* sourceMap)
-{
-
-    LifoAlloc lifo(AST_LIFO_DEFAULT_CHUNK_SIZE);
-
-    AstModule* module;
-    if (!BinaryToAst(cx, bytes, length, lifo, &module))
-        return false;
-
-    WasmPrintBuffer buf(buffer);
-    WasmPrintContext c(cx, module, buf, formatting, sourceMap);
-
-    if (!PrintModule(c, *module)) {
-        if (!cx->isExceptionPending())
-            ReportOutOfMemory(cx);
-        return false;
-    }
-
-    return true;
-}
-
deleted file mode 100644
--- a/js/src/wasm/WasmBinaryToExperimentalText.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- *
- * Copyright 2015 Mozilla Foundation
- *
- * 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.
- */
-
-#ifndef wasm_binary_to_experimental_text_h
-#define wasm_binary_to_experimental_text_h
-
-#include "NamespaceImports.h"
-
-#include "gc/Rooting.h"
-#include "js/Class.h"
-#include "wasm/WasmCode.h"
-
-namespace js {
-
-class StringBuffer;
-
-namespace wasm {
-
-struct ExperimentalTextFormatting
-{
-    bool allowAsciiOperators:1;
-    bool reduceParens:1;
-    bool groupBlocks:1;
-
-    ExperimentalTextFormatting()
-     : allowAsciiOperators(true),
-       reduceParens(true),
-       groupBlocks(true)
-    {}
-};
-
-// Translate the given binary representation of a wasm module into the module's textual
-// representation.
-
-MOZ_MUST_USE bool
-BinaryToExperimentalText(JSContext* cx, const uint8_t* bytes, size_t length, StringBuffer& buffer,
-                         const ExperimentalTextFormatting& formatting = ExperimentalTextFormatting(),
-                         GeneratedSourceMap* sourceMap = nullptr);
-
-}  // namespace wasm
-
-}  // namespace js
-
-#endif // namespace wasm_binary_to_experimental_text_h