1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2013 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/typing.h"
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/ast/compile-time-value.h"
8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/scopes.h"
9f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/ast/variables.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/frames-inl.h"
11f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/frames.h"
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ostreams.h"
13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/splay-tree-inl.h"
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAstTyper::AstTyper(Isolate* isolate, Zone* zone, Handle<JSFunction> closure,
19f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                   DeclarationScope* scope, BailoutId osr_ast_id,
20f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                   FunctionLiteral* root, AstTypeBounds* bounds)
21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : isolate_(isolate),
22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      zone_(zone),
23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      closure_(closure),
24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      scope_(scope),
25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      osr_ast_id_(osr_ast_id),
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      root_(root),
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      oracle_(isolate, zone, handle(closure->shared()->code()),
2813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch              handle(closure->feedback_vector()),
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              handle(closure->context()->native_context())),
30bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      store_(zone),
31bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      bounds_(bounds) {
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InitializeAstVisitor(isolate);
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef OBJECT_PRINT
37f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstatic void PrintObserved(Variable* var, Object* value, AstType* type) {
38f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  OFStream os(stdout);
39f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  os << "  observed " << (var->IsParameter() ? "param" : "local") << "  ";
40f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  var->name()->Print(os);
41f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  os << " : " << Brief(value) << " -> ";
42f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  type->PrintTo(os);
43f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  os << std::endl;
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // OBJECT_PRINT
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochEffect AstTyper::ObservedOnStack(Object* value) {
49f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* lower = AstType::NowOf(value, zone());
50f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return Effect(AstBounds(lower, AstType::Any()));
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::ObserveTypesAtOsrEntry(IterationStatement* stmt) {
55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (stmt->OsrEntryId() != osr_ast_id_) return;
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_gc;
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JavaScriptFrameIterator it(isolate_);
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JavaScriptFrame* frame = it.frame();
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Assert that the frame on the stack belongs to the function we want to OSR.
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(*closure_, frame->function());
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int params = scope_->num_parameters();
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int locals = scope_->StackLocalCount();
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Use sequential composition to achieve desired narrowing.
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The receiver is a parameter with index -1.
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  store_.Seq(parameter_index(-1), ObservedOnStack(frame->receiver()));
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < params; i++) {
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    store_.Seq(parameter_index(i), ObservedOnStack(frame->GetParameter(i)));
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < locals; i++) {
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    store_.Seq(stack_local_index(i), ObservedOnStack(frame->GetExpression(i)));
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef OBJECT_PRINT
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_trace_osr && FLAG_print_scopes) {
80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintObserved(scope_->receiver(), frame->receiver(),
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  store_.LookupBounds(parameter_index(-1)).lower);
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 0; i < params; i++) {
84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintObserved(scope_->parameter(i), frame->GetParameter(i),
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    store_.LookupBounds(parameter_index(i)).lower);
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
88f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    int local_index = 0;
89c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    for (Variable* var : *scope_->locals()) {
90f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (var->IsStackLocal()) {
91f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        PrintObserved(
92f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            var, frame->GetExpression(local_index),
93f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            store_.LookupBounds(stack_local_index(local_index)).lower);
94f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        local_index++;
95f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // OBJECT_PRINT
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define RECURSE(call)                \
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  do {                               \
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!HasStackOverflow());     \
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    call;                            \
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (HasStackOverflow()) return;  \
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } while (false)
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstTyper::Run() {
111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RECURSE(VisitDeclarations(scope_->declarations()));
112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RECURSE(VisitStatements(root_->body()));
113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitStatements(ZoneList<Statement*>* stmts) {
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < stmts->length(); ++i) {
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Statement* stmt = stmts->at(i);
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RECURSE(Visit(stmt));
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (stmt->IsJump()) break;
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitBlock(Block* stmt) {
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(VisitStatements(stmt->statements()));
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (stmt->labels() != NULL) {
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    store_.Forget();  // Control may transfer here via 'break l'.
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitExpressionStatement(ExpressionStatement* stmt) {
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(stmt->expression()));
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitEmptyStatement(EmptyStatement* stmt) {
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstTyper::VisitSloppyBlockFunctionStatement(
143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SloppyBlockFunctionStatement* stmt) {
144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Visit(stmt->statement());
145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitIfStatement(IfStatement* stmt) {
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Collect type feedback.
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!stmt->condition()->ToBooleanIsTrue() &&
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      !stmt->condition()->ToBooleanIsFalse()) {
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    stmt->condition()->RecordToBooleanTypeFeedback(oracle());
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(stmt->condition()));
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Effects then_effects = EnterEffects();
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(stmt->then_statement()));
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExitEffects();
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Effects else_effects = EnterEffects();
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(stmt->else_statement()));
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExitEffects();
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  then_effects.Alt(else_effects);
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  store_.Seq(then_effects);
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitContinueStatement(ContinueStatement* stmt) {
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(rossberg): is it worth having a non-termination effect?
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitBreakStatement(BreakStatement* stmt) {
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(rossberg): is it worth having a non-termination effect?
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitReturnStatement(ReturnStatement* stmt) {
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Collect type feedback.
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(rossberg): we only need this for inlining into test contexts...
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  stmt->expression()->RecordToBooleanTypeFeedback(oracle());
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(stmt->expression()));
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(rossberg): is it worth having a non-termination effect?
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitWithStatement(WithStatement* stmt) {
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(stmt->expression());
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(stmt->statement());
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitSwitchStatement(SwitchStatement* stmt) {
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(stmt->tag()));
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<CaseClause*>* clauses = stmt->cases();
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Effects local_effects(zone());
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool complex_effects = false;  // True for label effects or fall-through.
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < clauses->length(); ++i) {
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CaseClause* clause = clauses->at(i);
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Effects clause_effects = EnterEffects();
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!clause->is_default()) {
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Expression* label = clause->label();
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Collect type feedback.
208f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AstType* tag_type;
209f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AstType* label_type;
210f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AstType* combined_type;
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      oracle()->CompareType(clause->CompareId(),
212f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                            clause->CompareOperationFeedbackSlot(), &tag_type,
213f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                            &label_type, &combined_type);
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      NarrowLowerType(stmt->tag(), tag_type);
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      NarrowLowerType(label, label_type);
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      clause->set_compare_type(combined_type);
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RECURSE(Visit(label));
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!clause_effects.IsEmpty()) complex_effects = true;
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ZoneList<Statement*>* stmts = clause->statements();
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RECURSE(VisitStatements(stmts));
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ExitEffects();
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (stmts->is_empty() || stmts->last()->IsJump()) {
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      local_effects.Alt(clause_effects);
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      complex_effects = true;
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (complex_effects) {
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    store_.Forget();  // Reached this in unknown state.
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    store_.Seq(local_effects);
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitCaseClause(CaseClause* clause) {
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitDoWhileStatement(DoWhileStatement* stmt) {
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Collect type feedback.
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!stmt->cond()->ToBooleanIsTrue()) {
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    stmt->cond()->RecordToBooleanTypeFeedback(oracle());
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(rossberg): refine the unconditional Forget (here and elsewhere) by
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // computing the set of variables assigned in only some of the origins of the
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // control transfer (such as the loop body here).
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  store_.Forget();  // Control may transfer here via looping or 'continue'.
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ObserveTypesAtOsrEntry(stmt);
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(stmt->body()));
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(stmt->cond()));
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  store_.Forget();  // Control may transfer here via 'break'.
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitWhileStatement(WhileStatement* stmt) {
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Collect type feedback.
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!stmt->cond()->ToBooleanIsTrue()) {
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    stmt->cond()->RecordToBooleanTypeFeedback(oracle());
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  store_.Forget();  // Control may transfer here via looping or 'continue'.
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(stmt->cond()));
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ObserveTypesAtOsrEntry(stmt);
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(stmt->body()));
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  store_.Forget();  // Control may transfer here via termination or 'break'.
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitForStatement(ForStatement* stmt) {
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (stmt->init() != NULL) {
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RECURSE(Visit(stmt->init()));
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  store_.Forget();  // Control may transfer here via looping.
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (stmt->cond() != NULL) {
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Collect type feedback.
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    stmt->cond()->RecordToBooleanTypeFeedback(oracle());
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RECURSE(Visit(stmt->cond()));
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ObserveTypesAtOsrEntry(stmt);
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(stmt->body()));
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (stmt->next() != NULL) {
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    store_.Forget();  // Control may transfer here via 'continue'.
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RECURSE(Visit(stmt->next()));
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  store_.Forget();  // Control may transfer here via termination or 'break'.
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitForInStatement(ForInStatement* stmt) {
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Collect type feedback.
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  stmt->set_for_in_type(static_cast<ForInStatement::ForInType>(
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      oracle()->ForInType(stmt->ForInFeedbackSlot())));
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(stmt->enumerable()));
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  store_.Forget();  // Control may transfer here via looping or 'continue'.
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ObserveTypesAtOsrEntry(stmt);
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(stmt->body()));
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  store_.Forget();  // Control may transfer here via 'break'.
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
309bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid AstTyper::VisitForOfStatement(ForOfStatement* stmt) {}
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitTryCatchStatement(TryCatchStatement* stmt) {
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Effects try_effects = EnterEffects();
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(stmt->try_block()));
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExitEffects();
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Effects catch_effects = EnterEffects();
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  store_.Forget();  // Control may transfer here via 'throw'.
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(stmt->catch_block()));
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExitEffects();
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  try_effects.Alt(catch_effects);
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  store_.Seq(try_effects);
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // At this point, only variables that were reassigned in the catch block are
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // still remembered.
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(stmt->try_block()));
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  store_.Forget();  // Control may transfer here via 'throw'.
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(stmt->finally_block()));
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitDebuggerStatement(DebuggerStatement* stmt) {
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  store_.Forget();  // May do whatever.
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstTyper::VisitFunctionLiteral(FunctionLiteral* expr) {}
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitClassLiteral(ClassLiteral* expr) {}
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstTyper::VisitDoExpression(DoExpression* expr) {
349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RECURSE(VisitBlock(expr->block()));
350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RECURSE(VisitVariableProxy(expr->result()));
351bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  NarrowType(expr, bounds_->get(expr->result()));
352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitConditional(Conditional* expr) {
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Collect type feedback.
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  expr->condition()->RecordToBooleanTypeFeedback(oracle());
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(expr->condition()));
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Effects then_effects = EnterEffects();
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(expr->then_expression()));
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExitEffects();
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Effects else_effects = EnterEffects();
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(expr->else_expression()));
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExitEffects();
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  then_effects.Alt(else_effects);
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  store_.Seq(then_effects);
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
369bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  NarrowType(expr,
370f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch             AstBounds::Either(bounds_->get(expr->then_expression()),
371f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                               bounds_->get(expr->else_expression()), zone()));
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitVariableProxy(VariableProxy* expr) {
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Variable* var = expr->var();
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (var->IsStackAllocated()) {
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NarrowType(expr, store_.LookupBounds(variable_index(var)));
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitLiteral(Literal* expr) {
384f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* type = AstType::Constant(expr->value(), zone());
385f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  NarrowType(expr, AstBounds(type));
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) {
390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // TODO(rossberg): Reintroduce RegExp type.
391f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  NarrowType(expr, AstBounds(AstType::Object()));
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitObjectLiteral(ObjectLiteral* expr) {
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<ObjectLiteral::Property*>* properties = expr->properties();
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < properties->length(); ++i) {
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ObjectLiteral::Property* prop = properties->at(i);
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Collect type feedback.
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if ((prop->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL &&
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        !CompileTimeValue::IsCompileTimeValue(prop->value())) ||
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        prop->kind() == ObjectLiteral::Property::COMPUTED) {
404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!prop->is_computed_name() &&
405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          prop->key()->AsLiteral()->value()->IsInternalizedString() &&
406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          prop->emit_store()) {
407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Record type feed back for the property.
40862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        FeedbackSlot slot = prop->GetSlot();
409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        SmallMapList maps;
410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        oracle()->CollectReceiverTypes(slot, &maps);
411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        prop->set_receiver_type(maps.length() == 1 ? maps.at(0)
412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   : Handle<Map>::null());
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RECURSE(Visit(prop->value()));
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
419f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  NarrowType(expr, AstBounds(AstType::Object()));
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitArrayLiteral(ArrayLiteral* expr) {
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<Expression*>* values = expr->values();
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < values->length(); ++i) {
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Expression* value = values->at(i);
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RECURSE(Visit(value));
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
430f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  NarrowType(expr, AstBounds(AstType::Object()));
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitAssignment(Assignment* expr) {
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Collect type feedback.
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Property* prop = expr->target()->AsProperty();
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (prop != NULL) {
43862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    FeedbackSlot slot = expr->AssignmentSlot();
439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    expr->set_is_uninitialized(oracle()->StoreIsUninitialized(slot));
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!expr->IsUninitialized()) {
441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SmallMapList* receiver_types = expr->GetReceiverTypes();
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (prop->key()->IsPropertyName()) {
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Literal* lit_key = prop->key()->AsLiteral();
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK(lit_key != NULL && lit_key->value()->IsString());
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<String> name = Handle<String>::cast(lit_key->value());
446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        oracle()->AssignmentReceiverTypes(slot, name, receiver_types);
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        KeyedAccessStoreMode store_mode;
449958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        IcCheckType key_type;
450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        oracle()->KeyedAssignmentReceiverTypes(slot, receiver_types,
451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                               &store_mode, &key_type);
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        expr->set_store_mode(store_mode);
453958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        expr->set_key_type(key_type);
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Expression* rhs =
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      expr->is_compound() ? expr->binary_operation() : expr->value();
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(expr->target()));
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(rhs));
462bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  NarrowType(expr, bounds_->get(rhs));
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VariableProxy* proxy = expr->target()->AsVariableProxy();
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (proxy != NULL && proxy->var()->IsStackAllocated()) {
466bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    store_.Seq(variable_index(proxy->var()), Effect(bounds_->get(expr)));
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitYield(Yield* expr) {
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(expr->generator_object()));
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(expr->expression()));
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We don't know anything about the result type.
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitThrow(Throw* expr) {
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(expr->exception()));
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(rossberg): is it worth having a non-termination effect?
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
483f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  NarrowType(expr, AstBounds(AstType::None()));
484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitProperty(Property* expr) {
488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Collect type feedback.
48962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  FeedbackSlot slot = expr->PropertyFeedbackSlot();
490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  expr->set_inline_cache_state(oracle()->LoadInlineCacheState(slot));
491958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!expr->IsUninitialized()) {
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (expr->key()->IsPropertyName()) {
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Literal* lit_key = expr->key()->AsLiteral();
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(lit_key != NULL && lit_key->value()->IsString());
496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Handle<String> name = Handle<String>::cast(lit_key->value());
497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      oracle()->PropertyReceiverTypes(slot, name, expr->GetReceiverTypes());
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      bool is_string;
500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      IcCheckType key_type;
501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      oracle()->KeyedPropertyReceiverTypes(slot, expr->GetReceiverTypes(),
502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           &is_string, &key_type);
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      expr->set_is_string_access(is_string);
504958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      expr->set_key_type(key_type);
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(expr->obj()));
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(expr->key()));
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We don't know anything about the result type.
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitCall(Call* expr) {
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Collect type feedback.
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(expr->expression()));
51862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  FeedbackSlot slot = expr->CallFeedbackICSlot();
519c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  bool is_uninitialized = oracle()->CallIsUninitialized(slot);
520c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (!expr->expression()->IsProperty() && oracle()->CallIsMonomorphic(slot)) {
521c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    expr->set_target(oracle()->GetCallTarget(slot));
522c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Handle<AllocationSite> site = oracle()->GetCallAllocationSite(slot);
523c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    expr->set_allocation_site(site);
524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
526958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  expr->set_is_uninitialized(is_uninitialized);
527958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<Expression*>* args = expr->arguments();
529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < args->length(); ++i) {
530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Expression* arg = args->at(i);
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RECURSE(Visit(arg));
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
534f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (expr->is_possibly_eval()) {
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    store_.Forget();  // Eval could do whatever to local variables.
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We don't know anything about the result type.
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitCallNew(CallNew* expr) {
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Collect type feedback.
54462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  FeedbackSlot allocation_site_feedback_slot = expr->CallNewFeedbackSlot();
545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  expr->set_allocation_site(
546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      oracle()->GetCallNewAllocationSite(allocation_site_feedback_slot));
547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool monomorphic =
548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      oracle()->CallNewIsMonomorphic(expr->CallNewFeedbackSlot());
549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  expr->set_is_monomorphic(monomorphic);
550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (monomorphic) {
551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    expr->set_target(oracle()->GetCallNewTarget(expr->CallNewFeedbackSlot()));
552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(expr->expression()));
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<Expression*>* args = expr->arguments();
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < args->length(); ++i) {
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Expression* arg = args->at(i);
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RECURSE(Visit(arg));
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
561f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  NarrowType(expr, AstBounds(AstType::None(), AstType::Receiver()));
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitCallRuntime(CallRuntime* expr) {
566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<Expression*>* args = expr->arguments();
567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < args->length(); ++i) {
568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Expression* arg = args->at(i);
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RECURSE(Visit(arg));
570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We don't know anything about the result type.
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitUnaryOperation(UnaryOperation* expr) {
577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Collect type feedback.
578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (expr->op() == Token::NOT) {
579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(rossberg): only do in test or value context.
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    expr->expression()->RecordToBooleanTypeFeedback(oracle());
581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(expr->expression()));
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (expr->op()) {
586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::NOT:
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::DELETE:
588f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      NarrowType(expr, AstBounds(AstType::Boolean()));
589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::VOID:
591f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      NarrowType(expr, AstBounds(AstType::Undefined()));
592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::TYPEOF:
594f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      NarrowType(expr, AstBounds(AstType::InternalizedString()));
595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitCountOperation(CountOperation* expr) {
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Collect type feedback.
60462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  FeedbackSlot slot = expr->CountSlot();
605958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  KeyedAccessStoreMode store_mode;
606958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  IcCheckType key_type;
607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  oracle()->GetStoreModeAndKeyType(slot, &store_mode, &key_type);
608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  oracle()->CountReceiverTypes(slot, expr->GetReceiverTypes());
609958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  expr->set_store_mode(store_mode);
610958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  expr->set_key_type(key_type);
611f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  expr->set_type(oracle()->CountType(expr->CountBinOpFeedbackId(),
612f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                     expr->CountBinaryOpFeedbackSlot()));
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(rossberg): merge the count type with the generic expression type.
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(expr->expression()));
616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
617f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  NarrowType(expr, AstBounds(AstType::SignedSmall(), AstType::Number()));
618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VariableProxy* proxy = expr->expression()->AsVariableProxy();
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (proxy != NULL && proxy->var()->IsStackAllocated()) {
621bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    store_.Seq(variable_index(proxy->var()), Effect(bounds_->get(expr)));
622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Collect type feedback.
627f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* type;
628f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* left_type;
629f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* right_type;
630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Maybe<int> fixed_right_arg = Nothing<int>();
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<AllocationSite> allocation_site;
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  oracle()->BinaryType(expr->BinaryOperationFeedbackId(),
633f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                       expr->BinaryOperationFeedbackSlot(), &left_type,
634f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                       &right_type, &type, &fixed_right_arg, &allocation_site,
635f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                       expr->op());
636f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NarrowLowerType(expr, type);
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NarrowLowerType(expr->left(), left_type);
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NarrowLowerType(expr->right(), right_type);
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  expr->set_allocation_site(allocation_site);
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  expr->set_fixed_right_arg(fixed_right_arg);
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (expr->op() == Token::OR || expr->op() == Token::AND) {
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    expr->left()->RecordToBooleanTypeFeedback(oracle());
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (expr->op()) {
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::COMMA:
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RECURSE(Visit(expr->left()));
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RECURSE(Visit(expr->right()));
650bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      NarrowType(expr, bounds_->get(expr->right()));
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::OR:
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::AND: {
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Effects left_effects = EnterEffects();
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RECURSE(Visit(expr->left()));
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ExitEffects();
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Effects right_effects = EnterEffects();
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RECURSE(Visit(expr->right()));
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ExitEffects();
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      left_effects.Alt(right_effects);
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      store_.Seq(left_effects);
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
663f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      NarrowType(expr, AstBounds::Either(bounds_->get(expr->left()),
664f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                         bounds_->get(expr->right()), zone()));
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::BIT_OR:
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::BIT_AND: {
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RECURSE(Visit(expr->left()));
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RECURSE(Visit(expr->right()));
671f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AstType* upper =
672f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          AstType::Union(bounds_->get(expr->left()).upper,
673f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                         bounds_->get(expr->right()).upper, zone());
674f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (!upper->Is(AstType::Signed32())) upper = AstType::Signed32();
675f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AstType* lower =
676f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          AstType::Intersect(AstType::SignedSmall(), upper, zone());
677f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      NarrowType(expr, AstBounds(lower, upper));
678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::BIT_XOR:
681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::SHL:
682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::SAR:
683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RECURSE(Visit(expr->left()));
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RECURSE(Visit(expr->right()));
685f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      NarrowType(expr, AstBounds(AstType::SignedSmall(), AstType::Signed32()));
686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::SHR:
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RECURSE(Visit(expr->left()));
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RECURSE(Visit(expr->right()));
690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // TODO(rossberg): The upper bound would be Unsigned32, but since there
691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // is no 'positive Smi' type for the lower bound, we use the smallest
692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // union of Smi and Unsigned32 as upper bound instead.
693f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      NarrowType(expr, AstBounds(AstType::SignedSmall(), AstType::Number()));
694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::ADD: {
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RECURSE(Visit(expr->left()));
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RECURSE(Visit(expr->right()));
698f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AstBounds l = bounds_->get(expr->left());
699f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AstBounds r = bounds_->get(expr->right());
700f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AstType* lower =
701109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          !l.lower->IsInhabited() || !r.lower->IsInhabited()
702f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              ? AstType::None()
703f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              : l.lower->Is(AstType::String()) || r.lower->Is(AstType::String())
704f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                    ? AstType::String()
705f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                    : l.lower->Is(AstType::Number()) &&
706f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              r.lower->Is(AstType::Number())
707f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                          ? AstType::SignedSmall()
708f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                          : AstType::None();
709f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AstType* upper =
710f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          l.upper->Is(AstType::String()) || r.upper->Is(AstType::String())
711f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              ? AstType::String()
712f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              : l.upper->Is(AstType::Number()) && r.upper->Is(AstType::Number())
713f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                    ? AstType::Number()
714f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                    : AstType::NumberOrString();
715f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      NarrowType(expr, AstBounds(lower, upper));
716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::SUB:
719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::MUL:
720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::DIV:
721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::MOD:
722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RECURSE(Visit(expr->left()));
723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RECURSE(Visit(expr->right()));
724f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      NarrowType(expr, AstBounds(AstType::SignedSmall(), AstType::Number()));
725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitCompareOperation(CompareOperation* expr) {
733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Collect type feedback.
734f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* left_type;
735f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* right_type;
736f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* combined_type;
737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  oracle()->CompareType(expr->CompareOperationFeedbackId(),
738f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                        expr->CompareOperationFeedbackSlot(), &left_type,
739f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                        &right_type, &combined_type);
740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NarrowLowerType(expr->left(), left_type);
741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NarrowLowerType(expr->right(), right_type);
742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  expr->set_combined_type(combined_type);
743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(expr->left()));
745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(expr->right()));
746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
747f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  NarrowType(expr, AstBounds(AstType::Boolean()));
748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
751109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid AstTyper::VisitSpread(Spread* expr) { UNREACHABLE(); }
752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstTyper::VisitEmptyParentheses(EmptyParentheses* expr) {
755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
75862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid AstTyper::VisitGetIterator(GetIterator* expr) { UNREACHABLE(); }
759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
760109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid AstTyper::VisitThisFunction(ThisFunction* expr) {}
761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstTyper::VisitSuperPropertyReference(SuperPropertyReference* expr) {}
764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstTyper::VisitSuperCallReference(SuperCallReference* expr) {}
767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
769109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid AstTyper::VisitRewritableExpression(RewritableExpression* expr) {
770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Visit(expr->expression());
771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
773f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochint AstTyper::variable_index(Variable* var) {
774f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Stack locals have the range [0 .. l]
775f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Parameters have the range [-1 .. p]
776f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // We map this to [-p-2 .. -1, 0 .. l]
777f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return var->IsStackLocal()
778f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch             ? stack_local_index(var->index())
779f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch             : var->IsParameter() ? parameter_index(var->index()) : kNoVar;
780f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
782c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid AstTyper::VisitDeclarations(Declaration::List* decls) {
783c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  for (Declaration* decl : *decls) {
784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RECURSE(Visit(decl));
785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitVariableDeclaration(VariableDeclaration* declaration) {
790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstTyper::VisitFunctionDeclaration(FunctionDeclaration* declaration) {
794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RECURSE(Visit(declaration->fun()));
795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
800