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