13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 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
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ast.h"
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <cmath>  // For isfinite.
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/builtins.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/code-stubs.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/contexts.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/conversions.h"
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hashmap.h"
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/parser.h"
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/property.h"
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/property-details.h"
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/scopes.h"
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/string-stream.h"
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/type-info.h"
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// All the Accept member functions for each syntax tree node type.
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#define DECL_ACCEPT(type)                                       \
276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void type::Accept(AstVisitor* v) { v->Visit##type(this); }
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAST_NODE_LIST(DECL_ACCEPT)
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DECL_ACCEPT
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of other node functionality.
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Expression::IsSmiLiteral() const {
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return IsLiteral() && AsLiteral()->value()->IsSmi();
383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Expression::IsStringLiteral() const {
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return IsLiteral() && AsLiteral()->value()->IsString();
436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Expression::IsNullLiteral() const {
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return IsLiteral() && AsLiteral()->value()->IsNull();
486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Expression::IsUndefinedLiteral(Isolate* isolate) const {
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const VariableProxy* var_proxy = AsVariableProxy();
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (var_proxy == NULL) return false;
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Variable* var = var_proxy->var();
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The global identifier "undefined" is immutable. Everything
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // else could be reassigned.
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return var != NULL && var->location() == Variable::UNALLOCATED &&
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         var_proxy->raw_name()->IsOneByteEqualTo("undefined");
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVariableProxy::VariableProxy(Zone* zone, Variable* var, int position,
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                             IdGen* id_gen)
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : Expression(zone, position, id_gen),
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      name_(var->raw_name()),
660d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      var_(NULL),  // Will be set by the call to BindTo.
670d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      is_this_(var->is_this()),
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      is_assigned_(false),
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      interface_(var->interface()),
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      variable_feedback_slot_(kInvalidFeedbackSlot) {
710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  BindTo(var);
720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
740d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVariableProxy::VariableProxy(Zone* zone, const AstRawString* name, bool is_this,
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                             Interface* interface, int position, IdGen* id_gen)
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : Expression(zone, position, id_gen),
783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      name_(name),
793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      var_(NULL),
803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      is_this_(is_this),
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      is_assigned_(false),
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      interface_(interface),
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      variable_feedback_slot_(kInvalidFeedbackSlot) {}
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid VariableProxy::BindTo(Variable* var) {
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(var_ == NULL);  // must be bound only once
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(var != NULL);  // must bind
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!FLAG_harmony_modules || interface_->IsUnified(var->interface()));
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((is_this() && var->is_this()) || name_ == var->raw_name());
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Ideally CONST-ness should match. However, this is very hard to achieve
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // because we don't know the exact semantics of conflicting (const and
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // non-const) multiple variable declarations, const vars introduced via
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // eval() etc.  Const-ness and variable declarations are a complete mess
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // in JS. Sigh...
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var_ = var;
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var->set_is_used();
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAssignment::Assignment(Zone* zone, Token::Value op, Expression* target,
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       Expression* value, int pos, IdGen* id_gen)
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : Expression(zone, pos, id_gen),
1043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      op_(op),
105b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      target_(target),
106b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      value_(value),
107b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      binary_operation_(NULL),
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assignment_id_(id_gen->GetNextId()),
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      is_uninitialized_(false),
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      store_mode_(STANDARD_STORE) {}
111b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
112b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockToken::Value Assignment::binary_op() const {
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  switch (op_) {
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_BIT_OR: return Token::BIT_OR;
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR;
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_BIT_AND: return Token::BIT_AND;
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_SHL: return Token::SHL;
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_SAR: return Token::SAR;
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_SHR: return Token::SHR;
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_ADD: return Token::ADD;
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_SUB: return Token::SUB;
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_MUL: return Token::MUL;
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_DIV: return Token::DIV;
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_MOD: return Token::MOD;
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    default: UNREACHABLE();
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Token::ILLEGAL;
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool FunctionLiteral::AllowsLazyCompilation() {
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return scope()->AllowsLazyCompilation();
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool FunctionLiteral::AllowsLazyCompilationWithoutContext() {
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return scope()->AllowsLazyCompilationWithoutContext();
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint FunctionLiteral::start_position() const {
1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return scope()->start_position();
1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint FunctionLiteral::end_position() const {
1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return scope()->end_position();
1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochStrictMode FunctionLiteral::strict_mode() const {
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return scope()->strict_mode();
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FunctionLiteral::InitializeSharedInfo(
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<Code> unoptimized_code) {
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (RelocIterator it(*unoptimized_code); !it.done(); it.next()) {
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RelocInfo* rinfo = it.rinfo();
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue;
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object* obj = rinfo->target_object();
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (obj->IsSharedFunctionInfo()) {
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (shared->start_position() == start_position()) {
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        shared_info_ = Handle<SharedFunctionInfo>(shared);
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochObjectLiteralProperty::ObjectLiteralProperty(Zone* zone,
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             AstValueFactory* ast_value_factory,
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             Literal* key, Expression* value,
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             bool is_static) {
1783e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  emit_store_ = true;
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  key_ = key;
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  value_ = value;
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  is_static_ = is_static;
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (key->raw_value()->EqualsString(ast_value_factory->proto_string())) {
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    kind_ = PROTOTYPE;
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (value_->AsMaterializedLiteral() != NULL) {
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    kind_ = MATERIALIZED_LITERAL;
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (value_->IsLiteral()) {
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    kind_ = CONSTANT;
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    kind_ = COMPUTED;
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochObjectLiteralProperty::ObjectLiteralProperty(Zone* zone, bool is_getter,
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             FunctionLiteral* value,
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             bool is_static) {
1973e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  emit_store_ = true;
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  value_ = value;
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  kind_ = is_getter ? GETTER : SETTER;
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  is_static_ = is_static;
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
204d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockbool ObjectLiteral::Property::IsCompileTimeValue() {
205d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return kind_ == CONSTANT ||
206d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      (kind_ == MATERIALIZED_LITERAL &&
207d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block       CompileTimeValue::IsCompileTimeValue(value_));
208d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
209d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
210d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
2113e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhuvoid ObjectLiteral::Property::set_emit_store(bool emit_store) {
2123e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  emit_store_ = emit_store;
2133e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu}
2143e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
2153e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
2163e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhubool ObjectLiteral::Property::emit_store() {
2173e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  return emit_store_;
2183e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu}
2193e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
2203e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ObjectLiteral::CalculateEmitStore(Zone* zone) {
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneAllocationPolicy allocator(zone);
2231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneHashMap table(Literal::Match, ZoneHashMap::kDefaultHashMapCapacity,
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    allocator);
2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (int i = properties()->length() - 1; i >= 0; i--) {
2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ObjectLiteral::Property* property = properties()->at(i);
2283e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    Literal* literal = property->key();
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (literal->value()->IsNull()) continue;
2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    uint32_t hash = literal->Hash();
2313e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    // If the key of a computed property is in the table, do not emit
2323e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    // a store for the property later.
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if ((property->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL ||
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         property->kind() == ObjectLiteral::Property::COMPUTED) &&
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        table.Lookup(literal, hash, false, allocator) != NULL) {
2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      property->set_emit_store(false);
2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    } else {
2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // Add key to the table.
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      table.Lookup(literal, hash, true, allocator);
2403e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    }
2413e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  }
2423e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu}
2433e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
2443e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool ObjectLiteral::IsBoilerplateProperty(ObjectLiteral::Property* property) {
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return property != NULL &&
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         property->kind() != ObjectLiteral::Property::PROTOTYPE;
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ObjectLiteral::BuildConstantProperties(Isolate* isolate) {
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!constant_properties_.is_null()) return;
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate a fixed array to hold all the constant properties.
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<FixedArray> constant_properties = isolate->factory()->NewFixedArray(
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      boilerplate_properties_ * 2, TENURED);
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int position = 0;
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Accumulate the value in local variables and store it at the end.
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_simple = true;
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int depth_acc = 1;
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t max_element_index = 0;
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t elements = 0;
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < properties()->length(); i++) {
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ObjectLiteral::Property* property = properties()->at(i);
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!IsBoilerplateProperty(property)) {
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      is_simple = false;
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      continue;
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral();
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (m_literal != NULL) {
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      m_literal->BuildConstants(isolate);
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (m_literal->depth() >= depth_acc) depth_acc = m_literal->depth() + 1;
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // value for COMPUTED properties, the real value is filled in at
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // runtime. The enumeration order is maintained.
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<Object> key = property->key()->value();
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<Object> value = GetBoilerplateValue(property->value(), isolate);
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Ensure objects that may, at any point in time, contain fields with double
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // representation are always treated as nested objects. This is true for
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // computed fields (value is undefined), and smi and double literals
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // (value->IsNumber()).
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(verwaest): Remove once we can store them inline.
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (FLAG_track_double_fields &&
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (value->IsNumber() || value->IsUninitialized())) {
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      may_store_doubles_ = true;
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    is_simple = is_simple && !value->IsUninitialized();
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Keep track of the number of elements in the object literal and
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // the largest element index.  If the largest element index is
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // much larger than the number of elements, creating an object
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // literal with fast elements will be a waste of space.
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint32_t element_index = 0;
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (key->IsString()
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        && Handle<String>::cast(key)->AsArrayIndex(&element_index)
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        && element_index > max_element_index) {
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      max_element_index = element_index;
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      elements++;
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (key->IsSmi()) {
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int key_value = Smi::cast(*key)->value();
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (key_value > 0
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          && static_cast<uint32_t>(key_value) > max_element_index) {
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        max_element_index = key_value;
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      elements++;
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Add name, value pair to the fixed array.
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    constant_properties->set(position++, *key);
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    constant_properties->set(position++, *value);
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  constant_properties_ = constant_properties;
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  fast_elements_ =
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (max_element_index <= 32) || ((2 * elements) >= max_element_index);
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_is_simple(is_simple);
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_depth(depth_acc);
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ArrayLiteral::BuildConstantElements(Isolate* isolate) {
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!constant_elements_.is_null()) return;
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate a fixed array to hold all the object literals.
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<JSArray> array =
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->NewJSArray(0, FAST_HOLEY_SMI_ELEMENTS);
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JSArray::Expand(array, values()->length());
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Fill in the literals.
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_simple = true;
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int depth_acc = 1;
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_holey = false;
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0, n = values()->length(); i < n; i++) {
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Expression* element = values()->at(i);
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MaterializedLiteral* m_literal = element->AsMaterializedLiteral();
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (m_literal != NULL) {
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      m_literal->BuildConstants(isolate);
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (m_literal->depth() + 1 > depth_acc) {
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        depth_acc = m_literal->depth() + 1;
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<Object> boilerplate_value = GetBoilerplateValue(element, isolate);
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (boilerplate_value->IsTheHole()) {
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      is_holey = true;
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (boilerplate_value->IsUninitialized()) {
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      is_simple = false;
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      JSObject::SetOwnElement(
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          array, i, handle(Smi::FromInt(0), isolate), SLOPPY).Assert();
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      JSObject::SetOwnElement(array, i, boilerplate_value, SLOPPY).Assert();
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<FixedArrayBase> element_values(array->elements());
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Simple and shallow arrays can be lazily copied, we transform the
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // elements array to a copy-on-write array.
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_simple && depth_acc == 1 && values()->length() > 0 &&
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      array->HasFastSmiOrObjectElements()) {
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    element_values->set_map(isolate->heap()->fixed_cow_array_map());
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Remember both the literal's constant values as well as the ElementsKind
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // in a 2-element FixedArray.
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<FixedArray> literals = isolate->factory()->NewFixedArray(2, TENURED);
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ElementsKind kind = array->GetElementsKind();
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  kind = is_holey ? GetHoleyElementsKind(kind) : GetPackedElementsKind(kind);
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  literals->set(0, Smi::FromInt(kind));
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  literals->set(1, *element_values);
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  constant_elements_ = literals;
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_is_simple(is_simple);
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_depth(depth_acc);
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Object> MaterializedLiteral::GetBoilerplateValue(Expression* expression,
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        Isolate* isolate) {
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (expression->IsLiteral()) {
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return expression->AsLiteral()->value();
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (CompileTimeValue::IsCompileTimeValue(expression)) {
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return CompileTimeValue::GetValue(isolate, expression);
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return isolate->factory()->uninitialized_value();
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MaterializedLiteral::BuildConstants(Isolate* isolate) {
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsArrayLiteral()) {
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return AsArrayLiteral()->BuildConstantElements(isolate);
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsObjectLiteral()) {
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return AsObjectLiteral()->BuildConstantProperties(isolate);
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsRegExpLiteral());
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(depth() >= 1);  // Depth should be initialized.
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid TargetCollector::AddTarget(Label* target, Zone* zone) {
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Add the label to the collector, but discard duplicates.
4103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  int length = targets_.length();
411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < length; i++) {
4123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (targets_[i] == target) return;
413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  targets_.Add(target, zone);
415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid UnaryOperation::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) {
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(olivf) If this Operation is used in a test context, then the
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // expression has a ToBoolean stub and we want to collect the type
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // information. However the GraphBuilder expects it to be on the instruction
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // corresponding to the TestContext, therefore we have to store it here and
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // not on the operand.
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_to_boolean_types(oracle->ToBooleanTypes(expression()->test_id()));
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid BinaryOperation::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) {
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(olivf) If this Operation is used in a test context, then the right
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // hand side has a ToBoolean stub and we want to collect the type information.
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // However the GraphBuilder expects it to be on the instruction corresponding
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to the TestContext, therefore we have to store it here and not on the
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // right hand operand.
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_to_boolean_types(oracle->ToBooleanTypes(right()->test_id()));
43580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}
43680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
43780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool BinaryOperation::ResultOverwriteAllowed() const {
43980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  switch (op_) {
44080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::COMMA:
44180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::OR:
44280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::AND:
44380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      return false;
44480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::BIT_OR:
44580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::BIT_XOR:
44680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::BIT_AND:
44780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::SHL:
44880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::SAR:
44980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::SHR:
45080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::ADD:
45180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::SUB:
45280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::MUL:
45380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::DIV:
45480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::MOD:
45580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      return true;
45680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    default:
45780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      UNREACHABLE();
45880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  }
45980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  return false;
46080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}
46180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
46280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
4633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic bool IsTypeof(Expression* expr) {
4643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  UnaryOperation* maybe_unary = expr->AsUnaryOperation();
4653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return maybe_unary != NULL && maybe_unary->op() == Token::TYPEOF;
466592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch}
467592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
468592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
4693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Check for the pattern: typeof <expression> equals <string literal>.
4703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic bool MatchLiteralCompareTypeof(Expression* left,
4713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Token::Value op,
4723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Expression* right,
4733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Expression** expr,
4743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<String>* check) {
4753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (IsTypeof(left) && right->IsStringLiteral() && Token::IsEqualityOp(op)) {
4763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    *expr = left->AsUnaryOperation()->expression();
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *check = Handle<String>::cast(right->AsLiteral()->value());
4783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return true;
4793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
480592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch  return false;
481592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch}
482592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
4833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool CompareOperation::IsLiteralCompareTypeof(Expression** expr,
4853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              Handle<String>* check) {
4863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return MatchLiteralCompareTypeof(left_, op_, right_, expr, check) ||
4873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      MatchLiteralCompareTypeof(right_, op_, left_, expr, check);
488592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch}
4893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic bool IsVoidOfLiteral(Expression* expr) {
4923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  UnaryOperation* maybe_unary = expr->AsUnaryOperation();
4933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return maybe_unary != NULL &&
4943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      maybe_unary->op() == Token::VOID &&
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      maybe_unary->expression()->IsLiteral();
4963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
4973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Check for the pattern: void <literal> equals <expression> or
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// undefined equals <expression>
5013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic bool MatchLiteralCompareUndefined(Expression* left,
5023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         Token::Value op,
5033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         Expression* right,
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         Expression** expr,
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         Isolate* isolate) {
5063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (IsVoidOfLiteral(left) && Token::IsEqualityOp(op)) {
5073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    *expr = right;
5083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return true;
5093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (left->IsUndefinedLiteral(isolate) && Token::IsEqualityOp(op)) {
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *expr = right;
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return true;
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
51485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  return false;
51585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch}
516b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
51785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool CompareOperation::IsLiteralCompareUndefined(
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Expression** expr, Isolate* isolate) {
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return MatchLiteralCompareUndefined(left_, op_, right_, expr, isolate) ||
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MatchLiteralCompareUndefined(right_, op_, left_, expr, isolate);
5228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
5238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
52485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
5253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Check for the pattern: null equals <expression>
5263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic bool MatchLiteralCompareNull(Expression* left,
5273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Token::Value op,
5283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Expression* right,
5293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Expression** expr) {
5303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (left->IsNullLiteral() && Token::IsEqualityOp(op)) {
5313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    *expr = right;
5323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return true;
5333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
53485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  return false;
53585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch}
53685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
53785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
5383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool CompareOperation::IsLiteralCompareNull(Expression** expr) {
5393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return MatchLiteralCompareNull(left_, op_, right_, expr) ||
5403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      MatchLiteralCompareNull(right_, op_, left_, expr);
54185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch}
54285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
54385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
5443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// ----------------------------------------------------------------------------
5453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Inlining support
54685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
5473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool Declaration::IsInlineable() const {
5483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return proxy()->var()->IsStackAllocated();
5498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
5508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
5513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool FunctionDeclaration::IsInlineable() const {
55285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  return false;
55385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch}
55485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
55585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
556b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// ----------------------------------------------------------------------------
557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Recording of type feedback
558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(rossberg): all RecordTypeFeedback functions should disappear
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// once we use the common type field in the AST consistently.
561b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) {
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  to_boolean_types_ = oracle->ToBooleanTypes(test_id());
5648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
5658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
5668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Call::IsUsingCallFeedbackSlot(Isolate* isolate) const {
568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CallType call_type = GetCallType(isolate);
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (call_type != POSSIBLY_EVAL_CALL);
570b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
571b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
572b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCall::CallType Call::GetCallType(Isolate* isolate) const {
574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VariableProxy* proxy = expression()->AsVariableProxy();
575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (proxy != NULL) {
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (proxy->var()->is_possibly_eval(isolate)) {
577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return POSSIBLY_EVAL_CALL;
578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (proxy->var()->IsUnallocated()) {
579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return GLOBAL_CALL;
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (proxy->var()->IsLookupSlot()) {
581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return LOOKUP_SLOT_CALL;
582b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
583b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Property* property = expression()->AsProperty();
586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return property != NULL ? PROPERTY_CALL : OTHER_CALL;
587b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
588b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
589b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
590b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochbool Call::ComputeGlobalTarget(Handle<GlobalObject> global,
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               LookupIterator* it) {
592b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  target_ = Handle<JSFunction>::null();
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cell_ = Handle<Cell>::null();
594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(it->IsFound() && it->GetHolder<JSObject>().is_identical_to(global));
595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cell_ = it->GetPropertyCell();
5968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  if (cell_->value()->IsJSFunction()) {
5978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    Handle<JSFunction> candidate(JSFunction::cast(cell_->value()));
5988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    // If the function is in new space we assume it's more likely to
5998b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    // change and thus prefer the general IC code.
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!it->isolate()->heap()->InNewSpace(*candidate)) {
6018b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      target_ = candidate;
6028b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      return true;
603b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
604b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
605b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return false;
606b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
607b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
608b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid CallNew::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int allocation_site_feedback_slot = FLAG_pretenuring_call_new
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ? AllocationSiteFeedbackSlot()
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : CallNewFeedbackSlot();
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  allocation_site_ =
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      oracle->GetCallNewAllocationSite(allocation_site_feedback_slot);
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  is_monomorphic_ = oracle->CallNewIsMonomorphic(CallNewFeedbackSlot());
6163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (is_monomorphic_) {
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    target_ = oracle->GetCallNewTarget(CallNewFeedbackSlot());
618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation_site_.is_null()) {
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      elements_kind_ = allocation_site_->GetElementsKind();
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
621b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
622b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
623b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
624b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid ObjectLiteral::Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeFeedbackId id = key()->LiteralFeedbackId();
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SmallMapList maps;
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  oracle->CollectReceiverTypes(id, &maps);
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  receiver_type_ = maps.length() == 1 ? maps.at(0)
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      : Handle<Map>::null();
6313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
6323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
634b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// ----------------------------------------------------------------------------
635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of AstVisitor
636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid AstVisitor::VisitDeclarations(ZoneList<Declaration*>* declarations) {
6383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  for (int i = 0; i < declarations->length(); i++) {
6393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    Visit(declarations->at(i));
6403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
6413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
6423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
6433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstVisitor::VisitStatements(ZoneList<Statement*>* statements) {
645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < statements->length(); i++) {
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Statement* stmt = statements->at(i);
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Visit(stmt);
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (stmt->IsJump()) break;
649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstVisitor::VisitExpressions(ZoneList<Expression*>* expressions) {
654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < expressions->length(); i++) {
655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // The variable statement visiting code may pass NULL expressions
656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // to this code. Maybe this should be handled by introducing an
657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // undefined expression or literal?  Revisit this code if this
658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // changes
659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Expression* expression = expressions->at(i);
660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (expression != NULL) Visit(expression);
661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Regular expressions
667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define MAKE_ACCEPT(Name)                                            \
669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void* RegExp##Name::Accept(RegExpVisitor* visitor, void* data) {   \
670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return visitor->Visit##Name(this, data);                         \
671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockFOR_EACH_REG_EXP_TREE_TYPE(MAKE_ACCEPT)
673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef MAKE_ACCEPT
674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define MAKE_TYPE_CASE(Name)                                         \
676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  RegExp##Name* RegExpTree::As##Name() {                             \
677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return NULL;                                                     \
678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }                                                                  \
679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool RegExpTree::Is##Name() { return false; }
680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockFOR_EACH_REG_EXP_TREE_TYPE(MAKE_TYPE_CASE)
681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef MAKE_TYPE_CASE
682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define MAKE_TYPE_CASE(Name)                                        \
684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  RegExp##Name* RegExp##Name::As##Name() {                          \
685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return this;                                                    \
686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }                                                                 \
687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool RegExp##Name::Is##Name() { return true; }
688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockFOR_EACH_REG_EXP_TREE_TYPE(MAKE_TYPE_CASE)
689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef MAKE_TYPE_CASE
690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic Interval ListCaptureRegisters(ZoneList<RegExpTree*>* children) {
693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Interval result = Interval::Empty();
694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < children->length(); i++)
695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = result.Union(children->at(i)->CaptureRegisters());
696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockInterval RegExpAlternative::CaptureRegisters() {
701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return ListCaptureRegisters(nodes());
702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockInterval RegExpDisjunction::CaptureRegisters() {
706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return ListCaptureRegisters(alternatives());
707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockInterval RegExpLookahead::CaptureRegisters() {
711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return body()->CaptureRegisters();
712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockInterval RegExpCapture::CaptureRegisters() {
716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Interval self(StartRegister(index()), EndRegister(index()));
717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return self.Union(body()->CaptureRegisters());
718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockInterval RegExpQuantifier::CaptureRegisters() {
722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return body()->CaptureRegisters();
723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
726f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool RegExpAssertion::IsAnchoredAtStart() {
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return assertion_type() == RegExpAssertion::START_OF_INPUT;
728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
731f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool RegExpAssertion::IsAnchoredAtEnd() {
732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return assertion_type() == RegExpAssertion::END_OF_INPUT;
733f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch}
734f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
735f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
736f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool RegExpAlternative::IsAnchoredAtStart() {
737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<RegExpTree*>* nodes = this->nodes();
738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < nodes->length(); i++) {
739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    RegExpTree* node = nodes->at(i);
740f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    if (node->IsAnchoredAtStart()) { return true; }
741f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    if (node->max_match() > 0) { return false; }
742f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  }
743f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  return false;
744f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch}
745f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
746f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
747f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool RegExpAlternative::IsAnchoredAtEnd() {
748f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  ZoneList<RegExpTree*>* nodes = this->nodes();
749f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  for (int i = nodes->length() - 1; i >= 0; i--) {
750f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    RegExpTree* node = nodes->at(i);
751f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    if (node->IsAnchoredAtEnd()) { return true; }
752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (node->max_match() > 0) { return false; }
753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return false;
755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
758f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool RegExpDisjunction::IsAnchoredAtStart() {
759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<RegExpTree*>* alternatives = this->alternatives();
760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < alternatives->length(); i++) {
761f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    if (!alternatives->at(i)->IsAnchoredAtStart())
762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return false;
763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return true;
765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
768f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool RegExpDisjunction::IsAnchoredAtEnd() {
769f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  ZoneList<RegExpTree*>* alternatives = this->alternatives();
770f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  for (int i = 0; i < alternatives->length(); i++) {
771f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    if (!alternatives->at(i)->IsAnchoredAtEnd())
772f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch      return false;
773f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  }
774f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  return true;
775f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch}
776f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
777f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
778f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool RegExpLookahead::IsAnchoredAtStart() {
779f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  return is_positive() && body()->IsAnchoredAtStart();
780f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch}
781f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
782f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
783f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool RegExpCapture::IsAnchoredAtStart() {
784f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  return body()->IsAnchoredAtStart();
785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
788f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool RegExpCapture::IsAnchoredAtEnd() {
789f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  return body()->IsAnchoredAtEnd();
790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Convert regular expression trees to a simple sexp representation.
794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This representation should be different from the input grammar
795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// in as many cases as possible, to make it more difficult for incorrect
796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// parses to look as correct ones which is likely if the input and
797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// output formats are alike.
798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass RegExpUnparser FINAL : public RegExpVisitor {
799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RegExpUnparser(OStream& os, Zone* zone) : os_(os), zone_(zone) {}
801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void VisitCharacterRange(CharacterRange that);
802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define MAKE_CASE(Name) virtual void* Visit##Name(RegExp##Name*,          \
803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                  void* data) OVERRIDE;
804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef MAKE_CASE
806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  OStream& os_;
808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone_;
809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitDisjunction(RegExpDisjunction* that, void* data) {
813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os_ << "(|";
814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i <  that->alternatives()->length(); i++) {
815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    os_ << " ";
816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    that->alternatives()->at(i)->Accept(this, data);
817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os_ << ")";
819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitAlternative(RegExpAlternative* that, void* data) {
824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os_ << "(:";
825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i <  that->nodes()->length(); i++) {
826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    os_ << " ";
827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    that->nodes()->at(i)->Accept(this, data);
828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os_ << ")";
830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpUnparser::VisitCharacterRange(CharacterRange that) {
835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os_ << AsUC16(that.from());
836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!that.IsSingleton()) {
837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    os_ << "-" << AsUC16(that.to());
838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitCharacterClass(RegExpCharacterClass* that,
844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                          void* data) {
845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (that->is_negated()) os_ << "^";
846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os_ << "[";
847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < that->ranges(zone_)->length(); i++) {
848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (i > 0) os_ << " ";
849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitCharacterRange(that->ranges(zone_)->at(i));
850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os_ << "]";
852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitAssertion(RegExpAssertion* that, void* data) {
857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (that->assertion_type()) {
858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case RegExpAssertion::START_OF_INPUT:
859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os_ << "@^i";
860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case RegExpAssertion::END_OF_INPUT:
862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os_ << "@$i";
863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case RegExpAssertion::START_OF_LINE:
865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os_ << "@^l";
866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case RegExpAssertion::END_OF_LINE:
868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os_ << "@$l";
869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block       break;
870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case RegExpAssertion::BOUNDARY:
871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os_ << "@b";
872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case RegExpAssertion::NON_BOUNDARY:
874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os_ << "@B";
875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitAtom(RegExpAtom* that, void* data) {
882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os_ << "'";
883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Vector<const uc16> chardata = that->data();
884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < chardata.length(); i++) {
885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    os_ << AsUC16(chardata[i]);
886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os_ << "'";
888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitText(RegExpText* that, void* data) {
893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (that->elements()->length() == 1) {
894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    that->elements()->at(0).tree()->Accept(this, data);
895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    os_ << "(!";
897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (int i = 0; i < that->elements()->length(); i++) {
898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os_ << " ";
899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      that->elements()->at(i).tree()->Accept(this, data);
900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    os_ << ")";
902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitQuantifier(RegExpQuantifier* that, void* data) {
908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os_ << "(# " << that->min() << " ";
909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (that->max() == RegExpTree::kInfinity) {
910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    os_ << "- ";
911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    os_ << that->max() << " ";
913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os_ << (that->is_greedy() ? "g " : that->is_possessive() ? "p " : "n ");
915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  that->body()->Accept(this, data);
916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os_ << ")";
917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitCapture(RegExpCapture* that, void* data) {
922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os_ << "(^ ";
923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  that->body()->Accept(this, data);
924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os_ << ")";
925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitLookahead(RegExpLookahead* that, void* data) {
930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os_ << "(-> " << (that->is_positive() ? "+ " : "- ");
931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  that->body()->Accept(this, data);
932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os_ << ")";
933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitBackReference(RegExpBackReference* that,
938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                         void* data) {
939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os_ << "(<- " << that->index() << ")";
940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitEmpty(RegExpEmpty* that, void* data) {
945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os_ << '%';
946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOStream& RegExpTree::Print(OStream& os, Zone* zone) {  // NOLINT
951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RegExpUnparser unparser(os, zone);
952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Accept(&unparser, NULL);
953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return os;
954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockRegExpDisjunction::RegExpDisjunction(ZoneList<RegExpTree*>* alternatives)
958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    : alternatives_(alternatives) {
959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(alternatives->length() > 1);
960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  RegExpTree* first_alternative = alternatives->at(0);
961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  min_match_ = first_alternative->min_match();
962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  max_match_ = first_alternative->max_match();
963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 1; i < alternatives->length(); i++) {
964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    RegExpTree* alternative = alternatives->at(i);
965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    min_match_ = Min(min_match_, alternative->min_match());
966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    max_match_ = Max(max_match_, alternative->max_match());
967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic int IncreaseBy(int previous, int increase) {
972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (RegExpTree::kInfinity - previous < increase) {
973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return RegExpTree::kInfinity;
974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return previous + increase;
976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockRegExpAlternative::RegExpAlternative(ZoneList<RegExpTree*>* nodes)
980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    : nodes_(nodes) {
981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(nodes->length() > 1);
982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  min_match_ = 0;
983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  max_match_ = 0;
984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < nodes->length(); i++) {
985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    RegExpTree* node = nodes->at(i);
986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int node_min_match = node->min_match();
987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    min_match_ = IncreaseBy(min_match_, node_min_match);
988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int node_max_match = node->max_match();
989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    max_match_ = IncreaseBy(max_match_, node_max_match);
990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCaseClause::CaseClause(Zone* zone, Expression* label,
995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       ZoneList<Statement*>* statements, int pos, IdGen* id_gen)
996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : Expression(zone, pos, id_gen),
997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      label_(label),
998b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      statements_(statements),
999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      compare_type_(Type::None(zone)),
1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      compare_id_(id_gen->GetNextId()),
1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      entry_id_(id_gen->GetNextId()) {}
100225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
10033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define REGULAR_NODE(NodeType)                                   \
10053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    increase_node_count();                                       \
1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define REGULAR_NODE_WITH_FEEDBACK_SLOTS(NodeType)               \
1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    increase_node_count();                                       \
1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    add_slot_node(node);                                         \
1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DONT_OPTIMIZE_NODE(NodeType)                             \
1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    increase_node_count();                                       \
1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_dont_crankshaft_reason(k##NodeType);                     \
1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    add_flag(kDontSelfOptimize);                                 \
1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DONT_OPTIMIZE_NODE_WITH_FEEDBACK_SLOTS(NodeType)         \
1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    increase_node_count();                                       \
1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    add_slot_node(node);                                         \
1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_dont_crankshaft_reason(k##NodeType);                     \
1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    add_flag(kDontSelfOptimize);                                 \
1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DONT_TURBOFAN_NODE(NodeType)                             \
1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    increase_node_count();                                       \
1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_dont_crankshaft_reason(k##NodeType);                     \
1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_dont_turbofan_reason(k##NodeType);                       \
1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    add_flag(kDontSelfOptimize);                                 \
1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DONT_SELFOPTIMIZE_NODE(NodeType)                         \
1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    increase_node_count();                                       \
1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    add_flag(kDontSelfOptimize);                                 \
1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DONT_SELFOPTIMIZE_NODE_WITH_FEEDBACK_SLOTS(NodeType)     \
1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    increase_node_count();                                       \
1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    add_slot_node(node);                                         \
1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    add_flag(kDontSelfOptimize);                                 \
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DONT_CACHE_NODE(NodeType)                                \
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    increase_node_count();                                       \
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_dont_crankshaft_reason(k##NodeType);                     \
1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    add_flag(kDontSelfOptimize);                                 \
1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    add_flag(kDontCache);                                        \
10503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
10513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(VariableDeclaration)
1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(FunctionDeclaration)
1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(Block)
1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(ExpressionStatement)
1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(EmptyStatement)
1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(IfStatement)
1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(ContinueStatement)
1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(BreakStatement)
1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(ReturnStatement)
1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(SwitchStatement)
1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(CaseClause)
1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(Conditional)
1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(Literal)
1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(ArrayLiteral)
1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(ObjectLiteral)
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(RegExpLiteral)
1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(FunctionLiteral)
1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(Assignment)
1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(Throw)
1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(UnaryOperation)
1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(CountOperation)
1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(BinaryOperation)
1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(CompareOperation)
1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE(ThisFunction)
1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE_WITH_FEEDBACK_SLOTS(Call)
1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE_WITH_FEEDBACK_SLOTS(CallNew)
1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE_WITH_FEEDBACK_SLOTS(Property)
1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// In theory, for VariableProxy we'd have to add:
1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// if (node->var()->IsLookupSlot())
1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//   set_dont_optimize_reason(kReferenceToAVariableWhichRequiresDynamicLookup);
1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// But node->var() is usually not bound yet at VariableProxy creation time, and
1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// LOOKUP variables only result from constructs that cannot be inlined anyway.
1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGULAR_NODE_WITH_FEEDBACK_SLOTS(VariableProxy)
1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// We currently do not optimize any modules.
1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDONT_OPTIMIZE_NODE(ModuleDeclaration)
1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDONT_OPTIMIZE_NODE(ImportDeclaration)
1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDONT_OPTIMIZE_NODE(ExportDeclaration)
1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDONT_OPTIMIZE_NODE(ModuleVariable)
1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDONT_OPTIMIZE_NODE(ModulePath)
1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDONT_OPTIMIZE_NODE(ModuleUrl)
1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDONT_OPTIMIZE_NODE(ModuleStatement)
1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDONT_OPTIMIZE_NODE(WithStatement)
1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDONT_OPTIMIZE_NODE(DebuggerStatement)
1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDONT_OPTIMIZE_NODE(ClassLiteral)
1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDONT_OPTIMIZE_NODE(NativeFunctionLiteral)
1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDONT_OPTIMIZE_NODE(SuperReference)
1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDONT_OPTIMIZE_NODE_WITH_FEEDBACK_SLOTS(Yield)
1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(turbofan): Remove the dont_turbofan_reason once this list is empty.
1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDONT_TURBOFAN_NODE(ForOfStatement)
1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDONT_TURBOFAN_NODE(TryCatchStatement)
1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDONT_TURBOFAN_NODE(TryFinallyStatement)
1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDONT_SELFOPTIMIZE_NODE(DoWhileStatement)
1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDONT_SELFOPTIMIZE_NODE(WhileStatement)
1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDONT_SELFOPTIMIZE_NODE(ForStatement)
1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDONT_SELFOPTIMIZE_NODE_WITH_FEEDBACK_SLOTS(ForInStatement)
1113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDONT_CACHE_NODE(ModuleLiteral)
11153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
11163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
11173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstConstructionVisitor::VisitCallRuntime(CallRuntime* node) {
11183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  increase_node_count();
1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  add_slot_node(node);
11203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (node->is_jsruntime()) {
1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Don't try to optimize JS runtime calls because we bailout on them.
1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_dont_crankshaft_reason(kCallToAJavaScriptRuntimeFunction);
11233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
11243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
11253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef REGULAR_NODE
1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DONT_OPTIMIZE_NODE
1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DONT_SELFOPTIMIZE_NODE
1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DONT_CACHE_NODE
1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
11313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
11323ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<String> Literal::ToString() {
1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (value_->IsString()) return value_->AsString()->string();
1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(value_->IsNumber());
11353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  char arr[100];
1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Vector<char> buffer(arr, arraysize(arr));
11373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const char* str;
1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (value()->IsSmi()) {
11393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Optimization only, the heap number case would subsume this.
1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SNPrintF(buffer, "%d", Smi::cast(*value())->value());
11413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    str = arr;
11423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
1143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    str = DoubleToCString(value()->Number(), buffer);
11443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return isolate_->factory()->NewStringFromAsciiChecked(str);
11463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
11473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
11483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
1150