Fixing asm validation of switch statements.
BUG= https://code.google.com/p/v8/issues/detail?id=4203 TEST=test-asm-validator R=aseemgarg@chromium.org,titzer@chromium.org LOG=N Review URL: https://codereview.chromium.org/1564393003 Cr-Commit-Position: refs/heads/master@{#33216}
This commit is contained in:
parent
ab2e908468
commit
6932124c18
@ -388,14 +388,15 @@ void AsmTyper::VisitSwitchStatement(SwitchStatement* stmt) {
|
||||
ZoneList<CaseClause*>* clauses = stmt->cases();
|
||||
for (int i = 0; i < clauses->length(); ++i) {
|
||||
CaseClause* clause = clauses->at(i);
|
||||
if (clause->is_default()) continue;
|
||||
Expression* label = clause->label();
|
||||
RECURSE(VisitWithExpectation(label, cache_.kAsmSigned,
|
||||
"case label non-integer"));
|
||||
if (!label->IsLiteral()) FAIL(label, "non-literal case label");
|
||||
Handle<Object> value = label->AsLiteral()->value();
|
||||
int32_t value32;
|
||||
if (!value->ToInt32(&value32)) FAIL(label, "illegal case label value");
|
||||
if (!clause->is_default()) {
|
||||
Expression* label = clause->label();
|
||||
RECURSE(VisitWithExpectation(label, cache_.kAsmSigned,
|
||||
"case label non-integer"));
|
||||
if (!label->IsLiteral()) FAIL(label, "non-literal case label");
|
||||
Handle<Object> value = label->AsLiteral()->value();
|
||||
int32_t value32;
|
||||
if (!value->ToInt32(&value32)) FAIL(label, "illegal case label value");
|
||||
}
|
||||
// TODO(bradnelson): Detect duplicates.
|
||||
ZoneList<Statement*>* stmts = clause->statements();
|
||||
RECURSE(VisitStatements(stmts));
|
||||
@ -538,7 +539,12 @@ void AsmTyper::VisitVariableProxy(VariableProxy* expr) {
|
||||
Variable* var = expr->var();
|
||||
VariableInfo* info = GetVariableInfo(var, false);
|
||||
if (info == NULL || info->type == NULL) {
|
||||
FAIL(expr, "unbound variable");
|
||||
if (var->mode() == TEMPORARY) {
|
||||
SetType(var, Type::Any(zone()));
|
||||
info = GetVariableInfo(var, false);
|
||||
} else {
|
||||
FAIL(expr, "unbound variable");
|
||||
}
|
||||
}
|
||||
if (property_info_ != NULL) {
|
||||
SetVariableInfo(var, property_info_);
|
||||
|
@ -1978,3 +1978,49 @@ TEST(TypeConsistency) {
|
||||
CHECK(!cache.kAsmDouble->Is(cache.kAsmFixnum));
|
||||
CHECK(!cache.kAsmDouble->Is(cache.kAsmFloat));
|
||||
}
|
||||
|
||||
|
||||
TEST(SwitchTest) {
|
||||
CHECK_FUNC_TYPES_BEGIN(
|
||||
"function switcher(x) {\n"
|
||||
" x = x|0;\n"
|
||||
" switch (x|0) {\n"
|
||||
" case 1: return 23;\n"
|
||||
" case 2: return 43;\n"
|
||||
" default: return 66;\n"
|
||||
" }\n"
|
||||
" return 0;\n"
|
||||
"}\n"
|
||||
"function foo() { switcher(1); }") {
|
||||
CHECK_EXPR(FunctionLiteral, FUNC_I2I_TYPE) {
|
||||
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
||||
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
||||
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
||||
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
||||
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
||||
}
|
||||
}
|
||||
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
||||
CHECK_VAR(.switch_tag, Bounds(cache.kAsmInt));
|
||||
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
||||
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
||||
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
||||
}
|
||||
}
|
||||
CHECK_EXPR(Literal, Bounds(Type::Undefined(zone)));
|
||||
CHECK_VAR(.switch_tag, Bounds(cache.kAsmSigned));
|
||||
// case 1: return 23;
|
||||
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
||||
CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
|
||||
// case 2: return 43;
|
||||
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
||||
CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
|
||||
// default: return 66;
|
||||
CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
|
||||
// return 0;
|
||||
CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
|
||||
}
|
||||
CHECK_SKIP();
|
||||
}
|
||||
CHECK_FUNC_TYPES_END
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user