1fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without
343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modification, are permitted provided that the following conditions are
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// met:
543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     * Redistributions of source code must retain the above copyright
743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       notice, this list of conditions and the following disclaimer.
843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     * Redistributions in binary form must reproduce the above
943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       copyright notice, this list of conditions and the following
1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       disclaimer in the documentation and/or other materials provided
1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       with the distribution.
1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     * Neither the name of Google Inc. nor the names of its
1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       contributors may be used to endorse or promote products derived
1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       from this software without specific prior written permission.
1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "v8.h"
2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "api.h"
31c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org#include "ast.h"
3243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "bootstrapper.h"
331805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org#include "char-predicates-inl.h"
34f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org#include "codegen.h"
35b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org#include "compiler.h"
3665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include "func-name-inferrer.h"
37ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org#include "messages.h"
38dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org#include "parser.h"
3943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "platform.h"
40fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org#include "preparser.h"
4143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "runtime.h"
4255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org#include "scanner-character-streams.h"
43b5737496145078e47f3d28f19ed8d918e2254738ager@chromium.org#include "scopeinfo.h"
44a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include "string-stream.h"
4543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
4771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
4843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
49b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org// PositionStack is used for on-stack allocation of token positions for
50b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org// new expressions. Please look at ParseNewExpression.
51b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
52b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgclass PositionStack  {
53b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org public:
54b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  explicit PositionStack(bool* ok) : top_(NULL), ok_(ok) {}
55068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  ~PositionStack() {
56068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org    ASSERT(!*ok_ || is_empty());
57068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org    USE(ok_);
58068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  }
59b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
60b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  class Element  {
61b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org   public:
62b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    Element(PositionStack* stack, int value) {
63b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org      previous_ = stack->top();
64b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org      value_ = value;
65b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org      stack->set_top(this);
66b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    }
67b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
68b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org   private:
69b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    Element* previous() { return previous_; }
70b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    int value() { return value_; }
71b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    friend class PositionStack;
72b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    Element* previous_;
73b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    int value_;
74b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  };
75b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
76b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  bool is_empty() { return top_ == NULL; }
77b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  int pop() {
78b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    ASSERT(!is_empty());
79b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    int result = top_->value();
80b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    top_ = top_->previous();
81b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    return result;
82b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  }
83b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
84b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org private:
85b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  Element* top() { return top_; }
86b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  void set_top(Element* value) { top_ = value; }
87b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  Element* top_;
88b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  bool* ok_;
89b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org};
90b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
91b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
92400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.orgRegExpBuilder::RegExpBuilder(Zone* zone)
93400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org    : zone_(zone),
94c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      pending_empty_(false),
95c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      characters_(NULL),
96c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      terms_(),
97c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      alternatives_()
98a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#ifdef DEBUG
99c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    , last_added_(ADD_NONE)
100a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#endif
101a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  {}
102a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
103a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
104a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::FlushCharacters() {
105a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  pending_empty_ = false;
106a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (characters_ != NULL) {
107c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector());
108a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    characters_ = NULL;
1097028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    text_.Add(atom, zone());
110a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    LAST(ADD_ATOM);
111a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
112a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
113a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
114a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
115a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::FlushText() {
116a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  FlushCharacters();
117a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  int num_text = text_.length();
118a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (num_text == 0) {
119a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return;
120a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else if (num_text == 1) {
1217028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    terms_.Add(text_.last(), zone());
122a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else {
1237028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    RegExpText* text = new(zone()) RegExpText(zone());
124a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    for (int i = 0; i < num_text; i++)
1257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      text_.Get(i)->AppendToText(text, zone());
1267028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    terms_.Add(text, zone());
127a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
128a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  text_.Clear();
129a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
130a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
131a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
132a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::AddCharacter(uc16 c) {
133a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  pending_empty_ = false;
134a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (characters_ == NULL) {
1357028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    characters_ = new(zone()) ZoneList<uc16>(4, zone());
136a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
1377028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  characters_->Add(c, zone());
138a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  LAST(ADD_CHAR);
139a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
140a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
141a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
142a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::AddEmpty() {
143a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  pending_empty_ = true;
144a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
145a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
146a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
147a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::AddAtom(RegExpTree* term) {
148a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (term->IsEmpty()) {
149a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    AddEmpty();
150a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return;
151a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
152a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (term->IsTextElement()) {
153a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    FlushCharacters();
1547028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    text_.Add(term, zone());
155a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else {
156a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    FlushText();
1577028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    terms_.Add(term, zone());
158a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
159a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  LAST(ADD_ATOM);
160a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
161a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
162a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
163a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::AddAssertion(RegExpTree* assert) {
164a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  FlushText();
1657028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  terms_.Add(assert, zone());
166a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  LAST(ADD_ASSERT);
167a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
168a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
169a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
170a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::NewAlternative() {
171a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  FlushTerms();
172a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
173a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
174a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
175a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::FlushTerms() {
176a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  FlushText();
177a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  int num_terms = terms_.length();
178a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  RegExpTree* alternative;
179a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (num_terms == 0) {
180a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    alternative = RegExpEmpty::GetInstance();
181a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else if (num_terms == 1) {
182a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    alternative = terms_.last();
183a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else {
1847028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    alternative = new(zone()) RegExpAlternative(terms_.GetList(zone()));
185a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
1867028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  alternatives_.Add(alternative, zone());
187a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  terms_.Clear();
188a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  LAST(ADD_NONE);
189a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
190a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
191a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
192a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpTree* RegExpBuilder::ToRegExp() {
193a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  FlushTerms();
194a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  int num_alternatives = alternatives_.length();
195a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (num_alternatives == 0) {
196a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return RegExpEmpty::GetInstance();
197a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
198a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (num_alternatives == 1) {
199a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return alternatives_.last();
200a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
2017028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  return new(zone()) RegExpDisjunction(alternatives_.GetList(zone()));
202a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
203a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
204a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
205dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgvoid RegExpBuilder::AddQuantifierToAtom(
206dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    int min, int max, RegExpQuantifier::QuantifierType quantifier_type) {
207a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (pending_empty_) {
208a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    pending_empty_ = false;
209a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return;
210a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
211a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  RegExpTree* atom;
212a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (characters_ != NULL) {
213a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    ASSERT(last_added_ == ADD_CHAR);
214a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    // Last atom was character.
215a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    Vector<const uc16> char_vector = characters_->ToConstVector();
216a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    int num_chars = char_vector.length();
217a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if (num_chars > 1) {
218a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1);
2197028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      text_.Add(new(zone()) RegExpAtom(prefix), zone());
220a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      char_vector = char_vector.SubVector(num_chars - 1, num_chars);
221a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
222a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    characters_ = NULL;
223c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    atom = new(zone()) RegExpAtom(char_vector);
224a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    FlushText();
225a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else if (text_.length() > 0) {
226a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    ASSERT(last_added_ == ADD_ATOM);
227a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    atom = text_.RemoveLast();
228a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    FlushText();
229a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else if (terms_.length() > 0) {
230a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    ASSERT(last_added_ == ADD_ATOM);
231a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    atom = terms_.RemoveLast();
23237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    if (atom->max_match() == 0) {
23337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      // Guaranteed to only match an empty string.
234a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      LAST(ADD_TERM);
235a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if (min == 0) {
236a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        return;
237a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
2387028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      terms_.Add(atom, zone());
239a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      return;
240a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
241a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else {
242a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    // Only call immediately after adding an atom or character!
243a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    UNREACHABLE();
244a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return;
245a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
246dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  terms_.Add(
247dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone());
248a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  LAST(ADD_TERM);
249a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
250a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
251a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
2529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgHandle<String> Parser::LookupSymbol(int symbol_id) {
253fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  // Length of symbol cache is the number of identified symbols.
254fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  // If we are larger than that, or negative, it's not a cached symbol.
255fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  // This might also happen if there is no preparser symbol data, even
256fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  // if there is some preparser data.
257fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  if (static_cast<unsigned>(symbol_id)
258fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org      >= static_cast<unsigned>(symbol_cache_.length())) {
2599e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    if (scanner().is_literal_ascii()) {
2604a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      return isolate()->factory()->InternalizeOneByteString(
26159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org          Vector<const uint8_t>::cast(scanner().literal_ascii_string()));
2629e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    } else {
2634a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      return isolate()->factory()->InternalizeTwoByteString(
264154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org          scanner().literal_utf16_string());
2659e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    }
266fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  }
2679e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  return LookupCachedSymbol(symbol_id);
268fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org}
269fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
270fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
2719e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgHandle<String> Parser::LookupCachedSymbol(int symbol_id) {
272fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  // Make sure the cache is large enough to hold the symbol identifier.
273fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  if (symbol_cache_.length() <= symbol_id) {
274fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    // Increase length to index + 1.
275fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    symbol_cache_.AddBlock(Handle<String>::null(),
2767028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                           symbol_id + 1 - symbol_cache_.length(), zone());
277fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  }
278fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Handle<String> result = symbol_cache_.at(symbol_id);
279fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  if (result.is_null()) {
2809e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    if (scanner().is_literal_ascii()) {
2814a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      result = isolate()->factory()->InternalizeOneByteString(
28259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org          Vector<const uint8_t>::cast(scanner().literal_ascii_string()));
2839e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    } else {
2844a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      result = isolate()->factory()->InternalizeTwoByteString(
285154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org          scanner().literal_utf16_string());
2869e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    }
287fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    symbol_cache_.at(symbol_id) = result;
2885b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org    return result;
28943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
2907979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  isolate()->counters()->total_preparse_symbols_skipped()->Increment();
291fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  return result;
292fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org}
29343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
29443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
295d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgFunctionEntry ScriptDataImpl::GetFunctionEntry(int start) {
296d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // The current pre-data entry must be a FunctionEntry with the given
297d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // start position.
2985b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  if ((function_index_ + FunctionEntry::kSize <= store_.length())
2995b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org      && (static_cast<int>(store_[function_index_]) == start)) {
3005b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org    int index = function_index_;
3015b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org    function_index_ += FunctionEntry::kSize;
302d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    return FunctionEntry(store_.SubVector(index,
303d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org                                          index + FunctionEntry::kSize));
30443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
30543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return FunctionEntry();
30643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
30743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
309d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.comint ScriptDataImpl::GetSymbolIdentifier() {
310d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  return ReadNumber(&symbol_data_);
3115b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org}
3125b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org
3135b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org
3145b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.orgbool ScriptDataImpl::SanityCheck() {
3155b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  // Check that the header data is valid and doesn't specify
3165b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  // point to positions outside the store.
317beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  if (store_.length() < PreparseDataConstants::kHeaderSize) return false;
318beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  if (magic() != PreparseDataConstants::kMagicNumber) return false;
319beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  if (version() != PreparseDataConstants::kCurrentVersion) return false;
3205b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  if (has_error()) {
3215b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org    // Extra sane sanity check for error message encoding.
322beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    if (store_.length() <= PreparseDataConstants::kHeaderSize
323beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org                         + PreparseDataConstants::kMessageTextPos) {
324beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org      return false;
325beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    }
326beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    if (Read(PreparseDataConstants::kMessageStartPos) >
327beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org        Read(PreparseDataConstants::kMessageEndPos)) {
328beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org      return false;
329beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    }
330beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    unsigned arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
331beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    int pos = PreparseDataConstants::kMessageTextPos;
3325b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org    for (unsigned int i = 0; i <= arg_count; i++) {
333beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org      if (store_.length() <= PreparseDataConstants::kHeaderSize + pos) {
334beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org        return false;
335beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org      }
3365b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org      int length = static_cast<int>(Read(pos));
3375b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org      if (length < 0) return false;
3385b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org      pos += 1 + length;
3395b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org    }
340beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    if (store_.length() < PreparseDataConstants::kHeaderSize + pos) {
341beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org      return false;
342beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    }
3435b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org    return true;
3445b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  }
3455b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  // Check that the space allocated for function entries is sane.
3465b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  int functions_size =
347beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org      static_cast<int>(store_[PreparseDataConstants::kFunctionsSizeOffset]);
3485b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  if (functions_size < 0) return false;
3495b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  if (functions_size % FunctionEntry::kSize != 0) return false;
3505b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  // Check that the count of symbols is non-negative.
3515b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  int symbol_count =
352beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org      static_cast<int>(store_[PreparseDataConstants::kSymbolCountOffset]);
3535b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  if (symbol_count < 0) return false;
354d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  // Check that the total size has room for header and function entries.
3555b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  int minimum_size =
356beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org      PreparseDataConstants::kHeaderSize + functions_size;
3575b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  if (store_.length() < minimum_size) return false;
35843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return true;
35943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
36043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
36143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3622ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org
36365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgconst char* ScriptDataImpl::ReadString(unsigned* start, int* chars) {
36443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int length = start[0];
36543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  char* result = NewArray<char>(length + 1);
36665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  for (int i = 0; i < length; i++) {
36743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    result[i] = start[i + 1];
36865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  }
36943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  result[length] = '\0';
37043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (chars != NULL) *chars = length;
37143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
37243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
37343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
374e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
37543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenScanner::Location ScriptDataImpl::MessageLocation() {
376beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  int beg_pos = Read(PreparseDataConstants::kMessageStartPos);
377beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  int end_pos = Read(PreparseDataConstants::kMessageEndPos);
37843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return Scanner::Location(beg_pos, end_pos);
37943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
38043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
38143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
38243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenconst char* ScriptDataImpl::BuildMessage() {
383beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos);
38465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  return ReadString(start, NULL);
38543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
38643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
38743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
38843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenVector<const char*> ScriptDataImpl::BuildArgs() {
389beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  int arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
39043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  const char** array = NewArray<const char*>(arg_count);
391d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  // Position after text found by skipping past length field and
392d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  // length field content words.
393beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  int pos = PreparseDataConstants::kMessageTextPos + 1
394beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org      + Read(PreparseDataConstants::kMessageTextPos);
39543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < arg_count; i++) {
39643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int count = 0;
39765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    array[i] = ReadString(ReadAddress(pos), &count);
39843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    pos += count + 1;
39943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
40043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return Vector<const char*>(array, arg_count);
40143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
40243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
40343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
40443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenunsigned ScriptDataImpl::Read(int position) {
405beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  return store_[PreparseDataConstants::kHeaderSize + position];
40643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
40743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
40843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
40943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenunsigned* ScriptDataImpl::ReadAddress(int position) {
410beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  return &store_[PreparseDataConstants::kHeaderSize + position];
41143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
41243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
41343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
414dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgScope* Parser::NewScope(Scope* parent, ScopeType scope_type) {
415dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  Scope* result = new(zone()) Scope(parent, scope_type, zone());
416394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  result->Initialize();
41743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
41843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
41943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4204f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
42143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------
42243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Target is a support class to facilitate manipulation of the
42343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Parser's target_stack_ (the stack of potential 'break' and
42443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 'continue' statement targets). Upon construction, a new target is
42543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// added; it is removed upon destruction.
42643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
42743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass Target BASE_EMBEDDED {
42843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
429e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  Target(Target** variable, AstNode* node)
430e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org      : variable_(variable), node_(node), previous_(*variable) {
431e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    *variable = this;
43243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
43343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
43443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ~Target() {
435e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    *variable_ = previous_;
43643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
43743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
438b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  Target* previous() { return previous_; }
4390b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  AstNode* node() { return node_; }
440b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
44143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
442e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  Target** variable_;
4430b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  AstNode* node_;
444b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  Target* previous_;
44543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
44643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
44743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
44843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass TargetScope BASE_EMBEDDED {
44943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
450e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  explicit TargetScope(Target** variable)
451e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org      : variable_(variable), previous_(*variable) {
452e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    *variable = NULL;
45343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
45443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
45543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ~TargetScope() {
456e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    *variable_ = previous_;
45743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
45843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
45943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
460e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  Target** variable_;
461b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  Target* previous_;
46243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
46343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
46443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
46543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------
466c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org// FunctionState and BlockState together implement the parser's scope stack.
467c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org// The parser's current scope is in top_scope_.  The BlockState and
468c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org// FunctionState constructors push on the scope stack and the destructors
469c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org// pop.  They are also used to hold the parser's per-function and per-block
470c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org// state.
471394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
472c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.orgclass Parser::BlockState BASE_EMBEDDED {
473394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com public:
474c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  BlockState(Parser* parser, Scope* scope)
475394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      : parser_(parser),
476c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org        outer_scope_(parser->top_scope_) {
477394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    parser->top_scope_ = scope;
478394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
479394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
480c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  ~BlockState() { parser_->top_scope_ = outer_scope_; }
481394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
482394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com private:
483394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Parser* parser_;
484c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  Scope* outer_scope_;
485394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com};
486394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
48743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
488c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.orgParser::FunctionState::FunctionState(Parser* parser,
489c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org                                     Scope* scope,
490c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org                                     Isolate* isolate)
491c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
49204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org      next_handler_index_(0),
493c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org      expected_property_count_(0),
494e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      generator_object_variable_(NULL),
495c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org      parser_(parser),
496c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org      outer_function_state_(parser->current_function_state_),
497c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org      outer_scope_(parser->top_scope_),
498b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      saved_ast_node_id_(isolate->ast_node_id()),
4995a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      factory_(isolate, parser->zone()) {
500ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  parser->top_scope_ = scope;
501c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  parser->current_function_state_ = this;
502471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  isolate->set_ast_node_id(BailoutId::FirstUsable().ToInt());
503ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
504ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
505ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
506c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.orgParser::FunctionState::~FunctionState() {
507c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  parser_->top_scope_ = outer_scope_;
508c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  parser_->current_function_state_ = outer_function_state_;
50956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  if (outer_function_state_ != NULL) {
51056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org    parser_->isolate()->set_ast_node_id(saved_ast_node_id_);
51156454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  }
512ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
513ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
514ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
51543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------
51643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The CHECK_OK macro is a convenient macro to enforce error
51743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// handling for functions that may fail (by returning !*ok).
51843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
51943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// CAUTION: This macro appends extra statements after a call,
52043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// thus it must never be used where only a single statement
52143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// is correct (e.g. an if statement branch w/o braces)!
52243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
52343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define CHECK_OK  ok);   \
52443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!*ok) return NULL; \
52543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ((void)0
52643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define DUMMY )  // to make indentation work
52743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef DUMMY
52843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
529a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#define CHECK_FAILED  /**/);   \
530a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (failed_) return NULL; \
531a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  ((void)0
532a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#define DUMMY )  // to make indentation work
533a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#undef DUMMY
53443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
53543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------
53643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Implementation of Parser
53743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
538e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgParser::Parser(CompilationInfo* info)
5395a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    : isolate_(info->isolate()),
540e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      symbol_cache_(0, info->zone()),
5415a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      script_(info->script()),
542a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org      scanner_(isolate_->unicode_cache()),
5431b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      reusable_preparser_(NULL),
54443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      top_scope_(NULL),
545c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org      current_function_state_(NULL),
54643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      target_stack_(NULL),
547e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      extension_(info->extension()),
548e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      pre_parse_data_(NULL),
549a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      fni_(NULL),
550e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      allow_natives_syntax_(false),
551e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      allow_lazy_(false),
552e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      allow_generators_(false),
5531fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      allow_for_of_(false),
554c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      stack_overflow_(false),
555400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org      parenthesized_function_(false),
5565a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      zone_(info->zone()),
5575a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      info_(info) {
5585a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  ASSERT(!script_.is_null());
55956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  isolate_->set_ast_node_id(0);
560e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping);
561e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  set_allow_modules(!info->is_native() && FLAG_harmony_modules);
562e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native());
563e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  set_allow_lazy(false);  // Must be explicitly enabled.
564e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  set_allow_generators(FLAG_harmony_generators);
5651fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  set_allow_for_of(FLAG_harmony_iteration);
566ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
56743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
56843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
56943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5705a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgFunctionLiteral* Parser::ParseProgram() {
5717979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  HistogramTimerScope timer(isolate()->counters()->parse());
57227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  Handle<String> source(String::cast(script_->source()));
5737979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  isolate()->counters()->total_parse_size()->Increment(source->length());
574304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  int64_t start = FLAG_trace_parse ? OS::Ticks() : 0;
5757028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  fni_ = new(zone()) FuncNameInferrer(isolate(), zone());
57643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
57743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Initialize parser state.
578ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  source->TryFlatten();
579304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  FunctionLiteral* result;
5805f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  if (source->IsExternalTwoByteString()) {
5815f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    // Notice that the stream is destroyed at the end of the branch block.
5825f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    // The last line of the blocks can't be moved outside, even though they're
5835f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    // identical calls.
584154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    ExternalTwoByteStringUtf16CharacterStream stream(
5855f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        Handle<ExternalTwoByteString>::cast(source), 0, source->length());
5869e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    scanner_.Initialize(&stream);
5871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    result = DoParseProgram(info(), source);
5885f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  } else {
589154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    GenericStringUtf16CharacterStream stream(source, 0, source->length());
5909e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    scanner_.Initialize(&stream);
5911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    result = DoParseProgram(info(), source);
5925f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  }
593304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
594304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  if (FLAG_trace_parse && result != NULL) {
595304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    double ms = static_cast<double>(OS::Ticks() - start) / 1000;
596304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    if (info()->is_eval()) {
597304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      PrintF("[parsing eval");
598304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    } else if (info()->script()->name()->IsString()) {
599304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      String* name = String::cast(info()->script()->name());
600304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      SmartArrayPointer<char> name_chars = name->ToCString();
601304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      PrintF("[parsing script: %s", *name_chars);
602304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    } else {
603304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      PrintF("[parsing script");
604304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    }
605304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    PrintF(" - took %0.3f ms]\n", ms);
606304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  }
607304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  return result;
6085f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
6095f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
6105f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
61127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgFunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
6121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                        Handle<String> source) {
613394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(top_scope_ == NULL);
61443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(target_stack_ == NULL);
615e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (pre_parse_data_ != NULL) pre_parse_data_->Initialize();
61643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Handle<String> no_name = isolate()->factory()->empty_string();
61843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
61943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  FunctionLiteral* result = NULL;
62027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE);
62127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    info->SetGlobalScope(scope);
622355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    if (!info->context().is_null()) {
623355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      scope = Scope::DeserializeScopeChain(*info->context(), scope, zone());
624355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    }
6252c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org    if (info->is_eval()) {
6262c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org      if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) {
6272c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org        scope = NewScope(scope, EVAL_SCOPE);
6282c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org      }
629355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    } else if (info->is_global()) {
630355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      scope = NewScope(scope, GLOBAL_SCOPE);
63127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    }
632394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    scope->set_start_position(0);
633394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    scope->set_end_position(source->length());
634355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
635cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org    // Compute the parsing mode.
636e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY;
637e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (allow_natives_syntax() ||
638e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        extension_ != NULL ||
639e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        scope->is_eval_scope()) {
640cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org      mode = PARSE_EAGERLY;
641cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org    }
642cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org    ParsingModeScope parsing_mode(this, mode);
643cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org
644f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    // Enters 'scope'.
645e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    FunctionState function_state(this, scope, isolate());
646f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
6471b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    top_scope_->SetLanguageMode(info->language_mode());
6487028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
64943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    bool ok = true;
6500ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    int beg_loc = scanner().location().beg_pos;
65133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok);
6521b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (ok && !top_scope_->is_classic_mode()) {
6530ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org      CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
6540ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    }
6551805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
6561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (ok && is_extended_mode()) {
6572c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org      CheckConflictingVarDeclarations(top_scope_, &ok);
6581805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    }
6591805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
6609faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org    if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
6619faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org      if (body->length() != 1 ||
6629faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org          !body->at(0)->IsExpressionStatement() ||
6639faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org          !body->at(0)->AsExpressionStatement()->
6649faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org              expression()->IsFunctionLiteral()) {
665f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org        ReportMessage("single_function_literal", Vector<const char*>::empty());
6669faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org        ok = false;
6679faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org      }
6689faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org    }
6699faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org
67043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (ok) {
671b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      result = factory()->NewFunctionLiteral(
672911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org          no_name,
673911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org          top_scope_,
674fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org          body,
675c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org          function_state.materialized_literal_count(),
676c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org          function_state.expected_property_count(),
67704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org          function_state.handler_count(),
678911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org          0,
67956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org          FunctionLiteral::kNoDuplicateParameters,
6807c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          FunctionLiteral::ANONYMOUS_EXPRESSION,
681471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org          FunctionLiteral::kGlobalOrEval,
682f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org          FunctionLiteral::kNotParenthesized,
683f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org          FunctionLiteral::kNotGenerator);
684b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      result->set_ast_properties(factory()->visitor()->ast_properties());
685a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else if (stack_overflow_) {
686ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate()->StackOverflow();
68743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
68843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
68943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
69043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Make sure the target stack is empty.
69143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(target_stack_ == NULL);
69243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
69343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
69443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
69543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
696f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
6975a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgFunctionLiteral* Parser::ParseLazy() {
6987979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  HistogramTimerScope timer(isolate()->counters()->parse_lazy());
699f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org  Handle<String> source(String::cast(script_->source()));
7007979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  isolate()->counters()->total_parse_size()->Increment(source->length());
701304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  int64_t start = FLAG_trace_parse ? OS::Ticks() : 0;
7025a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Handle<SharedFunctionInfo> shared_info = info()->shared_info();
703304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
7045f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Initialize parser state.
7055f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  source->TryFlatten();
706304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  FunctionLiteral* result;
7075f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  if (source->IsExternalTwoByteString()) {
708154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    ExternalTwoByteStringUtf16CharacterStream stream(
7095f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        Handle<ExternalTwoByteString>::cast(source),
7104d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org        shared_info->start_position(),
7114d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org        shared_info->end_position());
7121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    result = ParseLazy(&stream);
7135f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  } else {
714154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    GenericStringUtf16CharacterStream stream(source,
715154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org                                             shared_info->start_position(),
716154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org                                             shared_info->end_position());
7171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    result = ParseLazy(&stream);
7185f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  }
719304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
720304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  if (FLAG_trace_parse && result != NULL) {
721304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    double ms = static_cast<double>(OS::Ticks() - start) / 1000;
722de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org    SmartArrayPointer<char> name_chars = result->debug_name()->ToCString();
723304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    PrintF("[parsing function: %s - took %0.3f ms]\n", *name_chars, ms);
724304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  }
725304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  return result;
7265f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
7275f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
7285f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
7291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgFunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) {
7305a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Handle<SharedFunctionInfo> shared_info = info()->shared_info();
7319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  scanner_.Initialize(source);
732394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(top_scope_ == NULL);
7335f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  ASSERT(target_stack_ == NULL);
7345f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
7354d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  Handle<String> name(String::cast(shared_info->name()));
7367028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  fni_ = new(zone()) FuncNameInferrer(isolate(), zone());
73765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  fni_->PushEnclosingName(name);
73865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
739471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
74043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
74143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Place holder for the result.
74243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  FunctionLiteral* result = NULL;
74343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
74443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  {
74543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Parse the function literal.
746394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE);
7475a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    info()->SetGlobalScope(scope);
7485a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    if (!info()->closure().is_null()) {
7495a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope,
7507028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                           zone());
7514d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    }
752e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    FunctionState function_state(this, scope, isolate());
7535a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode());
7541b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    ASSERT(scope->language_mode() != EXTENDED_MODE ||
7555a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org           info()->is_extended_mode());
7565a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    ASSERT(info()->language_mode() == shared_info->language_mode());
7571b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    scope->SetLanguageMode(shared_info->language_mode());
758dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    FunctionLiteral::FunctionType function_type = shared_info->is_expression()
7597c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        ? (shared_info->is_anonymous()
7607c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org              ? FunctionLiteral::ANONYMOUS_EXPRESSION
7617c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org              : FunctionLiteral::NAMED_EXPRESSION)
7627c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        : FunctionLiteral::DECLARATION;
76343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    bool ok = true;
76483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    result = ParseFunctionLiteral(name,
7657c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org                                  false,  // Strict mode name already checked.
766f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                                  shared_info->is_generator(),
7677c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org                                  RelocInfo::kNoPosition,
768dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                                  function_type,
7697c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org                                  &ok);
77043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Make sure the results agree.
77143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(ok == (result != NULL));
77243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
77343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
77443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Make sure the target stack is empty.
77543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(target_stack_ == NULL);
77643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
77743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (result == NULL) {
778ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (stack_overflow_) isolate()->StackOverflow();
779a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
7804d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    Handle<String> inferred_name(shared_info->inferred_name());
781a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    result->set_inferred_name(inferred_name);
78243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
78343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
78443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
78543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
786f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org
787bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.orgHandle<String> Parser::GetSymbol() {
788d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  int symbol_id = -1;
789e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (pre_parse_data() != NULL) {
790e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    symbol_id = pre_parse_data()->GetSymbolIdentifier();
7915b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  }
7929e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  return LookupSymbol(symbol_id);
7935b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org}
7945b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org
7955b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org
796dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgvoid Parser::ReportMessage(const char* message, Vector<const char*> args) {
7975f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  Scanner::Location source_location = scanner().location();
798dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  ReportMessageAt(source_location, message, args);
799fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org}
800fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
801fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
802dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgvoid Parser::ReportMessage(const char* message, Vector<Handle<String> > args) {
803bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  Scanner::Location source_location = scanner().location();
804dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  ReportMessageAt(source_location, message, args);
805bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com}
806bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
807bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
808fa943b736b1d996084393011529d568165bb5d83lrn@chromium.orgvoid Parser::ReportMessageAt(Scanner::Location source_location,
809dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                             const char* message,
810fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org                             Vector<const char*> args) {
81143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  MessageLocation location(script_,
812c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                           source_location.beg_pos,
813c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                           source_location.end_pos);
814ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Factory* factory = isolate()->factory();
815ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> elements = factory->NewFixedArray(args.length());
81643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < args.length(); i++) {
817ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i]));
8188f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    elements->set(i, *arg_string);
81943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
820ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
821dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  Handle<Object> result = factory->NewSyntaxError(message, array);
822ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate()->Throw(*result, &location);
82343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
82443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
82543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
826c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid Parser::ReportMessageAt(Scanner::Location source_location,
827dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                             const char* message,
828c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                             Vector<Handle<String> > args) {
829c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  MessageLocation location(script_,
830c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                           source_location.beg_pos,
831c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                           source_location.end_pos);
832ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Factory* factory = isolate()->factory();
833ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> elements = factory->NewFixedArray(args.length());
834c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  for (int i = 0; i < args.length(); i++) {
8358f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    elements->set(i, *args[i]);
836c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  }
837ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
838dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  Handle<Object> result = factory->NewSyntaxError(message, array);
839ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate()->Throw(*result, &location);
840c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org}
841c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
842c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
843fa943b736b1d996084393011529d568165bb5d83lrn@chromium.orgvoid* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
84443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                  int end_token,
8452c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org                                  bool is_eval,
84633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org                                  bool is_global,
84743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                  bool* ok) {
84843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // SourceElements ::
849f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //   (ModuleElement)* <end_token>
85043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
85143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate a target stack to use for this set of source
85243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // elements. This way, all scripts and functions get their own
85343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // target stack thus avoiding illegal breaks and continues across
85443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // functions.
855e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  TargetScope scope(&this->target_stack_);
85643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
85743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(processor != NULL);
8580a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  bool directive_prologue = true;     // Parsing directive prologue.
8590a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
86043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (peek() != end_token) {
8610a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    if (directive_prologue && peek() != Token::STRING) {
8620a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      directive_prologue = false;
8630a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    }
8640a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
8650a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    Scanner::Location token_loc = scanner().peek_location();
86633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    Statement* stat;
86733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    if (is_global && !is_eval) {
86833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org      stat = ParseModuleElement(NULL, CHECK_OK);
86933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    } else {
87033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org      stat = ParseBlockElement(NULL, CHECK_OK);
87133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    }
8720a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    if (stat == NULL || stat->IsEmpty()) {
8730a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      directive_prologue = false;   // End of directive prologue.
8740a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      continue;
8750a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    }
8760a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
8770a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    if (directive_prologue) {
8780a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      // A shot at a directive.
879f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      ExpressionStatement* e_stat;
880f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      Literal* literal;
8810a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      // Still processing directive prologue?
8820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      if ((e_stat = stat->AsExpressionStatement()) != NULL &&
8830a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org          (literal = e_stat->expression()->AsLiteral()) != NULL &&
8841510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          literal->value()->IsString()) {
8851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        Handle<String> directive = Handle<String>::cast(literal->value());
8860a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
8870a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        // Check "use strict" directive (ES5 14.1).
8881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        if (top_scope_->is_classic_mode() &&
8894a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org            directive->Equals(isolate()->heap()->use_strict_string()) &&
8900a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org            token_loc.end_pos - token_loc.beg_pos ==
8914a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org              isolate()->heap()->use_strict_string()->length() + 2) {
8922c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org          // TODO(mstarzinger): Global strict eval calls, need their own scope
8932c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org          // as specified in ES5 10.4.2(3). The correct fix would be to always
8942c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org          // add this scope in DoParseProgram(), but that requires adaptations
8952c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org          // all over the code base, so we go with a quick-fix for now.
896cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org          // In the same manner, we have to patch the parsing mode.
8972c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org          if (is_eval && !top_scope_->is_eval_scope()) {
8982c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org            ASSERT(top_scope_->is_global_scope());
8992c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org            Scope* scope = NewScope(top_scope_, EVAL_SCOPE);
9002c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org            scope->set_start_position(top_scope_->start_position());
9012c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org            scope->set_end_position(top_scope_->end_position());
9022c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org            top_scope_ = scope;
903cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org            mode_ = PARSE_EAGERLY;
9042c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org          }
9051b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          // TODO(ES6): Fix entering extended mode, once it is specified.
906e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org          top_scope_->SetLanguageMode(allow_harmony_scoping()
9071b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                                      ? EXTENDED_MODE : STRICT_MODE);
9080a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org          // "use strict" is the only directive for now.
9090a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org          directive_prologue = false;
9100a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        }
9110a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      } else {
9120a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        // End of the directive prologue.
9130a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        directive_prologue = false;
9140a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      }
9150a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    }
9160a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
9177028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    processor->Add(stat, zone());
91843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
919911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org
92043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return 0;
92143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
92243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
92343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
924f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgStatement* Parser::ParseModuleElement(ZoneStringList* labels,
925f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org                                      bool* ok) {
926f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // (Ecma 262 5th Edition, clause 14):
927f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // SourceElement:
928f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    Statement
929f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    FunctionDeclaration
930f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //
931f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // In harmony mode we allow additionally the following productions
932f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // ModuleElement:
933f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    LetDeclaration
934f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    ConstDeclaration
935f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    ModuleDeclaration
936f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    ImportDeclaration
937f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    ExportDeclaration
938f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  //    GeneratorDeclaration
939f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
940f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  switch (peek()) {
941f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    case Token::FUNCTION:
942812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      return ParseFunctionDeclaration(NULL, ok);
943f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    case Token::LET:
944f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    case Token::CONST:
945812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      return ParseVariableStatement(kModuleElement, NULL, ok);
946f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    case Token::IMPORT:
947f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      return ParseImportDeclaration(ok);
948f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    case Token::EXPORT:
949f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      return ParseExportDeclaration(ok);
950a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org    default: {
951a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org      Statement* stmt = ParseStatement(labels, CHECK_OK);
952a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org      // Handle 'module' as a context-sensitive keyword.
953a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org      if (FLAG_harmony_modules &&
954a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org          peek() == Token::IDENTIFIER &&
955a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org          !scanner().HasAnyLineTerminatorBeforeNext() &&
956a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org          stmt != NULL) {
957a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org        ExpressionStatement* estmt = stmt->AsExpressionStatement();
958a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org        if (estmt != NULL &&
959a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org            estmt->expression()->AsVariableProxy() != NULL &&
960a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org            estmt->expression()->AsVariableProxy()->name()->Equals(
9614a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org                isolate()->heap()->module_string()) &&
962a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org            !scanner().literal_contains_escapes()) {
963812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org          return ParseModuleDeclaration(NULL, ok);
964a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org        }
965a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org      }
966a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org      return stmt;
967a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org    }
968f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  }
969f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
970f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
971f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
97281cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.orgStatement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) {
973f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // ModuleDeclaration:
974f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    'module' Identifier Module
975f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
976f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Handle<String> name = ParseIdentifier(CHECK_OK);
977bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
978bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
979bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  if (FLAG_print_interface_details)
980bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    PrintF("# Module %s...\n", name->ToAsciiArray());
981bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
982bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
983812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Module* module = ParseModule(CHECK_OK);
9848e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface());
985812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Declaration* declaration =
986812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      factory()->NewModuleDeclaration(proxy, module, top_scope_);
987812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Declare(declaration, true, CHECK_OK);
988812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
989bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
990bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  if (FLAG_print_interface_details)
991bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    PrintF("# Module %s.\n", name->ToAsciiArray());
992bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
993bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  if (FLAG_print_interfaces) {
994bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    PrintF("module %s : ", name->ToAsciiArray());
995bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    module->interface()->Print();
996bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  }
997bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
998bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
9997028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  if (names) names->Add(name, zone());
100081cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  if (module->body() == NULL)
100181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org    return factory()->NewEmptyStatement();
100281cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  else
10038e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    return factory()->NewModuleStatement(proxy, module->body());
1004f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
1005f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1006f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1007f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModule(bool* ok) {
1008f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // Module:
1009f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    '{' ModuleElement '}'
1010812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //    '=' ModulePath ';'
1011812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //    'at' String ';'
1012f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1013f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  switch (peek()) {
1014f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    case Token::LBRACE:
1015f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      return ParseModuleLiteral(ok);
1016f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1017812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    case Token::ASSIGN: {
1018f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      Expect(Token::ASSIGN, CHECK_OK);
1019812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      Module* result = ParseModulePath(CHECK_OK);
1020812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      ExpectSemicolon(CHECK_OK);
1021812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      return result;
1022812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    }
1023f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1024812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    default: {
10251fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      ExpectContextualKeyword(CStrVector("at"), CHECK_OK);
1026812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      Module* result = ParseModuleUrl(CHECK_OK);
1027812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      ExpectSemicolon(CHECK_OK);
1028812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      return result;
1029812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    }
1030f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  }
1031f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
1032f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1033f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1034f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModuleLiteral(bool* ok) {
1035f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // Module:
1036f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    '{' ModuleElement '}'
1037f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1038f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // Construct block expecting 16 statements.
10395a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Block* body = factory()->NewBlock(NULL, 16, false);
1040bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1041bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  if (FLAG_print_interface_details) PrintF("# Literal ");
1042bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
1043f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Scope* scope = NewScope(top_scope_, MODULE_SCOPE);
1044f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1045f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Expect(Token::LBRACE, CHECK_OK);
1046f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  scope->set_start_position(scanner().location().beg_pos);
1047f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  scope->SetLanguageMode(EXTENDED_MODE);
1048f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1049f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  {
1050f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    BlockState block_state(this, scope);
10517028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    TargetCollector collector(zone());
1052f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    Target target(&this->target_stack_, &collector);
1053f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    Target target_body(&this->target_stack_, body);
1054f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1055f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    while (peek() != Token::RBRACE) {
1056f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      Statement* stat = ParseModuleElement(NULL, CHECK_OK);
1057f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      if (stat && !stat->IsEmpty()) {
1058400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org        body->AddStatement(stat, zone());
1059f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      }
1060f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    }
1061f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  }
1062f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1063f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Expect(Token::RBRACE, CHECK_OK);
1064f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  scope->set_end_position(scanner().location().end_pos);
1065ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  body->set_scope(scope);
1066bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
106781cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  // Check that all exports are bound.
1068ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  Interface* interface = scope->interface();
106981cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  for (Interface::Iterator it = interface->iterator();
107081cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org       !it.done(); it.Advance()) {
107181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org    if (scope->LocalLookup(it.name()) == NULL) {
107281cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org      Handle<String> name(it.name());
107381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org      ReportMessage("module_export_undefined",
107481cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org                    Vector<Handle<String> >(&name, 1));
107581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org      *ok = false;
107681cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org      return NULL;
107781cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org    }
107881cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  }
107981cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org
1080ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  interface->MakeModule(ok);
108181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  ASSERT(*ok);
1082ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  interface->Freeze(ok);
108381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  ASSERT(*ok);
1084ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  return factory()->NewModuleLiteral(body, interface);
1085f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
1086f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1087f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1088f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModulePath(bool* ok) {
1089f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // ModulePath:
1090f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    Identifier
1091f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    ModulePath '.' Identifier
1092f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1093f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Module* result = ParseModuleVariable(CHECK_OK);
1094f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  while (Check(Token::PERIOD)) {
1095f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    Handle<String> name = ParseIdentifierName(CHECK_OK);
1096bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1097bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    if (FLAG_print_interface_details)
1098bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      PrintF("# Path .%s ", name->ToAsciiArray());
1099bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
1100bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    Module* member = factory()->NewModulePath(result, name);
11017028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    result->interface()->Add(name, member->interface(), zone(), ok);
1102bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    if (!*ok) {
1103bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1104bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      if (FLAG_print_interfaces) {
1105bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray());
1106bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        PrintF("result: ");
1107bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        result->interface()->Print();
1108bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        PrintF("member: ");
1109bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        member->interface()->Print();
1110bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      }
1111bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
1112bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1));
1113bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      return NULL;
1114bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    }
1115bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    result = member;
1116f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  }
1117f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1118f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  return result;
1119f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
1120f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1121f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1122f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModuleVariable(bool* ok) {
1123f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // ModulePath:
1124f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    Identifier
1125f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1126f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Handle<String> name = ParseIdentifier(CHECK_OK);
1127bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1128bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  if (FLAG_print_interface_details)
1129bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    PrintF("# Module variable %s ", name->ToAsciiArray());
1130bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
1131f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  VariableProxy* proxy = top_scope_->NewUnresolved(
113228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org      factory(), name, Interface::NewModule(zone()),
113328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org      scanner().location().beg_pos);
1134bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
1135f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  return factory()->NewModuleVariable(proxy);
1136f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
1137f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1138f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1139f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModuleUrl(bool* ok) {
1140f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // Module:
1141812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //    String
1142f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1143f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Expect(Token::STRING, CHECK_OK);
1144bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  Handle<String> symbol = GetSymbol();
1145f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1146bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // TODO(ES6): Request JS resource from environment...
1147bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
1148bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1149bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  if (FLAG_print_interface_details) PrintF("# Url ");
1150bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
1151ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
11528e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // Create an empty literal as long as the feature isn't finished.
11538e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  USE(symbol);
11548e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Scope* scope = NewScope(top_scope_, MODULE_SCOPE);
11558e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Block* body = factory()->NewBlock(NULL, 1, false);
11568e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  body->set_scope(scope);
11578e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Interface* interface = scope->interface();
11588e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Module* result = factory()->NewModuleLiteral(body, interface);
1159ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  interface->Freeze(ok);
116081cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  ASSERT(*ok);
116181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  interface->Unify(scope->interface(), zone(), ok);
116281cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  ASSERT(*ok);
1163ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  return result;
1164f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
1165f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1166f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1167812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgModule* Parser::ParseModuleSpecifier(bool* ok) {
1168812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  // ModuleSpecifier:
1169812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //    String
1170812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //    ModulePath
1171812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1172812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  if (peek() == Token::STRING) {
1173812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    return ParseModuleUrl(ok);
1174812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  } else {
1175812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    return ParseModulePath(ok);
1176812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  }
1177812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org}
1178812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1179812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1180f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgBlock* Parser::ParseImportDeclaration(bool* ok) {
1181812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  // ImportDeclaration:
1182812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //    'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';'
1183812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //
1184812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  // TODO(ES6): implement destructuring ImportSpecifiers
1185812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1186812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Expect(Token::IMPORT, CHECK_OK);
11877028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  ZoneStringList names(1, zone());
1188812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1189812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Handle<String> name = ParseIdentifierName(CHECK_OK);
11907028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  names.Add(name, zone());
1191812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  while (peek() == Token::COMMA) {
1192812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    Consume(Token::COMMA);
1193812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    name = ParseIdentifierName(CHECK_OK);
11947028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    names.Add(name, zone());
1195812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  }
1196812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
11971fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1198812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Module* module = ParseModuleSpecifier(CHECK_OK);
1199812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  ExpectSemicolon(CHECK_OK);
1200812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1201812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  // Generate a separate declaration for each identifier.
1202812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  // TODO(ES6): once we implement destructuring, make that one declaration.
12035a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Block* block = factory()->NewBlock(NULL, 1, true);
1204812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  for (int i = 0; i < names.length(); ++i) {
1205bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1206bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    if (FLAG_print_interface_details)
1207bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      PrintF("# Import %s ", names[i]->ToAsciiArray());
1208bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
12097028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    Interface* interface = Interface::NewUnknown(zone());
12107028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    module->interface()->Add(names[i], interface, zone(), ok);
1211bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    if (!*ok) {
1212bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1213bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      if (FLAG_print_interfaces) {
1214bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray());
1215bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        PrintF("module: ");
1216bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        module->interface()->Print();
1217bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      }
1218bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
1219bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1));
1220bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      return NULL;
1221bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    }
1222bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    VariableProxy* proxy = NewUnresolved(names[i], LET, interface);
1223812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    Declaration* declaration =
1224812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org        factory()->NewImportDeclaration(proxy, module, top_scope_);
1225812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    Declare(declaration, true, CHECK_OK);
1226812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  }
1227812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1228812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  return block;
1229f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
1230f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1231f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1232812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgStatement* Parser::ParseExportDeclaration(bool* ok) {
1233812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  // ExportDeclaration:
1234812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //    'export' Identifier (',' Identifier)* ';'
1235812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //    'export' VariableDeclaration
1236812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //    'export' FunctionDeclaration
1237f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  //    'export' GeneratorDeclaration
1238812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //    'export' ModuleDeclaration
1239812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //
1240812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  // TODO(ES6): implement structuring ExportSpecifiers
1241812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1242812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Expect(Token::EXPORT, CHECK_OK);
1243812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1244812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Statement* result = NULL;
12457028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  ZoneStringList names(1, zone());
1246812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  switch (peek()) {
1247812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    case Token::IDENTIFIER: {
1248812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      Handle<String> name = ParseIdentifier(CHECK_OK);
1249812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      // Handle 'module' as a context-sensitive keyword.
125059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) {
12517028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        names.Add(name, zone());
1252812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org        while (peek() == Token::COMMA) {
1253812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org          Consume(Token::COMMA);
1254812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org          name = ParseIdentifier(CHECK_OK);
12557028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org          names.Add(name, zone());
1256812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org        }
1257812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org        ExpectSemicolon(CHECK_OK);
1258812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org        result = factory()->NewEmptyStatement();
1259812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      } else {
1260812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org        result = ParseModuleDeclaration(&names, CHECK_OK);
1261812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      }
1262812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      break;
1263812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    }
1264812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1265812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    case Token::FUNCTION:
1266812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      result = ParseFunctionDeclaration(&names, CHECK_OK);
1267812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      break;
1268812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1269812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    case Token::VAR:
1270812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    case Token::LET:
1271812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    case Token::CONST:
1272812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      result = ParseVariableStatement(kModuleElement, &names, CHECK_OK);
1273812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      break;
1274812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1275812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    default:
1276812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      *ok = false;
1277812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      ReportUnexpectedToken(scanner().current_token());
1278812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      return NULL;
1279812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  }
1280812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1281bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // Extract declared names into export declarations and interface.
1282bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  Interface* interface = top_scope_->interface();
1283812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  for (int i = 0; i < names.length(); ++i) {
1284bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1285bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    if (FLAG_print_interface_details)
1286bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      PrintF("# Export %s ", names[i]->ToAsciiArray());
1287bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
12887028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    Interface* inner = Interface::NewUnknown(zone());
12897028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    interface->Add(names[i], inner, zone(), CHECK_OK);
12907028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    if (!*ok)
12917028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      return NULL;
1292bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    VariableProxy* proxy = NewUnresolved(names[i], LET, inner);
1293bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    USE(proxy);
1294bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    // TODO(rossberg): Rethink whether we actually need to store export
1295bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    // declarations (for compilation?).
1296bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    // ExportDeclaration* declaration =
1297bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    //     factory()->NewExportDeclaration(proxy, top_scope_);
1298bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    // top_scope_->AddDeclaration(declaration);
1299812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  }
1300812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1301812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  ASSERT(result != NULL);
1302812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  return result;
1303f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
1304f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1305f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1306f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgStatement* Parser::ParseBlockElement(ZoneStringList* labels,
1307f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org                                     bool* ok) {
1308f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // (Ecma 262 5th Edition, clause 14):
1309f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // SourceElement:
1310f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    Statement
1311f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    FunctionDeclaration
1312f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //
1313f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // In harmony mode we allow additionally the following productions
1314f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // BlockElement (aka SourceElement):
1315f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    LetDeclaration
1316f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    ConstDeclaration
1317f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  //    GeneratorDeclaration
1318f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1319f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  switch (peek()) {
1320f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    case Token::FUNCTION:
1321812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      return ParseFunctionDeclaration(NULL, ok);
1322f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    case Token::LET:
1323f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    case Token::CONST:
1324812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      return ParseVariableStatement(kModuleElement, NULL, ok);
1325f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    default:
1326f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      return ParseStatement(labels, ok);
1327f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  }
1328f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
1329f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1330f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
133143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
133243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Statement ::
133343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   Block
133443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   VariableStatement
133543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   EmptyStatement
133643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   ExpressionStatement
133743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   IfStatement
133843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   IterationStatement
133943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   ContinueStatement
134043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   BreakStatement
134143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   ReturnStatement
134243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   WithStatement
134343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   LabelledStatement
134443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   SwitchStatement
134543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   ThrowStatement
134643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   TryStatement
134743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   DebuggerStatement
134843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
134943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Note: Since labels can only be used by 'break' and 'continue'
135043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // statements, which themselves are only valid within blocks,
135143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // iterations or 'switch' statements (i.e., BreakableStatements),
135243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // labels can be simply ignored in all other cases; except for
13533291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  // trivial labeled break statements 'label: break label' which is
135443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // parsed into an empty statement.
135543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
135643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Keep the source position of the statement
135743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int statement_pos = scanner().peek_location().beg_pos;
135843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Statement* stmt = NULL;
135943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  switch (peek()) {
136043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::LBRACE:
136143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return ParseBlock(labels, ok);
136243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
136343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::CONST:  // fall through
13641b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    case Token::LET:
136543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::VAR:
1366812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      stmt = ParseVariableStatement(kStatement, NULL, ok);
136743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
136843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
136943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::SEMICOLON:
137043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Next();
1371b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      return factory()->NewEmptyStatement();
137243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
137343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::IF:
137443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      stmt = ParseIfStatement(labels, ok);
137543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
137643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
137743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::DO:
13789d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com      stmt = ParseDoWhileStatement(labels, ok);
137943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
138043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
138143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::WHILE:
138243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      stmt = ParseWhileStatement(labels, ok);
138343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
138443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
138543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::FOR:
138643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      stmt = ParseForStatement(labels, ok);
138743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
138843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
138943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::CONTINUE:
139043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      stmt = ParseContinueStatement(ok);
139143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
139243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
139343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::BREAK:
139443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      stmt = ParseBreakStatement(labels, ok);
139543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
139643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
139743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::RETURN:
139843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      stmt = ParseReturnStatement(ok);
139943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
140043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
140143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::WITH:
140243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      stmt = ParseWithStatement(labels, ok);
140343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
140443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
140543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::SWITCH:
140643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      stmt = ParseSwitchStatement(labels, ok);
140743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
140843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
140943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::THROW:
141043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      stmt = ParseThrowStatement(ok);
141143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
141243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
141343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::TRY: {
141443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // NOTE: It is somewhat complicated to have labels on
141543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // try-statements. When breaking out of a try-finally statement,
141643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // one must take great care not to treat it as a
141743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // fall-through. It is much easier just to wrap the entire
141843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // try-statement in a statement block and put the labels there
14195a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      Block* result = factory()->NewBlock(labels, 1, false);
1420e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org      Target target(&this->target_stack_, result);
142143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      TryStatement* statement = ParseTryStatement(CHECK_OK);
142237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      if (statement) {
142337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        statement->set_statement_pos(statement_pos);
142437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      }
1425400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org      if (result) result->AddStatement(statement, zone());
142643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return result;
142743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
142843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14299ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    case Token::FUNCTION: {
1430c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // FunctionDeclaration is only allowed in the context of SourceElements
1431c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // (Ecma 262 5th Edition, clause 14):
1432c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // SourceElement:
1433c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      //    Statement
1434c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      //    FunctionDeclaration
1435c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Common language extension is to allow function declaration in place
1436c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // of any statement. This language extension is disabled in strict mode.
1437f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      //
1438f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      // In Harmony mode, this case also handles the extension:
1439f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      // Statement:
1440f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      //    GeneratorDeclaration
14411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      if (!top_scope_->is_classic_mode()) {
14429ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        ReportMessageAt(scanner().peek_location(), "strict_function",
14439ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org                        Vector<const char*>::empty());
14449ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        *ok = false;
14459ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        return NULL;
14469ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      }
1447812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      return ParseFunctionDeclaration(NULL, ok);
14489ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    }
144943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
145043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::DEBUGGER:
145143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      stmt = ParseDebuggerStatement(ok);
145243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
145343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
145443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    default:
145543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      stmt = ParseExpressionOrLabelledStatement(labels, ok);
145643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
145743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
145843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Store the source position of the statement
145943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (stmt != NULL) stmt->set_statement_pos(statement_pos);
146043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return stmt;
146143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
146243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
146343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1464bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.comVariableProxy* Parser::NewUnresolved(
1465bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    Handle<String> name, VariableMode mode, Interface* interface) {
1466b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  // If we are inside a function, a declaration of a var/const variable is a
1467b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  // truly local variable, and the scope of the variable is always the function
1468b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  // scope.
1469394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Let/const variables in harmony mode are always added to the immediately
1470394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // enclosing scope.
1471812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  return DeclarationScope(mode)->NewUnresolved(
147228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org      factory(), name, interface, scanner().location().beg_pos);
1473812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org}
1474812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1475812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1476812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgvoid Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
1477bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  VariableProxy* proxy = declaration->proxy();
1478bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  Handle<String> name = proxy->name();
1479812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  VariableMode mode = declaration->mode();
1480812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Scope* declaration_scope = DeclarationScope(mode);
1481812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Variable* var = NULL;
148243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
148381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  // If a suitable scope exists, then we can statically declare this
148443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // variable and also set its mode. In any case, a Declaration node
148543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // will be added to the scope so that the declaration can be added
148643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // to the corresponding activation frame at runtime if necessary.
148743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // For instance declarations inside an eval scope need to be added
148843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // to the calling function context.
14898e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // Similarly, strict mode eval scope does not leak variable declarations to
14908e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // the caller's scope so we declare all locals, too.
14914f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if (declaration_scope->is_function_scope() ||
14921b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      declaration_scope->is_strict_or_extended_eval_scope() ||
1493f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      declaration_scope->is_block_scope() ||
1494bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      declaration_scope->is_module_scope() ||
1495355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      declaration_scope->is_global_scope()) {
149681cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org    // Declare the variable in the declaration scope.
1497355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    // For the global scope, we have to check for collisions with earlier
1498355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    // (i.e., enclosing) global scopes, to maintain the illusion of a single
1499355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    // global scope.
1500355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    var = declaration_scope->is_global_scope()
1501355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        ? declaration_scope->Lookup(name)
1502355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        : declaration_scope->LocalLookup(name);
150343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (var == NULL) {
150443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Declare the name.
1505812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      var = declaration_scope->DeclareLocal(
1506bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com          name, mode, declaration->initialization(), proxy->interface());
1507355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    } else if ((mode != VAR || var->mode() != VAR) &&
1508355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org               (!declaration_scope->is_global_scope() ||
1509355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                IsLexicalVariableMode(mode) ||
1510355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                IsLexicalVariableMode(var->mode()))) {
15111805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      // The name was declared in this scope before; check for conflicting
15121805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      // re-declarations. We have a conflict if either of the declarations is
1513355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      // not a var (in the global scope, we also have to ignore legacy const for
1514355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      // compatibility). There is similar code in runtime.cc in the Declare
15151805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      // functions. The function CheckNonConflictingScope checks for conflicting
15161805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      // var and let bindings from different scopes whereas this is a check for
15171805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      // conflicting declarations within the same scope. This check also covers
1518355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      // the special case
15191805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      //
15201805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      // function () { let x; { var x; } }
15211805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      //
15221805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      // because the var declaration is hoisted to the function scope where 'x'
15231805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      // is already bound.
1524355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      ASSERT(IsDeclaredVariableMode(var->mode()));
1525355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      if (is_extended_mode()) {
1526355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        // In harmony mode we treat re-declarations as early errors. See
1527355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        // ES5 16 for a definition of early errors.
1528355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
1529355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        const char* elms[2] = { "Variable", *c_string };
1530355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        Vector<const char*> args(elms, 2);
1531355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        ReportMessage("redeclaration", args);
1532355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        *ok = false;
1533355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        return;
153443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
1535dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      Handle<String> message_string =
15368e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          isolate()->factory()->NewStringFromUtf8(CStrVector("Variable"),
15378e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org                                                  TENURED);
1538355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      Expression* expression =
15394a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org          NewThrowTypeError(isolate()->factory()->redeclaration_string(),
1540dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                            message_string, name);
1541355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      declaration_scope->SetIllegalRedeclaration(expression);
154243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
154343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
154443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
154543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // We add a declaration node for every declaration. The compiler
154643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // will only generate code if necessary. In particular, declarations
154743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for inner local variables that do not represent functions won't
154843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // result in any generated code.
154943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
155043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Note that we always add an unresolved proxy even if it's not
155143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // used, simply because we don't know in this method (w/o extra
155243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // parameters) if the proxy is needed or not. The proxy will be
155343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // bound during variable resolution time unless it was pre-bound
155443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // below.
155543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
155643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // WARNING: This will lead to multiple declaration nodes for the
155743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // same variable if it is declared several times. This is not a
155843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // semantic issue as long as we keep the source order, but it may be
155943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // a performance issue since it may lead to repeated
156043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Runtime::DeclareContextSlot() calls.
1561812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  declaration_scope->AddDeclaration(declaration);
156243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1563355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (mode == CONST && declaration_scope->is_global_scope()) {
156427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    // For global const variables we bind the proxy to a variable.
156543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(resolve);  // should be set by all callers
15663e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org    Variable::Kind kind = Variable::NORMAL;
156710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    var = new(zone()) Variable(
156810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org        declaration_scope, name, mode, true, kind,
156910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org        kNeedsInitialization, proxy->interface());
157027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  } else if (declaration_scope->is_eval_scope() &&
15711b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org             declaration_scope->is_classic_mode()) {
157227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    // For variable declarations in a non-strict eval scope the proxy is bound
157327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    // to a lookup variable to force a dynamic declaration using the
157427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    // DeclareContextSlot runtime function.
157527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    Variable::Kind kind = Variable::NORMAL;
157610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    var = new(zone()) Variable(
157710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org        declaration_scope, name, mode, true, kind,
157810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org        declaration->initialization(), proxy->interface());
157927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    var->AllocateTo(Variable::LOOKUP, -1);
158027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    resolve = true;
158143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
158243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
158343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If requested and we have a local variable, bind the proxy to the variable
158443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // at parse-time. This is used for functions (and consts) declared inside
158543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // statements: the corresponding function (or const) variable must be in the
158643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // function scope and not a statement-local scope, e.g. as provided with a
158743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // 'with' statement:
158843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
158943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   with (obj) {
159043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //     function f() {}
159143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   }
159243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
159343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // which is translated into:
159443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
159543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   with (obj) {
159643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //     // in this case this is not: 'var f; f = function () {};'
159743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //     var f = function () {};
159843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   }
159943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
160043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Note that if 'f' is accessed from inside the 'with' statement, it
160143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // will be allocated in the context (because we must be able to look
160243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // it up dynamically) but it will also be accessed statically, i.e.,
160343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // with a context slot index and a context chain length for this
160443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // initialization code. Thus, inside the 'with' statement, we need
160543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // both access to the static and the dynamic context chain; the
160643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // runtime needs to provide both.
1607bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  if (resolve && var != NULL) {
1608bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    proxy->BindTo(var);
1609bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
1610bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    if (FLAG_harmony_modules) {
1611bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      bool ok;
1612bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1613bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      if (FLAG_print_interface_details)
1614bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        PrintF("# Declare %s\n", var->name()->ToAsciiArray());
1615bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
16167028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      proxy->interface()->Unify(var->interface(), zone(), &ok);
1617bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      if (!ok) {
1618bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1619bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        if (FLAG_print_interfaces) {
1620bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com          PrintF("DECLARE TYPE ERROR\n");
1621bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com          PrintF("proxy: ");
1622bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com          proxy->interface()->Print();
1623bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com          PrintF("var: ");
1624bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com          var->interface()->Print();
1625bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        }
1626bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
1627bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        ReportMessage("module_type_error", Vector<Handle<String> >(&name, 1));
1628bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      }
1629bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    }
1630bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  }
163143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
163243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
163343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
163443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Language extension which is only enabled for source files loaded
163543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// through the API's extension mechanism.  A native function
163643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// declaration is resolved by looking up the function through a
163743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// callback provided by the extension.
163843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseNativeDeclaration(bool* ok) {
163943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::FUNCTION, CHECK_OK);
164043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<String> name = ParseIdentifier(CHECK_OK);
164143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::LPAREN, CHECK_OK);
164243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool done = (peek() == Token::RPAREN);
164343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (!done) {
164443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ParseIdentifier(CHECK_OK);
164543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    done = (peek() == Token::RPAREN);
1646fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    if (!done) {
1647fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org      Expect(Token::COMMA, CHECK_OK);
1648fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    }
164943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
165043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::RPAREN, CHECK_OK);
165143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::SEMICOLON, CHECK_OK);
165243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
165343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Make sure that the function containing the native declaration
165443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // isn't lazily compiled. The extension structures are only
165543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // accessible while parsing the first time not when reparsing
165643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // because of lazy compilation.
1657812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  DeclarationScope(VAR)->ForceEagerCompilation();
165843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
165943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Compute the function template for the native function.
166043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  v8::Handle<v8::FunctionTemplate> fun_template =
166143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      extension_->GetNativeFunction(v8::Utils::ToLocal(name));
166243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(!fun_template.IsEmpty());
166343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1664c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  // Instantiate the function and create a shared function info from it.
166543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->GetFunction());
166643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  const int literals = fun->NumberOfLiterals();
166743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Code> code = Handle<Code>(fun->shared()->code());
1668b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
1669b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  bool is_generator = false;
1670b5737496145078e47f3d28f19ed8d918e2254738ager@chromium.org  Handle<SharedFunctionInfo> shared =
1671b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      isolate()->factory()->NewSharedFunctionInfo(name, literals, is_generator,
1672b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org          code, Handle<ScopeInfo>(fun->shared()->scope_info()));
16735d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  shared->set_construct_stub(*construct_stub);
167443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1675c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  // Copy the function data to the shared function info.
16765d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  shared->set_function_data(fun->shared()->function_data());
1677b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  int parameters = fun->shared()->formal_parameter_count();
16785d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  shared->set_formal_parameter_count(parameters);
167943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
168043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // TODO(1240846): It's weird that native function declarations are
168143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // introduced dynamically when we meet their declarations, whereas
1682f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // other functions are set up when entering the surrounding scope.
168328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue());
1684812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Declaration* declaration =
1685812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      factory()->NewVariableDeclaration(proxy, VAR, top_scope_);
1686812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Declare(declaration, true, CHECK_OK);
1687c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  SharedFunctionInfoLiteral* lit =
1688b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      factory()->NewSharedFunctionInfoLiteral(shared);
1689b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  return factory()->NewExpressionStatement(
1690b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      factory()->NewAssignment(
1691812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org          Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition));
169243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
169343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
169443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1695812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgStatement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) {
1696c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  // FunctionDeclaration ::
1697c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  //   'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
1698f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  // GeneratorDeclaration ::
1699f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  //   'function' '*' Identifier '(' FormalParameterListopt ')'
1700f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  //      '{' FunctionBody '}'
170143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::FUNCTION, CHECK_OK);
170243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int function_token_position = scanner().location().beg_pos;
1703e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  bool is_generator = allow_generators() && Check(Token::MUL);
170404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  bool is_strict_reserved = false;
170504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  Handle<String> name = ParseIdentifierOrStrictReservedWord(
170604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      &is_strict_reserved, CHECK_OK);
1707c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  FunctionLiteral* fun = ParseFunctionLiteral(name,
170804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org                                              is_strict_reserved,
1709f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                                              is_generator,
1710c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org                                              function_token_position,
17117c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org                                              FunctionLiteral::DECLARATION,
1712c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org                                              CHECK_OK);
1713c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  // Even if we're not at the top-level of the global or a function
1714355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  // scope, we treat it as such and introduce the function with its
1715c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  // initial value upon entering the corresponding scope.
1716355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  // In extended mode, a function behaves as a lexical binding, except in the
1717355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  // global scope.
1718355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  VariableMode mode =
1719355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      is_extended_mode() && !top_scope_->is_global_scope() ? LET : VAR;
172028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
1721812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Declaration* declaration =
1722812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_);
1723812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Declare(declaration, true, CHECK_OK);
17247028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  if (names) names->Add(name, zone());
1725b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  return factory()->NewEmptyStatement();
172643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
172743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
172843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
172943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenBlock* Parser::ParseBlock(ZoneStringList* labels, bool* ok) {
17301b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  if (top_scope_->is_extended_mode()) return ParseScopedBlock(labels, ok);
17314acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
173243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Block ::
173343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   '{' Statement* '}'
173443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
173543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Note that a Block does not introduce a new execution scope!
173643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // (ECMA-262, 3rd, 12.2)
173743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
173843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Construct block expecting 16 statements.
17395a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Block* result = factory()->NewBlock(labels, 16, false);
1740e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  Target target(&this->target_stack_, result);
174143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::LBRACE, CHECK_OK);
174243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (peek() != Token::RBRACE) {
174343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Statement* stat = ParseStatement(NULL, CHECK_OK);
17446db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org    if (stat && !stat->IsEmpty()) {
1745400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org      result->AddStatement(stat, zone());
17466db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org    }
174743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
174843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::RBRACE, CHECK_OK);
174943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
175043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
175143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
175243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
17534acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.orgBlock* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) {
1754f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // The harmony mode uses block elements instead of statements.
1755c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  //
1756c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Block ::
1757f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //   '{' BlockElement* '}'
1758c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
17594acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  // Construct block expecting 16 statements.
17605a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Block* body = factory()->NewBlock(labels, 16, false);
1761394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE);
17624acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
17634acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  // Parse the statements and collect escaping labels.
17644acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  Expect(Token::LBRACE, CHECK_OK);
1765394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  block_scope->set_start_position(scanner().location().beg_pos);
1766c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  { BlockState block_state(this, block_scope);
17677028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    TargetCollector collector(zone());
1768394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Target target(&this->target_stack_, &collector);
17694acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    Target target_body(&this->target_stack_, body);
17704acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
17714acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    while (peek() != Token::RBRACE) {
1772f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      Statement* stat = ParseBlockElement(NULL, CHECK_OK);
17734acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      if (stat && !stat->IsEmpty()) {
1774400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org        body->AddStatement(stat, zone());
17754acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      }
17764acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    }
17774acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  }
17784acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  Expect(Token::RBRACE, CHECK_OK);
1779394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  block_scope->set_end_position(scanner().location().end_pos);
17801805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  block_scope = block_scope->FinalizeBlockScope();
1781ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  body->set_scope(block_scope);
1782486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  return body;
17834acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org}
17844acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
17854acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
1786b645116853c677aca8a316381b87441ba6004f67danno@chromium.orgBlock* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
1787812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org                                      ZoneStringList* names,
1788b645116853c677aca8a316381b87441ba6004f67danno@chromium.org                                      bool* ok) {
178943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // VariableStatement ::
179043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   VariableDeclarations ';'
179143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
17924f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  Handle<String> ignore;
1793f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Block* result =
1794812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK);
179543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ExpectSemicolon(CHECK_OK);
179643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
179743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
179843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1799ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
1800ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgbool Parser::IsEvalOrArguments(Handle<String> string) {
18014a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  return string.is_identical_to(isolate()->factory()->eval_string()) ||
18024a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      string.is_identical_to(isolate()->factory()->arguments_string());
18030a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org}
180443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1805ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
180643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// If the variable declaration declares exactly one non-const
180778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// variable, then *out is set to that variable. In all other cases,
180878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// *out is untouched; in particular, it is the caller's responsibility
180943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// to initialize it properly. This mechanism is used for the parsing
181043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// of 'for-in' loops.
1811394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comBlock* Parser::ParseVariableDeclarations(
1812394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    VariableDeclarationContext var_context,
1813394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    VariableDeclarationProperties* decl_props,
1814812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    ZoneStringList* names,
1815394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Handle<String>* out,
1816394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    bool* ok) {
181743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // VariableDeclarations ::
1818394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //   ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
1819394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //
1820394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // The ES6 Draft Rev3 specifies the following grammar for const declarations
1821394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //
1822394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // ConstDeclaration ::
1823394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //   const ConstBinding (',' ConstBinding)* ';'
1824394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // ConstBinding ::
1825394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //   Identifier '=' AssignmentExpression
1826394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //
1827394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // TODO(ES6):
1828394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // ConstBinding ::
1829394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //   BindingPattern '=' AssignmentExpression
1830b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  VariableMode mode = VAR;
183180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  // True if the binding needs initialization. 'let' and 'const' declared
183280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  // bindings are created uninitialized by their declaration nodes and
183380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  // need initialization. 'var' declared bindings are always initialized
183480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  // immediately by their declaration nodes.
183580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  bool needs_init = false;
183643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool is_const = false;
183780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  Token::Value init_op = Token::INIT_VAR;
183843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (peek() == Token::VAR) {
183943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Consume(Token::VAR);
184043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (peek() == Token::CONST) {
18411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
18421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    //
18431b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
18441b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    //
18451b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // * It is a Syntax Error if the code that matches this production is not
18461b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    //   contained in extended code.
18471b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    //
18481b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // However disallowing const in classic mode will break compatibility with
18491b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // existing pages. Therefore we keep allowing const with the old
18501b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // non-harmony semantics in classic mode.
185143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Consume(Token::CONST);
18521b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    switch (top_scope_->language_mode()) {
18531b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      case CLASSIC_MODE:
18541b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        mode = CONST;
18551b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        init_op = Token::INIT_CONST;
18561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        break;
18571b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      case STRICT_MODE:
18581b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        ReportMessage("strict_const", Vector<const char*>::empty());
1859394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        *ok = false;
1860394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        return NULL;
18611b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      case EXTENDED_MODE:
1862f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org        if (var_context == kStatement) {
18631b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          // In extended mode 'const' declarations are only allowed in source
18641b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          // element positions.
18651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          ReportMessage("unprotected_const", Vector<const char*>::empty());
18661b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          *ok = false;
18671b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          return NULL;
18681b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        }
18691b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        mode = CONST_HARMONY;
18701b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        init_op = Token::INIT_CONST_HARMONY;
18719ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    }
187243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    is_const = true;
187380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org    needs_init = true;
1874b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  } else if (peek() == Token::LET) {
18751b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // ES6 Draft Rev4 section 12.2.1:
18761b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    //
18771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // LetDeclaration : let LetBindingList ;
18781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    //
18791b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // * It is a Syntax Error if the code that matches this production is not
18801b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    //   contained in extended code.
18811b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (!is_extended_mode()) {
18821b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      ReportMessage("illegal_let", Vector<const char*>::empty());
18831b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      *ok = false;
18841b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      return NULL;
18851b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    }
1886b645116853c677aca8a316381b87441ba6004f67danno@chromium.org    Consume(Token::LET);
1887f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    if (var_context == kStatement) {
1888394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      // Let declarations are only allowed in source element positions.
1889b645116853c677aca8a316381b87441ba6004f67danno@chromium.org      ReportMessage("unprotected_let", Vector<const char*>::empty());
1890b645116853c677aca8a316381b87441ba6004f67danno@chromium.org      *ok = false;
1891b645116853c677aca8a316381b87441ba6004f67danno@chromium.org      return NULL;
1892b645116853c677aca8a316381b87441ba6004f67danno@chromium.org    }
1893b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    mode = LET;
189480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org    needs_init = true;
189580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org    init_op = Token::INIT_LET;
189643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
189743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    UNREACHABLE();  // by current callers
189843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
189943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1900812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Scope* declaration_scope = DeclarationScope(mode);
1901812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1902b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  // The scope of a var/const declared variable anywhere inside a function
190343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
1904b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  // transform a source-level var/const declaration into a (Function)
190543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Scope declaration, and rewrite the source-level initialization into an
190643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // assignment statement. We use a block to collect multiple assignments.
190743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
190843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // We mark the block as initializer block because we don't want the
190943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // rewriter to add a '.result' assignment to such a block (to get compliant
191043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // behavior for code such as print(eval('var x = 7')), and for cosmetic
191143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // reasons when pretty-printing. Also, unless an assignment (initialization)
191243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // is inside an initializer block, it is ignored.
191343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
191443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Create new block with one expected declaration.
19155a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Block* block = factory()->NewBlock(NULL, 1, true);
191643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int nvars = 0;  // the number of variables declared
19174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  Handle<String> name;
191843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  do {
191965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    if (fni_ != NULL) fni_->Enter();
192065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
192143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Parse variable name.
192243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (nvars > 0) Consume(Token::COMMA);
19234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    name = ParseIdentifier(CHECK_OK);
192465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    if (fni_ != NULL) fni_->PushVariableName(name);
192543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
19260a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    // Strict mode variables may not be named eval or arguments
19271b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (!declaration_scope->is_classic_mode() && IsEvalOrArguments(name)) {
19280a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      ReportMessage("strict_var_name", Vector<const char*>::empty());
19290a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      *ok = false;
19300a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      return NULL;
19310a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    }
19320a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
193343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Declare variable.
193443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Note that we *always* must treat the initial value via a separate init
193543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // assignment for variables and constants because the value must be assigned
193643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // when the variable is encountered in the source. But the variable/constant
193743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // is declared (and set to 'undefined') upon entering the function within
193843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // which the variable or constant is declared. Only function variables have
193943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // an initial value in the declaration (because they are initialized upon
194043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // entering the function).
194143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    //
194243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // If we have a const declaration, in an inner scope, the proxy is always
194343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // bound to the declared variable (independent of possibly surrounding with
194443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // statements).
1945394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // For let/const declarations in harmony mode, we can also immediately
1946394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // pre-resolve the proxy because it resides in the same scope as the
1947394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // declaration.
194828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    Interface* interface =
194928583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org        is_const ? Interface::NewConst() : Interface::NewValue();
195028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    VariableProxy* proxy = NewUnresolved(name, mode, interface);
1951812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    Declaration* declaration =
1952812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org        factory()->NewVariableDeclaration(proxy, mode, top_scope_);
1953812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    Declare(declaration, mode != VAR, CHECK_OK);
195443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    nvars++;
19554f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
19567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org      ReportMessageAt(scanner().location(), "too_many_variables",
19577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org                      Vector<const char*>::empty());
19587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org      *ok = false;
19597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org      return NULL;
19607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    }
19617028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    if (names) names->Add(name, zone());
196243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
196343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Parse initialization expression if present and/or needed. A
196443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // declaration of the form:
196543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    //
196643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    //    var v = x;
196743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    //
196843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // is syntactic sugar for:
196943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    //
197043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    //    var v; v = x;
197143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    //
19724f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    // In particular, we need to re-lookup 'v' (in top_scope_, not
19734f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    // declaration_scope) as it may be a different 'v' than the 'v' in the
19744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    // declaration (e.g., if we are inside a 'with' statement or 'catch'
19754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    // block).
197643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    //
197743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // However, note that const declarations are different! A const
197843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // declaration of the form:
197943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    //
198043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    //   const c = x;
198143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    //
198243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // is *not* syntactic sugar for:
198343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    //
198443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    //   const c; c = x;
198543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    //
198643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // The "variable" c initialized to x is the same as the declared
198743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // one - there is no re-lookup (see the last parameter of the
198843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Declare() call above).
198943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
19904f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    Scope* initialization_scope = is_const ? declaration_scope : top_scope_;
199143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Expression* value = NULL;
199243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int position = -1;
1993394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // Harmony consts have non-optional initializers.
1994394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    if (peek() == Token::ASSIGN || mode == CONST_HARMONY) {
199543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Expect(Token::ASSIGN, CHECK_OK);
199643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      position = scanner().location().beg_pos;
1997b645116853c677aca8a316381b87441ba6004f67danno@chromium.org      value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
199865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org      // Don't infer if it is "a = function(){...}();"-like expression.
199904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      if (fni_ != NULL &&
200004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org          value->AsCall() == NULL &&
200104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org          value->AsCallNew() == NULL) {
200204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org        fni_->Infer();
2003c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      } else {
2004c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        fni_->RemoveLastFunction();
200504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      }
2006394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      if (decl_props != NULL) *decl_props = kHasInitializers;
200743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
200843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2009c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    // Record the end position of the initializer.
2010c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    if (proxy->var() != NULL) {
2011c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org      proxy->var()->set_initializer_position(scanner().location().end_pos);
2012c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    }
2013c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
201480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org    // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
201580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org    if (value == NULL && needs_init) {
201643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      value = GetLiteralUndefined();
201743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
201843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
201943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Global variable declarations must be compiled in a specific
202043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // way. When the script containing the global variable declaration
202143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // is entered, the global variable must be declared, so that if it
2022ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    // doesn't exist (on the global object itself, see ES5 errata) it
202343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // gets created with an initial undefined value. This is handled
202443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // by the declarations part of the function representing the
202543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // top-level global code; see Runtime::DeclareGlobalVariable. If
202643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // it already exists (in the object or in a prototype), it is
202743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // *not* touched until the variable declaration statement is
202843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // executed.
202943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    //
203043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Executing the variable declaration statement will always
203143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // guarantee to give the global object a "local" variable; a
203243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // variable defined in the global object and not in any
203343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // prototype. This way, global variable declarations can shadow
203443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // properties in the prototype chain, but only after the variable
203543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // declaration statement has been executed. This is important in
203643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // browsers where the global object (window) has lots of
203743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // properties defined in prototype objects.
2038355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    if (initialization_scope->is_global_scope() &&
2039355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        !IsLexicalVariableMode(mode)) {
204043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Compute the arguments for the runtime call.
20417028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      ZoneList<Expression*>* arguments =
20427028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org          new(zone()) ZoneList<Expression*>(3, zone());
2043c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      // We have at least 1 parameter.
20447028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      arguments->Add(factory()->NewLiteral(name), zone());
204543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      CallRuntime* initialize;
20469ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
204743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (is_const) {
20487028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        arguments->Add(value, zone());
20499ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        value = NULL;  // zap the value to avoid the unnecessary assignment
20509ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
20519ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        // Construct the call to Runtime_InitializeConstGlobal
20529ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        // and add it to the initialization statement block.
20539ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        // Note that the function does different things depending on
20549ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        // the number of arguments (1 or 2).
2055b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        initialize = factory()->NewCallRuntime(
20564a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org            isolate()->factory()->InitializeConstGlobal_string(),
2057b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            Runtime::FunctionForId(Runtime::kInitializeConstGlobal),
2058b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            arguments);
205943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else {
20609ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        // Add strict mode.
20619ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        // We may want to pass singleton to avoid Literal allocations.
20621b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        LanguageMode language_mode = initialization_scope->language_mode();
20637028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        arguments->Add(factory()->NewNumberLiteral(language_mode), zone());
20649ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
20659ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        // Be careful not to assign a value to the global variable if
20669ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        // we're in a with. The initialization value should not
20679ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        // necessarily be stored in the global object in that case,
20689ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        // which is why we need to generate a separate assignment node.
20699ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        if (value != NULL && !inside_with()) {
20707028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org          arguments->Add(value, zone());
20719ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org          value = NULL;  // zap the value to avoid the unnecessary assignment
20729ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        }
20739ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
20749ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        // Construct the call to Runtime_InitializeVarGlobal
20759ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        // and add it to the initialization statement block.
20769ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        // Note that the function does different things depending on
20779ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        // the number of arguments (2 or 3).
2078b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        initialize = factory()->NewCallRuntime(
20794a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org            isolate()->factory()->InitializeVarGlobal_string(),
2080b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            Runtime::FunctionForId(Runtime::kInitializeVarGlobal),
2081b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            arguments);
208243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
20839ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
2084400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org      block->AddStatement(factory()->NewExpressionStatement(initialize),
2085400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org                          zone());
208627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    } else if (needs_init) {
208727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      // Constant initializations always assign to the declared constant which
208827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      // is always at the function scope level. This is only relevant for
208927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      // dynamically looked-up variables and constants (the start context for
209027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      // constant lookups is always the function context, while it is the top
209127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      // context for var declared variables). Sigh...
209227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      // For 'let' and 'const' declared variables in harmony mode the
209327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      // initialization also always assigns to the declared variable.
209427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      ASSERT(proxy != NULL);
209527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      ASSERT(proxy->var() != NULL);
209627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      ASSERT(value != NULL);
209727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      Assignment* assignment =
2098b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org          factory()->NewAssignment(init_op, proxy, value, position);
2099400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org      block->AddStatement(factory()->NewExpressionStatement(assignment),
2100400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org                          zone());
210127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      value = NULL;
210243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
210343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2104486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    // Add an assignment node to the initialization statement block if we still
210527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    // have a pending initialization value.
210643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (value != NULL) {
210727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      ASSERT(mode == VAR);
210827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      // 'var' initializations are simply assignments (with all the consequences
210927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      // if they are inside a 'with' statement - they may change a 'with' object
211027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      // property).
2111b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      VariableProxy* proxy =
211228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org          initialization_scope->NewUnresolved(factory(), name, interface);
2113c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      Assignment* assignment =
2114b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org          factory()->NewAssignment(init_op, proxy, value, position);
2115400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org      block->AddStatement(factory()->NewExpressionStatement(assignment),
2116400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org                          zone());
211743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
211865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
211965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    if (fni_ != NULL) fni_->Leave();
212043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } while (peek() == Token::COMMA);
212143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
21224f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // If there was a single non-const declaration, return it in the output
21234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // parameter for possible use by for/in.
21244f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if (nvars == 1 && !is_const) {
21254f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    *out = name;
212643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
212743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
212843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return block;
212943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
213043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
213143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
213243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic bool ContainsLabel(ZoneStringList* labels, Handle<String> label) {
213343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(!label.is_null());
213443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (labels != NULL)
213543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    for (int i = labels->length(); i-- > 0; )
213643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (labels->at(i).is_identical_to(label))
213743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        return true;
213843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
213943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return false;
214043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
214143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
214243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
214343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
214443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                                      bool* ok) {
214543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ExpressionStatement | LabelledStatement ::
214643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   Expression ';'
214743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   Identifier ':' Statement
214883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  bool starts_with_idenfifier = peek_any_identifier();
214943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expression* expr = ParseExpression(true, CHECK_OK);
21507b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
215143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      expr->AsVariableProxy() != NULL &&
215243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      !expr->AsVariableProxy()->is_this()) {
21534a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // Expression is a single identifier, and not, e.g., a parenthesized
21544a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    // identifier.
215543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    VariableProxy* var = expr->AsVariableProxy();
215643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Handle<String> label = var->name();
215743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // TODO(1240780): We don't check for redeclaration of labels
215843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // during preparsing since keeping track of the set of active
215943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // labels requires nontrivial changes to the way scopes are
216043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // structured.  However, these are probably changes we want to
216143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // make later anyway so we should go back and fix this then.
2162fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
216383e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org      SmartArrayPointer<char> c_string = label->ToCString(DISALLOW_NULLS);
2164fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org      const char* elms[2] = { "Label", *c_string };
2165fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org      Vector<const char*> args(elms, 2);
2166fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org      ReportMessage("redeclaration", args);
2167fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org      *ok = false;
2168fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org      return NULL;
216943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
21707028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    if (labels == NULL) {
21717028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      labels = new(zone()) ZoneStringList(4, zone());
21727028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    }
21737028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    labels->Add(label, zone());
2174fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    // Remove the "ghost" variable that turned out to be a label
2175fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    // from the top scope. This way, we don't try to resolve it
2176fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    // during the scope processing.
2177fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    top_scope_->RemoveUnresolved(var);
217843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Expect(Token::COLON, CHECK_OK);
217943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return ParseStatement(labels, ok);
218043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
218143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
21827b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // If we have an extension, we allow a native function declaration.
21837b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // A native function declaration starts with "native function" with
21847b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // no line-terminator between the two words.
21857b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  if (extension_ != NULL &&
21867b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      peek() == Token::FUNCTION &&
2187df8c03c138809b385f3cca5d424d7b2f8ad92527whesse@chromium.org      !scanner().HasAnyLineTerminatorBeforeNext() &&
21887b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      expr != NULL &&
21897b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      expr->AsVariableProxy() != NULL &&
21907b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      expr->AsVariableProxy()->name()->Equals(
21914a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org          isolate()->heap()->native_string()) &&
21927b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      !scanner().literal_contains_escapes()) {
21937b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    return ParseNativeDeclaration(ok);
21947b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
21957b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
2196a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org  // Parsed expression statement, or the context-sensitive 'module' keyword.
2197a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org  // Only expect semicolon in the former case.
2198a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org  if (!FLAG_harmony_modules ||
2199a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org      peek() != Token::IDENTIFIER ||
2200a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org      scanner().HasAnyLineTerminatorBeforeNext() ||
2201a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org      expr->AsVariableProxy() == NULL ||
2202a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org      !expr->AsVariableProxy()->name()->Equals(
22034a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org          isolate()->heap()->module_string()) ||
2204a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org      scanner().literal_contains_escapes()) {
2205a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org    ExpectSemicolon(CHECK_OK);
2206a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org  }
2207b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  return factory()->NewExpressionStatement(expr);
220843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
220943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
221043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
221143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenIfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) {
221243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // IfStatement ::
221343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'if' '(' Expression ')' Statement ('else' Statement)?
221443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
221543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::IF, CHECK_OK);
221643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::LPAREN, CHECK_OK);
221743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expression* condition = ParseExpression(true, CHECK_OK);
221843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::RPAREN, CHECK_OK);
221943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Statement* then_statement = ParseStatement(labels, CHECK_OK);
222043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Statement* else_statement = NULL;
222143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (peek() == Token::ELSE) {
222243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Next();
222343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    else_statement = ParseStatement(labels, CHECK_OK);
2224fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  } else {
2225b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    else_statement = factory()->NewEmptyStatement();
222643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
2227b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  return factory()->NewIfStatement(condition, then_statement, else_statement);
222843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
222943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
223043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
223143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseContinueStatement(bool* ok) {
223243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ContinueStatement ::
223343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'continue' Identifier? ';'
223443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
223543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::CONTINUE, CHECK_OK);
223668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  Handle<String> label = Handle<String>::null();
223743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Token::Value tok = peek();
2238df8c03c138809b385f3cca5d424d7b2f8ad92527whesse@chromium.org  if (!scanner().HasAnyLineTerminatorBeforeNext() &&
22399258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org      tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
224043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    label = ParseIdentifier(CHECK_OK);
224143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
224243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  IterationStatement* target = NULL;
2243fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  target = LookupContinueTarget(label, CHECK_OK);
2244fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  if (target == NULL) {
2245c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    // Illegal continue statement.
2246c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    const char* message = "illegal_continue";
2247c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    Vector<Handle<String> > args;
2248c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    if (!label.is_null()) {
2249c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      message = "unknown_label";
2250c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      args = Vector<Handle<String> >(&label, 1);
2251c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    }
2252c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    ReportMessageAt(scanner().location(), message, args);
2253c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    *ok = false;
2254c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    return NULL;
225543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
225643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ExpectSemicolon(CHECK_OK);
2257b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  return factory()->NewContinueStatement(target);
225843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
225943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
226043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
226143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) {
226243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // BreakStatement ::
226343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'break' Identifier? ';'
226443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
226543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::BREAK, CHECK_OK);
226643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<String> label;
226743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Token::Value tok = peek();
2268df8c03c138809b385f3cca5d424d7b2f8ad92527whesse@chromium.org  if (!scanner().HasAnyLineTerminatorBeforeNext() &&
22699258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org      tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
227043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    label = ParseIdentifier(CHECK_OK);
227143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
22723291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  // Parse labeled break statements that target themselves into
227343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // empty statements, e.g. 'l1: l2: l3: break l2;'
227443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!label.is_null() && ContainsLabel(labels, label)) {
2275b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    ExpectSemicolon(CHECK_OK);
2276b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    return factory()->NewEmptyStatement();
227743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
227843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  BreakableStatement* target = NULL;
2279fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  target = LookupBreakTarget(label, CHECK_OK);
2280fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  if (target == NULL) {
2281c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    // Illegal break statement.
2282c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    const char* message = "illegal_break";
2283c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    Vector<Handle<String> > args;
2284c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    if (!label.is_null()) {
2285c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      message = "unknown_label";
2286c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      args = Vector<Handle<String> >(&label, 1);
2287c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    }
2288c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    ReportMessageAt(scanner().location(), message, args);
2289c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    *ok = false;
2290c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    return NULL;
229143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
229243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ExpectSemicolon(CHECK_OK);
2293b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  return factory()->NewBreakStatement(target);
229443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
229543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
229643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
229743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseReturnStatement(bool* ok) {
229843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ReturnStatement ::
229943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'return' Expression? ';'
230043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
230143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Consume the return token. It is necessary to do the before
230243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // reporting any errors on it, because of the way errors are
230343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // reported (underlining).
230443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::RETURN, CHECK_OK);
230543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
230664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Token::Value tok = peek();
230764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Statement* result;
230877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  Expression* return_value;
230964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  if (scanner().HasAnyLineTerminatorBeforeNext() ||
231064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      tok == Token::SEMICOLON ||
231164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      tok == Token::RBRACE ||
231264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      tok == Token::EOS) {
231377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    return_value = GetLiteralUndefined();
231464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  } else {
231577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    return_value = ParseExpression(true, CHECK_OK);
231677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  }
231777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  ExpectSemicolon(CHECK_OK);
231877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (is_generator()) {
231977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    Expression* generator = factory()->NewVariableProxy(
232077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org        current_function_state_->generator_object_variable());
232177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    Expression* yield = factory()->NewYield(
232277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org        generator, return_value, Yield::FINAL, RelocInfo::kNoPosition);
232377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    result = factory()->NewExpressionStatement(yield);
232477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  } else {
232577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    result = factory()->NewReturnStatement(return_value);
232664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  }
232764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
232843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // An ECMAScript program is considered syntactically incorrect if it
232943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // contains a return statement that is not within the body of a
233043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // function. See ECMA-262, section 12.9, page 67.
233143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
233243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // To be consistent with KJS we report the syntax error at runtime.
23334f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  Scope* declaration_scope = top_scope_->DeclarationScope();
23344f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if (declaration_scope->is_global_scope() ||
23354f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      declaration_scope->is_eval_scope()) {
2336dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    Handle<String> message = isolate()->factory()->illegal_return_string();
2337dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    Expression* throw_error =
2338dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org        NewThrowSyntaxError(message, Handle<Object>::null());
2339b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    return factory()->NewExpressionStatement(throw_error);
234043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
234164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  return result;
234243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
234343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
234443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
234543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) {
234643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // WithStatement ::
234743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'with' '(' Expression ')' Statement
234843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
234943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::WITH, CHECK_OK);
23500a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
23511b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  if (!top_scope_->is_classic_mode()) {
23520a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    ReportMessage("strict_mode_with", Vector<const char*>::empty());
23530a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    *ok = false;
23540a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    return NULL;
23550a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  }
23560a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
235743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::LPAREN, CHECK_OK);
235843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expression* expr = ParseExpression(true, CHECK_OK);
235943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::RPAREN, CHECK_OK);
236043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
23614acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  top_scope_->DeclarationScope()->RecordWithStatement();
2362394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Scope* with_scope = NewScope(top_scope_, WITH_SCOPE);
2363394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Statement* stmt;
2364c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  { BlockState block_state(this, with_scope);
2365394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    with_scope->set_start_position(scanner().peek_location().beg_pos);
2366394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    stmt = ParseStatement(labels, CHECK_OK);
2367394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    with_scope->set_end_position(scanner().location().end_pos);
2368394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
2369ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  return factory()->NewWithStatement(with_scope, expr, stmt);
237043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
237143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
237243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
237343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenCaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
237443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // CaseClause ::
237543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'case' Expression ':' Statement*
237643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'default' ':' Statement*
237743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
237843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expression* label = NULL;  // NULL expression indicates default case
237943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (peek() == Token::CASE) {
238043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Expect(Token::CASE, CHECK_OK);
238143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    label = ParseExpression(true, CHECK_OK);
238243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
238343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Expect(Token::DEFAULT, CHECK_OK);
238443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (*default_seen_ptr) {
238543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      ReportMessage("multiple_defaults_in_switch",
238643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Vector<const char*>::empty());
238743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      *ok = false;
238843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return NULL;
238943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
239043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    *default_seen_ptr = true;
239143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
239243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::COLON, CHECK_OK);
2393a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int pos = scanner().location().beg_pos;
23947028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  ZoneList<Statement*>* statements =
23957028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      new(zone()) ZoneList<Statement*>(5, zone());
239643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (peek() != Token::CASE &&
239743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen         peek() != Token::DEFAULT &&
239843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen         peek() != Token::RBRACE) {
239943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Statement* stat = ParseStatement(NULL, CHECK_OK);
24007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    statements->Add(stat, zone());
240143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
240243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2403717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  return new(zone()) CaseClause(isolate(), label, statements, pos);
240443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
240543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
240643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
240743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenSwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels,
240843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                              bool* ok) {
240943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // SwitchStatement ::
241043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'switch' '(' Expression ')' '{' CaseClause* '}'
241143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2412b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  SwitchStatement* statement = factory()->NewSwitchStatement(labels);
2413e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  Target target(&this->target_stack_, statement);
241443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
241543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::SWITCH, CHECK_OK);
241643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::LPAREN, CHECK_OK);
241743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expression* tag = ParseExpression(true, CHECK_OK);
241843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::RPAREN, CHECK_OK);
241943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
242043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool default_seen = false;
24217028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4, zone());
242243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::LBRACE, CHECK_OK);
242343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (peek() != Token::RBRACE) {
242443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
24257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    cases->Add(clause, zone());
242643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
242743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::RBRACE, CHECK_OK);
242843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2429fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  if (statement) statement->Initialize(tag, cases);
243043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return statement;
243143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
243243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
243343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
243443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseThrowStatement(bool* ok) {
243543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ThrowStatement ::
243643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'throw' Expression ';'
243743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
243843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::THROW, CHECK_OK);
243943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int pos = scanner().location().beg_pos;
2440df8c03c138809b385f3cca5d424d7b2f8ad92527whesse@chromium.org  if (scanner().HasAnyLineTerminatorBeforeNext()) {
244143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ReportMessage("newline_after_throw", Vector<const char*>::empty());
244243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    *ok = false;
244343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return NULL;
244443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
244543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expression* exception = ParseExpression(true, CHECK_OK);
244643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ExpectSemicolon(CHECK_OK);
244743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2448b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  return factory()->NewExpressionStatement(factory()->NewThrow(exception, pos));
244943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
245043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
245143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
245243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenTryStatement* Parser::ParseTryStatement(bool* ok) {
245343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // TryStatement ::
245443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'try' Block Catch
245543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'try' Block Finally
245643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'try' Block Catch Finally
245743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
245843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Catch ::
245943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'catch' '(' Identifier ')' Block
246043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
246143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Finally ::
246243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'finally' Block
246343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
246443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::TRY, CHECK_OK);
246543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24667028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  TargetCollector try_collector(zone());
246743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Block* try_block;
246843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24696d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  { Target target(&this->target_stack_, &try_collector);
247043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    try_block = ParseBlock(NULL, CHECK_OK);
247143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
247243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
247343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Token::Value tok = peek();
247443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (tok != Token::CATCH && tok != Token::FINALLY) {
247543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ReportMessage("no_catch_or_finally", Vector<const char*>::empty());
247643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    *ok = false;
247743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return NULL;
247843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
247943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
248043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If we can break out from the catch block and there is a finally block,
24816d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  // then we will need to collect escaping targets from the catch
24826d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  // block. Since we don't know yet if there will be a finally block, we
24836d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  // always collect the targets.
24847028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  TargetCollector catch_collector(zone());
24854f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  Scope* catch_scope = NULL;
24864f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  Variable* catch_variable = NULL;
24876d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  Block* catch_block = NULL;
24886d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  Handle<String> name;
248943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (tok == Token::CATCH) {
249043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Consume(Token::CATCH);
249143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
249243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Expect(Token::LPAREN, CHECK_OK);
2493394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    catch_scope = NewScope(top_scope_, CATCH_SCOPE);
2494394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    catch_scope->set_start_position(scanner().location().beg_pos);
24956d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    name = ParseIdentifier(CHECK_OK);
24960a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
24971b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (!top_scope_->is_classic_mode() && IsEvalOrArguments(name)) {
24980a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      ReportMessage("strict_catch_variable", Vector<const char*>::empty());
24990a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      *ok = false;
25000a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      return NULL;
25010a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    }
25020a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
250343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Expect(Token::RPAREN, CHECK_OK);
250443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
250543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (peek() == Token::LBRACE) {
25064acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      Target target(&this->target_stack_, &catch_collector);
25071b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      VariableMode mode = is_extended_mode() ? LET : VAR;
2508c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      catch_variable =
2509c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          catch_scope->DeclareLocal(name, mode, kCreatedInitialized);
25104acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
2511c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org      BlockState block_state(this, catch_scope);
251255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      catch_block = ParseBlock(NULL, CHECK_OK);
251343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
251443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Expect(Token::LBRACE, CHECK_OK);
251543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
2516394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    catch_scope->set_end_position(scanner().location().end_pos);
251743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    tok = peek();
251843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
251943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25206d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  Block* finally_block = NULL;
25216d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  if (tok == Token::FINALLY || catch_block == NULL) {
252243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Consume(Token::FINALLY);
252343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    finally_block = ParseBlock(NULL, CHECK_OK);
252443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
252543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
252643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Simplify the AST nodes by converting:
25276d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  //   'try B0 catch B1 finally B2'
252843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // to:
25296d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  //   'try { try B0 catch B1 } finally B2'
253043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2531fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  if (catch_block != NULL && finally_block != NULL) {
25324f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    // If we have both, create an inner try/catch.
25334f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    ASSERT(catch_scope != NULL && catch_variable != NULL);
253404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org    int index = current_function_state_->NextHandlerIndex();
2535b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    TryCatchStatement* statement = factory()->NewTryCatchStatement(
2536b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        index, try_block, catch_scope, catch_variable, catch_block);
25376d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    statement->set_escaping_targets(try_collector.targets());
25385a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    try_block = factory()->NewBlock(NULL, 1, false);
2539400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org    try_block->AddStatement(statement, zone());
25404f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    catch_block = NULL;  // Clear to indicate it's been handled.
254143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
254243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
254343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  TryStatement* result = NULL;
2544fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  if (catch_block != NULL) {
2545fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    ASSERT(finally_block == NULL);
25464f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    ASSERT(catch_scope != NULL && catch_variable != NULL);
254704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org    int index = current_function_state_->NextHandlerIndex();
2548b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    result = factory()->NewTryCatchStatement(
2549b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        index, try_block, catch_scope, catch_variable, catch_block);
2550fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  } else {
2551fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    ASSERT(finally_block != NULL);
255204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org    int index = current_function_state_->NextHandlerIndex();
2553b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    result = factory()->NewTryFinallyStatement(index, try_block, finally_block);
25546d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    // Combine the jump targets of the try block and the possible catch block.
25557028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    try_collector.targets()->AddAll(*catch_collector.targets(), zone());
255643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
255743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25586d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  result->set_escaping_targets(try_collector.targets());
255943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
256043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
256143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
256243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25639d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comDoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels,
25649d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com                                                bool* ok) {
256543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // DoStatement ::
256643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'do' Statement 'while' '(' Expression ')' ';'
256743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2568b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  DoWhileStatement* loop = factory()->NewDoWhileStatement(labels);
2569e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  Target target(&this->target_stack_, loop);
257043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
257143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::DO, CHECK_OK);
257243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Statement* body = ParseStatement(NULL, CHECK_OK);
257343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::WHILE, CHECK_OK);
257443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::LPAREN, CHECK_OK);
2575c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2576c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  if (loop != NULL) {
2577c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    int position = scanner().location().beg_pos;
2578c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    loop->set_condition_position(position);
2579c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  }
2580c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
258143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expression* cond = ParseExpression(true, CHECK_OK);
258243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::RPAREN, CHECK_OK);
258343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
258443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allow do-statements to be terminated with and without
258543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // semi-colons. This allows code such as 'do;while(0)return' to
258643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // parse, which would not be the case if we had used the
258743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ExpectSemicolon() functionality here.
258843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
258943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25909d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (loop != NULL) loop->Initialize(cond, body);
259143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return loop;
259243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
259343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
259443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25959d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comWhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) {
259643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // WhileStatement ::
259743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'while' '(' Expression ')' Statement
259843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2599b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  WhileStatement* loop = factory()->NewWhileStatement(labels);
2600e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  Target target(&this->target_stack_, loop);
260143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
260243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::WHILE, CHECK_OK);
260343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::LPAREN, CHECK_OK);
260443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expression* cond = ParseExpression(true, CHECK_OK);
260543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::RPAREN, CHECK_OK);
260643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Statement* body = ParseStatement(NULL, CHECK_OK);
260743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26089d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (loop != NULL) loop->Initialize(cond, body);
260943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return loop;
261043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
261143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
261243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
261341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgbool Parser::CheckInOrOf(bool accept_OF,
261441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                         ForEachStatement::VisitMode* visit_mode) {
26151fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  if (Check(Token::IN)) {
26161fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    *visit_mode = ForEachStatement::ENUMERATE;
26171fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    return true;
261841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  } else if (allow_for_of() && accept_OF &&
261941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org             CheckContextualKeyword(CStrVector("of"))) {
26201fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    *visit_mode = ForEachStatement::ITERATE;
26211fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    return true;
26221fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  }
26231fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  return false;
26241fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org}
26251fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
26261fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
26271fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.orgvoid Parser::InitializeForEachStatement(ForEachStatement* stmt,
26281fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org                                        Expression* each,
26291fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org                                        Expression* subject,
26301fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org                                        Statement* body) {
26311fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  ForOfStatement* for_of = stmt->AsForOfStatement();
26321fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
26331fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  if (for_of != NULL) {
26341fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    Factory* heap_factory = isolate()->factory();
26351fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    Handle<String> iterator_str = heap_factory->InternalizeOneByteString(
26361fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org        STATIC_ASCII_VECTOR(".iterator"));
26371fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    Handle<String> result_str = heap_factory->InternalizeOneByteString(
26381fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org        STATIC_ASCII_VECTOR(".result"));
26391fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    Variable* iterator =
26401fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org        top_scope_->DeclarationScope()->NewTemporary(iterator_str);
26411fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    Variable* result = top_scope_->DeclarationScope()->NewTemporary(result_str);
26421fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
26431fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    Expression* assign_iterator;
26441fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    Expression* next_result;
26451fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    Expression* result_done;
26461fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    Expression* assign_each;
26471fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
26481fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    // var iterator = iterable;
26491fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    {
26501fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
26511fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      assign_iterator = factory()->NewAssignment(
26521fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org          Token::ASSIGN, iterator_proxy, subject, RelocInfo::kNoPosition);
26531fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    }
26541fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
26551fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    // var result = iterator.next();
26561fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    {
26571fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
26581fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      Expression* next_literal =
26591fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org          factory()->NewLiteral(heap_factory->next_string());
26601fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      Expression* next_property = factory()->NewProperty(
26611fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org          iterator_proxy, next_literal, RelocInfo::kNoPosition);
26621fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      ZoneList<Expression*>* next_arguments =
26631fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org          new(zone()) ZoneList<Expression*>(0, zone());
26641fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      Expression* next_call = factory()->NewCall(
26651fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org          next_property, next_arguments, RelocInfo::kNoPosition);
26661fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      Expression* result_proxy = factory()->NewVariableProxy(result);
26671fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      next_result = factory()->NewAssignment(
26681fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org          Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition);
26691fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    }
26701fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
26711fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    // result.done
26721fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    {
26731fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      Expression* done_literal =
26741fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org          factory()->NewLiteral(heap_factory->done_string());
26751fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      Expression* result_proxy = factory()->NewVariableProxy(result);
26761fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      result_done = factory()->NewProperty(
26771fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org          result_proxy, done_literal, RelocInfo::kNoPosition);
26781fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    }
26791fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
26801fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    // each = result.value
26811fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    {
26821fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      Expression* value_literal =
26831fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org          factory()->NewLiteral(heap_factory->value_string());
26841fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      Expression* result_proxy = factory()->NewVariableProxy(result);
26851fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      Expression* result_value = factory()->NewProperty(
26861fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org          result_proxy, value_literal, RelocInfo::kNoPosition);
26871fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      assign_each = factory()->NewAssignment(
26881fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org          Token::ASSIGN, each, result_value, RelocInfo::kNoPosition);
26891fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    }
26901fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
26911fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    for_of->Initialize(each, subject, body,
26921fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org                       assign_iterator, next_result, result_done, assign_each);
26931fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  } else {
26941fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    stmt->Initialize(each, subject, body);
26951fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  }
26961fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org}
26971fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
26981fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
269943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
270043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ForStatement ::
270143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
270243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
270343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Statement* init = NULL;
270443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2705394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Create an in-between scope for let-bound iteration variables.
2706394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Scope* saved_scope = top_scope_;
2707394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE);
2708394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  top_scope_ = for_scope;
2709394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
271043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::FOR, CHECK_OK);
271143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::LPAREN, CHECK_OK);
2712394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  for_scope->set_start_position(scanner().location().beg_pos);
271343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (peek() != Token::SEMICOLON) {
271443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (peek() == Token::VAR || peek() == Token::CONST) {
271528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org      bool is_const = peek() == Token::CONST;
27164f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      Handle<String> name;
271741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      VariableDeclarationProperties decl_props = kHasNoInitializers;
271843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Block* variable_statement =
271941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org          ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
272041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                                    CHECK_OK);
272141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      bool accept_OF = decl_props == kHasNoInitializers;
27221fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      ForEachStatement::VisitMode mode;
27234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
272441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) {
272528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org        Interface* interface =
272628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org            is_const ? Interface::NewConst() : Interface::NewValue();
27271fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org        ForEachStatement* loop = factory()->NewForEachStatement(mode, labels);
2728e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org        Target target(&this->target_stack_, loop);
272943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
273043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        Expression* enumerable = ParseExpression(true, CHECK_OK);
273143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        Expect(Token::RPAREN, CHECK_OK);
273243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
273333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org        VariableProxy* each =
273433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org            top_scope_->NewUnresolved(factory(), name, interface);
273543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        Statement* body = ParseStatement(NULL, CHECK_OK);
27361fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org        InitializeForEachStatement(loop, each, enumerable, body);
27375a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        Block* result = factory()->NewBlock(NULL, 2, false);
2738400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org        result->AddStatement(variable_statement, zone());
2739400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org        result->AddStatement(loop, zone());
2740394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        top_scope_ = saved_scope;
2741394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        for_scope->set_end_position(scanner().location().end_pos);
2742394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        for_scope = for_scope->FinalizeBlockScope();
2743394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        ASSERT(for_scope == NULL);
2744fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org        // Parsed for-in loop w/ variable/const declaration.
2745fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org        return result;
274643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else {
274743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        init = variable_statement;
274843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
2749394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    } else if (peek() == Token::LET) {
2750394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      Handle<String> name;
2751394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      VariableDeclarationProperties decl_props = kHasNoInitializers;
2752394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      Block* variable_statement =
2753812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org         ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
2754812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org                                   CHECK_OK);
2755394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      bool accept_IN = !name.is_null() && decl_props != kHasInitializers;
275641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      bool accept_OF = decl_props == kHasNoInitializers;
27571fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      ForEachStatement::VisitMode mode;
27581fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
275941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      if (accept_IN && CheckInOrOf(accept_OF, &mode)) {
2760394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        // Rewrite a for-in statement of the form
2761394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        //
2762394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        //   for (let x in e) b
2763394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        //
2764394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        // into
2765394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        //
2766394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        //   <let x' be a temporary variable>
2767394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        //   for (x' in e) {
2768394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        //     let x;
2769394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        //     x = x';
2770394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        //     b;
2771394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        //   }
2772394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
2773394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        // TODO(keuchel): Move the temporary variable to the block scope, after
2774394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        // implementing stack allocated block scoped variables.
277533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org        Factory* heap_factory = isolate()->factory();
277633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org        Handle<String> tempstr =
27774a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org            heap_factory->NewConsString(heap_factory->dot_for_string(), name);
27784a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        Handle<String> tempname = heap_factory->InternalizeString(tempstr);
277933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org        Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname);
2780b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
27811fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org        ForEachStatement* loop = factory()->NewForEachStatement(mode, labels);
2782394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        Target target(&this->target_stack_, loop);
2783394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
278433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org        // The expression does not see the loop variable.
278533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org        top_scope_ = saved_scope;
2786394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        Expression* enumerable = ParseExpression(true, CHECK_OK);
278733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org        top_scope_ = for_scope;
2788394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        Expect(Token::RPAREN, CHECK_OK);
278943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
279033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org        VariableProxy* each =
279133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org            top_scope_->NewUnresolved(factory(), name, Interface::NewValue());
2792394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        Statement* body = ParseStatement(NULL, CHECK_OK);
27935a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        Block* body_block = factory()->NewBlock(NULL, 3, false);
2794b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        Assignment* assignment = factory()->NewAssignment(
2795b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition);
2796394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        Statement* assignment_statement =
2797b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            factory()->NewExpressionStatement(assignment);
2798400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org        body_block->AddStatement(variable_statement, zone());
2799400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org        body_block->AddStatement(assignment_statement, zone());
2800400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org        body_block->AddStatement(body, zone());
28011fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org        InitializeForEachStatement(loop, temp_proxy, enumerable, body_block);
2802394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        top_scope_ = saved_scope;
2803394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        for_scope->set_end_position(scanner().location().end_pos);
2804394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        for_scope = for_scope->FinalizeBlockScope();
2805ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        body_block->set_scope(for_scope);
2806394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        // Parsed for-in loop w/ let declaration.
2807394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        return loop;
2808394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
2809394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      } else {
2810394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        init = variable_statement;
2811394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      }
281243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
281343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Expression* expression = ParseExpression(false, CHECK_OK);
28141fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      ForEachStatement::VisitMode mode;
281541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      bool accept_OF = expression->AsVariableProxy();
28161fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
281741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      if (CheckInOrOf(accept_OF, &mode)) {
2818c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org        // Signal a reference error if the expression is an invalid
2819c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org        // left-hand side expression.  We could report this as a syntax
2820c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org        // error here but for compatibility with JSC we choose to report
2821c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org        // the error at runtime.
282243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        if (expression == NULL || !expression->IsValidLeftHandSide()) {
2823dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org          Handle<String> message =
28244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org              isolate()->factory()->invalid_lhs_in_for_in_string();
2825dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org          expression = NewThrowReferenceError(message);
282643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
28271fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org        ForEachStatement* loop = factory()->NewForEachStatement(mode, labels);
2828e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org        Target target(&this->target_stack_, loop);
282943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
283043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        Expression* enumerable = ParseExpression(true, CHECK_OK);
283143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        Expect(Token::RPAREN, CHECK_OK);
283243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
283343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        Statement* body = ParseStatement(NULL, CHECK_OK);
28341fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org        InitializeForEachStatement(loop, expression, enumerable, body);
2835394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        top_scope_ = saved_scope;
2836394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        for_scope->set_end_position(scanner().location().end_pos);
2837394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        for_scope = for_scope->FinalizeBlockScope();
2838394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        ASSERT(for_scope == NULL);
283943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        // Parsed for-in loop.
284043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        return loop;
284143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
284243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else {
2843b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        init = factory()->NewExpressionStatement(expression);
284443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
284543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
284643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
284743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
284843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Standard 'for' loop
2849b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  ForStatement* loop = factory()->NewForStatement(labels);
2850e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  Target target(&this->target_stack_, loop);
285143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
285243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Parsed initializer at this point.
285343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::SEMICOLON, CHECK_OK);
285443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
285543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expression* cond = NULL;
285643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (peek() != Token::SEMICOLON) {
285743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    cond = ParseExpression(true, CHECK_OK);
285843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
285943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::SEMICOLON, CHECK_OK);
286043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
286143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Statement* next = NULL;
286243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (peek() != Token::RPAREN) {
286343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Expression* exp = ParseExpression(true, CHECK_OK);
2864b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    next = factory()->NewExpressionStatement(exp);
286543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
286643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::RPAREN, CHECK_OK);
286743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
286843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Statement* body = ParseStatement(NULL, CHECK_OK);
2869394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  top_scope_ = saved_scope;
2870394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  for_scope->set_end_position(scanner().location().end_pos);
2871394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  for_scope = for_scope->FinalizeBlockScope();
2872394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (for_scope != NULL) {
2873394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // Rewrite a for statement of the form
2874394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    //
2875394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    //   for (let x = i; c; n) b
2876394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    //
2877394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // into
2878394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    //
2879394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    //   {
2880394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    //     let x = i;
2881394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    //     for (; c; n) b
2882394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    //   }
2883394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    ASSERT(init != NULL);
28845a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    Block* result = factory()->NewBlock(NULL, 2, false);
2885400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org    result->AddStatement(init, zone());
2886400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org    result->AddStatement(loop, zone());
2887ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    result->set_scope(for_scope);
28881fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    loop->Initialize(NULL, cond, next, body);
2889394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    return result;
2890394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  } else {
28911fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    loop->Initialize(init, cond, next, body);
2892394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    return loop;
2893394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
289443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
289543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
289643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
289743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Precedence = 1
289843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseExpression(bool accept_IN, bool* ok) {
289943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Expression ::
290043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   AssignmentExpression
290143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   Expression ',' AssignmentExpression
290243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
290343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK);
290443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (peek() == Token::COMMA) {
290543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Expect(Token::COMMA, CHECK_OK);
290665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    int position = scanner().location().beg_pos;
290743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
2908b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    result =
2909b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        factory()->NewBinaryOperation(Token::COMMA, result, right, position);
291043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
291143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
291243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
291343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
291443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
291543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Precedence = 2
291643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
291743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // AssignmentExpression ::
291843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   ConditionalExpression
2919f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  //   YieldExpression
292043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   LeftHandSideExpression AssignmentOperator AssignmentExpression
292143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2922f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  if (peek() == Token::YIELD && is_generator()) {
2923f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    return ParseYieldExpression(ok);
2924f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  }
2925f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
292665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  if (fni_ != NULL) fni_->Enter();
292743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK);
292843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
292943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!Token::IsAssignmentOp(peek())) {
293065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    if (fni_ != NULL) fni_->Leave();
293143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Parsed conditional expression only (no assignment).
293243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return expression;
293343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
293443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2935c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  // Signal a reference error if the expression is an invalid left-hand
2936c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  // side expression.  We could report this as a syntax error here but
2937c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  // for compatibility with JSC we choose to report the error at
2938c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  // runtime.
2939a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // TODO(ES5): Should change parsing for spec conformance.
294043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (expression == NULL || !expression->IsValidLeftHandSide()) {
2941dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    Handle<String> message =
29424a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        isolate()->factory()->invalid_lhs_in_assignment_string();
2943dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    expression = NewThrowReferenceError(message);
294443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
294543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
29461b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  if (!top_scope_->is_classic_mode()) {
2947378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    // Assignment to eval or arguments is disallowed in strict mode.
2948378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK);
2949378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
295064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  MarkAsLValue(expression);
2951378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
295243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Token::Value op = Next();  // Get assignment operator.
295343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int pos = scanner().location().beg_pos;
295443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
295543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
295643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // TODO(1231235): We try to estimate the set of properties set by
295743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // constructors. We define a new property whenever there is an
295843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // assignment to a property of 'this'. We should probably only add
295943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // properties if we haven't seen them before. Otherwise we'll
296043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // probably overestimate the number of properties.
296143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Property* property = expression ? expression->AsProperty() : NULL;
296243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (op == Token::ASSIGN &&
296343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      property != NULL &&
296443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      property->obj()->AsVariableProxy() != NULL &&
296543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      property->obj()->AsVariableProxy()->is_this()) {
2966c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    current_function_state_->AddProperty();
296743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
296843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
296921b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org  // If we assign a function literal to a property we pretenure the
297021b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org  // literal so it can be added as a constant function property.
297121b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org  if (property != NULL && right->AsFunctionLiteral() != NULL) {
2972c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    right->AsFunctionLiteral()->set_pretenure();
297321b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org  }
297421b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org
297565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  if (fni_ != NULL) {
297665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    // Check if the right hand side is a call to avoid inferring a
297765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    // name if we're dealing with "a = function(){...}();"-like
297865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    // expression.
297965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    if ((op == Token::INIT_VAR
298065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org         || op == Token::INIT_CONST
298165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org         || op == Token::ASSIGN)
298204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org        && (right->AsCall() == NULL && right->AsCallNew() == NULL)) {
298365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org      fni_->Infer();
2984c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    } else {
2985c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      fni_->RemoveLastFunction();
298665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    }
298765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    fni_->Leave();
298865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  }
298965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
2990b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  return factory()->NewAssignment(op, expression, right, pos);
299143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
299243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
299343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2994f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgExpression* Parser::ParseYieldExpression(bool* ok) {
2995f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  // YieldExpression ::
2996f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  //   'yield' '*'? AssignmentExpression
2997f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  int position = scanner().peek_location().beg_pos;
2998f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  Expect(Token::YIELD, CHECK_OK);
299977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  Yield::Kind kind =
300077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org      Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND;
3001e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Expression* generator_object = factory()->NewVariableProxy(
3002e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      current_function_state_->generator_object_variable());
3003f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  Expression* expression = ParseAssignmentExpression(false, CHECK_OK);
30044e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  Yield* yield =
30054e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      factory()->NewYield(generator_object, expression, kind, position);
30064e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  if (kind == Yield::DELEGATING) {
30074e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    yield->set_index(current_function_state_->NextHandlerIndex());
30084e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
30094e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  return yield;
3010f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org}
3011f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
3012f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
301343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Precedence = 3
301443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) {
301543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ConditionalExpression ::
301643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   LogicalOrExpression
301743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
301843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
301943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // We start using the binary expression parser for prec >= 4 only!
302043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
302143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (peek() != Token::CONDITIONAL) return expression;
302243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Consume(Token::CONDITIONAL);
302343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // In parsing the first assignment expression in conditional
302443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // expressions we always accept the 'in' keyword; see ECMA-262,
302543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // section 11.12, page 58.
30262356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  int left_position = scanner().peek_location().beg_pos;
302743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expression* left = ParseAssignmentExpression(true, CHECK_OK);
302843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::COLON, CHECK_OK);
30292356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  int right_position = scanner().peek_location().beg_pos;
303043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
3031b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  return factory()->NewConditional(
3032b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      expression, left, right, left_position, right_position);
303343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
303443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
303543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
303643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic int Precedence(Token::Value tok, bool accept_IN) {
303743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (tok == Token::IN && !accept_IN)
303843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return 0;  // 0 precedence will terminate binary expression parsing
303943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
304043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return Token::Precedence(tok);
304143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
304243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
304343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
304443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Precedence >= 4
304543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
304643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(prec >= 4);
304743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expression* x = ParseUnaryExpression(CHECK_OK);
304843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
304943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // prec1 >= 4
305043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    while (Precedence(peek(), accept_IN) == prec1) {
305143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Token::Value op = Next();
305265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org      int position = scanner().location().beg_pos;
305343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
305443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
305543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Compute some expressions involving only number literals.
30561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      if (x && x->AsLiteral() && x->AsLiteral()->value()->IsNumber() &&
30571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          y && y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) {
30581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        double x_val = x->AsLiteral()->value()->Number();
30591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        double y_val = y->AsLiteral()->value()->Number();
306043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
306143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        switch (op) {
306243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          case Token::ADD:
3063b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            x = factory()->NewNumberLiteral(x_val + y_val);
306443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            continue;
306543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          case Token::SUB:
3066b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            x = factory()->NewNumberLiteral(x_val - y_val);
306743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            continue;
306843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          case Token::MUL:
3069b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            x = factory()->NewNumberLiteral(x_val * y_val);
307043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            continue;
307143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          case Token::DIV:
3072b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            x = factory()->NewNumberLiteral(x_val / y_val);
307343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            continue;
3074b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org          case Token::BIT_OR: {
3075b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
3076b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            x = factory()->NewNumberLiteral(value);
307743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            continue;
3078b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org          }
3079b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org          case Token::BIT_AND: {
3080b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
3081b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            x = factory()->NewNumberLiteral(value);
308243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            continue;
3083b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org          }
3084b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org          case Token::BIT_XOR: {
3085b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
3086b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            x = factory()->NewNumberLiteral(value);
308743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            continue;
3088b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org          }
308943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          case Token::SHL: {
309043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
3091b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            x = factory()->NewNumberLiteral(value);
309243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            continue;
309343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          }
309443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          case Token::SHR: {
309543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            uint32_t shift = DoubleToInt32(y_val) & 0x1f;
309643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            uint32_t value = DoubleToUint32(x_val) >> shift;
3097b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            x = factory()->NewNumberLiteral(value);
309843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            continue;
309943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          }
310043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          case Token::SAR: {
310143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            uint32_t shift = DoubleToInt32(y_val) & 0x1f;
310243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
3103b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            x = factory()->NewNumberLiteral(value);
310443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            continue;
310543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          }
310643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          default:
310743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            break;
310843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
310943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
311043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
311143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // For now we distinguish between comparisons and other binary
311243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // operations.  (We could combine the two and get rid of this
311365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org      // code and AST node eventually.)
311443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (Token::IsCompareOp(op)) {
311543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        // We have a comparison.
311643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        Token::Value cmp = op;
311743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        switch (op) {
311843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          case Token::NE: cmp = Token::EQ; break;
311943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
312043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          default: break;
312143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
3122b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        x = factory()->NewCompareOperation(cmp, x, y, position);
312343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        if (cmp != op) {
312443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          // The comparison was negated - add a NOT.
3125b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org          x = factory()->NewUnaryOperation(Token::NOT, x, position);
312643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
312743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
312843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else {
312943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        // We have a "normal" binary operation.
3130b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        x = factory()->NewBinaryOperation(op, x, y, position);
313143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
313243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
313343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
313443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return x;
313543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
313643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
313743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
313843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseUnaryExpression(bool* ok) {
313943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // UnaryExpression ::
314043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   PostfixExpression
314143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'delete' UnaryExpression
314243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'void' UnaryExpression
314343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'typeof' UnaryExpression
314443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   '++' UnaryExpression
314543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   '--' UnaryExpression
314643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   '+' UnaryExpression
314743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   '-' UnaryExpression
314843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   '~' UnaryExpression
314943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   '!' UnaryExpression
315043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
315143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Token::Value op = peek();
315243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (Token::IsUnaryOp(op)) {
315343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    op = Next();
31548e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    int position = scanner().location().beg_pos;
3155c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    Expression* expression = ParseUnaryExpression(CHECK_OK);
315643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31577b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    if (expression != NULL && (expression->AsLiteral() != NULL)) {
31581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      Handle<Object> literal = expression->AsLiteral()->value();
31597b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      if (op == Token::NOT) {
31607b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        // Convert the literal to a boolean condition and negate it.
31619faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org        bool condition = literal->BooleanValue();
3162fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        Handle<Object> result(isolate()->heap()->ToBoolean(!condition),
3163fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                              isolate());
3164b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        return factory()->NewLiteral(result);
31657b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      } else if (literal->IsNumber()) {
31667b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        // Compute some expressions involving only number literals.
31677b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        double value = literal->Number();
31687b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        switch (op) {
31697b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          case Token::ADD:
31707b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org            return expression;
31717b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          case Token::SUB:
3172b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            return factory()->NewNumberLiteral(-value);
31737b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          case Token::BIT_NOT:
3174b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            return factory()->NewNumberLiteral(~DoubleToInt32(value));
31757b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          default:
31767b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org            break;
31777b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        }
317843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
317943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
318043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
318149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    // "delete identifier" is a syntax error in strict mode.
31821b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (op == Token::DELETE && !top_scope_->is_classic_mode()) {
318349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org      VariableProxy* operand = expression->AsVariableProxy();
318449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org      if (operand != NULL && !operand->is_this()) {
318549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org        ReportMessage("strict_delete", Vector<const char*>::empty());
318649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org        *ok = false;
318749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org        return NULL;
318849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org      }
318949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    }
319049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
3191b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    // Desugar '+foo' into 'foo*1', this enables the collection of type feedback
3192b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    // without any special stub and the multiplication is removed later in
3193b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    // Crankshaft's canonicalization pass.
3194b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    if (op == Token::ADD) {
3195b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      return factory()->NewBinaryOperation(Token::MUL,
3196b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org                                           expression,
3197b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org                                           factory()->NewNumberLiteral(1),
3198b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org                                           position);
3199b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    }
3200594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // The same idea for '-foo' => 'foo*(-1)'.
3201594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (op == Token::SUB) {
3202594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      return factory()->NewBinaryOperation(Token::MUL,
3203594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                           expression,
3204594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                           factory()->NewNumberLiteral(-1),
3205594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                           position);
3206594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
3207594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // ...and one more time for '~foo' => 'foo^(~0)'.
3208594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (op == Token::BIT_NOT) {
3209594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      return factory()->NewBinaryOperation(Token::BIT_XOR,
3210594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                           expression,
3211594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                           factory()->NewNumberLiteral(~0),
3212594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                           position);
3213594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
3214b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
3215b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    return factory()->NewUnaryOperation(op, expression, position);
321643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
321743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (Token::IsCountOp(op)) {
321843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    op = Next();
3219c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    Expression* expression = ParseUnaryExpression(CHECK_OK);
3220c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    // Signal a reference error if the expression is an invalid
3221c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    // left-hand side expression.  We could report this as a syntax
3222c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    // error here but for compatibility with JSC we choose to report the
3223c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    // error at runtime.
3224c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    if (expression == NULL || !expression->IsValidLeftHandSide()) {
3225dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      Handle<String> message =
32264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org          isolate()->factory()->invalid_lhs_in_prefix_op_string();
3227dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      expression = NewThrowReferenceError(message);
322843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
3229378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
32301b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (!top_scope_->is_classic_mode()) {
3231378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      // Prefix expression operand in strict mode may not be eval or arguments.
3232378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
3233378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    }
323464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    MarkAsLValue(expression);
3235378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
323665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    int position = scanner().location().beg_pos;
3237b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    return factory()->NewCountOperation(op,
3238b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                        true /* prefix */,
3239b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                        expression,
3240b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                        position);
324143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
324243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
324343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return ParsePostfixExpression(ok);
324443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
324543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
324643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
324743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
324843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParsePostfixExpression(bool* ok) {
324943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // PostfixExpression ::
325043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   LeftHandSideExpression ('++' | '--')?
325143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3252c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  Expression* expression = ParseLeftHandSideExpression(CHECK_OK);
3253df8c03c138809b385f3cca5d424d7b2f8ad92527whesse@chromium.org  if (!scanner().HasAnyLineTerminatorBeforeNext() &&
32545f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org      Token::IsCountOp(peek())) {
3255c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    // Signal a reference error if the expression is an invalid
3256c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    // left-hand side expression.  We could report this as a syntax
3257c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    // error here but for compatibility with JSC we choose to report the
3258c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    // error at runtime.
3259c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    if (expression == NULL || !expression->IsValidLeftHandSide()) {
3260dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      Handle<String> message =
32614a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org          isolate()->factory()->invalid_lhs_in_postfix_op_string();
3262dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      expression = NewThrowReferenceError(message);
326343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
3264378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
32651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (!top_scope_->is_classic_mode()) {
3266378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      // Postfix expression operand in strict mode may not be eval or arguments.
3267378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
3268378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    }
326964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    MarkAsLValue(expression);
3270378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
327143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Token::Value next = Next();
327265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    int position = scanner().location().beg_pos;
3273c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    expression =
3274b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        factory()->NewCountOperation(next,
3275b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                     false /* postfix */,
3276b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                     expression,
3277b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                     position);
327843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
3279c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  return expression;
328043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
328143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
328243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
328343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseLeftHandSideExpression(bool* ok) {
328443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // LeftHandSideExpression ::
328543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   (NewExpression | MemberExpression) ...
328643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
328743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expression* result;
328843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (peek() == Token::NEW) {
328943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    result = ParseNewExpression(CHECK_OK);
329043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
329143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    result = ParseMemberExpression(CHECK_OK);
329243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
329343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
329443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (true) {
329543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    switch (peek()) {
329643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      case Token::LBRACK: {
329743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        Consume(Token::LBRACK);
329843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        int pos = scanner().location().beg_pos;
329943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        Expression* index = ParseExpression(true, CHECK_OK);
3300b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        result = factory()->NewProperty(result, index, pos);
330143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        Expect(Token::RBRACK, CHECK_OK);
330243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        break;
330343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
330443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
330543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      case Token::LPAREN: {
3306f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        int pos;
3307f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        if (scanner().current_token() == Token::IDENTIFIER) {
3308f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com          // For call of an identifier we want to report position of
3309f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com          // the identifier as position of the call in the stack trace.
3310f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com          pos = scanner().location().beg_pos;
3311f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        } else {
3312f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com          // For other kinds of calls we record position of the parenthesis as
3313f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com          // position of the call.  Note that this is extremely important for
3314f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com          // expressions of the form function(){...}() for which call position
3315f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com          // should not point to the closing brace otherwise it will intersect
3316f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com          // with positions recorded for function literal and confuse debugger.
3317f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com          pos = scanner().peek_location().beg_pos;
3318de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org          // Also the trailing parenthesis are a hint that the function will
3319de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org          // be called immediately. If we happen to have parsed a preceding
3320de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org          // function literal eagerly, we can also compile it eagerly.
3321de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org          if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
3322de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org            result->AsFunctionLiteral()->set_parenthesized();
3323de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org          }
3324f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        }
332543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
332643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
332743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        // Keep track of eval() calls since they disable all local variable
3328a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        // optimizations.
3329a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        // The calls that need special treatment are the
3330c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // direct eval calls. These calls are all of the form eval(...), with
3331c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // no explicit receiver.
3332c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org        // These calls are marked as potentially direct eval calls. Whether
3333c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org        // they are actually direct calls to eval is determined at run time.
3334fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org        VariableProxy* callee = result->AsVariableProxy();
3335ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        if (callee != NULL &&
33364a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org            callee->IsVariable(isolate()->factory()->eval_string())) {
3337c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          top_scope_->DeclarationScope()->RecordEvalCall();
333843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
3339b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        result = factory()->NewCall(result, args, pos);
334079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org        if (fni_ != NULL) fni_->RemoveLastFunction();
334143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        break;
334243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
334343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
334443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      case Token::PERIOD: {
334543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        Consume(Token::PERIOD);
334643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        int pos = scanner().location().beg_pos;
3347d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org        Handle<String> name = ParseIdentifierName(CHECK_OK);
3348b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        result =
3349b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            factory()->NewProperty(result, factory()->NewLiteral(name), pos);
335065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org        if (fni_ != NULL) fni_->PushLiteralName(name);
335143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        break;
335243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
335343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
335443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      default:
335543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        return result;
335643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
335743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
335843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
335943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
336043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3361b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgExpression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) {
336243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // NewExpression ::
336343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   ('new')+ MemberExpression
336443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
336543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // The grammar for new expressions is pretty warped. The keyword
336643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // 'new' can either be a part of the new expression (where it isn't
336743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // followed by an argument list) or a part of the member expression,
336843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // where it must be followed by an argument list. To accommodate
336943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // this, we parse the 'new' keywords greedily and keep track of how
337043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // many we have parsed. This information is then passed on to the
337143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // member expression parser, which is only allowed to match argument
337243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // lists as long as it has 'new' prefixes left
3373b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  Expect(Token::NEW, CHECK_OK);
3374b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  PositionStack::Element pos(stack, scanner().location().beg_pos);
3375b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
3376b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  Expression* result;
3377b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  if (peek() == Token::NEW) {
3378b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    result = ParseNewPrefix(stack, CHECK_OK);
3379b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  } else {
3380b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK);
338143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
338243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3383b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  if (!stack->is_empty()) {
3384b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    int last = stack->pop();
3385b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    result = factory()->NewCallNew(
33867028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        result, new(zone()) ZoneList<Expression*>(0, zone()), last);
338743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
338843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
338943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
339043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
339143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3392b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgExpression* Parser::ParseNewExpression(bool* ok) {
3393b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  PositionStack stack(ok);
3394b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  return ParseNewPrefix(&stack, ok);
3395b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org}
3396b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
3397b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
339843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseMemberExpression(bool* ok) {
3399b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  return ParseMemberWithNewPrefixesExpression(NULL, ok);
340043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
340143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
340243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3403b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgExpression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
3404b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org                                                         bool* ok) {
340543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // MemberExpression ::
340643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   (PrimaryExpression | FunctionLiteral)
340743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //     ('[' Expression ']' | '.' Identifier | Arguments)*
340843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
340943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Parse the initial primary or function expression.
341043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expression* result = NULL;
341143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (peek() == Token::FUNCTION) {
341243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Expect(Token::FUNCTION, CHECK_OK);
341343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int function_token_position = scanner().location().beg_pos;
3414e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    bool is_generator = allow_generators() && Check(Token::MUL);
341543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Handle<String> name;
341604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    bool is_strict_reserved_name = false;
341783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    if (peek_any_identifier()) {
341804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
341904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org                                                 CHECK_OK);
342083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    }
3421dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    FunctionLiteral::FunctionType function_type = name.is_null()
34227c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        ? FunctionLiteral::ANONYMOUS_EXPRESSION
34237c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        : FunctionLiteral::NAMED_EXPRESSION;
34247c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org    result = ParseFunctionLiteral(name,
34257c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org                                  is_strict_reserved_name,
3426f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                                  is_generator,
34277c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org                                  function_token_position,
3428dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                                  function_type,
34297c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org                                  CHECK_OK);
343043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
343143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    result = ParsePrimaryExpression(CHECK_OK);
343243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
343343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
343443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (true) {
343543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    switch (peek()) {
343643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      case Token::LBRACK: {
343743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        Consume(Token::LBRACK);
343843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        int pos = scanner().location().beg_pos;
343943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        Expression* index = ParseExpression(true, CHECK_OK);
3440b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        result = factory()->NewProperty(result, index, pos);
344104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org        if (fni_ != NULL) {
344204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org          if (index->IsPropertyName()) {
344304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org            fni_->PushLiteralName(index->AsLiteral()->AsPropertyName());
344404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org          } else {
344504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org            fni_->PushLiteralName(
34464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org                isolate()->factory()->anonymous_function_string());
344704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org          }
344804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org        }
344943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        Expect(Token::RBRACK, CHECK_OK);
345043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        break;
345143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
345243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      case Token::PERIOD: {
345343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        Consume(Token::PERIOD);
345443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        int pos = scanner().location().beg_pos;
3455d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org        Handle<String> name = ParseIdentifierName(CHECK_OK);
3456b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        result =
3457b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            factory()->NewProperty(result, factory()->NewLiteral(name), pos);
345865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org        if (fni_ != NULL) fni_->PushLiteralName(name);
345943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        break;
346043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
346143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      case Token::LPAREN: {
3462b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org        if ((stack == NULL) || stack->is_empty()) return result;
346343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        // Consume one of the new prefixes (already parsed).
346443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
3465b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org        int last = stack->pop();
3466b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        result = factory()->NewCallNew(result, args, last);
346743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        break;
346843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
346943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      default:
347043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        return result;
347143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
347243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
347343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
347443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
347543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
347643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenDebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
347743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
347843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // contexts this is used as a statement which invokes the debugger as i a
347943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // break point is present.
348043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // DebuggerStatement ::
348143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'debugger' ';'
348243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
348343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::DEBUGGER, CHECK_OK);
348443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ExpectSemicolon(CHECK_OK);
3485b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  return factory()->NewDebuggerStatement();
348643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
348743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
348843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
348943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Parser::ReportUnexpectedToken(Token::Value token) {
349043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // We don't report stack overflows here, to avoid increasing the
349143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // stack depth even further.  Instead we report it after parsing is
3492b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // over, in ParseProgram/ParseJson.
3493a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (token == Token::ILLEGAL && stack_overflow_) return;
349443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Four of the tokens are treated specially
349543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  switch (token) {
3496a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Token::EOS:
3497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return ReportMessage("unexpected_eos", Vector<const char*>::empty());
3498a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Token::NUMBER:
3499a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return ReportMessage("unexpected_token_number",
3500a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                           Vector<const char*>::empty());
3501a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Token::STRING:
3502a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return ReportMessage("unexpected_token_string",
3503a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                           Vector<const char*>::empty());
3504a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Token::IDENTIFIER:
3505a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return ReportMessage("unexpected_token_identifier",
3506a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                           Vector<const char*>::empty());
350783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    case Token::FUTURE_RESERVED_WORD:
350804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      return ReportMessage("unexpected_reserved",
350904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org                           Vector<const char*>::empty());
3510f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    case Token::YIELD:
351104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    case Token::FUTURE_STRICT_RESERVED_WORD:
35121b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      return ReportMessage(top_scope_->is_classic_mode() ?
35131b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                               "unexpected_token_identifier" :
35141b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                               "unexpected_strict_reserved",
351583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                           Vector<const char*>::empty());
3516a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    default:
3517a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      const char* name = Token::String(token);
3518a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      ASSERT(name != NULL);
3519a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      ReportMessage("unexpected_token", Vector<const char*>(&name, 1));
352043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
352143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
352243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
352343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
35244a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.comvoid Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) {
352583e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS);
35264a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  const char* element[1] = { *name_string };
35274a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  ReportMessage("invalid_preparser_data",
35284a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com                Vector<const char*>(element, 1));
35294a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  *ok = false;
35304a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com}
35314a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
35324a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
353343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParsePrimaryExpression(bool* ok) {
353443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // PrimaryExpression ::
353543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'this'
353643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'null'
353743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'true'
353843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   'false'
353943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   Identifier
354043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   Number
354143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   String
354243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   ArrayLiteral
354343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   ObjectLiteral
354443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   RegExpLiteral
354543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   '(' Expression ')'
354643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
354743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expression* result = NULL;
354843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  switch (peek()) {
354943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::THIS: {
355043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Consume(Token::THIS);
3551b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      result = factory()->NewVariableProxy(top_scope_->receiver());
355243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
355343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
355443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
355543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::NULL_LITERAL:
355643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Consume(Token::NULL_LITERAL);
3557b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      result = factory()->NewLiteral(isolate()->factory()->null_value());
355843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
355943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
356043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::TRUE_LITERAL:
356143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Consume(Token::TRUE_LITERAL);
3562b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      result = factory()->NewLiteral(isolate()->factory()->true_value());
356343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
356443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
356543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::FALSE_LITERAL:
356643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Consume(Token::FALSE_LITERAL);
3567b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      result = factory()->NewLiteral(isolate()->factory()->false_value());
356843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
356943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
357083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    case Token::IDENTIFIER:
3571f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    case Token::YIELD:
357204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    case Token::FUTURE_STRICT_RESERVED_WORD: {
357343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Handle<String> name = ParseIdentifier(CHECK_OK);
357465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org      if (fni_ != NULL) fni_->PushVariableName(name);
3575bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      // The name may refer to a module instance object, so its type is unknown.
3576bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
3577bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      if (FLAG_print_interface_details)
3578bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        PrintF("# Variable %s ", name->ToAsciiArray());
3579bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
35807028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      Interface* interface = Interface::NewUnknown(zone());
3581b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      result = top_scope_->NewUnresolved(
358228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org          factory(), name, interface, scanner().location().beg_pos);
358343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
358443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
358543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
358643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::NUMBER: {
358743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Consume(Token::NUMBER);
35889e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      ASSERT(scanner().is_literal_ascii());
3589a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org      double value = StringToDouble(isolate()->unicode_cache(),
3590a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org                                    scanner().literal_ascii_string(),
3591ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                    ALLOW_HEX | ALLOW_OCTAL |
3592ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                        ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY);
3593b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      result = factory()->NewNumberLiteral(value);
359443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
359543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
359643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
359743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::STRING: {
359843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Consume(Token::STRING);
3599bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org      Handle<String> symbol = GetSymbol();
3600b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      result = factory()->NewLiteral(symbol);
360165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org      if (fni_ != NULL) fni_->PushLiteralName(symbol);
360243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
360343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
360443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
360543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::ASSIGN_DIV:
360643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      result = ParseRegExpLiteral(true, CHECK_OK);
360743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
360843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
360943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::DIV:
361043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      result = ParseRegExpLiteral(false, CHECK_OK);
361143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
361243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
361343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::LBRACK:
361443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      result = ParseArrayLiteral(CHECK_OK);
361543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
361643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
361743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::LBRACE:
361843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      result = ParseObjectLiteral(CHECK_OK);
361943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
362043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
362143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::LPAREN:
362243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Consume(Token::LPAREN);
3623c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      // Heuristically try to detect immediately called functions before
3624c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      // seeing the call parentheses.
3625c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      parenthesized_function_ = (peek() == Token::FUNCTION);
362643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      result = ParseExpression(true, CHECK_OK);
362743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Expect(Token::RPAREN, CHECK_OK);
362843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
362943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
363043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::MOD:
3631e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      if (allow_natives_syntax() || extension_ != NULL) {
363243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        result = ParseV8Intrinsic(CHECK_OK);
363343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        break;
363443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
363543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // If we're not allowing special syntax we fall-through to the
363643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // default case.
363743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
363843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    default: {
3639c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org      Token::Value tok = Next();
364043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      ReportUnexpectedToken(tok);
364143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      *ok = false;
364243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return NULL;
364343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
364443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
364543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
364643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
364743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
364843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
364943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
365043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseArrayLiteral(bool* ok) {
365143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ArrayLiteral ::
365243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   '[' Expression? (',' Expression?)* ']'
365343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
36547028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  ZoneList<Expression*>* values = new(zone()) ZoneList<Expression*>(4, zone());
365543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::LBRACK, CHECK_OK);
365643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (peek() != Token::RBRACK) {
365743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Expression* elem;
365843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (peek() == Token::COMMA) {
365943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      elem = GetLiteralTheHole();
366043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
366143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      elem = ParseAssignmentExpression(true, CHECK_OK);
366243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
36637028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    values->Add(elem, zone());
366443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (peek() != Token::RBRACK) {
366543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Expect(Token::COMMA, CHECK_OK);
366643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
366743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
366843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::RBRACK, CHECK_OK);
36699a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
36709a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // Update the scope information before the pre-parsing bailout.
3671c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  int literal_index = current_function_state_->NextMaterializedLiteralIndex();
36729a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3673394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Allocate a fixed array to hold all the object literals.
367483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  Handle<JSArray> array =
367583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org      isolate()->factory()->NewJSArray(0, FAST_HOLEY_SMI_ELEMENTS);
367683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  isolate()->factory()->SetElementsCapacityAndLength(
367783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org      array, values->length(), values->length());
367843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
367943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Fill in the literals.
3680830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  Heap* heap = isolate()->heap();
3681bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  bool is_simple = true;
3682bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int depth = 1;
368383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  bool is_holey = false;
3684fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  for (int i = 0, n = values->length(); i < n; i++) {
3685fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral();
3686bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    if (m_literal != NULL && m_literal->depth() + 1 > depth) {
3687bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      depth = m_literal->depth() + 1;
3688bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3689fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i));
3690830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    if (boilerplate_value->IsTheHole()) {
369183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org      is_holey = true;
36921fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    } else if (boilerplate_value->IsUninitialized()) {
3693bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      is_simple = false;
369483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org      JSObject::SetOwnElement(
369583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org          array, i, handle(Smi::FromInt(0), isolate()), kNonStrictMode);
369643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
369783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org      JSObject::SetOwnElement(array, i, boilerplate_value, kNonStrictMode);
369843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
369943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
370043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
370183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  Handle<FixedArrayBase> element_values(array->elements());
370283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
37030b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  // Simple and shallow arrays can be lazily copied, we transform the
37040b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  // elements array to a copy-on-write array.
3705394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (is_simple && depth == 1 && values->length() > 0 &&
370683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org      array->HasFastSmiOrObjectElements()) {
370783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    element_values->set_map(heap->fixed_cow_array_map());
37080b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  }
37090b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
3710394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Remember both the literal's constant values as well as the ElementsKind
3711394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // in a 2-element FixedArray.
371283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  Handle<FixedArray> literals = isolate()->factory()->NewFixedArray(2, TENURED);
3713394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
371483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ElementsKind kind = array->GetElementsKind();
371583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  kind = is_holey ? GetHoleyElementsKind(kind) : GetPackedElementsKind(kind);
3716830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org
371783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  literals->set(0, Smi::FromInt(kind));
3718394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  literals->set(1, *element_values);
3719394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
3720b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  return factory()->NewArrayLiteral(
3721b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      literals, values, literal_index, is_simple, depth);
372243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
372343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
372443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
37259258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.orgbool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) {
37269258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  return property != NULL &&
37279258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org         property->kind() != ObjectLiteral::Property::PROTOTYPE;
37289258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org}
37299258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
37309258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
3731bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgbool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
3732a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (expression->AsLiteral() != NULL) return true;
3733bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3734bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  return lit != NULL && lit->is_simple();
3735bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
3736bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
37370b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
3738bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgHandle<FixedArray> CompileTimeValue::GetValue(Expression* expression) {
3739d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Factory* factory = Isolate::Current()->factory();
3740bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  ASSERT(IsCompileTimeValue(expression));
3741d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Handle<FixedArray> result = factory->NewFixedArray(2, TENURED);
3742bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  ObjectLiteral* object_literal = expression->AsObjectLiteral();
3743bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  if (object_literal != NULL) {
3744bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    ASSERT(object_literal->is_simple());
3745f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    if (object_literal->fast_elements()) {
3746dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
3747f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    } else {
3748dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
3749f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    }
3750bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    result->set(kElementsSlot, *object_literal->constant_properties());
3751bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  } else {
3752bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    ArrayLiteral* array_literal = expression->AsArrayLiteral();
3753bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    ASSERT(array_literal != NULL && array_literal->is_simple());
3754dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    result->set(kLiteralTypeSlot, Smi::FromInt(ARRAY_LITERAL));
37550c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    result->set(kElementsSlot, *array_literal->constant_elements());
3756bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3757bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  return result;
3758bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
3759bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3760bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3761dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgCompileTimeValue::LiteralType CompileTimeValue::GetLiteralType(
3762dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    Handle<FixedArray> value) {
3763dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot));
3764dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  return static_cast<LiteralType>(literal_type->value());
3765bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
3766bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3767bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3768bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgHandle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
3769bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
3770bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
3771bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3772bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3773bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgHandle<Object> Parser::GetBoilerplateValue(Expression* expression) {
3774bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  if (expression->AsLiteral() != NULL) {
37751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return expression->AsLiteral()->value();
3776bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3777bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  if (CompileTimeValue::IsCompileTimeValue(expression)) {
3778bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    return CompileTimeValue::GetValue(expression);
3779bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
37801fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  return isolate()->factory()->uninitialized_value();
37819258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org}
37829258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
3783e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
3784378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Validation per 11.1.5 Object Initialiser
3785378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgclass ObjectLiteralPropertyChecker {
3786378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org public:
37871b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  ObjectLiteralPropertyChecker(Parser* parser, LanguageMode language_mode) :
3788bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    props_(Literal::Match),
3789378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    parser_(parser),
37901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    language_mode_(language_mode) {
3791378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
3792378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
3793378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  void CheckProperty(
3794378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    ObjectLiteral::Property* property,
3795378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    Scanner::Location loc,
3796378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    bool* ok);
3797378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
3798378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org private:
3799378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  enum PropertyKind {
3800378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    kGetAccessor = 0x01,
3801378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    kSetAccessor = 0x02,
3802378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    kAccessor = kGetAccessor | kSetAccessor,
3803378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    kData = 0x04
3804378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  };
3805378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
3806378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  static intptr_t GetPropertyKind(ObjectLiteral::Property* property) {
3807378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    switch (property->kind()) {
3808378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      case ObjectLiteral::Property::GETTER:
3809378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org        return kGetAccessor;
3810378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      case ObjectLiteral::Property::SETTER:
3811378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org        return kSetAccessor;
3812378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      default:
3813378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org        return kData;
3814378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    }
3815378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
3816378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
3817bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  HashMap props_;
3818378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  Parser* parser_;
38191b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  LanguageMode language_mode_;
3820378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org};
3821378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
3822378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
3823378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgvoid ObjectLiteralPropertyChecker::CheckProperty(
3824378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    ObjectLiteral::Property* property,
3825378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    Scanner::Location loc,
3826378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    bool* ok) {
3827378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ASSERT(property != NULL);
3828bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  Literal* literal = property->key();
3829bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  HashMap::Entry* entry = props_.Lookup(literal, literal->Hash(), true);
3830378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  intptr_t prev = reinterpret_cast<intptr_t> (entry->value);
3831378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  intptr_t curr = GetPropertyKind(property);
3832378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
38331b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  // Duplicate data properties are illegal in strict or extended mode.
38341b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  if (language_mode_ != CLASSIC_MODE && (curr & prev & kData) != 0) {
3835378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    parser_->ReportMessageAt(loc, "strict_duplicate_property",
3836378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org                             Vector<const char*>::empty());
3837378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    *ok = false;
3838378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    return;
3839378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
3840378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // Data property conflicting with an accessor.
3841378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  if (((curr & kData) && (prev & kAccessor)) ||
3842378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      ((prev & kData) && (curr & kAccessor))) {
3843378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    parser_->ReportMessageAt(loc, "accessor_data_property",
3844378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org                             Vector<const char*>::empty());
3845378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    *ok = false;
3846378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    return;
3847378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
3848378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // Two accessors of the same type conflicting
3849378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  if ((curr & prev & kAccessor) != 0) {
3850378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    parser_->ReportMessageAt(loc, "accessor_get_set",
3851378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org                             Vector<const char*>::empty());
3852378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    *ok = false;
3853378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    return;
3854378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
3855378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
3856378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // Update map
3857378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  entry->value = reinterpret_cast<void*> (prev | curr);
3858378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  *ok = true;
3859378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org}
3860378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
38619258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
3862b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid Parser::BuildObjectLiteralConstantProperties(
3863b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    ZoneList<ObjectLiteral::Property*>* properties,
3864b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    Handle<FixedArray> constant_properties,
3865b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    bool* is_simple,
3866f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    bool* fast_elements,
386757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    int* depth,
386857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    bool* may_store_doubles) {
3869b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  int position = 0;
3870b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Accumulate the value in local variables and store it at the end.
3871b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  bool is_simple_acc = true;
3872b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  int depth_acc = 1;
3873f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  uint32_t max_element_index = 0;
3874f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  uint32_t elements = 0;
3875b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  for (int i = 0; i < properties->length(); i++) {
3876b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    ObjectLiteral::Property* property = properties->at(i);
3877b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    if (!IsBoilerplateProperty(property)) {
3878b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      is_simple_acc = false;
3879b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      continue;
3880b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    }
3881b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral();
3882b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    if (m_literal != NULL && m_literal->depth() >= depth_acc) {
3883b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      depth_acc = m_literal->depth() + 1;
3884b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    }
3885b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
3886b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined
3887b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    // value for COMPUTED properties, the real value is filled in at
3888b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    // runtime. The enumeration order is maintained.
38891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Handle<Object> key = property->key()->value();
3890b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    Handle<Object> value = GetBoilerplateValue(property->value());
389157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
38921fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    // Ensure objects that may, at any point in time, contain fields with double
38931fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    // representation are always treated as nested objects. This is true for
38941fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    // computed fields (value is undefined), and smi and double literals
38951fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    // (value->IsNumber()).
389657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    // TODO(verwaest): Remove once we can store them inline.
38971fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    if (FLAG_track_double_fields &&
38981fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org        (value->IsNumber() || value->IsUninitialized())) {
389957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      *may_store_doubles = true;
390057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    }
390157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
39021fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    is_simple_acc = is_simple_acc && !value->IsUninitialized();
3903b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
3904f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    // Keep track of the number of elements in the object literal and
3905f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    // the largest element index.  If the largest element index is
3906f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    // much larger than the number of elements, creating an object
3907f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    // literal with fast elements will be a waste of space.
3908f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    uint32_t element_index = 0;
3909f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    if (key->IsString()
3910f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org        && Handle<String>::cast(key)->AsArrayIndex(&element_index)
3911f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org        && element_index > max_element_index) {
3912f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org      max_element_index = element_index;
3913f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org      elements++;
3914f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    } else if (key->IsSmi()) {
3915f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org      int key_value = Smi::cast(*key)->value();
3916f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org      if (key_value > 0
3917f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org          && static_cast<uint32_t>(key_value) > max_element_index) {
3918f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org        max_element_index = key_value;
3919f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org      }
3920f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org      elements++;
3921f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    }
3922f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
3923b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    // Add name, value pair to the fixed array.
3924b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    constant_properties->set(position++, *key);
3925b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    constant_properties->set(position++, *value);
3926b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
3927f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  *fast_elements =
3928f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org      (max_element_index <= 32) || ((2 * elements) >= max_element_index);
3929b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  *is_simple = is_simple_acc;
3930b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  *depth = depth_acc;
3931b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
3932b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
3933b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
3934c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.orgObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
3935c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org                                                          bool* ok) {
3936c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  // Special handling of getter and setter syntax:
3937c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
3938c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  // We have already read the "get" or "set" keyword.
3939c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  Token::Value next = Next();
39405d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  bool is_keyword = Token::IsKeyword(next);
39415d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  if (next == Token::IDENTIFIER || next == Token::NUMBER ||
394283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      next == Token::FUTURE_RESERVED_WORD ||
394304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      next == Token::FUTURE_STRICT_RESERVED_WORD ||
39445d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org      next == Token::STRING || is_keyword) {
39455d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org    Handle<String> name;
39465d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org    if (is_keyword) {
39474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      name = isolate_->factory()->InternalizeUtf8String(Token::String(next));
39485d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org    } else {
3949bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org      name = GetSymbol();
39505d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org    }
3951c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org    FunctionLiteral* value =
3952c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org        ParseFunctionLiteral(name,
395383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                             false,   // reserved words are allowed here
3954f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                             false,   // not a generator
3955c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org                             RelocInfo::kNoPosition,
39567c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org                             FunctionLiteral::ANONYMOUS_EXPRESSION,
3957c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org                             CHECK_OK);
39582efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    // Allow any number of parameters for compatibilty with JSC.
39595d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org    // Specification only allows zero parameters for get and one for set.
3960b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    return factory()->NewObjectLiteralProperty(is_getter, value);
3961c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  } else {
3962c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org    ReportUnexpectedToken(next);
3963c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org    *ok = false;
3964c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org    return NULL;
3965c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  }
3966c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org}
3967c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org
3968c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org
396943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseObjectLiteral(bool* ok) {
397043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ObjectLiteral ::
397143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   '{' (
3972d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org  //       ((IdentifierName | String | Number) ':' AssignmentExpression)
3973d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org  //     | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
397443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //    )*[','] '}'
397543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3976fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  ZoneList<ObjectLiteral::Property*>* properties =
39777028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      new(zone()) ZoneList<ObjectLiteral::Property*>(4, zone());
39789258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  int number_of_boilerplate_properties = 0;
3979ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  bool has_function = false;
398043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
39811b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  ObjectLiteralPropertyChecker checker(this, top_scope_->language_mode());
3982378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
398343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::LBRACE, CHECK_OK);
3984378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
398543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (peek() != Token::RBRACE) {
398665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    if (fni_ != NULL) fni_->Enter();
398765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
398843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Literal* key = NULL;
3989d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org    Token::Value next = peek();
3990378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
3991378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    // Location of the property name token
3992378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    Scanner::Location loc = scanner().peek_location();
3993378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
3994d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org    switch (next) {
399583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      case Token::FUTURE_RESERVED_WORD:
399604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      case Token::FUTURE_STRICT_RESERVED_WORD:
399743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      case Token::IDENTIFIER: {
399843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        bool is_getter = false;
399943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        bool is_setter = false;
400043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        Handle<String> id =
400104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org            ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
400265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org        if (fni_ != NULL) fni_->PushLiteralName(id);
400365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
4004c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org        if ((is_getter || is_setter) && peek() != Token::COLON) {
4005378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org            // Update loc to point to the identifier
4006378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org            loc = scanner().peek_location();
400743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            ObjectLiteral::Property* property =
4008c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org                ParseObjectLiteralGetSet(is_getter, CHECK_OK);
4009d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org            if (IsBoilerplateProperty(property)) {
40109258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org              number_of_boilerplate_properties++;
4011d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org            }
4012378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org            // Validate the property.
4013378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org            checker.CheckProperty(property, loc, CHECK_OK);
40147028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org            properties->Add(property, zone());
401543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
401665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
401765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org            if (fni_ != NULL) {
401865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org              fni_->Infer();
401965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org              fni_->Leave();
402065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org            }
402143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            continue;  // restart the while
402243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
4023c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org        // Failed to parse as get/set property, so it's just a property
4024c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org        // called "get" or "set".
4025b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        key = factory()->NewLiteral(id);
402643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        break;
402743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
402843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      case Token::STRING: {
4029c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org        Consume(Token::STRING);
4030bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org        Handle<String> string = GetSymbol();
403165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org        if (fni_ != NULL) fni_->PushLiteralName(string);
403243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        uint32_t index;
403326c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org        if (!string.is_null() && string->AsArrayIndex(&index)) {
4034b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org          key = factory()->NewNumberLiteral(index);
4035c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org          break;
403643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
4037b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        key = factory()->NewLiteral(string);
403843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        break;
403943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
404043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      case Token::NUMBER: {
404143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        Consume(Token::NUMBER);
40429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        ASSERT(scanner().is_literal_ascii());
4043a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org        double value = StringToDouble(isolate()->unicode_cache(),
4044a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org                                      scanner().literal_ascii_string(),
4045ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                      ALLOW_HEX | ALLOW_OCTAL |
4046ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                          ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY);
4047b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        key = factory()->NewNumberLiteral(value);
404843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        break;
404943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
405043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      default:
4051c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org        if (Token::IsKeyword(next)) {
4052c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org          Consume(next);
4053bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org          Handle<String> string = GetSymbol();
4054b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org          key = factory()->NewLiteral(string);
4055c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org        } else {
4056c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org          // Unexpected token.
4057c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org          Token::Value next = Next();
4058c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org          ReportUnexpectedToken(next);
4059c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org          *ok = false;
4060c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org          return NULL;
4061c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org        }
406243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
406343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
406443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Expect(Token::COLON, CHECK_OK);
406543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Expression* value = ParseAssignmentExpression(true, CHECK_OK);
406643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
406743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ObjectLiteral::Property* property =
4068812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org        new(zone()) ObjectLiteral::Property(key, value, isolate());
40699258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
4070ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org    // Mark top-level object literals that contain function literals and
4071ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org    // pretenure the literal so it can be added as a constant function
4072ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org    // property.
4073ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org    if (top_scope_->DeclarationScope()->is_global_scope() &&
4074ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org        value->AsFunctionLiteral() != NULL) {
4075ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      has_function = true;
4076c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org      value->AsFunctionLiteral()->set_pretenure();
4077ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    }
4078ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
40799258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
4080236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++;
4081378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    // Validate the property
4082378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    checker.CheckProperty(property, loc, CHECK_OK);
40837028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    properties->Add(property, zone());
408443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
408543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // TODO(1240767): Consider allowing trailing comma.
408643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
408765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
408865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    if (fni_ != NULL) {
408965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org      fni_->Infer();
409065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org      fni_->Leave();
409165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    }
409243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
409343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::RBRACE, CHECK_OK);
4094378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
409543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Computation of literal_index must happen before pre parse bailout.
4096c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  int literal_index = current_function_state_->NextMaterializedLiteralIndex();
409743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4098ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> constant_properties = isolate()->factory()->NewFixedArray(
4099ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      number_of_boilerplate_properties * 2, TENURED);
4100b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
4101bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  bool is_simple = true;
4102f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  bool fast_elements = true;
4103bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int depth = 1;
410457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  bool may_store_doubles = false;
4105fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  BuildObjectLiteralConstantProperties(properties,
4106b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                                       constant_properties,
4107b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                                       &is_simple,
4108f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org                                       &fast_elements,
410957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org                                       &depth,
411057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org                                       &may_store_doubles);
4111b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  return factory()->NewObjectLiteral(constant_properties,
4112b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                     properties,
4113b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                     literal_index,
4114b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                     is_simple,
4115b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                     fast_elements,
4116b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                     depth,
411757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org                                     may_store_doubles,
4118b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                     has_function);
411943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
412043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
412143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
412243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) {
41235f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  if (!scanner().ScanRegExpPattern(seen_equal)) {
412443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Next();
412543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ReportMessage("unterminated_regexp", Vector<const char*>::empty());
412643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    *ok = false;
412743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return NULL;
412843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
412943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4130c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  int literal_index = current_function_state_->NextMaterializedLiteralIndex();
413143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
41329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  Handle<String> js_pattern = NextLiteralString(TENURED);
41335f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  scanner().ScanRegExpFlags();
41349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  Handle<String> js_flags = NextLiteralString(TENURED);
413543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Next();
413643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4137b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index);
413843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
413943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
414043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
414143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenZoneList<Expression*>* Parser::ParseArguments(bool* ok) {
414243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Arguments ::
414343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   '(' (AssignmentExpression)*[','] ')'
414443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
41457028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4, zone());
414643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::LPAREN, CHECK_OK);
414743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool done = (peek() == Token::RPAREN);
414843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (!done) {
414943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Expression* argument = ParseAssignmentExpression(true, CHECK_OK);
41507028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    result->Add(argument, zone());
4151876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    if (result->length() > Code::kMaxArguments) {
4152e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org      ReportMessageAt(scanner().location(), "too_many_arguments",
4153e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org                      Vector<const char*>::empty());
4154e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org      *ok = false;
4155e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org      return NULL;
4156e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    }
415743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    done = (peek() == Token::RPAREN);
415843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (!done) Expect(Token::COMMA, CHECK_OK);
415943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
416043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::RPAREN, CHECK_OK);
4161fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  return result;
416243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
416343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
416443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
41651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgclass SingletonLogger : public ParserRecorder {
41661b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org public:
41671b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  SingletonLogger() : has_error_(false), start_(-1), end_(-1) { }
4168b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  virtual ~SingletonLogger() { }
41691b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
41701b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  void Reset() { has_error_ = false; }
41711b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
41721b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  virtual void LogFunction(int start,
41731b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                           int end,
41741b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                           int literals,
41751b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                           int properties,
41761b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                           LanguageMode mode) {
41771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    ASSERT(!has_error_);
41781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    start_ = start;
41791b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    end_ = end;
41801b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    literals_ = literals;
41811b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    properties_ = properties;
41821b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    mode_ = mode;
41831b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  };
41841b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
41851b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  // Logs a symbol creation of a literal or identifier.
41861b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  virtual void LogAsciiSymbol(int start, Vector<const char> literal) { }
4187154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  virtual void LogUtf16Symbol(int start, Vector<const uc16> literal) { }
41881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
41891b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  // Logs an error message and marks the log as containing an error.
41901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  // Further logging will be ignored, and ExtractData will return a vector
41911b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  // representing the error only.
41921b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  virtual void LogMessage(int start,
41931b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                          int end,
41941b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                          const char* message,
41951b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                          const char* argument_opt) {
4196657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    if (has_error_) return;
41971b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    has_error_ = true;
41981b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    start_ = start;
41991b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    end_ = end;
42001b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    message_ = message;
42011b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    argument_opt_ = argument_opt;
42021b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
42031b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
42041b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  virtual int function_position() { return 0; }
42051b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
42061b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  virtual int symbol_position() { return 0; }
42071b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
42081b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  virtual int symbol_ids() { return -1; }
42091b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
42101b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  virtual Vector<unsigned> ExtractData() {
42111b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    UNREACHABLE();
42121b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    return Vector<unsigned>();
42131b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
42141b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
42151b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  virtual void PauseRecording() { }
42161b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
42171b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  virtual void ResumeRecording() { }
42181b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
42191b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  bool has_error() { return has_error_; }
42201b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
42211b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  int start() { return start_; }
42221b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  int end() { return end_; }
42231b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  int literals() {
42241b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    ASSERT(!has_error_);
42251b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    return literals_;
42261b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
42271b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  int properties() {
42281b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    ASSERT(!has_error_);
42291b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    return properties_;
42301b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
42311b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  LanguageMode language_mode() {
42321b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    ASSERT(!has_error_);
42331b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    return mode_;
42341b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
42351b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  const char* message() {
42361b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    ASSERT(has_error_);
42371b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    return message_;
42381b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
42391b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  const char* argument_opt() {
42401b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    ASSERT(has_error_);
42411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    return argument_opt_;
42421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
42431b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
42441b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org private:
42451b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  bool has_error_;
42461b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  int start_;
42471b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  int end_;
42481b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  // For function entries.
42491b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  int literals_;
42501b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  int properties_;
42511b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  LanguageMode mode_;
42521b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  // For error messages.
42531b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  const char* message_;
42541b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  const char* argument_opt_;
42551b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org};
42561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
42571b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
4258dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgFunctionLiteral* Parser::ParseFunctionLiteral(
4259dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    Handle<String> function_name,
4260dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    bool name_is_strict_reserved,
4261dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    bool is_generator,
4262dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    int function_token_position,
4263dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    FunctionLiteral::FunctionType function_type,
4264dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    bool* ok) {
426543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Function ::
426643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   '(' FormalParameterList? ')' '{' FunctionBody '}'
426743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
42687c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  // Anonymous functions were passed either the empty symbol or a null
42697c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  // handle as the function name.  Remember if we were passed a non-empty
42707c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  // handle to decide whether to invoke function name inference.
42717c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  bool should_infer_name = function_name.is_null();
42727c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
42737c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  // We want a non-null handle as the function name.
42747c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  if (should_infer_name) {
42754a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    function_name = isolate()->factory()->empty_string();
427643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
427743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
427843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int num_parameters = 0;
4279b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  // Function declarations are function scoped in normal mode, so they are
4280b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  // hoisted. In harmony block scoping mode they are block scoped, so they
4281b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  // are not hoisted.
4282dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  Scope* scope =
4283dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      (function_type == FunctionLiteral::DECLARATION && !is_extended_mode())
4284394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE)
4285394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      : NewScope(top_scope_, FUNCTION_SCOPE);
428604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  ZoneList<Statement*>* body = NULL;
42871b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  int materialized_literal_count = -1;
42881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  int expected_property_count = -1;
428904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  int handler_count = 0;
429056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  FunctionLiteral::ParameterFlag duplicate_parameters =
429156454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org      FunctionLiteral::kNoDuplicateParameters;
4292471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
4293471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      ? FunctionLiteral::kIsParenthesized
4294471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      : FunctionLiteral::kNotParenthesized;
4295f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  FunctionLiteral::IsGeneratorFlag generator = is_generator
4296f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      ? FunctionLiteral::kIsGenerator
4297f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      : FunctionLiteral::kNotGenerator;
4298b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  AstProperties ast_properties;
429943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Parse function body.
4300e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  { FunctionState function_state(this, scope, isolate());
43017c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org    top_scope_->SetScopeName(function_name);
430243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4303e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (is_generator) {
4304e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      // For generators, allocating variables in contexts is currently a win
4305e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      // because it minimizes the work needed to suspend and resume an
4306e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      // activation.
4307e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      top_scope_->ForceContextAllocation();
4308e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
4309e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      // Calling a generator returns a generator object.  That object is stored
4310e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      // in a temporary variable, a definition that is used by "yield"
4311e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      // expressions.  Presence of a variable for the generator object in the
4312e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      // FunctionState indicates that this function is a generator.
4313e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      Handle<String> tempname = isolate()->factory()->InternalizeOneByteString(
4314e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org          STATIC_ASCII_VECTOR(".generator_object"));
4315e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname);
4316e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      function_state.set_generator_object_variable(temp);
4317e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
4318e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
431943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    //  FormalParameterList ::
432043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    //    '(' (Identifier)*[','] ')'
432143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Expect(Token::LPAREN, CHECK_OK);
4322394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    scope->set_start_position(scanner().location().beg_pos);
43231c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org    Scanner::Location name_loc = Scanner::Location::invalid();
43241c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org    Scanner::Location dupe_loc = Scanner::Location::invalid();
43251c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org    Scanner::Location reserved_loc = Scanner::Location::invalid();
43260a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
432743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    bool done = (peek() == Token::RPAREN);
432843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    while (!done) {
432904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      bool is_strict_reserved = false;
433083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      Handle<String> param_name =
433104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org          ParseIdentifierOrStrictReservedWord(&is_strict_reserved,
433204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org                                              CHECK_OK);
4333378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
4334378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      // Store locations for possible future error reports.
4335378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) {
4336378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org        name_loc = scanner().location();
4337378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      }
4338378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) {
433956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org        duplicate_parameters = FunctionLiteral::kHasDuplicateParameters;
4340378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org        dupe_loc = scanner().location();
4341378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      }
434204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      if (!reserved_loc.IsValid() && is_strict_reserved) {
434383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org        reserved_loc = scanner().location();
434483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      }
4345378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
434656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org      top_scope_->DeclareParameter(param_name, VAR);
4347fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org      num_parameters++;
4348876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org      if (num_parameters > Code::kMaxArguments) {
4349d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com        ReportMessageAt(scanner().location(), "too_many_parameters",
4350d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com                        Vector<const char*>::empty());
4351d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com        *ok = false;
4352d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com        return NULL;
4353d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com      }
435443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      done = (peek() == Token::RPAREN);
435543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (!done) Expect(Token::COMMA, CHECK_OK);
435643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
435743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Expect(Token::RPAREN, CHECK_OK);
435843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
435943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Expect(Token::LBRACE, CHECK_OK);
436043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
436143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // If we have a named function expression, we add a local variable
436243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // declaration to the body of the function with the name of the
436343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // function and let it refer to the function itself (closure).
436443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // NOTE: We create a proxy and resolve it here so that in the
436543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // future we can change the AST to only refer to VariableProxies
436643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // instead of Variables and Proxis as is the case now.
436704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org    Variable* fvar = NULL;
436804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org    Token::Value fvar_init_op = Token::INIT_CONST;
4369dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
4370ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY;
4371ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST;
4372ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      fvar = new(zone()) Variable(top_scope_,
4373ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com         function_name, fvar_mode, true /* is valid LHS */,
437428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org         Variable::NORMAL, kCreatedInitialized, Interface::NewConst());
4375ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      VariableProxy* proxy = factory()->NewVariableProxy(fvar);
4376ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      VariableDeclaration* fvar_declaration =
4377ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com          factory()->NewVariableDeclaration(proxy, fvar_mode, top_scope_);
4378ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      top_scope_->DeclareFunctionVar(fvar_declaration);
437943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
438043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
43811b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // Determine whether the function will be lazily compiled.
43821b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // The heuristics are:
43831b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // - It must not have been prohibited by the caller to Parse (some callers
43841b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    //   need a full AST).
43859c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org    // - The outer scope must allow lazy compilation of inner functions.
43861b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // - The function mustn't be a function expression with an open parenthesis
43871b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    //   before; we consider that a hint that the function will be called
43881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    //   immediately, and it would be a waste of time to make it lazily
43891b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    //   compiled.
43901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // These are all things we can know at this point, without looking at the
43911b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // function itself.
4392c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    bool is_lazily_compiled = (mode() == PARSE_LAZILY &&
43939c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org                               top_scope_->AllowsLazyCompilation() &&
43941b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                               !parenthesized_function_);
4395c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    parenthesized_function_ = false;  // The bit was set for this function only.
439643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4397d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    if (is_lazily_compiled) {
4398d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      int function_block_pos = scanner().location().beg_pos;
43991b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      FunctionEntry entry;
4400e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      if (pre_parse_data_ != NULL) {
4401e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        // If we have pre_parse_data_, we use it to skip parsing the function
4402e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        // body.  The preparser data contains the information we need to
4403e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        // construct the lazy function.
4404e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        entry = pre_parse_data()->GetFunctionEntry(function_block_pos);
44051b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        if (entry.is_valid()) {
44061b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          if (entry.end_pos() <= function_block_pos) {
44071b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org            // End position greater than end of stream is safe, and hard
44081b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org            // to check.
44091b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org            ReportInvalidPreparseData(function_name, CHECK_OK);
44101b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          }
44111b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          scanner().SeekForward(entry.end_pos() - 1);
44121b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
44131b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          scope->set_end_position(entry.end_pos());
44141b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          Expect(Token::RBRACE, CHECK_OK);
44151b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          isolate()->counters()->total_preparse_skipped()->Increment(
44161b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org              scope->end_position() - function_block_pos);
44171b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          materialized_literal_count = entry.literal_count();
44181b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          expected_property_count = entry.property_count();
44191b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          top_scope_->SetLanguageMode(entry.language_mode());
44201b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        } else {
44211b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          is_lazily_compiled = false;
44221b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        }
4423d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      } else {
44241b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        // With no preparser data, we partially parse the function, without
44251b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        // building an AST. This gathers the data needed to build a lazy
44261b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        // function.
44271b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        SingletonLogger logger;
44281b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        preparser::PreParser::PreParseResult result =
44291b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org            LazyParseFunctionLiteral(&logger);
44301b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        if (result == preparser::PreParser::kPreParseStackOverflow) {
44311b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          // Propagate stack overflow.
44321b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          stack_overflow_ = true;
44331b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          *ok = false;
44341b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          return NULL;
4435d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org        }
44361b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        if (logger.has_error()) {
44371b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          const char* arg = logger.argument_opt();
44381b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          Vector<const char*> args;
44391b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          if (arg != NULL) {
44401b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org            args = Vector<const char*>(&arg, 1);
44411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          }
44421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          ReportMessageAt(Scanner::Location(logger.start(), logger.end()),
44431b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                          logger.message(), args);
44441b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          *ok = false;
44451b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          return NULL;
44461b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        }
44471b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        scope->set_end_position(logger.end());
44481b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        Expect(Token::RBRACE, CHECK_OK);
4449d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org        isolate()->counters()->total_preparse_skipped()->Increment(
4450394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com            scope->end_position() - function_block_pos);
44511b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        materialized_literal_count = logger.literals();
44521b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        expected_property_count = logger.properties();
44531b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        top_scope_->SetLanguageMode(logger.language_mode());
44544a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com      }
4455d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    }
4456d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org
4457d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    if (!is_lazily_compiled) {
4458471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
44597028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      body = new(zone()) ZoneList<Statement*>(8, zone());
446004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org      if (fvar != NULL) {
446128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org        VariableProxy* fproxy = top_scope_->NewUnresolved(
446228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org            factory(), function_name, Interface::NewConst());
446304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org        fproxy->BindTo(fvar);
4464b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        body->Add(factory()->NewExpressionStatement(
4465b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org            factory()->NewAssignment(fvar_init_op,
4466b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                     fproxy,
4467b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                     factory()->NewThisFunction(),
44687028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                     RelocInfo::kNoPosition)),
4469471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                                     zone());
447004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org      }
4471e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
4472e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      // For generators, allocate and yield an iterator on function entry.
4473e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      if (is_generator) {
4474e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        ZoneList<Expression*>* arguments =
4475e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org            new(zone()) ZoneList<Expression*>(0, zone());
4476e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        CallRuntime* allocation = factory()->NewCallRuntime(
4477e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org            isolate()->factory()->empty_string(),
4478e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org            Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject),
4479e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org            arguments);
4480e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        VariableProxy* init_proxy = factory()->NewVariableProxy(
4481e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org            current_function_state_->generator_object_variable());
4482e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        Assignment* assignment = factory()->NewAssignment(
4483e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org            Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
4484e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        VariableProxy* get_proxy = factory()->NewVariableProxy(
4485e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org            current_function_state_->generator_object_variable());
4486e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        Yield* yield = factory()->NewYield(
448777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org            get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition);
4488e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        body->Add(factory()->NewExpressionStatement(yield), zone());
4489e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      }
4490e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
449133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org      ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK);
4492fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
449377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org      if (is_generator) {
449477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org        VariableProxy* get_proxy = factory()->NewVariableProxy(
449577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org            current_function_state_->generator_object_variable());
449677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org        Expression *undefined = factory()->NewLiteral(
449777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org            isolate()->factory()->undefined_value());
449877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org        Yield* yield = factory()->NewYield(
449977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org            get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition);
450077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org        body->Add(factory()->NewExpressionStatement(yield), zone());
450177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org      }
450277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
4503c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org      materialized_literal_count = function_state.materialized_literal_count();
4504c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org      expected_property_count = function_state.expected_property_count();
450504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org      handler_count = function_state.handler_count();
450643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4507d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org      Expect(Token::RBRACE, CHECK_OK);
4508394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      scope->set_end_position(scanner().location().end_pos);
450943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
451043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
45110a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    // Validate strict mode.
45121b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (!top_scope_->is_classic_mode()) {
45137c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org      if (IsEvalOrArguments(function_name)) {
4514394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        int start_pos = scope->start_position();
45150a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        int position = function_token_position != RelocInfo::kNoPosition
4516378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org            ? function_token_position
4517378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org            : (start_pos > 0 ? start_pos - 1 : start_pos);
451883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org        Scanner::Location location = Scanner::Location(position, start_pos);
451983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org        ReportMessageAt(location,
45200a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org                        "strict_function_name", Vector<const char*>::empty());
45210a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        *ok = false;
45220a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        return NULL;
45230a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      }
4524378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      if (name_loc.IsValid()) {
4525378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org        ReportMessageAt(name_loc, "strict_param_name",
4526378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org                        Vector<const char*>::empty());
4527378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org        *ok = false;
4528378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org        return NULL;
4529378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      }
4530378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      if (dupe_loc.IsValid()) {
4531378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org        ReportMessageAt(dupe_loc, "strict_param_dupe",
4532378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org                        Vector<const char*>::empty());
4533378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org        *ok = false;
4534378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org        return NULL;
4535378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      }
453604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      if (name_is_strict_reserved) {
4537394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        int start_pos = scope->start_position();
453883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org        int position = function_token_position != RelocInfo::kNoPosition
453983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org            ? function_token_position
454083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org            : (start_pos > 0 ? start_pos - 1 : start_pos);
454183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org        Scanner::Location location = Scanner::Location(position, start_pos);
454283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org        ReportMessageAt(location, "strict_reserved_word",
454383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                        Vector<const char*>::empty());
454483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org        *ok = false;
454583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org        return NULL;
454683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      }
454783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      if (reserved_loc.IsValid()) {
454883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org        ReportMessageAt(reserved_loc, "strict_reserved_word",
454983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                        Vector<const char*>::empty());
455083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org        *ok = false;
455183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org        return NULL;
455283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      }
4553394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      CheckOctalLiteral(scope->start_position(),
4554394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                        scope->end_position(),
4555394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                        CHECK_OK);
45560a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    }
4557b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    ast_properties = *factory()->visitor()->ast_properties();
455844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  }
45590a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
45601b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  if (is_extended_mode()) {
45611805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    CheckConflictingVarDeclarations(scope, CHECK_OK);
45621805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  }
45631805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
456444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  FunctionLiteral* function_literal =
4565b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      factory()->NewFunctionLiteral(function_name,
4566b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                    scope,
4567b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                    body,
4568b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                    materialized_literal_count,
4569b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                    expected_property_count,
4570b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                    handler_count,
4571b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                    num_parameters,
457256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                                    duplicate_parameters,
4573dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                                    function_type,
4574471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                                    FunctionLiteral::kIsFunction,
4575f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                                    parenthesized,
4576f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                                    generator);
457744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  function_literal->set_function_token_position(function_token_position);
4578b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  function_literal->set_ast_properties(&ast_properties);
45795d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
45807c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
458144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  return function_literal;
458243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
458343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
458443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
45851b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgpreparser::PreParser::PreParseResult Parser::LazyParseFunctionLiteral(
45861b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    SingletonLogger* logger) {
45871b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse());
45881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  ASSERT_EQ(Token::LBRACE, scanner().current_token());
45891b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
45901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  if (reusable_preparser_ == NULL) {
45911b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    intptr_t stack_limit = isolate()->stack_guard()->real_climit();
45921b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    reusable_preparser_ = new preparser::PreParser(&scanner_,
45931b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                                                   NULL,
4594e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                                   stack_limit);
4595e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping());
4596e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    reusable_preparser_->set_allow_modules(allow_modules());
4597e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax());
4598e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    reusable_preparser_->set_allow_lazy(true);
4599e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    reusable_preparser_->set_allow_generators(allow_generators());
46001fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    reusable_preparser_->set_allow_for_of(allow_for_of());
4601ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    reusable_preparser_->set_allow_harmony_numeric_literals(
4602ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        allow_harmony_numeric_literals());
46031b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
46041b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  preparser::PreParser::PreParseResult result =
46051b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(),
4606f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                                                is_generator(),
46071b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                                                logger);
46081b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  return result;
46091b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org}
46101b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
46111b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
461243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::ParseV8Intrinsic(bool* ok) {
461343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // CallRuntime ::
461443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   '%' Identifier Arguments
461543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
461643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::MOD, CHECK_OK);
461743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<String> name = ParseIdentifier(CHECK_OK);
461843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
4619d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com
4620d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  if (extension_ != NULL) {
462143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // The extension structures are only accessible while parsing the
462243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // very first time not when reparsing because of lazy compilation.
46234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    top_scope_->DeclarationScope()->ForceEagerCompilation();
462443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
462543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
46264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  const Runtime::Function* function = Runtime::FunctionForName(name);
462743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4628d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  // Check for built-in IS_VAR macro.
4629d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  if (function != NULL &&
4630d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com      function->intrinsic_type == Runtime::RUNTIME &&
4631d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com      function->function_id == Runtime::kIS_VAR) {
4632d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    // %IS_VAR(x) evaluates to x if x is a variable,
4633d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    // leads to a parse error otherwise.  Could be implemented as an
4634d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    // inline function %_IS_VAR(x) to eliminate this special case.
4635d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
4636d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com      return args->at(0);
4637d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    } else {
4638f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      ReportMessage("not_isvar", Vector<const char*>::empty());
4639d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com      *ok = false;
464043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return NULL;
464143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
464243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
464343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4644d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  // Check that the expected number of arguments are being passed.
4645d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  if (function != NULL &&
4646d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com      function->nargs != -1 &&
4647d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com      function->nargs != args->length()) {
4648d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    ReportMessage("illegal_access", Vector<const char*>::empty());
4649d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    *ok = false;
4650d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    return NULL;
4651de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org  }
4652de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org
4653de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org  // Check that the function is defined if it's an inline runtime call.
4654de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org  if (function == NULL && name->Get(0) == '_') {
4655de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org    ReportMessage("not_defined", Vector<Handle<String> >(&name, 1));
4656de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org    *ok = false;
4657de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org    return NULL;
4658f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  }
4659f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
4660d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  // We have a valid intrinsics call or a call to a builtin.
4661b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  return factory()->NewCallRuntime(name, function, args);
466243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
466343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
466443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
466583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.orgbool Parser::peek_any_identifier() {
466683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  Token::Value next = peek();
466783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  return next == Token::IDENTIFIER ||
466804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org         next == Token::FUTURE_RESERVED_WORD ||
4669f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org         next == Token::FUTURE_STRICT_RESERVED_WORD ||
4670f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org         next == Token::YIELD;
467183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org}
467283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
467383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
467443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Parser::Consume(Token::Value token) {
467543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Token::Value next = Next();
467643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  USE(next);
467743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  USE(token);
467843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(next == token);
467943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
468043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
468143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
468243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Parser::Expect(Token::Value token, bool* ok) {
468343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Token::Value next = Next();
468443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (next == token) return;
468543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ReportUnexpectedToken(next);
468643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  *ok = false;
468743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
468843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
468943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4690b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgbool Parser::Check(Token::Value token) {
4691b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  Token::Value next = peek();
4692b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (next == token) {
4693b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    Consume(next);
4694b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    return true;
4695b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
4696b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  return false;
4697b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
4698b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
4699b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
47001fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.orgbool Parser::CheckContextualKeyword(Vector<const char> keyword) {
47011fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  if (peek() == Token::IDENTIFIER &&
47021fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      scanner().is_next_contextual_keyword(keyword)) {
47031fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    Consume(Token::IDENTIFIER);
47041fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    return true;
47051fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  }
47061fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  return false;
47071fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org}
47081fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
47091fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
471043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Parser::ExpectSemicolon(bool* ok) {
471143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check for automatic semicolon insertion according to
471243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the rules given in ECMA-262, section 7.9, page 21.
471343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Token::Value tok = peek();
471443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (tok == Token::SEMICOLON) {
471543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Next();
471643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
471743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
4718df8c03c138809b385f3cca5d424d7b2f8ad92527whesse@chromium.org  if (scanner().HasAnyLineTerminatorBeforeNext() ||
471943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      tok == Token::RBRACE ||
472043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      tok == Token::EOS) {
472143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
472243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
472343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::SEMICOLON, ok);
472443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
472543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
472643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
47271fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.orgvoid Parser::ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
4728812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Expect(Token::IDENTIFIER, ok);
4729812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  if (!*ok) return;
47301fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  if (!scanner().is_literal_contextual_keyword(keyword)) {
4731812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    *ok = false;
4732812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    ReportUnexpectedToken(scanner().current_token());
4733812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  }
4734812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org}
4735812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
4736812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
473743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenLiteral* Parser::GetLiteralUndefined() {
4738b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  return factory()->NewLiteral(isolate()->factory()->undefined_value());
473943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
474043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
474143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
474243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenLiteral* Parser::GetLiteralTheHole() {
4743b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  return factory()->NewLiteral(isolate()->factory()->the_hole_value());
474443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
474543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
474643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4747b645116853c677aca8a316381b87441ba6004f67danno@chromium.org// Parses an identifier that is valid for the current scope, in particular it
474804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org// fails on strict mode future reserved keywords in a strict scope.
474943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenHandle<String> Parser::ParseIdentifier(bool* ok) {
4750f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  Token::Value next = Next();
4751f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  if (next == Token::IDENTIFIER ||
4752f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      (top_scope_->is_classic_mode() &&
4753f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org       (next == Token::FUTURE_STRICT_RESERVED_WORD ||
4754f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        (next == Token::YIELD && !is_generator())))) {
4755bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    return GetSymbol();
4756f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  } else {
4757f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    ReportUnexpectedToken(next);
4758f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    *ok = false;
4759f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    return Handle<String>();
476004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  }
476183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org}
476283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
476383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
476404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org// Parses and identifier or a strict mode future reserved word, and indicate
476504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org// whether it is strict mode future reserved.
476604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.orgHandle<String> Parser::ParseIdentifierOrStrictReservedWord(
476704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    bool* is_strict_reserved, bool* ok) {
4768f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  Token::Value next = Next();
4769f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  if (next == Token::IDENTIFIER) {
4770f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    *is_strict_reserved = false;
4771f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  } else if (next == Token::FUTURE_STRICT_RESERVED_WORD ||
4772f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org             (next == Token::YIELD && !is_generator())) {
477304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    *is_strict_reserved = true;
4774f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  } else {
4775f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    ReportUnexpectedToken(next);
4776f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    *ok = false;
4777f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    return Handle<String>();
477883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  }
4779bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  return GetSymbol();
478043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
478143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4782d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org
4783d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.orgHandle<String> Parser::ParseIdentifierName(bool* ok) {
4784d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org  Token::Value next = Next();
478583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  if (next != Token::IDENTIFIER &&
478604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      next != Token::FUTURE_RESERVED_WORD &&
478704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      next != Token::FUTURE_STRICT_RESERVED_WORD &&
478804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      !Token::IsKeyword(next)) {
4789d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org    ReportUnexpectedToken(next);
4790d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org    *ok = false;
4791d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org    return Handle<String>();
4792d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org  }
4793bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  return GetSymbol();
4794d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org}
4795d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org
4796378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
479764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgvoid Parser::MarkAsLValue(Expression* expression) {
479864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  VariableProxy* proxy = expression != NULL
479964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      ? expression->AsVariableProxy()
480064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      : NULL;
480164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
480264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  if (proxy != NULL) proxy->MarkAsLValue();
480364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org}
480464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
480564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
4806378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Checks LHS expression for assignment and prefix/postfix increment/decrement
4807378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// in strict mode.
4808378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgvoid Parser::CheckStrictModeLValue(Expression* expression,
4809378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org                                   const char* error,
4810378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org                                   bool* ok) {
48111b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  ASSERT(!top_scope_->is_classic_mode());
4812378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  VariableProxy* lhs = expression != NULL
4813378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      ? expression->AsVariableProxy()
4814378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      : NULL;
4815378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
4816378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) {
4817378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    ReportMessage(error, Vector<const char*>::empty());
4818378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    *ok = false;
4819378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
4820378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org}
4821378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
4822378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
48231c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org// Checks whether an octal literal was last seen between beg_pos and end_pos.
48241c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org// If so, reports an error. Only called for strict mode.
48250ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.orgvoid Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
48261c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  Scanner::Location octal = scanner().octal_position();
48271c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  if (octal.IsValid() &&
48281c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org      beg_pos <= octal.beg_pos &&
48291c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org      octal.end_pos <= end_pos) {
48301c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org    ReportMessageAt(octal, "strict_octal_literal",
48310ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org                    Vector<const char*>::empty());
48320ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    scanner().clear_octal_position();
48330ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    *ok = false;
48340ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  }
48350ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org}
48360ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org
4837d3b3be0240773cedde121ab23064d32f2c50a74fsgjesse@chromium.org
48381805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgvoid Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
48391805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  Declaration* decl = scope->CheckConflictingVarDeclarations();
48401805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  if (decl != NULL) {
48411805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    // In harmony mode we treat conflicting variable bindinds as early
48421805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    // errors. See ES5 16 for a definition of early errors.
48431805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    Handle<String> name = decl->proxy()->name();
484483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
48451805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    const char* elms[2] = { "Variable", *c_string };
48461805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    Vector<const char*> args(elms, 2);
48471805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    int position = decl->proxy()->position();
48481805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    Scanner::Location location = position == RelocInfo::kNoPosition
48491805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org        ? Scanner::Location::invalid()
48501805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org        : Scanner::Location(position, position + 1);
48511805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    ReportMessageAt(location, "redeclaration", args);
48521805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    *ok = false;
48531805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  }
48541805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org}
48551805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
48561805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
485704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org// This function reads an identifier name and determines whether or not it
485883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// is 'get' or 'set'.
485904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.orgHandle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get,
486004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org                                                     bool* is_set,
486104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org                                                     bool* ok) {
486204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  Handle<String> result = ParseIdentifierName(ok);
486343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!*ok) return Handle<String>();
48649e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  if (scanner().is_literal_ascii() && scanner().literal_length() == 3) {
48659e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    const char* token = scanner().literal_ascii_string().start();
48669e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    *is_get = strncmp(token, "get", 3) == 0;
48679e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    *is_set = !*is_get && strncmp(token, "set", 3) == 0;
486843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
486983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  return result;
487043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
487143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
487243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
487343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------
487443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Parser support
487543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
487643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
487743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Parser::TargetStackContainsLabel(Handle<String> label) {
4878b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4879b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    BreakableStatement* stat = t->node()->AsBreakableStatement();
488043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (stat != NULL && ContainsLabel(stat->labels(), label))
488143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return true;
488243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
488343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return false;
488443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
488543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
488643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
488743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenBreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) {
488843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool anonymous = label.is_null();
4889b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4890b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    BreakableStatement* stat = t->node()->AsBreakableStatement();
489143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (stat == NULL) continue;
489243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if ((anonymous && stat->is_target_for_anonymous()) ||
489343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        (!anonymous && ContainsLabel(stat->labels(), label))) {
4894b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org      RegisterTargetUse(stat->break_target(), t->previous());
489543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return stat;
489643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
489743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
489843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return NULL;
489943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
490043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
490143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
490243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenIterationStatement* Parser::LookupContinueTarget(Handle<String> label,
490343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                                 bool* ok) {
490443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool anonymous = label.is_null();
4905b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4906b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    IterationStatement* stat = t->node()->AsIterationStatement();
490743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (stat == NULL) continue;
490843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
490943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(stat->is_target_for_anonymous());
491043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (anonymous || ContainsLabel(stat->labels(), label)) {
4911b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org      RegisterTargetUse(stat->continue_target(), t->previous());
491243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return stat;
491343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
491443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
491543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return NULL;
491643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
491743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
491843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
491944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgvoid Parser::RegisterTargetUse(Label* target, Target* stop) {
4920b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // Register that a break target found at the given stop in the
49217be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  // target stack has been used from the top of the target stack. Add
49227be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  // the break target to any TargetCollectors passed on the stack.
4923b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  for (Target* t = target_stack_; t != stop; t = t->previous()) {
4924b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    TargetCollector* collector = t->node()->AsTargetCollector();
49257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    if (collector != NULL) collector->AddTarget(target, zone());
492643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
492743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
492843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
492943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4930dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgExpression* Parser::NewThrowReferenceError(Handle<String> message) {
49314a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  return NewThrowError(isolate()->factory()->MakeReferenceError_string(),
4932dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                       message, HandleVector<Object>(NULL, 0));
493343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
493443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
493543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4936dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgExpression* Parser::NewThrowSyntaxError(Handle<String> message,
493743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                        Handle<Object> first) {
493843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int argc = first.is_null() ? 0 : 1;
493943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Vector< Handle<Object> > arguments = HandleVector<Object>(&first, argc);
4940ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return NewThrowError(
4941dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      isolate()->factory()->MakeSyntaxError_string(), message, arguments);
494243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
494343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
494443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4945dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgExpression* Parser::NewThrowTypeError(Handle<String> message,
494643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                      Handle<Object> first,
494743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                      Handle<Object> second) {
494843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(!first.is_null() && !second.is_null());
494943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Object> elements[] = { first, second };
495043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Vector< Handle<Object> > arguments =
495143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      HandleVector<Object>(elements, ARRAY_SIZE(elements));
4952ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return NewThrowError(
4953dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      isolate()->factory()->MakeTypeError_string(), message, arguments);
495443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
495543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
495643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
495743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenExpression* Parser::NewThrowError(Handle<String> constructor,
4958dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                                  Handle<String> message,
495943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                  Vector< Handle<Object> > arguments) {
496043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int argc = arguments.length();
4961ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> elements = isolate()->factory()->NewFixedArray(argc,
4962ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                                                    TENURED);
496343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < argc; i++) {
496443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Handle<Object> element = arguments[i];
496543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (!element.is_null()) {
4966496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org      elements->set(i, *element);
496743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
496843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
4969fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements(
4970fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org      elements, FAST_ELEMENTS, TENURED);
4971496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
49727028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2, zone());
4973dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  args->Add(factory()->NewLiteral(message), zone());
49747028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  args->Add(factory()->NewLiteral(array), zone());
4975b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  CallRuntime* call_constructor =
4976b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      factory()->NewCallRuntime(constructor, NULL, args);
4977b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  return factory()->NewThrow(call_constructor, scanner().location().beg_pos);
497843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
497943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4980e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
4981b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// ----------------------------------------------------------------------------
4982a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Regular expressions
4983a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
4984a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
4985a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpParser::RegExpParser(FlatStringReader* in,
4986a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                           Handle<String>* error,
49875a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                           bool multiline,
49885a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                           Zone* zone)
4989ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    : isolate_(Isolate::Current()),
49905a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      zone_(zone),
4991ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      error_(error),
4992ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      captures_(NULL),
4993ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      in_(in),
4994ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      current_(kEndMarker),
4995ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      next_pos_(0),
4996ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      capture_count_(0),
4997ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      has_more_(true),
4998ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      multiline_(multiline),
4999ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      simple_(false),
5000ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      contains_anchor_(false),
5001ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      is_scanned_for_captures_(false),
5002ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      failed_(false) {
5003023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  Advance();
5004a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
5005a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5006a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5007a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orguc32 RegExpParser::Next() {
5008a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (has_next()) {
5009a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return in()->Get(next_pos_);
5010a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else {
5011a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return kEndMarker;
5012a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
5013a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
5014a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5015a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5016a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpParser::Advance() {
5017a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (next_pos_ < in()->length()) {
5018ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    StackLimitCheck check(isolate());
5019a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if (check.HasOverflowed()) {
5020ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      ReportError(CStrVector(Isolate::kStackOverflowMessage));
50215a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    } else if (zone()->excess_allocation()) {
5022a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      ReportError(CStrVector("Regular expression too large"));
5023a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    } else {
5024a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      current_ = in()->Get(next_pos_);
5025a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      next_pos_++;
5026a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5027a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else {
5028a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    current_ = kEndMarker;
5029a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    has_more_ = false;
5030a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
5031a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
5032a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5033a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5034a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpParser::Reset(int pos) {
5035a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  next_pos_ = pos;
503653ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  has_more_ = (pos < in()->length());
5037a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  Advance();
5038a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
5039a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5040a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5041a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpParser::Advance(int dist) {
5042023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  next_pos_ += dist - 1;
5043023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  Advance();
5044a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
5045a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5046a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
504737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.combool RegExpParser::simple() {
504837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  return simple_;
5049a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
5050a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5051e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
5052a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpTree* RegExpParser::ReportError(Vector<const char> message) {
5053a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  failed_ = true;
5054ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  *error_ = isolate()->factory()->NewStringFromAscii(message, NOT_TENURED);
5055a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // Zip to the end to make sure the no more input is read.
5056a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  current_ = kEndMarker;
5057a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  next_pos_ = in()->length();
5058a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  return NULL;
5059a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
5060a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5061a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5062a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Pattern ::
5063a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//   Disjunction
5064a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpTree* RegExpParser::ParsePattern() {
5065a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  RegExpTree* result = ParseDisjunction(CHECK_FAILED);
506686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  ASSERT(!has_more());
50677ccf02469d7fca9d9e02385346d316b5a679d4dbkasperl@chromium.org  // If the result of parsing is a literal string atom, and it has the
50687ccf02469d7fca9d9e02385346d316b5a679d4dbkasperl@chromium.org  // same length as the input, then the atom is identical to the input.
50697ccf02469d7fca9d9e02385346d316b5a679d4dbkasperl@chromium.org  if (result->IsAtom() && result->AsAtom()->length() == in()->length()) {
50707ccf02469d7fca9d9e02385346d316b5a679d4dbkasperl@chromium.org    simple_ = true;
50717ccf02469d7fca9d9e02385346d316b5a679d4dbkasperl@chromium.org  }
5072a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  return result;
5073a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
5074a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5075a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5076a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Disjunction ::
5077a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//   Alternative
5078a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//   Alternative | Disjunction
5079a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Alternative ::
5080a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//   [empty]
5081a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//   Term Alternative
5082a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Term ::
5083a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//   Assertion
5084a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//   Atom
5085a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//   Atom Quantifier
5086a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpTree* RegExpParser::ParseDisjunction() {
508786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // Used to store current state while parsing subexpressions.
5088400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  RegExpParserState initial_state(NULL, INITIAL, 0, zone());
508986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  RegExpParserState* stored_state = &initial_state;
509086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // Cache the builder in a local variable for quick access.
509186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  RegExpBuilder* builder = initial_state.builder();
5092a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  while (true) {
5093a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    switch (current()) {
5094a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case kEndMarker:
509586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      if (stored_state->IsSubexpression()) {
509686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        // Inside a parenthesized group when hitting end of input.
509786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        ReportError(CStrVector("Unterminated group") CHECK_FAILED);
509886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      }
509986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      ASSERT_EQ(INITIAL, stored_state->group_type());
510086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      // Parsing completed successfully.
510186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      return builder->ToRegExp();
510286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org    case ')': {
510386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      if (!stored_state->IsSubexpression()) {
510486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        ReportError(CStrVector("Unmatched ')'") CHECK_FAILED);
510586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      }
510686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      ASSERT_NE(INITIAL, stored_state->group_type());
510786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
5108a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
510986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      // End disjunction parsing and convert builder content to new single
511086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      // regexp atom.
511186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      RegExpTree* body = builder->ToRegExp();
511286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
511386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      int end_capture_index = captures_started();
511486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
511586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      int capture_index = stored_state->capture_index();
5116dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      SubexpressionType group_type = stored_state->group_type();
511786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
511886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      // Restore previous state.
511986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      stored_state = stored_state->previous_state();
512086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      builder = stored_state->builder();
512186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
512286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      // Build result of subexpression.
5123dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      if (group_type == CAPTURE) {
5124c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org        RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index);
512586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        captures_->at(capture_index - 1) = capture;
512686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        body = capture;
5127dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      } else if (group_type != GROUPING) {
5128dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org        ASSERT(group_type == POSITIVE_LOOKAHEAD ||
5129dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org               group_type == NEGATIVE_LOOKAHEAD);
5130dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org        bool is_positive = (group_type == POSITIVE_LOOKAHEAD);
5131c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org        body = new(zone()) RegExpLookahead(body,
513286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org                                   is_positive,
513386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org                                   end_capture_index - capture_index,
513486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org                                   capture_index);
5135a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
513686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      builder->AddAtom(body);
513749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org      // For compatability with JSC and ES3, we allow quantifiers after
513849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org      // lookaheads, and break in all cases.
513986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      break;
514086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org    }
514186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org    case '|': {
514286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      Advance();
514386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      builder->NewAlternative();
5144a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      continue;
5145a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5146a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case '*':
5147a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case '+':
5148a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case '?':
5149e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org      return ReportError(CStrVector("Nothing to repeat"));
5150a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case '^': {
5151a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5152245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org      if (multiline_) {
515386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        builder->AddAssertion(
5154c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org            new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE));
5155245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org      } else {
515686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        builder->AddAssertion(
5157c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org            new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
5158245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org        set_contains_anchor();
5159245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org      }
5160a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      continue;
5161a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5162a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case '$': {
5163a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5164dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      RegExpAssertion::AssertionType assertion_type =
5165a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          multiline_ ? RegExpAssertion::END_OF_LINE :
5166a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                       RegExpAssertion::END_OF_INPUT;
5167dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      builder->AddAssertion(new(zone()) RegExpAssertion(assertion_type));
5168a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      continue;
5169a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5170a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case '.': {
5171a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5172a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      // everything except \x0a, \x0d, \u2028 and \u2029
517340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org      ZoneList<CharacterRange>* ranges =
51747028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org          new(zone()) ZoneList<CharacterRange>(2, zone());
51757028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      CharacterRange::AddClassEscape('.', ranges, zone());
5176c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
517786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      builder->AddAtom(atom);
5178a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      break;
5179a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5180a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case '(': {
5181dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      SubexpressionType subexpr_type = CAPTURE;
518286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      Advance();
518386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      if (current() == '?') {
518486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        switch (Next()) {
518586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org          case ':':
5186dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org            subexpr_type = GROUPING;
518786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org            break;
518886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org          case '=':
5189dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org            subexpr_type = POSITIVE_LOOKAHEAD;
519086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org            break;
519186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org          case '!':
5192dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org            subexpr_type = NEGATIVE_LOOKAHEAD;
519386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org            break;
519486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org          default:
519586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org            ReportError(CStrVector("Invalid group") CHECK_FAILED);
519686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org            break;
519786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        }
519886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        Advance(2);
519986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      } else {
520086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        if (captures_ == NULL) {
52017028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org          captures_ = new(zone()) ZoneList<RegExpCapture*>(2, zone());
520286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        }
520386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        if (captures_started() >= kMaxCaptures) {
520486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org          ReportError(CStrVector("Too many captures") CHECK_FAILED);
520586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        }
52067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        captures_->Add(NULL, zone());
520786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      }
520886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      // Store current state and begin new disjunction parsing.
5209dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      stored_state = new(zone()) RegExpParserState(stored_state, subexpr_type,
5210400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org                                                   captures_started(), zone());
521186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      builder = stored_state->builder();
521249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org      continue;
5213a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5214a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case '[': {
5215a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      RegExpTree* atom = ParseCharacterClass(CHECK_FAILED);
521686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      builder->AddAtom(atom);
5217a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      break;
5218a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5219a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    // Atom ::
5220a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    //   \ AtomEscape
5221a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case '\\':
5222a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      switch (Next()) {
5223a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case kEndMarker:
5224e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org        return ReportError(CStrVector("\\ at end of pattern"));
5225a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case 'b':
5226a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        Advance(2);
522786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        builder->AddAssertion(
5228c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org            new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
5229a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        continue;
5230a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case 'B':
5231a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        Advance(2);
523286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        builder->AddAssertion(
5233c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org            new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
5234a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        continue;
523549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org      // AtomEscape ::
523649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org      //   CharacterClassEscape
523749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org      //
523849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org      // CharacterClassEscape :: one of
523949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org      //   d D s S w W
5240a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case 'd': case 'D': case 's': case 'S': case 'w': case 'W': {
5241a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        uc32 c = Next();
5242a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        Advance(2);
524340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org        ZoneList<CharacterRange>* ranges =
52447028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org            new(zone()) ZoneList<CharacterRange>(2, zone());
52457028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        CharacterRange::AddClassEscape(c, ranges, zone());
5246c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org        RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
524786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        builder->AddAtom(atom);
524886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        break;
5249a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
5250a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case '1': case '2': case '3': case '4': case '5': case '6':
5251a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case '7': case '8': case '9': {
5252a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        int index = 0;
5253a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if (ParseBackReferenceIndex(&index)) {
525486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org          RegExpCapture* capture = NULL;
525586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org          if (captures_ != NULL && index <= captures_->length()) {
525686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org            capture = captures_->at(index - 1);
525786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org          }
525886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org          if (capture == NULL) {
525986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org            builder->AddEmpty();
526086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org            break;
5261a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          }
5262c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org          RegExpTree* atom = new(zone()) RegExpBackReference(capture);
526386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org          builder->AddAtom(atom);
526486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org          break;
5265a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
5266a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        uc32 first_digit = Next();
5267a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if (first_digit == '8' || first_digit == '9') {
5268a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          // Treat as identity escape
526986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org          builder->AddCharacter(first_digit);
5270a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          Advance(2);
5271a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          break;
5272a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
5273a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
5274a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      // FALLTHROUGH
5275a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case '0': {
5276a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        Advance();
5277a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        uc32 octal = ParseOctalLiteral();
527886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        builder->AddCharacter(octal);
5279a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
5280a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
5281a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      // ControlEscape :: one of
5282a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      //   f n r t v
5283a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case 'f':
5284a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        Advance(2);
528586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        builder->AddCharacter('\f');
5286a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
5287a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case 'n':
5288a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        Advance(2);
528986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        builder->AddCharacter('\n');
5290a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
5291a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case 'r':
5292a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        Advance(2);
529386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        builder->AddCharacter('\r');
5294a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
5295a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case 't':
5296a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        Advance(2);
529786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        builder->AddCharacter('\t');
5298a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
5299a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case 'v':
5300a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        Advance(2);
530186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        builder->AddCharacter('\v');
5302a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
5303a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case 'c': {
5304d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org        Advance();
5305d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org        uc32 controlLetter = Next();
5306d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org        // Special case if it is an ASCII letter.
5307d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org        // Convert lower case letters to uppercase.
5308d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org        uc32 letter = controlLetter & ~('a' ^ 'A');
5309d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org        if (letter < 'A' || 'Z' < letter) {
5310d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org          // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
5311d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org          // This is outside the specification. We match JSC in
5312d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org          // reading the backslash as a literal character instead
5313d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org          // of as starting an escape.
5314d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org          builder->AddCharacter('\\');
5315d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org        } else {
5316d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org          Advance(2);
5317d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org          builder->AddCharacter(controlLetter & 0x1f);
5318d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org        }
5319a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
5320a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
5321a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case 'x': {
5322a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        Advance(2);
5323a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        uc32 value;
5324a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if (ParseHexEscape(2, &value)) {
532586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org          builder->AddCharacter(value);
5326a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        } else {
532786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org          builder->AddCharacter('x');
5328a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
5329a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
5330a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
5331a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case 'u': {
5332a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        Advance(2);
5333a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        uc32 value;
5334a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if (ParseHexEscape(4, &value)) {
533586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org          builder->AddCharacter(value);
5336a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        } else {
533786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org          builder->AddCharacter('u');
5338a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
5339a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
5340a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
5341a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      default:
5342a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        // Identity escape.
534386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        builder->AddCharacter(Next());
5344a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        Advance(2);
5345a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
5346a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
5347a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      break;
5348a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case '{': {
5349a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      int dummy;
5350a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if (ParseIntervalQuantifier(&dummy, &dummy)) {
5351a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        ReportError(CStrVector("Nothing to repeat") CHECK_FAILED);
5352a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
5353a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      // fallthrough
5354a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5355a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    default:
535686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      builder->AddCharacter(current());
5357a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5358a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      break;
5359a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }  // end switch(current())
5360a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5361a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    int min;
5362a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    int max;
5363a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    switch (current()) {
5364a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    // QuantifierPrefix ::
5365a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    //   *
5366a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    //   +
5367a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    //   ?
5368a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    //   {
5369a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case '*':
5370a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      min = 0;
537137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      max = RegExpTree::kInfinity;
5372a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5373a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      break;
5374a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case '+':
5375a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      min = 1;
537637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      max = RegExpTree::kInfinity;
5377a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5378a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      break;
5379a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case '?':
5380a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      min = 0;
5381a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      max = 1;
5382a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5383a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      break;
5384a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case '{':
5385a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if (ParseIntervalQuantifier(&min, &max)) {
5386245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org        if (max < min) {
5387245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org          ReportError(CStrVector("numbers out of order in {} quantifier.")
5388245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org                      CHECK_FAILED);
5389245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org        }
5390a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
5391a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      } else {
5392a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        continue;
5393a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
5394a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    default:
5395a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      continue;
5396a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5397dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    RegExpQuantifier::QuantifierType quantifier_type = RegExpQuantifier::GREEDY;
5398a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if (current() == '?') {
5399dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      quantifier_type = RegExpQuantifier::NON_GREEDY;
54000c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      Advance();
54010c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    } else if (FLAG_regexp_possessive_quantifier && current() == '+') {
54020c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      // FLAG_regexp_possessive_quantifier is a debug-only flag.
5403dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      quantifier_type = RegExpQuantifier::POSSESSIVE;
5404a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5405a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5406dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    builder->AddQuantifierToAtom(min, max, quantifier_type);
5407a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
5408a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
5409a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5410a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5411a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#ifdef DEBUG
5412a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Currently only used in an ASSERT.
5413a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgstatic bool IsSpecialClassEscape(uc32 c) {
5414a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  switch (c) {
5415a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case 'd': case 'D':
5416a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case 's': case 'S':
5417a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case 'w': case 'W':
5418a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      return true;
5419a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    default:
5420a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      return false;
5421a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
5422a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
5423a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#endif
5424a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5425a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5426a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// In order to know whether an escape is a backreference or not we have to scan
5427a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// the entire regexp and find the number of capturing parentheses.  However we
5428a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// don't want to scan the regexp twice unless it is necessary.  This mini-parser
5429a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// is called when needed.  It can see the difference between capturing and
5430a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// noncapturing parentheses and can skip character classes and backslash-escaped
5431a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// characters.
5432a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpParser::ScanForCaptures() {
5433a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // Start with captures started previous to current position
5434a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  int capture_count = captures_started();
5435a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // Add count of captures after this position.
5436a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  int n;
5437a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  while ((n = current()) != kEndMarker) {
5438a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    Advance();
5439a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    switch (n) {
5440a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case '\\':
5441a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        Advance();
5442a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
5443a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case '[': {
5444a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        int c;
5445a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        while ((c = current()) != kEndMarker) {
5446a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          Advance();
5447a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          if (c == '\\') {
5448a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org            Advance();
5449a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          } else {
5450a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org            if (c == ']') break;
5451a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          }
5452a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
5453a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
5454a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
5455a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case '(':
5456a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if (current() != '?') capture_count++;
5457a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
5458a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5459a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
5460a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  capture_count_ = capture_count;
5461a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  is_scanned_for_captures_ = true;
5462a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
5463a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5464a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5465a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgbool RegExpParser::ParseBackReferenceIndex(int* index_out) {
5466a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  ASSERT_EQ('\\', current());
5467a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  ASSERT('1' <= Next() && Next() <= '9');
5468245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org  // Try to parse a decimal literal that is no greater than the total number
5469245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org  // of left capturing parentheses in the input.
5470a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  int start = position();
5471a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  int value = Next() - '0';
5472a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  Advance(2);
5473a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  while (true) {
5474a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    uc32 c = current();
5475a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if (IsDecimalDigit(c)) {
5476a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      value = 10 * value + (c - '0');
5477245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org      if (value > kMaxCaptures) {
5478245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org        Reset(start);
5479245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org        return false;
5480245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org      }
5481a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5482a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    } else {
5483a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      break;
5484a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5485a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
5486a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (value > captures_started()) {
5487a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if (!is_scanned_for_captures_) {
5488a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      int saved_position = position();
5489a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      ScanForCaptures();
5490a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Reset(saved_position);
5491a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5492a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if (value > capture_count_) {
5493a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Reset(start);
5494a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      return false;
5495a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5496a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
5497a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  *index_out = value;
5498a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  return true;
5499a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
5500a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5501a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5502a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// QuantifierPrefix ::
5503a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//   { DecimalDigits }
5504a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//   { DecimalDigits , }
5505a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//   { DecimalDigits , DecimalDigits }
5506245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org//
5507245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// Returns true if parsing succeeds, and set the min_out and max_out
5508245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// values. Values are truncated to RegExpTree::kInfinity if they overflow.
5509a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgbool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
5510a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  ASSERT_EQ(current(), '{');
5511a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  int start = position();
5512a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  Advance();
5513a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  int min = 0;
5514a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (!IsDecimalDigit(current())) {
5515a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    Reset(start);
5516a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return false;
5517a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
5518a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  while (IsDecimalDigit(current())) {
5519245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    int next = current() - '0';
5520245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    if (min > (RegExpTree::kInfinity - next) / 10) {
5521245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org      // Overflow. Skip past remaining decimal digits and return -1.
5522245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org      do {
5523245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org        Advance();
5524245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org      } while (IsDecimalDigit(current()));
5525245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org      min = RegExpTree::kInfinity;
5526245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org      break;
5527245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    }
5528245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    min = 10 * min + next;
5529a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    Advance();
5530a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
5531a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  int max = 0;
5532a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (current() == '}') {
5533a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    max = min;
5534a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    Advance();
5535a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else if (current() == ',') {
5536a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    Advance();
5537a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if (current() == '}') {
553837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      max = RegExpTree::kInfinity;
5539a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5540a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    } else {
5541a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      while (IsDecimalDigit(current())) {
5542245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org        int next = current() - '0';
5543245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org        if (max > (RegExpTree::kInfinity - next) / 10) {
5544245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org          do {
5545245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org            Advance();
5546245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org          } while (IsDecimalDigit(current()));
5547245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org          max = RegExpTree::kInfinity;
5548245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org          break;
5549245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org        }
5550245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org        max = 10 * max + next;
5551a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        Advance();
5552a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
5553a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if (current() != '}') {
5554a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        Reset(start);
5555a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        return false;
5556a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
5557a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5558a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5559a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else {
5560a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    Reset(start);
5561a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return false;
5562a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
5563a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  *min_out = min;
5564a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  *max_out = max;
5565a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  return true;
5566a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
5567a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5568a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5569a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orguc32 RegExpParser::ParseOctalLiteral() {
5570a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  ASSERT('0' <= current() && current() <= '7');
5571a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // For compatibility with some other browsers (not all), we parse
5572a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // up to three octal digits with a value below 256.
5573a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  uc32 value = current() - '0';
5574a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  Advance();
5575a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if ('0' <= current() && current() <= '7') {
5576a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    value = value * 8 + current() - '0';
5577a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    Advance();
5578a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if (value < 32 && '0' <= current() && current() <= '7') {
5579a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      value = value * 8 + current() - '0';
5580a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5581a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5582a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
5583a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  return value;
5584a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
5585a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5586a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5587a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgbool RegExpParser::ParseHexEscape(int length, uc32 *value) {
5588a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  int start = position();
5589a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  uc32 val = 0;
5590a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  bool done = false;
5591a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  for (int i = 0; !done; i++) {
5592a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    uc32 c = current();
5593a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    int d = HexValue(c);
5594a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if (d < 0) {
5595a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Reset(start);
5596a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      return false;
5597a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5598a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    val = val * 16 + d;
5599a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    Advance();
5600a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if (i == length - 1) {
5601a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      done = true;
5602a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5603a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
5604a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  *value = val;
5605a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  return true;
5606a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
5607a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5608a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5609a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orguc32 RegExpParser::ParseClassCharacterEscape() {
5610a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  ASSERT(current() == '\\');
5611a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  ASSERT(has_next() && !IsSpecialClassEscape(Next()));
5612a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  Advance();
5613a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  switch (current()) {
5614a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case 'b':
5615a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5616a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      return '\b';
5617a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    // ControlEscape :: one of
5618a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    //   f n r t v
5619a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case 'f':
5620a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5621a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      return '\f';
5622a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case 'n':
5623a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5624a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      return '\n';
5625a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case 'r':
5626a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5627a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      return '\r';
5628a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case 't':
5629a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5630a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      return '\t';
5631a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case 'v':
5632a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5633a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      return '\v';
5634d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    case 'c': {
5635d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org      uc32 controlLetter = Next();
5636d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org      uc32 letter = controlLetter & ~('A' ^ 'a');
5637d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org      // For compatibility with JSC, inside a character class
5638d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org      // we also accept digits and underscore as control characters.
5639d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org      if ((controlLetter >= '0' && controlLetter <= '9') ||
5640d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org          controlLetter == '_' ||
5641d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org          (letter >= 'A' && letter <= 'Z')) {
5642d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org        Advance(2);
5643d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org        // Control letters mapped to ASCII control characters in the range
5644d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org        // 0x00-0x1f.
5645d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org        return controlLetter & 0x1f;
5646d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org      }
5647d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org      // We match JSC in reading the backslash as a literal
5648d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org      // character instead of as starting an escape.
5649d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org      return '\\';
5650d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    }
5651a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case '0': case '1': case '2': case '3': case '4': case '5':
5652a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case '6': case '7':
5653a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      // For compatibility, we interpret a decimal escape that isn't
5654a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      // a back reference (and therefore either \0 or not valid according
5655a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      // to the specification) as a 1..3 digit octal character code.
5656a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      return ParseOctalLiteral();
5657a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case 'x': {
5658a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5659a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      uc32 value;
5660a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if (ParseHexEscape(2, &value)) {
5661a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        return value;
5662a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
5663a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      // If \x is not followed by a two-digit hexadecimal, treat it
5664a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      // as an identity escape.
5665a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      return 'x';
5666a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5667a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    case 'u': {
5668a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5669a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      uc32 value;
5670a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if (ParseHexEscape(4, &value)) {
5671a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        return value;
5672a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
5673a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      // If \u is not followed by a four-digit hexadecimal, treat it
5674a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      // as an identity escape.
5675a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      return 'u';
5676a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5677a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    default: {
5678a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      // Extended identity escape. We accept any character that hasn't
5679a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      // been matched by a more specific case, not just the subset required
5680a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      // by the ECMAScript specification.
5681a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      uc32 result = current();
5682a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5683a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      return result;
5684a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5685a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
5686a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  return 0;
5687a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
5688a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5689a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5690a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgCharacterRange RegExpParser::ParseClassAtom(uc16* char_class) {
5691a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  ASSERT_EQ(0, *char_class);
5692a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  uc32 first = current();
5693a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (first == '\\') {
5694a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    switch (Next()) {
5695a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case 'w': case 'W': case 'd': case 'D': case 's': case 'S': {
5696a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        *char_class = Next();
5697a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        Advance(2);
5698a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        return CharacterRange::Singleton(0);  // Return dummy value.
5699a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
570037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      case kEndMarker:
5701e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org        return ReportError(CStrVector("\\ at end of pattern"));
5702a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      default:
5703a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        uc32 c = ParseClassCharacterEscape(CHECK_FAILED);
5704a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        return CharacterRange::Singleton(c);
5705a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5706a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else {
5707a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    Advance();
5708a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return CharacterRange::Singleton(first);
5709a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
5710a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
5711a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5712a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
571314a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.orgstatic const uc16 kNoCharClass = 0;
571414a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org
571514a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org// Adds range or pre-defined character class to character ranges.
571614a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org// If char_class is not kInvalidClass, it's interpreted as a class
571714a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org// escape (i.e., 's' means whitespace, from '\s').
571814a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.orgstatic inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges,
571914a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org                                    uc16 char_class,
57207028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                    CharacterRange range,
57217028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                    Zone* zone) {
572214a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org  if (char_class != kNoCharClass) {
57237028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    CharacterRange::AddClassEscape(char_class, ranges, zone);
572414a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org  } else {
57257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    ranges->Add(range, zone);
572614a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org  }
572714a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org}
572814a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org
572914a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org
5730a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpTree* RegExpParser::ParseCharacterClass() {
5731a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  static const char* kUnterminated = "Unterminated character class";
5732a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  static const char* kRangeOutOfOrder = "Range out of order in character class";
5733a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5734a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  ASSERT_EQ(current(), '[');
5735a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  Advance();
5736a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  bool is_negated = false;
5737a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (current() == '^') {
5738a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    is_negated = true;
5739a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    Advance();
5740a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
57417028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  ZoneList<CharacterRange>* ranges =
57427028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      new(zone()) ZoneList<CharacterRange>(2, zone());
5743a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  while (has_more() && current() != ']') {
574414a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org    uc16 char_class = kNoCharClass;
5745a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED);
5746a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if (current() == '-') {
5747a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Advance();
5748a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if (current() == kEndMarker) {
5749a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        // If we reach the end we break out of the loop and let the
5750a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        // following code report an error.
5751a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
5752a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      } else if (current() == ']') {
57537028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        AddRangeOrEscape(ranges, char_class, first, zone());
57547028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        ranges->Add(CharacterRange::Singleton('-'), zone());
5755a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
5756a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
575714a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org      uc16 char_class_2 = kNoCharClass;
575814a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org      CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED);
575914a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org      if (char_class != kNoCharClass || char_class_2 != kNoCharClass) {
576014a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org        // Either end is an escaped character class. Treat the '-' verbatim.
57617028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        AddRangeOrEscape(ranges, char_class, first, zone());
57627028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        ranges->Add(CharacterRange::Singleton('-'), zone());
57637028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        AddRangeOrEscape(ranges, char_class_2, next, zone());
576414a7035652e3bc60a2172d11dc9b8850e4efce3alrn@chromium.org        continue;
5765a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
5766a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if (first.from() > next.to()) {
5767a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED);
5768a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
57697028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      ranges->Add(CharacterRange::Range(first.from(), next.to()), zone());
5770a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    } else {
57717028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      AddRangeOrEscape(ranges, char_class, first, zone());
5772a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
5773a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
5774a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (!has_more()) {
5775a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return ReportError(CStrVector(kUnterminated) CHECK_FAILED);
5776a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
5777a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  Advance();
5778a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (ranges->length() == 0) {
57797028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    ranges->Add(CharacterRange::Everything(), zone());
5780a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    is_negated = !is_negated;
5781a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
5782c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  return new(zone()) RegExpCharacterClass(ranges, is_negated);
5783a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
5784a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5785a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5786a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// ----------------------------------------------------------------------------
578743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The Parser interface.
578843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
578943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenParserMessage::~ParserMessage() {
579043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < args().length(); i++)
579143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    DeleteArray(args()[i]);
579243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  DeleteArray(args().start());
579343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
579443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
579543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
579643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenScriptDataImpl::~ScriptDataImpl() {
57975b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  if (owns_store_) store_.Dispose();
579843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
579943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
580043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
580143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint ScriptDataImpl::Length() {
58029155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  return store_.length() * sizeof(unsigned);
580343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
580443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
580543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
58069155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.orgconst char* ScriptDataImpl::Data() {
58079155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  return reinterpret_cast<const char*>(store_.start());
580843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
580943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
581043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
58110c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgbool ScriptDataImpl::HasError() {
58120c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  return has_error();
58130c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org}
58140c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
58150c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
5816d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.comvoid ScriptDataImpl::Initialize() {
5817c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  // Prepares state for use.
5818beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  if (store_.length() >= PreparseDataConstants::kHeaderSize) {
5819beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    function_index_ = PreparseDataConstants::kHeaderSize;
5820beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    int symbol_data_offset = PreparseDataConstants::kHeaderSize
5821beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org        + store_[PreparseDataConstants::kFunctionsSizeOffset];
5822d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    if (store_.length() > symbol_data_offset) {
5823d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com      symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]);
5824d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    } else {
5825d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com      // Partial preparse causes no symbol information.
5826d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com      symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
5827d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    }
5828d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    symbol_data_end_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
5829d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  }
5830d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com}
5831d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com
5832d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com
5833d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.comint ScriptDataImpl::ReadNumber(byte** source) {
5834d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  // Reads a number from symbol_data_ in base 128. The most significant
5835d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  // bit marks that there are more digits.
5836d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  // If the first byte is 0x80 (kNumberTerminator), it would normally
5837d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  // represent a leading zero. Since that is useless, and therefore won't
5838d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  // appear as the first digit of any actual value, it is used to
5839d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  // mark the end of the input stream.
5840d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  byte* data = *source;
5841d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  if (data >= symbol_data_end_) return -1;
5842d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  byte input = *data;
5843beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  if (input == PreparseDataConstants::kNumberTerminator) {
5844d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    // End of stream marker.
5845d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    return -1;
5846d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  }
5847d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  int result = input & 0x7f;
5848d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  data++;
5849d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  while ((input & 0x80u) != 0) {
5850d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    if (data >= symbol_data_end_) return -1;
5851d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    input = *data;
5852d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    result = (result << 7) | (input & 0x7f);
5853d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    data++;
5854d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  }
5855d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  *source = data;
5856d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  return result;
5857d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com}
5858d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com
5859d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com
586021b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org// Create a Scanner for the preparser to use as input, and preparse the source.
5861e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgScriptDataImpl* PreParserApi::PreParse(Utf16CharacterStream* source) {
5862e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  CompleteParserRecorder recorder;
5863ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate = Isolate::Current();
58641b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  HistogramTimerScope timer(isolate->counters()->pre_parse());
5865c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Scanner scanner(isolate->unicode_cache());
5866ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  intptr_t stack_limit = isolate->stack_guard()->real_climit();
5867e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  preparser::PreParser preparser(&scanner, &recorder, stack_limit);
5868e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  preparser.set_allow_lazy(true);
5869e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  preparser.set_allow_generators(FLAG_harmony_generators);
58701fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  preparser.set_allow_for_of(FLAG_harmony_iteration);
5871e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  preparser.set_allow_harmony_scoping(FLAG_harmony_scoping);
5872ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  preparser.set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
5873e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  scanner.Initialize(source);
5874e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  preparser::PreParser::PreParseResult result = preparser.PreParseProgram();
58751b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  if (result == preparser::PreParser::kPreParseStackOverflow) {
5876ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate->StackOverflow();
58774a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    return NULL;
58784a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
58794a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
58804a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Extract the accumulated data from the recorder as a single
58814a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // contiguous vector that we are responsible for disposing.
5882e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Vector<unsigned> store = recorder.ExtractData();
58834a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  return new ScriptDataImpl(store);
58844a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
58854a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
58864a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
5887e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.orgbool RegExpParser::ParseRegExp(FlatStringReader* input,
5888e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org                               bool multiline,
58895a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                               RegExpCompileData* result,
58905a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                               Zone* zone) {
5891a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  ASSERT(result != NULL);
58925a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  RegExpParser parser(input, &result->error, multiline, zone);
589337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  RegExpTree* tree = parser.ParsePattern();
5894a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (parser.failed()) {
589537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    ASSERT(tree == NULL);
5896a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    ASSERT(!result->error.is_null());
5897a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else {
589837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    ASSERT(tree != NULL);
5899a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    ASSERT(result->error.is_null());
590037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    result->tree = tree;
590137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    int capture_count = parser.captures_started();
590237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
5903245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    result->contains_anchor = parser.contains_anchor();
590437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    result->capture_count = capture_count;
5905a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
5906a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  return !parser.failed();
5907a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
5908a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5909a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
5910e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgbool Parser::Parse() {
5911e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ASSERT(info()->function() == NULL);
5912b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org  FunctionLiteral* result = NULL;
5913e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (info()->is_lazy()) {
5914e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    ASSERT(!info()->is_eval());
5915e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (info()->shared_info()->is_function()) {
5916e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      result = ParseLazy();
591756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org    } else {
5918e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      result = ParseProgram();
591956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org    }
5920b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  } else {
5921e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    ScriptDataImpl* pre_parse_data = info()->pre_parse_data();
5922e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    set_pre_parse_data(pre_parse_data);
5923e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (pre_parse_data != NULL && pre_parse_data->has_error()) {
5924e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      Scanner::Location loc = pre_parse_data->MessageLocation();
5925e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      const char* message = pre_parse_data->BuildMessage();
5926e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      Vector<const char*> args = pre_parse_data->BuildArgs();
5927e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      ReportMessageAt(loc, message, args);
5928b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org      DeleteArray(message);
5929b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org      for (int i = 0; i < args.length(); i++) {
5930b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org        DeleteArray(args[i]);
5931b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org      }
5932b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org      DeleteArray(args.start());
5933e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      ASSERT(info()->isolate()->has_pending_exception());
5934b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org    } else {
5935e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      result = ParseProgram();
5936b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org    }
5937b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
5938e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  info()->SetFunction(result);
5939b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org  return (result != NULL);
594043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
594143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
594243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
5943