| 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;
|
| }
|
|
|