Commit 210e65ed authored by aseemgarg's avatar aseemgarg Committed by Commit bot

Add switch to asm to wasm

TEST=asm-wasm.js
R=titzer@chromium.org,bradnelson@google.com
BUG=

Review URL: https://codereview.chromium.org/1573413002

Cr-Commit-Position: refs/heads/master@{#33220}
parent 1be3c3a2
......@@ -149,6 +149,7 @@ class AsmWasmBuilderImpl : public AstVisitor {
void VisitContinueStatement(ContinueStatement* stmt) {
DCHECK(in_function_);
DCHECK(stmt->target() != NULL);
int i = static_cast<int>(breakable_blocks_.size()) - 1;
int block_distance = 0;
for (; i >= 0; i--) {
......@@ -169,6 +170,7 @@ class AsmWasmBuilderImpl : public AstVisitor {
void VisitBreakStatement(BreakStatement* stmt) {
DCHECK(in_function_);
DCHECK(stmt->target() != NULL);
int i = static_cast<int>(breakable_blocks_.size()) - 1;
int block_distance = 0;
for (; i >= 0; i--) {
......@@ -203,19 +205,52 @@ class AsmWasmBuilderImpl : public AstVisitor {
void VisitWithStatement(WithStatement* stmt) { UNREACHABLE(); }
void SetLocalTo(uint16_t index, int value) {
current_function_builder_->Emit(kExprSetLocal);
AddLeb128(index, true);
byte code[] = {WASM_I32(value)};
current_function_builder_->EmitCode(code, sizeof(code));
block_size_++;
}
void CompileCase(CaseClause* clause, uint16_t fall_through,
VariableProxy* tag) {
Literal* label = clause->label()->AsLiteral();
DCHECK(label != nullptr);
block_size_++;
current_function_builder_->Emit(kExprIf);
current_function_builder_->Emit(kExprI32Ior);
current_function_builder_->Emit(kExprI32Eq);
VisitVariableProxy(tag);
VisitLiteral(label);
current_function_builder_->Emit(kExprGetLocal);
AddLeb128(fall_through, true);
BlockVisitor visitor(this, nullptr, kExprBlock, false);
block_size_ = 0;
SetLocalTo(fall_through, 1);
ZoneList<Statement*>* stmts = clause->statements();
block_size_ += stmts->length();
RECURSE(VisitStatements(stmts));
}
void VisitSwitchStatement(SwitchStatement* stmt) {
RECURSE(Visit(stmt->tag()));
VariableProxy* tag = stmt->tag()->AsVariableProxy();
DCHECK(tag != NULL);
BlockVisitor visitor(this, stmt->AsBreakableStatement(), kExprBlock, false);
block_size_ = 0;
uint16_t fall_through = current_function_builder_->AddLocal(kAstI32);
SetLocalTo(fall_through, 0);
ZoneList<CaseClause*>* clauses = stmt->cases();
for (int i = 0; i < clauses->length(); ++i) {
CaseClause* clause = clauses->at(i);
if (!clause->is_default()) {
Expression* label = clause->label();
RECURSE(Visit(label));
CompileCase(clause, fall_through, tag);
} else {
ZoneList<Statement*>* stmts = clause->statements();
block_size_ += stmts->length();
RECURSE(VisitStatements(stmts));
}
ZoneList<Statement*>* stmts = clause->statements();
RECURSE(VisitStatements(stmts));
}
}
......
......@@ -669,3 +669,76 @@ function TestConditional() {
}
assertEquals(41, WASM.asmCompileRun(TestConditional.toString()));
function TestSwitch() {
"use asm"
function caller() {
var ret = 0;
var x = 7;
switch (x) {
case 1: return 0;
case 7: {
ret = 12;
break;
}
default: return 0;
}
switch (x) {
case 1: return 0;
case 8: return 0;
default: ret = (ret + 11)|0;
}
return ret|0;
}
return {caller:caller};
}
assertEquals(23, WASM.asmCompileRun(TestSwitch.toString()));
function TestSwitchFallthrough() {
"use asm"
function caller() {
var x = 17;
var ret = 0;
switch (x) {
case 17:
case 14: ret = 39;
case 1: ret = (ret + 3)|0;
case 4: break;
default: ret = (ret + 1)|0;
}
return ret|0;
}
return {caller:caller};
}
assertEquals(42, WASM.asmCompileRun(TestSwitchFallthrough.toString()));
function TestNestedSwitch() {
"use asm"
function caller() {
var x = 3;
var y = -13;
switch (x) {
case 1: return 0;
case 3: {
switch (y) {
case 2: return 0;
case -13: return 43;
default: return 0;
}
}
default: return 0;
}
return 0;
}
return {caller:caller};
}
assertEquals(43, WASM.asmCompileRun(TestNestedSwitch.toString()));
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment