static bool
RenderExpr(WasmRenderContext& c, AstExpr& expr)
{
    switch (expr.kind()) {
      case AstExprKind::NullaryOperator:
        return RenderNullaryOperator(c, expr.as<AstNullaryOperator>());
      case AstExprKind::Unreachable:
        return RenderUnreachable(c, expr.as<AstUnreachable>());
      case AstExprKind::Call:
        return RenderCall(c, expr.as<AstCall>());
      case AstExprKind::CallIndirect:
        return RenderCallIndirect(c, expr.as<AstCallIndirect>());
      case AstExprKind::Const:
        return RenderConst(c, expr.as<AstConst>());
      case AstExprKind::GetLocal:
        return RenderGetLocal(c, expr.as<AstGetLocal>());
      case AstExprKind::SetLocal:
        return RenderSetLocal(c, expr.as<AstSetLocal>());
      case AstExprKind::Block:
        return RenderBlock(c, expr.as<AstBlock>());
      case AstExprKind::If:
        return RenderIf(c, expr.as<AstIf>());
      case AstExprKind::UnaryOperator:
        return RenderUnaryOperator(c, expr.as<AstUnaryOperator>());
      case AstExprKind::BinaryOperator:
        return RenderBinaryOperator(c, expr.as<AstBinaryOperator>());
      case AstExprKind::TernaryOperator:
        return RenderTernaryOperator(c, expr.as<AstTernaryOperator>());
      case AstExprKind::ComparisonOperator:
        return RenderComparisonOperator(c, expr.as<AstComparisonOperator>());
      case AstExprKind::ConversionOperator:
        return RenderConversionOperator(c, expr.as<AstConversionOperator>());
      case AstExprKind::Load:
        return RenderLoad(c, expr.as<AstLoad>());
      case AstExprKind::Store:
        return RenderStore(c, expr.as<AstStore>());
      case AstExprKind::Branch:
        return RenderBranch(c, expr.as<AstBranch>());
      case AstExprKind::BranchTable:
        return RenderBrTable(c, expr.as<AstBranchTable>());
      case AstExprKind::Return:
        return RenderReturn(c, expr.as<AstReturn>());
      default:
        // Note: it's important not to remove this default since readExpr()
        // can return Expr values for which there is no enumerator.
        break;
    }

    return false;
}
static bool
RenderExpr(WasmRenderContext& c, AstExpr& expr, bool newLine /* = true */)
{
    switch (expr.kind()) {
      case AstExprKind::Drop:
        if (!RenderDrop(c, expr.as<AstDrop>()))
            return false;
        break;
      case AstExprKind::Nop:
        if (!RenderNop(c, expr.as<AstNop>()))
            return false;
        break;
      case AstExprKind::Unreachable:
        if (!RenderUnreachable(c, expr.as<AstUnreachable>()))
            return false;
        break;
      case AstExprKind::Call:
        if (!RenderCall(c, expr.as<AstCall>()))
            return false;
        break;
      case AstExprKind::CallIndirect:
        if (!RenderCallIndirect(c, expr.as<AstCallIndirect>()))
            return false;
        break;
      case AstExprKind::Const:
        if (!RenderConst(c, expr.as<AstConst>()))
            return false;
        break;
      case AstExprKind::GetLocal:
        if (!RenderGetLocal(c, expr.as<AstGetLocal>()))
            return false;
        break;
      case AstExprKind::SetLocal:
        if (!RenderSetLocal(c, expr.as<AstSetLocal>()))
            return false;
        break;
      case AstExprKind::GetGlobal:
        if (!RenderGetGlobal(c, expr.as<AstGetGlobal>()))
            return false;
        break;
      case AstExprKind::SetGlobal:
        if (!RenderSetGlobal(c, expr.as<AstSetGlobal>()))
            return false;
        break;
      case AstExprKind::TeeLocal:
        if (!RenderTeeLocal(c, expr.as<AstTeeLocal>()))
            return false;
        break;
      case AstExprKind::Block:
        if (!RenderBlock(c, expr.as<AstBlock>()))
            return false;
        break;
      case AstExprKind::If:
        if (!RenderIf(c, expr.as<AstIf>()))
            return false;
        break;
      case AstExprKind::UnaryOperator:
        if (!RenderUnaryOperator(c, expr.as<AstUnaryOperator>()))
            return false;
        break;
      case AstExprKind::BinaryOperator:
        if (!RenderBinaryOperator(c, expr.as<AstBinaryOperator>()))
            return false;
        break;
      case AstExprKind::TernaryOperator:
        if (!RenderTernaryOperator(c, expr.as<AstTernaryOperator>()))
            return false;
        break;
      case AstExprKind::ComparisonOperator:
        if (!RenderComparisonOperator(c, expr.as<AstComparisonOperator>()))
            return false;
        break;
      case AstExprKind::ConversionOperator:
        if (!RenderConversionOperator(c, expr.as<AstConversionOperator>()))
            return false;
        break;
      case AstExprKind::Load:
        if (!RenderLoad(c, expr.as<AstLoad>()))
            return false;
        break;
      case AstExprKind::Store:
        if (!RenderStore(c, expr.as<AstStore>()))
            return false;
        break;
      case AstExprKind::Branch:
        if (!RenderBranch(c, expr.as<AstBranch>()))
            return false;
        break;
      case AstExprKind::BranchTable:
        if (!RenderBrTable(c, expr.as<AstBranchTable>()))
            return false;
        break;
      case AstExprKind::Return:
        if (!RenderReturn(c, expr.as<AstReturn>()))
            return false;
        break;
      case AstExprKind::First:
        newLine = false;
        if (!RenderFirst(c, expr.as<AstFirst>()))
            return false;
        break;
      case AstExprKind::CurrentMemory:
        if (!RenderCurrentMemory(c, expr.as<AstCurrentMemory>()))
            return false;
        break;
      case AstExprKind::GrowMemory:
        if (!RenderGrowMemory(c, expr.as<AstGrowMemory>()))
            return false;
        break;
      default:
        MOZ_CRASH("Bad AstExprKind");
    }

    return !newLine || c.buffer.append("\n");
}
static bool
RenderExpr(WasmRenderContext& c, AstExpr& expr, bool newLine /* = true */)
{
    switch (expr.kind()) {
      case AstExprKind::Drop:
        if (!RenderDrop(c, expr.as<AstDrop>()))
            return false;
        break;
      case AstExprKind::Nop:
        if (!RenderNop(c, expr.as<AstNop>()))
            return false;
        break;
      case AstExprKind::Unreachable:
        if (!RenderUnreachable(c, expr.as<AstUnreachable>()))
            return false;
        break;
      case AstExprKind::Call:
        if (!RenderCall(c, expr.as<AstCall>()))
            return false;
        break;
      case AstExprKind::CallIndirect:
        if (!RenderCallIndirect(c, expr.as<AstCallIndirect>()))
            return false;
        break;
      case AstExprKind::Const:
        if (!RenderConst(c, expr.as<AstConst>()))
            return false;
        break;
      case AstExprKind::GetLocal:
        if (!RenderGetLocal(c, expr.as<AstGetLocal>()))
            return false;
        break;
      case AstExprKind::SetLocal:
        if (!RenderSetLocal(c, expr.as<AstSetLocal>()))
            return false;
        break;
      case AstExprKind::GetGlobal:
        if (!RenderGetGlobal(c, expr.as<AstGetGlobal>()))
            return false;
        break;
      case AstExprKind::SetGlobal:
        if (!RenderSetGlobal(c, expr.as<AstSetGlobal>()))
            return false;
        break;
      case AstExprKind::TeeLocal:
        if (!RenderTeeLocal(c, expr.as<AstTeeLocal>()))
            return false;
        break;
      case AstExprKind::Block:
        if (!RenderBlock(c, expr.as<AstBlock>()))
            return false;
        break;
      case AstExprKind::If:
        if (!RenderIf(c, expr.as<AstIf>()))
            return false;
        break;
      case AstExprKind::UnaryOperator:
        if (!RenderUnaryOperator(c, expr.as<AstUnaryOperator>()))
            return false;
        break;
      case AstExprKind::BinaryOperator:
        if (!RenderBinaryOperator(c, expr.as<AstBinaryOperator>()))
            return false;
        break;
      case AstExprKind::TernaryOperator:
        if (!RenderTernaryOperator(c, expr.as<AstTernaryOperator>()))
            return false;
        break;
      case AstExprKind::ComparisonOperator:
        if (!RenderComparisonOperator(c, expr.as<AstComparisonOperator>()))
            return false;
        break;
      case AstExprKind::ConversionOperator:
        if (!RenderConversionOperator(c, expr.as<AstConversionOperator>()))
            return false;
        break;
      case AstExprKind::Load:
        if (!RenderLoad(c, expr.as<AstLoad>()))
            return false;
        break;
      case AstExprKind::Store:
        if (!RenderStore(c, expr.as<AstStore>()))
            return false;
        break;
      case AstExprKind::Branch:
        if (!RenderBranch(c, expr.as<AstBranch>()))
            return false;
        break;
      case AstExprKind::BranchTable:
        if (!RenderBrTable(c, expr.as<AstBranchTable>()))
            return false;
        break;
      case AstExprKind::Return:
        if (!RenderReturn(c, expr.as<AstReturn>()))
            return false;
        break;
      case AstExprKind::First:
        newLine = false;
        if (!RenderFirst(c, expr.as<AstFirst>()))
            return false;
        break;
      case AstExprKind::CurrentMemory:
        if (!RenderCurrentMemory(c, expr.as<AstCurrentMemory>()))
            return false;
        break;
      case AstExprKind::GrowMemory:
        if (!RenderGrowMemory(c, expr.as<AstGrowMemory>()))
            return false;
        break;
      default:
        // Note: it's important not to remove this default since readExpr()
        // can return Expr values for which there is no enumerator.
        return Fail(c, "unexpected expression kind");
    }

    return !newLine || c.buffer.append("\n");
}