Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(381)

Unified Diff: src/asmjs/asm-wasm-builder.cc

Issue 2693993002: [asm-wasm] Fix continue target of do-while loops (Closed)
Patch Set: Fix comment Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | test/mjsunit/wasm/asm-wasm.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_;
« no previous file with comments | « no previous file | test/mjsunit/wasm/asm-wasm.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698