blob: da680411a9e4534bdd66d3221dae0f3df0fa2f9d [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "v8.h"
29
30#include "api.h"
Ben Murdoch3ef787d2012-04-12 10:51:47 +010031#include "ast.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000032#include "bootstrapper.h"
Ben Murdoch589d6972011-11-30 16:04:58 +000033#include "char-predicates-inl.h"
Steve Block6ded16b2010-05-10 14:33:55 +010034#include "codegen.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000035#include "compiler.h"
Kristian Monsen80d68ea2010-09-08 11:05:35 +010036#include "func-name-inferrer.h"
Steve Block6ded16b2010-05-10 14:33:55 +010037#include "messages.h"
Kristian Monsen25f61362010-05-21 11:50:48 +010038#include "parser.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000039#include "platform.h"
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -080040#include "preparser.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000041#include "runtime.h"
Ben Murdoch589d6972011-11-30 16:04:58 +000042#include "scanner-character-streams.h"
Ben Murdoch3bec4d22010-07-22 14:51:16 +010043#include "scopeinfo.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000044#include "string-stream.h"
45
46namespace v8 {
47namespace internal {
48
Steve Blocka7e24c12009-10-30 11:49:00 +000049// PositionStack is used for on-stack allocation of token positions for
50// new expressions. Please look at ParseNewExpression.
51
52class PositionStack {
53 public:
54 explicit PositionStack(bool* ok) : top_(NULL), ok_(ok) {}
55 ~PositionStack() { ASSERT(!*ok_ || is_empty()); }
56
57 class Element {
58 public:
59 Element(PositionStack* stack, int value) {
60 previous_ = stack->top();
61 value_ = value;
62 stack->set_top(this);
63 }
64
65 private:
66 Element* previous() { return previous_; }
67 int value() { return value_; }
68 friend class PositionStack;
69 Element* previous_;
70 int value_;
71 };
72
73 bool is_empty() { return top_ == NULL; }
74 int pop() {
75 ASSERT(!is_empty());
76 int result = top_->value();
77 top_ = top_->previous();
78 return result;
79 }
80
81 private:
82 Element* top() { return top_; }
83 void set_top(Element* value) { top_ = value; }
84 Element* top_;
85 bool* ok_;
86};
87
88
Steve Blocka7e24c12009-10-30 11:49:00 +000089RegExpBuilder::RegExpBuilder()
Ben Murdoch8b112d22011-06-08 16:22:53 +010090 : zone_(Isolate::Current()->zone()),
91 pending_empty_(false),
92 characters_(NULL),
93 terms_(),
94 alternatives_()
Steve Blocka7e24c12009-10-30 11:49:00 +000095#ifdef DEBUG
Ben Murdoch8b112d22011-06-08 16:22:53 +010096 , last_added_(ADD_NONE)
Steve Blocka7e24c12009-10-30 11:49:00 +000097#endif
98 {}
99
100
101void RegExpBuilder::FlushCharacters() {
102 pending_empty_ = false;
103 if (characters_ != NULL) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100104 RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector());
Steve Blocka7e24c12009-10-30 11:49:00 +0000105 characters_ = NULL;
106 text_.Add(atom);
107 LAST(ADD_ATOM);
108 }
109}
110
111
112void RegExpBuilder::FlushText() {
113 FlushCharacters();
114 int num_text = text_.length();
115 if (num_text == 0) {
116 return;
117 } else if (num_text == 1) {
118 terms_.Add(text_.last());
119 } else {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100120 RegExpText* text = new(zone()) RegExpText();
Steve Blocka7e24c12009-10-30 11:49:00 +0000121 for (int i = 0; i < num_text; i++)
122 text_.Get(i)->AppendToText(text);
123 terms_.Add(text);
124 }
125 text_.Clear();
126}
127
128
129void RegExpBuilder::AddCharacter(uc16 c) {
130 pending_empty_ = false;
131 if (characters_ == NULL) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000132 characters_ = new(zone()) ZoneList<uc16>(4);
Steve Blocka7e24c12009-10-30 11:49:00 +0000133 }
134 characters_->Add(c);
135 LAST(ADD_CHAR);
136}
137
138
139void RegExpBuilder::AddEmpty() {
140 pending_empty_ = true;
141}
142
143
144void RegExpBuilder::AddAtom(RegExpTree* term) {
145 if (term->IsEmpty()) {
146 AddEmpty();
147 return;
148 }
149 if (term->IsTextElement()) {
150 FlushCharacters();
151 text_.Add(term);
152 } else {
153 FlushText();
154 terms_.Add(term);
155 }
156 LAST(ADD_ATOM);
157}
158
159
160void RegExpBuilder::AddAssertion(RegExpTree* assert) {
161 FlushText();
162 terms_.Add(assert);
163 LAST(ADD_ASSERT);
164}
165
166
167void RegExpBuilder::NewAlternative() {
168 FlushTerms();
169}
170
171
172void RegExpBuilder::FlushTerms() {
173 FlushText();
174 int num_terms = terms_.length();
175 RegExpTree* alternative;
176 if (num_terms == 0) {
177 alternative = RegExpEmpty::GetInstance();
178 } else if (num_terms == 1) {
179 alternative = terms_.last();
180 } else {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100181 alternative = new(zone()) RegExpAlternative(terms_.GetList());
Steve Blocka7e24c12009-10-30 11:49:00 +0000182 }
183 alternatives_.Add(alternative);
184 terms_.Clear();
185 LAST(ADD_NONE);
186}
187
188
189RegExpTree* RegExpBuilder::ToRegExp() {
190 FlushTerms();
191 int num_alternatives = alternatives_.length();
192 if (num_alternatives == 0) {
193 return RegExpEmpty::GetInstance();
194 }
195 if (num_alternatives == 1) {
196 return alternatives_.last();
197 }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100198 return new(zone()) RegExpDisjunction(alternatives_.GetList());
Steve Blocka7e24c12009-10-30 11:49:00 +0000199}
200
201
Leon Clarkee46be812010-01-19 14:06:41 +0000202void RegExpBuilder::AddQuantifierToAtom(int min,
203 int max,
204 RegExpQuantifier::Type type) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000205 if (pending_empty_) {
206 pending_empty_ = false;
207 return;
208 }
209 RegExpTree* atom;
210 if (characters_ != NULL) {
211 ASSERT(last_added_ == ADD_CHAR);
212 // Last atom was character.
213 Vector<const uc16> char_vector = characters_->ToConstVector();
214 int num_chars = char_vector.length();
215 if (num_chars > 1) {
216 Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1);
Ben Murdoch8b112d22011-06-08 16:22:53 +0100217 text_.Add(new(zone()) RegExpAtom(prefix));
Steve Blocka7e24c12009-10-30 11:49:00 +0000218 char_vector = char_vector.SubVector(num_chars - 1, num_chars);
219 }
220 characters_ = NULL;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100221 atom = new(zone()) RegExpAtom(char_vector);
Steve Blocka7e24c12009-10-30 11:49:00 +0000222 FlushText();
223 } else if (text_.length() > 0) {
224 ASSERT(last_added_ == ADD_ATOM);
225 atom = text_.RemoveLast();
226 FlushText();
227 } else if (terms_.length() > 0) {
228 ASSERT(last_added_ == ADD_ATOM);
229 atom = terms_.RemoveLast();
230 if (atom->max_match() == 0) {
231 // Guaranteed to only match an empty string.
232 LAST(ADD_TERM);
233 if (min == 0) {
234 return;
235 }
236 terms_.Add(atom);
237 return;
238 }
239 } else {
240 // Only call immediately after adding an atom or character!
241 UNREACHABLE();
242 return;
243 }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100244 terms_.Add(new(zone()) RegExpQuantifier(min, max, type, atom));
Steve Blocka7e24c12009-10-30 11:49:00 +0000245 LAST(ADD_TERM);
246}
247
248
Steve Block9fac8402011-05-12 15:51:54 +0100249Handle<String> Parser::LookupSymbol(int symbol_id) {
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800250 // Length of symbol cache is the number of identified symbols.
251 // If we are larger than that, or negative, it's not a cached symbol.
252 // This might also happen if there is no preparser symbol data, even
253 // if there is some preparser data.
254 if (static_cast<unsigned>(symbol_id)
255 >= static_cast<unsigned>(symbol_cache_.length())) {
Steve Block9fac8402011-05-12 15:51:54 +0100256 if (scanner().is_literal_ascii()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100257 return isolate()->factory()->LookupAsciiSymbol(
258 scanner().literal_ascii_string());
Steve Block9fac8402011-05-12 15:51:54 +0100259 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100260 return isolate()->factory()->LookupTwoByteSymbol(
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100261 scanner().literal_utf16_string());
Steve Block9fac8402011-05-12 15:51:54 +0100262 }
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800263 }
Steve Block9fac8402011-05-12 15:51:54 +0100264 return LookupCachedSymbol(symbol_id);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800265}
266
267
Steve Block9fac8402011-05-12 15:51:54 +0100268Handle<String> Parser::LookupCachedSymbol(int symbol_id) {
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800269 // Make sure the cache is large enough to hold the symbol identifier.
270 if (symbol_cache_.length() <= symbol_id) {
271 // Increase length to index + 1.
272 symbol_cache_.AddBlock(Handle<String>::null(),
273 symbol_id + 1 - symbol_cache_.length());
274 }
275 Handle<String> result = symbol_cache_.at(symbol_id);
276 if (result.is_null()) {
Steve Block9fac8402011-05-12 15:51:54 +0100277 if (scanner().is_literal_ascii()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100278 result = isolate()->factory()->LookupAsciiSymbol(
279 scanner().literal_ascii_string());
Steve Block9fac8402011-05-12 15:51:54 +0100280 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100281 result = isolate()->factory()->LookupTwoByteSymbol(
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100282 scanner().literal_utf16_string());
Steve Block9fac8402011-05-12 15:51:54 +0100283 }
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800284 symbol_cache_.at(symbol_id) = result;
Iain Merrick9ac36c92010-09-13 15:29:50 +0100285 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +0000286 }
Steve Block44f0eee2011-05-26 01:26:41 +0100287 isolate()->counters()->total_preparse_symbols_skipped()->Increment();
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800288 return result;
289}
Steve Blocka7e24c12009-10-30 11:49:00 +0000290
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800291
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100292FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) {
293 // The current pre-data entry must be a FunctionEntry with the given
294 // start position.
Iain Merrick9ac36c92010-09-13 15:29:50 +0100295 if ((function_index_ + FunctionEntry::kSize <= store_.length())
296 && (static_cast<int>(store_[function_index_]) == start)) {
297 int index = function_index_;
298 function_index_ += FunctionEntry::kSize;
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100299 return FunctionEntry(store_.SubVector(index,
300 index + FunctionEntry::kSize));
Steve Blocka7e24c12009-10-30 11:49:00 +0000301 }
302 return FunctionEntry();
303}
304
305
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100306int ScriptDataImpl::GetSymbolIdentifier() {
307 return ReadNumber(&symbol_data_);
Iain Merrick9ac36c92010-09-13 15:29:50 +0100308}
309
310
Iain Merrick9ac36c92010-09-13 15:29:50 +0100311bool ScriptDataImpl::SanityCheck() {
312 // Check that the header data is valid and doesn't specify
313 // point to positions outside the store.
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800314 if (store_.length() < PreparseDataConstants::kHeaderSize) return false;
315 if (magic() != PreparseDataConstants::kMagicNumber) return false;
316 if (version() != PreparseDataConstants::kCurrentVersion) return false;
Iain Merrick9ac36c92010-09-13 15:29:50 +0100317 if (has_error()) {
318 // Extra sane sanity check for error message encoding.
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800319 if (store_.length() <= PreparseDataConstants::kHeaderSize
320 + PreparseDataConstants::kMessageTextPos) {
321 return false;
322 }
323 if (Read(PreparseDataConstants::kMessageStartPos) >
324 Read(PreparseDataConstants::kMessageEndPos)) {
325 return false;
326 }
327 unsigned arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
328 int pos = PreparseDataConstants::kMessageTextPos;
Iain Merrick9ac36c92010-09-13 15:29:50 +0100329 for (unsigned int i = 0; i <= arg_count; i++) {
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800330 if (store_.length() <= PreparseDataConstants::kHeaderSize + pos) {
331 return false;
332 }
Iain Merrick9ac36c92010-09-13 15:29:50 +0100333 int length = static_cast<int>(Read(pos));
334 if (length < 0) return false;
335 pos += 1 + length;
336 }
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800337 if (store_.length() < PreparseDataConstants::kHeaderSize + pos) {
338 return false;
339 }
Iain Merrick9ac36c92010-09-13 15:29:50 +0100340 return true;
341 }
342 // Check that the space allocated for function entries is sane.
343 int functions_size =
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800344 static_cast<int>(store_[PreparseDataConstants::kFunctionsSizeOffset]);
Iain Merrick9ac36c92010-09-13 15:29:50 +0100345 if (functions_size < 0) return false;
346 if (functions_size % FunctionEntry::kSize != 0) return false;
347 // Check that the count of symbols is non-negative.
348 int symbol_count =
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800349 static_cast<int>(store_[PreparseDataConstants::kSymbolCountOffset]);
Iain Merrick9ac36c92010-09-13 15:29:50 +0100350 if (symbol_count < 0) return false;
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100351 // Check that the total size has room for header and function entries.
Iain Merrick9ac36c92010-09-13 15:29:50 +0100352 int minimum_size =
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800353 PreparseDataConstants::kHeaderSize + functions_size;
Iain Merrick9ac36c92010-09-13 15:29:50 +0100354 if (store_.length() < minimum_size) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +0000355 return true;
356}
357
358
Steve Block59151502010-09-22 15:07:15 +0100359
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100360const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000361 int length = start[0];
362 char* result = NewArray<char>(length + 1);
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100363 for (int i = 0; i < length; i++) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000364 result[i] = start[i + 1];
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100365 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000366 result[length] = '\0';
367 if (chars != NULL) *chars = length;
368 return result;
369}
370
Steve Blocka7e24c12009-10-30 11:49:00 +0000371Scanner::Location ScriptDataImpl::MessageLocation() {
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800372 int beg_pos = Read(PreparseDataConstants::kMessageStartPos);
373 int end_pos = Read(PreparseDataConstants::kMessageEndPos);
Steve Blocka7e24c12009-10-30 11:49:00 +0000374 return Scanner::Location(beg_pos, end_pos);
375}
376
377
378const char* ScriptDataImpl::BuildMessage() {
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800379 unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos);
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100380 return ReadString(start, NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +0000381}
382
383
384Vector<const char*> ScriptDataImpl::BuildArgs() {
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800385 int arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
Steve Blocka7e24c12009-10-30 11:49:00 +0000386 const char** array = NewArray<const char*>(arg_count);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100387 // Position after text found by skipping past length field and
388 // length field content words.
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800389 int pos = PreparseDataConstants::kMessageTextPos + 1
390 + Read(PreparseDataConstants::kMessageTextPos);
Steve Blocka7e24c12009-10-30 11:49:00 +0000391 for (int i = 0; i < arg_count; i++) {
392 int count = 0;
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100393 array[i] = ReadString(ReadAddress(pos), &count);
Steve Blocka7e24c12009-10-30 11:49:00 +0000394 pos += count + 1;
395 }
396 return Vector<const char*>(array, arg_count);
397}
398
399
400unsigned ScriptDataImpl::Read(int position) {
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800401 return store_[PreparseDataConstants::kHeaderSize + position];
Steve Blocka7e24c12009-10-30 11:49:00 +0000402}
403
404
405unsigned* ScriptDataImpl::ReadAddress(int position) {
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800406 return &store_[PreparseDataConstants::kHeaderSize + position];
Steve Blocka7e24c12009-10-30 11:49:00 +0000407}
408
409
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100410Scope* Parser::NewScope(Scope* parent, ScopeType type) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100411 Scope* result = new(zone()) Scope(parent, type);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100412 result->Initialize();
Steve Blocka7e24c12009-10-30 11:49:00 +0000413 return result;
414}
415
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000416
Steve Blocka7e24c12009-10-30 11:49:00 +0000417// ----------------------------------------------------------------------------
418// Target is a support class to facilitate manipulation of the
419// Parser's target_stack_ (the stack of potential 'break' and
420// 'continue' statement targets). Upon construction, a new target is
421// added; it is removed upon destruction.
422
423class Target BASE_EMBEDDED {
424 public:
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800425 Target(Target** variable, AstNode* node)
426 : variable_(variable), node_(node), previous_(*variable) {
427 *variable = this;
Steve Blocka7e24c12009-10-30 11:49:00 +0000428 }
429
430 ~Target() {
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800431 *variable_ = previous_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000432 }
433
434 Target* previous() { return previous_; }
435 AstNode* node() { return node_; }
436
437 private:
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800438 Target** variable_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000439 AstNode* node_;
440 Target* previous_;
441};
442
443
444class TargetScope BASE_EMBEDDED {
445 public:
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800446 explicit TargetScope(Target** variable)
447 : variable_(variable), previous_(*variable) {
448 *variable = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +0000449 }
450
451 ~TargetScope() {
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800452 *variable_ = previous_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000453 }
454
455 private:
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800456 Target** variable_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000457 Target* previous_;
458};
459
460
461// ----------------------------------------------------------------------------
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100462// FunctionState and BlockState together implement the parser's scope stack.
463// The parser's current scope is in top_scope_. The BlockState and
464// FunctionState constructors push on the scope stack and the destructors
465// pop. They are also used to hold the parser's per-function and per-block
466// state.
Steve Blocka7e24c12009-10-30 11:49:00 +0000467
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100468class Parser::BlockState BASE_EMBEDDED {
Steve Blocka7e24c12009-10-30 11:49:00 +0000469 public:
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100470 BlockState(Parser* parser, Scope* scope)
471 : parser_(parser),
472 outer_scope_(parser->top_scope_) {
473 parser->top_scope_ = scope;
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000474 }
475
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100476 ~BlockState() { parser_->top_scope_ = outer_scope_; }
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000477
478 private:
479 Parser* parser_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100480 Scope* outer_scope_;
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000481};
482
483
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100484Parser::FunctionState::FunctionState(Parser* parser,
485 Scope* scope,
486 Isolate* isolate)
487 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
488 next_handler_index_(0),
489 expected_property_count_(0),
490 only_simple_this_property_assignments_(false),
491 this_property_assignments_(isolate->factory()->empty_fixed_array()),
492 parser_(parser),
493 outer_function_state_(parser->current_function_state_),
494 outer_scope_(parser->top_scope_),
495 saved_ast_node_id_(isolate->ast_node_id()),
496 factory_(isolate) {
Steve Block44f0eee2011-05-26 01:26:41 +0100497 parser->top_scope_ = scope;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100498 parser->current_function_state_ = this;
Ben Murdoch589d6972011-11-30 16:04:58 +0000499 isolate->set_ast_node_id(AstNode::kDeclarationsId + 1);
Steve Block44f0eee2011-05-26 01:26:41 +0100500}
501
502
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100503Parser::FunctionState::~FunctionState() {
504 parser_->top_scope_ = outer_scope_;
505 parser_->current_function_state_ = outer_function_state_;
506 if (outer_function_state_ != NULL) {
507 parser_->isolate()->set_ast_node_id(saved_ast_node_id_);
508 }
Steve Block44f0eee2011-05-26 01:26:41 +0100509}
510
511
Steve Blocka7e24c12009-10-30 11:49:00 +0000512// ----------------------------------------------------------------------------
513// The CHECK_OK macro is a convenient macro to enforce error
514// handling for functions that may fail (by returning !*ok).
515//
516// CAUTION: This macro appends extra statements after a call,
517// thus it must never be used where only a single statement
518// is correct (e.g. an if statement branch w/o braces)!
519
520#define CHECK_OK ok); \
521 if (!*ok) return NULL; \
522 ((void)0
523#define DUMMY ) // to make indentation work
524#undef DUMMY
525
526#define CHECK_FAILED /**/); \
527 if (failed_) return NULL; \
528 ((void)0
529#define DUMMY ) // to make indentation work
530#undef DUMMY
531
532// ----------------------------------------------------------------------------
533// Implementation of Parser
534
535Parser::Parser(Handle<Script> script,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100536 int parser_flags,
Steve Blocka7e24c12009-10-30 11:49:00 +0000537 v8::Extension* extension,
Steve Blocka7e24c12009-10-30 11:49:00 +0000538 ScriptDataImpl* pre_data)
Steve Block44f0eee2011-05-26 01:26:41 +0100539 : isolate_(script->GetIsolate()),
540 symbol_cache_(pre_data ? pre_data->symbol_count() : 0),
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800541 script_(script),
Ben Murdoch8b112d22011-06-08 16:22:53 +0100542 scanner_(isolate_->unicode_cache()),
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100543 reusable_preparser_(NULL),
Steve Blocka7e24c12009-10-30 11:49:00 +0000544 top_scope_(NULL),
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100545 current_function_state_(NULL),
Steve Blocka7e24c12009-10-30 11:49:00 +0000546 target_stack_(NULL),
Steve Blocka7e24c12009-10-30 11:49:00 +0000547 extension_(extension),
Steve Block6ded16b2010-05-10 14:33:55 +0100548 pre_data_(pre_data),
Ben Murdochb0fe1622011-05-05 13:52:32 +0100549 fni_(NULL),
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100550 allow_natives_syntax_((parser_flags & kAllowNativesSyntax) != 0),
551 allow_lazy_((parser_flags & kAllowLazy) != 0),
552 allow_modules_((parser_flags & kAllowModules) != 0),
Ben Murdochb8e0da22011-05-16 14:20:40 +0100553 stack_overflow_(false),
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100554 parenthesized_function_(false) {
555 isolate_->set_ast_node_id(0);
556 if ((parser_flags & kLanguageModeMask) == EXTENDED_MODE) {
557 scanner().SetHarmonyScoping(true);
558 }
559 if ((parser_flags & kAllowModules) != 0) {
560 scanner().SetHarmonyModules(true);
561 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000562}
563
564
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100565FunctionLiteral* Parser::ParseProgram(CompilationInfo* info) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000566 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
Steve Blocka7e24c12009-10-30 11:49:00 +0000567
Steve Block44f0eee2011-05-26 01:26:41 +0100568 HistogramTimerScope timer(isolate()->counters()->parse());
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100569 Handle<String> source(String::cast(script_->source()));
Steve Block44f0eee2011-05-26 01:26:41 +0100570 isolate()->counters()->total_parse_size()->Increment(source->length());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000571 fni_ = new(zone()) FuncNameInferrer(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +0000572
573 // Initialize parser state.
Steve Block6ded16b2010-05-10 14:33:55 +0100574 source->TryFlatten();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100575 if (source->IsExternalTwoByteString()) {
576 // Notice that the stream is destroyed at the end of the branch block.
577 // The last line of the blocks can't be moved outside, even though they're
578 // identical calls.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100579 ExternalTwoByteStringUtf16CharacterStream stream(
Ben Murdochb0fe1622011-05-05 13:52:32 +0100580 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
Steve Block9fac8402011-05-12 15:51:54 +0100581 scanner_.Initialize(&stream);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100582 return DoParseProgram(info, source, &zone_scope);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100583 } else {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100584 GenericStringUtf16CharacterStream stream(source, 0, source->length());
Steve Block9fac8402011-05-12 15:51:54 +0100585 scanner_.Initialize(&stream);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100586 return DoParseProgram(info, source, &zone_scope);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100587 }
588}
589
590
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100591FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
592 Handle<String> source,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100593 ZoneScope* zone_scope) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100594 ASSERT(top_scope_ == NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +0000595 ASSERT(target_stack_ == NULL);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100596 if (pre_data_ != NULL) pre_data_->Initialize();
Steve Blocka7e24c12009-10-30 11:49:00 +0000597
598 // Compute the parsing mode.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100599 mode_ = (FLAG_lazy && allow_lazy_) ? PARSE_LAZILY : PARSE_EAGERLY;
Steve Blocka7e24c12009-10-30 11:49:00 +0000600 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY;
601
Steve Block44f0eee2011-05-26 01:26:41 +0100602 Handle<String> no_name = isolate()->factory()->empty_symbol();
Steve Blocka7e24c12009-10-30 11:49:00 +0000603
604 FunctionLiteral* result = NULL;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100605 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE);
606 info->SetGlobalScope(scope);
607 if (info->is_eval()) {
608 Handle<SharedFunctionInfo> shared = info->shared_info();
609 if (!info->is_global() && (shared.is_null() || shared->is_function())) {
610 scope = Scope::DeserializeScopeChain(*info->calling_context(), scope);
611 }
612 if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) {
613 scope = NewScope(scope, EVAL_SCOPE);
614 }
Steve Block1e0659c2011-05-24 12:43:12 +0100615 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100616 scope->set_start_position(0);
617 scope->set_end_position(source->length());
618 FunctionState function_state(this, scope, isolate());
619 top_scope_->SetLanguageMode(info->language_mode());
Ben Murdoch257744e2011-11-30 15:57:28 +0000620 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16);
Steve Blocka7e24c12009-10-30 11:49:00 +0000621 bool ok = true;
Steve Block1e0659c2011-05-24 12:43:12 +0100622 int beg_loc = scanner().location().beg_pos;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100623 ParseSourceElements(body, Token::EOS, info->is_eval(), &ok);
624 if (ok && !top_scope_->is_classic_mode()) {
Steve Block1e0659c2011-05-24 12:43:12 +0100625 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
626 }
Ben Murdoch589d6972011-11-30 16:04:58 +0000627
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100628 if (ok && is_extended_mode()) {
629 CheckConflictingVarDeclarations(top_scope_, &ok);
Ben Murdoch589d6972011-11-30 16:04:58 +0000630 }
631
Steve Blocka7e24c12009-10-30 11:49:00 +0000632 if (ok) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100633 result = factory()->NewFunctionLiteral(
Steve Blocka7e24c12009-10-30 11:49:00 +0000634 no_name,
635 top_scope_,
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800636 body,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100637 function_state.materialized_literal_count(),
638 function_state.expected_property_count(),
639 function_state.handler_count(),
640 function_state.only_simple_this_property_assignments(),
641 function_state.this_property_assignments(),
Steve Blocka7e24c12009-10-30 11:49:00 +0000642 0,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100643 FunctionLiteral::kNoDuplicateParameters,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000644 FunctionLiteral::ANONYMOUS_EXPRESSION,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100645 FunctionLiteral::kGlobalOrEval);
646 result->set_ast_properties(factory()->visitor()->ast_properties());
Ben Murdochb0fe1622011-05-05 13:52:32 +0100647 } else if (stack_overflow_) {
Steve Block44f0eee2011-05-26 01:26:41 +0100648 isolate()->StackOverflow();
Steve Blocka7e24c12009-10-30 11:49:00 +0000649 }
650 }
651
652 // Make sure the target stack is empty.
653 ASSERT(target_stack_ == NULL);
654
655 // If there was a syntax error we have to get rid of the AST
656 // and it is not safe to do so before the scope has been deleted.
Ben Murdochb0fe1622011-05-05 13:52:32 +0100657 if (result == NULL) zone_scope->DeleteOnExit();
Steve Blocka7e24c12009-10-30 11:49:00 +0000658 return result;
659}
660
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100661
Steve Block44f0eee2011-05-26 01:26:41 +0100662FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000663 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
Steve Block44f0eee2011-05-26 01:26:41 +0100664 HistogramTimerScope timer(isolate()->counters()->parse_lazy());
Ben Murdochf87a2032010-10-22 12:50:53 +0100665 Handle<String> source(String::cast(script_->source()));
Steve Block44f0eee2011-05-26 01:26:41 +0100666 isolate()->counters()->total_parse_size()->Increment(source->length());
Steve Blocka7e24c12009-10-30 11:49:00 +0000667
Steve Block44f0eee2011-05-26 01:26:41 +0100668 Handle<SharedFunctionInfo> shared_info = info->shared_info();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100669 // Initialize parser state.
670 source->TryFlatten();
671 if (source->IsExternalTwoByteString()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100672 ExternalTwoByteStringUtf16CharacterStream stream(
Ben Murdochb0fe1622011-05-05 13:52:32 +0100673 Handle<ExternalTwoByteString>::cast(source),
Steve Block44f0eee2011-05-26 01:26:41 +0100674 shared_info->start_position(),
675 shared_info->end_position());
Ben Murdochb0fe1622011-05-05 13:52:32 +0100676 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope);
677 return result;
678 } else {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100679 GenericStringUtf16CharacterStream stream(source,
680 shared_info->start_position(),
681 shared_info->end_position());
Ben Murdochb0fe1622011-05-05 13:52:32 +0100682 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope);
683 return result;
684 }
685}
686
687
Steve Block44f0eee2011-05-26 01:26:41 +0100688FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100689 Utf16CharacterStream* source,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100690 ZoneScope* zone_scope) {
Steve Block44f0eee2011-05-26 01:26:41 +0100691 Handle<SharedFunctionInfo> shared_info = info->shared_info();
Steve Block9fac8402011-05-12 15:51:54 +0100692 scanner_.Initialize(source);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100693 ASSERT(top_scope_ == NULL);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100694 ASSERT(target_stack_ == NULL);
695
Steve Block44f0eee2011-05-26 01:26:41 +0100696 Handle<String> name(String::cast(shared_info->name()));
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000697 fni_ = new(zone()) FuncNameInferrer(isolate());
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100698 fni_->PushEnclosingName(name);
699
Steve Blocka7e24c12009-10-30 11:49:00 +0000700 mode_ = PARSE_EAGERLY;
701
702 // Place holder for the result.
703 FunctionLiteral* result = NULL;
704
705 {
706 // Parse the function literal.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100707 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE);
708 info->SetGlobalScope(scope);
Steve Block44f0eee2011-05-26 01:26:41 +0100709 if (!info->closure().is_null()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100710 scope = Scope::DeserializeScopeChain(info->closure()->context(), scope);
Steve Block44f0eee2011-05-26 01:26:41 +0100711 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100712 FunctionState function_state(this, scope, isolate());
713 ASSERT(scope->language_mode() != STRICT_MODE || !info->is_classic_mode());
714 ASSERT(scope->language_mode() != EXTENDED_MODE ||
715 info->is_extended_mode());
716 ASSERT(info->language_mode() == shared_info->language_mode());
717 scope->SetLanguageMode(shared_info->language_mode());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000718 FunctionLiteral::Type type = shared_info->is_expression()
719 ? (shared_info->is_anonymous()
720 ? FunctionLiteral::ANONYMOUS_EXPRESSION
721 : FunctionLiteral::NAMED_EXPRESSION)
722 : FunctionLiteral::DECLARATION;
Steve Blocka7e24c12009-10-30 11:49:00 +0000723 bool ok = true;
Steve Block1e0659c2011-05-24 12:43:12 +0100724 result = ParseFunctionLiteral(name,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000725 false, // Strict mode name already checked.
726 RelocInfo::kNoPosition,
727 type,
728 &ok);
Steve Blocka7e24c12009-10-30 11:49:00 +0000729 // Make sure the results agree.
730 ASSERT(ok == (result != NULL));
Steve Blocka7e24c12009-10-30 11:49:00 +0000731 }
732
733 // Make sure the target stack is empty.
734 ASSERT(target_stack_ == NULL);
735
736 // If there was a stack overflow we have to get rid of AST and it is
737 // not safe to do before scope has been deleted.
738 if (result == NULL) {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100739 zone_scope->DeleteOnExit();
Steve Block44f0eee2011-05-26 01:26:41 +0100740 if (stack_overflow_) isolate()->StackOverflow();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100741 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100742 Handle<String> inferred_name(shared_info->inferred_name());
Ben Murdochb0fe1622011-05-05 13:52:32 +0100743 result->set_inferred_name(inferred_name);
Steve Blocka7e24c12009-10-30 11:49:00 +0000744 }
745 return result;
746}
747
Ben Murdochf87a2032010-10-22 12:50:53 +0100748
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800749Handle<String> Parser::GetSymbol(bool* ok) {
750 int symbol_id = -1;
751 if (pre_data() != NULL) {
752 symbol_id = pre_data()->GetSymbolIdentifier();
Leon Clarke4515c472010-02-03 11:58:03 +0000753 }
Steve Block9fac8402011-05-12 15:51:54 +0100754 return LookupSymbol(symbol_id);
Leon Clarke4515c472010-02-03 11:58:03 +0000755}
Steve Blocka7e24c12009-10-30 11:49:00 +0000756
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800757
Steve Blocka7e24c12009-10-30 11:49:00 +0000758void Parser::ReportMessage(const char* type, Vector<const char*> args) {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100759 Scanner::Location source_location = scanner().location();
Steve Blocka7e24c12009-10-30 11:49:00 +0000760 ReportMessageAt(source_location, type, args);
761}
762
763
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100764void Parser::ReportMessage(const char* type, Vector<Handle<String> > args) {
765 Scanner::Location source_location = scanner().location();
766 ReportMessageAt(source_location, type, args);
767}
768
769
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800770void Parser::ReportMessageAt(Scanner::Location source_location,
771 const char* type,
772 Vector<const char*> args) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000773 MessageLocation location(script_,
Ben Murdochb8e0da22011-05-16 14:20:40 +0100774 source_location.beg_pos,
775 source_location.end_pos);
Steve Block44f0eee2011-05-26 01:26:41 +0100776 Factory* factory = isolate()->factory();
777 Handle<FixedArray> elements = factory->NewFixedArray(args.length());
Steve Blocka7e24c12009-10-30 11:49:00 +0000778 for (int i = 0; i < args.length(); i++) {
Steve Block44f0eee2011-05-26 01:26:41 +0100779 Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i]));
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100780 elements->set(i, *arg_string);
Steve Blocka7e24c12009-10-30 11:49:00 +0000781 }
Steve Block44f0eee2011-05-26 01:26:41 +0100782 Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
783 Handle<Object> result = factory->NewSyntaxError(type, array);
784 isolate()->Throw(*result, &location);
Steve Blocka7e24c12009-10-30 11:49:00 +0000785}
786
787
Ben Murdochb8e0da22011-05-16 14:20:40 +0100788void Parser::ReportMessageAt(Scanner::Location source_location,
789 const char* type,
790 Vector<Handle<String> > args) {
791 MessageLocation location(script_,
792 source_location.beg_pos,
793 source_location.end_pos);
Steve Block44f0eee2011-05-26 01:26:41 +0100794 Factory* factory = isolate()->factory();
795 Handle<FixedArray> elements = factory->NewFixedArray(args.length());
Ben Murdochb8e0da22011-05-16 14:20:40 +0100796 for (int i = 0; i < args.length(); i++) {
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100797 elements->set(i, *args[i]);
Ben Murdochb8e0da22011-05-16 14:20:40 +0100798 }
Steve Block44f0eee2011-05-26 01:26:41 +0100799 Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
800 Handle<Object> result = factory->NewSyntaxError(type, array);
801 isolate()->Throw(*result, &location);
Ben Murdochb8e0da22011-05-16 14:20:40 +0100802}
803
804
Steve Blocka7e24c12009-10-30 11:49:00 +0000805// Base class containing common code for the different finder classes used by
806// the parser.
807class ParserFinder {
808 protected:
809 ParserFinder() {}
810 static Assignment* AsAssignment(Statement* stat) {
811 if (stat == NULL) return NULL;
812 ExpressionStatement* exp_stat = stat->AsExpressionStatement();
813 if (exp_stat == NULL) return NULL;
814 return exp_stat->expression()->AsAssignment();
815 }
816};
817
818
819// An InitializationBlockFinder finds and marks sequences of statements of the
Steve Blockd0582a62009-12-15 09:54:21 +0000820// form expr.a = ...; expr.b = ...; etc.
Steve Blocka7e24c12009-10-30 11:49:00 +0000821class InitializationBlockFinder : public ParserFinder {
822 public:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000823 // We find and mark the initialization blocks in top level
824 // non-looping code only. This is because the optimization prevents
825 // reuse of the map transitions, so it should be used only for code
826 // that will only be run once.
827 InitializationBlockFinder(Scope* top_scope, Target* target)
828 : enabled_(top_scope->DeclarationScope()->is_global_scope() &&
829 !IsLoopTarget(target)),
830 first_in_block_(NULL),
831 last_in_block_(NULL),
832 block_size_(0) {}
Steve Blocka7e24c12009-10-30 11:49:00 +0000833
834 ~InitializationBlockFinder() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000835 if (!enabled_) return;
Steve Blocka7e24c12009-10-30 11:49:00 +0000836 if (InBlock()) EndBlock();
837 }
838
839 void Update(Statement* stat) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000840 if (!enabled_) return;
Steve Blocka7e24c12009-10-30 11:49:00 +0000841 Assignment* assignment = AsAssignment(stat);
842 if (InBlock()) {
843 if (BlockContinues(assignment)) {
844 UpdateBlock(assignment);
845 } else {
846 EndBlock();
847 }
848 }
849 if (!InBlock() && (assignment != NULL) &&
850 (assignment->op() == Token::ASSIGN)) {
851 StartBlock(assignment);
852 }
853 }
854
855 private:
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800856 // The minimum number of contiguous assignment that will
857 // be treated as an initialization block. Benchmarks show that
858 // the overhead exceeds the savings below this limit.
859 static const int kMinInitializationBlock = 3;
860
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000861 static bool IsLoopTarget(Target* target) {
862 while (target != NULL) {
863 if (target->node()->AsIterationStatement() != NULL) return true;
864 target = target->previous();
865 }
866 return false;
867 }
868
Steve Blocka7e24c12009-10-30 11:49:00 +0000869 // Returns true if the expressions appear to denote the same object.
870 // In the context of initialization blocks, we only consider expressions
Steve Blockd0582a62009-12-15 09:54:21 +0000871 // of the form 'expr.x' or expr["x"].
Steve Blocka7e24c12009-10-30 11:49:00 +0000872 static bool SameObject(Expression* e1, Expression* e2) {
873 VariableProxy* v1 = e1->AsVariableProxy();
874 VariableProxy* v2 = e2->AsVariableProxy();
875 if (v1 != NULL && v2 != NULL) {
876 return v1->name()->Equals(*v2->name());
877 }
878 Property* p1 = e1->AsProperty();
879 Property* p2 = e2->AsProperty();
880 if ((p1 == NULL) || (p2 == NULL)) return false;
881 Literal* key1 = p1->key()->AsLiteral();
882 Literal* key2 = p2->key()->AsLiteral();
883 if ((key1 == NULL) || (key2 == NULL)) return false;
884 if (!key1->handle()->IsString() || !key2->handle()->IsString()) {
885 return false;
886 }
887 String* name1 = String::cast(*key1->handle());
888 String* name2 = String::cast(*key2->handle());
889 if (!name1->Equals(name2)) return false;
890 return SameObject(p1->obj(), p2->obj());
891 }
892
893 // Returns true if the expressions appear to denote different properties
894 // of the same object.
895 static bool PropertyOfSameObject(Expression* e1, Expression* e2) {
896 Property* p1 = e1->AsProperty();
897 Property* p2 = e2->AsProperty();
898 if ((p1 == NULL) || (p2 == NULL)) return false;
899 return SameObject(p1->obj(), p2->obj());
900 }
901
902 bool BlockContinues(Assignment* assignment) {
903 if ((assignment == NULL) || (first_in_block_ == NULL)) return false;
904 if (assignment->op() != Token::ASSIGN) return false;
905 return PropertyOfSameObject(first_in_block_->target(),
906 assignment->target());
907 }
908
909 void StartBlock(Assignment* assignment) {
910 first_in_block_ = assignment;
911 last_in_block_ = assignment;
912 block_size_ = 1;
913 }
914
915 void UpdateBlock(Assignment* assignment) {
916 last_in_block_ = assignment;
917 ++block_size_;
918 }
919
920 void EndBlock() {
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800921 if (block_size_ >= kMinInitializationBlock) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000922 first_in_block_->mark_block_start();
923 last_in_block_->mark_block_end();
924 }
925 last_in_block_ = first_in_block_ = NULL;
926 block_size_ = 0;
927 }
928
929 bool InBlock() { return first_in_block_ != NULL; }
930
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000931 const bool enabled_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000932 Assignment* first_in_block_;
933 Assignment* last_in_block_;
934 int block_size_;
935
936 DISALLOW_COPY_AND_ASSIGN(InitializationBlockFinder);
937};
938
939
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100940// A ThisNamedPropertyAssignmentFinder finds and marks statements of the form
Steve Blocka7e24c12009-10-30 11:49:00 +0000941// this.x = ...;, where x is a named property. It also determines whether a
942// function contains only assignments of this type.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100943class ThisNamedPropertyAssignmentFinder : public ParserFinder {
Steve Blocka7e24c12009-10-30 11:49:00 +0000944 public:
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100945 explicit ThisNamedPropertyAssignmentFinder(Isolate* isolate)
Steve Block44f0eee2011-05-26 01:26:41 +0100946 : isolate_(isolate),
947 only_simple_this_property_assignments_(true),
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100948 names_(0),
949 assigned_arguments_(0),
950 assigned_constants_(0) {
951 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000952
953 void Update(Scope* scope, Statement* stat) {
Steve Blockd0582a62009-12-15 09:54:21 +0000954 // Bail out if function already has property assignment that are
955 // not simple this property assignments.
956 if (!only_simple_this_property_assignments_) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000957 return;
958 }
959
960 // Check whether this statement is of the form this.x = ...;
961 Assignment* assignment = AsAssignment(stat);
962 if (IsThisPropertyAssignment(assignment)) {
963 HandleThisPropertyAssignment(scope, assignment);
964 } else {
Steve Blocka7e24c12009-10-30 11:49:00 +0000965 only_simple_this_property_assignments_ = false;
966 }
967 }
968
Steve Blocka7e24c12009-10-30 11:49:00 +0000969 // Returns whether only statements of the form this.x = y; where y is either a
970 // constant or a function argument was encountered.
971 bool only_simple_this_property_assignments() {
972 return only_simple_this_property_assignments_;
973 }
974
975 // Returns a fixed array containing three elements for each assignment of the
976 // form this.x = y;
977 Handle<FixedArray> GetThisPropertyAssignments() {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100978 if (names_.is_empty()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100979 return isolate_->factory()->empty_fixed_array();
Steve Blocka7e24c12009-10-30 11:49:00 +0000980 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100981 ASSERT_EQ(names_.length(), assigned_arguments_.length());
982 ASSERT_EQ(names_.length(), assigned_constants_.length());
Steve Blocka7e24c12009-10-30 11:49:00 +0000983 Handle<FixedArray> assignments =
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100984 isolate_->factory()->NewFixedArray(names_.length() * 3);
985 for (int i = 0; i < names_.length(); ++i) {
986 assignments->set(i * 3, *names_[i]);
987 assignments->set(i * 3 + 1, Smi::FromInt(assigned_arguments_[i]));
988 assignments->set(i * 3 + 2, *assigned_constants_[i]);
Steve Blocka7e24c12009-10-30 11:49:00 +0000989 }
990 return assignments;
991 }
992
993 private:
994 bool IsThisPropertyAssignment(Assignment* assignment) {
995 if (assignment != NULL) {
996 Property* property = assignment->target()->AsProperty();
997 return assignment->op() == Token::ASSIGN
998 && property != NULL
999 && property->obj()->AsVariableProxy() != NULL
1000 && property->obj()->AsVariableProxy()->is_this();
1001 }
1002 return false;
1003 }
1004
1005 void HandleThisPropertyAssignment(Scope* scope, Assignment* assignment) {
Steve Block6ded16b2010-05-10 14:33:55 +01001006 // Check that the property assigned to is a named property, which is not
1007 // __proto__.
Steve Blocka7e24c12009-10-30 11:49:00 +00001008 Property* property = assignment->target()->AsProperty();
1009 ASSERT(property != NULL);
1010 Literal* literal = property->key()->AsLiteral();
1011 uint32_t dummy;
1012 if (literal != NULL &&
1013 literal->handle()->IsString() &&
Steve Block44f0eee2011-05-26 01:26:41 +01001014 !String::cast(*(literal->handle()))->Equals(
1015 isolate_->heap()->Proto_symbol()) &&
Steve Blocka7e24c12009-10-30 11:49:00 +00001016 !String::cast(*(literal->handle()))->AsArrayIndex(&dummy)) {
1017 Handle<String> key = Handle<String>::cast(literal->handle());
1018
1019 // Check whether the value assigned is either a constant or matches the
1020 // name of one of the arguments to the function.
1021 if (assignment->value()->AsLiteral() != NULL) {
1022 // Constant assigned.
1023 Literal* literal = assignment->value()->AsLiteral();
1024 AssignmentFromConstant(key, literal->handle());
Steve Blockd0582a62009-12-15 09:54:21 +00001025 return;
Steve Blocka7e24c12009-10-30 11:49:00 +00001026 } else if (assignment->value()->AsVariableProxy() != NULL) {
1027 // Variable assigned.
1028 Handle<String> name =
1029 assignment->value()->AsVariableProxy()->name();
1030 // Check whether the variable assigned matches an argument name.
Steve Blocka7e24c12009-10-30 11:49:00 +00001031 for (int i = 0; i < scope->num_parameters(); i++) {
1032 if (*scope->parameter(i)->name() == *name) {
1033 // Assigned from function argument.
Steve Blockd0582a62009-12-15 09:54:21 +00001034 AssignmentFromParameter(key, i);
1035 return;
Steve Blocka7e24c12009-10-30 11:49:00 +00001036 }
1037 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001038 }
1039 }
Steve Blockd0582a62009-12-15 09:54:21 +00001040 // It is not a simple "this.x = value;" assignment with a constant
1041 // or parameter value.
1042 AssignmentFromSomethingElse();
Steve Blocka7e24c12009-10-30 11:49:00 +00001043 }
1044
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001045
1046
1047
1048 // We will potentially reorder the property assignments, so they must be
1049 // simple enough that the ordering does not matter.
Steve Blocka7e24c12009-10-30 11:49:00 +00001050 void AssignmentFromParameter(Handle<String> name, int index) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001051 EnsureInitialized();
1052 for (int i = 0; i < names_.length(); ++i) {
1053 if (name->Equals(*names_[i])) {
1054 assigned_arguments_[i] = index;
1055 assigned_constants_[i] = isolate_->factory()->undefined_value();
1056 return;
1057 }
1058 }
1059 names_.Add(name);
1060 assigned_arguments_.Add(index);
1061 assigned_constants_.Add(isolate_->factory()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00001062 }
1063
1064 void AssignmentFromConstant(Handle<String> name, Handle<Object> value) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001065 EnsureInitialized();
1066 for (int i = 0; i < names_.length(); ++i) {
1067 if (name->Equals(*names_[i])) {
1068 assigned_arguments_[i] = -1;
1069 assigned_constants_[i] = value;
1070 return;
1071 }
1072 }
1073 names_.Add(name);
1074 assigned_arguments_.Add(-1);
1075 assigned_constants_.Add(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00001076 }
1077
Steve Blockd0582a62009-12-15 09:54:21 +00001078 void AssignmentFromSomethingElse() {
Steve Blocka7e24c12009-10-30 11:49:00 +00001079 // The this assignment is not a simple one.
1080 only_simple_this_property_assignments_ = false;
1081 }
1082
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001083 void EnsureInitialized() {
1084 if (names_.capacity() == 0) {
1085 ASSERT(assigned_arguments_.capacity() == 0);
1086 ASSERT(assigned_constants_.capacity() == 0);
1087 names_.Initialize(4);
1088 assigned_arguments_.Initialize(4);
1089 assigned_constants_.Initialize(4);
Steve Blocka7e24c12009-10-30 11:49:00 +00001090 }
1091 }
1092
Steve Block44f0eee2011-05-26 01:26:41 +01001093 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001094 bool only_simple_this_property_assignments_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001095 ZoneStringList names_;
1096 ZoneList<int> assigned_arguments_;
1097 ZoneObjectList assigned_constants_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001098};
1099
1100
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001101void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
Steve Blocka7e24c12009-10-30 11:49:00 +00001102 int end_token,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001103 bool is_eval,
Steve Blocka7e24c12009-10-30 11:49:00 +00001104 bool* ok) {
1105 // SourceElements ::
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001106 // (ModuleElement)* <end_token>
Steve Blocka7e24c12009-10-30 11:49:00 +00001107
1108 // Allocate a target stack to use for this set of source
1109 // elements. This way, all scripts and functions get their own
1110 // target stack thus avoiding illegal breaks and continues across
1111 // functions.
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001112 TargetScope scope(&this->target_stack_);
Steve Blocka7e24c12009-10-30 11:49:00 +00001113
1114 ASSERT(processor != NULL);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001115 InitializationBlockFinder block_finder(top_scope_, target_stack_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001116 ThisNamedPropertyAssignmentFinder this_property_assignment_finder(isolate());
Steve Block1e0659c2011-05-24 12:43:12 +01001117 bool directive_prologue = true; // Parsing directive prologue.
1118
Steve Blocka7e24c12009-10-30 11:49:00 +00001119 while (peek() != end_token) {
Steve Block1e0659c2011-05-24 12:43:12 +01001120 if (directive_prologue && peek() != Token::STRING) {
1121 directive_prologue = false;
1122 }
1123
1124 Scanner::Location token_loc = scanner().peek_location();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001125 Statement* stat = ParseModuleElement(NULL, CHECK_OK);
Steve Block1e0659c2011-05-24 12:43:12 +01001126 if (stat == NULL || stat->IsEmpty()) {
1127 directive_prologue = false; // End of directive prologue.
1128 continue;
1129 }
1130
1131 if (directive_prologue) {
1132 // A shot at a directive.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001133 ExpressionStatement* e_stat;
1134 Literal* literal;
Steve Block1e0659c2011-05-24 12:43:12 +01001135 // Still processing directive prologue?
1136 if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1137 (literal = e_stat->expression()->AsLiteral()) != NULL &&
1138 literal->handle()->IsString()) {
1139 Handle<String> directive = Handle<String>::cast(literal->handle());
1140
1141 // Check "use strict" directive (ES5 14.1).
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001142 if (top_scope_->is_classic_mode() &&
Steve Block44f0eee2011-05-26 01:26:41 +01001143 directive->Equals(isolate()->heap()->use_strict()) &&
Steve Block1e0659c2011-05-24 12:43:12 +01001144 token_loc.end_pos - token_loc.beg_pos ==
Steve Block44f0eee2011-05-26 01:26:41 +01001145 isolate()->heap()->use_strict()->length() + 2) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001146 // TODO(mstarzinger): Global strict eval calls, need their own scope
1147 // as specified in ES5 10.4.2(3). The correct fix would be to always
1148 // add this scope in DoParseProgram(), but that requires adaptations
1149 // all over the code base, so we go with a quick-fix for now.
1150 if (is_eval && !top_scope_->is_eval_scope()) {
1151 ASSERT(top_scope_->is_global_scope());
1152 Scope* scope = NewScope(top_scope_, EVAL_SCOPE);
1153 scope->set_start_position(top_scope_->start_position());
1154 scope->set_end_position(top_scope_->end_position());
1155 top_scope_ = scope;
1156 }
1157 // TODO(ES6): Fix entering extended mode, once it is specified.
1158 top_scope_->SetLanguageMode(FLAG_harmony_scoping
1159 ? EXTENDED_MODE : STRICT_MODE);
Steve Block1e0659c2011-05-24 12:43:12 +01001160 // "use strict" is the only directive for now.
1161 directive_prologue = false;
1162 }
1163 } else {
1164 // End of the directive prologue.
1165 directive_prologue = false;
1166 }
1167 }
1168
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001169 block_finder.Update(stat);
Steve Blocka7e24c12009-10-30 11:49:00 +00001170 // Find and mark all assignments to named properties in this (this.x =)
1171 if (top_scope_->is_function_scope()) {
1172 this_property_assignment_finder.Update(top_scope_, stat);
1173 }
1174 processor->Add(stat);
1175 }
1176
1177 // Propagate the collected information on this property assignments.
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001178 if (top_scope_->is_function_scope()) {
Steve Blockd0582a62009-12-15 09:54:21 +00001179 bool only_simple_this_property_assignments =
Andrei Popescu402d9372010-02-26 13:31:12 +00001180 this_property_assignment_finder.only_simple_this_property_assignments()
1181 && top_scope_->declarations()->length() == 0;
Steve Blockd0582a62009-12-15 09:54:21 +00001182 if (only_simple_this_property_assignments) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001183 current_function_state_->SetThisPropertyAssignmentInfo(
Steve Blockd0582a62009-12-15 09:54:21 +00001184 only_simple_this_property_assignments,
Steve Blocka7e24c12009-10-30 11:49:00 +00001185 this_property_assignment_finder.GetThisPropertyAssignments());
1186 }
1187 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001188
Steve Blocka7e24c12009-10-30 11:49:00 +00001189 return 0;
1190}
1191
1192
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001193Statement* Parser::ParseModuleElement(ZoneStringList* labels,
1194 bool* ok) {
1195 // (Ecma 262 5th Edition, clause 14):
1196 // SourceElement:
1197 // Statement
1198 // FunctionDeclaration
1199 //
1200 // In harmony mode we allow additionally the following productions
1201 // ModuleElement:
1202 // LetDeclaration
1203 // ConstDeclaration
1204 // ModuleDeclaration
1205 // ImportDeclaration
1206 // ExportDeclaration
1207
1208 switch (peek()) {
1209 case Token::FUNCTION:
1210 return ParseFunctionDeclaration(NULL, ok);
1211 case Token::LET:
1212 case Token::CONST:
1213 return ParseVariableStatement(kModuleElement, NULL, ok);
1214 case Token::IMPORT:
1215 return ParseImportDeclaration(ok);
1216 case Token::EXPORT:
1217 return ParseExportDeclaration(ok);
1218 default: {
1219 Statement* stmt = ParseStatement(labels, CHECK_OK);
1220 // Handle 'module' as a context-sensitive keyword.
1221 if (FLAG_harmony_modules &&
1222 peek() == Token::IDENTIFIER &&
1223 !scanner().HasAnyLineTerminatorBeforeNext() &&
1224 stmt != NULL) {
1225 ExpressionStatement* estmt = stmt->AsExpressionStatement();
1226 if (estmt != NULL &&
1227 estmt->expression()->AsVariableProxy() != NULL &&
1228 estmt->expression()->AsVariableProxy()->name()->Equals(
1229 isolate()->heap()->module_symbol()) &&
1230 !scanner().literal_contains_escapes()) {
1231 return ParseModuleDeclaration(NULL, ok);
1232 }
1233 }
1234 return stmt;
1235 }
1236 }
1237}
1238
1239
1240Block* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) {
1241 // ModuleDeclaration:
1242 // 'module' Identifier Module
1243
1244 // Create new block with one expected declaration.
1245 Block* block = factory()->NewBlock(NULL, 1, true);
1246 Handle<String> name = ParseIdentifier(CHECK_OK);
1247
1248#ifdef DEBUG
1249 if (FLAG_print_interface_details)
1250 PrintF("# Module %s...\n", name->ToAsciiArray());
1251#endif
1252
1253 Module* module = ParseModule(CHECK_OK);
1254 VariableProxy* proxy = NewUnresolved(name, LET, module->interface());
1255 Declaration* declaration =
1256 factory()->NewModuleDeclaration(proxy, module, top_scope_);
1257 Declare(declaration, true, CHECK_OK);
1258
1259#ifdef DEBUG
1260 if (FLAG_print_interface_details)
1261 PrintF("# Module %s.\n", name->ToAsciiArray());
1262
1263 if (FLAG_print_interfaces) {
1264 PrintF("module %s : ", name->ToAsciiArray());
1265 module->interface()->Print();
1266 }
1267#endif
1268
1269 // TODO(rossberg): Add initialization statement to block.
1270
1271 if (names) names->Add(name);
1272 return block;
1273}
1274
1275
1276Module* Parser::ParseModule(bool* ok) {
1277 // Module:
1278 // '{' ModuleElement '}'
1279 // '=' ModulePath ';'
1280 // 'at' String ';'
1281
1282 switch (peek()) {
1283 case Token::LBRACE:
1284 return ParseModuleLiteral(ok);
1285
1286 case Token::ASSIGN: {
1287 Expect(Token::ASSIGN, CHECK_OK);
1288 Module* result = ParseModulePath(CHECK_OK);
1289 ExpectSemicolon(CHECK_OK);
1290 return result;
1291 }
1292
1293 default: {
1294 ExpectContextualKeyword("at", CHECK_OK);
1295 Module* result = ParseModuleUrl(CHECK_OK);
1296 ExpectSemicolon(CHECK_OK);
1297 return result;
1298 }
1299 }
1300}
1301
1302
1303Module* Parser::ParseModuleLiteral(bool* ok) {
1304 // Module:
1305 // '{' ModuleElement '}'
1306
1307 // Construct block expecting 16 statements.
1308 Block* body = factory()->NewBlock(NULL, 16, false);
1309#ifdef DEBUG
1310 if (FLAG_print_interface_details) PrintF("# Literal ");
1311#endif
1312 Scope* scope = NewScope(top_scope_, MODULE_SCOPE);
1313
1314 Expect(Token::LBRACE, CHECK_OK);
1315 scope->set_start_position(scanner().location().beg_pos);
1316 scope->SetLanguageMode(EXTENDED_MODE);
1317
1318 {
1319 BlockState block_state(this, scope);
1320 TargetCollector collector;
1321 Target target(&this->target_stack_, &collector);
1322 Target target_body(&this->target_stack_, body);
1323 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1324
1325 while (peek() != Token::RBRACE) {
1326 Statement* stat = ParseModuleElement(NULL, CHECK_OK);
1327 if (stat && !stat->IsEmpty()) {
1328 body->AddStatement(stat);
1329 block_finder.Update(stat);
1330 }
1331 }
1332 }
1333
1334 Expect(Token::RBRACE, CHECK_OK);
1335 scope->set_end_position(scanner().location().end_pos);
1336 body->set_block_scope(scope);
1337
1338 scope->interface()->Freeze(ok);
1339 ASSERT(ok);
1340 return factory()->NewModuleLiteral(body, scope->interface());
1341}
1342
1343
1344Module* Parser::ParseModulePath(bool* ok) {
1345 // ModulePath:
1346 // Identifier
1347 // ModulePath '.' Identifier
1348
1349 Module* result = ParseModuleVariable(CHECK_OK);
1350 while (Check(Token::PERIOD)) {
1351 Handle<String> name = ParseIdentifierName(CHECK_OK);
1352#ifdef DEBUG
1353 if (FLAG_print_interface_details)
1354 PrintF("# Path .%s ", name->ToAsciiArray());
1355#endif
1356 Module* member = factory()->NewModulePath(result, name);
1357 result->interface()->Add(name, member->interface(), ok);
1358 if (!*ok) {
1359#ifdef DEBUG
1360 if (FLAG_print_interfaces) {
1361 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray());
1362 PrintF("result: ");
1363 result->interface()->Print();
1364 PrintF("member: ");
1365 member->interface()->Print();
1366 }
1367#endif
1368 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1));
1369 return NULL;
1370 }
1371 result = member;
1372 }
1373
1374 return result;
1375}
1376
1377
1378Module* Parser::ParseModuleVariable(bool* ok) {
1379 // ModulePath:
1380 // Identifier
1381
1382 Handle<String> name = ParseIdentifier(CHECK_OK);
1383#ifdef DEBUG
1384 if (FLAG_print_interface_details)
1385 PrintF("# Module variable %s ", name->ToAsciiArray());
1386#endif
1387 VariableProxy* proxy = top_scope_->NewUnresolved(
1388 factory(), name, scanner().location().beg_pos, Interface::NewModule());
1389
1390 return factory()->NewModuleVariable(proxy);
1391}
1392
1393
1394Module* Parser::ParseModuleUrl(bool* ok) {
1395 // Module:
1396 // String
1397
1398 Expect(Token::STRING, CHECK_OK);
1399 Handle<String> symbol = GetSymbol(CHECK_OK);
1400
1401 // TODO(ES6): Request JS resource from environment...
1402
1403#ifdef DEBUG
1404 if (FLAG_print_interface_details) PrintF("# Url ");
1405#endif
1406 return factory()->NewModuleUrl(symbol);
1407}
1408
1409
1410Module* Parser::ParseModuleSpecifier(bool* ok) {
1411 // ModuleSpecifier:
1412 // String
1413 // ModulePath
1414
1415 if (peek() == Token::STRING) {
1416 return ParseModuleUrl(ok);
1417 } else {
1418 return ParseModulePath(ok);
1419 }
1420}
1421
1422
1423Block* Parser::ParseImportDeclaration(bool* ok) {
1424 // ImportDeclaration:
1425 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';'
1426 //
1427 // TODO(ES6): implement destructuring ImportSpecifiers
1428
1429 Expect(Token::IMPORT, CHECK_OK);
1430 ZoneStringList names(1);
1431
1432 Handle<String> name = ParseIdentifierName(CHECK_OK);
1433 names.Add(name);
1434 while (peek() == Token::COMMA) {
1435 Consume(Token::COMMA);
1436 name = ParseIdentifierName(CHECK_OK);
1437 names.Add(name);
1438 }
1439
1440 ExpectContextualKeyword("from", CHECK_OK);
1441 Module* module = ParseModuleSpecifier(CHECK_OK);
1442 ExpectSemicolon(CHECK_OK);
1443
1444 // Generate a separate declaration for each identifier.
1445 // TODO(ES6): once we implement destructuring, make that one declaration.
1446 Block* block = factory()->NewBlock(NULL, 1, true);
1447 for (int i = 0; i < names.length(); ++i) {
1448#ifdef DEBUG
1449 if (FLAG_print_interface_details)
1450 PrintF("# Import %s ", names[i]->ToAsciiArray());
1451#endif
1452 Interface* interface = Interface::NewUnknown();
1453 module->interface()->Add(names[i], interface, ok);
1454 if (!*ok) {
1455#ifdef DEBUG
1456 if (FLAG_print_interfaces) {
1457 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray());
1458 PrintF("module: ");
1459 module->interface()->Print();
1460 }
1461#endif
1462 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1));
1463 return NULL;
1464 }
1465 VariableProxy* proxy = NewUnresolved(names[i], LET, interface);
1466 Declaration* declaration =
1467 factory()->NewImportDeclaration(proxy, module, top_scope_);
1468 Declare(declaration, true, CHECK_OK);
1469 // TODO(rossberg): Add initialization statement to block.
1470 }
1471
1472 return block;
1473}
1474
1475
1476Statement* Parser::ParseExportDeclaration(bool* ok) {
1477 // ExportDeclaration:
1478 // 'export' Identifier (',' Identifier)* ';'
1479 // 'export' VariableDeclaration
1480 // 'export' FunctionDeclaration
1481 // 'export' ModuleDeclaration
1482 //
1483 // TODO(ES6): implement structuring ExportSpecifiers
1484
1485 Expect(Token::EXPORT, CHECK_OK);
1486
1487 Statement* result = NULL;
1488 ZoneStringList names(1);
1489 switch (peek()) {
1490 case Token::IDENTIFIER: {
1491 Handle<String> name = ParseIdentifier(CHECK_OK);
1492 // Handle 'module' as a context-sensitive keyword.
1493 if (!name->IsEqualTo(CStrVector("module"))) {
1494 names.Add(name);
1495 while (peek() == Token::COMMA) {
1496 Consume(Token::COMMA);
1497 name = ParseIdentifier(CHECK_OK);
1498 names.Add(name);
1499 }
1500 ExpectSemicolon(CHECK_OK);
1501 result = factory()->NewEmptyStatement();
1502 } else {
1503 result = ParseModuleDeclaration(&names, CHECK_OK);
1504 }
1505 break;
1506 }
1507
1508 case Token::FUNCTION:
1509 result = ParseFunctionDeclaration(&names, CHECK_OK);
1510 break;
1511
1512 case Token::VAR:
1513 case Token::LET:
1514 case Token::CONST:
1515 result = ParseVariableStatement(kModuleElement, &names, CHECK_OK);
1516 break;
1517
1518 default:
1519 *ok = false;
1520 ReportUnexpectedToken(scanner().current_token());
1521 return NULL;
1522 }
1523
1524 // Extract declared names into export declarations and interface.
1525 Interface* interface = top_scope_->interface();
1526 for (int i = 0; i < names.length(); ++i) {
1527#ifdef DEBUG
1528 if (FLAG_print_interface_details)
1529 PrintF("# Export %s ", names[i]->ToAsciiArray());
1530#endif
1531 Interface* inner = Interface::NewUnknown();
1532 interface->Add(names[i], inner, CHECK_OK);
1533 VariableProxy* proxy = NewUnresolved(names[i], LET, inner);
1534 USE(proxy);
1535 // TODO(rossberg): Rethink whether we actually need to store export
1536 // declarations (for compilation?).
1537 // ExportDeclaration* declaration =
1538 // factory()->NewExportDeclaration(proxy, top_scope_);
1539 // top_scope_->AddDeclaration(declaration);
1540 }
1541
1542 ASSERT(result != NULL);
1543 return result;
1544}
1545
1546
1547Statement* Parser::ParseBlockElement(ZoneStringList* labels,
1548 bool* ok) {
1549 // (Ecma 262 5th Edition, clause 14):
1550 // SourceElement:
1551 // Statement
1552 // FunctionDeclaration
1553 //
1554 // In harmony mode we allow additionally the following productions
1555 // BlockElement (aka SourceElement):
1556 // LetDeclaration
1557 // ConstDeclaration
1558
1559 switch (peek()) {
1560 case Token::FUNCTION:
1561 return ParseFunctionDeclaration(NULL, ok);
1562 case Token::LET:
1563 case Token::CONST:
1564 return ParseVariableStatement(kModuleElement, NULL, ok);
1565 default:
1566 return ParseStatement(labels, ok);
1567 }
1568}
1569
1570
Steve Blocka7e24c12009-10-30 11:49:00 +00001571Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
1572 // Statement ::
1573 // Block
1574 // VariableStatement
1575 // EmptyStatement
1576 // ExpressionStatement
1577 // IfStatement
1578 // IterationStatement
1579 // ContinueStatement
1580 // BreakStatement
1581 // ReturnStatement
1582 // WithStatement
1583 // LabelledStatement
1584 // SwitchStatement
1585 // ThrowStatement
1586 // TryStatement
1587 // DebuggerStatement
1588
1589 // Note: Since labels can only be used by 'break' and 'continue'
1590 // statements, which themselves are only valid within blocks,
1591 // iterations or 'switch' statements (i.e., BreakableStatements),
1592 // labels can be simply ignored in all other cases; except for
1593 // trivial labeled break statements 'label: break label' which is
1594 // parsed into an empty statement.
1595
1596 // Keep the source position of the statement
1597 int statement_pos = scanner().peek_location().beg_pos;
1598 Statement* stmt = NULL;
1599 switch (peek()) {
1600 case Token::LBRACE:
1601 return ParseBlock(labels, ok);
1602
1603 case Token::CONST: // fall through
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001604 case Token::LET:
Steve Blocka7e24c12009-10-30 11:49:00 +00001605 case Token::VAR:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001606 stmt = ParseVariableStatement(kStatement, NULL, ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001607 break;
1608
1609 case Token::SEMICOLON:
1610 Next();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001611 return factory()->NewEmptyStatement();
Steve Blocka7e24c12009-10-30 11:49:00 +00001612
1613 case Token::IF:
1614 stmt = ParseIfStatement(labels, ok);
1615 break;
1616
1617 case Token::DO:
Steve Block3ce2e202009-11-05 08:53:23 +00001618 stmt = ParseDoWhileStatement(labels, ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001619 break;
1620
1621 case Token::WHILE:
1622 stmt = ParseWhileStatement(labels, ok);
1623 break;
1624
1625 case Token::FOR:
1626 stmt = ParseForStatement(labels, ok);
1627 break;
1628
1629 case Token::CONTINUE:
1630 stmt = ParseContinueStatement(ok);
1631 break;
1632
1633 case Token::BREAK:
1634 stmt = ParseBreakStatement(labels, ok);
1635 break;
1636
1637 case Token::RETURN:
1638 stmt = ParseReturnStatement(ok);
1639 break;
1640
1641 case Token::WITH:
1642 stmt = ParseWithStatement(labels, ok);
1643 break;
1644
1645 case Token::SWITCH:
1646 stmt = ParseSwitchStatement(labels, ok);
1647 break;
1648
1649 case Token::THROW:
1650 stmt = ParseThrowStatement(ok);
1651 break;
1652
1653 case Token::TRY: {
1654 // NOTE: It is somewhat complicated to have labels on
1655 // try-statements. When breaking out of a try-finally statement,
1656 // one must take great care not to treat it as a
1657 // fall-through. It is much easier just to wrap the entire
1658 // try-statement in a statement block and put the labels there
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001659 Block* result = factory()->NewBlock(labels, 1, false);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001660 Target target(&this->target_stack_, result);
Steve Blocka7e24c12009-10-30 11:49:00 +00001661 TryStatement* statement = ParseTryStatement(CHECK_OK);
1662 if (statement) {
1663 statement->set_statement_pos(statement_pos);
1664 }
1665 if (result) result->AddStatement(statement);
1666 return result;
1667 }
1668
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001669 case Token::FUNCTION: {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001670 // FunctionDeclaration is only allowed in the context of SourceElements
1671 // (Ecma 262 5th Edition, clause 14):
1672 // SourceElement:
1673 // Statement
1674 // FunctionDeclaration
1675 // Common language extension is to allow function declaration in place
1676 // of any statement. This language extension is disabled in strict mode.
1677 if (!top_scope_->is_classic_mode()) {
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001678 ReportMessageAt(scanner().peek_location(), "strict_function",
1679 Vector<const char*>::empty());
1680 *ok = false;
1681 return NULL;
1682 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001683 return ParseFunctionDeclaration(NULL, ok);
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001684 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001685
Steve Blocka7e24c12009-10-30 11:49:00 +00001686 case Token::DEBUGGER:
1687 stmt = ParseDebuggerStatement(ok);
1688 break;
1689
1690 default:
1691 stmt = ParseExpressionOrLabelledStatement(labels, ok);
1692 }
1693
1694 // Store the source position of the statement
1695 if (stmt != NULL) stmt->set_statement_pos(statement_pos);
1696 return stmt;
1697}
1698
1699
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001700VariableProxy* Parser::NewUnresolved(
1701 Handle<String> name, VariableMode mode, Interface* interface) {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001702 // If we are inside a function, a declaration of a var/const variable is a
1703 // truly local variable, and the scope of the variable is always the function
1704 // scope.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001705 // Let/const variables in harmony mode are always added to the immediately
1706 // enclosing scope.
1707 return DeclarationScope(mode)->NewUnresolved(
1708 factory(), name, scanner().location().beg_pos, interface);
1709}
1710
1711
1712void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
1713 VariableProxy* proxy = declaration->proxy();
1714 Handle<String> name = proxy->name();
1715 VariableMode mode = declaration->mode();
1716 Scope* declaration_scope = DeclarationScope(mode);
1717 Variable* var = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00001718
1719 // If a function scope exists, then we can statically declare this
1720 // variable and also set its mode. In any case, a Declaration node
1721 // will be added to the scope so that the declaration can be added
1722 // to the corresponding activation frame at runtime if necessary.
1723 // For instance declarations inside an eval scope need to be added
1724 // to the calling function context.
Ben Murdoch257744e2011-11-30 15:57:28 +00001725 // Similarly, strict mode eval scope does not leak variable declarations to
1726 // the caller's scope so we declare all locals, too.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001727 // Also for block scoped let/const bindings the variable can be
1728 // statically declared.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001729 if (declaration_scope->is_function_scope() ||
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001730 declaration_scope->is_strict_or_extended_eval_scope() ||
1731 declaration_scope->is_block_scope() ||
1732 declaration_scope->is_module_scope() ||
1733 declaration->AsModuleDeclaration() != NULL) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001734 // Declare the variable in the function scope.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001735 var = declaration_scope->LocalLookup(name);
Steve Blocka7e24c12009-10-30 11:49:00 +00001736 if (var == NULL) {
1737 // Declare the name.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001738 var = declaration_scope->DeclareLocal(
1739 name, mode, declaration->initialization(), proxy->interface());
Steve Blocka7e24c12009-10-30 11:49:00 +00001740 } else {
Ben Murdoch589d6972011-11-30 16:04:58 +00001741 // The name was declared in this scope before; check for conflicting
1742 // re-declarations. We have a conflict if either of the declarations is
1743 // not a var. There is similar code in runtime.cc in the Declare
1744 // functions. The function CheckNonConflictingScope checks for conflicting
1745 // var and let bindings from different scopes whereas this is a check for
1746 // conflicting declarations within the same scope. This check also covers
1747 //
1748 // function () { let x; { var x; } }
1749 //
1750 // because the var declaration is hoisted to the function scope where 'x'
1751 // is already bound.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001752 if ((mode != VAR) || (var->mode() != VAR)) {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001753 // We only have vars, consts and lets in declarations.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001754 ASSERT(var->mode() == VAR ||
1755 var->mode() == CONST ||
1756 var->mode() == CONST_HARMONY ||
1757 var->mode() == LET);
1758 if (is_extended_mode()) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001759 // In harmony mode we treat re-declarations as early errors. See
1760 // ES5 16 for a definition of early errors.
1761 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
1762 const char* elms[2] = { "Variable", *c_string };
1763 Vector<const char*> args(elms, 2);
1764 ReportMessage("redeclaration", args);
1765 *ok = false;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001766 return;
Ben Murdoch589d6972011-11-30 16:04:58 +00001767 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001768 const char* type = (var->mode() == VAR)
1769 ? "var" : var->is_const_mode() ? "const" : "let";
Steve Blocka7e24c12009-10-30 11:49:00 +00001770 Handle<String> type_string =
Steve Block44f0eee2011-05-26 01:26:41 +01001771 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00001772 Expression* expression =
Steve Block44f0eee2011-05-26 01:26:41 +01001773 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(),
Steve Blocka7e24c12009-10-30 11:49:00 +00001774 type_string, name);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001775 declaration_scope->SetIllegalRedeclaration(expression);
Steve Blocka7e24c12009-10-30 11:49:00 +00001776 }
1777 }
1778 }
1779
1780 // We add a declaration node for every declaration. The compiler
1781 // will only generate code if necessary. In particular, declarations
1782 // for inner local variables that do not represent functions won't
1783 // result in any generated code.
1784 //
1785 // Note that we always add an unresolved proxy even if it's not
1786 // used, simply because we don't know in this method (w/o extra
1787 // parameters) if the proxy is needed or not. The proxy will be
1788 // bound during variable resolution time unless it was pre-bound
1789 // below.
1790 //
1791 // WARNING: This will lead to multiple declaration nodes for the
1792 // same variable if it is declared several times. This is not a
1793 // semantic issue as long as we keep the source order, but it may be
1794 // a performance issue since it may lead to repeated
1795 // Runtime::DeclareContextSlot() calls.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001796 declaration_scope->AddDeclaration(declaration);
Steve Blocka7e24c12009-10-30 11:49:00 +00001797
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001798 if ((mode == CONST || mode == CONST_HARMONY) &&
1799 declaration_scope->is_global_scope()) {
1800 // For global const variables we bind the proxy to a variable.
Steve Blocka7e24c12009-10-30 11:49:00 +00001801 ASSERT(resolve); // should be set by all callers
1802 Variable::Kind kind = Variable::NORMAL;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001803 var = new(zone()) Variable(declaration_scope,
1804 name,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001805 mode,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001806 true,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001807 kind,
1808 kNeedsInitialization);
1809 } else if (declaration_scope->is_eval_scope() &&
1810 declaration_scope->is_classic_mode()) {
1811 // For variable declarations in a non-strict eval scope the proxy is bound
1812 // to a lookup variable to force a dynamic declaration using the
1813 // DeclareContextSlot runtime function.
1814 Variable::Kind kind = Variable::NORMAL;
1815 var = new(zone()) Variable(declaration_scope,
1816 name,
1817 mode,
1818 true,
1819 kind,
1820 declaration->initialization());
1821 var->AllocateTo(Variable::LOOKUP, -1);
1822 resolve = true;
Steve Blocka7e24c12009-10-30 11:49:00 +00001823 }
1824
1825 // If requested and we have a local variable, bind the proxy to the variable
1826 // at parse-time. This is used for functions (and consts) declared inside
1827 // statements: the corresponding function (or const) variable must be in the
1828 // function scope and not a statement-local scope, e.g. as provided with a
1829 // 'with' statement:
1830 //
1831 // with (obj) {
1832 // function f() {}
1833 // }
1834 //
1835 // which is translated into:
1836 //
1837 // with (obj) {
1838 // // in this case this is not: 'var f; f = function () {};'
1839 // var f = function () {};
1840 // }
1841 //
1842 // Note that if 'f' is accessed from inside the 'with' statement, it
1843 // will be allocated in the context (because we must be able to look
1844 // it up dynamically) but it will also be accessed statically, i.e.,
1845 // with a context slot index and a context chain length for this
1846 // initialization code. Thus, inside the 'with' statement, we need
1847 // both access to the static and the dynamic context chain; the
1848 // runtime needs to provide both.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001849 if (resolve && var != NULL) {
1850 proxy->BindTo(var);
Steve Blocka7e24c12009-10-30 11:49:00 +00001851
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001852 if (FLAG_harmony_modules) {
1853 bool ok;
1854#ifdef DEBUG
1855 if (FLAG_print_interface_details)
1856 PrintF("# Declare %s\n", var->name()->ToAsciiArray());
1857#endif
1858 proxy->interface()->Unify(var->interface(), &ok);
1859 if (!ok) {
1860#ifdef DEBUG
1861 if (FLAG_print_interfaces) {
1862 PrintF("DECLARE TYPE ERROR\n");
1863 PrintF("proxy: ");
1864 proxy->interface()->Print();
1865 PrintF("var: ");
1866 var->interface()->Print();
1867 }
1868#endif
1869 ReportMessage("module_type_error", Vector<Handle<String> >(&name, 1));
1870 }
1871 }
1872 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001873}
1874
1875
1876// Language extension which is only enabled for source files loaded
1877// through the API's extension mechanism. A native function
1878// declaration is resolved by looking up the function through a
1879// callback provided by the extension.
1880Statement* Parser::ParseNativeDeclaration(bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001881 Expect(Token::FUNCTION, CHECK_OK);
1882 Handle<String> name = ParseIdentifier(CHECK_OK);
1883 Expect(Token::LPAREN, CHECK_OK);
1884 bool done = (peek() == Token::RPAREN);
1885 while (!done) {
1886 ParseIdentifier(CHECK_OK);
1887 done = (peek() == Token::RPAREN);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001888 if (!done) {
1889 Expect(Token::COMMA, CHECK_OK);
1890 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001891 }
1892 Expect(Token::RPAREN, CHECK_OK);
1893 Expect(Token::SEMICOLON, CHECK_OK);
1894
Steve Blocka7e24c12009-10-30 11:49:00 +00001895 // Make sure that the function containing the native declaration
1896 // isn't lazily compiled. The extension structures are only
1897 // accessible while parsing the first time not when reparsing
1898 // because of lazy compilation.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001899 DeclarationScope(VAR)->ForceEagerCompilation();
Steve Blocka7e24c12009-10-30 11:49:00 +00001900
1901 // Compute the function template for the native function.
1902 v8::Handle<v8::FunctionTemplate> fun_template =
1903 extension_->GetNativeFunction(v8::Utils::ToLocal(name));
1904 ASSERT(!fun_template.IsEmpty());
1905
Steve Block6ded16b2010-05-10 14:33:55 +01001906 // Instantiate the function and create a shared function info from it.
Steve Blocka7e24c12009-10-30 11:49:00 +00001907 Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->GetFunction());
1908 const int literals = fun->NumberOfLiterals();
1909 Handle<Code> code = Handle<Code>(fun->shared()->code());
Leon Clarkee46be812010-01-19 14:06:41 +00001910 Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
Steve Block6ded16b2010-05-10 14:33:55 +01001911 Handle<SharedFunctionInfo> shared =
Steve Block44f0eee2011-05-26 01:26:41 +01001912 isolate()->factory()->NewSharedFunctionInfo(name, literals, code,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001913 Handle<ScopeInfo>(fun->shared()->scope_info()));
Steve Block6ded16b2010-05-10 14:33:55 +01001914 shared->set_construct_stub(*construct_stub);
Steve Blocka7e24c12009-10-30 11:49:00 +00001915
Steve Block6ded16b2010-05-10 14:33:55 +01001916 // Copy the function data to the shared function info.
1917 shared->set_function_data(fun->shared()->function_data());
Steve Blocka7e24c12009-10-30 11:49:00 +00001918 int parameters = fun->shared()->formal_parameter_count();
Steve Block6ded16b2010-05-10 14:33:55 +01001919 shared->set_formal_parameter_count(parameters);
Steve Blocka7e24c12009-10-30 11:49:00 +00001920
1921 // TODO(1240846): It's weird that native function declarations are
1922 // introduced dynamically when we meet their declarations, whereas
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001923 // other functions are set up when entering the surrounding scope.
1924 VariableProxy* proxy = NewUnresolved(name, VAR);
1925 Declaration* declaration =
1926 factory()->NewVariableDeclaration(proxy, VAR, top_scope_);
1927 Declare(declaration, true, CHECK_OK);
Ben Murdoch8b112d22011-06-08 16:22:53 +01001928 SharedFunctionInfoLiteral* lit =
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001929 factory()->NewSharedFunctionInfoLiteral(shared);
1930 return factory()->NewExpressionStatement(
1931 factory()->NewAssignment(
1932 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition));
Steve Blocka7e24c12009-10-30 11:49:00 +00001933}
1934
1935
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001936Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001937 // FunctionDeclaration ::
1938 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
1939 Expect(Token::FUNCTION, CHECK_OK);
1940 int function_token_position = scanner().location().beg_pos;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001941 bool is_strict_reserved = false;
1942 Handle<String> name = ParseIdentifierOrStrictReservedWord(
1943 &is_strict_reserved, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00001944 FunctionLiteral* fun = ParseFunctionLiteral(name,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001945 is_strict_reserved,
Steve Blocka7e24c12009-10-30 11:49:00 +00001946 function_token_position,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001947 FunctionLiteral::DECLARATION,
Steve Blocka7e24c12009-10-30 11:49:00 +00001948 CHECK_OK);
1949 // Even if we're not at the top-level of the global or a function
1950 // scope, we treat is as such and introduce the function with it's
1951 // initial value upon entering the corresponding scope.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001952 VariableMode mode = is_extended_mode() ? LET : VAR;
1953 VariableProxy* proxy = NewUnresolved(name, mode);
1954 Declaration* declaration =
1955 factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_);
1956 Declare(declaration, true, CHECK_OK);
1957 if (names) names->Add(name);
1958 return factory()->NewEmptyStatement();
Steve Blocka7e24c12009-10-30 11:49:00 +00001959}
1960
1961
1962Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001963 if (top_scope_->is_extended_mode()) return ParseScopedBlock(labels, ok);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001964
Steve Blocka7e24c12009-10-30 11:49:00 +00001965 // Block ::
1966 // '{' Statement* '}'
1967
1968 // Note that a Block does not introduce a new execution scope!
1969 // (ECMA-262, 3rd, 12.2)
1970 //
1971 // Construct block expecting 16 statements.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001972 Block* result = factory()->NewBlock(labels, 16, false);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001973 Target target(&this->target_stack_, result);
Steve Blocka7e24c12009-10-30 11:49:00 +00001974 Expect(Token::LBRACE, CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001975 InitializationBlockFinder block_finder(top_scope_, target_stack_);
Steve Blocka7e24c12009-10-30 11:49:00 +00001976 while (peek() != Token::RBRACE) {
1977 Statement* stat = ParseStatement(NULL, CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001978 if (stat && !stat->IsEmpty()) {
1979 result->AddStatement(stat);
1980 block_finder.Update(stat);
1981 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001982 }
1983 Expect(Token::RBRACE, CHECK_OK);
1984 return result;
1985}
1986
1987
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001988Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001989 // The harmony mode uses block elements instead of statements.
1990 //
1991 // Block ::
1992 // '{' BlockElement* '}'
1993
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001994 // Construct block expecting 16 statements.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001995 Block* body = factory()->NewBlock(labels, 16, false);
1996 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001997
1998 // Parse the statements and collect escaping labels.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001999 Expect(Token::LBRACE, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002000 block_scope->set_start_position(scanner().location().beg_pos);
2001 { BlockState block_state(this, block_scope);
2002 TargetCollector collector;
2003 Target target(&this->target_stack_, &collector);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002004 Target target_body(&this->target_stack_, body);
2005 InitializationBlockFinder block_finder(top_scope_, target_stack_);
2006
2007 while (peek() != Token::RBRACE) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002008 Statement* stat = ParseBlockElement(NULL, CHECK_OK);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002009 if (stat && !stat->IsEmpty()) {
2010 body->AddStatement(stat);
2011 block_finder.Update(stat);
2012 }
2013 }
2014 }
2015 Expect(Token::RBRACE, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002016 block_scope->set_end_position(scanner().location().end_pos);
Ben Murdoch589d6972011-11-30 16:04:58 +00002017 block_scope = block_scope->FinalizeBlockScope();
2018 body->set_block_scope(block_scope);
2019 return body;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002020}
2021
2022
2023Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002024 ZoneStringList* names,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002025 bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002026 // VariableStatement ::
2027 // VariableDeclarations ';'
2028
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002029 Handle<String> ignore;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002030 Block* result =
2031 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00002032 ExpectSemicolon(CHECK_OK);
2033 return result;
2034}
2035
Steve Block44f0eee2011-05-26 01:26:41 +01002036
2037bool Parser::IsEvalOrArguments(Handle<String> string) {
2038 return string.is_identical_to(isolate()->factory()->eval_symbol()) ||
2039 string.is_identical_to(isolate()->factory()->arguments_symbol());
Steve Block1e0659c2011-05-24 12:43:12 +01002040}
Steve Blocka7e24c12009-10-30 11:49:00 +00002041
Steve Block44f0eee2011-05-26 01:26:41 +01002042
Steve Blocka7e24c12009-10-30 11:49:00 +00002043// If the variable declaration declares exactly one non-const
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002044// variable, then *out is set to that variable. In all other cases,
2045// *out is untouched; in particular, it is the caller's responsibility
Steve Blocka7e24c12009-10-30 11:49:00 +00002046// to initialize it properly. This mechanism is used for the parsing
2047// of 'for-in' loops.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002048Block* Parser::ParseVariableDeclarations(
2049 VariableDeclarationContext var_context,
2050 VariableDeclarationProperties* decl_props,
2051 ZoneStringList* names,
2052 Handle<String>* out,
2053 bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002054 // VariableDeclarations ::
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002055 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
2056 //
2057 // The ES6 Draft Rev3 specifies the following grammar for const declarations
2058 //
2059 // ConstDeclaration ::
2060 // const ConstBinding (',' ConstBinding)* ';'
2061 // ConstBinding ::
2062 // Identifier '=' AssignmentExpression
2063 //
2064 // TODO(ES6):
2065 // ConstBinding ::
2066 // BindingPattern '=' AssignmentExpression
2067 VariableMode mode = VAR;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002068 // True if the binding needs initialization. 'let' and 'const' declared
2069 // bindings are created uninitialized by their declaration nodes and
2070 // need initialization. 'var' declared bindings are always initialized
2071 // immediately by their declaration nodes.
2072 bool needs_init = false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002073 bool is_const = false;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002074 Token::Value init_op = Token::INIT_VAR;
Steve Blocka7e24c12009-10-30 11:49:00 +00002075 if (peek() == Token::VAR) {
2076 Consume(Token::VAR);
2077 } else if (peek() == Token::CONST) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002078 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
2079 //
2080 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
2081 //
2082 // * It is a Syntax Error if the code that matches this production is not
2083 // contained in extended code.
2084 //
2085 // However disallowing const in classic mode will break compatibility with
2086 // existing pages. Therefore we keep allowing const with the old
2087 // non-harmony semantics in classic mode.
Steve Blocka7e24c12009-10-30 11:49:00 +00002088 Consume(Token::CONST);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002089 switch (top_scope_->language_mode()) {
2090 case CLASSIC_MODE:
2091 mode = CONST;
2092 init_op = Token::INIT_CONST;
2093 break;
2094 case STRICT_MODE:
2095 ReportMessage("strict_const", Vector<const char*>::empty());
2096 *ok = false;
2097 return NULL;
2098 case EXTENDED_MODE:
2099 if (var_context == kStatement) {
2100 // In extended mode 'const' declarations are only allowed in source
2101 // element positions.
2102 ReportMessage("unprotected_const", Vector<const char*>::empty());
2103 *ok = false;
2104 return NULL;
2105 }
2106 mode = CONST_HARMONY;
2107 init_op = Token::INIT_CONST_HARMONY;
2108 }
2109 is_const = true;
2110 needs_init = true;
2111 } else if (peek() == Token::LET) {
2112 // ES6 Draft Rev4 section 12.2.1:
2113 //
2114 // LetDeclaration : let LetBindingList ;
2115 //
2116 // * It is a Syntax Error if the code that matches this production is not
2117 // contained in extended code.
2118 if (!is_extended_mode()) {
2119 ReportMessage("illegal_let", Vector<const char*>::empty());
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002120 *ok = false;
2121 return NULL;
2122 }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002123 Consume(Token::LET);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002124 if (var_context == kStatement) {
2125 // Let declarations are only allowed in source element positions.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002126 ReportMessage("unprotected_let", Vector<const char*>::empty());
2127 *ok = false;
2128 return NULL;
2129 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002130 mode = LET;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002131 needs_init = true;
2132 init_op = Token::INIT_LET;
Steve Blocka7e24c12009-10-30 11:49:00 +00002133 } else {
2134 UNREACHABLE(); // by current callers
2135 }
2136
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002137 Scope* declaration_scope = DeclarationScope(mode);
2138
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002139 // The scope of a var/const declared variable anywhere inside a function
Steve Blocka7e24c12009-10-30 11:49:00 +00002140 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002141 // transform a source-level var/const declaration into a (Function)
Steve Blocka7e24c12009-10-30 11:49:00 +00002142 // Scope declaration, and rewrite the source-level initialization into an
2143 // assignment statement. We use a block to collect multiple assignments.
2144 //
2145 // We mark the block as initializer block because we don't want the
2146 // rewriter to add a '.result' assignment to such a block (to get compliant
2147 // behavior for code such as print(eval('var x = 7')), and for cosmetic
2148 // reasons when pretty-printing. Also, unless an assignment (initialization)
2149 // is inside an initializer block, it is ignored.
2150 //
2151 // Create new block with one expected declaration.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002152 Block* block = factory()->NewBlock(NULL, 1, true);
Steve Blocka7e24c12009-10-30 11:49:00 +00002153 int nvars = 0; // the number of variables declared
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002154 Handle<String> name;
Steve Blocka7e24c12009-10-30 11:49:00 +00002155 do {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002156 if (fni_ != NULL) fni_->Enter();
2157
Steve Blocka7e24c12009-10-30 11:49:00 +00002158 // Parse variable name.
2159 if (nvars > 0) Consume(Token::COMMA);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002160 name = ParseIdentifier(CHECK_OK);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002161 if (fni_ != NULL) fni_->PushVariableName(name);
Steve Blocka7e24c12009-10-30 11:49:00 +00002162
Steve Block1e0659c2011-05-24 12:43:12 +01002163 // Strict mode variables may not be named eval or arguments
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002164 if (!declaration_scope->is_classic_mode() && IsEvalOrArguments(name)) {
Steve Block1e0659c2011-05-24 12:43:12 +01002165 ReportMessage("strict_var_name", Vector<const char*>::empty());
2166 *ok = false;
2167 return NULL;
2168 }
2169
Steve Blocka7e24c12009-10-30 11:49:00 +00002170 // Declare variable.
2171 // Note that we *always* must treat the initial value via a separate init
2172 // assignment for variables and constants because the value must be assigned
2173 // when the variable is encountered in the source. But the variable/constant
2174 // is declared (and set to 'undefined') upon entering the function within
2175 // which the variable or constant is declared. Only function variables have
2176 // an initial value in the declaration (because they are initialized upon
2177 // entering the function).
2178 //
2179 // If we have a const declaration, in an inner scope, the proxy is always
2180 // bound to the declared variable (independent of possibly surrounding with
2181 // statements).
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002182 // For let/const declarations in harmony mode, we can also immediately
2183 // pre-resolve the proxy because it resides in the same scope as the
2184 // declaration.
2185 VariableProxy* proxy = NewUnresolved(name, mode);
2186 Declaration* declaration =
2187 factory()->NewVariableDeclaration(proxy, mode, top_scope_);
2188 Declare(declaration, mode != VAR, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00002189 nvars++;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002190 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
Steve Block053d10c2011-06-13 19:13:29 +01002191 ReportMessageAt(scanner().location(), "too_many_variables",
2192 Vector<const char*>::empty());
2193 *ok = false;
2194 return NULL;
2195 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002196 if (names) names->Add(name);
Steve Blocka7e24c12009-10-30 11:49:00 +00002197
2198 // Parse initialization expression if present and/or needed. A
2199 // declaration of the form:
2200 //
2201 // var v = x;
2202 //
2203 // is syntactic sugar for:
2204 //
2205 // var v; v = x;
2206 //
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002207 // In particular, we need to re-lookup 'v' (in top_scope_, not
2208 // declaration_scope) as it may be a different 'v' than the 'v' in the
2209 // declaration (e.g., if we are inside a 'with' statement or 'catch'
2210 // block).
Steve Blocka7e24c12009-10-30 11:49:00 +00002211 //
2212 // However, note that const declarations are different! A const
2213 // declaration of the form:
2214 //
2215 // const c = x;
2216 //
2217 // is *not* syntactic sugar for:
2218 //
2219 // const c; c = x;
2220 //
2221 // The "variable" c initialized to x is the same as the declared
2222 // one - there is no re-lookup (see the last parameter of the
2223 // Declare() call above).
2224
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002225 Scope* initialization_scope = is_const ? declaration_scope : top_scope_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002226 Expression* value = NULL;
2227 int position = -1;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002228 // Harmony consts have non-optional initializers.
2229 if (peek() == Token::ASSIGN || mode == CONST_HARMONY) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002230 Expect(Token::ASSIGN, CHECK_OK);
2231 position = scanner().location().beg_pos;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002232 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002233 // Don't infer if it is "a = function(){...}();"-like expression.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002234 if (fni_ != NULL &&
2235 value->AsCall() == NULL &&
2236 value->AsCallNew() == NULL) {
2237 fni_->Infer();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002238 } else {
2239 fni_->RemoveLastFunction();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002240 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002241 if (decl_props != NULL) *decl_props = kHasInitializers;
2242 }
2243
2244 // Record the end position of the initializer.
2245 if (proxy->var() != NULL) {
2246 proxy->var()->set_initializer_position(scanner().location().end_pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002247 }
2248
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002249 // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
2250 if (value == NULL && needs_init) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002251 value = GetLiteralUndefined();
2252 }
2253
2254 // Global variable declarations must be compiled in a specific
2255 // way. When the script containing the global variable declaration
2256 // is entered, the global variable must be declared, so that if it
2257 // doesn't exist (not even in a prototype of the global object) it
2258 // gets created with an initial undefined value. This is handled
2259 // by the declarations part of the function representing the
2260 // top-level global code; see Runtime::DeclareGlobalVariable. If
2261 // it already exists (in the object or in a prototype), it is
2262 // *not* touched until the variable declaration statement is
2263 // executed.
2264 //
2265 // Executing the variable declaration statement will always
2266 // guarantee to give the global object a "local" variable; a
2267 // variable defined in the global object and not in any
2268 // prototype. This way, global variable declarations can shadow
2269 // properties in the prototype chain, but only after the variable
2270 // declaration statement has been executed. This is important in
2271 // browsers where the global object (window) has lots of
2272 // properties defined in prototype objects.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002273 if (initialization_scope->is_global_scope()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002274 // Compute the arguments for the runtime call.
Ben Murdoch257744e2011-11-30 15:57:28 +00002275 ZoneList<Expression*>* arguments = new(zone()) ZoneList<Expression*>(3);
Ben Murdoch8b112d22011-06-08 16:22:53 +01002276 // We have at least 1 parameter.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002277 arguments->Add(factory()->NewLiteral(name));
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002278 CallRuntime* initialize;
2279
2280 if (is_const) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002281 arguments->Add(value);
2282 value = NULL; // zap the value to avoid the unnecessary assignment
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002283
2284 // Construct the call to Runtime_InitializeConstGlobal
2285 // and add it to the initialization statement block.
2286 // Note that the function does different things depending on
2287 // the number of arguments (1 or 2).
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002288 initialize = factory()->NewCallRuntime(
2289 isolate()->factory()->InitializeConstGlobal_symbol(),
2290 Runtime::FunctionForId(Runtime::kInitializeConstGlobal),
2291 arguments);
Steve Blocka7e24c12009-10-30 11:49:00 +00002292 } else {
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002293 // Add strict mode.
2294 // We may want to pass singleton to avoid Literal allocations.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002295 LanguageMode language_mode = initialization_scope->language_mode();
2296 arguments->Add(factory()->NewNumberLiteral(language_mode));
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002297
2298 // Be careful not to assign a value to the global variable if
2299 // we're in a with. The initialization value should not
2300 // necessarily be stored in the global object in that case,
2301 // which is why we need to generate a separate assignment node.
2302 if (value != NULL && !inside_with()) {
2303 arguments->Add(value);
2304 value = NULL; // zap the value to avoid the unnecessary assignment
2305 }
2306
2307 // Construct the call to Runtime_InitializeVarGlobal
2308 // and add it to the initialization statement block.
2309 // Note that the function does different things depending on
2310 // the number of arguments (2 or 3).
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002311 initialize = factory()->NewCallRuntime(
2312 isolate()->factory()->InitializeVarGlobal_symbol(),
2313 Runtime::FunctionForId(Runtime::kInitializeVarGlobal),
2314 arguments);
Steve Blocka7e24c12009-10-30 11:49:00 +00002315 }
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002316
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002317 block->AddStatement(factory()->NewExpressionStatement(initialize));
2318 } else if (needs_init) {
2319 // Constant initializations always assign to the declared constant which
2320 // is always at the function scope level. This is only relevant for
2321 // dynamically looked-up variables and constants (the start context for
2322 // constant lookups is always the function context, while it is the top
2323 // context for var declared variables). Sigh...
2324 // For 'let' and 'const' declared variables in harmony mode the
2325 // initialization also always assigns to the declared variable.
2326 ASSERT(proxy != NULL);
2327 ASSERT(proxy->var() != NULL);
2328 ASSERT(value != NULL);
2329 Assignment* assignment =
2330 factory()->NewAssignment(init_op, proxy, value, position);
2331 block->AddStatement(factory()->NewExpressionStatement(assignment));
2332 value = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002333 }
2334
Ben Murdoch589d6972011-11-30 16:04:58 +00002335 // Add an assignment node to the initialization statement block if we still
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002336 // have a pending initialization value.
Steve Blocka7e24c12009-10-30 11:49:00 +00002337 if (value != NULL) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002338 ASSERT(mode == VAR);
2339 // 'var' initializations are simply assignments (with all the consequences
2340 // if they are inside a 'with' statement - they may change a 'with' object
2341 // property).
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002342 VariableProxy* proxy =
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002343 initialization_scope->NewUnresolved(factory(), name);
Ben Murdoch8b112d22011-06-08 16:22:53 +01002344 Assignment* assignment =
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002345 factory()->NewAssignment(init_op, proxy, value, position);
2346 block->AddStatement(factory()->NewExpressionStatement(assignment));
Steve Blocka7e24c12009-10-30 11:49:00 +00002347 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002348
2349 if (fni_ != NULL) fni_->Leave();
Steve Blocka7e24c12009-10-30 11:49:00 +00002350 } while (peek() == Token::COMMA);
2351
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002352 // If there was a single non-const declaration, return it in the output
2353 // parameter for possible use by for/in.
2354 if (nvars == 1 && !is_const) {
2355 *out = name;
Steve Blocka7e24c12009-10-30 11:49:00 +00002356 }
2357
2358 return block;
2359}
2360
2361
2362static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) {
2363 ASSERT(!label.is_null());
2364 if (labels != NULL)
2365 for (int i = labels->length(); i-- > 0; )
2366 if (labels->at(i).is_identical_to(label))
2367 return true;
2368
2369 return false;
2370}
2371
2372
2373Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
2374 bool* ok) {
2375 // ExpressionStatement | LabelledStatement ::
2376 // Expression ';'
2377 // Identifier ':' Statement
Steve Block1e0659c2011-05-24 12:43:12 +01002378 bool starts_with_idenfifier = peek_any_identifier();
Steve Blocka7e24c12009-10-30 11:49:00 +00002379 Expression* expr = ParseExpression(true, CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002380 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
Steve Blocka7e24c12009-10-30 11:49:00 +00002381 expr->AsVariableProxy() != NULL &&
2382 !expr->AsVariableProxy()->is_this()) {
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08002383 // Expression is a single identifier, and not, e.g., a parenthesized
2384 // identifier.
Steve Blocka7e24c12009-10-30 11:49:00 +00002385 VariableProxy* var = expr->AsVariableProxy();
2386 Handle<String> label = var->name();
2387 // TODO(1240780): We don't check for redeclaration of labels
2388 // during preparsing since keeping track of the set of active
2389 // labels requires nontrivial changes to the way scopes are
2390 // structured. However, these are probably changes we want to
2391 // make later anyway so we should go back and fix this then.
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002392 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
Ben Murdoch589d6972011-11-30 16:04:58 +00002393 SmartArrayPointer<char> c_string = label->ToCString(DISALLOW_NULLS);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002394 const char* elms[2] = { "Label", *c_string };
2395 Vector<const char*> args(elms, 2);
2396 ReportMessage("redeclaration", args);
2397 *ok = false;
2398 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002399 }
Ben Murdoch257744e2011-11-30 15:57:28 +00002400 if (labels == NULL) labels = new(zone()) ZoneStringList(4);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002401 labels->Add(label);
2402 // Remove the "ghost" variable that turned out to be a label
2403 // from the top scope. This way, we don't try to resolve it
2404 // during the scope processing.
2405 top_scope_->RemoveUnresolved(var);
Steve Blocka7e24c12009-10-30 11:49:00 +00002406 Expect(Token::COLON, CHECK_OK);
2407 return ParseStatement(labels, ok);
2408 }
2409
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002410 // If we have an extension, we allow a native function declaration.
2411 // A native function declaration starts with "native function" with
2412 // no line-terminator between the two words.
2413 if (extension_ != NULL &&
2414 peek() == Token::FUNCTION &&
2415 !scanner().HasAnyLineTerminatorBeforeNext() &&
2416 expr != NULL &&
2417 expr->AsVariableProxy() != NULL &&
2418 expr->AsVariableProxy()->name()->Equals(
2419 isolate()->heap()->native_symbol()) &&
2420 !scanner().literal_contains_escapes()) {
2421 return ParseNativeDeclaration(ok);
2422 }
2423
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002424 // Parsed expression statement, or the context-sensitive 'module' keyword.
2425 // Only expect semicolon in the former case.
2426 if (!FLAG_harmony_modules ||
2427 peek() != Token::IDENTIFIER ||
2428 scanner().HasAnyLineTerminatorBeforeNext() ||
2429 expr->AsVariableProxy() == NULL ||
2430 !expr->AsVariableProxy()->name()->Equals(
2431 isolate()->heap()->module_symbol()) ||
2432 scanner().literal_contains_escapes()) {
2433 ExpectSemicolon(CHECK_OK);
2434 }
2435 return factory()->NewExpressionStatement(expr);
Steve Blocka7e24c12009-10-30 11:49:00 +00002436}
2437
2438
2439IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) {
2440 // IfStatement ::
2441 // 'if' '(' Expression ')' Statement ('else' Statement)?
2442
2443 Expect(Token::IF, CHECK_OK);
2444 Expect(Token::LPAREN, CHECK_OK);
2445 Expression* condition = ParseExpression(true, CHECK_OK);
2446 Expect(Token::RPAREN, CHECK_OK);
2447 Statement* then_statement = ParseStatement(labels, CHECK_OK);
2448 Statement* else_statement = NULL;
2449 if (peek() == Token::ELSE) {
2450 Next();
2451 else_statement = ParseStatement(labels, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002452 } else {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002453 else_statement = factory()->NewEmptyStatement();
Steve Blocka7e24c12009-10-30 11:49:00 +00002454 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002455 return factory()->NewIfStatement(condition, then_statement, else_statement);
Steve Blocka7e24c12009-10-30 11:49:00 +00002456}
2457
2458
2459Statement* Parser::ParseContinueStatement(bool* ok) {
2460 // ContinueStatement ::
2461 // 'continue' Identifier? ';'
2462
2463 Expect(Token::CONTINUE, CHECK_OK);
2464 Handle<String> label = Handle<String>::null();
2465 Token::Value tok = peek();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002466 if (!scanner().HasAnyLineTerminatorBeforeNext() &&
Steve Blocka7e24c12009-10-30 11:49:00 +00002467 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2468 label = ParseIdentifier(CHECK_OK);
2469 }
2470 IterationStatement* target = NULL;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002471 target = LookupContinueTarget(label, CHECK_OK);
2472 if (target == NULL) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01002473 // Illegal continue statement.
2474 const char* message = "illegal_continue";
2475 Vector<Handle<String> > args;
2476 if (!label.is_null()) {
2477 message = "unknown_label";
2478 args = Vector<Handle<String> >(&label, 1);
2479 }
2480 ReportMessageAt(scanner().location(), message, args);
2481 *ok = false;
2482 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002483 }
2484 ExpectSemicolon(CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002485 return factory()->NewContinueStatement(target);
Steve Blocka7e24c12009-10-30 11:49:00 +00002486}
2487
2488
2489Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) {
2490 // BreakStatement ::
2491 // 'break' Identifier? ';'
2492
2493 Expect(Token::BREAK, CHECK_OK);
2494 Handle<String> label;
2495 Token::Value tok = peek();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002496 if (!scanner().HasAnyLineTerminatorBeforeNext() &&
Steve Blocka7e24c12009-10-30 11:49:00 +00002497 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2498 label = ParseIdentifier(CHECK_OK);
2499 }
2500 // Parse labeled break statements that target themselves into
2501 // empty statements, e.g. 'l1: l2: l3: break l2;'
2502 if (!label.is_null() && ContainsLabel(labels, label)) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002503 ExpectSemicolon(CHECK_OK);
2504 return factory()->NewEmptyStatement();
Steve Blocka7e24c12009-10-30 11:49:00 +00002505 }
2506 BreakableStatement* target = NULL;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002507 target = LookupBreakTarget(label, CHECK_OK);
2508 if (target == NULL) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01002509 // Illegal break statement.
2510 const char* message = "illegal_break";
2511 Vector<Handle<String> > args;
2512 if (!label.is_null()) {
2513 message = "unknown_label";
2514 args = Vector<Handle<String> >(&label, 1);
2515 }
2516 ReportMessageAt(scanner().location(), message, args);
2517 *ok = false;
2518 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002519 }
2520 ExpectSemicolon(CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002521 return factory()->NewBreakStatement(target);
Steve Blocka7e24c12009-10-30 11:49:00 +00002522}
2523
2524
2525Statement* Parser::ParseReturnStatement(bool* ok) {
2526 // ReturnStatement ::
2527 // 'return' Expression? ';'
2528
2529 // Consume the return token. It is necessary to do the before
2530 // reporting any errors on it, because of the way errors are
2531 // reported (underlining).
2532 Expect(Token::RETURN, CHECK_OK);
2533
Ben Murdoch692be652012-01-10 18:47:50 +00002534 Token::Value tok = peek();
2535 Statement* result;
2536 if (scanner().HasAnyLineTerminatorBeforeNext() ||
2537 tok == Token::SEMICOLON ||
2538 tok == Token::RBRACE ||
2539 tok == Token::EOS) {
2540 ExpectSemicolon(CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002541 result = factory()->NewReturnStatement(GetLiteralUndefined());
Ben Murdoch692be652012-01-10 18:47:50 +00002542 } else {
2543 Expression* expr = ParseExpression(true, CHECK_OK);
2544 ExpectSemicolon(CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002545 result = factory()->NewReturnStatement(expr);
Ben Murdoch692be652012-01-10 18:47:50 +00002546 }
2547
Steve Blocka7e24c12009-10-30 11:49:00 +00002548 // An ECMAScript program is considered syntactically incorrect if it
2549 // contains a return statement that is not within the body of a
2550 // function. See ECMA-262, section 12.9, page 67.
2551 //
2552 // To be consistent with KJS we report the syntax error at runtime.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002553 Scope* declaration_scope = top_scope_->DeclarationScope();
2554 if (declaration_scope->is_global_scope() ||
2555 declaration_scope->is_eval_scope()) {
Steve Block44f0eee2011-05-26 01:26:41 +01002556 Handle<String> type = isolate()->factory()->illegal_return_symbol();
Steve Blocka7e24c12009-10-30 11:49:00 +00002557 Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002558 return factory()->NewExpressionStatement(throw_error);
Steve Blocka7e24c12009-10-30 11:49:00 +00002559 }
Ben Murdoch692be652012-01-10 18:47:50 +00002560 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00002561}
2562
2563
Steve Blocka7e24c12009-10-30 11:49:00 +00002564Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) {
2565 // WithStatement ::
2566 // 'with' '(' Expression ')' Statement
2567
2568 Expect(Token::WITH, CHECK_OK);
Steve Block1e0659c2011-05-24 12:43:12 +01002569
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002570 if (!top_scope_->is_classic_mode()) {
Steve Block1e0659c2011-05-24 12:43:12 +01002571 ReportMessage("strict_mode_with", Vector<const char*>::empty());
2572 *ok = false;
2573 return NULL;
2574 }
2575
Steve Blocka7e24c12009-10-30 11:49:00 +00002576 Expect(Token::LPAREN, CHECK_OK);
2577 Expression* expr = ParseExpression(true, CHECK_OK);
2578 Expect(Token::RPAREN, CHECK_OK);
2579
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002580 top_scope_->DeclarationScope()->RecordWithStatement();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002581 Scope* with_scope = NewScope(top_scope_, WITH_SCOPE);
2582 Statement* stmt;
2583 { BlockState block_state(this, with_scope);
2584 with_scope->set_start_position(scanner().peek_location().beg_pos);
2585 stmt = ParseStatement(labels, CHECK_OK);
2586 with_scope->set_end_position(scanner().location().end_pos);
2587 }
2588 return factory()->NewWithStatement(expr, stmt);
Steve Blocka7e24c12009-10-30 11:49:00 +00002589}
2590
2591
2592CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
2593 // CaseClause ::
2594 // 'case' Expression ':' Statement*
2595 // 'default' ':' Statement*
2596
2597 Expression* label = NULL; // NULL expression indicates default case
2598 if (peek() == Token::CASE) {
2599 Expect(Token::CASE, CHECK_OK);
2600 label = ParseExpression(true, CHECK_OK);
2601 } else {
2602 Expect(Token::DEFAULT, CHECK_OK);
2603 if (*default_seen_ptr) {
2604 ReportMessage("multiple_defaults_in_switch",
2605 Vector<const char*>::empty());
2606 *ok = false;
2607 return NULL;
2608 }
2609 *default_seen_ptr = true;
2610 }
2611 Expect(Token::COLON, CHECK_OK);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002612 int pos = scanner().location().beg_pos;
Ben Murdoch257744e2011-11-30 15:57:28 +00002613 ZoneList<Statement*>* statements = new(zone()) ZoneList<Statement*>(5);
Steve Blocka7e24c12009-10-30 11:49:00 +00002614 while (peek() != Token::CASE &&
2615 peek() != Token::DEFAULT &&
2616 peek() != Token::RBRACE) {
2617 Statement* stat = ParseStatement(NULL, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002618 statements->Add(stat);
Steve Blocka7e24c12009-10-30 11:49:00 +00002619 }
2620
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002621 return new(zone()) CaseClause(isolate(), label, statements, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002622}
2623
2624
2625SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels,
2626 bool* ok) {
2627 // SwitchStatement ::
2628 // 'switch' '(' Expression ')' '{' CaseClause* '}'
2629
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002630 SwitchStatement* statement = factory()->NewSwitchStatement(labels);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002631 Target target(&this->target_stack_, statement);
Steve Blocka7e24c12009-10-30 11:49:00 +00002632
2633 Expect(Token::SWITCH, CHECK_OK);
2634 Expect(Token::LPAREN, CHECK_OK);
2635 Expression* tag = ParseExpression(true, CHECK_OK);
2636 Expect(Token::RPAREN, CHECK_OK);
2637
2638 bool default_seen = false;
Ben Murdoch257744e2011-11-30 15:57:28 +00002639 ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4);
Steve Blocka7e24c12009-10-30 11:49:00 +00002640 Expect(Token::LBRACE, CHECK_OK);
2641 while (peek() != Token::RBRACE) {
2642 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002643 cases->Add(clause);
Steve Blocka7e24c12009-10-30 11:49:00 +00002644 }
2645 Expect(Token::RBRACE, CHECK_OK);
2646
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002647 if (statement) statement->Initialize(tag, cases);
Steve Blocka7e24c12009-10-30 11:49:00 +00002648 return statement;
2649}
2650
2651
2652Statement* Parser::ParseThrowStatement(bool* ok) {
2653 // ThrowStatement ::
2654 // 'throw' Expression ';'
2655
2656 Expect(Token::THROW, CHECK_OK);
2657 int pos = scanner().location().beg_pos;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002658 if (scanner().HasAnyLineTerminatorBeforeNext()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002659 ReportMessage("newline_after_throw", Vector<const char*>::empty());
2660 *ok = false;
2661 return NULL;
2662 }
2663 Expression* exception = ParseExpression(true, CHECK_OK);
2664 ExpectSemicolon(CHECK_OK);
2665
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002666 return factory()->NewExpressionStatement(factory()->NewThrow(exception, pos));
Steve Blocka7e24c12009-10-30 11:49:00 +00002667}
2668
2669
2670TryStatement* Parser::ParseTryStatement(bool* ok) {
2671 // TryStatement ::
2672 // 'try' Block Catch
2673 // 'try' Block Finally
2674 // 'try' Block Catch Finally
2675 //
2676 // Catch ::
2677 // 'catch' '(' Identifier ')' Block
2678 //
2679 // Finally ::
2680 // 'finally' Block
2681
2682 Expect(Token::TRY, CHECK_OK);
2683
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002684 TargetCollector try_collector;
Steve Blocka7e24c12009-10-30 11:49:00 +00002685 Block* try_block;
2686
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002687 { Target target(&this->target_stack_, &try_collector);
Steve Blocka7e24c12009-10-30 11:49:00 +00002688 try_block = ParseBlock(NULL, CHECK_OK);
2689 }
2690
Steve Blocka7e24c12009-10-30 11:49:00 +00002691 Token::Value tok = peek();
2692 if (tok != Token::CATCH && tok != Token::FINALLY) {
2693 ReportMessage("no_catch_or_finally", Vector<const char*>::empty());
2694 *ok = false;
2695 return NULL;
2696 }
2697
2698 // If we can break out from the catch block and there is a finally block,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002699 // then we will need to collect escaping targets from the catch
2700 // block. Since we don't know yet if there will be a finally block, we
2701 // always collect the targets.
2702 TargetCollector catch_collector;
2703 Scope* catch_scope = NULL;
2704 Variable* catch_variable = NULL;
2705 Block* catch_block = NULL;
2706 Handle<String> name;
Steve Blocka7e24c12009-10-30 11:49:00 +00002707 if (tok == Token::CATCH) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002708 Consume(Token::CATCH);
2709
2710 Expect(Token::LPAREN, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002711 catch_scope = NewScope(top_scope_, CATCH_SCOPE);
2712 catch_scope->set_start_position(scanner().location().beg_pos);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002713 name = ParseIdentifier(CHECK_OK);
Steve Block1e0659c2011-05-24 12:43:12 +01002714
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002715 if (!top_scope_->is_classic_mode() && IsEvalOrArguments(name)) {
Steve Block1e0659c2011-05-24 12:43:12 +01002716 ReportMessage("strict_catch_variable", Vector<const char*>::empty());
2717 *ok = false;
2718 return NULL;
2719 }
2720
Steve Blocka7e24c12009-10-30 11:49:00 +00002721 Expect(Token::RPAREN, CHECK_OK);
2722
2723 if (peek() == Token::LBRACE) {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002724 Target target(&this->target_stack_, &catch_collector);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002725 VariableMode mode = is_extended_mode() ? LET : VAR;
2726 catch_variable =
2727 catch_scope->DeclareLocal(name, mode, kCreatedInitialized);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002728
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002729 BlockState block_state(this, catch_scope);
Ben Murdoch589d6972011-11-30 16:04:58 +00002730 catch_block = ParseBlock(NULL, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00002731 } else {
2732 Expect(Token::LBRACE, CHECK_OK);
2733 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002734 catch_scope->set_end_position(scanner().location().end_pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002735 tok = peek();
2736 }
2737
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002738 Block* finally_block = NULL;
2739 if (tok == Token::FINALLY || catch_block == NULL) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002740 Consume(Token::FINALLY);
Steve Blocka7e24c12009-10-30 11:49:00 +00002741 finally_block = ParseBlock(NULL, CHECK_OK);
2742 }
2743
2744 // Simplify the AST nodes by converting:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002745 // 'try B0 catch B1 finally B2'
Steve Blocka7e24c12009-10-30 11:49:00 +00002746 // to:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002747 // 'try { try B0 catch B1 } finally B2'
Steve Blocka7e24c12009-10-30 11:49:00 +00002748
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002749 if (catch_block != NULL && finally_block != NULL) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002750 // If we have both, create an inner try/catch.
2751 ASSERT(catch_scope != NULL && catch_variable != NULL);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002752 int index = current_function_state_->NextHandlerIndex();
2753 TryCatchStatement* statement = factory()->NewTryCatchStatement(
2754 index, try_block, catch_scope, catch_variable, catch_block);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002755 statement->set_escaping_targets(try_collector.targets());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002756 try_block = factory()->NewBlock(NULL, 1, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002757 try_block->AddStatement(statement);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002758 catch_block = NULL; // Clear to indicate it's been handled.
Steve Blocka7e24c12009-10-30 11:49:00 +00002759 }
2760
2761 TryStatement* result = NULL;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002762 if (catch_block != NULL) {
2763 ASSERT(finally_block == NULL);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002764 ASSERT(catch_scope != NULL && catch_variable != NULL);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002765 int index = current_function_state_->NextHandlerIndex();
2766 result = factory()->NewTryCatchStatement(
2767 index, try_block, catch_scope, catch_variable, catch_block);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002768 } else {
2769 ASSERT(finally_block != NULL);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002770 int index = current_function_state_->NextHandlerIndex();
2771 result = factory()->NewTryFinallyStatement(index, try_block, finally_block);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002772 // Combine the jump targets of the try block and the possible catch block.
2773 try_collector.targets()->AddAll(*catch_collector.targets());
Steve Blocka7e24c12009-10-30 11:49:00 +00002774 }
2775
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002776 result->set_escaping_targets(try_collector.targets());
Steve Blocka7e24c12009-10-30 11:49:00 +00002777 return result;
2778}
2779
2780
Steve Block3ce2e202009-11-05 08:53:23 +00002781DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels,
2782 bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002783 // DoStatement ::
2784 // 'do' Statement 'while' '(' Expression ')' ';'
2785
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002786 DoWhileStatement* loop = factory()->NewDoWhileStatement(labels);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002787 Target target(&this->target_stack_, loop);
Steve Blocka7e24c12009-10-30 11:49:00 +00002788
2789 Expect(Token::DO, CHECK_OK);
2790 Statement* body = ParseStatement(NULL, CHECK_OK);
2791 Expect(Token::WHILE, CHECK_OK);
2792 Expect(Token::LPAREN, CHECK_OK);
Steve Blockd0582a62009-12-15 09:54:21 +00002793
2794 if (loop != NULL) {
2795 int position = scanner().location().beg_pos;
2796 loop->set_condition_position(position);
2797 }
2798
Steve Blocka7e24c12009-10-30 11:49:00 +00002799 Expression* cond = ParseExpression(true, CHECK_OK);
2800 Expect(Token::RPAREN, CHECK_OK);
2801
2802 // Allow do-statements to be terminated with and without
2803 // semi-colons. This allows code such as 'do;while(0)return' to
2804 // parse, which would not be the case if we had used the
2805 // ExpectSemicolon() functionality here.
2806 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
2807
Steve Block3ce2e202009-11-05 08:53:23 +00002808 if (loop != NULL) loop->Initialize(cond, body);
Steve Blocka7e24c12009-10-30 11:49:00 +00002809 return loop;
2810}
2811
2812
Steve Block3ce2e202009-11-05 08:53:23 +00002813WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002814 // WhileStatement ::
2815 // 'while' '(' Expression ')' Statement
2816
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002817 WhileStatement* loop = factory()->NewWhileStatement(labels);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002818 Target target(&this->target_stack_, loop);
Steve Blocka7e24c12009-10-30 11:49:00 +00002819
2820 Expect(Token::WHILE, CHECK_OK);
2821 Expect(Token::LPAREN, CHECK_OK);
2822 Expression* cond = ParseExpression(true, CHECK_OK);
2823 Expect(Token::RPAREN, CHECK_OK);
2824 Statement* body = ParseStatement(NULL, CHECK_OK);
2825
Steve Block3ce2e202009-11-05 08:53:23 +00002826 if (loop != NULL) loop->Initialize(cond, body);
Steve Blocka7e24c12009-10-30 11:49:00 +00002827 return loop;
2828}
2829
2830
2831Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
2832 // ForStatement ::
2833 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
2834
2835 Statement* init = NULL;
2836
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002837 // Create an in-between scope for let-bound iteration variables.
2838 Scope* saved_scope = top_scope_;
2839 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE);
2840 top_scope_ = for_scope;
2841
Steve Blocka7e24c12009-10-30 11:49:00 +00002842 Expect(Token::FOR, CHECK_OK);
2843 Expect(Token::LPAREN, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002844 for_scope->set_start_position(scanner().location().beg_pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002845 if (peek() != Token::SEMICOLON) {
2846 if (peek() == Token::VAR || peek() == Token::CONST) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002847 Handle<String> name;
Steve Blocka7e24c12009-10-30 11:49:00 +00002848 Block* variable_statement =
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002849 ParseVariableDeclarations(kForStatement, NULL, NULL, &name, CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002850
2851 if (peek() == Token::IN && !name.is_null()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002852 VariableProxy* each = top_scope_->NewUnresolved(factory(), name);
2853 ForInStatement* loop = factory()->NewForInStatement(labels);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002854 Target target(&this->target_stack_, loop);
Steve Blocka7e24c12009-10-30 11:49:00 +00002855
2856 Expect(Token::IN, CHECK_OK);
2857 Expression* enumerable = ParseExpression(true, CHECK_OK);
2858 Expect(Token::RPAREN, CHECK_OK);
2859
2860 Statement* body = ParseStatement(NULL, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002861 loop->Initialize(each, enumerable, body);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002862 Block* result = factory()->NewBlock(NULL, 2, false);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002863 result->AddStatement(variable_statement);
2864 result->AddStatement(loop);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002865 top_scope_ = saved_scope;
2866 for_scope->set_end_position(scanner().location().end_pos);
2867 for_scope = for_scope->FinalizeBlockScope();
2868 ASSERT(for_scope == NULL);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002869 // Parsed for-in loop w/ variable/const declaration.
2870 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00002871 } else {
2872 init = variable_statement;
2873 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002874 } else if (peek() == Token::LET) {
2875 Handle<String> name;
2876 VariableDeclarationProperties decl_props = kHasNoInitializers;
2877 Block* variable_statement =
2878 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
2879 CHECK_OK);
2880 bool accept_IN = !name.is_null() && decl_props != kHasInitializers;
2881 if (peek() == Token::IN && accept_IN) {
2882 // Rewrite a for-in statement of the form
2883 //
2884 // for (let x in e) b
2885 //
2886 // into
2887 //
2888 // <let x' be a temporary variable>
2889 // for (x' in e) {
2890 // let x;
2891 // x = x';
2892 // b;
2893 // }
Steve Blocka7e24c12009-10-30 11:49:00 +00002894
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002895 // TODO(keuchel): Move the temporary variable to the block scope, after
2896 // implementing stack allocated block scoped variables.
2897 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(name);
2898 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
2899 VariableProxy* each = top_scope_->NewUnresolved(factory(), name);
2900 ForInStatement* loop = factory()->NewForInStatement(labels);
2901 Target target(&this->target_stack_, loop);
2902
2903 Expect(Token::IN, CHECK_OK);
2904 Expression* enumerable = ParseExpression(true, CHECK_OK);
2905 Expect(Token::RPAREN, CHECK_OK);
2906
2907 Statement* body = ParseStatement(NULL, CHECK_OK);
2908 Block* body_block = factory()->NewBlock(NULL, 3, false);
2909 Assignment* assignment = factory()->NewAssignment(
2910 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition);
2911 Statement* assignment_statement =
2912 factory()->NewExpressionStatement(assignment);
2913 body_block->AddStatement(variable_statement);
2914 body_block->AddStatement(assignment_statement);
2915 body_block->AddStatement(body);
2916 loop->Initialize(temp_proxy, enumerable, body_block);
2917 top_scope_ = saved_scope;
2918 for_scope->set_end_position(scanner().location().end_pos);
2919 for_scope = for_scope->FinalizeBlockScope();
2920 body_block->set_block_scope(for_scope);
2921 // Parsed for-in loop w/ let declaration.
2922 return loop;
2923
2924 } else {
2925 init = variable_statement;
2926 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002927 } else {
2928 Expression* expression = ParseExpression(false, CHECK_OK);
2929 if (peek() == Token::IN) {
2930 // Signal a reference error if the expression is an invalid
2931 // left-hand side expression. We could report this as a syntax
2932 // error here but for compatibility with JSC we choose to report
2933 // the error at runtime.
2934 if (expression == NULL || !expression->IsValidLeftHandSide()) {
Steve Block44f0eee2011-05-26 01:26:41 +01002935 Handle<String> type =
2936 isolate()->factory()->invalid_lhs_in_for_in_symbol();
Steve Blocka7e24c12009-10-30 11:49:00 +00002937 expression = NewThrowReferenceError(type);
2938 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002939 ForInStatement* loop = factory()->NewForInStatement(labels);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002940 Target target(&this->target_stack_, loop);
Steve Blocka7e24c12009-10-30 11:49:00 +00002941
2942 Expect(Token::IN, CHECK_OK);
2943 Expression* enumerable = ParseExpression(true, CHECK_OK);
2944 Expect(Token::RPAREN, CHECK_OK);
2945
2946 Statement* body = ParseStatement(NULL, CHECK_OK);
2947 if (loop) loop->Initialize(expression, enumerable, body);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002948 top_scope_ = saved_scope;
2949 for_scope->set_end_position(scanner().location().end_pos);
2950 for_scope = for_scope->FinalizeBlockScope();
2951 ASSERT(for_scope == NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00002952 // Parsed for-in loop.
2953 return loop;
2954
2955 } else {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002956 init = factory()->NewExpressionStatement(expression);
Steve Blocka7e24c12009-10-30 11:49:00 +00002957 }
2958 }
2959 }
2960
2961 // Standard 'for' loop
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002962 ForStatement* loop = factory()->NewForStatement(labels);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002963 Target target(&this->target_stack_, loop);
Steve Blocka7e24c12009-10-30 11:49:00 +00002964
2965 // Parsed initializer at this point.
2966 Expect(Token::SEMICOLON, CHECK_OK);
2967
2968 Expression* cond = NULL;
2969 if (peek() != Token::SEMICOLON) {
2970 cond = ParseExpression(true, CHECK_OK);
2971 }
2972 Expect(Token::SEMICOLON, CHECK_OK);
2973
2974 Statement* next = NULL;
2975 if (peek() != Token::RPAREN) {
2976 Expression* exp = ParseExpression(true, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002977 next = factory()->NewExpressionStatement(exp);
Steve Blocka7e24c12009-10-30 11:49:00 +00002978 }
2979 Expect(Token::RPAREN, CHECK_OK);
2980
2981 Statement* body = ParseStatement(NULL, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002982 top_scope_ = saved_scope;
2983 for_scope->set_end_position(scanner().location().end_pos);
2984 for_scope = for_scope->FinalizeBlockScope();
2985 if (for_scope != NULL) {
2986 // Rewrite a for statement of the form
2987 //
2988 // for (let x = i; c; n) b
2989 //
2990 // into
2991 //
2992 // {
2993 // let x = i;
2994 // for (; c; n) b
2995 // }
2996 ASSERT(init != NULL);
2997 Block* result = factory()->NewBlock(NULL, 2, false);
2998 result->AddStatement(init);
2999 result->AddStatement(loop);
3000 result->set_block_scope(for_scope);
3001 if (loop) loop->Initialize(NULL, cond, next, body);
3002 return result;
3003 } else {
3004 if (loop) loop->Initialize(init, cond, next, body);
3005 return loop;
3006 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003007}
3008
3009
3010// Precedence = 1
3011Expression* Parser::ParseExpression(bool accept_IN, bool* ok) {
3012 // Expression ::
3013 // AssignmentExpression
3014 // Expression ',' AssignmentExpression
3015
3016 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK);
3017 while (peek() == Token::COMMA) {
3018 Expect(Token::COMMA, CHECK_OK);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003019 int position = scanner().location().beg_pos;
Steve Blocka7e24c12009-10-30 11:49:00 +00003020 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003021 result =
3022 factory()->NewBinaryOperation(Token::COMMA, result, right, position);
Steve Blocka7e24c12009-10-30 11:49:00 +00003023 }
3024 return result;
3025}
3026
3027
3028// Precedence = 2
3029Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
3030 // AssignmentExpression ::
3031 // ConditionalExpression
3032 // LeftHandSideExpression AssignmentOperator AssignmentExpression
3033
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003034 if (fni_ != NULL) fni_->Enter();
Steve Blocka7e24c12009-10-30 11:49:00 +00003035 Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK);
3036
3037 if (!Token::IsAssignmentOp(peek())) {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003038 if (fni_ != NULL) fni_->Leave();
Steve Blocka7e24c12009-10-30 11:49:00 +00003039 // Parsed conditional expression only (no assignment).
3040 return expression;
3041 }
3042
3043 // Signal a reference error if the expression is an invalid left-hand
3044 // side expression. We could report this as a syntax error here but
3045 // for compatibility with JSC we choose to report the error at
3046 // runtime.
3047 if (expression == NULL || !expression->IsValidLeftHandSide()) {
Steve Block44f0eee2011-05-26 01:26:41 +01003048 Handle<String> type =
3049 isolate()->factory()->invalid_lhs_in_assignment_symbol();
Steve Blocka7e24c12009-10-30 11:49:00 +00003050 expression = NewThrowReferenceError(type);
3051 }
3052
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003053 if (!top_scope_->is_classic_mode()) {
Steve Block1e0659c2011-05-24 12:43:12 +01003054 // Assignment to eval or arguments is disallowed in strict mode.
3055 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK);
3056 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003057 MarkAsLValue(expression);
Steve Block1e0659c2011-05-24 12:43:12 +01003058
Steve Blocka7e24c12009-10-30 11:49:00 +00003059 Token::Value op = Next(); // Get assignment operator.
3060 int pos = scanner().location().beg_pos;
3061 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
3062
3063 // TODO(1231235): We try to estimate the set of properties set by
3064 // constructors. We define a new property whenever there is an
3065 // assignment to a property of 'this'. We should probably only add
3066 // properties if we haven't seen them before. Otherwise we'll
3067 // probably overestimate the number of properties.
3068 Property* property = expression ? expression->AsProperty() : NULL;
3069 if (op == Token::ASSIGN &&
3070 property != NULL &&
3071 property->obj()->AsVariableProxy() != NULL &&
3072 property->obj()->AsVariableProxy()->is_this()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003073 current_function_state_->AddProperty();
Steve Blocka7e24c12009-10-30 11:49:00 +00003074 }
3075
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08003076 // If we assign a function literal to a property we pretenure the
3077 // literal so it can be added as a constant function property.
3078 if (property != NULL && right->AsFunctionLiteral() != NULL) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003079 right->AsFunctionLiteral()->set_pretenure();
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08003080 }
3081
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003082 if (fni_ != NULL) {
3083 // Check if the right hand side is a call to avoid inferring a
3084 // name if we're dealing with "a = function(){...}();"-like
3085 // expression.
3086 if ((op == Token::INIT_VAR
3087 || op == Token::INIT_CONST
3088 || op == Token::ASSIGN)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003089 && (right->AsCall() == NULL && right->AsCallNew() == NULL)) {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003090 fni_->Infer();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003091 } else {
3092 fni_->RemoveLastFunction();
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003093 }
3094 fni_->Leave();
3095 }
3096
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003097 return factory()->NewAssignment(op, expression, right, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00003098}
3099
3100
3101// Precedence = 3
3102Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) {
3103 // ConditionalExpression ::
3104 // LogicalOrExpression
3105 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
3106
3107 // We start using the binary expression parser for prec >= 4 only!
3108 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
3109 if (peek() != Token::CONDITIONAL) return expression;
3110 Consume(Token::CONDITIONAL);
3111 // In parsing the first assignment expression in conditional
3112 // expressions we always accept the 'in' keyword; see ECMA-262,
3113 // section 11.12, page 58.
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01003114 int left_position = scanner().peek_location().beg_pos;
Steve Blocka7e24c12009-10-30 11:49:00 +00003115 Expression* left = ParseAssignmentExpression(true, CHECK_OK);
3116 Expect(Token::COLON, CHECK_OK);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01003117 int right_position = scanner().peek_location().beg_pos;
Steve Blocka7e24c12009-10-30 11:49:00 +00003118 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003119 return factory()->NewConditional(
3120 expression, left, right, left_position, right_position);
Steve Blocka7e24c12009-10-30 11:49:00 +00003121}
3122
3123
3124static int Precedence(Token::Value tok, bool accept_IN) {
3125 if (tok == Token::IN && !accept_IN)
3126 return 0; // 0 precedence will terminate binary expression parsing
3127
3128 return Token::Precedence(tok);
3129}
3130
3131
3132// Precedence >= 4
3133Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
3134 ASSERT(prec >= 4);
3135 Expression* x = ParseUnaryExpression(CHECK_OK);
3136 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
3137 // prec1 >= 4
3138 while (Precedence(peek(), accept_IN) == prec1) {
3139 Token::Value op = Next();
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003140 int position = scanner().location().beg_pos;
Steve Blocka7e24c12009-10-30 11:49:00 +00003141 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
3142
3143 // Compute some expressions involving only number literals.
3144 if (x && x->AsLiteral() && x->AsLiteral()->handle()->IsNumber() &&
3145 y && y->AsLiteral() && y->AsLiteral()->handle()->IsNumber()) {
3146 double x_val = x->AsLiteral()->handle()->Number();
3147 double y_val = y->AsLiteral()->handle()->Number();
3148
3149 switch (op) {
3150 case Token::ADD:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003151 x = factory()->NewNumberLiteral(x_val + y_val);
Steve Blocka7e24c12009-10-30 11:49:00 +00003152 continue;
3153 case Token::SUB:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003154 x = factory()->NewNumberLiteral(x_val - y_val);
Steve Blocka7e24c12009-10-30 11:49:00 +00003155 continue;
3156 case Token::MUL:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003157 x = factory()->NewNumberLiteral(x_val * y_val);
Steve Blocka7e24c12009-10-30 11:49:00 +00003158 continue;
3159 case Token::DIV:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003160 x = factory()->NewNumberLiteral(x_val / y_val);
Steve Blocka7e24c12009-10-30 11:49:00 +00003161 continue;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003162 case Token::BIT_OR: {
3163 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
3164 x = factory()->NewNumberLiteral(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003165 continue;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003166 }
3167 case Token::BIT_AND: {
3168 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
3169 x = factory()->NewNumberLiteral(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003170 continue;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003171 }
3172 case Token::BIT_XOR: {
3173 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
3174 x = factory()->NewNumberLiteral(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003175 continue;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003176 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003177 case Token::SHL: {
3178 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003179 x = factory()->NewNumberLiteral(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003180 continue;
3181 }
3182 case Token::SHR: {
3183 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
3184 uint32_t value = DoubleToUint32(x_val) >> shift;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003185 x = factory()->NewNumberLiteral(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003186 continue;
3187 }
3188 case Token::SAR: {
3189 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
3190 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003191 x = factory()->NewNumberLiteral(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003192 continue;
3193 }
3194 default:
3195 break;
3196 }
3197 }
3198
Steve Blocka7e24c12009-10-30 11:49:00 +00003199 // For now we distinguish between comparisons and other binary
3200 // operations. (We could combine the two and get rid of this
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003201 // code and AST node eventually.)
Steve Blocka7e24c12009-10-30 11:49:00 +00003202 if (Token::IsCompareOp(op)) {
3203 // We have a comparison.
3204 Token::Value cmp = op;
3205 switch (op) {
3206 case Token::NE: cmp = Token::EQ; break;
3207 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
3208 default: break;
3209 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003210 x = factory()->NewCompareOperation(cmp, x, y, position);
Steve Blocka7e24c12009-10-30 11:49:00 +00003211 if (cmp != op) {
3212 // The comparison was negated - add a NOT.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003213 x = factory()->NewUnaryOperation(Token::NOT, x, position);
Steve Blocka7e24c12009-10-30 11:49:00 +00003214 }
3215
3216 } else {
3217 // We have a "normal" binary operation.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003218 x = factory()->NewBinaryOperation(op, x, y, position);
Steve Blocka7e24c12009-10-30 11:49:00 +00003219 }
3220 }
3221 }
3222 return x;
3223}
3224
3225
3226Expression* Parser::ParseUnaryExpression(bool* ok) {
3227 // UnaryExpression ::
3228 // PostfixExpression
3229 // 'delete' UnaryExpression
3230 // 'void' UnaryExpression
3231 // 'typeof' UnaryExpression
3232 // '++' UnaryExpression
3233 // '--' UnaryExpression
3234 // '+' UnaryExpression
3235 // '-' UnaryExpression
3236 // '~' UnaryExpression
3237 // '!' UnaryExpression
3238
3239 Token::Value op = peek();
3240 if (Token::IsUnaryOp(op)) {
3241 op = Next();
Ben Murdoch257744e2011-11-30 15:57:28 +00003242 int position = scanner().location().beg_pos;
Steve Blocka7e24c12009-10-30 11:49:00 +00003243 Expression* expression = ParseUnaryExpression(CHECK_OK);
3244
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003245 if (expression != NULL && (expression->AsLiteral() != NULL)) {
3246 Handle<Object> literal = expression->AsLiteral()->handle();
3247 if (op == Token::NOT) {
3248 // Convert the literal to a boolean condition and negate it.
3249 bool condition = literal->ToBoolean()->IsTrue();
3250 Handle<Object> result(isolate()->heap()->ToBoolean(!condition));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003251 return factory()->NewLiteral(result);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003252 } else if (literal->IsNumber()) {
3253 // Compute some expressions involving only number literals.
3254 double value = literal->Number();
3255 switch (op) {
3256 case Token::ADD:
3257 return expression;
3258 case Token::SUB:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003259 return factory()->NewNumberLiteral(-value);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003260 case Token::BIT_NOT:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003261 return factory()->NewNumberLiteral(~DoubleToInt32(value));
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003262 default:
3263 break;
3264 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003265 }
3266 }
3267
Ben Murdoche0cee9b2011-05-25 10:26:03 +01003268 // "delete identifier" is a syntax error in strict mode.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003269 if (op == Token::DELETE && !top_scope_->is_classic_mode()) {
Ben Murdoche0cee9b2011-05-25 10:26:03 +01003270 VariableProxy* operand = expression->AsVariableProxy();
3271 if (operand != NULL && !operand->is_this()) {
3272 ReportMessage("strict_delete", Vector<const char*>::empty());
3273 *ok = false;
3274 return NULL;
3275 }
3276 }
3277
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003278 return factory()->NewUnaryOperation(op, expression, position);
Steve Blocka7e24c12009-10-30 11:49:00 +00003279
3280 } else if (Token::IsCountOp(op)) {
3281 op = Next();
3282 Expression* expression = ParseUnaryExpression(CHECK_OK);
3283 // Signal a reference error if the expression is an invalid
3284 // left-hand side expression. We could report this as a syntax
3285 // error here but for compatibility with JSC we choose to report the
3286 // error at runtime.
3287 if (expression == NULL || !expression->IsValidLeftHandSide()) {
Steve Block44f0eee2011-05-26 01:26:41 +01003288 Handle<String> type =
3289 isolate()->factory()->invalid_lhs_in_prefix_op_symbol();
Steve Blocka7e24c12009-10-30 11:49:00 +00003290 expression = NewThrowReferenceError(type);
3291 }
Steve Block1e0659c2011-05-24 12:43:12 +01003292
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003293 if (!top_scope_->is_classic_mode()) {
Steve Block1e0659c2011-05-24 12:43:12 +01003294 // Prefix expression operand in strict mode may not be eval or arguments.
3295 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
3296 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003297 MarkAsLValue(expression);
Steve Block1e0659c2011-05-24 12:43:12 +01003298
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003299 int position = scanner().location().beg_pos;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003300 return factory()->NewCountOperation(op,
3301 true /* prefix */,
3302 expression,
3303 position);
Steve Blocka7e24c12009-10-30 11:49:00 +00003304
3305 } else {
3306 return ParsePostfixExpression(ok);
3307 }
3308}
3309
3310
3311Expression* Parser::ParsePostfixExpression(bool* ok) {
3312 // PostfixExpression ::
3313 // LeftHandSideExpression ('++' | '--')?
3314
3315 Expression* expression = ParseLeftHandSideExpression(CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003316 if (!scanner().HasAnyLineTerminatorBeforeNext() &&
Ben Murdochb0fe1622011-05-05 13:52:32 +01003317 Token::IsCountOp(peek())) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003318 // Signal a reference error if the expression is an invalid
3319 // left-hand side expression. We could report this as a syntax
3320 // error here but for compatibility with JSC we choose to report the
3321 // error at runtime.
3322 if (expression == NULL || !expression->IsValidLeftHandSide()) {
Steve Block44f0eee2011-05-26 01:26:41 +01003323 Handle<String> type =
3324 isolate()->factory()->invalid_lhs_in_postfix_op_symbol();
Steve Blocka7e24c12009-10-30 11:49:00 +00003325 expression = NewThrowReferenceError(type);
3326 }
Steve Block1e0659c2011-05-24 12:43:12 +01003327
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003328 if (!top_scope_->is_classic_mode()) {
Steve Block1e0659c2011-05-24 12:43:12 +01003329 // Postfix expression operand in strict mode may not be eval or arguments.
3330 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
3331 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003332 MarkAsLValue(expression);
Steve Block1e0659c2011-05-24 12:43:12 +01003333
Steve Blocka7e24c12009-10-30 11:49:00 +00003334 Token::Value next = Next();
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003335 int position = scanner().location().beg_pos;
Ben Murdoch8b112d22011-06-08 16:22:53 +01003336 expression =
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003337 factory()->NewCountOperation(next,
3338 false /* postfix */,
3339 expression,
3340 position);
Steve Blocka7e24c12009-10-30 11:49:00 +00003341 }
3342 return expression;
3343}
3344
3345
3346Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
3347 // LeftHandSideExpression ::
3348 // (NewExpression | MemberExpression) ...
3349
3350 Expression* result;
3351 if (peek() == Token::NEW) {
3352 result = ParseNewExpression(CHECK_OK);
3353 } else {
3354 result = ParseMemberExpression(CHECK_OK);
3355 }
3356
3357 while (true) {
3358 switch (peek()) {
3359 case Token::LBRACK: {
3360 Consume(Token::LBRACK);
3361 int pos = scanner().location().beg_pos;
3362 Expression* index = ParseExpression(true, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003363 result = factory()->NewProperty(result, index, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00003364 Expect(Token::RBRACK, CHECK_OK);
3365 break;
3366 }
3367
3368 case Token::LPAREN: {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003369 int pos;
3370 if (scanner().current_token() == Token::IDENTIFIER) {
3371 // For call of an identifier we want to report position of
3372 // the identifier as position of the call in the stack trace.
3373 pos = scanner().location().beg_pos;
3374 } else {
3375 // For other kinds of calls we record position of the parenthesis as
3376 // position of the call. Note that this is extremely important for
3377 // expressions of the form function(){...}() for which call position
3378 // should not point to the closing brace otherwise it will intersect
3379 // with positions recorded for function literal and confuse debugger.
3380 pos = scanner().peek_location().beg_pos;
3381 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003382 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
3383
3384 // Keep track of eval() calls since they disable all local variable
3385 // optimizations.
3386 // The calls that need special treatment are the
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003387 // direct eval calls. These calls are all of the form eval(...), with
3388 // no explicit receiver.
Ben Murdochb8e0da22011-05-16 14:20:40 +01003389 // These calls are marked as potentially direct eval calls. Whether
3390 // they are actually direct calls to eval is determined at run time.
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003391 VariableProxy* callee = result->AsVariableProxy();
Steve Block44f0eee2011-05-26 01:26:41 +01003392 if (callee != NULL &&
3393 callee->IsVariable(isolate()->factory()->eval_symbol())) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003394 top_scope_->DeclarationScope()->RecordEvalCall();
Steve Blocka7e24c12009-10-30 11:49:00 +00003395 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003396 result = factory()->NewCall(result, args, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00003397 break;
3398 }
3399
3400 case Token::PERIOD: {
3401 Consume(Token::PERIOD);
3402 int pos = scanner().location().beg_pos;
Ben Murdochbb769b22010-08-11 14:56:33 +01003403 Handle<String> name = ParseIdentifierName(CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003404 result =
3405 factory()->NewProperty(result, factory()->NewLiteral(name), pos);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003406 if (fni_ != NULL) fni_->PushLiteralName(name);
Steve Blocka7e24c12009-10-30 11:49:00 +00003407 break;
3408 }
3409
3410 default:
3411 return result;
3412 }
3413 }
3414}
3415
3416
Steve Blocka7e24c12009-10-30 11:49:00 +00003417Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) {
3418 // NewExpression ::
3419 // ('new')+ MemberExpression
3420
3421 // The grammar for new expressions is pretty warped. The keyword
3422 // 'new' can either be a part of the new expression (where it isn't
3423 // followed by an argument list) or a part of the member expression,
3424 // where it must be followed by an argument list. To accommodate
3425 // this, we parse the 'new' keywords greedily and keep track of how
3426 // many we have parsed. This information is then passed on to the
3427 // member expression parser, which is only allowed to match argument
3428 // lists as long as it has 'new' prefixes left
3429 Expect(Token::NEW, CHECK_OK);
3430 PositionStack::Element pos(stack, scanner().location().beg_pos);
3431
3432 Expression* result;
3433 if (peek() == Token::NEW) {
3434 result = ParseNewPrefix(stack, CHECK_OK);
3435 } else {
3436 result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK);
3437 }
3438
3439 if (!stack->is_empty()) {
3440 int last = stack->pop();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003441 result = factory()->NewCallNew(
3442 result, new(zone()) ZoneList<Expression*>(0), last);
Steve Blocka7e24c12009-10-30 11:49:00 +00003443 }
3444 return result;
3445}
3446
3447
3448Expression* Parser::ParseNewExpression(bool* ok) {
3449 PositionStack stack(ok);
3450 return ParseNewPrefix(&stack, ok);
3451}
3452
3453
3454Expression* Parser::ParseMemberExpression(bool* ok) {
3455 return ParseMemberWithNewPrefixesExpression(NULL, ok);
3456}
3457
3458
3459Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
3460 bool* ok) {
3461 // MemberExpression ::
3462 // (PrimaryExpression | FunctionLiteral)
3463 // ('[' Expression ']' | '.' Identifier | Arguments)*
3464
3465 // Parse the initial primary or function expression.
3466 Expression* result = NULL;
3467 if (peek() == Token::FUNCTION) {
3468 Expect(Token::FUNCTION, CHECK_OK);
3469 int function_token_position = scanner().location().beg_pos;
3470 Handle<String> name;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003471 bool is_strict_reserved_name = false;
Steve Block1e0659c2011-05-24 12:43:12 +01003472 if (peek_any_identifier()) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003473 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
3474 CHECK_OK);
Steve Block1e0659c2011-05-24 12:43:12 +01003475 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003476 FunctionLiteral::Type type = name.is_null()
3477 ? FunctionLiteral::ANONYMOUS_EXPRESSION
3478 : FunctionLiteral::NAMED_EXPRESSION;
3479 result = ParseFunctionLiteral(name,
3480 is_strict_reserved_name,
3481 function_token_position,
3482 type,
3483 CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00003484 } else {
3485 result = ParsePrimaryExpression(CHECK_OK);
3486 }
3487
3488 while (true) {
3489 switch (peek()) {
3490 case Token::LBRACK: {
3491 Consume(Token::LBRACK);
3492 int pos = scanner().location().beg_pos;
3493 Expression* index = ParseExpression(true, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003494 result = factory()->NewProperty(result, index, pos);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003495 if (fni_ != NULL) {
3496 if (index->IsPropertyName()) {
3497 fni_->PushLiteralName(index->AsLiteral()->AsPropertyName());
3498 } else {
3499 fni_->PushLiteralName(
3500 isolate()->factory()->anonymous_function_symbol());
3501 }
3502 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003503 Expect(Token::RBRACK, CHECK_OK);
3504 break;
3505 }
3506 case Token::PERIOD: {
3507 Consume(Token::PERIOD);
3508 int pos = scanner().location().beg_pos;
Ben Murdochbb769b22010-08-11 14:56:33 +01003509 Handle<String> name = ParseIdentifierName(CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003510 result =
3511 factory()->NewProperty(result, factory()->NewLiteral(name), pos);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003512 if (fni_ != NULL) fni_->PushLiteralName(name);
Steve Blocka7e24c12009-10-30 11:49:00 +00003513 break;
3514 }
3515 case Token::LPAREN: {
3516 if ((stack == NULL) || stack->is_empty()) return result;
3517 // Consume one of the new prefixes (already parsed).
3518 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
3519 int last = stack->pop();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003520 result = factory()->NewCallNew(result, args, last);
Steve Blocka7e24c12009-10-30 11:49:00 +00003521 break;
3522 }
3523 default:
3524 return result;
3525 }
3526 }
3527}
3528
3529
3530DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
3531 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
3532 // contexts this is used as a statement which invokes the debugger as i a
3533 // break point is present.
3534 // DebuggerStatement ::
3535 // 'debugger' ';'
3536
3537 Expect(Token::DEBUGGER, CHECK_OK);
3538 ExpectSemicolon(CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003539 return factory()->NewDebuggerStatement();
Steve Blocka7e24c12009-10-30 11:49:00 +00003540}
3541
3542
3543void Parser::ReportUnexpectedToken(Token::Value token) {
3544 // We don't report stack overflows here, to avoid increasing the
3545 // stack depth even further. Instead we report it after parsing is
Leon Clarke4515c472010-02-03 11:58:03 +00003546 // over, in ParseProgram/ParseJson.
Ben Murdochb0fe1622011-05-05 13:52:32 +01003547 if (token == Token::ILLEGAL && stack_overflow_) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00003548 // Four of the tokens are treated specially
3549 switch (token) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01003550 case Token::EOS:
3551 return ReportMessage("unexpected_eos", Vector<const char*>::empty());
3552 case Token::NUMBER:
3553 return ReportMessage("unexpected_token_number",
3554 Vector<const char*>::empty());
3555 case Token::STRING:
3556 return ReportMessage("unexpected_token_string",
3557 Vector<const char*>::empty());
3558 case Token::IDENTIFIER:
3559 return ReportMessage("unexpected_token_identifier",
3560 Vector<const char*>::empty());
Steve Block1e0659c2011-05-24 12:43:12 +01003561 case Token::FUTURE_RESERVED_WORD:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003562 return ReportMessage("unexpected_reserved",
3563 Vector<const char*>::empty());
3564 case Token::FUTURE_STRICT_RESERVED_WORD:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003565 return ReportMessage(top_scope_->is_classic_mode() ?
3566 "unexpected_token_identifier" :
3567 "unexpected_strict_reserved",
Steve Block1e0659c2011-05-24 12:43:12 +01003568 Vector<const char*>::empty());
Ben Murdochb0fe1622011-05-05 13:52:32 +01003569 default:
3570 const char* name = Token::String(token);
3571 ASSERT(name != NULL);
3572 ReportMessage("unexpected_token", Vector<const char*>(&name, 1));
Steve Blocka7e24c12009-10-30 11:49:00 +00003573 }
3574}
3575
3576
Leon Clarkeac952652010-07-15 11:15:24 +01003577void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) {
Ben Murdoch589d6972011-11-30 16:04:58 +00003578 SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS);
Leon Clarkeac952652010-07-15 11:15:24 +01003579 const char* element[1] = { *name_string };
3580 ReportMessage("invalid_preparser_data",
3581 Vector<const char*>(element, 1));
3582 *ok = false;
3583}
3584
3585
Steve Blocka7e24c12009-10-30 11:49:00 +00003586Expression* Parser::ParsePrimaryExpression(bool* ok) {
3587 // PrimaryExpression ::
3588 // 'this'
3589 // 'null'
3590 // 'true'
3591 // 'false'
3592 // Identifier
3593 // Number
3594 // String
3595 // ArrayLiteral
3596 // ObjectLiteral
3597 // RegExpLiteral
3598 // '(' Expression ')'
3599
3600 Expression* result = NULL;
3601 switch (peek()) {
3602 case Token::THIS: {
3603 Consume(Token::THIS);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003604 result = factory()->NewVariableProxy(top_scope_->receiver());
Steve Blocka7e24c12009-10-30 11:49:00 +00003605 break;
3606 }
3607
3608 case Token::NULL_LITERAL:
3609 Consume(Token::NULL_LITERAL);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003610 result = factory()->NewLiteral(isolate()->factory()->null_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00003611 break;
3612
3613 case Token::TRUE_LITERAL:
3614 Consume(Token::TRUE_LITERAL);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003615 result = factory()->NewLiteral(isolate()->factory()->true_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00003616 break;
3617
3618 case Token::FALSE_LITERAL:
3619 Consume(Token::FALSE_LITERAL);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003620 result = factory()->NewLiteral(isolate()->factory()->false_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00003621 break;
3622
Steve Block1e0659c2011-05-24 12:43:12 +01003623 case Token::IDENTIFIER:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003624 case Token::FUTURE_STRICT_RESERVED_WORD: {
Steve Blocka7e24c12009-10-30 11:49:00 +00003625 Handle<String> name = ParseIdentifier(CHECK_OK);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003626 if (fni_ != NULL) fni_->PushVariableName(name);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003627 // The name may refer to a module instance object, so its type is unknown.
3628#ifdef DEBUG
3629 if (FLAG_print_interface_details)
3630 PrintF("# Variable %s ", name->ToAsciiArray());
3631#endif
3632 Interface* interface = Interface::NewUnknown();
3633 result = top_scope_->NewUnresolved(
3634 factory(), name, scanner().location().beg_pos, interface);
Steve Blocka7e24c12009-10-30 11:49:00 +00003635 break;
3636 }
3637
3638 case Token::NUMBER: {
3639 Consume(Token::NUMBER);
Steve Block9fac8402011-05-12 15:51:54 +01003640 ASSERT(scanner().is_literal_ascii());
Ben Murdoch8b112d22011-06-08 16:22:53 +01003641 double value = StringToDouble(isolate()->unicode_cache(),
3642 scanner().literal_ascii_string(),
Steve Block9fac8402011-05-12 15:51:54 +01003643 ALLOW_HEX | ALLOW_OCTALS);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003644 result = factory()->NewNumberLiteral(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003645 break;
3646 }
3647
3648 case Token::STRING: {
3649 Consume(Token::STRING);
Iain Merrick9ac36c92010-09-13 15:29:50 +01003650 Handle<String> symbol = GetSymbol(CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003651 result = factory()->NewLiteral(symbol);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003652 if (fni_ != NULL) fni_->PushLiteralName(symbol);
Steve Blocka7e24c12009-10-30 11:49:00 +00003653 break;
3654 }
3655
3656 case Token::ASSIGN_DIV:
3657 result = ParseRegExpLiteral(true, CHECK_OK);
3658 break;
3659
3660 case Token::DIV:
3661 result = ParseRegExpLiteral(false, CHECK_OK);
3662 break;
3663
3664 case Token::LBRACK:
3665 result = ParseArrayLiteral(CHECK_OK);
3666 break;
3667
3668 case Token::LBRACE:
3669 result = ParseObjectLiteral(CHECK_OK);
3670 break;
3671
3672 case Token::LPAREN:
3673 Consume(Token::LPAREN);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003674 // Heuristically try to detect immediately called functions before
3675 // seeing the call parentheses.
3676 parenthesized_function_ = (peek() == Token::FUNCTION);
Steve Blocka7e24c12009-10-30 11:49:00 +00003677 result = ParseExpression(true, CHECK_OK);
3678 Expect(Token::RPAREN, CHECK_OK);
3679 break;
3680
3681 case Token::MOD:
3682 if (allow_natives_syntax_ || extension_ != NULL) {
3683 result = ParseV8Intrinsic(CHECK_OK);
3684 break;
3685 }
3686 // If we're not allowing special syntax we fall-through to the
3687 // default case.
3688
3689 default: {
Ben Murdochbb769b22010-08-11 14:56:33 +01003690 Token::Value tok = Next();
Steve Blocka7e24c12009-10-30 11:49:00 +00003691 ReportUnexpectedToken(tok);
3692 *ok = false;
3693 return NULL;
3694 }
3695 }
3696
3697 return result;
3698}
3699
3700
Leon Clarke4515c472010-02-03 11:58:03 +00003701void Parser::BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* values,
3702 Handle<FixedArray> literals,
3703 bool* is_simple,
3704 int* depth) {
3705 // Fill in the literals.
3706 // Accumulate output values in local variables.
3707 bool is_simple_acc = true;
3708 int depth_acc = 1;
3709 for (int i = 0; i < values->length(); i++) {
3710 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral();
3711 if (m_literal != NULL && m_literal->depth() >= depth_acc) {
3712 depth_acc = m_literal->depth() + 1;
3713 }
3714 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i));
3715 if (boilerplate_value->IsUndefined()) {
3716 literals->set_the_hole(i);
3717 is_simple_acc = false;
3718 } else {
3719 literals->set(i, *boilerplate_value);
3720 }
3721 }
3722
3723 *is_simple = is_simple_acc;
3724 *depth = depth_acc;
3725}
3726
3727
Steve Blocka7e24c12009-10-30 11:49:00 +00003728Expression* Parser::ParseArrayLiteral(bool* ok) {
3729 // ArrayLiteral ::
3730 // '[' Expression? (',' Expression?)* ']'
3731
Ben Murdoch257744e2011-11-30 15:57:28 +00003732 ZoneList<Expression*>* values = new(zone()) ZoneList<Expression*>(4);
Steve Blocka7e24c12009-10-30 11:49:00 +00003733 Expect(Token::LBRACK, CHECK_OK);
3734 while (peek() != Token::RBRACK) {
3735 Expression* elem;
3736 if (peek() == Token::COMMA) {
3737 elem = GetLiteralTheHole();
3738 } else {
3739 elem = ParseAssignmentExpression(true, CHECK_OK);
3740 }
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003741 values->Add(elem);
Steve Blocka7e24c12009-10-30 11:49:00 +00003742 if (peek() != Token::RBRACK) {
3743 Expect(Token::COMMA, CHECK_OK);
3744 }
3745 }
3746 Expect(Token::RBRACK, CHECK_OK);
3747
3748 // Update the scope information before the pre-parsing bailout.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003749 int literal_index = current_function_state_->NextMaterializedLiteralIndex();
Steve Blocka7e24c12009-10-30 11:49:00 +00003750
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003751 // Allocate a fixed array to hold all the object literals.
3752 Handle<FixedArray> object_literals =
Steve Block44f0eee2011-05-26 01:26:41 +01003753 isolate()->factory()->NewFixedArray(values->length(), TENURED);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003754 Handle<FixedDoubleArray> double_literals;
3755 ElementsKind elements_kind = FAST_SMI_ONLY_ELEMENTS;
3756 bool has_only_undefined_values = true;
Steve Blocka7e24c12009-10-30 11:49:00 +00003757
3758 // Fill in the literals.
3759 bool is_simple = true;
3760 int depth = 1;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003761 for (int i = 0, n = values->length(); i < n; i++) {
3762 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral();
Steve Blocka7e24c12009-10-30 11:49:00 +00003763 if (m_literal != NULL && m_literal->depth() + 1 > depth) {
3764 depth = m_literal->depth() + 1;
3765 }
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003766 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i));
Steve Blocka7e24c12009-10-30 11:49:00 +00003767 if (boilerplate_value->IsUndefined()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003768 object_literals->set_the_hole(i);
3769 if (elements_kind == FAST_DOUBLE_ELEMENTS) {
3770 double_literals->set_the_hole(i);
3771 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003772 is_simple = false;
3773 } else {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003774 // Examine each literal element, and adjust the ElementsKind if the
3775 // literal element is not of a type that can be stored in the current
3776 // ElementsKind. Start with FAST_SMI_ONLY_ELEMENTS, and transition to
3777 // FAST_DOUBLE_ELEMENTS and FAST_ELEMENTS as necessary. Always remember
3778 // the tagged value, no matter what the ElementsKind is in case we
3779 // ultimately end up in FAST_ELEMENTS.
3780 has_only_undefined_values = false;
3781 object_literals->set(i, *boilerplate_value);
3782 if (elements_kind == FAST_SMI_ONLY_ELEMENTS) {
3783 // Smi only elements. Notice if a transition to FAST_DOUBLE_ELEMENTS or
3784 // FAST_ELEMENTS is required.
3785 if (!boilerplate_value->IsSmi()) {
3786 if (boilerplate_value->IsNumber() && FLAG_smi_only_arrays) {
3787 // Allocate a double array on the FAST_DOUBLE_ELEMENTS transition to
3788 // avoid over-allocating in TENURED space.
3789 double_literals = isolate()->factory()->NewFixedDoubleArray(
3790 values->length(), TENURED);
3791 // Copy the contents of the FAST_SMI_ONLY_ELEMENT array to the
3792 // FAST_DOUBLE_ELEMENTS array so that they are in sync.
3793 for (int j = 0; j < i; ++j) {
3794 Object* smi_value = object_literals->get(j);
3795 if (smi_value->IsTheHole()) {
3796 double_literals->set_the_hole(j);
3797 } else {
3798 double_literals->set(j, Smi::cast(smi_value)->value());
3799 }
3800 }
3801 double_literals->set(i, boilerplate_value->Number());
3802 elements_kind = FAST_DOUBLE_ELEMENTS;
3803 } else {
3804 elements_kind = FAST_ELEMENTS;
3805 }
3806 }
3807 } else if (elements_kind == FAST_DOUBLE_ELEMENTS) {
3808 // Continue to store double values in to FAST_DOUBLE_ELEMENTS arrays
3809 // until the first value is seen that can't be stored as a double.
3810 if (boilerplate_value->IsNumber()) {
3811 double_literals->set(i, boilerplate_value->Number());
3812 } else {
3813 elements_kind = FAST_ELEMENTS;
3814 }
3815 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003816 }
3817 }
3818
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003819 // Very small array literals that don't have a concrete hint about their type
3820 // from a constant value should default to the slow case to avoid lots of
3821 // elements transitions on really small objects.
3822 if (has_only_undefined_values && values->length() <= 2) {
3823 elements_kind = FAST_ELEMENTS;
3824 }
3825
Iain Merrick75681382010-08-19 15:07:18 +01003826 // Simple and shallow arrays can be lazily copied, we transform the
3827 // elements array to a copy-on-write array.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003828 if (is_simple && depth == 1 && values->length() > 0 &&
3829 elements_kind != FAST_DOUBLE_ELEMENTS) {
3830 object_literals->set_map(isolate()->heap()->fixed_cow_array_map());
Iain Merrick75681382010-08-19 15:07:18 +01003831 }
3832
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003833 Handle<FixedArrayBase> element_values = elements_kind == FAST_DOUBLE_ELEMENTS
3834 ? Handle<FixedArrayBase>(double_literals)
3835 : Handle<FixedArrayBase>(object_literals);
3836
3837 // Remember both the literal's constant values as well as the ElementsKind
3838 // in a 2-element FixedArray.
3839 Handle<FixedArray> literals =
3840 isolate()->factory()->NewFixedArray(2, TENURED);
3841
3842 literals->set(0, Smi::FromInt(elements_kind));
3843 literals->set(1, *element_values);
3844
3845 return factory()->NewArrayLiteral(
3846 literals, values, literal_index, is_simple, depth);
Steve Blocka7e24c12009-10-30 11:49:00 +00003847}
3848
3849
3850bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) {
3851 return property != NULL &&
3852 property->kind() != ObjectLiteral::Property::PROTOTYPE;
3853}
3854
3855
3856bool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01003857 if (expression->AsLiteral() != NULL) return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00003858 MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3859 return lit != NULL && lit->is_simple();
3860}
3861
Iain Merrick75681382010-08-19 15:07:18 +01003862
3863bool CompileTimeValue::ArrayLiteralElementNeedsInitialization(
3864 Expression* value) {
3865 // If value is a literal the property value is already set in the
3866 // boilerplate object.
3867 if (value->AsLiteral() != NULL) return false;
3868 // If value is a materialized literal the property value is already set
3869 // in the boilerplate object if it is simple.
3870 if (CompileTimeValue::IsCompileTimeValue(value)) return false;
3871 return true;
3872}
3873
3874
Steve Blocka7e24c12009-10-30 11:49:00 +00003875Handle<FixedArray> CompileTimeValue::GetValue(Expression* expression) {
3876 ASSERT(IsCompileTimeValue(expression));
Steve Block44f0eee2011-05-26 01:26:41 +01003877 Handle<FixedArray> result = FACTORY->NewFixedArray(2, TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00003878 ObjectLiteral* object_literal = expression->AsObjectLiteral();
3879 if (object_literal != NULL) {
3880 ASSERT(object_literal->is_simple());
Steve Block6ded16b2010-05-10 14:33:55 +01003881 if (object_literal->fast_elements()) {
3882 result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
3883 } else {
3884 result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
3885 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003886 result->set(kElementsSlot, *object_literal->constant_properties());
3887 } else {
3888 ArrayLiteral* array_literal = expression->AsArrayLiteral();
3889 ASSERT(array_literal != NULL && array_literal->is_simple());
3890 result->set(kTypeSlot, Smi::FromInt(ARRAY_LITERAL));
Leon Clarkee46be812010-01-19 14:06:41 +00003891 result->set(kElementsSlot, *array_literal->constant_elements());
Steve Blocka7e24c12009-10-30 11:49:00 +00003892 }
3893 return result;
3894}
3895
3896
3897CompileTimeValue::Type CompileTimeValue::GetType(Handle<FixedArray> value) {
3898 Smi* type_value = Smi::cast(value->get(kTypeSlot));
3899 return static_cast<Type>(type_value->value());
3900}
3901
3902
3903Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
3904 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
3905}
3906
3907
3908Handle<Object> Parser::GetBoilerplateValue(Expression* expression) {
3909 if (expression->AsLiteral() != NULL) {
3910 return expression->AsLiteral()->handle();
3911 }
3912 if (CompileTimeValue::IsCompileTimeValue(expression)) {
3913 return CompileTimeValue::GetValue(expression);
3914 }
Steve Block44f0eee2011-05-26 01:26:41 +01003915 return isolate()->factory()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00003916}
3917
Steve Block1e0659c2011-05-24 12:43:12 +01003918// Validation per 11.1.5 Object Initialiser
3919class ObjectLiteralPropertyChecker {
3920 public:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003921 ObjectLiteralPropertyChecker(Parser* parser, LanguageMode language_mode) :
3922 props_(Literal::Match),
Steve Block1e0659c2011-05-24 12:43:12 +01003923 parser_(parser),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003924 language_mode_(language_mode) {
Steve Block1e0659c2011-05-24 12:43:12 +01003925 }
3926
3927 void CheckProperty(
3928 ObjectLiteral::Property* property,
3929 Scanner::Location loc,
3930 bool* ok);
3931
3932 private:
3933 enum PropertyKind {
3934 kGetAccessor = 0x01,
3935 kSetAccessor = 0x02,
3936 kAccessor = kGetAccessor | kSetAccessor,
3937 kData = 0x04
3938 };
3939
3940 static intptr_t GetPropertyKind(ObjectLiteral::Property* property) {
3941 switch (property->kind()) {
3942 case ObjectLiteral::Property::GETTER:
3943 return kGetAccessor;
3944 case ObjectLiteral::Property::SETTER:
3945 return kSetAccessor;
3946 default:
3947 return kData;
3948 }
3949 }
3950
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003951 HashMap props_;
Steve Block1e0659c2011-05-24 12:43:12 +01003952 Parser* parser_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003953 LanguageMode language_mode_;
Steve Block1e0659c2011-05-24 12:43:12 +01003954};
3955
3956
3957void ObjectLiteralPropertyChecker::CheckProperty(
3958 ObjectLiteral::Property* property,
3959 Scanner::Location loc,
3960 bool* ok) {
Steve Block1e0659c2011-05-24 12:43:12 +01003961 ASSERT(property != NULL);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003962 Literal* literal = property->key();
3963 HashMap::Entry* entry = props_.Lookup(literal, literal->Hash(), true);
Steve Block1e0659c2011-05-24 12:43:12 +01003964 intptr_t prev = reinterpret_cast<intptr_t> (entry->value);
3965 intptr_t curr = GetPropertyKind(property);
3966
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003967 // Duplicate data properties are illegal in strict or extended mode.
3968 if (language_mode_ != CLASSIC_MODE && (curr & prev & kData) != 0) {
Steve Block1e0659c2011-05-24 12:43:12 +01003969 parser_->ReportMessageAt(loc, "strict_duplicate_property",
3970 Vector<const char*>::empty());
3971 *ok = false;
3972 return;
3973 }
3974 // Data property conflicting with an accessor.
3975 if (((curr & kData) && (prev & kAccessor)) ||
3976 ((prev & kData) && (curr & kAccessor))) {
3977 parser_->ReportMessageAt(loc, "accessor_data_property",
3978 Vector<const char*>::empty());
3979 *ok = false;
3980 return;
3981 }
3982 // Two accessors of the same type conflicting
3983 if ((curr & prev & kAccessor) != 0) {
3984 parser_->ReportMessageAt(loc, "accessor_get_set",
3985 Vector<const char*>::empty());
3986 *ok = false;
3987 return;
3988 }
3989
3990 // Update map
3991 entry->value = reinterpret_cast<void*> (prev | curr);
3992 *ok = true;
3993}
3994
Steve Blocka7e24c12009-10-30 11:49:00 +00003995
Leon Clarke4515c472010-02-03 11:58:03 +00003996void Parser::BuildObjectLiteralConstantProperties(
3997 ZoneList<ObjectLiteral::Property*>* properties,
3998 Handle<FixedArray> constant_properties,
3999 bool* is_simple,
Steve Block6ded16b2010-05-10 14:33:55 +01004000 bool* fast_elements,
Leon Clarke4515c472010-02-03 11:58:03 +00004001 int* depth) {
4002 int position = 0;
4003 // Accumulate the value in local variables and store it at the end.
4004 bool is_simple_acc = true;
4005 int depth_acc = 1;
Steve Block6ded16b2010-05-10 14:33:55 +01004006 uint32_t max_element_index = 0;
4007 uint32_t elements = 0;
Leon Clarke4515c472010-02-03 11:58:03 +00004008 for (int i = 0; i < properties->length(); i++) {
4009 ObjectLiteral::Property* property = properties->at(i);
4010 if (!IsBoilerplateProperty(property)) {
4011 is_simple_acc = false;
4012 continue;
4013 }
4014 MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral();
4015 if (m_literal != NULL && m_literal->depth() >= depth_acc) {
4016 depth_acc = m_literal->depth() + 1;
4017 }
4018
4019 // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined
4020 // value for COMPUTED properties, the real value is filled in at
4021 // runtime. The enumeration order is maintained.
4022 Handle<Object> key = property->key()->handle();
4023 Handle<Object> value = GetBoilerplateValue(property->value());
4024 is_simple_acc = is_simple_acc && !value->IsUndefined();
4025
Steve Block6ded16b2010-05-10 14:33:55 +01004026 // Keep track of the number of elements in the object literal and
4027 // the largest element index. If the largest element index is
4028 // much larger than the number of elements, creating an object
4029 // literal with fast elements will be a waste of space.
4030 uint32_t element_index = 0;
4031 if (key->IsString()
4032 && Handle<String>::cast(key)->AsArrayIndex(&element_index)
4033 && element_index > max_element_index) {
4034 max_element_index = element_index;
4035 elements++;
4036 } else if (key->IsSmi()) {
4037 int key_value = Smi::cast(*key)->value();
4038 if (key_value > 0
4039 && static_cast<uint32_t>(key_value) > max_element_index) {
4040 max_element_index = key_value;
4041 }
4042 elements++;
4043 }
4044
Leon Clarke4515c472010-02-03 11:58:03 +00004045 // Add name, value pair to the fixed array.
4046 constant_properties->set(position++, *key);
4047 constant_properties->set(position++, *value);
4048 }
Steve Block6ded16b2010-05-10 14:33:55 +01004049 *fast_elements =
4050 (max_element_index <= 32) || ((2 * elements) >= max_element_index);
Leon Clarke4515c472010-02-03 11:58:03 +00004051 *is_simple = is_simple_acc;
4052 *depth = depth_acc;
4053}
4054
4055
Ben Murdochbb769b22010-08-11 14:56:33 +01004056ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
4057 bool* ok) {
4058 // Special handling of getter and setter syntax:
4059 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
4060 // We have already read the "get" or "set" keyword.
4061 Token::Value next = Next();
Steve Block9fac8402011-05-12 15:51:54 +01004062 bool is_keyword = Token::IsKeyword(next);
4063 if (next == Token::IDENTIFIER || next == Token::NUMBER ||
Steve Block1e0659c2011-05-24 12:43:12 +01004064 next == Token::FUTURE_RESERVED_WORD ||
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004065 next == Token::FUTURE_STRICT_RESERVED_WORD ||
Steve Block9fac8402011-05-12 15:51:54 +01004066 next == Token::STRING || is_keyword) {
4067 Handle<String> name;
4068 if (is_keyword) {
Steve Block44f0eee2011-05-26 01:26:41 +01004069 name = isolate_->factory()->LookupAsciiSymbol(Token::String(next));
Steve Block9fac8402011-05-12 15:51:54 +01004070 } else {
4071 name = GetSymbol(CHECK_OK);
4072 }
Ben Murdochbb769b22010-08-11 14:56:33 +01004073 FunctionLiteral* value =
4074 ParseFunctionLiteral(name,
Steve Block1e0659c2011-05-24 12:43:12 +01004075 false, // reserved words are allowed here
Ben Murdochbb769b22010-08-11 14:56:33 +01004076 RelocInfo::kNoPosition,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004077 FunctionLiteral::ANONYMOUS_EXPRESSION,
Ben Murdochbb769b22010-08-11 14:56:33 +01004078 CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004079 // Allow any number of parameters for compatibilty with JSC.
Steve Block9fac8402011-05-12 15:51:54 +01004080 // Specification only allows zero parameters for get and one for set.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004081 return factory()->NewObjectLiteralProperty(is_getter, value);
Ben Murdochbb769b22010-08-11 14:56:33 +01004082 } else {
4083 ReportUnexpectedToken(next);
4084 *ok = false;
4085 return NULL;
4086 }
4087}
4088
4089
Steve Blocka7e24c12009-10-30 11:49:00 +00004090Expression* Parser::ParseObjectLiteral(bool* ok) {
4091 // ObjectLiteral ::
4092 // '{' (
Ben Murdochbb769b22010-08-11 14:56:33 +01004093 // ((IdentifierName | String | Number) ':' AssignmentExpression)
4094 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +00004095 // )*[','] '}'
4096
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08004097 ZoneList<ObjectLiteral::Property*>* properties =
Ben Murdoch257744e2011-11-30 15:57:28 +00004098 new(zone()) ZoneList<ObjectLiteral::Property*>(4);
Steve Blocka7e24c12009-10-30 11:49:00 +00004099 int number_of_boilerplate_properties = 0;
Steve Block44f0eee2011-05-26 01:26:41 +01004100 bool has_function = false;
Steve Blocka7e24c12009-10-30 11:49:00 +00004101
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004102 ObjectLiteralPropertyChecker checker(this, top_scope_->language_mode());
Steve Block1e0659c2011-05-24 12:43:12 +01004103
Steve Blocka7e24c12009-10-30 11:49:00 +00004104 Expect(Token::LBRACE, CHECK_OK);
Steve Block1e0659c2011-05-24 12:43:12 +01004105
Steve Blocka7e24c12009-10-30 11:49:00 +00004106 while (peek() != Token::RBRACE) {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004107 if (fni_ != NULL) fni_->Enter();
4108
Steve Blocka7e24c12009-10-30 11:49:00 +00004109 Literal* key = NULL;
Ben Murdochbb769b22010-08-11 14:56:33 +01004110 Token::Value next = peek();
Steve Block1e0659c2011-05-24 12:43:12 +01004111
4112 // Location of the property name token
4113 Scanner::Location loc = scanner().peek_location();
4114
Ben Murdochbb769b22010-08-11 14:56:33 +01004115 switch (next) {
Steve Block1e0659c2011-05-24 12:43:12 +01004116 case Token::FUTURE_RESERVED_WORD:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004117 case Token::FUTURE_STRICT_RESERVED_WORD:
Steve Blocka7e24c12009-10-30 11:49:00 +00004118 case Token::IDENTIFIER: {
Steve Blocka7e24c12009-10-30 11:49:00 +00004119 bool is_getter = false;
4120 bool is_setter = false;
4121 Handle<String> id =
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004122 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004123 if (fni_ != NULL) fni_->PushLiteralName(id);
4124
Ben Murdochbb769b22010-08-11 14:56:33 +01004125 if ((is_getter || is_setter) && peek() != Token::COLON) {
Steve Block1e0659c2011-05-24 12:43:12 +01004126 // Update loc to point to the identifier
4127 loc = scanner().peek_location();
Steve Blocka7e24c12009-10-30 11:49:00 +00004128 ObjectLiteral::Property* property =
Ben Murdochbb769b22010-08-11 14:56:33 +01004129 ParseObjectLiteralGetSet(is_getter, CHECK_OK);
4130 if (IsBoilerplateProperty(property)) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004131 number_of_boilerplate_properties++;
Ben Murdochbb769b22010-08-11 14:56:33 +01004132 }
Steve Block1e0659c2011-05-24 12:43:12 +01004133 // Validate the property.
4134 checker.CheckProperty(property, loc, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08004135 properties->Add(property);
Steve Blocka7e24c12009-10-30 11:49:00 +00004136 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004137
4138 if (fni_ != NULL) {
4139 fni_->Infer();
4140 fni_->Leave();
4141 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004142 continue; // restart the while
Steve Blocka7e24c12009-10-30 11:49:00 +00004143 }
Ben Murdochbb769b22010-08-11 14:56:33 +01004144 // Failed to parse as get/set property, so it's just a property
4145 // called "get" or "set".
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004146 key = factory()->NewLiteral(id);
Steve Blocka7e24c12009-10-30 11:49:00 +00004147 break;
4148 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004149 case Token::STRING: {
4150 Consume(Token::STRING);
Iain Merrick9ac36c92010-09-13 15:29:50 +01004151 Handle<String> string = GetSymbol(CHECK_OK);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004152 if (fni_ != NULL) fni_->PushLiteralName(string);
Steve Blocka7e24c12009-10-30 11:49:00 +00004153 uint32_t index;
Iain Merrick75681382010-08-19 15:07:18 +01004154 if (!string.is_null() && string->AsArrayIndex(&index)) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004155 key = factory()->NewNumberLiteral(index);
Ben Murdochbb769b22010-08-11 14:56:33 +01004156 break;
Steve Blocka7e24c12009-10-30 11:49:00 +00004157 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004158 key = factory()->NewLiteral(string);
Steve Blocka7e24c12009-10-30 11:49:00 +00004159 break;
4160 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004161 case Token::NUMBER: {
4162 Consume(Token::NUMBER);
Steve Block9fac8402011-05-12 15:51:54 +01004163 ASSERT(scanner().is_literal_ascii());
Ben Murdoch8b112d22011-06-08 16:22:53 +01004164 double value = StringToDouble(isolate()->unicode_cache(),
4165 scanner().literal_ascii_string(),
Steve Block9fac8402011-05-12 15:51:54 +01004166 ALLOW_HEX | ALLOW_OCTALS);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004167 key = factory()->NewNumberLiteral(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004168 break;
4169 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004170 default:
Ben Murdochbb769b22010-08-11 14:56:33 +01004171 if (Token::IsKeyword(next)) {
4172 Consume(next);
Iain Merrick9ac36c92010-09-13 15:29:50 +01004173 Handle<String> string = GetSymbol(CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004174 key = factory()->NewLiteral(string);
Ben Murdochbb769b22010-08-11 14:56:33 +01004175 } else {
4176 // Unexpected token.
4177 Token::Value next = Next();
4178 ReportUnexpectedToken(next);
4179 *ok = false;
4180 return NULL;
4181 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004182 }
4183
4184 Expect(Token::COLON, CHECK_OK);
4185 Expression* value = ParseAssignmentExpression(true, CHECK_OK);
4186
4187 ObjectLiteral::Property* property =
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004188 new(zone()) ObjectLiteral::Property(key, value, isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00004189
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004190 // Mark top-level object literals that contain function literals and
4191 // pretenure the literal so it can be added as a constant function
4192 // property.
4193 if (top_scope_->DeclarationScope()->is_global_scope() &&
4194 value->AsFunctionLiteral() != NULL) {
Steve Block44f0eee2011-05-26 01:26:41 +01004195 has_function = true;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004196 value->AsFunctionLiteral()->set_pretenure();
Steve Block44f0eee2011-05-26 01:26:41 +01004197 }
4198
Steve Blocka7e24c12009-10-30 11:49:00 +00004199 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
4200 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++;
Steve Block1e0659c2011-05-24 12:43:12 +01004201 // Validate the property
4202 checker.CheckProperty(property, loc, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08004203 properties->Add(property);
Steve Blocka7e24c12009-10-30 11:49:00 +00004204
4205 // TODO(1240767): Consider allowing trailing comma.
4206 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004207
4208 if (fni_ != NULL) {
4209 fni_->Infer();
4210 fni_->Leave();
4211 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004212 }
4213 Expect(Token::RBRACE, CHECK_OK);
Steve Block1e0659c2011-05-24 12:43:12 +01004214
Steve Blocka7e24c12009-10-30 11:49:00 +00004215 // Computation of literal_index must happen before pre parse bailout.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004216 int literal_index = current_function_state_->NextMaterializedLiteralIndex();
Steve Blocka7e24c12009-10-30 11:49:00 +00004217
Steve Block44f0eee2011-05-26 01:26:41 +01004218 Handle<FixedArray> constant_properties = isolate()->factory()->NewFixedArray(
4219 number_of_boilerplate_properties * 2, TENURED);
Leon Clarke4515c472010-02-03 11:58:03 +00004220
Steve Blocka7e24c12009-10-30 11:49:00 +00004221 bool is_simple = true;
Steve Block6ded16b2010-05-10 14:33:55 +01004222 bool fast_elements = true;
Steve Blocka7e24c12009-10-30 11:49:00 +00004223 int depth = 1;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08004224 BuildObjectLiteralConstantProperties(properties,
Leon Clarke4515c472010-02-03 11:58:03 +00004225 constant_properties,
4226 &is_simple,
Steve Block6ded16b2010-05-10 14:33:55 +01004227 &fast_elements,
Leon Clarke4515c472010-02-03 11:58:03 +00004228 &depth);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004229 return factory()->NewObjectLiteral(constant_properties,
4230 properties,
4231 literal_index,
4232 is_simple,
4233 fast_elements,
4234 depth,
4235 has_function);
Steve Blocka7e24c12009-10-30 11:49:00 +00004236}
4237
4238
4239Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01004240 if (!scanner().ScanRegExpPattern(seen_equal)) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004241 Next();
4242 ReportMessage("unterminated_regexp", Vector<const char*>::empty());
4243 *ok = false;
4244 return NULL;
4245 }
4246
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004247 int literal_index = current_function_state_->NextMaterializedLiteralIndex();
Steve Blocka7e24c12009-10-30 11:49:00 +00004248
Steve Block9fac8402011-05-12 15:51:54 +01004249 Handle<String> js_pattern = NextLiteralString(TENURED);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004250 scanner().ScanRegExpFlags();
Steve Block9fac8402011-05-12 15:51:54 +01004251 Handle<String> js_flags = NextLiteralString(TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00004252 Next();
4253
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004254 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index);
Steve Blocka7e24c12009-10-30 11:49:00 +00004255}
4256
4257
4258ZoneList<Expression*>* Parser::ParseArguments(bool* ok) {
4259 // Arguments ::
4260 // '(' (AssignmentExpression)*[','] ')'
4261
Ben Murdoch257744e2011-11-30 15:57:28 +00004262 ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4);
Steve Blocka7e24c12009-10-30 11:49:00 +00004263 Expect(Token::LPAREN, CHECK_OK);
4264 bool done = (peek() == Token::RPAREN);
4265 while (!done) {
4266 Expression* argument = ParseAssignmentExpression(true, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08004267 result->Add(argument);
Steve Block053d10c2011-06-13 19:13:29 +01004268 if (result->length() > kMaxNumFunctionParameters) {
4269 ReportMessageAt(scanner().location(), "too_many_arguments",
4270 Vector<const char*>::empty());
4271 *ok = false;
4272 return NULL;
4273 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004274 done = (peek() == Token::RPAREN);
4275 if (!done) Expect(Token::COMMA, CHECK_OK);
4276 }
4277 Expect(Token::RPAREN, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08004278 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00004279}
4280
4281
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004282class SingletonLogger : public ParserRecorder {
4283 public:
4284 SingletonLogger() : has_error_(false), start_(-1), end_(-1) { }
4285 virtual ~SingletonLogger() { }
4286
4287 void Reset() { has_error_ = false; }
4288
4289 virtual void LogFunction(int start,
4290 int end,
4291 int literals,
4292 int properties,
4293 LanguageMode mode) {
4294 ASSERT(!has_error_);
4295 start_ = start;
4296 end_ = end;
4297 literals_ = literals;
4298 properties_ = properties;
4299 mode_ = mode;
4300 };
4301
4302 // Logs a symbol creation of a literal or identifier.
4303 virtual void LogAsciiSymbol(int start, Vector<const char> literal) { }
4304 virtual void LogUtf16Symbol(int start, Vector<const uc16> literal) { }
4305
4306 // Logs an error message and marks the log as containing an error.
4307 // Further logging will be ignored, and ExtractData will return a vector
4308 // representing the error only.
4309 virtual void LogMessage(int start,
4310 int end,
4311 const char* message,
4312 const char* argument_opt) {
4313 has_error_ = true;
4314 start_ = start;
4315 end_ = end;
4316 message_ = message;
4317 argument_opt_ = argument_opt;
4318 }
4319
4320 virtual int function_position() { return 0; }
4321
4322 virtual int symbol_position() { return 0; }
4323
4324 virtual int symbol_ids() { return -1; }
4325
4326 virtual Vector<unsigned> ExtractData() {
4327 UNREACHABLE();
4328 return Vector<unsigned>();
4329 }
4330
4331 virtual void PauseRecording() { }
4332
4333 virtual void ResumeRecording() { }
4334
4335 bool has_error() { return has_error_; }
4336
4337 int start() { return start_; }
4338 int end() { return end_; }
4339 int literals() {
4340 ASSERT(!has_error_);
4341 return literals_;
4342 }
4343 int properties() {
4344 ASSERT(!has_error_);
4345 return properties_;
4346 }
4347 LanguageMode language_mode() {
4348 ASSERT(!has_error_);
4349 return mode_;
4350 }
4351 const char* message() {
4352 ASSERT(has_error_);
4353 return message_;
4354 }
4355 const char* argument_opt() {
4356 ASSERT(has_error_);
4357 return argument_opt_;
4358 }
4359
4360 private:
4361 bool has_error_;
4362 int start_;
4363 int end_;
4364 // For function entries.
4365 int literals_;
4366 int properties_;
4367 LanguageMode mode_;
4368 // For error messages.
4369 const char* message_;
4370 const char* argument_opt_;
4371};
4372
4373
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004374FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
4375 bool name_is_strict_reserved,
Steve Blocka7e24c12009-10-30 11:49:00 +00004376 int function_token_position,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004377 FunctionLiteral::Type type,
Steve Blocka7e24c12009-10-30 11:49:00 +00004378 bool* ok) {
4379 // Function ::
4380 // '(' FormalParameterList? ')' '{' FunctionBody '}'
Steve Blocka7e24c12009-10-30 11:49:00 +00004381
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004382 // Anonymous functions were passed either the empty symbol or a null
4383 // handle as the function name. Remember if we were passed a non-empty
4384 // handle to decide whether to invoke function name inference.
4385 bool should_infer_name = function_name.is_null();
4386
4387 // We want a non-null handle as the function name.
4388 if (should_infer_name) {
4389 function_name = isolate()->factory()->empty_symbol();
Steve Blocka7e24c12009-10-30 11:49:00 +00004390 }
4391
4392 int num_parameters = 0;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00004393 // Function declarations are function scoped in normal mode, so they are
4394 // hoisted. In harmony block scoping mode they are block scoped, so they
4395 // are not hoisted.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004396 Scope* scope = (type == FunctionLiteral::DECLARATION && !is_extended_mode())
4397 ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE)
4398 : NewScope(top_scope_, FUNCTION_SCOPE);
4399 ZoneList<Statement*>* body = NULL;
4400 int materialized_literal_count = -1;
4401 int expected_property_count = -1;
4402 int handler_count = 0;
Ben Murdoch8b112d22011-06-08 16:22:53 +01004403 bool only_simple_this_property_assignments;
4404 Handle<FixedArray> this_property_assignments;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004405 FunctionLiteral::ParameterFlag duplicate_parameters =
4406 FunctionLiteral::kNoDuplicateParameters;
4407 AstProperties ast_properties;
Steve Blocka7e24c12009-10-30 11:49:00 +00004408 // Parse function body.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004409 { FunctionState function_state(this, scope, isolate());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004410 top_scope_->SetScopeName(function_name);
Steve Blocka7e24c12009-10-30 11:49:00 +00004411
4412 // FormalParameterList ::
4413 // '(' (Identifier)*[','] ')'
4414 Expect(Token::LPAREN, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004415 scope->set_start_position(scanner().location().beg_pos);
Ben Murdoch257744e2011-11-30 15:57:28 +00004416 Scanner::Location name_loc = Scanner::Location::invalid();
4417 Scanner::Location dupe_loc = Scanner::Location::invalid();
4418 Scanner::Location reserved_loc = Scanner::Location::invalid();
Steve Block1e0659c2011-05-24 12:43:12 +01004419
Steve Blocka7e24c12009-10-30 11:49:00 +00004420 bool done = (peek() == Token::RPAREN);
4421 while (!done) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004422 bool is_strict_reserved = false;
Steve Block1e0659c2011-05-24 12:43:12 +01004423 Handle<String> param_name =
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004424 ParseIdentifierOrStrictReservedWord(&is_strict_reserved,
4425 CHECK_OK);
Steve Block1e0659c2011-05-24 12:43:12 +01004426
4427 // Store locations for possible future error reports.
4428 if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) {
4429 name_loc = scanner().location();
4430 }
4431 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004432 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters;
Steve Block1e0659c2011-05-24 12:43:12 +01004433 dupe_loc = scanner().location();
4434 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004435 if (!reserved_loc.IsValid() && is_strict_reserved) {
Steve Block1e0659c2011-05-24 12:43:12 +01004436 reserved_loc = scanner().location();
4437 }
4438
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004439 top_scope_->DeclareParameter(param_name, VAR);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08004440 num_parameters++;
Steve Block1e0659c2011-05-24 12:43:12 +01004441 if (num_parameters > kMaxNumFunctionParameters) {
4442 ReportMessageAt(scanner().location(), "too_many_parameters",
4443 Vector<const char*>::empty());
4444 *ok = false;
4445 return NULL;
4446 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004447 done = (peek() == Token::RPAREN);
4448 if (!done) Expect(Token::COMMA, CHECK_OK);
4449 }
4450 Expect(Token::RPAREN, CHECK_OK);
4451
4452 Expect(Token::LBRACE, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00004453
4454 // If we have a named function expression, we add a local variable
4455 // declaration to the body of the function with the name of the
4456 // function and let it refer to the function itself (closure).
4457 // NOTE: We create a proxy and resolve it here so that in the
4458 // future we can change the AST to only refer to VariableProxies
4459 // instead of Variables and Proxis as is the case now.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004460 Variable* fvar = NULL;
4461 Token::Value fvar_init_op = Token::INIT_CONST;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004462 if (type == FunctionLiteral::NAMED_EXPRESSION) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004463 VariableMode fvar_mode;
4464 if (is_extended_mode()) {
4465 fvar_mode = CONST_HARMONY;
4466 fvar_init_op = Token::INIT_CONST_HARMONY;
4467 } else {
4468 fvar_mode = CONST;
4469 }
4470 fvar =
4471 top_scope_->DeclareFunctionVar(function_name, fvar_mode, factory());
Steve Blocka7e24c12009-10-30 11:49:00 +00004472 }
4473
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004474 // Determine whether the function will be lazily compiled.
4475 // The heuristics are:
4476 // - It must not have been prohibited by the caller to Parse (some callers
4477 // need a full AST).
4478 // - The outer scope must be trivial (only global variables in scope).
4479 // - The function mustn't be a function expression with an open parenthesis
4480 // before; we consider that a hint that the function will be called
4481 // immediately, and it would be a waste of time to make it lazily
4482 // compiled.
4483 // These are all things we can know at this point, without looking at the
4484 // function itself.
Ben Murdochb8e0da22011-05-16 14:20:40 +01004485 bool is_lazily_compiled = (mode() == PARSE_LAZILY &&
4486 top_scope_->outer_scope()->is_global_scope() &&
4487 top_scope_->HasTrivialOuterContext() &&
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004488 !parenthesized_function_);
Ben Murdochb8e0da22011-05-16 14:20:40 +01004489 parenthesized_function_ = false; // The bit was set for this function only.
Steve Blocka7e24c12009-10-30 11:49:00 +00004490
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004491 if (is_lazily_compiled) {
4492 int function_block_pos = scanner().location().beg_pos;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004493 FunctionEntry entry;
4494 if (pre_data_ != NULL) {
4495 // If we have pre_data_, we use it to skip parsing the function body.
4496 // the preparser data contains the information we need to construct the
4497 // lazy function.
4498 entry = pre_data()->GetFunctionEntry(function_block_pos);
4499 if (entry.is_valid()) {
4500 if (entry.end_pos() <= function_block_pos) {
4501 // End position greater than end of stream is safe, and hard
4502 // to check.
4503 ReportInvalidPreparseData(function_name, CHECK_OK);
4504 }
4505 scanner().SeekForward(entry.end_pos() - 1);
4506
4507 scope->set_end_position(entry.end_pos());
4508 Expect(Token::RBRACE, CHECK_OK);
4509 isolate()->counters()->total_preparse_skipped()->Increment(
4510 scope->end_position() - function_block_pos);
4511 materialized_literal_count = entry.literal_count();
4512 expected_property_count = entry.property_count();
4513 top_scope_->SetLanguageMode(entry.language_mode());
4514 only_simple_this_property_assignments = false;
4515 this_property_assignments = isolate()->factory()->empty_fixed_array();
4516 } else {
4517 is_lazily_compiled = false;
Ben Murdoch592a9fc2012-03-05 11:04:45 +00004518 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004519 } else {
4520 // With no preparser data, we partially parse the function, without
4521 // building an AST. This gathers the data needed to build a lazy
4522 // function.
4523 SingletonLogger logger;
4524 preparser::PreParser::PreParseResult result =
4525 LazyParseFunctionLiteral(&logger);
4526 if (result == preparser::PreParser::kPreParseStackOverflow) {
4527 // Propagate stack overflow.
4528 stack_overflow_ = true;
4529 *ok = false;
4530 return NULL;
4531 }
4532 if (logger.has_error()) {
4533 const char* arg = logger.argument_opt();
4534 Vector<const char*> args;
4535 if (arg != NULL) {
4536 args = Vector<const char*>(&arg, 1);
4537 }
4538 ReportMessageAt(Scanner::Location(logger.start(), logger.end()),
4539 logger.message(), args);
4540 *ok = false;
4541 return NULL;
4542 }
4543 scope->set_end_position(logger.end());
4544 Expect(Token::RBRACE, CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004545 isolate()->counters()->total_preparse_skipped()->Increment(
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004546 scope->end_position() - function_block_pos);
4547 materialized_literal_count = logger.literals();
4548 expected_property_count = logger.properties();
4549 top_scope_->SetLanguageMode(logger.language_mode());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004550 only_simple_this_property_assignments = false;
4551 this_property_assignments = isolate()->factory()->empty_fixed_array();
Leon Clarkeac952652010-07-15 11:15:24 +01004552 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004553 }
4554
4555 if (!is_lazily_compiled) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004556 body = new(zone()) ZoneList<Statement*>(8);
4557 if (fvar != NULL) {
4558 VariableProxy* fproxy =
4559 top_scope_->NewUnresolved(factory(), function_name);
4560 fproxy->BindTo(fvar);
4561 body->Add(factory()->NewExpressionStatement(
4562 factory()->NewAssignment(fvar_init_op,
4563 fproxy,
4564 factory()->NewThisFunction(),
4565 RelocInfo::kNoPosition)));
4566 }
4567 ParseSourceElements(body, Token::RBRACE, false, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08004568
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004569 materialized_literal_count = function_state.materialized_literal_count();
4570 expected_property_count = function_state.expected_property_count();
4571 handler_count = function_state.handler_count();
Steve Blocka7e24c12009-10-30 11:49:00 +00004572 only_simple_this_property_assignments =
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004573 function_state.only_simple_this_property_assignments();
4574 this_property_assignments = function_state.this_property_assignments();
Steve Blocka7e24c12009-10-30 11:49:00 +00004575
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004576 Expect(Token::RBRACE, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004577 scope->set_end_position(scanner().location().end_pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00004578 }
4579
Steve Block1e0659c2011-05-24 12:43:12 +01004580 // Validate strict mode.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004581 if (!top_scope_->is_classic_mode()) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004582 if (IsEvalOrArguments(function_name)) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004583 int start_pos = scope->start_position();
Steve Block1e0659c2011-05-24 12:43:12 +01004584 int position = function_token_position != RelocInfo::kNoPosition
4585 ? function_token_position
4586 : (start_pos > 0 ? start_pos - 1 : start_pos);
4587 Scanner::Location location = Scanner::Location(position, start_pos);
4588 ReportMessageAt(location,
4589 "strict_function_name", Vector<const char*>::empty());
4590 *ok = false;
4591 return NULL;
4592 }
4593 if (name_loc.IsValid()) {
4594 ReportMessageAt(name_loc, "strict_param_name",
4595 Vector<const char*>::empty());
4596 *ok = false;
4597 return NULL;
4598 }
4599 if (dupe_loc.IsValid()) {
4600 ReportMessageAt(dupe_loc, "strict_param_dupe",
4601 Vector<const char*>::empty());
4602 *ok = false;
4603 return NULL;
4604 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004605 if (name_is_strict_reserved) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004606 int start_pos = scope->start_position();
Steve Block1e0659c2011-05-24 12:43:12 +01004607 int position = function_token_position != RelocInfo::kNoPosition
4608 ? function_token_position
4609 : (start_pos > 0 ? start_pos - 1 : start_pos);
4610 Scanner::Location location = Scanner::Location(position, start_pos);
4611 ReportMessageAt(location, "strict_reserved_word",
4612 Vector<const char*>::empty());
4613 *ok = false;
4614 return NULL;
4615 }
4616 if (reserved_loc.IsValid()) {
4617 ReportMessageAt(reserved_loc, "strict_reserved_word",
4618 Vector<const char*>::empty());
4619 *ok = false;
4620 return NULL;
4621 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004622 CheckOctalLiteral(scope->start_position(),
4623 scope->end_position(),
4624 CHECK_OK);
Steve Block1e0659c2011-05-24 12:43:12 +01004625 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004626 ast_properties = *factory()->visitor()->ast_properties();
Steve Blocka7e24c12009-10-30 11:49:00 +00004627 }
Ben Murdoch8b112d22011-06-08 16:22:53 +01004628
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004629 if (is_extended_mode()) {
Ben Murdoch589d6972011-11-30 16:04:58 +00004630 CheckConflictingVarDeclarations(scope, CHECK_OK);
4631 }
4632
Ben Murdoch8b112d22011-06-08 16:22:53 +01004633 FunctionLiteral* function_literal =
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004634 factory()->NewFunctionLiteral(function_name,
4635 scope,
4636 body,
4637 materialized_literal_count,
4638 expected_property_count,
4639 handler_count,
4640 only_simple_this_property_assignments,
4641 this_property_assignments,
4642 num_parameters,
4643 duplicate_parameters,
4644 type,
4645 FunctionLiteral::kIsFunction);
Ben Murdoch8b112d22011-06-08 16:22:53 +01004646 function_literal->set_function_token_position(function_token_position);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004647 function_literal->set_ast_properties(&ast_properties);
Ben Murdoch8b112d22011-06-08 16:22:53 +01004648
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004649 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
Ben Murdoch8b112d22011-06-08 16:22:53 +01004650 return function_literal;
Steve Blocka7e24c12009-10-30 11:49:00 +00004651}
4652
4653
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004654preparser::PreParser::PreParseResult Parser::LazyParseFunctionLiteral(
4655 SingletonLogger* logger) {
4656 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse());
4657 ASSERT_EQ(Token::LBRACE, scanner().current_token());
4658
4659 if (reusable_preparser_ == NULL) {
4660 intptr_t stack_limit = isolate()->stack_guard()->real_climit();
4661 bool do_allow_lazy = true;
4662 reusable_preparser_ = new preparser::PreParser(&scanner_,
4663 NULL,
4664 stack_limit,
4665 do_allow_lazy,
4666 allow_natives_syntax_,
4667 allow_modules_);
4668 }
4669 preparser::PreParser::PreParseResult result =
4670 reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(),
4671 logger);
4672 return result;
4673}
4674
4675
Steve Blocka7e24c12009-10-30 11:49:00 +00004676Expression* Parser::ParseV8Intrinsic(bool* ok) {
4677 // CallRuntime ::
4678 // '%' Identifier Arguments
4679
4680 Expect(Token::MOD, CHECK_OK);
4681 Handle<String> name = ParseIdentifier(CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00004682 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01004683
4684 if (extension_ != NULL) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004685 // The extension structures are only accessible while parsing the
4686 // very first time not when reparsing because of lazy compilation.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004687 top_scope_->DeclarationScope()->ForceEagerCompilation();
Steve Blocka7e24c12009-10-30 11:49:00 +00004688 }
4689
Steve Block44f0eee2011-05-26 01:26:41 +01004690 const Runtime::Function* function = Runtime::FunctionForSymbol(name);
Steve Blocka7e24c12009-10-30 11:49:00 +00004691
Kristian Monsen0d5e1162010-09-30 15:31:59 +01004692 // Check for built-in IS_VAR macro.
4693 if (function != NULL &&
4694 function->intrinsic_type == Runtime::RUNTIME &&
4695 function->function_id == Runtime::kIS_VAR) {
4696 // %IS_VAR(x) evaluates to x if x is a variable,
4697 // leads to a parse error otherwise. Could be implemented as an
4698 // inline function %_IS_VAR(x) to eliminate this special case.
4699 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
4700 return args->at(0);
4701 } else {
Steve Blocka7e24c12009-10-30 11:49:00 +00004702 ReportMessage("unable_to_parse", Vector<const char*>::empty());
Steve Block6ded16b2010-05-10 14:33:55 +01004703 *ok = false;
4704 return NULL;
Steve Block6ded16b2010-05-10 14:33:55 +01004705 }
4706 }
4707
Kristian Monsen0d5e1162010-09-30 15:31:59 +01004708 // Check that the expected number of arguments are being passed.
4709 if (function != NULL &&
4710 function->nargs != -1 &&
4711 function->nargs != args->length()) {
4712 ReportMessage("illegal_access", Vector<const char*>::empty());
4713 *ok = false;
4714 return NULL;
4715 }
4716
4717 // We have a valid intrinsics call or a call to a builtin.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004718 return factory()->NewCallRuntime(name, function, args);
Steve Blocka7e24c12009-10-30 11:49:00 +00004719}
4720
4721
Steve Block1e0659c2011-05-24 12:43:12 +01004722bool Parser::peek_any_identifier() {
4723 Token::Value next = peek();
4724 return next == Token::IDENTIFIER ||
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004725 next == Token::FUTURE_RESERVED_WORD ||
4726 next == Token::FUTURE_STRICT_RESERVED_WORD;
Steve Block1e0659c2011-05-24 12:43:12 +01004727}
4728
4729
Steve Blocka7e24c12009-10-30 11:49:00 +00004730void Parser::Consume(Token::Value token) {
4731 Token::Value next = Next();
4732 USE(next);
4733 USE(token);
4734 ASSERT(next == token);
4735}
4736
4737
4738void Parser::Expect(Token::Value token, bool* ok) {
4739 Token::Value next = Next();
4740 if (next == token) return;
4741 ReportUnexpectedToken(next);
4742 *ok = false;
4743}
4744
4745
Leon Clarke4515c472010-02-03 11:58:03 +00004746bool Parser::Check(Token::Value token) {
4747 Token::Value next = peek();
4748 if (next == token) {
4749 Consume(next);
4750 return true;
4751 }
4752 return false;
4753}
4754
4755
Steve Blocka7e24c12009-10-30 11:49:00 +00004756void Parser::ExpectSemicolon(bool* ok) {
4757 // Check for automatic semicolon insertion according to
4758 // the rules given in ECMA-262, section 7.9, page 21.
4759 Token::Value tok = peek();
4760 if (tok == Token::SEMICOLON) {
4761 Next();
4762 return;
4763 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004764 if (scanner().HasAnyLineTerminatorBeforeNext() ||
Steve Blocka7e24c12009-10-30 11:49:00 +00004765 tok == Token::RBRACE ||
4766 tok == Token::EOS) {
4767 return;
4768 }
4769 Expect(Token::SEMICOLON, ok);
4770}
4771
4772
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004773void Parser::ExpectContextualKeyword(const char* keyword, bool* ok) {
4774 Expect(Token::IDENTIFIER, ok);
4775 if (!*ok) return;
4776 Handle<String> symbol = GetSymbol(ok);
4777 if (!*ok) return;
4778 if (!symbol->IsEqualTo(CStrVector(keyword))) {
4779 *ok = false;
4780 ReportUnexpectedToken(scanner().current_token());
4781 }
4782}
4783
4784
Steve Blocka7e24c12009-10-30 11:49:00 +00004785Literal* Parser::GetLiteralUndefined() {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004786 return factory()->NewLiteral(isolate()->factory()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00004787}
4788
4789
4790Literal* Parser::GetLiteralTheHole() {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004791 return factory()->NewLiteral(isolate()->factory()->the_hole_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00004792}
4793
4794
Ben Murdoch69a99ed2011-11-30 16:03:39 +00004795// Parses an identifier that is valid for the current scope, in particular it
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004796// fails on strict mode future reserved keywords in a strict scope.
Steve Blocka7e24c12009-10-30 11:49:00 +00004797Handle<String> Parser::ParseIdentifier(bool* ok) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004798 if (!top_scope_->is_classic_mode()) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004799 Expect(Token::IDENTIFIER, ok);
4800 } else if (!Check(Token::IDENTIFIER)) {
4801 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
4802 }
4803 if (!*ok) return Handle<String>();
4804 return GetSymbol(ok);
Steve Block1e0659c2011-05-24 12:43:12 +01004805}
4806
4807
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004808// Parses and identifier or a strict mode future reserved word, and indicate
4809// whether it is strict mode future reserved.
4810Handle<String> Parser::ParseIdentifierOrStrictReservedWord(
4811 bool* is_strict_reserved, bool* ok) {
4812 *is_strict_reserved = false;
4813 if (!Check(Token::IDENTIFIER)) {
4814 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
4815 *is_strict_reserved = true;
Steve Block1e0659c2011-05-24 12:43:12 +01004816 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004817 if (!*ok) return Handle<String>();
Iain Merrick9ac36c92010-09-13 15:29:50 +01004818 return GetSymbol(ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00004819}
4820
Ben Murdochbb769b22010-08-11 14:56:33 +01004821
4822Handle<String> Parser::ParseIdentifierName(bool* ok) {
4823 Token::Value next = Next();
Steve Block1e0659c2011-05-24 12:43:12 +01004824 if (next != Token::IDENTIFIER &&
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004825 next != Token::FUTURE_RESERVED_WORD &&
4826 next != Token::FUTURE_STRICT_RESERVED_WORD &&
4827 !Token::IsKeyword(next)) {
Ben Murdochbb769b22010-08-11 14:56:33 +01004828 ReportUnexpectedToken(next);
4829 *ok = false;
4830 return Handle<String>();
4831 }
Iain Merrick9ac36c92010-09-13 15:29:50 +01004832 return GetSymbol(ok);
Ben Murdochbb769b22010-08-11 14:56:33 +01004833}
4834
4835
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004836void Parser::MarkAsLValue(Expression* expression) {
4837 VariableProxy* proxy = expression != NULL
4838 ? expression->AsVariableProxy()
4839 : NULL;
4840
4841 if (proxy != NULL) proxy->MarkAsLValue();
4842}
4843
4844
Steve Block1e0659c2011-05-24 12:43:12 +01004845// Checks LHS expression for assignment and prefix/postfix increment/decrement
4846// in strict mode.
4847void Parser::CheckStrictModeLValue(Expression* expression,
4848 const char* error,
4849 bool* ok) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004850 ASSERT(!top_scope_->is_classic_mode());
Steve Block1e0659c2011-05-24 12:43:12 +01004851 VariableProxy* lhs = expression != NULL
4852 ? expression->AsVariableProxy()
4853 : NULL;
4854
4855 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) {
4856 ReportMessage(error, Vector<const char*>::empty());
4857 *ok = false;
4858 }
4859}
4860
4861
Ben Murdoch257744e2011-11-30 15:57:28 +00004862// Checks whether an octal literal was last seen between beg_pos and end_pos.
4863// If so, reports an error. Only called for strict mode.
Steve Block1e0659c2011-05-24 12:43:12 +01004864void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
Ben Murdoch257744e2011-11-30 15:57:28 +00004865 Scanner::Location octal = scanner().octal_position();
4866 if (octal.IsValid() &&
4867 beg_pos <= octal.beg_pos &&
4868 octal.end_pos <= end_pos) {
4869 ReportMessageAt(octal, "strict_octal_literal",
Steve Block1e0659c2011-05-24 12:43:12 +01004870 Vector<const char*>::empty());
4871 scanner().clear_octal_position();
4872 *ok = false;
4873 }
4874}
4875
4876
Ben Murdoch589d6972011-11-30 16:04:58 +00004877void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
4878 Declaration* decl = scope->CheckConflictingVarDeclarations();
4879 if (decl != NULL) {
4880 // In harmony mode we treat conflicting variable bindinds as early
4881 // errors. See ES5 16 for a definition of early errors.
4882 Handle<String> name = decl->proxy()->name();
4883 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
4884 const char* elms[2] = { "Variable", *c_string };
4885 Vector<const char*> args(elms, 2);
4886 int position = decl->proxy()->position();
4887 Scanner::Location location = position == RelocInfo::kNoPosition
4888 ? Scanner::Location::invalid()
4889 : Scanner::Location(position, position + 1);
4890 ReportMessageAt(location, "redeclaration", args);
4891 *ok = false;
4892 }
4893}
4894
4895
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004896// This function reads an identifier name and determines whether or not it
Steve Block1e0659c2011-05-24 12:43:12 +01004897// is 'get' or 'set'.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004898Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get,
4899 bool* is_set,
4900 bool* ok) {
4901 Handle<String> result = ParseIdentifierName(ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00004902 if (!*ok) return Handle<String>();
Steve Block9fac8402011-05-12 15:51:54 +01004903 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) {
4904 const char* token = scanner().literal_ascii_string().start();
4905 *is_get = strncmp(token, "get", 3) == 0;
4906 *is_set = !*is_get && strncmp(token, "set", 3) == 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00004907 }
Steve Block1e0659c2011-05-24 12:43:12 +01004908 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00004909}
4910
4911
4912// ----------------------------------------------------------------------------
4913// Parser support
4914
4915
4916bool Parser::TargetStackContainsLabel(Handle<String> label) {
4917 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4918 BreakableStatement* stat = t->node()->AsBreakableStatement();
4919 if (stat != NULL && ContainsLabel(stat->labels(), label))
4920 return true;
4921 }
4922 return false;
4923}
4924
4925
4926BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) {
4927 bool anonymous = label.is_null();
4928 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4929 BreakableStatement* stat = t->node()->AsBreakableStatement();
4930 if (stat == NULL) continue;
4931 if ((anonymous && stat->is_target_for_anonymous()) ||
4932 (!anonymous && ContainsLabel(stat->labels(), label))) {
4933 RegisterTargetUse(stat->break_target(), t->previous());
4934 return stat;
4935 }
4936 }
4937 return NULL;
4938}
4939
4940
4941IterationStatement* Parser::LookupContinueTarget(Handle<String> label,
4942 bool* ok) {
4943 bool anonymous = label.is_null();
4944 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4945 IterationStatement* stat = t->node()->AsIterationStatement();
4946 if (stat == NULL) continue;
4947
4948 ASSERT(stat->is_target_for_anonymous());
4949 if (anonymous || ContainsLabel(stat->labels(), label)) {
4950 RegisterTargetUse(stat->continue_target(), t->previous());
4951 return stat;
4952 }
4953 }
4954 return NULL;
4955}
4956
4957
Ben Murdoch8b112d22011-06-08 16:22:53 +01004958void Parser::RegisterTargetUse(Label* target, Target* stop) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004959 // Register that a break target found at the given stop in the
4960 // target stack has been used from the top of the target stack. Add
4961 // the break target to any TargetCollectors passed on the stack.
4962 for (Target* t = target_stack_; t != stop; t = t->previous()) {
4963 TargetCollector* collector = t->node()->AsTargetCollector();
4964 if (collector != NULL) collector->AddTarget(target);
4965 }
4966}
4967
4968
Steve Blocka7e24c12009-10-30 11:49:00 +00004969Expression* Parser::NewThrowReferenceError(Handle<String> type) {
Steve Block44f0eee2011-05-26 01:26:41 +01004970 return NewThrowError(isolate()->factory()->MakeReferenceError_symbol(),
Steve Blocka7e24c12009-10-30 11:49:00 +00004971 type, HandleVector<Object>(NULL, 0));
4972}
4973
4974
4975Expression* Parser::NewThrowSyntaxError(Handle<String> type,
4976 Handle<Object> first) {
4977 int argc = first.is_null() ? 0 : 1;
4978 Vector< Handle<Object> > arguments = HandleVector<Object>(&first, argc);
Steve Block44f0eee2011-05-26 01:26:41 +01004979 return NewThrowError(
4980 isolate()->factory()->MakeSyntaxError_symbol(), type, arguments);
Steve Blocka7e24c12009-10-30 11:49:00 +00004981}
4982
4983
4984Expression* Parser::NewThrowTypeError(Handle<String> type,
4985 Handle<Object> first,
4986 Handle<Object> second) {
4987 ASSERT(!first.is_null() && !second.is_null());
4988 Handle<Object> elements[] = { first, second };
4989 Vector< Handle<Object> > arguments =
4990 HandleVector<Object>(elements, ARRAY_SIZE(elements));
Steve Block44f0eee2011-05-26 01:26:41 +01004991 return NewThrowError(
4992 isolate()->factory()->MakeTypeError_symbol(), type, arguments);
Steve Blocka7e24c12009-10-30 11:49:00 +00004993}
4994
4995
4996Expression* Parser::NewThrowError(Handle<String> constructor,
4997 Handle<String> type,
4998 Vector< Handle<Object> > arguments) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004999 int argc = arguments.length();
Steve Block44f0eee2011-05-26 01:26:41 +01005000 Handle<FixedArray> elements = isolate()->factory()->NewFixedArray(argc,
5001 TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00005002 for (int i = 0; i < argc; i++) {
5003 Handle<Object> element = arguments[i];
5004 if (!element.is_null()) {
Steve Block1e0659c2011-05-24 12:43:12 +01005005 elements->set(i, *element);
Steve Blocka7e24c12009-10-30 11:49:00 +00005006 }
5007 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005008 Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements(
5009 elements, FAST_ELEMENTS, TENURED);
Steve Block1e0659c2011-05-24 12:43:12 +01005010
Ben Murdoch257744e2011-11-30 15:57:28 +00005011 ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005012 args->Add(factory()->NewLiteral(type));
5013 args->Add(factory()->NewLiteral(array));
5014 CallRuntime* call_constructor =
5015 factory()->NewCallRuntime(constructor, NULL, args);
5016 return factory()->NewThrow(call_constructor, scanner().location().beg_pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00005017}
5018
Leon Clarke4515c472010-02-03 11:58:03 +00005019// ----------------------------------------------------------------------------
Steve Blocka7e24c12009-10-30 11:49:00 +00005020// Regular expressions
5021
5022
5023RegExpParser::RegExpParser(FlatStringReader* in,
5024 Handle<String>* error,
5025 bool multiline)
Steve Block44f0eee2011-05-26 01:26:41 +01005026 : isolate_(Isolate::Current()),
5027 error_(error),
5028 captures_(NULL),
5029 in_(in),
5030 current_(kEndMarker),
5031 next_pos_(0),
5032 capture_count_(0),
5033 has_more_(true),
5034 multiline_(multiline),
5035 simple_(false),
5036 contains_anchor_(false),
5037 is_scanned_for_captures_(false),
5038 failed_(false) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01005039 Advance();
Steve Blocka7e24c12009-10-30 11:49:00 +00005040}
5041
5042
5043uc32 RegExpParser::Next() {
5044 if (has_next()) {
5045 return in()->Get(next_pos_);
5046 } else {
5047 return kEndMarker;
5048 }
5049}
5050
5051
5052void RegExpParser::Advance() {
5053 if (next_pos_ < in()->length()) {
Steve Block44f0eee2011-05-26 01:26:41 +01005054 StackLimitCheck check(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00005055 if (check.HasOverflowed()) {
Steve Block44f0eee2011-05-26 01:26:41 +01005056 ReportError(CStrVector(Isolate::kStackOverflowMessage));
5057 } else if (isolate()->zone()->excess_allocation()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005058 ReportError(CStrVector("Regular expression too large"));
5059 } else {
5060 current_ = in()->Get(next_pos_);
5061 next_pos_++;
5062 }
5063 } else {
5064 current_ = kEndMarker;
5065 has_more_ = false;
5066 }
5067}
5068
5069
5070void RegExpParser::Reset(int pos) {
5071 next_pos_ = pos;
5072 Advance();
5073}
5074
5075
5076void RegExpParser::Advance(int dist) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01005077 next_pos_ += dist - 1;
5078 Advance();
Steve Blocka7e24c12009-10-30 11:49:00 +00005079}
5080
5081
5082bool RegExpParser::simple() {
5083 return simple_;
5084}
5085
5086RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
5087 failed_ = true;
Steve Block44f0eee2011-05-26 01:26:41 +01005088 *error_ = isolate()->factory()->NewStringFromAscii(message, NOT_TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00005089 // Zip to the end to make sure the no more input is read.
5090 current_ = kEndMarker;
5091 next_pos_ = in()->length();
5092 return NULL;
5093}
5094
5095
5096// Pattern ::
5097// Disjunction
5098RegExpTree* RegExpParser::ParsePattern() {
5099 RegExpTree* result = ParseDisjunction(CHECK_FAILED);
5100 ASSERT(!has_more());
5101 // If the result of parsing is a literal string atom, and it has the
5102 // same length as the input, then the atom is identical to the input.
5103 if (result->IsAtom() && result->AsAtom()->length() == in()->length()) {
5104 simple_ = true;
5105 }
5106 return result;
5107}
5108
5109
5110// Disjunction ::
5111// Alternative
5112// Alternative | Disjunction
5113// Alternative ::
5114// [empty]
5115// Term Alternative
5116// Term ::
5117// Assertion
5118// Atom
5119// Atom Quantifier
5120RegExpTree* RegExpParser::ParseDisjunction() {
5121 // Used to store current state while parsing subexpressions.
5122 RegExpParserState initial_state(NULL, INITIAL, 0);
5123 RegExpParserState* stored_state = &initial_state;
5124 // Cache the builder in a local variable for quick access.
5125 RegExpBuilder* builder = initial_state.builder();
5126 while (true) {
5127 switch (current()) {
5128 case kEndMarker:
5129 if (stored_state->IsSubexpression()) {
5130 // Inside a parenthesized group when hitting end of input.
5131 ReportError(CStrVector("Unterminated group") CHECK_FAILED);
5132 }
5133 ASSERT_EQ(INITIAL, stored_state->group_type());
5134 // Parsing completed successfully.
5135 return builder->ToRegExp();
5136 case ')': {
5137 if (!stored_state->IsSubexpression()) {
5138 ReportError(CStrVector("Unmatched ')'") CHECK_FAILED);
5139 }
5140 ASSERT_NE(INITIAL, stored_state->group_type());
5141
5142 Advance();
5143 // End disjunction parsing and convert builder content to new single
5144 // regexp atom.
5145 RegExpTree* body = builder->ToRegExp();
5146
5147 int end_capture_index = captures_started();
5148
5149 int capture_index = stored_state->capture_index();
5150 SubexpressionType type = stored_state->group_type();
5151
5152 // Restore previous state.
5153 stored_state = stored_state->previous_state();
5154 builder = stored_state->builder();
5155
5156 // Build result of subexpression.
5157 if (type == CAPTURE) {
Ben Murdoch8b112d22011-06-08 16:22:53 +01005158 RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index);
Steve Blocka7e24c12009-10-30 11:49:00 +00005159 captures_->at(capture_index - 1) = capture;
5160 body = capture;
5161 } else if (type != GROUPING) {
5162 ASSERT(type == POSITIVE_LOOKAHEAD || type == NEGATIVE_LOOKAHEAD);
5163 bool is_positive = (type == POSITIVE_LOOKAHEAD);
Ben Murdoch8b112d22011-06-08 16:22:53 +01005164 body = new(zone()) RegExpLookahead(body,
Steve Blocka7e24c12009-10-30 11:49:00 +00005165 is_positive,
5166 end_capture_index - capture_index,
5167 capture_index);
5168 }
5169 builder->AddAtom(body);
Ben Murdoche0cee9b2011-05-25 10:26:03 +01005170 // For compatability with JSC and ES3, we allow quantifiers after
5171 // lookaheads, and break in all cases.
Steve Blocka7e24c12009-10-30 11:49:00 +00005172 break;
5173 }
5174 case '|': {
5175 Advance();
5176 builder->NewAlternative();
5177 continue;
5178 }
5179 case '*':
5180 case '+':
5181 case '?':
5182 return ReportError(CStrVector("Nothing to repeat"));
5183 case '^': {
5184 Advance();
5185 if (multiline_) {
5186 builder->AddAssertion(
Ben Murdoch8b112d22011-06-08 16:22:53 +01005187 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE));
Steve Blocka7e24c12009-10-30 11:49:00 +00005188 } else {
5189 builder->AddAssertion(
Ben Murdoch8b112d22011-06-08 16:22:53 +01005190 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
Steve Blocka7e24c12009-10-30 11:49:00 +00005191 set_contains_anchor();
5192 }
5193 continue;
5194 }
5195 case '$': {
5196 Advance();
5197 RegExpAssertion::Type type =
5198 multiline_ ? RegExpAssertion::END_OF_LINE :
5199 RegExpAssertion::END_OF_INPUT;
Ben Murdoch8b112d22011-06-08 16:22:53 +01005200 builder->AddAssertion(new(zone()) RegExpAssertion(type));
Steve Blocka7e24c12009-10-30 11:49:00 +00005201 continue;
5202 }
5203 case '.': {
5204 Advance();
5205 // everything except \x0a, \x0d, \u2028 and \u2029
Ben Murdoch257744e2011-11-30 15:57:28 +00005206 ZoneList<CharacterRange>* ranges =
5207 new(zone()) ZoneList<CharacterRange>(2);
Steve Blocka7e24c12009-10-30 11:49:00 +00005208 CharacterRange::AddClassEscape('.', ranges);
Ben Murdoch8b112d22011-06-08 16:22:53 +01005209 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00005210 builder->AddAtom(atom);
5211 break;
5212 }
5213 case '(': {
5214 SubexpressionType type = CAPTURE;
5215 Advance();
5216 if (current() == '?') {
5217 switch (Next()) {
5218 case ':':
5219 type = GROUPING;
5220 break;
5221 case '=':
5222 type = POSITIVE_LOOKAHEAD;
5223 break;
5224 case '!':
5225 type = NEGATIVE_LOOKAHEAD;
5226 break;
5227 default:
5228 ReportError(CStrVector("Invalid group") CHECK_FAILED);
5229 break;
5230 }
5231 Advance(2);
5232 } else {
5233 if (captures_ == NULL) {
Ben Murdoch257744e2011-11-30 15:57:28 +00005234 captures_ = new(zone()) ZoneList<RegExpCapture*>(2);
Steve Blocka7e24c12009-10-30 11:49:00 +00005235 }
5236 if (captures_started() >= kMaxCaptures) {
5237 ReportError(CStrVector("Too many captures") CHECK_FAILED);
5238 }
5239 captures_->Add(NULL);
5240 }
5241 // Store current state and begin new disjunction parsing.
Ben Murdoch8b112d22011-06-08 16:22:53 +01005242 stored_state = new(zone()) RegExpParserState(stored_state,
Steve Blocka7e24c12009-10-30 11:49:00 +00005243 type,
5244 captures_started());
5245 builder = stored_state->builder();
Ben Murdoche0cee9b2011-05-25 10:26:03 +01005246 continue;
Steve Blocka7e24c12009-10-30 11:49:00 +00005247 }
5248 case '[': {
5249 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED);
5250 builder->AddAtom(atom);
5251 break;
5252 }
5253 // Atom ::
5254 // \ AtomEscape
5255 case '\\':
5256 switch (Next()) {
5257 case kEndMarker:
5258 return ReportError(CStrVector("\\ at end of pattern"));
5259 case 'b':
5260 Advance(2);
5261 builder->AddAssertion(
Ben Murdoch8b112d22011-06-08 16:22:53 +01005262 new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
Steve Blocka7e24c12009-10-30 11:49:00 +00005263 continue;
5264 case 'B':
5265 Advance(2);
5266 builder->AddAssertion(
Ben Murdoch8b112d22011-06-08 16:22:53 +01005267 new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
Steve Blocka7e24c12009-10-30 11:49:00 +00005268 continue;
Ben Murdoche0cee9b2011-05-25 10:26:03 +01005269 // AtomEscape ::
5270 // CharacterClassEscape
5271 //
5272 // CharacterClassEscape :: one of
5273 // d D s S w W
Steve Blocka7e24c12009-10-30 11:49:00 +00005274 case 'd': case 'D': case 's': case 'S': case 'w': case 'W': {
5275 uc32 c = Next();
5276 Advance(2);
Ben Murdoch257744e2011-11-30 15:57:28 +00005277 ZoneList<CharacterRange>* ranges =
5278 new(zone()) ZoneList<CharacterRange>(2);
Steve Blocka7e24c12009-10-30 11:49:00 +00005279 CharacterRange::AddClassEscape(c, ranges);
Ben Murdoch8b112d22011-06-08 16:22:53 +01005280 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00005281 builder->AddAtom(atom);
5282 break;
5283 }
5284 case '1': case '2': case '3': case '4': case '5': case '6':
5285 case '7': case '8': case '9': {
5286 int index = 0;
5287 if (ParseBackReferenceIndex(&index)) {
5288 RegExpCapture* capture = NULL;
5289 if (captures_ != NULL && index <= captures_->length()) {
5290 capture = captures_->at(index - 1);
5291 }
5292 if (capture == NULL) {
5293 builder->AddEmpty();
5294 break;
5295 }
Ben Murdoch8b112d22011-06-08 16:22:53 +01005296 RegExpTree* atom = new(zone()) RegExpBackReference(capture);
Steve Blocka7e24c12009-10-30 11:49:00 +00005297 builder->AddAtom(atom);
5298 break;
5299 }
5300 uc32 first_digit = Next();
5301 if (first_digit == '8' || first_digit == '9') {
5302 // Treat as identity escape
5303 builder->AddCharacter(first_digit);
5304 Advance(2);
5305 break;
5306 }
5307 }
5308 // FALLTHROUGH
5309 case '0': {
5310 Advance();
5311 uc32 octal = ParseOctalLiteral();
5312 builder->AddCharacter(octal);
5313 break;
5314 }
5315 // ControlEscape :: one of
5316 // f n r t v
5317 case 'f':
5318 Advance(2);
5319 builder->AddCharacter('\f');
5320 break;
5321 case 'n':
5322 Advance(2);
5323 builder->AddCharacter('\n');
5324 break;
5325 case 'r':
5326 Advance(2);
5327 builder->AddCharacter('\r');
5328 break;
5329 case 't':
5330 Advance(2);
5331 builder->AddCharacter('\t');
5332 break;
5333 case 'v':
5334 Advance(2);
5335 builder->AddCharacter('\v');
5336 break;
5337 case 'c': {
Ben Murdoch086aeea2011-05-13 15:57:08 +01005338 Advance();
5339 uc32 controlLetter = Next();
5340 // Special case if it is an ASCII letter.
5341 // Convert lower case letters to uppercase.
5342 uc32 letter = controlLetter & ~('a' ^ 'A');
5343 if (letter < 'A' || 'Z' < letter) {
5344 // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
5345 // This is outside the specification. We match JSC in
5346 // reading the backslash as a literal character instead
5347 // of as starting an escape.
5348 builder->AddCharacter('\\');
5349 } else {
5350 Advance(2);
5351 builder->AddCharacter(controlLetter & 0x1f);
5352 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005353 break;
5354 }
5355 case 'x': {
5356 Advance(2);
5357 uc32 value;
5358 if (ParseHexEscape(2, &value)) {
5359 builder->AddCharacter(value);
5360 } else {
5361 builder->AddCharacter('x');
5362 }
5363 break;
5364 }
5365 case 'u': {
5366 Advance(2);
5367 uc32 value;
5368 if (ParseHexEscape(4, &value)) {
5369 builder->AddCharacter(value);
5370 } else {
5371 builder->AddCharacter('u');
5372 }
5373 break;
5374 }
5375 default:
5376 // Identity escape.
5377 builder->AddCharacter(Next());
5378 Advance(2);
5379 break;
5380 }
5381 break;
5382 case '{': {
5383 int dummy;
5384 if (ParseIntervalQuantifier(&dummy, &dummy)) {
5385 ReportError(CStrVector("Nothing to repeat") CHECK_FAILED);
5386 }
5387 // fallthrough
5388 }
5389 default:
5390 builder->AddCharacter(current());
5391 Advance();
5392 break;
5393 } // end switch(current())
5394
5395 int min;
5396 int max;
5397 switch (current()) {
5398 // QuantifierPrefix ::
5399 // *
5400 // +
5401 // ?
5402 // {
5403 case '*':
5404 min = 0;
5405 max = RegExpTree::kInfinity;
5406 Advance();
5407 break;
5408 case '+':
5409 min = 1;
5410 max = RegExpTree::kInfinity;
5411 Advance();
5412 break;
5413 case '?':
5414 min = 0;
5415 max = 1;
5416 Advance();
5417 break;
5418 case '{':
5419 if (ParseIntervalQuantifier(&min, &max)) {
5420 if (max < min) {
5421 ReportError(CStrVector("numbers out of order in {} quantifier.")
5422 CHECK_FAILED);
5423 }
5424 break;
5425 } else {
5426 continue;
5427 }
5428 default:
5429 continue;
5430 }
Leon Clarkee46be812010-01-19 14:06:41 +00005431 RegExpQuantifier::Type type = RegExpQuantifier::GREEDY;
Steve Blocka7e24c12009-10-30 11:49:00 +00005432 if (current() == '?') {
Leon Clarkee46be812010-01-19 14:06:41 +00005433 type = RegExpQuantifier::NON_GREEDY;
5434 Advance();
5435 } else if (FLAG_regexp_possessive_quantifier && current() == '+') {
5436 // FLAG_regexp_possessive_quantifier is a debug-only flag.
5437 type = RegExpQuantifier::POSSESSIVE;
Steve Blocka7e24c12009-10-30 11:49:00 +00005438 Advance();
5439 }
Leon Clarkee46be812010-01-19 14:06:41 +00005440 builder->AddQuantifierToAtom(min, max, type);
Steve Blocka7e24c12009-10-30 11:49:00 +00005441 }
5442}
5443
Steve Blocka7e24c12009-10-30 11:49:00 +00005444
5445#ifdef DEBUG
5446// Currently only used in an ASSERT.
5447static bool IsSpecialClassEscape(uc32 c) {
5448 switch (c) {
5449 case 'd': case 'D':
5450 case 's': case 'S':
5451 case 'w': case 'W':
5452 return true;
5453 default:
5454 return false;
5455 }
5456}
5457#endif
5458
5459
5460// In order to know whether an escape is a backreference or not we have to scan
5461// the entire regexp and find the number of capturing parentheses. However we
5462// don't want to scan the regexp twice unless it is necessary. This mini-parser
5463// is called when needed. It can see the difference between capturing and
5464// noncapturing parentheses and can skip character classes and backslash-escaped
5465// characters.
5466void RegExpParser::ScanForCaptures() {
5467 // Start with captures started previous to current position
5468 int capture_count = captures_started();
5469 // Add count of captures after this position.
5470 int n;
5471 while ((n = current()) != kEndMarker) {
5472 Advance();
5473 switch (n) {
5474 case '\\':
5475 Advance();
5476 break;
5477 case '[': {
5478 int c;
5479 while ((c = current()) != kEndMarker) {
5480 Advance();
5481 if (c == '\\') {
5482 Advance();
5483 } else {
5484 if (c == ']') break;
5485 }
5486 }
5487 break;
5488 }
5489 case '(':
5490 if (current() != '?') capture_count++;
5491 break;
5492 }
5493 }
5494 capture_count_ = capture_count;
5495 is_scanned_for_captures_ = true;
5496}
5497
5498
5499bool RegExpParser::ParseBackReferenceIndex(int* index_out) {
5500 ASSERT_EQ('\\', current());
5501 ASSERT('1' <= Next() && Next() <= '9');
5502 // Try to parse a decimal literal that is no greater than the total number
5503 // of left capturing parentheses in the input.
5504 int start = position();
5505 int value = Next() - '0';
5506 Advance(2);
5507 while (true) {
5508 uc32 c = current();
5509 if (IsDecimalDigit(c)) {
5510 value = 10 * value + (c - '0');
5511 if (value > kMaxCaptures) {
5512 Reset(start);
5513 return false;
5514 }
5515 Advance();
5516 } else {
5517 break;
5518 }
5519 }
5520 if (value > captures_started()) {
5521 if (!is_scanned_for_captures_) {
5522 int saved_position = position();
5523 ScanForCaptures();
5524 Reset(saved_position);
5525 }
5526 if (value > capture_count_) {
5527 Reset(start);
5528 return false;
5529 }
5530 }
5531 *index_out = value;
5532 return true;
5533}
5534
5535
5536// QuantifierPrefix ::
5537// { DecimalDigits }
5538// { DecimalDigits , }
5539// { DecimalDigits , DecimalDigits }
5540//
5541// Returns true if parsing succeeds, and set the min_out and max_out
5542// values. Values are truncated to RegExpTree::kInfinity if they overflow.
5543bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
5544 ASSERT_EQ(current(), '{');
5545 int start = position();
5546 Advance();
5547 int min = 0;
5548 if (!IsDecimalDigit(current())) {
5549 Reset(start);
5550 return false;
5551 }
5552 while (IsDecimalDigit(current())) {
5553 int next = current() - '0';
5554 if (min > (RegExpTree::kInfinity - next) / 10) {
5555 // Overflow. Skip past remaining decimal digits and return -1.
5556 do {
5557 Advance();
5558 } while (IsDecimalDigit(current()));
5559 min = RegExpTree::kInfinity;
5560 break;
5561 }
5562 min = 10 * min + next;
5563 Advance();
5564 }
5565 int max = 0;
5566 if (current() == '}') {
5567 max = min;
5568 Advance();
5569 } else if (current() == ',') {
5570 Advance();
5571 if (current() == '}') {
5572 max = RegExpTree::kInfinity;
5573 Advance();
5574 } else {
5575 while (IsDecimalDigit(current())) {
5576 int next = current() - '0';
5577 if (max > (RegExpTree::kInfinity - next) / 10) {
5578 do {
5579 Advance();
5580 } while (IsDecimalDigit(current()));
5581 max = RegExpTree::kInfinity;
5582 break;
5583 }
5584 max = 10 * max + next;
5585 Advance();
5586 }
5587 if (current() != '}') {
5588 Reset(start);
5589 return false;
5590 }
5591 Advance();
5592 }
5593 } else {
5594 Reset(start);
5595 return false;
5596 }
5597 *min_out = min;
5598 *max_out = max;
5599 return true;
5600}
5601
5602
Steve Blocka7e24c12009-10-30 11:49:00 +00005603uc32 RegExpParser::ParseOctalLiteral() {
5604 ASSERT('0' <= current() && current() <= '7');
5605 // For compatibility with some other browsers (not all), we parse
5606 // up to three octal digits with a value below 256.
5607 uc32 value = current() - '0';
5608 Advance();
5609 if ('0' <= current() && current() <= '7') {
5610 value = value * 8 + current() - '0';
5611 Advance();
5612 if (value < 32 && '0' <= current() && current() <= '7') {
5613 value = value * 8 + current() - '0';
5614 Advance();
5615 }
5616 }
5617 return value;
5618}
5619
5620
5621bool RegExpParser::ParseHexEscape(int length, uc32 *value) {
5622 int start = position();
5623 uc32 val = 0;
5624 bool done = false;
5625 for (int i = 0; !done; i++) {
5626 uc32 c = current();
5627 int d = HexValue(c);
5628 if (d < 0) {
5629 Reset(start);
5630 return false;
5631 }
5632 val = val * 16 + d;
5633 Advance();
5634 if (i == length - 1) {
5635 done = true;
5636 }
5637 }
5638 *value = val;
5639 return true;
5640}
5641
5642
5643uc32 RegExpParser::ParseClassCharacterEscape() {
5644 ASSERT(current() == '\\');
5645 ASSERT(has_next() && !IsSpecialClassEscape(Next()));
5646 Advance();
5647 switch (current()) {
5648 case 'b':
5649 Advance();
5650 return '\b';
5651 // ControlEscape :: one of
5652 // f n r t v
5653 case 'f':
5654 Advance();
5655 return '\f';
5656 case 'n':
5657 Advance();
5658 return '\n';
5659 case 'r':
5660 Advance();
5661 return '\r';
5662 case 't':
5663 Advance();
5664 return '\t';
5665 case 'v':
5666 Advance();
5667 return '\v';
Ben Murdoch086aeea2011-05-13 15:57:08 +01005668 case 'c': {
5669 uc32 controlLetter = Next();
5670 uc32 letter = controlLetter & ~('A' ^ 'a');
5671 // For compatibility with JSC, inside a character class
5672 // we also accept digits and underscore as control characters.
5673 if ((controlLetter >= '0' && controlLetter <= '9') ||
5674 controlLetter == '_' ||
5675 (letter >= 'A' && letter <= 'Z')) {
5676 Advance(2);
5677 // Control letters mapped to ASCII control characters in the range
5678 // 0x00-0x1f.
5679 return controlLetter & 0x1f;
5680 }
5681 // We match JSC in reading the backslash as a literal
5682 // character instead of as starting an escape.
5683 return '\\';
5684 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005685 case '0': case '1': case '2': case '3': case '4': case '5':
5686 case '6': case '7':
5687 // For compatibility, we interpret a decimal escape that isn't
5688 // a back reference (and therefore either \0 or not valid according
5689 // to the specification) as a 1..3 digit octal character code.
5690 return ParseOctalLiteral();
5691 case 'x': {
5692 Advance();
5693 uc32 value;
5694 if (ParseHexEscape(2, &value)) {
5695 return value;
5696 }
5697 // If \x is not followed by a two-digit hexadecimal, treat it
5698 // as an identity escape.
5699 return 'x';
5700 }
5701 case 'u': {
5702 Advance();
5703 uc32 value;
5704 if (ParseHexEscape(4, &value)) {
5705 return value;
5706 }
5707 // If \u is not followed by a four-digit hexadecimal, treat it
5708 // as an identity escape.
5709 return 'u';
5710 }
5711 default: {
5712 // Extended identity escape. We accept any character that hasn't
5713 // been matched by a more specific case, not just the subset required
5714 // by the ECMAScript specification.
5715 uc32 result = current();
5716 Advance();
5717 return result;
5718 }
5719 }
5720 return 0;
5721}
5722
5723
5724CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) {
5725 ASSERT_EQ(0, *char_class);
5726 uc32 first = current();
5727 if (first == '\\') {
5728 switch (Next()) {
5729 case 'w': case 'W': case 'd': case 'D': case 's': case 'S': {
5730 *char_class = Next();
5731 Advance(2);
5732 return CharacterRange::Singleton(0); // Return dummy value.
5733 }
5734 case kEndMarker:
5735 return ReportError(CStrVector("\\ at end of pattern"));
5736 default:
5737 uc32 c = ParseClassCharacterEscape(CHECK_FAILED);
5738 return CharacterRange::Singleton(c);
5739 }
5740 } else {
5741 Advance();
5742 return CharacterRange::Singleton(first);
5743 }
5744}
5745
5746
Ben Murdochb0fe1622011-05-05 13:52:32 +01005747static const uc16 kNoCharClass = 0;
5748
5749// Adds range or pre-defined character class to character ranges.
5750// If char_class is not kInvalidClass, it's interpreted as a class
5751// escape (i.e., 's' means whitespace, from '\s').
5752static inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges,
5753 uc16 char_class,
5754 CharacterRange range) {
5755 if (char_class != kNoCharClass) {
5756 CharacterRange::AddClassEscape(char_class, ranges);
5757 } else {
5758 ranges->Add(range);
5759 }
5760}
5761
5762
Steve Blocka7e24c12009-10-30 11:49:00 +00005763RegExpTree* RegExpParser::ParseCharacterClass() {
5764 static const char* kUnterminated = "Unterminated character class";
5765 static const char* kRangeOutOfOrder = "Range out of order in character class";
5766
5767 ASSERT_EQ(current(), '[');
5768 Advance();
5769 bool is_negated = false;
5770 if (current() == '^') {
5771 is_negated = true;
5772 Advance();
5773 }
Ben Murdoch257744e2011-11-30 15:57:28 +00005774 ZoneList<CharacterRange>* ranges = new(zone()) ZoneList<CharacterRange>(2);
Steve Blocka7e24c12009-10-30 11:49:00 +00005775 while (has_more() && current() != ']') {
Ben Murdochb0fe1622011-05-05 13:52:32 +01005776 uc16 char_class = kNoCharClass;
Steve Blocka7e24c12009-10-30 11:49:00 +00005777 CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED);
Steve Blocka7e24c12009-10-30 11:49:00 +00005778 if (current() == '-') {
5779 Advance();
5780 if (current() == kEndMarker) {
5781 // If we reach the end we break out of the loop and let the
5782 // following code report an error.
5783 break;
5784 } else if (current() == ']') {
Ben Murdochb0fe1622011-05-05 13:52:32 +01005785 AddRangeOrEscape(ranges, char_class, first);
Steve Blocka7e24c12009-10-30 11:49:00 +00005786 ranges->Add(CharacterRange::Singleton('-'));
5787 break;
5788 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01005789 uc16 char_class_2 = kNoCharClass;
5790 CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED);
5791 if (char_class != kNoCharClass || char_class_2 != kNoCharClass) {
5792 // Either end is an escaped character class. Treat the '-' verbatim.
5793 AddRangeOrEscape(ranges, char_class, first);
Steve Blocka7e24c12009-10-30 11:49:00 +00005794 ranges->Add(CharacterRange::Singleton('-'));
Ben Murdochb0fe1622011-05-05 13:52:32 +01005795 AddRangeOrEscape(ranges, char_class_2, next);
Steve Blocka7e24c12009-10-30 11:49:00 +00005796 continue;
5797 }
5798 if (first.from() > next.to()) {
5799 return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED);
5800 }
5801 ranges->Add(CharacterRange::Range(first.from(), next.to()));
5802 } else {
Ben Murdochb0fe1622011-05-05 13:52:32 +01005803 AddRangeOrEscape(ranges, char_class, first);
Steve Blocka7e24c12009-10-30 11:49:00 +00005804 }
5805 }
5806 if (!has_more()) {
5807 return ReportError(CStrVector(kUnterminated) CHECK_FAILED);
5808 }
5809 Advance();
5810 if (ranges->length() == 0) {
5811 ranges->Add(CharacterRange::Everything());
5812 is_negated = !is_negated;
5813 }
Ben Murdoch8b112d22011-06-08 16:22:53 +01005814 return new(zone()) RegExpCharacterClass(ranges, is_negated);
Steve Blocka7e24c12009-10-30 11:49:00 +00005815}
5816
5817
5818// ----------------------------------------------------------------------------
5819// The Parser interface.
5820
Steve Blocka7e24c12009-10-30 11:49:00 +00005821ParserMessage::~ParserMessage() {
5822 for (int i = 0; i < args().length(); i++)
5823 DeleteArray(args()[i]);
5824 DeleteArray(args().start());
5825}
5826
5827
5828ScriptDataImpl::~ScriptDataImpl() {
Iain Merrick9ac36c92010-09-13 15:29:50 +01005829 if (owns_store_) store_.Dispose();
Steve Blocka7e24c12009-10-30 11:49:00 +00005830}
5831
5832
5833int ScriptDataImpl::Length() {
Leon Clarkef7060e22010-06-03 12:02:55 +01005834 return store_.length() * sizeof(unsigned);
Steve Blocka7e24c12009-10-30 11:49:00 +00005835}
5836
5837
Leon Clarkef7060e22010-06-03 12:02:55 +01005838const char* ScriptDataImpl::Data() {
5839 return reinterpret_cast<const char*>(store_.start());
Steve Blocka7e24c12009-10-30 11:49:00 +00005840}
5841
5842
Leon Clarkee46be812010-01-19 14:06:41 +00005843bool ScriptDataImpl::HasError() {
5844 return has_error();
5845}
5846
5847
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005848void ScriptDataImpl::Initialize() {
5849 // Prepares state for use.
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005850 if (store_.length() >= PreparseDataConstants::kHeaderSize) {
5851 function_index_ = PreparseDataConstants::kHeaderSize;
5852 int symbol_data_offset = PreparseDataConstants::kHeaderSize
5853 + store_[PreparseDataConstants::kFunctionsSizeOffset];
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005854 if (store_.length() > symbol_data_offset) {
5855 symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]);
5856 } else {
5857 // Partial preparse causes no symbol information.
5858 symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
5859 }
5860 symbol_data_end_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
5861 }
5862}
5863
5864
5865int ScriptDataImpl::ReadNumber(byte** source) {
5866 // Reads a number from symbol_data_ in base 128. The most significant
5867 // bit marks that there are more digits.
5868 // If the first byte is 0x80 (kNumberTerminator), it would normally
5869 // represent a leading zero. Since that is useless, and therefore won't
5870 // appear as the first digit of any actual value, it is used to
5871 // mark the end of the input stream.
5872 byte* data = *source;
5873 if (data >= symbol_data_end_) return -1;
5874 byte input = *data;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005875 if (input == PreparseDataConstants::kNumberTerminator) {
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005876 // End of stream marker.
5877 return -1;
5878 }
5879 int result = input & 0x7f;
5880 data++;
5881 while ((input & 0x80u) != 0) {
5882 if (data >= symbol_data_end_) return -1;
5883 input = *data;
5884 result = (result << 7) | (input & 0x7f);
5885 data++;
5886 }
5887 *source = data;
5888 return result;
5889}
5890
5891
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005892// Create a Scanner for the preparser to use as input, and preparse the source.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005893static ScriptDataImpl* DoPreParse(Utf16CharacterStream* source,
5894 int flags,
5895 ParserRecorder* recorder) {
Steve Block44f0eee2011-05-26 01:26:41 +01005896 Isolate* isolate = Isolate::Current();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005897 HistogramTimerScope timer(isolate->counters()->pre_parse());
5898 Scanner scanner(isolate->unicode_cache());
5899 scanner.SetHarmonyScoping(FLAG_harmony_scoping);
Steve Block9fac8402011-05-12 15:51:54 +01005900 scanner.Initialize(source);
Steve Block44f0eee2011-05-26 01:26:41 +01005901 intptr_t stack_limit = isolate->stack_guard()->real_climit();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005902 preparser::PreParser::PreParseResult result =
5903 preparser::PreParser::PreParseProgram(&scanner,
5904 recorder,
5905 flags,
5906 stack_limit);
5907 if (result == preparser::PreParser::kPreParseStackOverflow) {
Steve Block44f0eee2011-05-26 01:26:41 +01005908 isolate->StackOverflow();
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005909 return NULL;
5910 }
5911
Kristian Monsen80d68ea2010-09-08 11:05:35 +01005912 // Extract the accumulated data from the recorder as a single
5913 // contiguous vector that we are responsible for disposing.
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005914 Vector<unsigned> store = recorder->ExtractData();
Steve Blocka7e24c12009-10-30 11:49:00 +00005915 return new ScriptDataImpl(store);
5916}
5917
5918
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005919// Preparse, but only collect data that is immediately useful,
5920// even if the preparser data is only used once.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005921ScriptDataImpl* ParserApi::PartialPreParse(Handle<String> source,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005922 v8::Extension* extension,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005923 int flags) {
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005924 bool allow_lazy = FLAG_lazy && (extension == NULL);
5925 if (!allow_lazy) {
5926 // Partial preparsing is only about lazily compiled functions.
5927 // If we don't allow lazy compilation, the log data will be empty.
5928 return NULL;
5929 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005930 flags |= kAllowLazy;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005931 PartialParserRecorder recorder;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005932 int source_length = source->length();
5933 if (source->IsExternalTwoByteString()) {
5934 ExternalTwoByteStringUtf16CharacterStream stream(
5935 Handle<ExternalTwoByteString>::cast(source), 0, source_length);
5936 return DoPreParse(&stream, flags, &recorder);
5937 } else {
5938 GenericStringUtf16CharacterStream stream(source, 0, source_length);
5939 return DoPreParse(&stream, flags, &recorder);
5940 }
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005941}
5942
5943
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005944ScriptDataImpl* ParserApi::PreParse(Utf16CharacterStream* source,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005945 v8::Extension* extension,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005946 int flags) {
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005947 Handle<Script> no_script;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005948 if (FLAG_lazy && (extension == NULL)) {
5949 flags |= kAllowLazy;
5950 }
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005951 CompleteParserRecorder recorder;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005952 return DoPreParse(source, flags, &recorder);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005953}
5954
5955
5956bool RegExpParser::ParseRegExp(FlatStringReader* input,
5957 bool multiline,
5958 RegExpCompileData* result) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005959 ASSERT(result != NULL);
5960 RegExpParser parser(input, &result->error, multiline);
5961 RegExpTree* tree = parser.ParsePattern();
5962 if (parser.failed()) {
5963 ASSERT(tree == NULL);
5964 ASSERT(!result->error.is_null());
5965 } else {
5966 ASSERT(tree != NULL);
5967 ASSERT(result->error.is_null());
5968 result->tree = tree;
5969 int capture_count = parser.captures_started();
5970 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
5971 result->contains_anchor = parser.contains_anchor();
5972 result->capture_count = capture_count;
5973 }
5974 return !parser.failed();
5975}
5976
5977
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005978bool ParserApi::Parse(CompilationInfo* info, int parsing_flags) {
Ben Murdochf87a2032010-10-22 12:50:53 +01005979 ASSERT(info->function() == NULL);
5980 FunctionLiteral* result = NULL;
5981 Handle<Script> script = info->script();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005982 ASSERT((parsing_flags & kLanguageModeMask) == CLASSIC_MODE);
5983 if (!info->is_native() && FLAG_harmony_scoping) {
5984 // Harmony scoping is requested.
5985 parsing_flags |= EXTENDED_MODE;
5986 }
5987 if (!info->is_native() && FLAG_harmony_modules) {
5988 parsing_flags |= kAllowModules;
5989 }
5990 if (FLAG_allow_natives_syntax || info->is_native()) {
5991 // We require %identifier(..) syntax.
5992 parsing_flags |= kAllowNativesSyntax;
5993 }
Ben Murdochf87a2032010-10-22 12:50:53 +01005994 if (info->is_lazy()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005995 ASSERT(!info->is_eval());
5996 Parser parser(script, parsing_flags, NULL, NULL);
5997 if (info->shared_info()->is_function()) {
5998 result = parser.ParseLazy(info);
5999 } else {
6000 result = parser.ParseProgram(info);
6001 }
Leon Clarke4515c472010-02-03 11:58:03 +00006002 } else {
Ben Murdochf87a2032010-10-22 12:50:53 +01006003 ScriptDataImpl* pre_data = info->pre_parse_data();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006004 Parser parser(script, parsing_flags, info->extension(), pre_data);
Ben Murdochf87a2032010-10-22 12:50:53 +01006005 if (pre_data != NULL && pre_data->has_error()) {
6006 Scanner::Location loc = pre_data->MessageLocation();
6007 const char* message = pre_data->BuildMessage();
6008 Vector<const char*> args = pre_data->BuildArgs();
6009 parser.ReportMessageAt(loc, message, args);
6010 DeleteArray(message);
6011 for (int i = 0; i < args.length(); i++) {
6012 DeleteArray(args[i]);
6013 }
6014 DeleteArray(args.start());
Steve Block44f0eee2011-05-26 01:26:41 +01006015 ASSERT(info->isolate()->has_pending_exception());
Ben Murdochf87a2032010-10-22 12:50:53 +01006016 } else {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006017 result = parser.ParseProgram(info);
Ben Murdochf87a2032010-10-22 12:50:53 +01006018 }
Leon Clarke4515c472010-02-03 11:58:03 +00006019 }
Ben Murdochf87a2032010-10-22 12:50:53 +01006020 info->SetFunction(result);
6021 return (result != NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00006022}
6023
Steve Blocka7e24c12009-10-30 11:49:00 +00006024} } // namespace v8::internal