| Index: src/asmjs/asm-wasm-builder.cc
|
| diff --git a/src/asmjs/asm-wasm-builder.cc b/src/asmjs/asm-wasm-builder.cc
|
| index 5e89ed5fdb20db4eb109aaafa3f2d3eed9119273..f7f7bfcad042a8a77bbf850412f1f18ae9941a57 100644
|
| --- a/src/asmjs/asm-wasm-builder.cc
|
| +++ b/src/asmjs/asm-wasm-builder.cc
|
| @@ -36,6 +36,8 @@ namespace wasm {
|
| if (HasStackOverflow()) return; \
|
| } while (false)
|
|
|
| +namespace {
|
| +
|
| enum AsmScope { kModuleScope, kInitScope, kFuncScope, kExportScope };
|
| enum ValueFate { kDrop, kLeaveOnStack };
|
|
|
| @@ -45,6 +47,10 @@ struct ForeignVariable {
|
| ValueType type;
|
| };
|
|
|
| +enum TargetType : uint8_t { NoTarget, BreakTarget, ContinueTarget };
|
| +
|
| +} // namespace
|
| +
|
| class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
|
| public:
|
| AsmWasmBuilderImpl(Isolate* isolate, Zone* zone, CompilationInfo* info,
|
| @@ -231,7 +237,8 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
|
| }
|
| }
|
| if (scope_ == kFuncScope) {
|
| - BlockVisitor visitor(this, stmt->AsBreakableStatement(), kExprBlock);
|
| + BlockVisitor visitor(this, stmt->AsBreakableStatement(), kExprBlock,
|
| + BreakTarget);
|
| RECURSE(VisitStatements(stmt->statements()));
|
| } else {
|
| RECURSE(VisitStatements(stmt->statements()));
|
| @@ -244,10 +251,9 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
|
|
|
| public:
|
| BlockVisitor(AsmWasmBuilderImpl* builder, BreakableStatement* stmt,
|
| - WasmOpcode opcode)
|
| + WasmOpcode opcode, TargetType target_type = NoTarget)
|
| : builder_(builder) {
|
| - builder_->breakable_blocks_.push_back(
|
| - std::make_pair(stmt, opcode == kExprLoop));
|
| + builder_->breakable_blocks_.emplace_back(stmt, target_type);
|
| // block and loops have a type immediate.
|
| builder_->current_function_builder_->EmitWithU8(opcode, kLocalVoid);
|
| }
|
| @@ -295,9 +301,8 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
|
| void VisitIfStatement(IfStatement* stmt) {
|
| DCHECK_EQ(kFuncScope, scope_);
|
| RECURSE(Visit(stmt->condition()));
|
| - current_function_builder_->EmitWithU8(kExprIf, kLocalVoid);
|
| - // WASM ifs come with implement blocks for both arms.
|
| - breakable_blocks_.push_back(std::make_pair(nullptr, false));
|
| + // Wasm ifs come with implicit blocks for both arms.
|
| + BlockVisitor block(this, nullptr, kExprIf);
|
| if (stmt->HasThenStatement()) {
|
| RECURSE(Visit(stmt->then_statement()));
|
| }
|
| @@ -305,18 +310,15 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
|
| current_function_builder_->Emit(kExprElse);
|
| RECURSE(Visit(stmt->else_statement()));
|
| }
|
| - current_function_builder_->Emit(kExprEnd);
|
| - breakable_blocks_.pop_back();
|
| }
|
|
|
| - void DoBreakOrContinue(BreakableStatement* target, bool is_continue) {
|
| + void DoBreakOrContinue(BreakableStatement* target, TargetType type) {
|
| DCHECK_EQ(kFuncScope, scope_);
|
| for (int i = static_cast<int>(breakable_blocks_.size()) - 1; i >= 0; --i) {
|
| auto elem = breakable_blocks_.at(i);
|
| - if (elem.first == target && elem.second == is_continue) {
|
| + if (elem.first == target && elem.second == type) {
|
| int block_distance = static_cast<int>(breakable_blocks_.size() - i - 1);
|
| - current_function_builder_->Emit(kExprBr);
|
| - current_function_builder_->EmitVarInt(block_distance);
|
| + current_function_builder_->EmitWithVarInt(kExprBr, block_distance);
|
| return;
|
| }
|
| }
|
| @@ -324,11 +326,11 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
|
| }
|
|
|
| void VisitContinueStatement(ContinueStatement* stmt) {
|
| - DoBreakOrContinue(stmt->target(), true);
|
| + DoBreakOrContinue(stmt->target(), ContinueTarget);
|
| }
|
|
|
| void VisitBreakStatement(BreakStatement* stmt) {
|
| - DoBreakOrContinue(stmt->target(), false);
|
| + DoBreakOrContinue(stmt->target(), BreakTarget);
|
| }
|
|
|
| void VisitReturnStatement(ReturnStatement* stmt) {
|
| @@ -366,7 +368,7 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
|
| current_function_builder_->Emit(kExprI32LtS);
|
| current_function_builder_->EmitWithU8(kExprIf, kLocalVoid);
|
| if_depth++;
|
| - breakable_blocks_.push_back(std::make_pair(nullptr, false));
|
| + breakable_blocks_.emplace_back(nullptr, NoTarget);
|
| HandleCase(node->left, case_to_block, tag, default_block, if_depth);
|
| current_function_builder_->Emit(kExprElse);
|
| }
|
| @@ -376,7 +378,7 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
|
| current_function_builder_->Emit(kExprI32GtS);
|
| current_function_builder_->EmitWithU8(kExprIf, kLocalVoid);
|
| if_depth++;
|
| - breakable_blocks_.push_back(std::make_pair(nullptr, false));
|
| + breakable_blocks_.emplace_back(nullptr, NoTarget);
|
| HandleCase(node->right, case_to_block, tag, default_block, if_depth);
|
| current_function_builder_->Emit(kExprElse);
|
| }
|
| @@ -430,7 +432,8 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
|
| if (case_count == 0) {
|
| return;
|
| }
|
| - BlockVisitor visitor(this, stmt->AsBreakableStatement(), kExprBlock);
|
| + BlockVisitor visitor(this, stmt->AsBreakableStatement(), kExprBlock,
|
| + BreakTarget);
|
| ZoneVector<BlockVisitor*> blocks(zone_);
|
| ZoneVector<int32_t> cases(zone_);
|
| ZoneMap<int, unsigned int> case_to_block(zone_);
|
| @@ -476,26 +479,28 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
|
|
|
| void VisitDoWhileStatement(DoWhileStatement* stmt) {
|
| DCHECK_EQ(kFuncScope, scope_);
|
| - BlockVisitor block(this, stmt->AsBreakableStatement(), kExprBlock);
|
| + BlockVisitor block(this, stmt->AsBreakableStatement(), kExprBlock,
|
| + BreakTarget);
|
| BlockVisitor loop(this, stmt->AsBreakableStatement(), kExprLoop);
|
| - RECURSE(Visit(stmt->body()));
|
| + {
|
| + BlockVisitor inner_block(this, stmt->AsBreakableStatement(), kExprBlock,
|
| + ContinueTarget);
|
| + RECURSE(Visit(stmt->body()));
|
| + }
|
| RECURSE(Visit(stmt->cond()));
|
| - current_function_builder_->EmitWithU8(kExprIf, kLocalVoid);
|
| - current_function_builder_->EmitWithU8(kExprBr, 1);
|
| - current_function_builder_->Emit(kExprEnd);
|
| + current_function_builder_->EmitWithU8(kExprBrIf, 0);
|
| }
|
|
|
| void VisitWhileStatement(WhileStatement* stmt) {
|
| DCHECK_EQ(kFuncScope, scope_);
|
| - BlockVisitor block(this, stmt->AsBreakableStatement(), kExprBlock);
|
| - BlockVisitor loop(this, stmt->AsBreakableStatement(), kExprLoop);
|
| + BlockVisitor block(this, stmt->AsBreakableStatement(), kExprBlock,
|
| + BreakTarget);
|
| + BlockVisitor loop(this, stmt->AsBreakableStatement(), kExprLoop,
|
| + ContinueTarget);
|
| RECURSE(Visit(stmt->cond()));
|
| - breakable_blocks_.push_back(std::make_pair(nullptr, false));
|
| - current_function_builder_->EmitWithU8(kExprIf, kLocalVoid);
|
| + BlockVisitor if_block(this, nullptr, kExprIf);
|
| RECURSE(Visit(stmt->body()));
|
| current_function_builder_->EmitWithU8(kExprBr, 1);
|
| - current_function_builder_->Emit(kExprEnd);
|
| - breakable_blocks_.pop_back();
|
| }
|
|
|
| void VisitForStatement(ForStatement* stmt) {
|
| @@ -503,8 +508,10 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
|
| if (stmt->init() != nullptr) {
|
| RECURSE(Visit(stmt->init()));
|
| }
|
| - BlockVisitor block(this, stmt->AsBreakableStatement(), kExprBlock);
|
| - BlockVisitor loop(this, stmt->AsBreakableStatement(), kExprLoop);
|
| + BlockVisitor block(this, stmt->AsBreakableStatement(), kExprBlock,
|
| + BreakTarget);
|
| + BlockVisitor loop(this, stmt->AsBreakableStatement(), kExprLoop,
|
| + ContinueTarget);
|
| if (stmt->cond() != nullptr) {
|
| RECURSE(Visit(stmt->cond()));
|
| current_function_builder_->Emit(kExprI32Eqz);
|
| @@ -562,8 +569,8 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
|
| void VisitConditional(Conditional* expr) {
|
| DCHECK_EQ(kFuncScope, scope_);
|
| RECURSE(Visit(expr->condition()));
|
| - // WASM ifs come with implicit blocks for both arms.
|
| - breakable_blocks_.push_back(std::make_pair(nullptr, false));
|
| + // Wasm ifs come with implicit blocks for both arms.
|
| + breakable_blocks_.emplace_back(nullptr, NoTarget);
|
| ValueTypeCode type;
|
| switch (TypeOf(expr)) {
|
| case kWasmI32:
|
| @@ -1969,7 +1976,7 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
|
| AsmTyper* typer_;
|
| bool typer_failed_;
|
| bool typer_finished_;
|
| - ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_;
|
| + ZoneVector<std::pair<BreakableStatement*, TargetType>> breakable_blocks_;
|
| ZoneVector<ForeignVariable> foreign_variables_;
|
| WasmFunctionBuilder* init_function_;
|
| WasmFunctionBuilder* foreign_init_function_;
|
|
|