1fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
6196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
7196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/api.h"
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/ast.h"
9b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org#include "src/bailout-reason.h"
105de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/platform/platform.h"
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/bootstrapper.h"
12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/char-predicates-inl.h"
13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h"
14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/compiler.h"
15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/messages.h"
16196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/parser.h"
17196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/preparser.h"
18196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/runtime.h"
19196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/scanner-character-streams.h"
20196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/scopeinfo.h"
21196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/string-stream.h"
2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
2471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.orgRegExpBuilder::RegExpBuilder(Zone* zone)
27400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org    : zone_(zone),
28c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      pending_empty_(false),
29c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      characters_(NULL),
30c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      terms_(),
31c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      alternatives_()
32a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#ifdef DEBUG
33c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    , last_added_(ADD_NONE)
34a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#endif
35a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  {}
36a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
37a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
38a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::FlushCharacters() {
39a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  pending_empty_ = false;
40a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (characters_ != NULL) {
41c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector());
42a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    characters_ = NULL;
437028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    text_.Add(atom, zone());
44a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    LAST(ADD_ATOM);
45a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
46a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
47a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
48a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
49a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::FlushText() {
50a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  FlushCharacters();
51a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  int num_text = text_.length();
52a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (num_text == 0) {
53a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return;
54a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else if (num_text == 1) {
557028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    terms_.Add(text_.last(), zone());
56a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else {
577028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    RegExpText* text = new(zone()) RegExpText(zone());
58a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    for (int i = 0; i < num_text; i++)
597028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      text_.Get(i)->AppendToText(text, zone());
607028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    terms_.Add(text, zone());
61a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
62a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  text_.Clear();
63a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
64a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
65a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
66a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::AddCharacter(uc16 c) {
67a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  pending_empty_ = false;
68a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (characters_ == NULL) {
697028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    characters_ = new(zone()) ZoneList<uc16>(4, zone());
70a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
717028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  characters_->Add(c, zone());
72a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  LAST(ADD_CHAR);
73a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
74a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
75a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
76a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::AddEmpty() {
77a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  pending_empty_ = true;
78a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
79a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
80a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
81a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::AddAtom(RegExpTree* term) {
82a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (term->IsEmpty()) {
83a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    AddEmpty();
84a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return;
85a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
86a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (term->IsTextElement()) {
87a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    FlushCharacters();
887028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    text_.Add(term, zone());
89a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else {
90a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    FlushText();
917028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    terms_.Add(term, zone());
92a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
93a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  LAST(ADD_ATOM);
94a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
95a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
96a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
97a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::AddAssertion(RegExpTree* assert) {
98a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  FlushText();
997028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  terms_.Add(assert, zone());
100a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  LAST(ADD_ASSERT);
101a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
102a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
103a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
104a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::NewAlternative() {
105a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  FlushTerms();
106a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
107a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
108a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
109a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpBuilder::FlushTerms() {
110a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  FlushText();
111a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  int num_terms = terms_.length();
112a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  RegExpTree* alternative;
113a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (num_terms == 0) {
114a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    alternative = RegExpEmpty::GetInstance();
115a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else if (num_terms == 1) {
116a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    alternative = terms_.last();
117a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else {
1187028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    alternative = new(zone()) RegExpAlternative(terms_.GetList(zone()));
119a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
1207028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  alternatives_.Add(alternative, zone());
121a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  terms_.Clear();
122a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  LAST(ADD_NONE);
123a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
124a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
125a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
126a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpTree* RegExpBuilder::ToRegExp() {
127a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  FlushTerms();
128a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  int num_alternatives = alternatives_.length();
129a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (num_alternatives == 0) {
130a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return RegExpEmpty::GetInstance();
131a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
132a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (num_alternatives == 1) {
133a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return alternatives_.last();
134a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
1357028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  return new(zone()) RegExpDisjunction(alternatives_.GetList(zone()));
136a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
137a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
138a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
139dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgvoid RegExpBuilder::AddQuantifierToAtom(
140dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    int min, int max, RegExpQuantifier::QuantifierType quantifier_type) {
141a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (pending_empty_) {
142a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    pending_empty_ = false;
143a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return;
144a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
145a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  RegExpTree* atom;
146a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (characters_ != NULL) {
147e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(last_added_ == ADD_CHAR);
148a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    // Last atom was character.
149a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    Vector<const uc16> char_vector = characters_->ToConstVector();
150a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    int num_chars = char_vector.length();
151a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if (num_chars > 1) {
152a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1);
1537028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      text_.Add(new(zone()) RegExpAtom(prefix), zone());
154a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      char_vector = char_vector.SubVector(num_chars - 1, num_chars);
155a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
156a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    characters_ = NULL;
157c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    atom = new(zone()) RegExpAtom(char_vector);
158a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    FlushText();
159a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else if (text_.length() > 0) {
160e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(last_added_ == ADD_ATOM);
161a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    atom = text_.RemoveLast();
162a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    FlushText();
163a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else if (terms_.length() > 0) {
164e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(last_added_ == ADD_ATOM);
165a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    atom = terms_.RemoveLast();
16637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    if (atom->max_match() == 0) {
16737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      // Guaranteed to only match an empty string.
168a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      LAST(ADD_TERM);
169a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if (min == 0) {
170a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        return;
171a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
1727028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      terms_.Add(atom, zone());
173a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      return;
174a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
175a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else {
176a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    // Only call immediately after adding an atom or character!
177a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    UNREACHABLE();
178a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return;
179a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
180dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  terms_.Add(
181dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone());
182a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  LAST(ADD_TERM);
183a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
184a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
185a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
18670d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgFunctionEntry ParseData::GetFunctionEntry(int start) {
187d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // The current pre-data entry must be a FunctionEntry with the given
188d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // start position.
18970d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  if ((function_index_ + FunctionEntry::kSize <= Length()) &&
19070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      (static_cast<int>(Data()[function_index_]) == start)) {
1915b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org    int index = function_index_;
1925b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org    function_index_ += FunctionEntry::kSize;
19370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize);
19470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    return FunctionEntry(subvector);
19543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
19643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return FunctionEntry();
19743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
19843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
19943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
20070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgint ParseData::FunctionCount() {
20170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  int functions_size = FunctionsSize();
20270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  if (functions_size < 0) return 0;
20370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  if (functions_size % FunctionEntry::kSize != 0) return 0;
20470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  return functions_size / FunctionEntry::kSize;
2055b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org}
2065b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org
2075b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org
20870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgbool ParseData::IsSane() {
2095b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  // Check that the header data is valid and doesn't specify
2105b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  // point to positions outside the store.
21170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  int data_length = Length();
21270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  if (data_length < PreparseDataConstants::kHeaderSize) return false;
21370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  if (Magic() != PreparseDataConstants::kMagicNumber) return false;
21470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  if (Version() != PreparseDataConstants::kCurrentVersion) return false;
21570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  if (HasError()) return false;
2165b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  // Check that the space allocated for function entries is sane.
21770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  int functions_size = FunctionsSize();
2185b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  if (functions_size < 0) return false;
2195b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  if (functions_size % FunctionEntry::kSize != 0) return false;
220d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  // Check that the total size has room for header and function entries.
2215b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  int minimum_size =
222beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org      PreparseDataConstants::kHeaderSize + functions_size;
22370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  if (data_length < minimum_size) return false;
22443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return true;
22543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
22643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
22743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
22870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgvoid ParseData::Initialize() {
22970d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  // Prepares state for use.
23070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  int data_length = Length();
23170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  if (data_length >= PreparseDataConstants::kHeaderSize) {
23270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    function_index_ = PreparseDataConstants::kHeaderSize;
23365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  }
23443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
23543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
23643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
23770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgbool ParseData::HasError() {
23870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  return Data()[PreparseDataConstants::kHasErrorOffset];
239ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org}
240ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
241ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
24270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgunsigned ParseData::Magic() {
24370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  return Data()[PreparseDataConstants::kMagicOffset];
24443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
24543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgunsigned ParseData::Version() {
24870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  return Data()[PreparseDataConstants::kVersionOffset];
24943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
25043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgint ParseData::FunctionsSize() {
25370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]);
25443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
25543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgvoid Parser::SetCachedData() {
2584c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org  if (compile_options() == ScriptCompiler::kNoCompileOptions) {
25970d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    cached_parse_data_ = NULL;
26070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  } else {
261e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(info_->cached_data() != NULL);
2624c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org    if (compile_options() == ScriptCompiler::kConsumeParserCache) {
26370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      cached_parse_data_ = new ParseData(*info_->cached_data());
26470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    }
26570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  }
26643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
26743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
269dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgScope* Parser::NewScope(Scope* parent, ScopeType scope_type) {
2706313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  DCHECK(ast_value_factory());
27108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  Scope* result =
2726313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org      new (zone()) Scope(parent, scope_type, ast_value_factory(), zone());
273394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  result->Initialize();
27443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
27543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
27643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
27843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------
27943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Target is a support class to facilitate manipulation of the
28043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Parser's target_stack_ (the stack of potential 'break' and
28143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 'continue' statement targets). Upon construction, a new target is
28243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// added; it is removed upon destruction.
28343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass Target BASE_EMBEDDED {
28543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
286e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  Target(Target** variable, AstNode* node)
287e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org      : variable_(variable), node_(node), previous_(*variable) {
288e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    *variable = this;
28943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
29043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
29143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ~Target() {
292e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    *variable_ = previous_;
29343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
29443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
295b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  Target* previous() { return previous_; }
2960b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  AstNode* node() { return node_; }
297b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
29843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
299e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  Target** variable_;
3000b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  AstNode* node_;
301b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  Target* previous_;
30243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
30343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass TargetScope BASE_EMBEDDED {
30643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
307e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  explicit TargetScope(Target** variable)
308e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org      : variable_(variable), previous_(*variable) {
309e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    *variable = NULL;
31043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
31143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ~TargetScope() {
313e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    *variable_ = previous_;
31443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
31543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
317e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  Target** variable_;
318b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  Target* previous_;
31943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
32043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------
32343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The CHECK_OK macro is a convenient macro to enforce error
32443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// handling for functions that may fail (by returning !*ok).
32543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
32643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// CAUTION: This macro appends extra statements after a call,
32743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// thus it must never be used where only a single statement
32843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// is correct (e.g. an if statement branch w/o braces)!
32943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
33043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define CHECK_OK  ok);   \
33143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!*ok) return NULL; \
33243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ((void)0
33343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define DUMMY )  // to make indentation work
33443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef DUMMY
33543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
336a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#define CHECK_FAILED  /**/);   \
337a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (failed_) return NULL; \
338a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  ((void)0
339a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#define DUMMY )  // to make indentation work
340a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#undef DUMMY
34143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
34243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------
34343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Implementation of Parser
34443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
345f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.orgclass ParserTraits::Checkpoint
346f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    : public ParserBase<ParserTraits>::CheckpointBase {
347f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org public:
348f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org  explicit Checkpoint(ParserBase<ParserTraits>* parser)
349a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      : CheckpointBase(parser), parser_(parser) {
350a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    saved_ast_node_id_gen_ = *parser_->ast_node_id_gen_;
351f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org  }
352f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org
353f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org  void Restore() {
354f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    CheckpointBase::Restore();
355a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    *parser_->ast_node_id_gen_ = saved_ast_node_id_gen_;
356f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org  }
357f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org
358f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org private:
359a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  ParserBase<ParserTraits>* parser_;
360a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  AstNode::IdGen saved_ast_node_id_gen_;
361f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org};
362f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org
363f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org
36408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgbool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const {
3656313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  return identifier == parser_->ast_value_factory()->eval_string() ||
3666313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org         identifier == parser_->ast_value_factory()->arguments_string();
367f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
368f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
369f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
370a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgbool ParserTraits::IsPrototype(const AstRawString* identifier) const {
371a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  return identifier == parser_->ast_value_factory()->prototype_string();
372a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org}
373a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
374a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
375a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgbool ParserTraits::IsConstructor(const AstRawString* identifier) const {
376a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  return identifier == parser_->ast_value_factory()->constructor_string();
377a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org}
378a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
379a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
3806b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.orgbool ParserTraits::IsThisProperty(Expression* expression) {
381e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(expression != NULL);
3826b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  Property* property = expression->AsProperty();
3836b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  return property != NULL &&
3846b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org      property->obj()->AsVariableProxy() != NULL &&
3856b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org      property->obj()->AsVariableProxy()->is_this();
3866b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org}
3876b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org
3886b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org
38969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.orgbool ParserTraits::IsIdentifier(Expression* expression) {
39069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  VariableProxy* operand = expression->AsVariableProxy();
39169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  return operand != NULL && !operand->is_this();
39269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org}
39369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org
39469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org
395fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.orgvoid ParserTraits::PushPropertyName(FuncNameInferrer* fni,
396fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org                                    Expression* expression) {
397fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  if (expression->IsPropertyName()) {
39808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
399fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  } else {
400fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    fni->PushLiteralName(
4016313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org        parser_->ast_value_factory()->anonymous_function_string());
402fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  }
403fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org}
404fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org
405fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org
4066b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.orgvoid ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
4076b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org                                                           Expression* right) {
408e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(left != NULL);
4096b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  if (left->AsProperty() != NULL &&
4106b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org      right->AsFunctionLiteral() != NULL) {
4116b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org    right->AsFunctionLiteral()->set_pretenure();
4126b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  }
4136b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org}
4146b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org
4156b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org
416fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.orgvoid ParserTraits::CheckPossibleEvalCall(Expression* expression,
417fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org                                         Scope* scope) {
418fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  VariableProxy* callee = expression->AsVariableProxy();
419fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  if (callee != NULL &&
4206313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org      callee->raw_name() == parser_->ast_value_factory()->eval_string()) {
421fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    scope->DeclarationScope()->RecordEvalCall();
422fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  }
423fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org}
424fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org
425fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org
426248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.orgExpression* ParserTraits::MarkExpressionAsAssigned(Expression* expression) {
427248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  VariableProxy* proxy =
428248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org      expression != NULL ? expression->AsVariableProxy() : NULL;
429248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  if (proxy != NULL) proxy->set_is_assigned();
4306b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  return expression;
4316b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org}
4326b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org
4336b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org
4342904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgbool ParserTraits::ShortcutNumericLiteralBinaryExpression(
4352904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    Expression** x, Expression* y, Token::Value op, int pos,
4362904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    AstNodeFactory<AstConstructionVisitor>* factory) {
43708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
43808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) {
43908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    double x_val = (*x)->AsLiteral()->raw_value()->AsNumber();
44008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    double y_val = y->AsLiteral()->raw_value()->AsNumber();
4412904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    switch (op) {
4422904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      case Token::ADD:
4432904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        *x = factory->NewNumberLiteral(x_val + y_val, pos);
4442904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        return true;
4452904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      case Token::SUB:
4462904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        *x = factory->NewNumberLiteral(x_val - y_val, pos);
4472904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        return true;
4482904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      case Token::MUL:
4492904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        *x = factory->NewNumberLiteral(x_val * y_val, pos);
4502904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        return true;
4512904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      case Token::DIV:
4522904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        *x = factory->NewNumberLiteral(x_val / y_val, pos);
4532904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        return true;
4542904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      case Token::BIT_OR: {
4552904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
4562904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        *x = factory->NewNumberLiteral(value, pos);
4572904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        return true;
4582904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      }
4592904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      case Token::BIT_AND: {
4602904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
4612904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        *x = factory->NewNumberLiteral(value, pos);
4622904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        return true;
4632904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      }
4642904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      case Token::BIT_XOR: {
4652904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
4662904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        *x = factory->NewNumberLiteral(value, pos);
4672904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        return true;
4682904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      }
4692904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      case Token::SHL: {
4702904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
4712904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        *x = factory->NewNumberLiteral(value, pos);
4722904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        return true;
4732904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      }
4742904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      case Token::SHR: {
4752904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        uint32_t shift = DoubleToInt32(y_val) & 0x1f;
4762904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        uint32_t value = DoubleToUint32(x_val) >> shift;
4772904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        *x = factory->NewNumberLiteral(value, pos);
4782904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        return true;
4792904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      }
4802904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      case Token::SAR: {
4812904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        uint32_t shift = DoubleToInt32(y_val) & 0x1f;
4822904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
4832904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        *x = factory->NewNumberLiteral(value, pos);
4842904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        return true;
4852904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      }
4862904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      default:
4872904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        break;
4882904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    }
4892904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  }
4902904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  return false;
4912904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org}
4922904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
4932904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
49469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.orgExpression* ParserTraits::BuildUnaryExpression(
49569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org    Expression* expression, Token::Value op, int pos,
49669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org    AstNodeFactory<AstConstructionVisitor>* factory) {
497e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(expression != NULL);
498196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (expression->IsLiteral()) {
49908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    const AstValue* literal = expression->AsLiteral()->raw_value();
50069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org    if (op == Token::NOT) {
50169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org      // Convert the literal to a boolean condition and negate it.
50269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org      bool condition = literal->BooleanValue();
50308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      return factory->NewBooleanLiteral(!condition, pos);
50469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org    } else if (literal->IsNumber()) {
50569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org      // Compute some expressions involving only number literals.
50608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      double value = literal->AsNumber();
50769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org      switch (op) {
50869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org        case Token::ADD:
50969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org          return expression;
51069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org        case Token::SUB:
51169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org          return factory->NewNumberLiteral(-value, pos);
51269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org        case Token::BIT_NOT:
51369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org          return factory->NewNumberLiteral(~DoubleToInt32(value), pos);
51469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org        default:
51569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org          break;
51669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org      }
51769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org    }
51869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  }
51969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  // Desugar '+foo' => 'foo*1'
52069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  if (op == Token::ADD) {
52169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org    return factory->NewBinaryOperation(
52269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org        Token::MUL, expression, factory->NewNumberLiteral(1, pos), pos);
52369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  }
52469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  // The same idea for '-foo' => 'foo*(-1)'.
52569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  if (op == Token::SUB) {
52669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org    return factory->NewBinaryOperation(
52769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org        Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos);
52869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  }
52969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  // ...and one more time for '~foo' => 'foo^(~0)'.
53069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  if (op == Token::BIT_NOT) {
53169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org    return factory->NewBinaryOperation(
53269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org        Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos);
53369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  }
53469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  return factory->NewUnaryOperation(op, expression, pos);
53569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org}
53669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org
53769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org
5384edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.orgExpression* ParserTraits::NewThrowReferenceError(const char* message, int pos) {
5394edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  return NewThrowError(
5406313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org      parser_->ast_value_factory()->make_reference_error_string(), message,
5416313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org      NULL, pos);
5424edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org}
5434edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org
5444edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org
5454edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.orgExpression* ParserTraits::NewThrowSyntaxError(
54608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    const char* message, const AstRawString* arg, int pos) {
5476313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  return NewThrowError(parser_->ast_value_factory()->make_syntax_error_string(),
54808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                       message, arg, pos);
5494edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org}
5504edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org
5514edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org
5524edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.orgExpression* ParserTraits::NewThrowTypeError(
55308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    const char* message, const AstRawString* arg, int pos) {
5546313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  return NewThrowError(parser_->ast_value_factory()->make_type_error_string(),
55508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                       message, arg, pos);
5564edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org}
5574edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org
5584edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org
5594edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.orgExpression* ParserTraits::NewThrowError(
56008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    const AstRawString* constructor, const char* message,
56108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    const AstRawString* arg, int pos) {
5624edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  Zone* zone = parser_->zone();
56308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  int argc = arg != NULL ? 1 : 0;
56408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  const AstRawString* type =
5656313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org      parser_->ast_value_factory()->GetOneByteString(message);
56608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  ZoneList<const AstRawString*>* array =
56708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      new (zone) ZoneList<const AstRawString*>(argc, zone);
56808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  if (arg != NULL) {
56908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    array->Add(arg, zone);
57008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  }
57108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone);
57208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  args->Add(parser_->factory()->NewStringLiteral(type, pos), zone);
57308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  args->Add(parser_->factory()->NewStringListLiteral(array, pos), zone);
5744edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  CallRuntime* call_constructor =
5754edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org      parser_->factory()->NewCallRuntime(constructor, NULL, args, pos);
5764edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  return parser_->factory()->NewThrow(call_constructor, pos);
5774edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org}
5784edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org
5794edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org
580f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid ParserTraits::ReportMessageAt(Scanner::Location source_location,
581f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                   const char* message,
582285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org                                   const char* arg,
5832904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org                                   bool is_reference_error) {
58497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  if (parser_->stack_overflow()) {
58597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    // Suppress the error message (syntax error or such) in the presence of a
58697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    // stack overflow. The isolate allows only one pending exception at at time
58797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    // and we want to report the stack overflow later.
58897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    return;
58997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  }
5906a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  parser_->has_pending_error_ = true;
5916a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  parser_->pending_error_location_ = source_location;
5926a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  parser_->pending_error_message_ = message;
5936a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  parser_->pending_error_char_arg_ = arg;
59408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  parser_->pending_error_arg_ = NULL;
5956a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  parser_->pending_error_is_reference_error_ = is_reference_error;
596f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
597f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
598f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
599f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid ParserTraits::ReportMessage(const char* message,
60008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                 const char* arg,
60108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                 bool is_reference_error) {
60208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  Scanner::Location source_location = parser_->scanner()->location();
60308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  ReportMessageAt(source_location, message, arg, is_reference_error);
60408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org}
60508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org
60608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org
60708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgvoid ParserTraits::ReportMessage(const char* message,
60808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                 const AstRawString* arg,
6092904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org                                 bool is_reference_error) {
610f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Scanner::Location source_location = parser_->scanner()->location();
611285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org  ReportMessageAt(source_location, message, arg, is_reference_error);
612f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
613f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
614f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
615f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid ParserTraits::ReportMessageAt(Scanner::Location source_location,
616f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                   const char* message,
61708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                   const AstRawString* arg,
6182904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org                                   bool is_reference_error) {
61997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  if (parser_->stack_overflow()) {
62097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    // Suppress the error message (syntax error or such) in the presence of a
62197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    // stack overflow. The isolate allows only one pending exception at at time
62297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    // and we want to report the stack overflow later.
62397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    return;
62497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  }
6256a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  parser_->has_pending_error_ = true;
6266a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  parser_->pending_error_location_ = source_location;
6276a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  parser_->pending_error_message_ = message;
6286a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  parser_->pending_error_char_arg_ = NULL;
6296a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  parser_->pending_error_arg_ = arg;
6306a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  parser_->pending_error_is_reference_error_ = is_reference_error;
631f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
632f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
633f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
63408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgconst AstRawString* ParserTraits::GetSymbol(Scanner* scanner) {
63508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  const AstRawString* result =
6366313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org      parser_->scanner()->CurrentSymbol(parser_->ast_value_factory());
637e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(result != NULL);
638b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org  return result;
639f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
640f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
641f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
642a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgconst AstRawString* ParserTraits::GetNumberAsSymbol(Scanner* scanner) {
643a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  double double_value = parser_->scanner()->DoubleValue();
644a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  char array[100];
645a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  const char* string =
646fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      DoubleToCString(double_value, Vector<char>(array, arraysize(array)));
647a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  return ast_value_factory()->GetOneByteString(string);
648a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org}
649a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
650a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
65108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgconst AstRawString* ParserTraits::GetNextSymbol(Scanner* scanner) {
6526313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  return parser_->scanner()->NextSymbol(parser_->ast_value_factory());
653f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
654f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
655f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
656f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgExpression* ParserTraits::ThisExpression(
6579d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org    Scope* scope, AstNodeFactory<AstConstructionVisitor>* factory, int pos) {
6589d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  return factory->NewVariableProxy(scope->receiver(), pos);
659f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
660f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
6615e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgExpression* ParserTraits::SuperReference(
6625e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    Scope* scope, AstNodeFactory<AstConstructionVisitor>* factory, int pos) {
6635e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  return factory->NewSuperReference(
6645e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      ThisExpression(scope, factory, pos)->AsVariableProxy(),
6655e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      pos);
6665e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
667f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
668a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgExpression* ParserTraits::ClassLiteral(
669a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    const AstRawString* name, Expression* extends, Expression* constructor,
670a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    ZoneList<ObjectLiteral::Property*>* properties, int pos,
671a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    AstNodeFactory<AstConstructionVisitor>* factory) {
672a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  return factory->NewClassLiteral(name, extends, constructor, properties, pos);
673a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org}
674a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
675486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.orgLiteral* ParserTraits::ExpressionFromLiteral(
676f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    Token::Value token, int pos,
677f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    Scanner* scanner,
678f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    AstNodeFactory<AstConstructionVisitor>* factory) {
679f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  switch (token) {
680f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    case Token::NULL_LITERAL:
68108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      return factory->NewNullLiteral(pos);
682f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    case Token::TRUE_LITERAL:
68308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      return factory->NewBooleanLiteral(true, pos);
684f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    case Token::FALSE_LITERAL:
68508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      return factory->NewBooleanLiteral(false, pos);
686f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    case Token::NUMBER: {
68797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      double value = scanner->DoubleValue();
688f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      return factory->NewNumberLiteral(value, pos);
689f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    }
690f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    default:
691e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(false);
692f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
693f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  return NULL;
694f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
695f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
696f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
697f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgExpression* ParserTraits::ExpressionFromIdentifier(
69808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    const AstRawString* name, int pos, Scope* scope,
699f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    AstNodeFactory<AstConstructionVisitor>* factory) {
700f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name);
701f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // The name may refer to a module instance object, so its type is unknown.
702f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#ifdef DEBUG
703f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (FLAG_print_interface_details)
70408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    PrintF("# Variable %.*s ", name->length(), name->raw_data());
705f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#endif
706f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Interface* interface = Interface::NewUnknown(parser_->zone());
707f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  return scope->NewUnresolved(factory, name, interface, pos);
708f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
709f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
710f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
711f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgExpression* ParserTraits::ExpressionFromString(
712f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    int pos, Scanner* scanner,
713f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    AstNodeFactory<AstConstructionVisitor>* factory) {
71408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  const AstRawString* symbol = GetSymbol(scanner);
715f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol);
71608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  return factory->NewStringLiteral(symbol, pos);
717f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
718f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
719f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
7203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgExpression* ParserTraits::GetIterator(
7213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    Expression* iterable, AstNodeFactory<AstConstructionVisitor>* factory) {
7223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  Expression* iterator_symbol_literal =
7233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      factory->NewSymbolLiteral("symbolIterator", RelocInfo::kNoPosition);
7243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  int pos = iterable->position();
7253e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  Expression* prop =
7263e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      factory->NewProperty(iterable, iterator_symbol_literal, pos);
7273e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  Zone* zone = parser_->zone();
7283e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(0, zone);
7293e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  return factory->NewCall(prop, args, pos);
7303e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org}
7313e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
7323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
733f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgLiteral* ParserTraits::GetLiteralTheHole(
734f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    int position, AstNodeFactory<AstConstructionVisitor>* factory) {
73508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  return factory->NewTheHoleLiteral(RelocInfo::kNoPosition);
736f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
737f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
738f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
739f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgExpression* ParserTraits::ParseV8Intrinsic(bool* ok) {
740f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  return parser_->ParseV8Intrinsic(ok);
741f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
742f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
743f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
744486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.orgFunctionLiteral* ParserTraits::ParseFunctionLiteral(
7452c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    const AstRawString* name, Scanner::Location function_name_location,
7462c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    bool name_is_strict_reserved, FunctionKind kind,
7472c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    int function_token_position, FunctionLiteral::FunctionType type,
7482c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
7492c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  return parser_->ParseFunctionLiteral(
7502c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      name, function_name_location, name_is_strict_reserved, kind,
7512c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      function_token_position, type, arity_restriction, ok);
752486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org}
753486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org
754486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org
75521d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.orgParser::Parser(CompilationInfo* info, ParseInfo* parse_info)
75621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    : ParserBase<ParserTraits>(&scanner_, parse_info->stack_limit,
75721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org                               info->extension(), NULL, info->zone(),
75821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org                               info->ast_node_id_gen(), this),
75921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org      scanner_(parse_info->unicode_cache),
7601b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      reusable_preparser_(NULL),
7611e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org      original_scope_(NULL),
76243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      target_stack_(NULL),
76370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      cached_parse_data_(NULL),
7646a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      info_(info),
7656a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      has_pending_error_(false),
7666a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      pending_error_message_(NULL),
76708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      pending_error_arg_(NULL),
76821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org      pending_error_char_arg_(NULL),
76921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org      total_preparse_skipped_(0),
77021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org      pre_parse_timer_(NULL) {
771b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  DCHECK(!script().is_null() || info->source_stream() != NULL);
772e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping);
773e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  set_allow_modules(!info->is_native() && FLAG_harmony_modules);
774e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native());
775e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  set_allow_lazy(false);  // Must be explicitly enabled.
7769bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  set_allow_arrow_functions(FLAG_harmony_arrow_functions);
777ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
7785e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  set_allow_classes(FLAG_harmony_classes);
7792c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  set_allow_harmony_object_literals(FLAG_harmony_object_literals);
7805de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
7815de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org       ++feature) {
7825de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org    use_counts_[feature] = 0;
7835de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  }
7846313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  if (info->ast_value_factory() == NULL) {
7856313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org    // info takes ownership of AstValueFactory.
7866313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org    info->SetAstValueFactory(
7876313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org        new AstValueFactory(zone(), parse_info->hash_seed));
78821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  }
78943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
79043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
79143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7925a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgFunctionLiteral* Parser::ParseProgram() {
7934000f228dd279f96628ed845f1e81d01ba7e14d8jkummerow@chromium.org  // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
7944000f228dd279f96628ed845f1e81d01ba7e14d8jkummerow@chromium.org  // see comment for HistogramTimerScope class.
79521d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org
79621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  // It's OK to use the counters here, since this function is only called in
79721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  // the main thread.
7984000f228dd279f96628ed845f1e81d01ba7e14d8jkummerow@chromium.org  HistogramTimerScope timer_scope(isolate()->counters()->parse(), true);
7996313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  Handle<String> source(String::cast(script()->source()));
8007979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  isolate()->counters()->total_parse_size()->Increment(source->length());
8015de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  base::ElapsedTimer timer;
802dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  if (FLAG_trace_parse) {
803dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    timer.Start();
804dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  }
8056313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
80643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
80743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Initialize parser state.
80869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  CompleteParserRecorder recorder;
8094c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org
8104c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org  if (compile_options() == ScriptCompiler::kProduceParserCache) {
81169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org    log_ = &recorder;
8124c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org  } else if (compile_options() == ScriptCompiler::kConsumeParserCache) {
81370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    cached_parse_data_->Initialize();
81469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  }
81569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org
8169e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  source = String::Flatten(source);
817304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  FunctionLiteral* result;
818b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
819b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  Scope* top_scope = NULL;
820b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  Scope* eval_scope = NULL;
8215f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  if (source->IsExternalTwoByteString()) {
8225f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    // Notice that the stream is destroyed at the end of the branch block.
8235f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    // The last line of the blocks can't be moved outside, even though they're
8245f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    // identical calls.
825154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    ExternalTwoByteStringUtf16CharacterStream stream(
8265f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        Handle<ExternalTwoByteString>::cast(source), 0, source->length());
8279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    scanner_.Initialize(&stream);
828b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    result = DoParseProgram(info(), &top_scope, &eval_scope);
8295f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  } else {
830154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    GenericStringUtf16CharacterStream stream(source, 0, source->length());
8319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    scanner_.Initialize(&stream);
832b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    result = DoParseProgram(info(), &top_scope, &eval_scope);
833b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  }
834b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  top_scope->set_end_position(source->length());
835b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  if (eval_scope != NULL) {
836b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    eval_scope->set_end_position(source->length());
8375f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  }
83821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  HandleSourceURLComments();
839304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
840304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  if (FLAG_trace_parse && result != NULL) {
841dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    double ms = timer.Elapsed().InMillisecondsF();
842304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    if (info()->is_eval()) {
843304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      PrintF("[parsing eval");
844304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    } else if (info()->script()->name()->IsString()) {
845304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      String* name = String::cast(info()->script()->name());
846304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      SmartArrayPointer<char> name_chars = name->ToCString();
847afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org      PrintF("[parsing script: %s", name_chars.get());
848304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    } else {
849304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      PrintF("[parsing script");
850304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    }
851304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    PrintF(" - took %0.3f ms]\n", ms);
852304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  }
8534c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org  if (compile_options() == ScriptCompiler::kProduceParserCache) {
85470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
85569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org    log_ = NULL;
85669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  }
857304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  return result;
8585f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
8595f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
8605f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
861b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.orgFunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope,
862b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org                                        Scope** eval_scope) {
863e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(scope_ == NULL);
864e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(target_stack_ == NULL);
86543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
86643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  FunctionLiteral* result = NULL;
867b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  {
868b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    *scope = NewScope(scope_, GLOBAL_SCOPE);
869b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    info->SetGlobalScope(*scope);
87012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    if (!info->context().is_null() && !info->context()->IsNativeContext()) {
871b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      *scope = Scope::DeserializeScopeChain(*info->context(), *scope, zone());
87208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      // The Scope is backed up by ScopeInfo (which is in the V8 heap); this
87308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      // means the Parser cannot operate independent of the V8 heap. Tell the
87408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      // string table to internalize strings and values right after they're
87508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      // created.
8766313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org      ast_value_factory()->Internalize(isolate());
877355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    }
878b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    original_scope_ = *scope;
8792c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org    if (info->is_eval()) {
880b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      if (!(*scope)->is_global_scope() || info->strict_mode() == STRICT) {
881b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org        *scope = NewScope(*scope, EVAL_SCOPE);
8822c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org      }
883355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    } else if (info->is_global()) {
884b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      *scope = NewScope(*scope, GLOBAL_SCOPE);
88527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    }
886b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    (*scope)->set_start_position(0);
887b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    // End position will be set by the caller.
888355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
889cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org    // Compute the parsing mode.
890e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY;
891b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    if (allow_natives_syntax() || extension_ != NULL ||
892b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org        (*scope)->is_eval_scope()) {
893cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org      mode = PARSE_EAGERLY;
894cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org    }
895cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org    ParsingModeScope parsing_mode(this, mode);
896cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org
897f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    // Enters 'scope'.
898b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    FunctionState function_state(&function_state_, &scope_, *scope, zone(),
8996313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org                                 ast_value_factory(), info->ast_node_id_gen());
900f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
901486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    scope_->SetStrictMode(info->strict_mode());
9027028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
90343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    bool ok = true;
904f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    int beg_pos = scanner()->location().beg_pos;
905b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    ParseSourceElements(body, Token::EOS, info->is_eval(), true, eval_scope,
906b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org                        &ok);
907d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
908486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    if (ok && strict_mode() == STRICT) {
909f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
9100ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    }
9111805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
912a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    if (ok && allow_harmony_scoping() && strict_mode() == STRICT) {
913f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      CheckConflictingVarDeclarations(scope_, &ok);
9141805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    }
9151805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
9169faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org    if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
9179faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org      if (body->length() != 1 ||
9189faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org          !body->at(0)->IsExpressionStatement() ||
9199faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org          !body->at(0)->AsExpressionStatement()->
9209faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org              expression()->IsFunctionLiteral()) {
921285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org        ReportMessage("single_function_literal");
9229faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org        ok = false;
9239faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org      }
9249faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org    }
9259faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org
92643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (ok) {
927b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      result = factory()->NewFunctionLiteral(
9286313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org          ast_value_factory()->empty_string(), ast_value_factory(), scope_,
9296313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org          body, function_state.materialized_literal_count(),
930c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org          function_state.expected_property_count(),
9319d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org          function_state.handler_count(), 0,
93256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org          FunctionLiteral::kNoDuplicateParameters,
9339d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org          FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval,
9342c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org          FunctionLiteral::kNotParenthesized, FunctionKind::kNormalFunction, 0);
935b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      result->set_ast_properties(factory()->visitor()->ast_properties());
9362c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org      result->set_dont_optimize_reason(
9372c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org          factory()->visitor()->dont_optimize_reason());
93843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
93943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
94043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
94143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Make sure the target stack is empty.
942e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(target_stack_ == NULL);
94343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
94443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
94543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
94643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
947f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
9485a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgFunctionLiteral* Parser::ParseLazy() {
94921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  // It's OK to use the counters here, since this function is only called in
95021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  // the main thread.
951dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy());
9526313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  Handle<String> source(String::cast(script()->source()));
9537979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  isolate()->counters()->total_parse_size()->Increment(source->length());
9545de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  base::ElapsedTimer timer;
955dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  if (FLAG_trace_parse) {
956dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    timer.Start();
957dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  }
9585a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Handle<SharedFunctionInfo> shared_info = info()->shared_info();
959304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
9605f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Initialize parser state.
9619e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  source = String::Flatten(source);
962304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  FunctionLiteral* result;
9635f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  if (source->IsExternalTwoByteString()) {
964154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    ExternalTwoByteStringUtf16CharacterStream stream(
9655f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        Handle<ExternalTwoByteString>::cast(source),
9664d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org        shared_info->start_position(),
9674d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org        shared_info->end_position());
9681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    result = ParseLazy(&stream);
9695f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  } else {
970154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    GenericStringUtf16CharacterStream stream(source,
971154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org                                             shared_info->start_position(),
972154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org                                             shared_info->end_position());
9731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    result = ParseLazy(&stream);
9745f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  }
975304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
976304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  if (FLAG_trace_parse && result != NULL) {
977dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    double ms = timer.Elapsed().InMillisecondsF();
978de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org    SmartArrayPointer<char> name_chars = result->debug_name()->ToCString();
979afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
980304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  }
981304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  return result;
9825f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
9835f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
9845f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
9851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgFunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) {
9865a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Handle<SharedFunctionInfo> shared_info = info()->shared_info();
9879e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  scanner_.Initialize(source);
988e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(scope_ == NULL);
989e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(target_stack_ == NULL);
9905f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
9914d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  Handle<String> name(String::cast(shared_info->name()));
9926313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  DCHECK(ast_value_factory());
9936313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
9946313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  const AstRawString* raw_name = ast_value_factory()->GetString(name);
99508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  fni_->PushEnclosingName(raw_name);
99665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
997471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
99843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
99943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Place holder for the result.
100043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  FunctionLiteral* result = NULL;
100143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
100243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  {
100343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Parse the function literal.
1004f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    Scope* scope = NewScope(scope_, GLOBAL_SCOPE);
10055a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    info()->SetGlobalScope(scope);
10065a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    if (!info()->closure().is_null()) {
10075a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope,
10087028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                           zone());
10094d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    }
10101e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    original_scope_ = scope;
101108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    FunctionState function_state(&function_state_, &scope_, scope, zone(),
10126313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org                                 ast_value_factory(),
10136313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org                                 info()->ast_node_id_gen());
1014e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT);
1015e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(info()->strict_mode() == shared_info->strict_mode());
1016486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    scope->SetStrictMode(shared_info->strict_mode());
1017dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    FunctionLiteral::FunctionType function_type = shared_info->is_expression()
10187c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        ? (shared_info->is_anonymous()
10197c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org              ? FunctionLiteral::ANONYMOUS_EXPRESSION
10207c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org              : FunctionLiteral::NAMED_EXPRESSION)
10217c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        : FunctionLiteral::DECLARATION;
102243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    bool ok = true;
10239d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org
10249d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org    if (shared_info->is_arrow()) {
10259d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org      Expression* expression = ParseExpression(false, &ok);
1026e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(expression->IsFunctionLiteral());
10279d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org      result = expression->AsFunctionLiteral();
10289d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org    } else {
10299d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org      result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(),
10309d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org                                    false,  // Strict mode name already checked.
10312c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                                    shared_info->kind(), RelocInfo::kNoPosition,
10329d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org                                    function_type,
10339d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org                                    FunctionLiteral::NORMAL_ARITY, &ok);
10349d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org    }
103543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Make sure the results agree.
1036e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(ok == (result != NULL));
103743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
103843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
103943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Make sure the target stack is empty.
1040e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(target_stack_ == NULL);
104143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
104221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  if (result != NULL) {
10434d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    Handle<String> inferred_name(shared_info->inferred_name());
1044a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    result->set_inferred_name(inferred_name);
104543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
104643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
104743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
104843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1049f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org
1050fa943b736b1d996084393011529d568165bb5d83lrn@chromium.orgvoid* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
1051b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org                                  int end_token, bool is_eval, bool is_global,
1052b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org                                  Scope** eval_scope, bool* ok) {
105343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // SourceElements ::
1054f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //   (ModuleElement)* <end_token>
105543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
105643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate a target stack to use for this set of source
105743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // elements. This way, all scripts and functions get their own
105843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // target stack thus avoiding illegal breaks and continues across
105943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // functions.
1060e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  TargetScope scope(&this->target_stack_);
106143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1062e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(processor != NULL);
10630a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  bool directive_prologue = true;     // Parsing directive prologue.
10640a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
106543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (peek() != end_token) {
10660a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    if (directive_prologue && peek() != Token::STRING) {
10670a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      directive_prologue = false;
10680a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    }
10690a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
1070f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    Scanner::Location token_loc = scanner()->peek_location();
107133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    Statement* stat;
107233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    if (is_global && !is_eval) {
107333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org      stat = ParseModuleElement(NULL, CHECK_OK);
107433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    } else {
107533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org      stat = ParseBlockElement(NULL, CHECK_OK);
107633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    }
10770a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    if (stat == NULL || stat->IsEmpty()) {
10780a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      directive_prologue = false;   // End of directive prologue.
10790a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      continue;
10800a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    }
10810a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
10820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    if (directive_prologue) {
10830a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      // A shot at a directive.
1084f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      ExpressionStatement* e_stat;
1085f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      Literal* literal;
10860a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      // Still processing directive prologue?
10870a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      if ((e_stat = stat->AsExpressionStatement()) != NULL &&
10880a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org          (literal = e_stat->expression()->AsLiteral()) != NULL &&
108908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org          literal->raw_value()->IsString()) {
10905de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org        // Check "use strict" directive (ES5 14.1) and "use asm" directive. Only
10915de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org        // one can be present.
1092486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        if (strict_mode() == SLOPPY &&
109308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org            literal->raw_value()->AsString() ==
10946313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org                ast_value_factory()->use_strict_string() &&
10955de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org            token_loc.end_pos - token_loc.beg_pos ==
10966313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org                ast_value_factory()->use_strict_string()->length() + 2) {
10972c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org          // TODO(mstarzinger): Global strict eval calls, need their own scope
10982c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org          // as specified in ES5 10.4.2(3). The correct fix would be to always
10992c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org          // add this scope in DoParseProgram(), but that requires adaptations
11002c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org          // all over the code base, so we go with a quick-fix for now.
1101cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org          // In the same manner, we have to patch the parsing mode.
1102f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          if (is_eval && !scope_->is_eval_scope()) {
1103e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org            DCHECK(scope_->is_global_scope());
1104f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org            Scope* scope = NewScope(scope_, EVAL_SCOPE);
1105f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org            scope->set_start_position(scope_->start_position());
1106f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org            scope->set_end_position(scope_->end_position());
1107f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org            scope_ = scope;
1108b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org            if (eval_scope != NULL) {
1109b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org              // Caller will correct the positions of the ad hoc eval scope.
1110b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org              *eval_scope = scope;
1111b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org            }
1112cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org            mode_ = PARSE_EAGERLY;
11132c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org          }
1114486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org          scope_->SetStrictMode(STRICT);
11150a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org          // "use strict" is the only directive for now.
11160a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org          directive_prologue = false;
11175de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org        } else if (literal->raw_value()->AsString() ==
11186313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org                       ast_value_factory()->use_asm_string() &&
11195de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org                   token_loc.end_pos - token_loc.beg_pos ==
11206313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org                       ast_value_factory()->use_asm_string()->length() + 2) {
11215de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org          // Store the usage count; The actual use counter on the isolate is
11225de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org          // incremented after parsing is done.
11235de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org          ++use_counts_[v8::Isolate::kUseAsm];
1124a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org          scope_->SetAsmModule();
11250a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        }
11260a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      } else {
11270a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        // End of the directive prologue.
11280a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        directive_prologue = false;
11290a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      }
11300a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    }
11310a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
11327028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    processor->Add(stat, zone());
113343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1134911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org
113543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return 0;
113643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
113743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
113843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
113908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgStatement* Parser::ParseModuleElement(ZoneList<const AstRawString*>* labels,
1140f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org                                      bool* ok) {
1141f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // (Ecma 262 5th Edition, clause 14):
1142f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // SourceElement:
1143f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    Statement
1144f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    FunctionDeclaration
1145f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //
1146f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // In harmony mode we allow additionally the following productions
1147f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // ModuleElement:
1148f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    LetDeclaration
1149f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    ConstDeclaration
1150f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    ModuleDeclaration
1151f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    ImportDeclaration
1152f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    ExportDeclaration
1153f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  //    GeneratorDeclaration
1154f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1155f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  switch (peek()) {
1156f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    case Token::FUNCTION:
1157812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      return ParseFunctionDeclaration(NULL, ok);
1158a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    case Token::CLASS:
1159a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      return ParseClassDeclaration(NULL, ok);
1160f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    case Token::IMPORT:
1161f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      return ParseImportDeclaration(ok);
1162f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    case Token::EXPORT:
1163f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      return ParseExportDeclaration(ok);
116470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    case Token::CONST:
116570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      return ParseVariableStatement(kModuleElement, NULL, ok);
116670d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    case Token::LET:
1167e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(allow_harmony_scoping());
116870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      if (strict_mode() == STRICT) {
116970d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org        return ParseVariableStatement(kModuleElement, NULL, ok);
117070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      }
117170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      // Fall through.
1172a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org    default: {
1173a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org      Statement* stmt = ParseStatement(labels, CHECK_OK);
1174a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org      // Handle 'module' as a context-sensitive keyword.
1175a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org      if (FLAG_harmony_modules &&
1176a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org          peek() == Token::IDENTIFIER &&
1177f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          !scanner()->HasAnyLineTerminatorBeforeNext() &&
1178a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org          stmt != NULL) {
1179a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org        ExpressionStatement* estmt = stmt->AsExpressionStatement();
118008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org        if (estmt != NULL && estmt->expression()->AsVariableProxy() != NULL &&
118108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org            estmt->expression()->AsVariableProxy()->raw_name() ==
11826313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org                ast_value_factory()->module_string() &&
1183f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org            !scanner()->literal_contains_escapes()) {
1184812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org          return ParseModuleDeclaration(NULL, ok);
1185a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org        }
1186a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org      }
1187a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org      return stmt;
1188a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org    }
1189f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  }
1190f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
1191f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1192f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
119308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgStatement* Parser::ParseModuleDeclaration(ZoneList<const AstRawString*>* names,
119408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                          bool* ok) {
1195f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // ModuleDeclaration:
1196f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    'module' Identifier Module
1197f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1198a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  int pos = peek_position();
119908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  const AstRawString* name =
120008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1201bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
1202bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1203bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  if (FLAG_print_interface_details)
120408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    PrintF("# Module %.*s ", name->length(), name->raw_data());
1205bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
1206bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
1207812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Module* module = ParseModule(CHECK_OK);
12088e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface());
1209812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Declaration* declaration =
1210f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      factory()->NewModuleDeclaration(proxy, module, scope_, pos);
1211812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Declare(declaration, true, CHECK_OK);
1212812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1213bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1214bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  if (FLAG_print_interface_details)
121508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    PrintF("# Module %.*s ", name->length(), name->raw_data());
1216bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  if (FLAG_print_interfaces) {
121708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    PrintF("module %.*s: ", name->length(), name->raw_data());
1218bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    module->interface()->Print();
1219bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  }
1220bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
1221bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
12227028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  if (names) names->Add(name, zone());
122381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  if (module->body() == NULL)
1224a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    return factory()->NewEmptyStatement(pos);
122581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  else
1226a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    return factory()->NewModuleStatement(proxy, module->body(), pos);
1227f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
1228f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1229f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1230f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModule(bool* ok) {
1231f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // Module:
1232f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    '{' ModuleElement '}'
1233812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //    '=' ModulePath ';'
1234812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //    'at' String ';'
1235f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1236f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  switch (peek()) {
1237f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    case Token::LBRACE:
1238f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      return ParseModuleLiteral(ok);
1239f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1240812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    case Token::ASSIGN: {
1241f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      Expect(Token::ASSIGN, CHECK_OK);
1242812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      Module* result = ParseModulePath(CHECK_OK);
1243812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      ExpectSemicolon(CHECK_OK);
1244812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      return result;
1245812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    }
1246f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1247812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    default: {
12481fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      ExpectContextualKeyword(CStrVector("at"), CHECK_OK);
1249812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      Module* result = ParseModuleUrl(CHECK_OK);
1250812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      ExpectSemicolon(CHECK_OK);
1251812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      return result;
1252812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    }
1253f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  }
1254f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
1255f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1256f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1257f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModuleLiteral(bool* ok) {
1258f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // Module:
1259f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    '{' ModuleElement '}'
1260f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1261a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  int pos = peek_position();
1262f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // Construct block expecting 16 statements.
1263a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition);
1264bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1265bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  if (FLAG_print_interface_details) PrintF("# Literal ");
1266bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
1267f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Scope* scope = NewScope(scope_, MODULE_SCOPE);
1268f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1269f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Expect(Token::LBRACE, CHECK_OK);
1270f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  scope->set_start_position(scanner()->location().beg_pos);
1271486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  scope->SetStrictMode(STRICT);
1272f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1273f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  {
1274f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    BlockState block_state(&scope_, scope);
12757028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    TargetCollector collector(zone());
1276f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    Target target(&this->target_stack_, &collector);
1277f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    Target target_body(&this->target_stack_, body);
1278f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1279f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    while (peek() != Token::RBRACE) {
1280f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      Statement* stat = ParseModuleElement(NULL, CHECK_OK);
1281f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      if (stat && !stat->IsEmpty()) {
1282400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org        body->AddStatement(stat, zone());
1283f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      }
1284f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    }
1285f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  }
1286f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1287f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Expect(Token::RBRACE, CHECK_OK);
1288f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  scope->set_end_position(scanner()->location().end_pos);
1289ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  body->set_scope(scope);
1290bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
129181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  // Check that all exports are bound.
1292ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  Interface* interface = scope->interface();
129381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  for (Interface::Iterator it = interface->iterator();
129481cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org       !it.done(); it.Advance()) {
1295fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    if (scope->LookupLocal(it.name()) == NULL) {
1296285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org      ParserTraits::ReportMessage("module_export_undefined", it.name());
129781cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org      *ok = false;
129881cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org      return NULL;
129981cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org    }
130081cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  }
130181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org
1302ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  interface->MakeModule(ok);
1303e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(*ok);
1304ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  interface->Freeze(ok);
1305e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(*ok);
1306a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  return factory()->NewModuleLiteral(body, interface, pos);
1307f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
1308f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1309f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1310f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModulePath(bool* ok) {
1311f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // ModulePath:
1312f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    Identifier
1313f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    ModulePath '.' Identifier
1314f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1315a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  int pos = peek_position();
1316f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Module* result = ParseModuleVariable(CHECK_OK);
1317f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  while (Check(Token::PERIOD)) {
131808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    const AstRawString* name = ParseIdentifierName(CHECK_OK);
1319bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1320bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    if (FLAG_print_interface_details)
132108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      PrintF("# Path .%.*s ", name->length(), name->raw_data());
1322bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
1323a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    Module* member = factory()->NewModulePath(result, name, pos);
13247028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    result->interface()->Add(name, member->interface(), zone(), ok);
1325bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    if (!*ok) {
1326bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1327bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      if (FLAG_print_interfaces) {
132808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org        PrintF("PATH TYPE ERROR at '%.*s'\n", name->length(), name->raw_data());
1329bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        PrintF("result: ");
1330bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        result->interface()->Print();
1331bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        PrintF("member: ");
1332bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        member->interface()->Print();
1333bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      }
1334bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
1335285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org      ParserTraits::ReportMessage("invalid_module_path", name);
1336bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      return NULL;
1337bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    }
1338bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    result = member;
1339f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  }
1340f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1341f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  return result;
1342f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
1343f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1344f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1345f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModuleVariable(bool* ok) {
1346f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // ModulePath:
1347f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    Identifier
1348f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1349a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  int pos = peek_position();
135008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  const AstRawString* name =
135108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1352bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1353bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  if (FLAG_print_interface_details)
135408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    PrintF("# Module variable %.*s ", name->length(), name->raw_data());
1355bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
1356f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  VariableProxy* proxy = scope_->NewUnresolved(
135728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org      factory(), name, Interface::NewModule(zone()),
1358f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      scanner()->location().beg_pos);
1359bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
1360a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  return factory()->NewModuleVariable(proxy, pos);
1361f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
1362f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1363f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1364f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgModule* Parser::ParseModuleUrl(bool* ok) {
1365f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // Module:
1366812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //    String
1367f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1368a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  int pos = peek_position();
1369f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Expect(Token::STRING, CHECK_OK);
137008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  const AstRawString* symbol = GetSymbol(scanner());
1371f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1372bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // TODO(ES6): Request JS resource from environment...
1373bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
1374bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1375bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  if (FLAG_print_interface_details) PrintF("# Url ");
1376bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
1377ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
13788e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // Create an empty literal as long as the feature isn't finished.
13798e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  USE(symbol);
1380f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Scope* scope = NewScope(scope_, MODULE_SCOPE);
1381a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
13828e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  body->set_scope(scope);
13838e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Interface* interface = scope->interface();
1384a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  Module* result = factory()->NewModuleLiteral(body, interface, pos);
1385ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  interface->Freeze(ok);
1386e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(*ok);
138781cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  interface->Unify(scope->interface(), zone(), ok);
1388e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(*ok);
1389ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  return result;
1390f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
1391f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1392f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1393812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgModule* Parser::ParseModuleSpecifier(bool* ok) {
1394812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  // ModuleSpecifier:
1395812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //    String
1396812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //    ModulePath
1397812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1398812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  if (peek() == Token::STRING) {
1399812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    return ParseModuleUrl(ok);
1400812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  } else {
1401812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    return ParseModulePath(ok);
1402812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  }
1403812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org}
1404812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1405812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1406f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgBlock* Parser::ParseImportDeclaration(bool* ok) {
1407812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  // ImportDeclaration:
1408812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //    'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';'
1409812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //
1410812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  // TODO(ES6): implement destructuring ImportSpecifiers
1411812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1412a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  int pos = peek_position();
1413812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Expect(Token::IMPORT, CHECK_OK);
141408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  ZoneList<const AstRawString*> names(1, zone());
1415812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
141608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  const AstRawString* name = ParseIdentifierName(CHECK_OK);
14177028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  names.Add(name, zone());
1418812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  while (peek() == Token::COMMA) {
1419812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    Consume(Token::COMMA);
1420812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    name = ParseIdentifierName(CHECK_OK);
14217028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    names.Add(name, zone());
1422812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  }
1423812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
14241fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1425812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Module* module = ParseModuleSpecifier(CHECK_OK);
1426812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  ExpectSemicolon(CHECK_OK);
1427812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1428812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  // Generate a separate declaration for each identifier.
1429812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  // TODO(ES6): once we implement destructuring, make that one declaration.
1430a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
1431812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  for (int i = 0; i < names.length(); ++i) {
1432bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1433bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    if (FLAG_print_interface_details)
143408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      PrintF("# Import %.*s ", name->length(), name->raw_data());
1435bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
14367028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    Interface* interface = Interface::NewUnknown(zone());
14377028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    module->interface()->Add(names[i], interface, zone(), ok);
1438bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    if (!*ok) {
1439bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1440bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      if (FLAG_print_interfaces) {
144108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org        PrintF("IMPORT TYPE ERROR at '%.*s'\n", name->length(),
144208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org               name->raw_data());
1443bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        PrintF("module: ");
1444bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        module->interface()->Print();
1445bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      }
1446bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
1447285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org      ParserTraits::ReportMessage("invalid_module_path", name);
1448bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      return NULL;
1449bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    }
1450bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    VariableProxy* proxy = NewUnresolved(names[i], LET, interface);
1451812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    Declaration* declaration =
1452f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        factory()->NewImportDeclaration(proxy, module, scope_, pos);
1453812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    Declare(declaration, true, CHECK_OK);
1454812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  }
1455812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1456812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  return block;
1457f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
1458f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1459f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1460812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgStatement* Parser::ParseExportDeclaration(bool* ok) {
1461812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  // ExportDeclaration:
1462812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //    'export' Identifier (',' Identifier)* ';'
1463812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //    'export' VariableDeclaration
1464812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //    'export' FunctionDeclaration
1465f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  //    'export' GeneratorDeclaration
1466812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //    'export' ModuleDeclaration
1467812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  //
1468812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  // TODO(ES6): implement structuring ExportSpecifiers
1469812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1470812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Expect(Token::EXPORT, CHECK_OK);
1471812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1472812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Statement* result = NULL;
147308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  ZoneList<const AstRawString*> names(1, zone());
1474812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  switch (peek()) {
1475812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    case Token::IDENTIFIER: {
1476a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      int pos = position();
147708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      const AstRawString* name =
14788297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org          ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1479812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      // Handle 'module' as a context-sensitive keyword.
14806313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org      if (name != ast_value_factory()->module_string()) {
14817028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        names.Add(name, zone());
1482812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org        while (peek() == Token::COMMA) {
1483812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org          Consume(Token::COMMA);
14848297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org          name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
14857028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org          names.Add(name, zone());
1486812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org        }
1487812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org        ExpectSemicolon(CHECK_OK);
1488a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org        result = factory()->NewEmptyStatement(pos);
1489812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      } else {
1490812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org        result = ParseModuleDeclaration(&names, CHECK_OK);
1491812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      }
1492812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      break;
1493812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    }
1494812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1495812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    case Token::FUNCTION:
1496812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      result = ParseFunctionDeclaration(&names, CHECK_OK);
1497812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      break;
1498812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1499a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    case Token::CLASS:
1500a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      result = ParseClassDeclaration(&names, CHECK_OK);
1501a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      break;
1502a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
1503812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    case Token::VAR:
1504812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    case Token::LET:
1505812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    case Token::CONST:
1506812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      result = ParseVariableStatement(kModuleElement, &names, CHECK_OK);
1507812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      break;
1508812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1509812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    default:
1510812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      *ok = false;
1511f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      ReportUnexpectedToken(scanner()->current_token());
1512812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      return NULL;
1513812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  }
1514812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
15157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Every export of a module may be assigned.
15167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  for (int i = 0; i < names.length(); ++i) {
15177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    Variable* var = scope_->Lookup(names[i]);
15187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    if (var == NULL) {
15197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // TODO(sigurds) This is an export that has no definition yet,
15207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // not clear what to do in this case.
15217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      continue;
15227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
15237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    if (!IsImmutableVariableMode(var->mode())) {
15247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      var->set_maybe_assigned();
15257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
15267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
15277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1528bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // Extract declared names into export declarations and interface.
1529f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Interface* interface = scope_->interface();
1530812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  for (int i = 0; i < names.length(); ++i) {
1531bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1532bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    if (FLAG_print_interface_details)
153308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      PrintF("# Export %.*s ", names[i]->length(), names[i]->raw_data());
1534bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
15357028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    Interface* inner = Interface::NewUnknown(zone());
15367028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    interface->Add(names[i], inner, zone(), CHECK_OK);
15377028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    if (!*ok)
15387028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      return NULL;
1539bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    VariableProxy* proxy = NewUnresolved(names[i], LET, inner);
1540bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    USE(proxy);
1541bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    // TODO(rossberg): Rethink whether we actually need to store export
1542bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    // declarations (for compilation?).
1543bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    // ExportDeclaration* declaration =
1544f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    //     factory()->NewExportDeclaration(proxy, scope_, position);
1545f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    // scope_->AddDeclaration(declaration);
1546812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  }
1547812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1548e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(result != NULL);
1549812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  return result;
1550f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
1551f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1552f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
155308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgStatement* Parser::ParseBlockElement(ZoneList<const AstRawString*>* labels,
1554f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org                                     bool* ok) {
1555f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // (Ecma 262 5th Edition, clause 14):
1556f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // SourceElement:
1557f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    Statement
1558f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    FunctionDeclaration
1559f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //
1560f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // In harmony mode we allow additionally the following productions
1561f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // BlockElement (aka SourceElement):
1562f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    LetDeclaration
1563f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //    ConstDeclaration
1564f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  //    GeneratorDeclaration
1565a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  //    ClassDeclaration
1566f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1567f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  switch (peek()) {
1568f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    case Token::FUNCTION:
1569812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      return ParseFunctionDeclaration(NULL, ok);
1570a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    case Token::CLASS:
1571a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      return ParseClassDeclaration(NULL, ok);
1572f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    case Token::CONST:
1573812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      return ParseVariableStatement(kModuleElement, NULL, ok);
157470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    case Token::LET:
1575e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(allow_harmony_scoping());
157670d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      if (strict_mode() == STRICT) {
157770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org        return ParseVariableStatement(kModuleElement, NULL, ok);
157870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      }
157970d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      // Fall through.
1580f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    default:
1581f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      return ParseStatement(labels, ok);
1582f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  }
1583f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
1584f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1585f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
158608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgStatement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels,
158708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                  bool* ok) {
158843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Statement ::
158943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   Block
159043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   VariableStatement
159143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   EmptyStatement
159243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   ExpressionStatement
159343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   IfStatement
159443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   IterationStatement
159543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   ContinueStatement
159643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   BreakStatement
159743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   ReturnStatement
159843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   WithStatement
159943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   LabelledStatement
160043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   SwitchStatement
160143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   ThrowStatement
160243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   TryStatement
160343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   DebuggerStatement
160443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
160543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Note: Since labels can only be used by 'break' and 'continue'
160643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // statements, which themselves are only valid within blocks,
160743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // iterations or 'switch' statements (i.e., BreakableStatements),
160843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // labels can be simply ignored in all other cases; except for
16093291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  // trivial labeled break statements 'label: break label' which is
161043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // parsed into an empty statement.
161143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  switch (peek()) {
161243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::LBRACE:
161343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return ParseBlock(labels, ok);
161443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
161543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::SEMICOLON:
161643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Next();
1617a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
161843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
161943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::IF:
1620a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      return ParseIfStatement(labels, ok);
162143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
162243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::DO:
1623a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      return ParseDoWhileStatement(labels, ok);
162443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
162543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::WHILE:
1626a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      return ParseWhileStatement(labels, ok);
162743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
162843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::FOR:
1629a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      return ParseForStatement(labels, ok);
163043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
163143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::CONTINUE:
1632a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      return ParseContinueStatement(ok);
163343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
163443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::BREAK:
1635a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      return ParseBreakStatement(labels, ok);
163643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
163743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::RETURN:
1638a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      return ParseReturnStatement(ok);
163943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
164043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::WITH:
1641a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      return ParseWithStatement(labels, ok);
164243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
164343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::SWITCH:
1644a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      return ParseSwitchStatement(labels, ok);
164543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
164643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::THROW:
1647a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      return ParseThrowStatement(ok);
164843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
164943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::TRY: {
165043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // NOTE: It is somewhat complicated to have labels on
165143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // try-statements. When breaking out of a try-finally statement,
165243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // one must take great care not to treat it as a
165343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // fall-through. It is much easier just to wrap the entire
165443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // try-statement in a statement block and put the labels there
1655a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      Block* result =
1656a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org          factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition);
1657e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org      Target target(&this->target_stack_, result);
165843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      TryStatement* statement = ParseTryStatement(CHECK_OK);
1659400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org      if (result) result->AddStatement(statement, zone());
166043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return result;
166143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
166243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
16639ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    case Token::FUNCTION: {
1664c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // FunctionDeclaration is only allowed in the context of SourceElements
1665c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // (Ecma 262 5th Edition, clause 14):
1666c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // SourceElement:
1667c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      //    Statement
1668c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      //    FunctionDeclaration
1669c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Common language extension is to allow function declaration in place
1670c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // of any statement. This language extension is disabled in strict mode.
1671f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      //
1672f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      // In Harmony mode, this case also handles the extension:
1673f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      // Statement:
1674f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      //    GeneratorDeclaration
1675486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      if (strict_mode() == STRICT) {
1676f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        ReportMessageAt(scanner()->peek_location(), "strict_function");
16779ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        *ok = false;
16789ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        return NULL;
16799ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      }
1680812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      return ParseFunctionDeclaration(NULL, ok);
16819ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    }
168243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1683a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    case Token::CLASS:
1684a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      return ParseClassDeclaration(NULL, ok);
1685a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
168643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case Token::DEBUGGER:
1687a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      return ParseDebuggerStatement(ok);
168843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
168970d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    case Token::VAR:
169070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    case Token::CONST:
169170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      return ParseVariableStatement(kStatement, NULL, ok);
169270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org
169370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    case Token::LET:
1694e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(allow_harmony_scoping());
169570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      if (strict_mode() == STRICT) {
169670d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org        return ParseVariableStatement(kStatement, NULL, ok);
169770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      }
169870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      // Fall through.
169943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    default:
1700a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      return ParseExpressionOrLabelledStatement(labels, ok);
170143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
170243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
170343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
170443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
170508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgVariableProxy* Parser::NewUnresolved(const AstRawString* name,
170608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                     VariableMode mode, Interface* interface) {
1707b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  // If we are inside a function, a declaration of a var/const variable is a
1708b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  // truly local variable, and the scope of the variable is always the function
1709b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  // scope.
1710394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Let/const variables in harmony mode are always added to the immediately
1711394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // enclosing scope.
1712812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  return DeclarationScope(mode)->NewUnresolved(
1713a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      factory(), name, interface, position());
1714812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org}
1715812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1716812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1717812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgvoid Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
1718bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  VariableProxy* proxy = declaration->proxy();
1719e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(proxy->raw_name() != NULL);
172008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  const AstRawString* name = proxy->raw_name();
1721812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  VariableMode mode = declaration->mode();
1722812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Scope* declaration_scope = DeclarationScope(mode);
1723812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Variable* var = NULL;
172443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
172581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  // If a suitable scope exists, then we can statically declare this
172643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // variable and also set its mode. In any case, a Declaration node
172743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // will be added to the scope so that the declaration can be added
172843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // to the corresponding activation frame at runtime if necessary.
172943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // For instance declarations inside an eval scope need to be added
173043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // to the calling function context.
17318e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // Similarly, strict mode eval scope does not leak variable declarations to
17328e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // the caller's scope so we declare all locals, too.
17334f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if (declaration_scope->is_function_scope() ||
1734486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      declaration_scope->is_strict_eval_scope() ||
1735f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      declaration_scope->is_block_scope() ||
1736bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      declaration_scope->is_module_scope() ||
1737355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      declaration_scope->is_global_scope()) {
173881cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org    // Declare the variable in the declaration scope.
1739355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    // For the global scope, we have to check for collisions with earlier
1740355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    // (i.e., enclosing) global scopes, to maintain the illusion of a single
1741355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    // global scope.
1742355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    var = declaration_scope->is_global_scope()
1743355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        ? declaration_scope->Lookup(name)
1744fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org        : declaration_scope->LookupLocal(name);
174543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (var == NULL) {
174643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Declare the name.
17477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      var = declaration_scope->DeclareLocal(name, mode,
17487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                            declaration->initialization(),
17497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                            kNotAssigned, proxy->interface());
175012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    } else if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode())
175112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org               || ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) &&
175212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                   !declaration_scope->is_global_scope())) {
17531805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      // The name was declared in this scope before; check for conflicting
17541805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      // re-declarations. We have a conflict if either of the declarations is
1755355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      // not a var (in the global scope, we also have to ignore legacy const for
1756355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      // compatibility). There is similar code in runtime.cc in the Declare
175712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      // functions. The function CheckConflictingVarDeclarations checks for
17581805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      // var and let bindings from different scopes whereas this is a check for
17591805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      // conflicting declarations within the same scope. This check also covers
1760355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      // the special case
17611805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      //
17621805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      // function () { let x; { var x; } }
17631805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      //
17641805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      // because the var declaration is hoisted to the function scope where 'x'
17651805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      // is already bound.
1766e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(IsDeclaredVariableMode(var->mode()));
1767a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org      if (allow_harmony_scoping() && strict_mode() == STRICT) {
1768486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        // In harmony we treat re-declarations as early errors. See
1769355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        // ES5 16 for a definition of early errors.
1770285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org        ParserTraits::ReportMessage("var_redeclaration", name);
1771355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        *ok = false;
1772355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        return;
177343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
17744edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org      Expression* expression = NewThrowTypeError(
17754edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org          "var_redeclaration", name, declaration->position());
1776355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      declaration_scope->SetIllegalRedeclaration(expression);
1777248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org    } else if (mode == VAR) {
1778248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org      var->set_maybe_assigned();
177943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
178043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
178143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
178243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // We add a declaration node for every declaration. The compiler
178343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // will only generate code if necessary. In particular, declarations
178443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for inner local variables that do not represent functions won't
178543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // result in any generated code.
178643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
178743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Note that we always add an unresolved proxy even if it's not
178843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // used, simply because we don't know in this method (w/o extra
178943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // parameters) if the proxy is needed or not. The proxy will be
179043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // bound during variable resolution time unless it was pre-bound
179143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // below.
179243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
179343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // WARNING: This will lead to multiple declaration nodes for the
179443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // same variable if it is declared several times. This is not a
179543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // semantic issue as long as we keep the source order, but it may be
179643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // a performance issue since it may lead to repeated
17979bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  // RuntimeHidden_DeclareLookupSlot calls.
1798812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  declaration_scope->AddDeclaration(declaration);
179943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1800486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  if (mode == CONST_LEGACY && declaration_scope->is_global_scope()) {
180127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    // For global const variables we bind the proxy to a variable.
1802e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(resolve);  // should be set by all callers
18033e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org    Variable::Kind kind = Variable::NORMAL;
18047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    var = new (zone())
18057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        Variable(declaration_scope, name, mode, true, kind,
18067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                 kNeedsInitialization, kNotAssigned, proxy->interface());
180727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  } else if (declaration_scope->is_eval_scope() &&
1808486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org             declaration_scope->strict_mode() == SLOPPY) {
1809486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    // For variable declarations in a sloppy eval scope the proxy is bound
181027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    // to a lookup variable to force a dynamic declaration using the
18119bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    // DeclareLookupSlot runtime function.
181227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    Variable::Kind kind = Variable::NORMAL;
18137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    // TODO(sigurds) figure out if kNotAssigned is OK here
18147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    var = new (zone()) Variable(declaration_scope, name, mode, true, kind,
18157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                declaration->initialization(), kNotAssigned,
18167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                proxy->interface());
181727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    var->AllocateTo(Variable::LOOKUP, -1);
181827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    resolve = true;
181943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
182043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
182143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If requested and we have a local variable, bind the proxy to the variable
182243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // at parse-time. This is used for functions (and consts) declared inside
182343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // statements: the corresponding function (or const) variable must be in the
182443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // function scope and not a statement-local scope, e.g. as provided with a
182543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // 'with' statement:
182643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
182743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   with (obj) {
182843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //     function f() {}
182943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   }
183043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
183143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // which is translated into:
183243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
183343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   with (obj) {
183443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //     // in this case this is not: 'var f; f = function () {};'
183543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //     var f = function () {};
183643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   }
183743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
183843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Note that if 'f' is accessed from inside the 'with' statement, it
183943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // will be allocated in the context (because we must be able to look
184043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // it up dynamically) but it will also be accessed statically, i.e.,
184143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // with a context slot index and a context chain length for this
184243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // initialization code. Thus, inside the 'with' statement, we need
184343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // both access to the static and the dynamic context chain; the
184443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // runtime needs to provide both.
1845bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  if (resolve && var != NULL) {
1846bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    proxy->BindTo(var);
1847bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
1848bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    if (FLAG_harmony_modules) {
1849bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      bool ok;
1850bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
185108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      if (FLAG_print_interface_details) {
185208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org        PrintF("# Declare %.*s ", var->raw_name()->length(),
185308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org               var->raw_name()->raw_data());
185408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      }
1855bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
18567028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      proxy->interface()->Unify(var->interface(), zone(), &ok);
1857bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      if (!ok) {
1858bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1859bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        if (FLAG_print_interfaces) {
1860bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com          PrintF("DECLARE TYPE ERROR\n");
1861bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com          PrintF("proxy: ");
1862bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com          proxy->interface()->Print();
1863bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com          PrintF("var: ");
1864bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com          var->interface()->Print();
1865bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        }
1866bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
1867285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org        ParserTraits::ReportMessage("module_type_error", name);
1868bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      }
1869bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    }
1870bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  }
187143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
187243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
187343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
187443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Language extension which is only enabled for source files loaded
187543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// through the API's extension mechanism.  A native function
187643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// declaration is resolved by looking up the function through a
187743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// callback provided by the extension.
187843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenStatement* Parser::ParseNativeDeclaration(bool* ok) {
1879a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  int pos = peek_position();
188043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::FUNCTION, CHECK_OK);
18818297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  // Allow "eval" or "arguments" for backward compatibility.
188208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
188343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::LPAREN, CHECK_OK);
188443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool done = (peek() == Token::RPAREN);
188543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (!done) {
18868297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
188743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    done = (peek() == Token::RPAREN);
1888fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    if (!done) {
1889fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org      Expect(Token::COMMA, CHECK_OK);
1890fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    }
189143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
189243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::RPAREN, CHECK_OK);
189343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::SEMICOLON, CHECK_OK);
189443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
189543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Make sure that the function containing the native declaration
189643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // isn't lazily compiled. The extension structures are only
189743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // accessible while parsing the first time not when reparsing
189843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // because of lazy compilation.
1899812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  DeclarationScope(VAR)->ForceEagerCompilation();
190043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
190143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // TODO(1240846): It's weird that native function declarations are
190243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // introduced dynamically when we meet their declarations, whereas
1903f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // other functions are set up when entering the surrounding scope.
190428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue());
1905812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Declaration* declaration =
1906f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      factory()->NewVariableDeclaration(proxy, VAR, scope_, pos);
1907812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Declare(declaration, true, CHECK_OK);
1908a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral(
1909a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      name, extension_, RelocInfo::kNoPosition);
1910b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  return factory()->NewExpressionStatement(
1911b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      factory()->NewAssignment(
1912a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org          Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition),
1913a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      pos);
191443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
191543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
191643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
191708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgStatement* Parser::ParseFunctionDeclaration(
191808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    ZoneList<const AstRawString*>* names, bool* ok) {
1919c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  // FunctionDeclaration ::
1920c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  //   'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
1921f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  // GeneratorDeclaration ::
1922f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  //   'function' '*' Identifier '(' FormalParameterListopt ')'
1923f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  //      '{' FunctionBody '}'
192443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::FUNCTION, CHECK_OK);
1925a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  int pos = position();
1926d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org  bool is_generator = Check(Token::MUL);
192704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  bool is_strict_reserved = false;
192808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  const AstRawString* name = ParseIdentifierOrStrictReservedWord(
192904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      &is_strict_reserved, CHECK_OK);
19302c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  FunctionLiteral* fun =
19312c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      ParseFunctionLiteral(name, scanner()->location(), is_strict_reserved,
19322c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                           is_generator ? FunctionKind::kGeneratorFunction
19332c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                                        : FunctionKind::kNormalFunction,
19342c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                           pos, FunctionLiteral::DECLARATION,
19352c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                           FunctionLiteral::NORMAL_ARITY, CHECK_OK);
1936c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  // Even if we're not at the top-level of the global or a function
1937355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  // scope, we treat it as such and introduce the function with its
1938c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  // initial value upon entering the corresponding scope.
193912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // In ES6, a function behaves as a lexical binding, except in the
194012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // global scope, or the initial scope of eval or another function.
1941355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  VariableMode mode =
194212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      allow_harmony_scoping() && strict_mode() == STRICT &&
194312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      !(scope_->is_global_scope() || scope_->is_eval_scope() ||
194412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          scope_->is_function_scope()) ? LET : VAR;
194528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
1946812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Declaration* declaration =
1947f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
1948812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Declare(declaration, true, CHECK_OK);
19497028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  if (names) names->Add(name, zone());
1950a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
195143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
195243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
195343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1954a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgStatement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
1955a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org                                         bool* ok) {
1956a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  // ClassDeclaration ::
1957a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  //   'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
1958a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  //
1959a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  // A ClassDeclaration
1960a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  //
1961a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  //   class C { ... }
1962a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  //
1963a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  // has the same semantics as:
1964a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  //
1965a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  //   let C = class C { ... };
1966a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  //
1967a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  // so rewrite it as such.
1968a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
1969a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Expect(Token::CLASS, CHECK_OK);
1970a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  int pos = position();
1971a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  bool is_strict_reserved = false;
1972a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  const AstRawString* name =
1973a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
1974a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Expression* value = ParseClassLiteral(name, scanner()->location(),
1975a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org                                        is_strict_reserved, pos, CHECK_OK);
1976a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
1977a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Block* block = factory()->NewBlock(NULL, 1, true, pos);
1978a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  VariableMode mode = LET;
1979a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
1980a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Declaration* declaration =
1981a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
1982a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Declare(declaration, true, CHECK_OK);
1983a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
1984a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Token::Value init_op = Token::INIT_LET;
1985a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos);
1986a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  block->AddStatement(
1987a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
1988a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      zone());
1989a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
1990a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  if (names) names->Add(name, zone());
1991a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  return block;
1992a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org}
1993a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
1994a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
199508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgBlock* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) {
1996a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  if (allow_harmony_scoping() && strict_mode() == STRICT) {
1997486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    return ParseScopedBlock(labels, ok);
1998486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  }
19994acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
200043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Block ::
200143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   '{' Statement* '}'
200243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
200343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Note that a Block does not introduce a new execution scope!
200443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // (ECMA-262, 3rd, 12.2)
200543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
200643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Construct block expecting 16 statements.
2007a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  Block* result =
2008a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2009e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  Target target(&this->target_stack_, result);
201043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::LBRACE, CHECK_OK);
201143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (peek() != Token::RBRACE) {
201243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Statement* stat = ParseStatement(NULL, CHECK_OK);
20136db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org    if (stat && !stat->IsEmpty()) {
2014400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org      result->AddStatement(stat, zone());
20156db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org    }
201643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
201743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expect(Token::RBRACE, CHECK_OK);
201843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
201943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
202043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
202143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
202208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgBlock* Parser::ParseScopedBlock(ZoneList<const AstRawString*>* labels,
202308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                bool* ok) {
2024f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // The harmony mode uses block elements instead of statements.
2025c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  //
2026c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Block ::
2027f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  //   '{' BlockElement* '}'
2028c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
20294acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  // Construct block expecting 16 statements.
2030a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  Block* body =
2031a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2032f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
20334acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
20344acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  // Parse the statements and collect escaping labels.
20354acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  Expect(Token::LBRACE, CHECK_OK);
2036f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  block_scope->set_start_position(scanner()->location().beg_pos);
2037f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  { BlockState block_state(&scope_, block_scope);
20387028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    TargetCollector collector(zone());
2039394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Target target(&this->target_stack_, &collector);
20404acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    Target target_body(&this->target_stack_, body);
20414acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
20424acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    while (peek() != Token::RBRACE) {
2043f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      Statement* stat = ParseBlockElement(NULL, CHECK_OK);
20444acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      if (stat && !stat->IsEmpty()) {
2045400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org        body->AddStatement(stat, zone());
20464acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      }
20474acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    }
20484acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  }
20494acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  Expect(Token::RBRACE, CHECK_OK);
2050f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  block_scope->set_end_position(scanner()->location().end_pos);
20511805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  block_scope = block_scope->FinalizeBlockScope();
2052ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  body->set_scope(block_scope);
2053486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  return body;
20544acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org}
20554acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
20564acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
2057b645116853c677aca8a316381b87441ba6004f67danno@chromium.orgBlock* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
205808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                      ZoneList<const AstRawString*>* names,
2059b645116853c677aca8a316381b87441ba6004f67danno@chromium.org                                      bool* ok) {
206043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // VariableStatement ::
206143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //   VariableDeclarations ';'
206243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
206308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  const AstRawString* ignore;
2064f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Block* result =
2065812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK);
206643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ExpectSemicolon(CHECK_OK);
206743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
206843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
206943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2070ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
207143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// If the variable declaration declares exactly one non-const
207278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// variable, then *out is set to that variable. In all other cases,
207378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// *out is untouched; in particular, it is the caller's responsibility
207443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// to initialize it properly. This mechanism is used for the parsing
207543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// of 'for-in' loops.
2076394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comBlock* Parser::ParseVariableDeclarations(
2077394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    VariableDeclarationContext var_context,
2078394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    VariableDeclarationProperties* decl_props,
207908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    ZoneList<const AstRawString*>* names,
208008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    const AstRawString** out,
2081394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    bool* ok) {
208243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // VariableDeclarations ::
2083394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //   ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
2084394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //
2085394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // The ES6 Draft Rev3 specifies the following grammar for const declarations
2086394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //
2087394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // ConstDeclaration ::
2088394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //   const ConstBinding (',' ConstBinding)* ';'
2089394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // ConstBinding ::
2090394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //   Identifier '=' AssignmentExpression
2091394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //
2092394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // TODO(ES6):
2093394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // ConstBinding ::
2094394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //   BindingPattern '=' AssignmentExpression
2095a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
2096a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  int pos = peek_position();
2097b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  VariableMode mode = VAR;
209880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  // True if the binding needs initialization. 'let' and 'const' declared
209980c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  // bindings are created uninitialized by their declaration nodes and
210080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  // need initialization. 'var' declared bindings are always initialized
210180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  // immediately by their declaration nodes.
210280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  bool needs_init = false;
210343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool is_const = false;
210480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  Token::Value init_op = Token::INIT_VAR;
210543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (peek() == Token::VAR) {
210643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Consume(Token::VAR);
210743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (peek() == Token::CONST) {
21081b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
21091b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    //
21101b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
21111b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    //
21121b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // * It is a Syntax Error if the code that matches this production is not
21131b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    //   contained in extended code.
21141b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    //
2115486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    // However disallowing const in sloppy mode will break compatibility with
21161b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // existing pages. Therefore we keep allowing const with the old
2117486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    // non-harmony semantics in sloppy mode.
211843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Consume(Token::CONST);
2119486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    switch (strict_mode()) {
2120486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      case SLOPPY:
2121486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        mode = CONST_LEGACY;
2122486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        init_op = Token::INIT_CONST_LEGACY;
21231b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        break;
2124486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      case STRICT:
2125a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org        if (allow_harmony_scoping()) {
2126486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org          if (var_context == kStatement) {
2127486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org            // In strict mode 'const' declarations are only allowed in source
2128486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org            // element positions.
2129285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org            ReportMessage("unprotected_const");
2130486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org            *ok = false;
2131486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org            return NULL;
2132486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org          }
2133486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org          mode = CONST;
2134486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org          init_op = Token::INIT_CONST;
2135486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        } else {
2136285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org          ReportMessage("strict_const");
21371b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          *ok = false;
21381b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          return NULL;
21391b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        }
21409ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    }
214143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    is_const = true;
214280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org    needs_init = true;
214370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  } else if (peek() == Token::LET && strict_mode() == STRICT) {
2144e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(allow_harmony_scoping());
2145b645116853c677aca8a316381b87441ba6004f67danno@chromium.org    Consume(Token::LET);
2146f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    if (var_context == kStatement) {
2147394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      // Let declarations are only allowed in source element positions.
2148285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org      ReportMessage("unprotected_let");
2149b645116853c677aca8a316381b87441ba6004f67danno@chromium.org      *ok = false;
2150b645116853c677aca8a316381b87441ba6004f67danno@chromium.org      return NULL;
2151b645116853c677aca8a316381b87441ba6004f67danno@chromium.org    }
2152b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    mode = LET;
215380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org    needs_init = true;
215480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org    init_op = Token::INIT_LET;
215543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
215643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    UNREACHABLE();  // by current callers
215743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
215843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2159812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Scope* declaration_scope = DeclarationScope(mode);
2160812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
2161b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  // The scope of a var/const declared variable anywhere inside a function
216243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
2163b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  // transform a source-level var/const declaration into a (Function)
216443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Scope declaration, and rewrite the source-level initialization into an
216543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // assignment statement. We use a block to collect multiple assignments.
216643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
216743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // We mark the block as initializer block because we don't want the
216843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // rewriter to add a '.result' assignment to such a block (to get compliant
216943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // behavior for code such as print(eval('var x = 7')), and for cosmetic
217043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // reasons when pretty-printing. Also, unless an assignment (initialization)
217143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // is inside an initializer block, it is ignored.
217243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
217343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Create new block with one expected declaration.
2174a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  Block* block = factory()->NewBlock(NULL, 1, true, pos);
217543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int nvars = 0;  // the number of variables declared
217608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  const AstRawString* name = NULL;
217743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  do {
217865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    if (fni_ != NULL) fni_->Enter();
217965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
218043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Parse variable name.
218143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (nvars > 0) Consume(Token::COMMA);
21828297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
218365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    if (fni_ != NULL) fni_->PushVariableName(name);
218443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
218543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Declare variable.
218643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Note that we *always* must treat the initial value via a separate init
218743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // assignment for variables and constants because the value must be assigned
218843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // when the variable is encountered in the source. But the variable/constant
218943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // is declared (and set to 'undefined') upon entering the function within
219043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // which the variable or constant is declared. Only function variables have
219143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // an initial value in the declaration (because they are initialized upon
219243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // entering the function).
219343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    //
219443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // If we have a const declaration, in an inner scope, the proxy is always
219543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // bound to the declared variable (independent of possibly surrounding with
219643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // statements).
2197394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // For let/const declarations in harmony mode, we can also immediately
2198394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // pre-resolve the proxy because it resides in the same scope as the
2199394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // declaration.
220028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    Interface* interface =
220128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org        is_const ? Interface::NewConst() : Interface::NewValue();
220228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    VariableProxy* proxy = NewUnresolved(name, mode, interface);
2203812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    Declaration* declaration =
2204f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
2205812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    Declare(declaration, mode != VAR, CHECK_OK);
220643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    nvars++;
22074f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
2208196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      ReportMessage("too_many_variables");
22097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org      *ok = false;
22107304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org      return NULL;
22117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    }
22127028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    if (names) names->Add(name, zone());
221343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
221443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Parse initialization expression if present and/or needed. A
221543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // declaration of the form:
221643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    //
221743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    //    var v = x;