Index: src/typing.cc |
diff --git a/src/typing.cc b/src/typing.cc |
index 65a20cf38e89a845543159a7a4984ff471191a7e..747f70fb3b939d2dd9ce0d077d5b30a39ab19169 100644 |
--- a/src/typing.cc |
+++ b/src/typing.cc |
@@ -252,8 +252,8 @@ void AstTyper::VisitForStatement(ForStatement* stmt) { |
RECURSE(Visit(stmt->cond())); |
} |
RECURSE(Visit(stmt->body())); |
- store_.Forget(); // Control may transfer here via 'continue'. |
if (stmt->next() != NULL) { |
+ store_.Forget(); // Control may transfer here via 'continue'. |
RECURSE(Visit(stmt->next())); |
} |
store_.Forget(); // Control may transfer here via termination or 'break'. |
@@ -582,10 +582,15 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { |
case Token::BIT_AND: { |
RECURSE(Visit(expr->left())); |
RECURSE(Visit(expr->right())); |
- Type* upper = Type::Union( |
- expr->left()->bounds().upper, expr->right()->bounds().upper); |
- if (!upper->Is(Type::Signed32())) upper = Type::Signed32(); |
- NarrowType(expr, Bounds(Type::Smi(), upper, isolate_)); |
+ Handle<Type> upper( |
+ Type::Union( |
+ expr->left()->bounds().upper, expr->right()->bounds().upper), |
+ isolate_); |
+ if (!upper->Is(Type::Signed32())) upper = |
+ handle(Type::Signed32(), isolate_); |
+ Handle<Type> lower(Type::Intersect( |
+ handle(Type::Smi(), isolate_), upper), isolate_); |
+ NarrowType(expr, Bounds(lower, upper)); |
break; |
} |
case Token::BIT_XOR: |
@@ -598,7 +603,8 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { |
case Token::SHR: |
RECURSE(Visit(expr->left())); |
RECURSE(Visit(expr->right())); |
- NarrowType(expr, Bounds(Type::Smi(), Type::Unsigned32(), isolate_)); |
+ // TODO(rossberg): we could use an UnsignedSmi as lower bound here... |
+ NarrowType(expr, Bounds(Type::Unsigned32(), isolate_)); |
break; |
case Token::ADD: { |
RECURSE(Visit(expr->left())); |
@@ -606,15 +612,17 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { |
Bounds l = expr->left()->bounds(); |
Bounds r = expr->right()->bounds(); |
Type* lower = |
- l.lower->Is(Type::Number()) && r.lower->Is(Type::Number()) ? |
- Type::Smi() : |
+ l.lower->Is(Type::None()) || r.lower->Is(Type::None()) ? |
+ Type::None() : |
l.lower->Is(Type::String()) || r.lower->Is(Type::String()) ? |
- Type::String() : Type::None(); |
+ Type::String() : |
+ l.lower->Is(Type::Number()) && r.lower->Is(Type::Number()) ? |
+ Type::Smi() : Type::None(); |
Type* upper = |
- l.upper->Is(Type::Number()) && r.upper->Is(Type::Number()) ? |
- Type::Number() : |
l.upper->Is(Type::String()) || r.upper->Is(Type::String()) ? |
- Type::String() : Type::NumberOrString(); |
+ Type::String() : |
+ l.upper->Is(Type::Number()) && r.upper->Is(Type::Number()) ? |
+ Type::Number() : Type::NumberOrString(); |
NarrowType(expr, Bounds(lower, upper, isolate_)); |
break; |
} |