13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch#include "ast.h"
293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include <math.h>  // For isfinite.
313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "builtins.h"
323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "conversions.h"
333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "hashmap.h"
34d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#include "parser.h"
353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "property-details.h"
363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "property.h"
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "scopes.h"
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "string-stream.h"
398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#include "type-info.h"
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// All the Accept member functions for each syntax tree node type.
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#define DECL_ACCEPT(type)                                       \
486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void type::Accept(AstVisitor* v) { v->Visit##type(this); }
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAST_NODE_LIST(DECL_ACCEPT)
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DECL_ACCEPT
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of other node functionality.
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool Expression::IsSmiLiteral() {
583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return AsLiteral() != NULL && AsLiteral()->handle()->IsSmi();
593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool Expression::IsStringLiteral() {
633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return AsLiteral() != NULL && AsLiteral()->handle()->IsString();
646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool Expression::IsNullLiteral() {
683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return AsLiteral() != NULL && AsLiteral()->handle()->IsNull();
696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
723fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochVariableProxy::VariableProxy(Isolate* isolate, Variable* var)
733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    : Expression(isolate),
743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      name_(var->name()),
750d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      var_(NULL),  // Will be set by the call to BindTo.
760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      is_this_(var->is_this()),
778b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      is_trivial_(false),
783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      is_lvalue_(false),
793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      position_(RelocInfo::kNoPosition),
803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      interface_(var->interface()) {
810d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  BindTo(var);
820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
840d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
853fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochVariableProxy::VariableProxy(Isolate* isolate,
863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                             Handle<String> name,
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                             bool is_this,
883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                             int position,
893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                             Interface* interface)
903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    : Expression(isolate),
913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      name_(name),
923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      var_(NULL),
933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      is_this_(is_this),
943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      is_trivial_(false),
953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      is_lvalue_(false),
963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      position_(position),
973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      interface_(interface) {
988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // Names must be canonicalized for fast equality checks.
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(name->IsSymbol());
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid VariableProxy::BindTo(Variable* var) {
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(var_ == NULL);  // must be bound only once
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(var != NULL);  // must bind
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT((is_this() && var->is_this()) || name_.is_identical_to(var->name()));
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Ideally CONST-ness should match. However, this is very hard to achieve
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // because we don't know the exact semantics of conflicting (const and
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // non-const) multiple variable declarations, const vars introduced via
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // eval() etc.  Const-ness and variable declarations are a complete mess
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // in JS. Sigh...
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var_ = var;
1136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  var->set_is_used(true);
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1173fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochAssignment::Assignment(Isolate* isolate,
1183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                       Token::Value op,
119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                       Expression* target,
120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                       Expression* value,
121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                       int pos)
1223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    : Expression(isolate),
1233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      op_(op),
124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      target_(target),
125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      value_(value),
126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      pos_(pos),
127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      binary_operation_(NULL),
128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      compound_load_id_(kNoNumber),
1293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      assignment_id_(GetNextId(isolate)),
130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      block_start_(false),
131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      block_end_(false),
1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      is_monomorphic_(false) { }
133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
134b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockToken::Value Assignment::binary_op() const {
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  switch (op_) {
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_BIT_OR: return Token::BIT_OR;
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR;
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_BIT_AND: return Token::BIT_AND;
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_SHL: return Token::SHL;
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_SAR: return Token::SAR;
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_SHR: return Token::SHR;
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_ADD: return Token::ADD;
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_SUB: return Token::SUB;
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_MUL: return Token::MUL;
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_DIV: return Token::DIV;
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_MOD: return Token::MOD;
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    default: UNREACHABLE();
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Token::ILLEGAL;
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool FunctionLiteral::AllowsLazyCompilation() {
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return scope()->AllowsLazyCompilation();
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint FunctionLiteral::start_position() const {
1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return scope()->start_position();
1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint FunctionLiteral::end_position() const {
1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return scope()->end_position();
1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1693ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochLanguageMode FunctionLiteral::language_mode() const {
1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return scope()->language_mode();
1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochObjectLiteral::Property::Property(Literal* key,
1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  Expression* value,
1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  Isolate* isolate) {
1773e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  emit_store_ = true;
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  key_ = key;
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  value_ = value;
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* k = *key->handle();
1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (k->IsSymbol() &&
1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      isolate->heap()->Proto_symbol()->Equals(String::cast(k))) {
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    kind_ = PROTOTYPE;
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (value_->AsMaterializedLiteral() != NULL) {
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    kind_ = MATERIALIZED_LITERAL;
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (value_->AsLiteral() != NULL) {
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    kind_ = CONSTANT;
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    kind_ = COMPUTED;
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObjectLiteral::Property::Property(bool is_getter, FunctionLiteral* value) {
1953e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  emit_store_ = true;
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  value_ = value;
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  kind_ = is_getter ? GETTER : SETTER;
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
201d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockbool ObjectLiteral::Property::IsCompileTimeValue() {
202d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return kind_ == CONSTANT ||
203d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      (kind_ == MATERIALIZED_LITERAL &&
204d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block       CompileTimeValue::IsCompileTimeValue(value_));
205d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
206d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
207d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
2083e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhuvoid ObjectLiteral::Property::set_emit_store(bool emit_store) {
2093e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  emit_store_ = emit_store;
2103e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu}
2113e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
2123e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
2133e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhubool ObjectLiteral::Property::emit_store() {
2143e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  return emit_store_;
2153e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu}
2163e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
2173e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
2183e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhubool IsEqualString(void* first, void* second) {
219b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  ASSERT((*reinterpret_cast<String**>(first))->IsString());
220b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  ASSERT((*reinterpret_cast<String**>(second))->IsString());
2213e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  Handle<String> h1(reinterpret_cast<String**>(first));
2223e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  Handle<String> h2(reinterpret_cast<String**>(second));
2233e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  return (*h1)->Equals(*h2);
2243e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu}
2253e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
2261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockbool IsEqualNumber(void* first, void* second) {
2281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  ASSERT((*reinterpret_cast<Object**>(first))->IsNumber());
2291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  ASSERT((*reinterpret_cast<Object**>(second))->IsNumber());
2301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  Handle<Object> h1(reinterpret_cast<Object**>(first));
2321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  Handle<Object> h2(reinterpret_cast<Object**>(second));
2331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (h1->IsSmi()) {
2341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return h2->IsSmi() && *h1 == *h2;
2351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
2361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (h2->IsSmi()) return false;
2371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  Handle<HeapNumber> n1 = Handle<HeapNumber>::cast(h1);
2381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  Handle<HeapNumber> n2 = Handle<HeapNumber>::cast(h2);
2391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  ASSERT(isfinite(n1->value()));
2401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  ASSERT(isfinite(n2->value()));
2411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  return n1->value() == n2->value();
2423e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu}
2433e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
2441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2453e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhuvoid ObjectLiteral::CalculateEmitStore() {
2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ZoneHashMap table(Literal::Match);
2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (int i = properties()->length() - 1; i >= 0; i--) {
2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ObjectLiteral::Property* property = properties()->at(i);
2493e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    Literal* literal = property->key();
2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (literal->handle()->IsNull()) continue;
2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    uint32_t hash = literal->Hash();
2523e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    // If the key of a computed property is in the table, do not emit
2533e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    // a store for the property later.
2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (property->kind() == ObjectLiteral::Property::COMPUTED &&
2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        table.Lookup(literal, hash, false) != NULL) {
2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      property->set_emit_store(false);
2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    } else {
2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // Add key to the table.
2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      table.Lookup(literal, hash, true);
2603e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    }
2613e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  }
2623e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu}
2633e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
2643e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
2658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochvoid TargetCollector::AddTarget(Label* target) {
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Add the label to the collector, but discard duplicates.
2673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  int length = targets_.length();
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < length; i++) {
2693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (targets_[i] == target) return;
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  targets_.Add(target);
272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
27580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenbool UnaryOperation::ResultOverwriteAllowed() {
27680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  switch (op_) {
27780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::BIT_NOT:
27880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::SUB:
27980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      return true;
28080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    default:
28180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      return false;
28280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  }
28380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}
28480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
28580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
28680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenbool BinaryOperation::ResultOverwriteAllowed() {
28780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  switch (op_) {
28880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::COMMA:
28980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::OR:
29080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::AND:
29180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      return false;
29280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::BIT_OR:
29380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::BIT_XOR:
29480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::BIT_AND:
29580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::SHL:
29680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::SAR:
29780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::SHR:
29880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::ADD:
29980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::SUB:
30080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::MUL:
30180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::DIV:
30280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    case Token::MOD:
30380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      return true;
30480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    default:
30580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      UNREACHABLE();
30680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  }
30780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  return false;
30880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}
30980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
31080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
3113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic bool IsTypeof(Expression* expr) {
3123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  UnaryOperation* maybe_unary = expr->AsUnaryOperation();
3133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return maybe_unary != NULL && maybe_unary->op() == Token::TYPEOF;
314592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch}
315592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
316592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
3173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Check for the pattern: typeof <expression> equals <string literal>.
3183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic bool MatchLiteralCompareTypeof(Expression* left,
3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Token::Value op,
3203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Expression* right,
3213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Expression** expr,
3223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<String>* check) {
3233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (IsTypeof(left) && right->IsStringLiteral() && Token::IsEqualityOp(op)) {
3243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    *expr = left->AsUnaryOperation()->expression();
3253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    *check = Handle<String>::cast(right->AsLiteral()->handle());
3263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return true;
3273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
328592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch  return false;
329592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch}
330592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
3313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool CompareOperation::IsLiteralCompareTypeof(Expression** expr,
3333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              Handle<String>* check) {
3343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return MatchLiteralCompareTypeof(left_, op_, right_, expr, check) ||
3353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      MatchLiteralCompareTypeof(right_, op_, left_, expr, check);
336592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch}
3373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic bool IsVoidOfLiteral(Expression* expr) {
3403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  UnaryOperation* maybe_unary = expr->AsUnaryOperation();
3413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return maybe_unary != NULL &&
3423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      maybe_unary->op() == Token::VOID &&
3433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      maybe_unary->expression()->AsLiteral() != NULL;
3443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
3453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Check for the pattern: void <literal> equals <expression>
3483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic bool MatchLiteralCompareUndefined(Expression* left,
3493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         Token::Value op,
3503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         Expression* right,
3513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         Expression** expr) {
3523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (IsVoidOfLiteral(left) && Token::IsEqualityOp(op)) {
3533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    *expr = right;
3543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return true;
3553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
35685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  return false;
35785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch}
358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
35985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
3603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool CompareOperation::IsLiteralCompareUndefined(Expression** expr) {
3613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return MatchLiteralCompareUndefined(left_, op_, right_, expr) ||
3623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      MatchLiteralCompareUndefined(right_, op_, left_, expr);
3638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
3648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
36585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
3663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Check for the pattern: null equals <expression>
3673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic bool MatchLiteralCompareNull(Expression* left,
3683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Token::Value op,
3693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Expression* right,
3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Expression** expr) {
3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (left->IsNullLiteral() && Token::IsEqualityOp(op)) {
3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    *expr = right;
3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return true;
3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
37585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  return false;
37685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch}
37785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
37885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool CompareOperation::IsLiteralCompareNull(Expression** expr) {
3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return MatchLiteralCompareNull(left_, op_, right_, expr) ||
3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      MatchLiteralCompareNull(right_, op_, left_, expr);
38285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch}
38385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
38485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
3853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// ----------------------------------------------------------------------------
3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Inlining support
38785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool Declaration::IsInlineable() const {
3893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return proxy()->var()->IsStackAllocated();
3908b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
3918b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool FunctionDeclaration::IsInlineable() const {
39385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  return false;
39485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch}
39585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
39685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// ----------------------------------------------------------------------------
398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Recording of type feedback
399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
400b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Record type feedback from the oracle in the AST.
4023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  is_uninitialized_ = oracle->LoadIsUninitialized(this);
4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (is_uninitialized_) return;
4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  is_monomorphic_ = oracle->LoadIsMonomorphicNormal(this);
40669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  receiver_types_.Clear();
407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (key()->IsPropertyName()) {
40844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (oracle->LoadIsBuiltin(this, Builtins::kLoadIC_ArrayLength)) {
409b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      is_array_length_ = true;
41044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    } else if (oracle->LoadIsBuiltin(this, Builtins::kLoadIC_StringLength)) {
4111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      is_string_length_ = true;
4129fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    } else if (oracle->LoadIsBuiltin(this,
41344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                     Builtins::kLoadIC_FunctionPrototype)) {
4149fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block      is_function_prototype_ = true;
415b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    } else {
416b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      Literal* lit_key = key()->AsLiteral();
417b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      ASSERT(lit_key != NULL && lit_key->handle()->IsString());
418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      Handle<String> name = Handle<String>::cast(lit_key->handle());
41969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      oracle->LoadReceiverTypes(this, name, &receiver_types_);
420b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
42144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else if (oracle->LoadIsBuiltin(this, Builtins::kKeyedLoadIC_String)) {
42244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    is_string_access_ = true;
423b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else if (is_monomorphic_) {
42469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    receiver_types_.Add(oracle->LoadMonomorphicReceiverType(this));
4253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  } else if (oracle->LoadIsMegamorphicWithTypeInfo(this)) {
42669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    receiver_types_.Reserve(kMaxKeyedPolymorphism);
42769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    oracle->CollectKeyedReceiverTypes(this->id(), &receiver_types_);
428b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
429b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
430b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
431b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Assignment::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Property* prop = target()->AsProperty();
434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(prop != NULL);
4353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  is_monomorphic_ = oracle->StoreIsMonomorphicNormal(this);
43669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  receiver_types_.Clear();
437b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (prop->key()->IsPropertyName()) {
438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Literal* lit_key = prop->key()->AsLiteral();
439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ASSERT(lit_key != NULL && lit_key->handle()->IsString());
440b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Handle<String> name = Handle<String>::cast(lit_key->handle());
44169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    oracle->StoreReceiverTypes(this, name, &receiver_types_);
442b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else if (is_monomorphic_) {
4433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // Record receiver type for monomorphic keyed stores.
44469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    receiver_types_.Add(oracle->StoreMonomorphicReceiverType(this));
4453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  } else if (oracle->StoreIsMegamorphicWithTypeInfo(this)) {
44669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    receiver_types_.Reserve(kMaxKeyedPolymorphism);
44769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    oracle->CollectKeyedReceiverTypes(this->id(), &receiver_types_);
4488b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
4498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
4508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
4518b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
4528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochvoid CountOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
4533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  is_monomorphic_ = oracle->StoreIsMonomorphicNormal(this);
45469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  receiver_types_.Clear();
4558b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  if (is_monomorphic_) {
4563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // Record receiver type for monomorphic keyed stores.
45769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    receiver_types_.Add(oracle->StoreMonomorphicReceiverType(this));
4583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  } else if (oracle->StoreIsMegamorphicWithTypeInfo(this)) {
45969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    receiver_types_.Reserve(kMaxKeyedPolymorphism);
46069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    oracle->CollectKeyedReceiverTypes(this->id(), &receiver_types_);
461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
463b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
465b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid CaseClause::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
466b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  TypeInfo info = oracle->SwitchType(this);
467b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (info.IsSmi()) {
468b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    compare_type_ = SMI_ONLY;
4693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else if (info.IsSymbol()) {
4703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    compare_type_ = SYMBOL_ONLY;
4713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else if (info.IsNonSymbol()) {
4723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    compare_type_ = STRING_ONLY;
473b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else if (info.IsNonPrimitive()) {
474b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    compare_type_ = OBJECT_ONLY;
475b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else {
476b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ASSERT(compare_type_ == NONE);
477b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
478b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
479b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
480b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
48185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochbool Call::ComputeTarget(Handle<Map> type, Handle<String> name) {
4823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // If there is an interceptor, we can't compute the target for a direct call.
4833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (type->has_named_interceptor()) return false;
4843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (check_type_ == RECEIVER_MAP_CHECK) {
4863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // For primitive checks the holder is set up to point to the corresponding
4873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // prototype object, i.e. one step of the algorithm below has been already
4883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // performed. For non-primitive checks we clear it to allow computing
4893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // targets for polymorphic calls.
4901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    holder_ = Handle<JSObject>::null();
4911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
4923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LookupResult lookup(type->GetIsolate());
493b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  while (true) {
494b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    type->LookupInDescriptors(NULL, *name, &lookup);
4953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (lookup.IsFound()) {
4963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      switch (lookup.type()) {
4973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        case CONSTANT_FUNCTION:
4983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          // We surely know the target for a constant function.
4993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          target_ =
5003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch              Handle<JSFunction>(lookup.GetConstantFunctionFromMap(*type));
5013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          return true;
5023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        case NORMAL:
5033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        case FIELD:
5043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        case CALLBACKS:
5053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        case HANDLER:
5063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        case INTERCEPTOR:
5073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          // We don't know the target.
5083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          return false;
5093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        case MAP_TRANSITION:
5103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        case ELEMENTS_TRANSITION:
5113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        case CONSTANT_TRANSITION:
5123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        case NULL_DESCRIPTOR:
5133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          // Perhaps something interesting is up in the prototype chain...
5143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          break;
5153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
516b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
5173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // If we reach the end of the prototype chain, we don't know the target.
5183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!type->prototype()->IsJSObject()) return false;
5193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Go up the prototype chain, recording where we are currently.
5203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    holder_ = Handle<JSObject>(JSObject::cast(type->prototype()));
5213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    type = Handle<Map>(holder()->map());
522b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
523b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
525b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochbool Call::ComputeGlobalTarget(Handle<GlobalObject> global,
5278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                               LookupResult* lookup) {
528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  target_ = Handle<JSFunction>::null();
529b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  cell_ = Handle<JSGlobalPropertyCell>::null();
5303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(lookup->IsFound() &&
5318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch         lookup->type() == NORMAL &&
5328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch         lookup->holder() == *global);
5338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  cell_ = Handle<JSGlobalPropertyCell>(global->GetPropertyCell(lookup));
5348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  if (cell_->value()->IsJSFunction()) {
5358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    Handle<JSFunction> candidate(JSFunction::cast(cell_->value()));
5368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    // If the function is in new space we assume it's more likely to
5378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    // change and thus prefer the general IC code.
5383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!HEAP->InNewSpace(*candidate)) {
5398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      target_ = candidate;
5408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      return true;
541b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
542b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
543b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return false;
544b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
545b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
546b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
547257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Call::RecordTypeFeedback(TypeFeedbackOracle* oracle,
548257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                              CallKind call_kind) {
5493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  is_monomorphic_ = oracle->CallIsMonomorphic(this);
550b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Property* property = expression()->AsProperty();
5513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (property == NULL) {
5523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Function call.  Specialize for monomorphic calls.
5533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (is_monomorphic_) target_ = oracle->GetCallTarget(this);
5543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
5553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Method call.  Specialize for the receiver types seen at runtime.
5563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Literal* key = property->key()->AsLiteral();
5573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(key != NULL && key->handle()->IsString());
5583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<String> name = Handle<String>::cast(key->handle());
5593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    receiver_types_.Clear();
5603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    oracle->CallReceiverTypes(this, name, call_kind, &receiver_types_);
561b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG
5623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (FLAG_enable_slow_asserts) {
5633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      int length = receiver_types_.length();
5643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      for (int i = 0; i < length; i++) {
5653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        Handle<Map> map = receiver_types_.at(i);
5663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        ASSERT(!map.is_null() && *map != NULL);
5673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
568b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    }
56985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch#endif
5703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    check_type_ = oracle->GetCallCheckType(this);
5713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (is_monomorphic_) {
5723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Handle<Map> map;
5733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (receiver_types_.length() > 0) {
5743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        ASSERT(check_type_ == RECEIVER_MAP_CHECK);
5753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        map = receiver_types_.at(0);
5763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      } else {
5773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        ASSERT(check_type_ != RECEIVER_MAP_CHECK);
5783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        holder_ = Handle<JSObject>(
5793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            oracle->GetPrototypeForPrimitiveCheck(check_type_));
5803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        map = Handle<Map>(holder_->map());
5813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
5823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      is_monomorphic_ = ComputeTarget(map, name);
58385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    }
5843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
5853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
5863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid CallNew::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
5893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  is_monomorphic_ = oracle->CallNewIsMonomorphic(this);
5903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (is_monomorphic_) {
5913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    target_ = oracle->GetCallNewTarget(this);
5925d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch  }
5935d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch}
5945d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
5955d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
596b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid CompareOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
5971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TypeInfo info = oracle->CompareType(this);
5981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (info.IsSmi()) {
599b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    compare_type_ = SMI_ONLY;
6001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  } else if (info.IsNonPrimitive()) {
601b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    compare_type_ = OBJECT_ONLY;
602b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else {
603b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ASSERT(compare_type_ == NONE);
604b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
605b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
606b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
607b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid ObjectLiteral::Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
6093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  receiver_type_ = oracle->ObjectLiteralStoreIsMonomorphic(this)
6103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ? oracle->GetObjectLiteralStoreMap(this)
6113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      : Handle<Map>::null();
6123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
6133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
615b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// ----------------------------------------------------------------------------
616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of AstVisitor
617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6186ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockbool AstVisitor::CheckStackOverflow() {
6196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (stack_overflow_) return true;
62044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  StackLimitCheck check(isolate_);
6216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (!check.HasOverflowed()) return false;
6226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return (stack_overflow_ = true);
6236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
6246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid AstVisitor::VisitDeclarations(ZoneList<Declaration*>* declarations) {
6273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  for (int i = 0; i < declarations->length(); i++) {
6283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    Visit(declarations->at(i));
6293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
6303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
6313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
6323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstVisitor::VisitStatements(ZoneList<Statement*>* statements) {
634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < statements->length(); i++) {
635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(statements->at(i));
636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstVisitor::VisitExpressions(ZoneList<Expression*>* expressions) {
641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < expressions->length(); i++) {
642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // The variable statement visiting code may pass NULL expressions
643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // to this code. Maybe this should be handled by introducing an
644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // undefined expression or literal?  Revisit this code if this
645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // changes
646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Expression* expression = expressions->at(i);
647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (expression != NULL) Visit(expression);
648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Regular expressions
654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define MAKE_ACCEPT(Name)                                            \
656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void* RegExp##Name::Accept(RegExpVisitor* visitor, void* data) {   \
657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return visitor->Visit##Name(this, data);                         \
658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockFOR_EACH_REG_EXP_TREE_TYPE(MAKE_ACCEPT)
660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef MAKE_ACCEPT
661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define MAKE_TYPE_CASE(Name)                                         \
663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  RegExp##Name* RegExpTree::As##Name() {                             \
664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return NULL;                                                     \
665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }                                                                  \
666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool RegExpTree::Is##Name() { return false; }
667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockFOR_EACH_REG_EXP_TREE_TYPE(MAKE_TYPE_CASE)
668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef MAKE_TYPE_CASE
669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define MAKE_TYPE_CASE(Name)                                        \
671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  RegExp##Name* RegExp##Name::As##Name() {                          \
672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return this;                                                    \
673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }                                                                 \
674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool RegExp##Name::Is##Name() { return true; }
675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockFOR_EACH_REG_EXP_TREE_TYPE(MAKE_TYPE_CASE)
676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef MAKE_TYPE_CASE
677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic Interval ListCaptureRegisters(ZoneList<RegExpTree*>* children) {
680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Interval result = Interval::Empty();
681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < children->length(); i++)
682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = result.Union(children->at(i)->CaptureRegisters());
683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockInterval RegExpAlternative::CaptureRegisters() {
688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return ListCaptureRegisters(nodes());
689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockInterval RegExpDisjunction::CaptureRegisters() {
693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return ListCaptureRegisters(alternatives());
694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockInterval RegExpLookahead::CaptureRegisters() {
698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return body()->CaptureRegisters();
699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockInterval RegExpCapture::CaptureRegisters() {
703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Interval self(StartRegister(index()), EndRegister(index()));
704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return self.Union(body()->CaptureRegisters());
705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockInterval RegExpQuantifier::CaptureRegisters() {
709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return body()->CaptureRegisters();
710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
713f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool RegExpAssertion::IsAnchoredAtStart() {
714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return type() == RegExpAssertion::START_OF_INPUT;
715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
718f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool RegExpAssertion::IsAnchoredAtEnd() {
719f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  return type() == RegExpAssertion::END_OF_INPUT;
720f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch}
721f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
722f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
723f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool RegExpAlternative::IsAnchoredAtStart() {
724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<RegExpTree*>* nodes = this->nodes();
725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < nodes->length(); i++) {
726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    RegExpTree* node = nodes->at(i);
727f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    if (node->IsAnchoredAtStart()) { return true; }
728f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    if (node->max_match() > 0) { return false; }
729f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  }
730f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  return false;
731f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch}
732f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
733f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
734f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool RegExpAlternative::IsAnchoredAtEnd() {
735f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  ZoneList<RegExpTree*>* nodes = this->nodes();
736f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  for (int i = nodes->length() - 1; i >= 0; i--) {
737f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    RegExpTree* node = nodes->at(i);
738f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    if (node->IsAnchoredAtEnd()) { return true; }
739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (node->max_match() > 0) { return false; }
740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return false;
742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
745f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool RegExpDisjunction::IsAnchoredAtStart() {
746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<RegExpTree*>* alternatives = this->alternatives();
747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < alternatives->length(); i++) {
748f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    if (!alternatives->at(i)->IsAnchoredAtStart())
749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return false;
750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return true;
752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
755f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool RegExpDisjunction::IsAnchoredAtEnd() {
756f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  ZoneList<RegExpTree*>* alternatives = this->alternatives();
757f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  for (int i = 0; i < alternatives->length(); i++) {
758f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    if (!alternatives->at(i)->IsAnchoredAtEnd())
759f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch      return false;
760f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  }
761f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  return true;
762f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch}
763f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
764f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
765f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool RegExpLookahead::IsAnchoredAtStart() {
766f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  return is_positive() && body()->IsAnchoredAtStart();
767f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch}
768f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
769f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
770f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool RegExpCapture::IsAnchoredAtStart() {
771f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  return body()->IsAnchoredAtStart();
772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
775f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool RegExpCapture::IsAnchoredAtEnd() {
776f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  return body()->IsAnchoredAtEnd();
777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Convert regular expression trees to a simple sexp representation.
781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This representation should be different from the input grammar
782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// in as many cases as possible, to make it more difficult for incorrect
783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// parses to look as correct ones which is likely if the input and
784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// output formats are alike.
785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass RegExpUnparser: public RegExpVisitor {
786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  RegExpUnparser();
788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void VisitCharacterRange(CharacterRange that);
789589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  SmartArrayPointer<const char> ToString() { return stream_.ToCString(); }
790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define MAKE_CASE(Name) virtual void* Visit##Name(RegExp##Name*, void* data);
791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef MAKE_CASE
793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StringStream* stream() { return &stream_; }
795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HeapStringAllocator alloc_;
796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StringStream stream_;
797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockRegExpUnparser::RegExpUnparser() : stream_(&alloc_) {
801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitDisjunction(RegExpDisjunction* that, void* data) {
805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  stream()->Add("(|");
806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i <  that->alternatives()->length(); i++) {
807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    stream()->Add(" ");
808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    that->alternatives()->at(i)->Accept(this, data);
809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  stream()->Add(")");
811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitAlternative(RegExpAlternative* that, void* data) {
816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  stream()->Add("(:");
817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i <  that->nodes()->length(); i++) {
818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    stream()->Add(" ");
819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    that->nodes()->at(i)->Accept(this, data);
820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  stream()->Add(")");
822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpUnparser::VisitCharacterRange(CharacterRange that) {
827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  stream()->Add("%k", that.from());
828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!that.IsSingleton()) {
829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    stream()->Add("-%k", that.to());
830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitCharacterClass(RegExpCharacterClass* that,
836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                          void* data) {
837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (that->is_negated())
838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    stream()->Add("^");
839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  stream()->Add("[");
840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < that->ranges()->length(); i++) {
841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (i > 0) stream()->Add(" ");
842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    VisitCharacterRange(that->ranges()->at(i));
843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  stream()->Add("]");
845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitAssertion(RegExpAssertion* that, void* data) {
850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  switch (that->type()) {
851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case RegExpAssertion::START_OF_INPUT:
852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      stream()->Add("@^i");
853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case RegExpAssertion::END_OF_INPUT:
855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      stream()->Add("@$i");
856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case RegExpAssertion::START_OF_LINE:
858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      stream()->Add("@^l");
859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case RegExpAssertion::END_OF_LINE:
861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      stream()->Add("@$l");
862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block       break;
863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case RegExpAssertion::BOUNDARY:
864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      stream()->Add("@b");
865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case RegExpAssertion::NON_BOUNDARY:
867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      stream()->Add("@B");
868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitAtom(RegExpAtom* that, void* data) {
875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  stream()->Add("'");
876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Vector<const uc16> chardata = that->data();
877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < chardata.length(); i++) {
878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    stream()->Add("%k", chardata[i]);
879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  stream()->Add("'");
881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitText(RegExpText* that, void* data) {
886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (that->elements()->length() == 1) {
887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    that->elements()->at(0).data.u_atom->Accept(this, data);
888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    stream()->Add("(!");
890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (int i = 0; i < that->elements()->length(); i++) {
891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      stream()->Add(" ");
892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      that->elements()->at(i).data.u_atom->Accept(this, data);
893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    stream()->Add(")");
895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitQuantifier(RegExpQuantifier* that, void* data) {
901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  stream()->Add("(# %i ", that->min());
902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (that->max() == RegExpTree::kInfinity) {
903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    stream()->Add("- ");
904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    stream()->Add("%i ", that->max());
906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
907e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  stream()->Add(that->is_greedy() ? "g " : that->is_possessive() ? "p " : "n ");
908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  that->body()->Accept(this, data);
909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  stream()->Add(")");
910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitCapture(RegExpCapture* that, void* data) {
915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  stream()->Add("(^ ");
916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  that->body()->Accept(this, data);
917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  stream()->Add(")");
918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitLookahead(RegExpLookahead* that, void* data) {
923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  stream()->Add("(-> ");
924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  stream()->Add(that->is_positive() ? "+ " : "- ");
925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  that->body()->Accept(this, data);
926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  stream()->Add(")");
927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitBackReference(RegExpBackReference* that,
932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                         void* data) {
933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  stream()->Add("(<- %i)", that->index());
934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* RegExpUnparser::VisitEmpty(RegExpEmpty* that, void* data) {
939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  stream()->Put('%');
940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
944589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochSmartArrayPointer<const char> RegExpTree::ToString() {
945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  RegExpUnparser unparser;
946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Accept(&unparser, NULL);
947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return unparser.ToString();
948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockRegExpDisjunction::RegExpDisjunction(ZoneList<RegExpTree*>* alternatives)
952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    : alternatives_(alternatives) {
953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(alternatives->length() > 1);
954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  RegExpTree* first_alternative = alternatives->at(0);
955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  min_match_ = first_alternative->min_match();
956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  max_match_ = first_alternative->max_match();
957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 1; i < alternatives->length(); i++) {
958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    RegExpTree* alternative = alternatives->at(i);
959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    min_match_ = Min(min_match_, alternative->min_match());
960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    max_match_ = Max(max_match_, alternative->max_match());
961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockRegExpAlternative::RegExpAlternative(ZoneList<RegExpTree*>* nodes)
966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    : nodes_(nodes) {
967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(nodes->length() > 1);
968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  min_match_ = 0;
969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  max_match_ = 0;
970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < nodes->length(); i++) {
971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    RegExpTree* node = nodes->at(i);
972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    min_match_ += node->min_match();
973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int node_max_match = node->max_match();
974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (kInfinity - max_match_ < node_max_match) {
975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      max_match_ = kInfinity;
976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      max_match_ += node->max_match();
978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9833fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochCaseClause::CaseClause(Isolate* isolate,
9843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                       Expression* label,
985b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                       ZoneList<Statement*>* statements,
986b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                       int pos)
987b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    : label_(label),
988b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      statements_(statements),
989b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      position_(pos),
99044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      compare_type_(NONE),
9913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      compare_id_(AstNode::GetNextId(isolate)),
9923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      entry_id_(AstNode::GetNextId(isolate)) {
99344f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
99425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
9953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define INCREASE_NODE_COUNT(NodeType) \
9973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
9983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    increase_node_count(); \
9993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
10003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10013ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(VariableDeclaration)
10023ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(FunctionDeclaration)
10033ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(ModuleDeclaration)
10043ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(ImportDeclaration)
10053ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(ExportDeclaration)
10063ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(ModuleLiteral)
10073ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(ModuleVariable)
10083ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(ModulePath)
10093ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(ModuleUrl)
10103ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(Block)
10113ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(ExpressionStatement)
10123ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(EmptyStatement)
10133ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(IfStatement)
10143ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(ContinueStatement)
10153ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(BreakStatement)
10163ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(ReturnStatement)
10173ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(Conditional)
10183ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(Literal)
10193ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(ObjectLiteral)
10203ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(Assignment)
10213ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(Throw)
10223ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(Property)
10233ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(UnaryOperation)
10243ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(CountOperation)
10253ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(BinaryOperation)
10263ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(CompareOperation)
10273ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(ThisFunction)
10283ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(Call)
10293ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochINCREASE_NODE_COUNT(CallNew)
10303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#undef INCREASE_NODE_COUNT
10323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstConstructionVisitor::VisitWithStatement(WithStatement* node) {
10353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  increase_node_count();
10363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  add_flag(kDontOptimize);
10373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  add_flag(kDontInline);
10383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
10393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstConstructionVisitor::VisitSwitchStatement(SwitchStatement* node) {
10423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  increase_node_count();
10433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  add_flag(kDontInline);
10443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
10453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstConstructionVisitor::VisitDoWhileStatement(DoWhileStatement* node) {
10483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  increase_node_count();
10493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  add_flag(kDontSelfOptimize);
10503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
10513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstConstructionVisitor::VisitWhileStatement(WhileStatement* node) {
10543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  increase_node_count();
10553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  add_flag(kDontSelfOptimize);
10563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
10573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstConstructionVisitor::VisitForStatement(ForStatement* node) {
10603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  increase_node_count();
10613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  add_flag(kDontSelfOptimize);
10623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
10633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstConstructionVisitor::VisitForInStatement(ForInStatement* node) {
10663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  increase_node_count();
10673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  add_flag(kDontSelfOptimize);
10683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
10693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstConstructionVisitor::VisitTryCatchStatement(TryCatchStatement* node) {
10723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  increase_node_count();
10733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  add_flag(kDontOptimize);
10743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  add_flag(kDontInline);
10753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
10763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstConstructionVisitor::VisitTryFinallyStatement(
10793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    TryFinallyStatement* node) {
10803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  increase_node_count();
10813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  add_flag(kDontOptimize);
10823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  add_flag(kDontInline);
10833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
10843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstConstructionVisitor::VisitDebuggerStatement(DebuggerStatement* node) {
10873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  increase_node_count();
10883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  add_flag(kDontOptimize);
10893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  add_flag(kDontInline);
10903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
10913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstConstructionVisitor::VisitFunctionLiteral(FunctionLiteral* node) {
10943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  increase_node_count();
10953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  add_flag(kDontInline);
10963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
10973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstConstructionVisitor::VisitSharedFunctionInfoLiteral(
11003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    SharedFunctionInfoLiteral* node) {
11013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  increase_node_count();
11023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  add_flag(kDontOptimize);
11033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  add_flag(kDontInline);
11043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
11053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
11063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
11073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstConstructionVisitor::VisitVariableProxy(VariableProxy* node) {
11083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  increase_node_count();
11093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // In theory, we'd have to add:
11103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // if(node->var()->IsLookupSlot()) { add_flag(kDontInline); }
11113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // However, node->var() is usually not bound yet at VariableProxy creation
11123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // time, and LOOKUP variables only result from constructs that cannot
11133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // be inlined anyway.
11143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
11153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
11163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
11173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstConstructionVisitor::VisitRegExpLiteral(RegExpLiteral* node) {
11183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  increase_node_count();
11193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  add_flag(kDontInline);  // TODO(1322): Allow materialized literals.
11203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
11213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
11223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
11233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstConstructionVisitor::VisitArrayLiteral(ArrayLiteral* node) {
11243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  increase_node_count();
11253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  add_flag(kDontInline);  // TODO(1322): Allow materialized literals.
11263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
11273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
11283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
11293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstConstructionVisitor::VisitCallRuntime(CallRuntime* node) {
11303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  increase_node_count();
11313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (node->is_jsruntime()) {
11323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Don't try to inline JS runtime calls because we don't (currently) even
11333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // optimize them.
11343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    add_flag(kDontInline);
11353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else if (node->function()->intrinsic_type == Runtime::INLINE &&
11363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      (node->name()->IsEqualTo(CStrVector("_ArgumentsLength")) ||
11373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch       node->name()->IsEqualTo(CStrVector("_Arguments")))) {
11383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Don't inline the %_ArgumentsLength or %_Arguments because their
11393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // implementation will not work.  There is no stack frame to get them
11403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // from.
11413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    add_flag(kDontInline);
11423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
11433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
11443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
11453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
11463ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<String> Literal::ToString() {
11473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (handle_->IsString()) return Handle<String>::cast(handle_);
11483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(handle_->IsNumber());
11493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  char arr[100];
11503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Vector<char> buffer(arr, ARRAY_SIZE(arr));
11513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const char* str;
11523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (handle_->IsSmi()) {
11533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Optimization only, the heap number case would subsume this.
11543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    OS::SNPrintF(buffer, "%d", Smi::cast(*handle_)->value());
11553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    str = arr;
11563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
11573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    str = DoubleToCString(handle_->Number(), buffer);
11583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
11593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return FACTORY->NewStringFromAscii(CStrVector(str));
11603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
11613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
11623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
1164