Index: src/compiler/typer.cc |
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc |
index 1024f0a25dbafb0e7a3a5d5f8a3dfae2cf934a08..0f1183c7b9a8f4282a97b9760df82f6e06cc2631 100644 |
--- a/src/compiler/typer.cc |
+++ b/src/compiler/typer.cc |
@@ -650,12 +650,12 @@ Type* Typer::Visitor::TypeCall(Node* node) { return Type::Any(); } |
Type* Typer::Visitor::TypeProjection(Node* node) { |
- // TODO(bmeurer): Make this beautiful! Use tuple type here. |
- if (node->InputAt(0)->opcode() == IrOpcode::kJSForInPrepare && |
- ProjectionIndexOf(node->op()) == 2) { |
- return typer_->cache_.kSmi; |
+ Type* const type = Operand(node, 0); |
+ if (type->Is(Type::None())) return Type::None(); |
+ int const index = static_cast<int>(ProjectionIndexOf(node->op())); |
+ if (type->IsTuple() && index < type->AsTuple()->Arity()) { |
+ return type->AsTuple()->Element(index); |
} |
- // TODO(titzer): use the output type of the input to determine the bounds. |
return Type::Any(); |
} |
@@ -1618,8 +1618,13 @@ Type* Typer::Visitor::TypeJSForInNext(Node* node) { |
Type* Typer::Visitor::TypeJSForInPrepare(Node* node) { |
- // TODO(bmeurer): Return a tuple type here. |
- return Type::Any(); |
+ STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength); |
+ Factory* const f = isolate()->factory(); |
+ Type* const cache_type = Type::Union( |
+ typer_->cache_.kSmi, Type::Class(f->meta_map(), zone()), zone()); |
+ Type* const cache_array = Type::Class(f->fixed_array_map(), zone()); |
+ Type* const cache_length = typer_->cache_.kFixedArrayLengthType; |
+ return Type::Tuple(cache_type, cache_array, cache_length, zone()); |
} |