| Index: src/wasm/asm-wasm-builder.cc
 | 
| diff --git a/src/wasm/asm-wasm-builder.cc b/src/wasm/asm-wasm-builder.cc
 | 
| index 70c5c1ef8b4eaad87f38c820dadb363d77278162..a6287b047a9ffdaf1fd7c8d7e85779b62650942e 100644
 | 
| --- a/src/wasm/asm-wasm-builder.cc
 | 
| +++ b/src/wasm/asm-wasm-builder.cc
 | 
| @@ -92,19 +92,35 @@ class AsmWasmBuilderImpl : public AstVisitor {
 | 
|        }
 | 
|      }
 | 
|      DCHECK(in_function_);
 | 
| -    breakable_blocks_.push_back(
 | 
| -        std::make_pair(stmt->AsBreakableStatement(), false));
 | 
| -    current_function_builder_->Emit(kExprBlock);
 | 
| -    uint32_t index = current_function_builder_->EmitEditableImmediate(0);
 | 
| -    int prev_block_size = block_size_;
 | 
| +    BlockVisitor visitor(this, stmt->AsBreakableStatement(), kExprBlock, false);
 | 
|      block_size_ = static_cast<byte>(stmt->statements()->length());
 | 
|      RECURSE(VisitStatements(stmt->statements()));
 | 
|      DCHECK(block_size_ >= 0);
 | 
| -    current_function_builder_->EditImmediate(index, block_size_);
 | 
| -    block_size_ = prev_block_size;
 | 
| -    breakable_blocks_.pop_back();
 | 
|    }
 | 
|  
 | 
| +  class BlockVisitor {
 | 
| +   private:
 | 
| +    int prev_block_size_;
 | 
| +    uint32_t index_;
 | 
| +    AsmWasmBuilderImpl* builder_;
 | 
| +
 | 
| +   public:
 | 
| +    BlockVisitor(AsmWasmBuilderImpl* builder, BreakableStatement* stmt,
 | 
| +                 WasmOpcode opcode, bool is_loop)
 | 
| +        : builder_(builder) {
 | 
| +      builder_->breakable_blocks_.push_back(std::make_pair(stmt, is_loop));
 | 
| +      builder_->current_function_builder_->Emit(opcode);
 | 
| +      index_ = builder_->current_function_builder_->EmitEditableImmediate(0);
 | 
| +      prev_block_size_ = builder_->block_size_;
 | 
| +    }
 | 
| +    ~BlockVisitor() {
 | 
| +      builder_->current_function_builder_->EditImmediate(index_,
 | 
| +                                                         builder_->block_size_);
 | 
| +      builder_->block_size_ = prev_block_size_;
 | 
| +      builder_->breakable_blocks_.pop_back();
 | 
| +    }
 | 
| +  };
 | 
| +
 | 
|    void VisitExpressionStatement(ExpressionStatement* stmt) {
 | 
|      RECURSE(Visit(stmt->expression()));
 | 
|    }
 | 
| @@ -207,34 +223,23 @@ class AsmWasmBuilderImpl : public AstVisitor {
 | 
|  
 | 
|    void VisitDoWhileStatement(DoWhileStatement* stmt) {
 | 
|      DCHECK(in_function_);
 | 
| -    current_function_builder_->Emit(kExprLoop);
 | 
| -    uint32_t index = current_function_builder_->EmitEditableImmediate(0);
 | 
| -    int prev_block_size = block_size_;
 | 
| -    block_size_ = 0;
 | 
| -    breakable_blocks_.push_back(
 | 
| -        std::make_pair(stmt->AsBreakableStatement(), true));
 | 
| -    block_size_++;
 | 
| +    BlockVisitor visitor(this, stmt->AsBreakableStatement(), kExprLoop, true);
 | 
| +    block_size_ = 2;
 | 
|      RECURSE(Visit(stmt->body()));
 | 
| -    block_size_++;
 | 
|      current_function_builder_->Emit(kExprIf);
 | 
|      RECURSE(Visit(stmt->cond()));
 | 
|      current_function_builder_->EmitWithU8(kExprBr, 0);
 | 
|      current_function_builder_->Emit(kExprNop);
 | 
| -    current_function_builder_->EditImmediate(index, block_size_);
 | 
| -    block_size_ = prev_block_size;
 | 
| -    breakable_blocks_.pop_back();
 | 
|    }
 | 
|  
 | 
|    void VisitWhileStatement(WhileStatement* stmt) {
 | 
|      DCHECK(in_function_);
 | 
| -    current_function_builder_->EmitWithU8(kExprLoop, 1);
 | 
| -    breakable_blocks_.push_back(
 | 
| -        std::make_pair(stmt->AsBreakableStatement(), true));
 | 
| +    BlockVisitor visitor(this, stmt->AsBreakableStatement(), kExprLoop, true);
 | 
| +    block_size_ = 1;
 | 
|      current_function_builder_->Emit(kExprIf);
 | 
|      RECURSE(Visit(stmt->cond()));
 | 
|      current_function_builder_->EmitWithU8(kExprBr, 0);
 | 
|      RECURSE(Visit(stmt->body()));
 | 
| -    breakable_blocks_.pop_back();
 | 
|    }
 | 
|  
 | 
|    void VisitForStatement(ForStatement* stmt) {
 | 
| @@ -243,12 +248,8 @@ class AsmWasmBuilderImpl : public AstVisitor {
 | 
|        block_size_++;
 | 
|        RECURSE(Visit(stmt->init()));
 | 
|      }
 | 
| -    current_function_builder_->Emit(kExprLoop);
 | 
| -    uint32_t index = current_function_builder_->EmitEditableImmediate(0);
 | 
| -    int prev_block_size = block_size_;
 | 
| +    BlockVisitor visitor(this, stmt->AsBreakableStatement(), kExprLoop, true);
 | 
|      block_size_ = 0;
 | 
| -    breakable_blocks_.push_back(
 | 
| -        std::make_pair(stmt->AsBreakableStatement(), true));
 | 
|      if (stmt->cond() != NULL) {
 | 
|        block_size_++;
 | 
|        current_function_builder_->Emit(kExprIf);
 | 
| @@ -268,9 +269,6 @@ class AsmWasmBuilderImpl : public AstVisitor {
 | 
|      block_size_++;
 | 
|      current_function_builder_->EmitWithU8(kExprBr, 0);
 | 
|      current_function_builder_->Emit(kExprNop);
 | 
| -    current_function_builder_->EditImmediate(index, block_size_);
 | 
| -    block_size_ = prev_block_size;
 | 
| -    breakable_blocks_.pop_back();
 | 
|    }
 | 
|  
 | 
|    void VisitForInStatement(ForInStatement* stmt) { UNREACHABLE(); }
 | 
| 
 |