blob: f9500c405b837eb8aab67c1e82b7c48e3684676d [file] [log] [blame]
Ben Murdoch8b112d22011-06-08 16:22:53 +01001// Copyright 2011 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 Murdoch257744e2011-11-30 15:57:28 +000031#include "ast-inl.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(
261 scanner().literal_uc16_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(
282 scanner().literal_uc16_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
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800410Scope* Parser::NewScope(Scope* parent, Scope::Type type, bool inside_with) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100411 Scope* result = new(zone()) Scope(parent, type);
Steve Blocka7e24c12009-10-30 11:49:00 +0000412 result->Initialize(inside_with);
413 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// ----------------------------------------------------------------------------
462// LexicalScope is a support class to facilitate manipulation of the
463// Parser's scope stack. The constructor sets the parser's top scope
464// to the incoming scope, and the destructor resets it.
Steve Block44f0eee2011-05-26 01:26:41 +0100465//
Ben Murdoch8b112d22011-06-08 16:22:53 +0100466// Additionally, it stores transient information used during parsing.
Steve Block44f0eee2011-05-26 01:26:41 +0100467// These scopes are not kept around after parsing or referenced by syntax
468// trees so they can be stack-allocated and hence used by the pre-parser.
Steve Blocka7e24c12009-10-30 11:49:00 +0000469
470class LexicalScope BASE_EMBEDDED {
471 public:
Steve Block44f0eee2011-05-26 01:26:41 +0100472 LexicalScope(Parser* parser, Scope* scope, Isolate* isolate);
473 ~LexicalScope();
474
475 int NextMaterializedLiteralIndex() {
476 int next_index =
477 materialized_literal_count_ + JSFunction::kLiteralsPrefixSize;
478 materialized_literal_count_++;
479 return next_index;
480 }
481 int materialized_literal_count() { return materialized_literal_count_; }
482
483 void SetThisPropertyAssignmentInfo(
484 bool only_simple_this_property_assignments,
485 Handle<FixedArray> this_property_assignments) {
486 only_simple_this_property_assignments_ =
487 only_simple_this_property_assignments;
488 this_property_assignments_ = this_property_assignments;
489 }
490 bool only_simple_this_property_assignments() {
491 return only_simple_this_property_assignments_;
492 }
493 Handle<FixedArray> this_property_assignments() {
494 return this_property_assignments_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000495 }
496
Steve Block44f0eee2011-05-26 01:26:41 +0100497 void AddProperty() { expected_property_count_++; }
498 int expected_property_count() { return expected_property_count_; }
499
Steve Blocka7e24c12009-10-30 11:49:00 +0000500 private:
Steve Block44f0eee2011-05-26 01:26:41 +0100501 // Captures the number of literals that need materialization in the
502 // function. Includes regexp literals, and boilerplate for object
503 // and array literals.
504 int materialized_literal_count_;
505
506 // Properties count estimation.
507 int expected_property_count_;
508
509 // Keeps track of assignments to properties of this. Used for
510 // optimizing constructors.
511 bool only_simple_this_property_assignments_;
512 Handle<FixedArray> this_property_assignments_;
513
Steve Block44f0eee2011-05-26 01:26:41 +0100514 // Bookkeeping
515 Parser* parser_;
516 // Previous values
517 LexicalScope* lexical_scope_parent_;
518 Scope* previous_scope_;
519 int previous_with_nesting_level_;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100520 unsigned previous_ast_node_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000521};
522
Steve Block44f0eee2011-05-26 01:26:41 +0100523
524LexicalScope::LexicalScope(Parser* parser, Scope* scope, Isolate* isolate)
525 : materialized_literal_count_(0),
526 expected_property_count_(0),
527 only_simple_this_property_assignments_(false),
528 this_property_assignments_(isolate->factory()->empty_fixed_array()),
Steve Block44f0eee2011-05-26 01:26:41 +0100529 parser_(parser),
530 lexical_scope_parent_(parser->lexical_scope_),
531 previous_scope_(parser->top_scope_),
Ben Murdoch8b112d22011-06-08 16:22:53 +0100532 previous_with_nesting_level_(parser->with_nesting_level_),
533 previous_ast_node_id_(isolate->ast_node_id()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100534 parser->top_scope_ = scope;
535 parser->lexical_scope_ = this;
536 parser->with_nesting_level_ = 0;
Ben Murdoch589d6972011-11-30 16:04:58 +0000537 isolate->set_ast_node_id(AstNode::kDeclarationsId + 1);
Steve Block44f0eee2011-05-26 01:26:41 +0100538}
539
540
541LexicalScope::~LexicalScope() {
Steve Block44f0eee2011-05-26 01:26:41 +0100542 parser_->top_scope_ = previous_scope_;
543 parser_->lexical_scope_ = lexical_scope_parent_;
544 parser_->with_nesting_level_ = previous_with_nesting_level_;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100545 parser_->isolate()->set_ast_node_id(previous_ast_node_id_);
Steve Block44f0eee2011-05-26 01:26:41 +0100546}
547
548
Steve Blocka7e24c12009-10-30 11:49:00 +0000549// ----------------------------------------------------------------------------
550// The CHECK_OK macro is a convenient macro to enforce error
551// handling for functions that may fail (by returning !*ok).
552//
553// CAUTION: This macro appends extra statements after a call,
554// thus it must never be used where only a single statement
555// is correct (e.g. an if statement branch w/o braces)!
556
557#define CHECK_OK ok); \
558 if (!*ok) return NULL; \
559 ((void)0
560#define DUMMY ) // to make indentation work
561#undef DUMMY
562
563#define CHECK_FAILED /**/); \
564 if (failed_) return NULL; \
565 ((void)0
566#define DUMMY ) // to make indentation work
567#undef DUMMY
568
569// ----------------------------------------------------------------------------
570// Implementation of Parser
571
572Parser::Parser(Handle<Script> script,
573 bool allow_natives_syntax,
574 v8::Extension* extension,
Steve Blocka7e24c12009-10-30 11:49:00 +0000575 ScriptDataImpl* pre_data)
Steve Block44f0eee2011-05-26 01:26:41 +0100576 : isolate_(script->GetIsolate()),
577 symbol_cache_(pre_data ? pre_data->symbol_count() : 0),
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800578 script_(script),
Ben Murdoch8b112d22011-06-08 16:22:53 +0100579 scanner_(isolate_->unicode_cache()),
Steve Blocka7e24c12009-10-30 11:49:00 +0000580 top_scope_(NULL),
581 with_nesting_level_(0),
Steve Block44f0eee2011-05-26 01:26:41 +0100582 lexical_scope_(NULL),
Steve Blocka7e24c12009-10-30 11:49:00 +0000583 target_stack_(NULL),
584 allow_natives_syntax_(allow_natives_syntax),
585 extension_(extension),
Steve Block6ded16b2010-05-10 14:33:55 +0100586 pre_data_(pre_data),
Ben Murdochb0fe1622011-05-05 13:52:32 +0100587 fni_(NULL),
Ben Murdochb8e0da22011-05-16 14:20:40 +0100588 stack_overflow_(false),
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000589 parenthesized_function_(false),
590 harmony_block_scoping_(false) {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100591 AstNode::ResetIds();
Steve Blocka7e24c12009-10-30 11:49:00 +0000592}
593
594
Steve Blocka7e24c12009-10-30 11:49:00 +0000595FunctionLiteral* Parser::ParseProgram(Handle<String> source,
Steve Block1e0659c2011-05-24 12:43:12 +0100596 bool in_global_context,
597 StrictModeFlag strict_mode) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000598 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
Steve Blocka7e24c12009-10-30 11:49:00 +0000599
Steve Block44f0eee2011-05-26 01:26:41 +0100600 HistogramTimerScope timer(isolate()->counters()->parse());
601 isolate()->counters()->total_parse_size()->Increment(source->length());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000602 fni_ = new(zone()) FuncNameInferrer(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +0000603
604 // Initialize parser state.
Steve Block6ded16b2010-05-10 14:33:55 +0100605 source->TryFlatten();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100606 if (source->IsExternalTwoByteString()) {
607 // Notice that the stream is destroyed at the end of the branch block.
608 // The last line of the blocks can't be moved outside, even though they're
609 // identical calls.
610 ExternalTwoByteStringUC16CharacterStream stream(
611 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
Steve Block9fac8402011-05-12 15:51:54 +0100612 scanner_.Initialize(&stream);
Steve Block1e0659c2011-05-24 12:43:12 +0100613 return DoParseProgram(source, in_global_context, strict_mode, &zone_scope);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100614 } else {
615 GenericStringUC16CharacterStream stream(source, 0, source->length());
Steve Block9fac8402011-05-12 15:51:54 +0100616 scanner_.Initialize(&stream);
Steve Block1e0659c2011-05-24 12:43:12 +0100617 return DoParseProgram(source, in_global_context, strict_mode, &zone_scope);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100618 }
619}
620
621
622FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
623 bool in_global_context,
Steve Block1e0659c2011-05-24 12:43:12 +0100624 StrictModeFlag strict_mode,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100625 ZoneScope* zone_scope) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000626 ASSERT(target_stack_ == NULL);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100627 if (pre_data_ != NULL) pre_data_->Initialize();
Steve Blocka7e24c12009-10-30 11:49:00 +0000628
629 // Compute the parsing mode.
630 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY;
631 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY;
632
633 Scope::Type type =
634 in_global_context
635 ? Scope::GLOBAL_SCOPE
636 : Scope::EVAL_SCOPE;
Steve Block44f0eee2011-05-26 01:26:41 +0100637 Handle<String> no_name = isolate()->factory()->empty_symbol();
Steve Blocka7e24c12009-10-30 11:49:00 +0000638
639 FunctionLiteral* result = NULL;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800640 { Scope* scope = NewScope(top_scope_, type, inside_with());
Steve Block44f0eee2011-05-26 01:26:41 +0100641 LexicalScope lexical_scope(this, scope, isolate());
Steve Block1e0659c2011-05-24 12:43:12 +0100642 if (strict_mode == kStrictMode) {
Steve Block44f0eee2011-05-26 01:26:41 +0100643 top_scope_->EnableStrictMode();
Steve Block1e0659c2011-05-24 12:43:12 +0100644 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000645 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16);
Steve Blocka7e24c12009-10-30 11:49:00 +0000646 bool ok = true;
Steve Block1e0659c2011-05-24 12:43:12 +0100647 int beg_loc = scanner().location().beg_pos;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800648 ParseSourceElements(body, Token::EOS, &ok);
Steve Block44f0eee2011-05-26 01:26:41 +0100649 if (ok && top_scope_->is_strict_mode()) {
Steve Block1e0659c2011-05-24 12:43:12 +0100650 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
651 }
Ben Murdoch589d6972011-11-30 16:04:58 +0000652
653 if (ok && harmony_block_scoping_) {
654 CheckConflictingVarDeclarations(scope, &ok);
655 }
656
Steve Blocka7e24c12009-10-30 11:49:00 +0000657 if (ok) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100658 result = new(zone()) FunctionLiteral(
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000659 isolate(),
Steve Blocka7e24c12009-10-30 11:49:00 +0000660 no_name,
661 top_scope_,
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800662 body,
Steve Block44f0eee2011-05-26 01:26:41 +0100663 lexical_scope.materialized_literal_count(),
664 lexical_scope.expected_property_count(),
665 lexical_scope.only_simple_this_property_assignments(),
666 lexical_scope.this_property_assignments(),
Steve Blocka7e24c12009-10-30 11:49:00 +0000667 0,
668 0,
669 source->length(),
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000670 FunctionLiteral::ANONYMOUS_EXPRESSION,
671 false); // Does not have duplicate parameters.
Ben Murdochb0fe1622011-05-05 13:52:32 +0100672 } else if (stack_overflow_) {
Steve Block44f0eee2011-05-26 01:26:41 +0100673 isolate()->StackOverflow();
Steve Blocka7e24c12009-10-30 11:49:00 +0000674 }
675 }
676
677 // Make sure the target stack is empty.
678 ASSERT(target_stack_ == NULL);
679
680 // If there was a syntax error we have to get rid of the AST
681 // and it is not safe to do so before the scope has been deleted.
Ben Murdochb0fe1622011-05-05 13:52:32 +0100682 if (result == NULL) zone_scope->DeleteOnExit();
Steve Blocka7e24c12009-10-30 11:49:00 +0000683 return result;
684}
685
Steve Block44f0eee2011-05-26 01:26:41 +0100686FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000687 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
Steve Block44f0eee2011-05-26 01:26:41 +0100688 HistogramTimerScope timer(isolate()->counters()->parse_lazy());
Ben Murdochf87a2032010-10-22 12:50:53 +0100689 Handle<String> source(String::cast(script_->source()));
Steve Block44f0eee2011-05-26 01:26:41 +0100690 isolate()->counters()->total_parse_size()->Increment(source->length());
Steve Blocka7e24c12009-10-30 11:49:00 +0000691
Steve Block44f0eee2011-05-26 01:26:41 +0100692 Handle<SharedFunctionInfo> shared_info = info->shared_info();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100693 // Initialize parser state.
694 source->TryFlatten();
695 if (source->IsExternalTwoByteString()) {
696 ExternalTwoByteStringUC16CharacterStream stream(
697 Handle<ExternalTwoByteString>::cast(source),
Steve Block44f0eee2011-05-26 01:26:41 +0100698 shared_info->start_position(),
699 shared_info->end_position());
Ben Murdochb0fe1622011-05-05 13:52:32 +0100700 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope);
701 return result;
702 } else {
703 GenericStringUC16CharacterStream stream(source,
Steve Block44f0eee2011-05-26 01:26:41 +0100704 shared_info->start_position(),
705 shared_info->end_position());
Ben Murdochb0fe1622011-05-05 13:52:32 +0100706 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope);
707 return result;
708 }
709}
710
711
Steve Block44f0eee2011-05-26 01:26:41 +0100712FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100713 UC16CharacterStream* source,
714 ZoneScope* zone_scope) {
Steve Block44f0eee2011-05-26 01:26:41 +0100715 Handle<SharedFunctionInfo> shared_info = info->shared_info();
Steve Block9fac8402011-05-12 15:51:54 +0100716 scanner_.Initialize(source);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100717 ASSERT(target_stack_ == NULL);
718
Steve Block44f0eee2011-05-26 01:26:41 +0100719 Handle<String> name(String::cast(shared_info->name()));
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000720 fni_ = new(zone()) FuncNameInferrer(isolate());
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100721 fni_->PushEnclosingName(name);
722
Steve Blocka7e24c12009-10-30 11:49:00 +0000723 mode_ = PARSE_EAGERLY;
724
725 // Place holder for the result.
726 FunctionLiteral* result = NULL;
727
728 {
729 // Parse the function literal.
Steve Block44f0eee2011-05-26 01:26:41 +0100730 Scope* scope = NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with());
731 if (!info->closure().is_null()) {
732 scope = Scope::DeserializeScopeChain(info, scope);
733 }
734 LexicalScope lexical_scope(this, scope, isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +0000735
Steve Block44f0eee2011-05-26 01:26:41 +0100736 if (shared_info->strict_mode()) {
737 top_scope_->EnableStrictMode();
Steve Block1e0659c2011-05-24 12:43:12 +0100738 }
739
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000740 FunctionLiteral::Type type = shared_info->is_expression()
741 ? (shared_info->is_anonymous()
742 ? FunctionLiteral::ANONYMOUS_EXPRESSION
743 : FunctionLiteral::NAMED_EXPRESSION)
744 : FunctionLiteral::DECLARATION;
Steve Blocka7e24c12009-10-30 11:49:00 +0000745 bool ok = true;
Steve Block1e0659c2011-05-24 12:43:12 +0100746 result = ParseFunctionLiteral(name,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000747 false, // Strict mode name already checked.
748 RelocInfo::kNoPosition,
749 type,
750 &ok);
Steve Blocka7e24c12009-10-30 11:49:00 +0000751 // Make sure the results agree.
752 ASSERT(ok == (result != NULL));
Steve Blocka7e24c12009-10-30 11:49:00 +0000753 }
754
755 // Make sure the target stack is empty.
756 ASSERT(target_stack_ == NULL);
757
758 // If there was a stack overflow we have to get rid of AST and it is
759 // not safe to do before scope has been deleted.
760 if (result == NULL) {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100761 zone_scope->DeleteOnExit();
Steve Block44f0eee2011-05-26 01:26:41 +0100762 if (stack_overflow_) isolate()->StackOverflow();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100763 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100764 Handle<String> inferred_name(shared_info->inferred_name());
Ben Murdochb0fe1622011-05-05 13:52:32 +0100765 result->set_inferred_name(inferred_name);
Steve Blocka7e24c12009-10-30 11:49:00 +0000766 }
767 return result;
768}
769
Ben Murdochf87a2032010-10-22 12:50:53 +0100770
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800771Handle<String> Parser::GetSymbol(bool* ok) {
772 int symbol_id = -1;
773 if (pre_data() != NULL) {
774 symbol_id = pre_data()->GetSymbolIdentifier();
Leon Clarke4515c472010-02-03 11:58:03 +0000775 }
Steve Block9fac8402011-05-12 15:51:54 +0100776 return LookupSymbol(symbol_id);
Leon Clarke4515c472010-02-03 11:58:03 +0000777}
Steve Blocka7e24c12009-10-30 11:49:00 +0000778
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800779
Steve Blocka7e24c12009-10-30 11:49:00 +0000780void Parser::ReportMessage(const char* type, Vector<const char*> args) {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100781 Scanner::Location source_location = scanner().location();
Steve Blocka7e24c12009-10-30 11:49:00 +0000782 ReportMessageAt(source_location, type, args);
783}
784
785
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800786void Parser::ReportMessageAt(Scanner::Location source_location,
787 const char* type,
788 Vector<const char*> args) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000789 MessageLocation location(script_,
Ben Murdochb8e0da22011-05-16 14:20:40 +0100790 source_location.beg_pos,
791 source_location.end_pos);
Steve Block44f0eee2011-05-26 01:26:41 +0100792 Factory* factory = isolate()->factory();
793 Handle<FixedArray> elements = factory->NewFixedArray(args.length());
Steve Blocka7e24c12009-10-30 11:49:00 +0000794 for (int i = 0; i < args.length(); i++) {
Steve Block44f0eee2011-05-26 01:26:41 +0100795 Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i]));
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100796 elements->set(i, *arg_string);
Steve Blocka7e24c12009-10-30 11:49:00 +0000797 }
Steve Block44f0eee2011-05-26 01:26:41 +0100798 Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
799 Handle<Object> result = factory->NewSyntaxError(type, array);
800 isolate()->Throw(*result, &location);
Steve Blocka7e24c12009-10-30 11:49:00 +0000801}
802
803
Ben Murdochb8e0da22011-05-16 14:20:40 +0100804void Parser::ReportMessageAt(Scanner::Location source_location,
805 const char* type,
806 Vector<Handle<String> > args) {
807 MessageLocation location(script_,
808 source_location.beg_pos,
809 source_location.end_pos);
Steve Block44f0eee2011-05-26 01:26:41 +0100810 Factory* factory = isolate()->factory();
811 Handle<FixedArray> elements = factory->NewFixedArray(args.length());
Ben Murdochb8e0da22011-05-16 14:20:40 +0100812 for (int i = 0; i < args.length(); i++) {
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100813 elements->set(i, *args[i]);
Ben Murdochb8e0da22011-05-16 14:20:40 +0100814 }
Steve Block44f0eee2011-05-26 01:26:41 +0100815 Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
816 Handle<Object> result = factory->NewSyntaxError(type, array);
817 isolate()->Throw(*result, &location);
Ben Murdochb8e0da22011-05-16 14:20:40 +0100818}
819
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000820void Parser::SetHarmonyBlockScoping(bool block_scoping) {
821 scanner().SetHarmonyBlockScoping(block_scoping);
822 harmony_block_scoping_ = block_scoping;
823}
Ben Murdochb8e0da22011-05-16 14:20:40 +0100824
Steve Blocka7e24c12009-10-30 11:49:00 +0000825// Base class containing common code for the different finder classes used by
826// the parser.
827class ParserFinder {
828 protected:
829 ParserFinder() {}
830 static Assignment* AsAssignment(Statement* stat) {
831 if (stat == NULL) return NULL;
832 ExpressionStatement* exp_stat = stat->AsExpressionStatement();
833 if (exp_stat == NULL) return NULL;
834 return exp_stat->expression()->AsAssignment();
835 }
836};
837
838
839// An InitializationBlockFinder finds and marks sequences of statements of the
Steve Blockd0582a62009-12-15 09:54:21 +0000840// form expr.a = ...; expr.b = ...; etc.
Steve Blocka7e24c12009-10-30 11:49:00 +0000841class InitializationBlockFinder : public ParserFinder {
842 public:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000843 // We find and mark the initialization blocks in top level
844 // non-looping code only. This is because the optimization prevents
845 // reuse of the map transitions, so it should be used only for code
846 // that will only be run once.
847 InitializationBlockFinder(Scope* top_scope, Target* target)
848 : enabled_(top_scope->DeclarationScope()->is_global_scope() &&
849 !IsLoopTarget(target)),
850 first_in_block_(NULL),
851 last_in_block_(NULL),
852 block_size_(0) {}
Steve Blocka7e24c12009-10-30 11:49:00 +0000853
854 ~InitializationBlockFinder() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000855 if (!enabled_) return;
Steve Blocka7e24c12009-10-30 11:49:00 +0000856 if (InBlock()) EndBlock();
857 }
858
859 void Update(Statement* stat) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000860 if (!enabled_) return;
Steve Blocka7e24c12009-10-30 11:49:00 +0000861 Assignment* assignment = AsAssignment(stat);
862 if (InBlock()) {
863 if (BlockContinues(assignment)) {
864 UpdateBlock(assignment);
865 } else {
866 EndBlock();
867 }
868 }
869 if (!InBlock() && (assignment != NULL) &&
870 (assignment->op() == Token::ASSIGN)) {
871 StartBlock(assignment);
872 }
873 }
874
875 private:
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800876 // The minimum number of contiguous assignment that will
877 // be treated as an initialization block. Benchmarks show that
878 // the overhead exceeds the savings below this limit.
879 static const int kMinInitializationBlock = 3;
880
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000881 static bool IsLoopTarget(Target* target) {
882 while (target != NULL) {
883 if (target->node()->AsIterationStatement() != NULL) return true;
884 target = target->previous();
885 }
886 return false;
887 }
888
Steve Blocka7e24c12009-10-30 11:49:00 +0000889 // Returns true if the expressions appear to denote the same object.
890 // In the context of initialization blocks, we only consider expressions
Steve Blockd0582a62009-12-15 09:54:21 +0000891 // of the form 'expr.x' or expr["x"].
Steve Blocka7e24c12009-10-30 11:49:00 +0000892 static bool SameObject(Expression* e1, Expression* e2) {
893 VariableProxy* v1 = e1->AsVariableProxy();
894 VariableProxy* v2 = e2->AsVariableProxy();
895 if (v1 != NULL && v2 != NULL) {
896 return v1->name()->Equals(*v2->name());
897 }
898 Property* p1 = e1->AsProperty();
899 Property* p2 = e2->AsProperty();
900 if ((p1 == NULL) || (p2 == NULL)) return false;
901 Literal* key1 = p1->key()->AsLiteral();
902 Literal* key2 = p2->key()->AsLiteral();
903 if ((key1 == NULL) || (key2 == NULL)) return false;
904 if (!key1->handle()->IsString() || !key2->handle()->IsString()) {
905 return false;
906 }
907 String* name1 = String::cast(*key1->handle());
908 String* name2 = String::cast(*key2->handle());
909 if (!name1->Equals(name2)) return false;
910 return SameObject(p1->obj(), p2->obj());
911 }
912
913 // Returns true if the expressions appear to denote different properties
914 // of the same object.
915 static bool PropertyOfSameObject(Expression* e1, Expression* e2) {
916 Property* p1 = e1->AsProperty();
917 Property* p2 = e2->AsProperty();
918 if ((p1 == NULL) || (p2 == NULL)) return false;
919 return SameObject(p1->obj(), p2->obj());
920 }
921
922 bool BlockContinues(Assignment* assignment) {
923 if ((assignment == NULL) || (first_in_block_ == NULL)) return false;
924 if (assignment->op() != Token::ASSIGN) return false;
925 return PropertyOfSameObject(first_in_block_->target(),
926 assignment->target());
927 }
928
929 void StartBlock(Assignment* assignment) {
930 first_in_block_ = assignment;
931 last_in_block_ = assignment;
932 block_size_ = 1;
933 }
934
935 void UpdateBlock(Assignment* assignment) {
936 last_in_block_ = assignment;
937 ++block_size_;
938 }
939
940 void EndBlock() {
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800941 if (block_size_ >= kMinInitializationBlock) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000942 first_in_block_->mark_block_start();
943 last_in_block_->mark_block_end();
944 }
945 last_in_block_ = first_in_block_ = NULL;
946 block_size_ = 0;
947 }
948
949 bool InBlock() { return first_in_block_ != NULL; }
950
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000951 const bool enabled_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000952 Assignment* first_in_block_;
953 Assignment* last_in_block_;
954 int block_size_;
955
956 DISALLOW_COPY_AND_ASSIGN(InitializationBlockFinder);
957};
958
959
Ben Murdoch589d6972011-11-30 16:04:58 +0000960// A ThisNamedPropertyAssigmentFinder finds and marks statements of the form
Steve Blocka7e24c12009-10-30 11:49:00 +0000961// this.x = ...;, where x is a named property. It also determines whether a
962// function contains only assignments of this type.
Ben Murdoch589d6972011-11-30 16:04:58 +0000963class ThisNamedPropertyAssigmentFinder : public ParserFinder {
Steve Blocka7e24c12009-10-30 11:49:00 +0000964 public:
Ben Murdoch589d6972011-11-30 16:04:58 +0000965 explicit ThisNamedPropertyAssigmentFinder(Isolate* isolate)
Steve Block44f0eee2011-05-26 01:26:41 +0100966 : isolate_(isolate),
967 only_simple_this_property_assignments_(true),
Ben Murdoch589d6972011-11-30 16:04:58 +0000968 names_(NULL),
969 assigned_arguments_(NULL),
970 assigned_constants_(NULL) {}
Steve Blocka7e24c12009-10-30 11:49:00 +0000971
972 void Update(Scope* scope, Statement* stat) {
Steve Blockd0582a62009-12-15 09:54:21 +0000973 // Bail out if function already has property assignment that are
974 // not simple this property assignments.
975 if (!only_simple_this_property_assignments_) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000976 return;
977 }
978
979 // Check whether this statement is of the form this.x = ...;
980 Assignment* assignment = AsAssignment(stat);
981 if (IsThisPropertyAssignment(assignment)) {
982 HandleThisPropertyAssignment(scope, assignment);
983 } else {
Steve Blocka7e24c12009-10-30 11:49:00 +0000984 only_simple_this_property_assignments_ = false;
985 }
986 }
987
Steve Blocka7e24c12009-10-30 11:49:00 +0000988 // Returns whether only statements of the form this.x = y; where y is either a
989 // constant or a function argument was encountered.
990 bool only_simple_this_property_assignments() {
991 return only_simple_this_property_assignments_;
992 }
993
994 // Returns a fixed array containing three elements for each assignment of the
995 // form this.x = y;
996 Handle<FixedArray> GetThisPropertyAssignments() {
Ben Murdoch589d6972011-11-30 16:04:58 +0000997 if (names_ == NULL) {
Steve Block44f0eee2011-05-26 01:26:41 +0100998 return isolate_->factory()->empty_fixed_array();
Steve Blocka7e24c12009-10-30 11:49:00 +0000999 }
Ben Murdoch589d6972011-11-30 16:04:58 +00001000 ASSERT(names_ != NULL);
1001 ASSERT(assigned_arguments_ != NULL);
1002 ASSERT_EQ(names_->length(), assigned_arguments_->length());
1003 ASSERT_EQ(names_->length(), assigned_constants_->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00001004 Handle<FixedArray> assignments =
Ben Murdoch589d6972011-11-30 16:04:58 +00001005 isolate_->factory()->NewFixedArray(names_->length() * 3);
1006 for (int i = 0; i < names_->length(); i++) {
1007 assignments->set(i * 3, *names_->at(i));
1008 assignments->set(i * 3 + 1, Smi::FromInt(assigned_arguments_->at(i)));
1009 assignments->set(i * 3 + 2, *assigned_constants_->at(i));
Steve Blocka7e24c12009-10-30 11:49:00 +00001010 }
1011 return assignments;
1012 }
1013
1014 private:
1015 bool IsThisPropertyAssignment(Assignment* assignment) {
1016 if (assignment != NULL) {
1017 Property* property = assignment->target()->AsProperty();
1018 return assignment->op() == Token::ASSIGN
1019 && property != NULL
1020 && property->obj()->AsVariableProxy() != NULL
1021 && property->obj()->AsVariableProxy()->is_this();
1022 }
1023 return false;
1024 }
1025
1026 void HandleThisPropertyAssignment(Scope* scope, Assignment* assignment) {
Steve Block6ded16b2010-05-10 14:33:55 +01001027 // Check that the property assigned to is a named property, which is not
1028 // __proto__.
Steve Blocka7e24c12009-10-30 11:49:00 +00001029 Property* property = assignment->target()->AsProperty();
1030 ASSERT(property != NULL);
1031 Literal* literal = property->key()->AsLiteral();
1032 uint32_t dummy;
1033 if (literal != NULL &&
1034 literal->handle()->IsString() &&
Steve Block44f0eee2011-05-26 01:26:41 +01001035 !String::cast(*(literal->handle()))->Equals(
1036 isolate_->heap()->Proto_symbol()) &&
Steve Blocka7e24c12009-10-30 11:49:00 +00001037 !String::cast(*(literal->handle()))->AsArrayIndex(&dummy)) {
1038 Handle<String> key = Handle<String>::cast(literal->handle());
1039
1040 // Check whether the value assigned is either a constant or matches the
1041 // name of one of the arguments to the function.
1042 if (assignment->value()->AsLiteral() != NULL) {
1043 // Constant assigned.
1044 Literal* literal = assignment->value()->AsLiteral();
1045 AssignmentFromConstant(key, literal->handle());
Steve Blockd0582a62009-12-15 09:54:21 +00001046 return;
Steve Blocka7e24c12009-10-30 11:49:00 +00001047 } else if (assignment->value()->AsVariableProxy() != NULL) {
1048 // Variable assigned.
1049 Handle<String> name =
1050 assignment->value()->AsVariableProxy()->name();
1051 // Check whether the variable assigned matches an argument name.
Steve Blocka7e24c12009-10-30 11:49:00 +00001052 for (int i = 0; i < scope->num_parameters(); i++) {
1053 if (*scope->parameter(i)->name() == *name) {
1054 // Assigned from function argument.
Steve Blockd0582a62009-12-15 09:54:21 +00001055 AssignmentFromParameter(key, i);
1056 return;
Steve Blocka7e24c12009-10-30 11:49:00 +00001057 }
1058 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001059 }
1060 }
Steve Blockd0582a62009-12-15 09:54:21 +00001061 // It is not a simple "this.x = value;" assignment with a constant
1062 // or parameter value.
1063 AssignmentFromSomethingElse();
Steve Blocka7e24c12009-10-30 11:49:00 +00001064 }
1065
1066 void AssignmentFromParameter(Handle<String> name, int index) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001067 EnsureAllocation();
1068 names_->Add(name);
1069 assigned_arguments_->Add(index);
1070 assigned_constants_->Add(isolate_->factory()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00001071 }
1072
1073 void AssignmentFromConstant(Handle<String> name, Handle<Object> value) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001074 EnsureAllocation();
1075 names_->Add(name);
1076 assigned_arguments_->Add(-1);
1077 assigned_constants_->Add(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00001078 }
1079
Steve Blockd0582a62009-12-15 09:54:21 +00001080 void AssignmentFromSomethingElse() {
Steve Blocka7e24c12009-10-30 11:49:00 +00001081 // The this assignment is not a simple one.
1082 only_simple_this_property_assignments_ = false;
1083 }
1084
Ben Murdoch589d6972011-11-30 16:04:58 +00001085 void EnsureAllocation() {
1086 if (names_ == NULL) {
1087 ASSERT(assigned_arguments_ == NULL);
1088 ASSERT(assigned_constants_ == NULL);
1089 Zone* zone = isolate_->zone();
1090 names_ = new(zone) ZoneStringList(4);
1091 assigned_arguments_ = new(zone) ZoneList<int>(4);
1092 assigned_constants_ = new(zone) ZoneObjectList(4);
Steve Blocka7e24c12009-10-30 11:49:00 +00001093 }
1094 }
1095
Steve Block44f0eee2011-05-26 01:26:41 +01001096 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001097 bool only_simple_this_property_assignments_;
Ben Murdoch589d6972011-11-30 16:04:58 +00001098 ZoneStringList* names_;
1099 ZoneList<int>* assigned_arguments_;
1100 ZoneObjectList* assigned_constants_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001101};
1102
1103
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001104Statement* Parser::ParseSourceElement(ZoneStringList* labels,
1105 bool* ok) {
1106 if (peek() == Token::FUNCTION) {
1107 // FunctionDeclaration is only allowed in the context of SourceElements
1108 // (Ecma 262 5th Edition, clause 14):
1109 // SourceElement:
1110 // Statement
1111 // FunctionDeclaration
1112 // Common language extension is to allow function declaration in place
1113 // of any statement. This language extension is disabled in strict mode.
1114 return ParseFunctionDeclaration(ok);
1115 } else if (peek() == Token::LET) {
1116 return ParseVariableStatement(kSourceElement, ok);
1117 } else {
1118 return ParseStatement(labels, ok);
1119 }
1120}
1121
1122
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001123void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
Steve Blocka7e24c12009-10-30 11:49:00 +00001124 int end_token,
1125 bool* ok) {
1126 // SourceElements ::
1127 // (Statement)* <end_token>
1128
1129 // Allocate a target stack to use for this set of source
1130 // elements. This way, all scripts and functions get their own
1131 // target stack thus avoiding illegal breaks and continues across
1132 // functions.
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001133 TargetScope scope(&this->target_stack_);
Steve Blocka7e24c12009-10-30 11:49:00 +00001134
1135 ASSERT(processor != NULL);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001136 InitializationBlockFinder block_finder(top_scope_, target_stack_);
Ben Murdoch589d6972011-11-30 16:04:58 +00001137 ThisNamedPropertyAssigmentFinder this_property_assignment_finder(isolate());
Steve Block1e0659c2011-05-24 12:43:12 +01001138 bool directive_prologue = true; // Parsing directive prologue.
1139
Steve Blocka7e24c12009-10-30 11:49:00 +00001140 while (peek() != end_token) {
Steve Block1e0659c2011-05-24 12:43:12 +01001141 if (directive_prologue && peek() != Token::STRING) {
1142 directive_prologue = false;
1143 }
1144
1145 Scanner::Location token_loc = scanner().peek_location();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001146 Statement* stat = ParseSourceElement(NULL, CHECK_OK);
Steve Block1e0659c2011-05-24 12:43:12 +01001147 if (stat == NULL || stat->IsEmpty()) {
1148 directive_prologue = false; // End of directive prologue.
1149 continue;
1150 }
1151
1152 if (directive_prologue) {
1153 // A shot at a directive.
1154 ExpressionStatement *e_stat;
1155 Literal *literal;
1156 // Still processing directive prologue?
1157 if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1158 (literal = e_stat->expression()->AsLiteral()) != NULL &&
1159 literal->handle()->IsString()) {
1160 Handle<String> directive = Handle<String>::cast(literal->handle());
1161
1162 // Check "use strict" directive (ES5 14.1).
Steve Block44f0eee2011-05-26 01:26:41 +01001163 if (!top_scope_->is_strict_mode() &&
1164 directive->Equals(isolate()->heap()->use_strict()) &&
Steve Block1e0659c2011-05-24 12:43:12 +01001165 token_loc.end_pos - token_loc.beg_pos ==
Steve Block44f0eee2011-05-26 01:26:41 +01001166 isolate()->heap()->use_strict()->length() + 2) {
1167 top_scope_->EnableStrictMode();
Steve Block1e0659c2011-05-24 12:43:12 +01001168 // "use strict" is the only directive for now.
1169 directive_prologue = false;
1170 }
1171 } else {
1172 // End of the directive prologue.
1173 directive_prologue = false;
1174 }
1175 }
1176
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001177 block_finder.Update(stat);
Steve Blocka7e24c12009-10-30 11:49:00 +00001178 // Find and mark all assignments to named properties in this (this.x =)
1179 if (top_scope_->is_function_scope()) {
1180 this_property_assignment_finder.Update(top_scope_, stat);
1181 }
1182 processor->Add(stat);
1183 }
1184
1185 // Propagate the collected information on this property assignments.
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001186 if (top_scope_->is_function_scope()) {
Steve Blockd0582a62009-12-15 09:54:21 +00001187 bool only_simple_this_property_assignments =
Andrei Popescu402d9372010-02-26 13:31:12 +00001188 this_property_assignment_finder.only_simple_this_property_assignments()
1189 && top_scope_->declarations()->length() == 0;
Steve Blockd0582a62009-12-15 09:54:21 +00001190 if (only_simple_this_property_assignments) {
Steve Block44f0eee2011-05-26 01:26:41 +01001191 lexical_scope_->SetThisPropertyAssignmentInfo(
Steve Blockd0582a62009-12-15 09:54:21 +00001192 only_simple_this_property_assignments,
Steve Blocka7e24c12009-10-30 11:49:00 +00001193 this_property_assignment_finder.GetThisPropertyAssignments());
1194 }
1195 }
1196 return 0;
1197}
1198
1199
1200Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
1201 // Statement ::
1202 // Block
1203 // VariableStatement
1204 // EmptyStatement
1205 // ExpressionStatement
1206 // IfStatement
1207 // IterationStatement
1208 // ContinueStatement
1209 // BreakStatement
1210 // ReturnStatement
1211 // WithStatement
1212 // LabelledStatement
1213 // SwitchStatement
1214 // ThrowStatement
1215 // TryStatement
1216 // DebuggerStatement
1217
1218 // Note: Since labels can only be used by 'break' and 'continue'
1219 // statements, which themselves are only valid within blocks,
1220 // iterations or 'switch' statements (i.e., BreakableStatements),
1221 // labels can be simply ignored in all other cases; except for
1222 // trivial labeled break statements 'label: break label' which is
1223 // parsed into an empty statement.
1224
1225 // Keep the source position of the statement
1226 int statement_pos = scanner().peek_location().beg_pos;
1227 Statement* stmt = NULL;
1228 switch (peek()) {
1229 case Token::LBRACE:
1230 return ParseBlock(labels, ok);
1231
1232 case Token::CONST: // fall through
1233 case Token::VAR:
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001234 stmt = ParseVariableStatement(kStatement, ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001235 break;
1236
1237 case Token::SEMICOLON:
1238 Next();
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001239 return EmptyStatement();
Steve Blocka7e24c12009-10-30 11:49:00 +00001240
1241 case Token::IF:
1242 stmt = ParseIfStatement(labels, ok);
1243 break;
1244
1245 case Token::DO:
Steve Block3ce2e202009-11-05 08:53:23 +00001246 stmt = ParseDoWhileStatement(labels, ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001247 break;
1248
1249 case Token::WHILE:
1250 stmt = ParseWhileStatement(labels, ok);
1251 break;
1252
1253 case Token::FOR:
1254 stmt = ParseForStatement(labels, ok);
1255 break;
1256
1257 case Token::CONTINUE:
1258 stmt = ParseContinueStatement(ok);
1259 break;
1260
1261 case Token::BREAK:
1262 stmt = ParseBreakStatement(labels, ok);
1263 break;
1264
1265 case Token::RETURN:
1266 stmt = ParseReturnStatement(ok);
1267 break;
1268
1269 case Token::WITH:
1270 stmt = ParseWithStatement(labels, ok);
1271 break;
1272
1273 case Token::SWITCH:
1274 stmt = ParseSwitchStatement(labels, ok);
1275 break;
1276
1277 case Token::THROW:
1278 stmt = ParseThrowStatement(ok);
1279 break;
1280
1281 case Token::TRY: {
1282 // NOTE: It is somewhat complicated to have labels on
1283 // try-statements. When breaking out of a try-finally statement,
1284 // one must take great care not to treat it as a
1285 // fall-through. It is much easier just to wrap the entire
1286 // try-statement in a statement block and put the labels there
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001287 Block* result = new(zone()) Block(isolate(), labels, 1, false);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001288 Target target(&this->target_stack_, result);
Steve Blocka7e24c12009-10-30 11:49:00 +00001289 TryStatement* statement = ParseTryStatement(CHECK_OK);
1290 if (statement) {
1291 statement->set_statement_pos(statement_pos);
1292 }
1293 if (result) result->AddStatement(statement);
1294 return result;
1295 }
1296
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001297 case Token::FUNCTION: {
1298 // In strict mode, FunctionDeclaration is only allowed in the context
1299 // of SourceElements.
Steve Block44f0eee2011-05-26 01:26:41 +01001300 if (top_scope_->is_strict_mode()) {
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001301 ReportMessageAt(scanner().peek_location(), "strict_function",
1302 Vector<const char*>::empty());
1303 *ok = false;
1304 return NULL;
1305 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001306 return ParseFunctionDeclaration(ok);
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001307 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001308
Steve Blocka7e24c12009-10-30 11:49:00 +00001309 case Token::DEBUGGER:
1310 stmt = ParseDebuggerStatement(ok);
1311 break;
1312
1313 default:
1314 stmt = ParseExpressionOrLabelledStatement(labels, ok);
1315 }
1316
1317 // Store the source position of the statement
1318 if (stmt != NULL) stmt->set_statement_pos(statement_pos);
1319 return stmt;
1320}
1321
1322
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001323VariableProxy* Parser::Declare(Handle<String> name,
1324 Variable::Mode mode,
1325 FunctionLiteral* fun,
1326 bool resolve,
1327 bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001328 Variable* var = NULL;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001329 // If we are inside a function, a declaration of a var/const variable is a
1330 // truly local variable, and the scope of the variable is always the function
1331 // scope.
Steve Blocka7e24c12009-10-30 11:49:00 +00001332
1333 // If a function scope exists, then we can statically declare this
1334 // variable and also set its mode. In any case, a Declaration node
1335 // will be added to the scope so that the declaration can be added
1336 // to the corresponding activation frame at runtime if necessary.
1337 // For instance declarations inside an eval scope need to be added
1338 // to the calling function context.
Ben Murdoch257744e2011-11-30 15:57:28 +00001339 // Similarly, strict mode eval scope does not leak variable declarations to
1340 // the caller's scope so we declare all locals, too.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001341
1342 Scope* declaration_scope = mode == Variable::LET ? top_scope_
1343 : top_scope_->DeclarationScope();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001344 if (declaration_scope->is_function_scope() ||
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001345 declaration_scope->is_strict_mode_eval_scope() ||
1346 declaration_scope->is_block_scope()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001347 // Declare the variable in the function scope.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001348 var = declaration_scope->LocalLookup(name);
Steve Blocka7e24c12009-10-30 11:49:00 +00001349 if (var == NULL) {
1350 // Declare the name.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001351 var = declaration_scope->DeclareLocal(name, mode);
Steve Blocka7e24c12009-10-30 11:49:00 +00001352 } else {
Ben Murdoch589d6972011-11-30 16:04:58 +00001353 // The name was declared in this scope before; check for conflicting
1354 // re-declarations. We have a conflict if either of the declarations is
1355 // not a var. There is similar code in runtime.cc in the Declare
1356 // functions. The function CheckNonConflictingScope checks for conflicting
1357 // var and let bindings from different scopes whereas this is a check for
1358 // conflicting declarations within the same scope. This check also covers
1359 //
1360 // function () { let x; { var x; } }
1361 //
1362 // because the var declaration is hoisted to the function scope where 'x'
1363 // is already bound.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001364 if ((mode != Variable::VAR) || (var->mode() != Variable::VAR)) {
1365 // We only have vars, consts and lets in declarations.
Steve Blocka7e24c12009-10-30 11:49:00 +00001366 ASSERT(var->mode() == Variable::VAR ||
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001367 var->mode() == Variable::CONST ||
1368 var->mode() == Variable::LET);
Ben Murdoch589d6972011-11-30 16:04:58 +00001369 if (harmony_block_scoping_) {
1370 // In harmony mode we treat re-declarations as early errors. See
1371 // ES5 16 for a definition of early errors.
1372 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
1373 const char* elms[2] = { "Variable", *c_string };
1374 Vector<const char*> args(elms, 2);
1375 ReportMessage("redeclaration", args);
1376 *ok = false;
1377 return NULL;
1378 }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001379 const char* type = (var->mode() == Variable::VAR) ? "var" :
1380 (var->mode() == Variable::CONST) ? "const" : "let";
Steve Blocka7e24c12009-10-30 11:49:00 +00001381 Handle<String> type_string =
Steve Block44f0eee2011-05-26 01:26:41 +01001382 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00001383 Expression* expression =
Steve Block44f0eee2011-05-26 01:26:41 +01001384 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(),
Steve Blocka7e24c12009-10-30 11:49:00 +00001385 type_string, name);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001386 declaration_scope->SetIllegalRedeclaration(expression);
Steve Blocka7e24c12009-10-30 11:49:00 +00001387 }
1388 }
1389 }
1390
1391 // We add a declaration node for every declaration. The compiler
1392 // will only generate code if necessary. In particular, declarations
1393 // for inner local variables that do not represent functions won't
1394 // result in any generated code.
1395 //
1396 // Note that we always add an unresolved proxy even if it's not
1397 // used, simply because we don't know in this method (w/o extra
1398 // parameters) if the proxy is needed or not. The proxy will be
1399 // bound during variable resolution time unless it was pre-bound
1400 // below.
1401 //
1402 // WARNING: This will lead to multiple declaration nodes for the
1403 // same variable if it is declared several times. This is not a
1404 // semantic issue as long as we keep the source order, but it may be
1405 // a performance issue since it may lead to repeated
1406 // Runtime::DeclareContextSlot() calls.
Ben Murdoch589d6972011-11-30 16:04:58 +00001407 VariableProxy* proxy = declaration_scope->NewUnresolved(
1408 name, false, scanner().location().beg_pos);
1409 declaration_scope->AddDeclaration(
1410 new(zone()) Declaration(proxy, mode, fun, top_scope_));
Steve Blocka7e24c12009-10-30 11:49:00 +00001411
1412 // For global const variables we bind the proxy to a variable.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001413 if (mode == Variable::CONST && declaration_scope->is_global_scope()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001414 ASSERT(resolve); // should be set by all callers
1415 Variable::Kind kind = Variable::NORMAL;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001416 var = new(zone()) Variable(declaration_scope,
1417 name,
1418 Variable::CONST,
1419 true,
1420 kind);
Steve Blocka7e24c12009-10-30 11:49:00 +00001421 }
1422
1423 // If requested and we have a local variable, bind the proxy to the variable
1424 // at parse-time. This is used for functions (and consts) declared inside
1425 // statements: the corresponding function (or const) variable must be in the
1426 // function scope and not a statement-local scope, e.g. as provided with a
1427 // 'with' statement:
1428 //
1429 // with (obj) {
1430 // function f() {}
1431 // }
1432 //
1433 // which is translated into:
1434 //
1435 // with (obj) {
1436 // // in this case this is not: 'var f; f = function () {};'
1437 // var f = function () {};
1438 // }
1439 //
1440 // Note that if 'f' is accessed from inside the 'with' statement, it
1441 // will be allocated in the context (because we must be able to look
1442 // it up dynamically) but it will also be accessed statically, i.e.,
1443 // with a context slot index and a context chain length for this
1444 // initialization code. Thus, inside the 'with' statement, we need
1445 // both access to the static and the dynamic context chain; the
1446 // runtime needs to provide both.
1447 if (resolve && var != NULL) proxy->BindTo(var);
1448
1449 return proxy;
1450}
1451
1452
1453// Language extension which is only enabled for source files loaded
1454// through the API's extension mechanism. A native function
1455// declaration is resolved by looking up the function through a
1456// callback provided by the extension.
1457Statement* Parser::ParseNativeDeclaration(bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001458 Expect(Token::FUNCTION, CHECK_OK);
1459 Handle<String> name = ParseIdentifier(CHECK_OK);
1460 Expect(Token::LPAREN, CHECK_OK);
1461 bool done = (peek() == Token::RPAREN);
1462 while (!done) {
1463 ParseIdentifier(CHECK_OK);
1464 done = (peek() == Token::RPAREN);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001465 if (!done) {
1466 Expect(Token::COMMA, CHECK_OK);
1467 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001468 }
1469 Expect(Token::RPAREN, CHECK_OK);
1470 Expect(Token::SEMICOLON, CHECK_OK);
1471
Steve Blocka7e24c12009-10-30 11:49:00 +00001472 // Make sure that the function containing the native declaration
1473 // isn't lazily compiled. The extension structures are only
1474 // accessible while parsing the first time not when reparsing
1475 // because of lazy compilation.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001476 top_scope_->DeclarationScope()->ForceEagerCompilation();
Steve Blocka7e24c12009-10-30 11:49:00 +00001477
1478 // Compute the function template for the native function.
1479 v8::Handle<v8::FunctionTemplate> fun_template =
1480 extension_->GetNativeFunction(v8::Utils::ToLocal(name));
1481 ASSERT(!fun_template.IsEmpty());
1482
Steve Block6ded16b2010-05-10 14:33:55 +01001483 // Instantiate the function and create a shared function info from it.
Steve Blocka7e24c12009-10-30 11:49:00 +00001484 Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->GetFunction());
1485 const int literals = fun->NumberOfLiterals();
1486 Handle<Code> code = Handle<Code>(fun->shared()->code());
Leon Clarkee46be812010-01-19 14:06:41 +00001487 Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
Steve Block6ded16b2010-05-10 14:33:55 +01001488 Handle<SharedFunctionInfo> shared =
Steve Block44f0eee2011-05-26 01:26:41 +01001489 isolate()->factory()->NewSharedFunctionInfo(name, literals, code,
Ben Murdoch3bec4d22010-07-22 14:51:16 +01001490 Handle<SerializedScopeInfo>(fun->shared()->scope_info()));
Steve Block6ded16b2010-05-10 14:33:55 +01001491 shared->set_construct_stub(*construct_stub);
Steve Blocka7e24c12009-10-30 11:49:00 +00001492
Steve Block6ded16b2010-05-10 14:33:55 +01001493 // Copy the function data to the shared function info.
1494 shared->set_function_data(fun->shared()->function_data());
Steve Blocka7e24c12009-10-30 11:49:00 +00001495 int parameters = fun->shared()->formal_parameter_count();
Steve Block6ded16b2010-05-10 14:33:55 +01001496 shared->set_formal_parameter_count(parameters);
Steve Blocka7e24c12009-10-30 11:49:00 +00001497
1498 // TODO(1240846): It's weird that native function declarations are
1499 // introduced dynamically when we meet their declarations, whereas
1500 // other functions are setup when entering the surrounding scope.
Ben Murdoch8b112d22011-06-08 16:22:53 +01001501 SharedFunctionInfoLiteral* lit =
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001502 new(zone()) SharedFunctionInfoLiteral(isolate(), shared);
Steve Blocka7e24c12009-10-30 11:49:00 +00001503 VariableProxy* var = Declare(name, Variable::VAR, NULL, true, CHECK_OK);
Ben Murdoch8b112d22011-06-08 16:22:53 +01001504 return new(zone()) ExpressionStatement(new(zone()) Assignment(
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001505 isolate(), Token::INIT_VAR, var, lit, RelocInfo::kNoPosition));
Steve Blocka7e24c12009-10-30 11:49:00 +00001506}
1507
1508
1509Statement* Parser::ParseFunctionDeclaration(bool* ok) {
1510 // FunctionDeclaration ::
1511 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
1512 Expect(Token::FUNCTION, CHECK_OK);
1513 int function_token_position = scanner().location().beg_pos;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001514 bool is_strict_reserved = false;
1515 Handle<String> name = ParseIdentifierOrStrictReservedWord(
1516 &is_strict_reserved, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00001517 FunctionLiteral* fun = ParseFunctionLiteral(name,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001518 is_strict_reserved,
Steve Blocka7e24c12009-10-30 11:49:00 +00001519 function_token_position,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001520 FunctionLiteral::DECLARATION,
Steve Blocka7e24c12009-10-30 11:49:00 +00001521 CHECK_OK);
1522 // Even if we're not at the top-level of the global or a function
1523 // scope, we treat is as such and introduce the function with it's
1524 // initial value upon entering the corresponding scope.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001525 Variable::Mode mode = harmony_block_scoping_ ? Variable::LET : Variable::VAR;
1526 Declare(name, mode, fun, true, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001527 return EmptyStatement();
Steve Blocka7e24c12009-10-30 11:49:00 +00001528}
1529
1530
1531Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001532 if (harmony_block_scoping_) return ParseScopedBlock(labels, ok);
1533
Steve Blocka7e24c12009-10-30 11:49:00 +00001534 // Block ::
1535 // '{' Statement* '}'
1536
1537 // Note that a Block does not introduce a new execution scope!
1538 // (ECMA-262, 3rd, 12.2)
1539 //
1540 // Construct block expecting 16 statements.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001541 Block* result = new(zone()) Block(isolate(), labels, 16, false);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001542 Target target(&this->target_stack_, result);
Steve Blocka7e24c12009-10-30 11:49:00 +00001543 Expect(Token::LBRACE, CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001544 InitializationBlockFinder block_finder(top_scope_, target_stack_);
Steve Blocka7e24c12009-10-30 11:49:00 +00001545 while (peek() != Token::RBRACE) {
1546 Statement* stat = ParseStatement(NULL, CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001547 if (stat && !stat->IsEmpty()) {
1548 result->AddStatement(stat);
1549 block_finder.Update(stat);
1550 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001551 }
1552 Expect(Token::RBRACE, CHECK_OK);
1553 return result;
1554}
1555
1556
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001557Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) {
1558 // Construct block expecting 16 statements.
1559 Block* body = new(zone()) Block(isolate(), labels, 16, false);
1560 Scope* saved_scope = top_scope_;
1561 Scope* block_scope = NewScope(top_scope_,
1562 Scope::BLOCK_SCOPE,
1563 inside_with());
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001564 if (top_scope_->is_strict_mode()) {
1565 block_scope->EnableStrictMode();
1566 }
1567 top_scope_ = block_scope;
1568
1569 // Parse the statements and collect escaping labels.
1570 TargetCollector collector;
1571 Target target(&this->target_stack_, &collector);
1572 Expect(Token::LBRACE, CHECK_OK);
1573 {
1574 Target target_body(&this->target_stack_, body);
1575 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1576
1577 while (peek() != Token::RBRACE) {
1578 Statement* stat = ParseSourceElement(NULL, CHECK_OK);
1579 if (stat && !stat->IsEmpty()) {
1580 body->AddStatement(stat);
1581 block_finder.Update(stat);
1582 }
1583 }
1584 }
1585 Expect(Token::RBRACE, CHECK_OK);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001586 top_scope_ = saved_scope;
1587
Ben Murdoch589d6972011-11-30 16:04:58 +00001588 block_scope = block_scope->FinalizeBlockScope();
1589 body->set_block_scope(block_scope);
1590 return body;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001591}
1592
1593
1594Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
1595 bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001596 // VariableStatement ::
1597 // VariableDeclarations ';'
1598
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001599 Handle<String> ignore;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001600 Block* result = ParseVariableDeclarations(var_context,
1601 &ignore,
1602 CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00001603 ExpectSemicolon(CHECK_OK);
1604 return result;
1605}
1606
Steve Block44f0eee2011-05-26 01:26:41 +01001607
1608bool Parser::IsEvalOrArguments(Handle<String> string) {
1609 return string.is_identical_to(isolate()->factory()->eval_symbol()) ||
1610 string.is_identical_to(isolate()->factory()->arguments_symbol());
Steve Block1e0659c2011-05-24 12:43:12 +01001611}
Steve Blocka7e24c12009-10-30 11:49:00 +00001612
Steve Block44f0eee2011-05-26 01:26:41 +01001613
Steve Blocka7e24c12009-10-30 11:49:00 +00001614// If the variable declaration declares exactly one non-const
1615// variable, then *var is set to that variable. In all other cases,
1616// *var is untouched; in particular, it is the caller's responsibility
1617// to initialize it properly. This mechanism is used for the parsing
1618// of 'for-in' loops.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001619Block* Parser::ParseVariableDeclarations(VariableDeclarationContext var_context,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001620 Handle<String>* out,
Steve Blocka7e24c12009-10-30 11:49:00 +00001621 bool* ok) {
1622 // VariableDeclarations ::
1623 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
1624
1625 Variable::Mode mode = Variable::VAR;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001626 // True if the binding needs initialization. 'let' and 'const' declared
1627 // bindings are created uninitialized by their declaration nodes and
1628 // need initialization. 'var' declared bindings are always initialized
1629 // immediately by their declaration nodes.
1630 bool needs_init = false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001631 bool is_const = false;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001632 Token::Value init_op = Token::INIT_VAR;
Steve Blocka7e24c12009-10-30 11:49:00 +00001633 if (peek() == Token::VAR) {
1634 Consume(Token::VAR);
1635 } else if (peek() == Token::CONST) {
1636 Consume(Token::CONST);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001637 if (top_scope_->is_strict_mode()) {
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001638 ReportMessage("strict_const", Vector<const char*>::empty());
1639 *ok = false;
1640 return NULL;
1641 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001642 mode = Variable::CONST;
1643 is_const = true;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001644 needs_init = true;
1645 init_op = Token::INIT_CONST;
1646 } else if (peek() == Token::LET) {
1647 Consume(Token::LET);
1648 if (var_context != kSourceElement &&
1649 var_context != kForStatement) {
1650 ASSERT(var_context == kStatement);
1651 ReportMessage("unprotected_let", Vector<const char*>::empty());
1652 *ok = false;
1653 return NULL;
1654 }
1655 mode = Variable::LET;
1656 needs_init = true;
1657 init_op = Token::INIT_LET;
Steve Blocka7e24c12009-10-30 11:49:00 +00001658 } else {
1659 UNREACHABLE(); // by current callers
1660 }
1661
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001662 Scope* declaration_scope = mode == Variable::LET
1663 ? top_scope_ : top_scope_->DeclarationScope();
1664 // The scope of a var/const declared variable anywhere inside a function
Steve Blocka7e24c12009-10-30 11:49:00 +00001665 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001666 // transform a source-level var/const declaration into a (Function)
Steve Blocka7e24c12009-10-30 11:49:00 +00001667 // Scope declaration, and rewrite the source-level initialization into an
1668 // assignment statement. We use a block to collect multiple assignments.
1669 //
1670 // We mark the block as initializer block because we don't want the
1671 // rewriter to add a '.result' assignment to such a block (to get compliant
1672 // behavior for code such as print(eval('var x = 7')), and for cosmetic
1673 // reasons when pretty-printing. Also, unless an assignment (initialization)
1674 // is inside an initializer block, it is ignored.
1675 //
1676 // Create new block with one expected declaration.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001677 Block* block = new(zone()) Block(isolate(), NULL, 1, true);
Steve Blocka7e24c12009-10-30 11:49:00 +00001678 int nvars = 0; // the number of variables declared
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001679 Handle<String> name;
Steve Blocka7e24c12009-10-30 11:49:00 +00001680 do {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001681 if (fni_ != NULL) fni_->Enter();
1682
Steve Blocka7e24c12009-10-30 11:49:00 +00001683 // Parse variable name.
1684 if (nvars > 0) Consume(Token::COMMA);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001685 name = ParseIdentifier(CHECK_OK);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001686 if (fni_ != NULL) fni_->PushVariableName(name);
Steve Blocka7e24c12009-10-30 11:49:00 +00001687
Steve Block1e0659c2011-05-24 12:43:12 +01001688 // Strict mode variables may not be named eval or arguments
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001689 if (declaration_scope->is_strict_mode() && IsEvalOrArguments(name)) {
Steve Block1e0659c2011-05-24 12:43:12 +01001690 ReportMessage("strict_var_name", Vector<const char*>::empty());
1691 *ok = false;
1692 return NULL;
1693 }
1694
Steve Blocka7e24c12009-10-30 11:49:00 +00001695 // Declare variable.
1696 // Note that we *always* must treat the initial value via a separate init
1697 // assignment for variables and constants because the value must be assigned
1698 // when the variable is encountered in the source. But the variable/constant
1699 // is declared (and set to 'undefined') upon entering the function within
1700 // which the variable or constant is declared. Only function variables have
1701 // an initial value in the declaration (because they are initialized upon
1702 // entering the function).
1703 //
1704 // If we have a const declaration, in an inner scope, the proxy is always
1705 // bound to the declared variable (independent of possibly surrounding with
1706 // statements).
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001707 Declare(name, mode, NULL, is_const /* always bound for CONST! */,
1708 CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00001709 nvars++;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001710 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
Steve Block053d10c2011-06-13 19:13:29 +01001711 ReportMessageAt(scanner().location(), "too_many_variables",
1712 Vector<const char*>::empty());
1713 *ok = false;
1714 return NULL;
1715 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001716
1717 // Parse initialization expression if present and/or needed. A
1718 // declaration of the form:
1719 //
1720 // var v = x;
1721 //
1722 // is syntactic sugar for:
1723 //
1724 // var v; v = x;
1725 //
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001726 // In particular, we need to re-lookup 'v' (in top_scope_, not
1727 // declaration_scope) as it may be a different 'v' than the 'v' in the
1728 // declaration (e.g., if we are inside a 'with' statement or 'catch'
1729 // block).
Steve Blocka7e24c12009-10-30 11:49:00 +00001730 //
1731 // However, note that const declarations are different! A const
1732 // declaration of the form:
1733 //
1734 // const c = x;
1735 //
1736 // is *not* syntactic sugar for:
1737 //
1738 // const c; c = x;
1739 //
1740 // The "variable" c initialized to x is the same as the declared
1741 // one - there is no re-lookup (see the last parameter of the
1742 // Declare() call above).
1743
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001744 Scope* initialization_scope = is_const ? declaration_scope : top_scope_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001745 Expression* value = NULL;
1746 int position = -1;
1747 if (peek() == Token::ASSIGN) {
1748 Expect(Token::ASSIGN, CHECK_OK);
1749 position = scanner().location().beg_pos;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001750 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001751 // Don't infer if it is "a = function(){...}();"-like expression.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001752 if (fni_ != NULL &&
1753 value->AsCall() == NULL &&
1754 value->AsCallNew() == NULL) {
1755 fni_->Infer();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001756 } else {
1757 fni_->RemoveLastFunction();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001758 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001759 }
1760
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001761 // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
1762 if (value == NULL && needs_init) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001763 value = GetLiteralUndefined();
1764 }
1765
1766 // Global variable declarations must be compiled in a specific
1767 // way. When the script containing the global variable declaration
1768 // is entered, the global variable must be declared, so that if it
1769 // doesn't exist (not even in a prototype of the global object) it
1770 // gets created with an initial undefined value. This is handled
1771 // by the declarations part of the function representing the
1772 // top-level global code; see Runtime::DeclareGlobalVariable. If
1773 // it already exists (in the object or in a prototype), it is
1774 // *not* touched until the variable declaration statement is
1775 // executed.
1776 //
1777 // Executing the variable declaration statement will always
1778 // guarantee to give the global object a "local" variable; a
1779 // variable defined in the global object and not in any
1780 // prototype. This way, global variable declarations can shadow
1781 // properties in the prototype chain, but only after the variable
1782 // declaration statement has been executed. This is important in
1783 // browsers where the global object (window) has lots of
1784 // properties defined in prototype objects.
1785
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001786 if (initialization_scope->is_global_scope()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001787 // Compute the arguments for the runtime call.
Ben Murdoch257744e2011-11-30 15:57:28 +00001788 ZoneList<Expression*>* arguments = new(zone()) ZoneList<Expression*>(3);
Ben Murdoch8b112d22011-06-08 16:22:53 +01001789 // We have at least 1 parameter.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001790 arguments->Add(NewLiteral(name));
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001791 CallRuntime* initialize;
1792
1793 if (is_const) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001794 arguments->Add(value);
1795 value = NULL; // zap the value to avoid the unnecessary assignment
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001796
1797 // Construct the call to Runtime_InitializeConstGlobal
1798 // and add it to the initialization statement block.
1799 // Note that the function does different things depending on
1800 // the number of arguments (1 or 2).
Steve Blocka7e24c12009-10-30 11:49:00 +00001801 initialize =
Ben Murdoch8b112d22011-06-08 16:22:53 +01001802 new(zone()) CallRuntime(
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001803 isolate(),
1804 isolate()->factory()->InitializeConstGlobal_symbol(),
1805 Runtime::FunctionForId(Runtime::kInitializeConstGlobal),
1806 arguments);
Steve Blocka7e24c12009-10-30 11:49:00 +00001807 } else {
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001808 // Add strict mode.
1809 // We may want to pass singleton to avoid Literal allocations.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001810 StrictModeFlag flag = initialization_scope->is_strict_mode()
1811 ? kStrictMode
1812 : kNonStrictMode;
1813 arguments->Add(NewNumberLiteral(flag));
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001814
1815 // Be careful not to assign a value to the global variable if
1816 // we're in a with. The initialization value should not
1817 // necessarily be stored in the global object in that case,
1818 // which is why we need to generate a separate assignment node.
1819 if (value != NULL && !inside_with()) {
1820 arguments->Add(value);
1821 value = NULL; // zap the value to avoid the unnecessary assignment
1822 }
1823
1824 // Construct the call to Runtime_InitializeVarGlobal
1825 // and add it to the initialization statement block.
1826 // Note that the function does different things depending on
1827 // the number of arguments (2 or 3).
Steve Blocka7e24c12009-10-30 11:49:00 +00001828 initialize =
Ben Murdoch8b112d22011-06-08 16:22:53 +01001829 new(zone()) CallRuntime(
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001830 isolate(),
1831 isolate()->factory()->InitializeVarGlobal_symbol(),
1832 Runtime::FunctionForId(Runtime::kInitializeVarGlobal),
1833 arguments);
Steve Blocka7e24c12009-10-30 11:49:00 +00001834 }
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001835
Ben Murdoch8b112d22011-06-08 16:22:53 +01001836 block->AddStatement(new(zone()) ExpressionStatement(initialize));
Steve Blocka7e24c12009-10-30 11:49:00 +00001837 }
1838
Ben Murdoch589d6972011-11-30 16:04:58 +00001839 // Add an assignment node to the initialization statement block if we still
1840 // have a pending initialization value. We must distinguish between
1841 // different kinds of declarations: 'var' initializations are simply
Steve Blocka7e24c12009-10-30 11:49:00 +00001842 // assignments (with all the consequences if they are inside a 'with'
1843 // statement - they may change a 'with' object property). Constant
1844 // initializations always assign to the declared constant which is
1845 // always at the function scope level. This is only relevant for
1846 // dynamically looked-up variables and constants (the start context
1847 // for constant lookups is always the function context, while it is
Ben Murdoch589d6972011-11-30 16:04:58 +00001848 // the top context for var declared variables). Sigh...
1849 // For 'let' declared variables the initialization is in the same scope
1850 // as the declaration. Thus dynamic lookups are unnecessary even if the
1851 // block scope is inside a with.
Steve Blocka7e24c12009-10-30 11:49:00 +00001852 if (value != NULL) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001853 bool in_with = mode == Variable::VAR ? inside_with() : false;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001854 VariableProxy* proxy =
1855 initialization_scope->NewUnresolved(name, in_with);
Ben Murdoch8b112d22011-06-08 16:22:53 +01001856 Assignment* assignment =
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001857 new(zone()) Assignment(isolate(), init_op, proxy, value, position);
Ben Murdoch8b112d22011-06-08 16:22:53 +01001858 if (block) {
1859 block->AddStatement(new(zone()) ExpressionStatement(assignment));
1860 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001861 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001862
1863 if (fni_ != NULL) fni_->Leave();
Steve Blocka7e24c12009-10-30 11:49:00 +00001864 } while (peek() == Token::COMMA);
1865
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001866 // If there was a single non-const declaration, return it in the output
1867 // parameter for possible use by for/in.
1868 if (nvars == 1 && !is_const) {
1869 *out = name;
Steve Blocka7e24c12009-10-30 11:49:00 +00001870 }
1871
1872 return block;
1873}
1874
1875
1876static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) {
1877 ASSERT(!label.is_null());
1878 if (labels != NULL)
1879 for (int i = labels->length(); i-- > 0; )
1880 if (labels->at(i).is_identical_to(label))
1881 return true;
1882
1883 return false;
1884}
1885
1886
1887Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
1888 bool* ok) {
1889 // ExpressionStatement | LabelledStatement ::
1890 // Expression ';'
1891 // Identifier ':' Statement
Steve Block1e0659c2011-05-24 12:43:12 +01001892 bool starts_with_idenfifier = peek_any_identifier();
Steve Blocka7e24c12009-10-30 11:49:00 +00001893 Expression* expr = ParseExpression(true, CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001894 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
Steve Blocka7e24c12009-10-30 11:49:00 +00001895 expr->AsVariableProxy() != NULL &&
1896 !expr->AsVariableProxy()->is_this()) {
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08001897 // Expression is a single identifier, and not, e.g., a parenthesized
1898 // identifier.
Steve Blocka7e24c12009-10-30 11:49:00 +00001899 VariableProxy* var = expr->AsVariableProxy();
1900 Handle<String> label = var->name();
1901 // TODO(1240780): We don't check for redeclaration of labels
1902 // during preparsing since keeping track of the set of active
1903 // labels requires nontrivial changes to the way scopes are
1904 // structured. However, these are probably changes we want to
1905 // make later anyway so we should go back and fix this then.
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001906 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001907 SmartArrayPointer<char> c_string = label->ToCString(DISALLOW_NULLS);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001908 const char* elms[2] = { "Label", *c_string };
1909 Vector<const char*> args(elms, 2);
1910 ReportMessage("redeclaration", args);
1911 *ok = false;
1912 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00001913 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001914 if (labels == NULL) labels = new(zone()) ZoneStringList(4);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001915 labels->Add(label);
1916 // Remove the "ghost" variable that turned out to be a label
1917 // from the top scope. This way, we don't try to resolve it
1918 // during the scope processing.
1919 top_scope_->RemoveUnresolved(var);
Steve Blocka7e24c12009-10-30 11:49:00 +00001920 Expect(Token::COLON, CHECK_OK);
1921 return ParseStatement(labels, ok);
1922 }
1923
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001924 // If we have an extension, we allow a native function declaration.
1925 // A native function declaration starts with "native function" with
1926 // no line-terminator between the two words.
1927 if (extension_ != NULL &&
1928 peek() == Token::FUNCTION &&
1929 !scanner().HasAnyLineTerminatorBeforeNext() &&
1930 expr != NULL &&
1931 expr->AsVariableProxy() != NULL &&
1932 expr->AsVariableProxy()->name()->Equals(
1933 isolate()->heap()->native_symbol()) &&
1934 !scanner().literal_contains_escapes()) {
1935 return ParseNativeDeclaration(ok);
1936 }
1937
Steve Blocka7e24c12009-10-30 11:49:00 +00001938 // Parsed expression statement.
1939 ExpectSemicolon(CHECK_OK);
Ben Murdoch8b112d22011-06-08 16:22:53 +01001940 return new(zone()) ExpressionStatement(expr);
Steve Blocka7e24c12009-10-30 11:49:00 +00001941}
1942
1943
1944IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) {
1945 // IfStatement ::
1946 // 'if' '(' Expression ')' Statement ('else' Statement)?
1947
1948 Expect(Token::IF, CHECK_OK);
1949 Expect(Token::LPAREN, CHECK_OK);
1950 Expression* condition = ParseExpression(true, CHECK_OK);
1951 Expect(Token::RPAREN, CHECK_OK);
1952 Statement* then_statement = ParseStatement(labels, CHECK_OK);
1953 Statement* else_statement = NULL;
1954 if (peek() == Token::ELSE) {
1955 Next();
1956 else_statement = ParseStatement(labels, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001957 } else {
1958 else_statement = EmptyStatement();
Steve Blocka7e24c12009-10-30 11:49:00 +00001959 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001960 return new(zone()) IfStatement(
1961 isolate(), condition, then_statement, else_statement);
Steve Blocka7e24c12009-10-30 11:49:00 +00001962}
1963
1964
1965Statement* Parser::ParseContinueStatement(bool* ok) {
1966 // ContinueStatement ::
1967 // 'continue' Identifier? ';'
1968
1969 Expect(Token::CONTINUE, CHECK_OK);
1970 Handle<String> label = Handle<String>::null();
1971 Token::Value tok = peek();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001972 if (!scanner().HasAnyLineTerminatorBeforeNext() &&
Steve Blocka7e24c12009-10-30 11:49:00 +00001973 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
1974 label = ParseIdentifier(CHECK_OK);
1975 }
1976 IterationStatement* target = NULL;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001977 target = LookupContinueTarget(label, CHECK_OK);
1978 if (target == NULL) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01001979 // Illegal continue statement.
1980 const char* message = "illegal_continue";
1981 Vector<Handle<String> > args;
1982 if (!label.is_null()) {
1983 message = "unknown_label";
1984 args = Vector<Handle<String> >(&label, 1);
1985 }
1986 ReportMessageAt(scanner().location(), message, args);
1987 *ok = false;
1988 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00001989 }
1990 ExpectSemicolon(CHECK_OK);
Ben Murdoch8b112d22011-06-08 16:22:53 +01001991 return new(zone()) ContinueStatement(target);
Steve Blocka7e24c12009-10-30 11:49:00 +00001992}
1993
1994
1995Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) {
1996 // BreakStatement ::
1997 // 'break' Identifier? ';'
1998
1999 Expect(Token::BREAK, CHECK_OK);
2000 Handle<String> label;
2001 Token::Value tok = peek();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002002 if (!scanner().HasAnyLineTerminatorBeforeNext() &&
Steve Blocka7e24c12009-10-30 11:49:00 +00002003 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2004 label = ParseIdentifier(CHECK_OK);
2005 }
2006 // Parse labeled break statements that target themselves into
2007 // empty statements, e.g. 'l1: l2: l3: break l2;'
2008 if (!label.is_null() && ContainsLabel(labels, label)) {
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002009 return EmptyStatement();
Steve Blocka7e24c12009-10-30 11:49:00 +00002010 }
2011 BreakableStatement* target = NULL;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002012 target = LookupBreakTarget(label, CHECK_OK);
2013 if (target == NULL) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01002014 // Illegal break statement.
2015 const char* message = "illegal_break";
2016 Vector<Handle<String> > args;
2017 if (!label.is_null()) {
2018 message = "unknown_label";
2019 args = Vector<Handle<String> >(&label, 1);
2020 }
2021 ReportMessageAt(scanner().location(), message, args);
2022 *ok = false;
2023 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002024 }
2025 ExpectSemicolon(CHECK_OK);
Ben Murdoch8b112d22011-06-08 16:22:53 +01002026 return new(zone()) BreakStatement(target);
Steve Blocka7e24c12009-10-30 11:49:00 +00002027}
2028
2029
2030Statement* Parser::ParseReturnStatement(bool* ok) {
2031 // ReturnStatement ::
2032 // 'return' Expression? ';'
2033
2034 // Consume the return token. It is necessary to do the before
2035 // reporting any errors on it, because of the way errors are
2036 // reported (underlining).
2037 Expect(Token::RETURN, CHECK_OK);
2038
2039 // An ECMAScript program is considered syntactically incorrect if it
2040 // contains a return statement that is not within the body of a
2041 // function. See ECMA-262, section 12.9, page 67.
2042 //
2043 // To be consistent with KJS we report the syntax error at runtime.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002044 Scope* declaration_scope = top_scope_->DeclarationScope();
2045 if (declaration_scope->is_global_scope() ||
2046 declaration_scope->is_eval_scope()) {
Steve Block44f0eee2011-05-26 01:26:41 +01002047 Handle<String> type = isolate()->factory()->illegal_return_symbol();
Steve Blocka7e24c12009-10-30 11:49:00 +00002048 Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null());
Ben Murdoch8b112d22011-06-08 16:22:53 +01002049 return new(zone()) ExpressionStatement(throw_error);
Steve Blocka7e24c12009-10-30 11:49:00 +00002050 }
2051
2052 Token::Value tok = peek();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002053 if (scanner().HasAnyLineTerminatorBeforeNext() ||
Steve Blocka7e24c12009-10-30 11:49:00 +00002054 tok == Token::SEMICOLON ||
2055 tok == Token::RBRACE ||
2056 tok == Token::EOS) {
2057 ExpectSemicolon(CHECK_OK);
Ben Murdoch8b112d22011-06-08 16:22:53 +01002058 return new(zone()) ReturnStatement(GetLiteralUndefined());
Steve Blocka7e24c12009-10-30 11:49:00 +00002059 }
2060
2061 Expression* expr = ParseExpression(true, CHECK_OK);
2062 ExpectSemicolon(CHECK_OK);
Ben Murdoch8b112d22011-06-08 16:22:53 +01002063 return new(zone()) ReturnStatement(expr);
Steve Blocka7e24c12009-10-30 11:49:00 +00002064}
2065
2066
Steve Blocka7e24c12009-10-30 11:49:00 +00002067Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) {
2068 // WithStatement ::
2069 // 'with' '(' Expression ')' Statement
2070
2071 Expect(Token::WITH, CHECK_OK);
Steve Block1e0659c2011-05-24 12:43:12 +01002072
Steve Block44f0eee2011-05-26 01:26:41 +01002073 if (top_scope_->is_strict_mode()) {
Steve Block1e0659c2011-05-24 12:43:12 +01002074 ReportMessage("strict_mode_with", Vector<const char*>::empty());
2075 *ok = false;
2076 return NULL;
2077 }
2078
Steve Blocka7e24c12009-10-30 11:49:00 +00002079 Expect(Token::LPAREN, CHECK_OK);
2080 Expression* expr = ParseExpression(true, CHECK_OK);
2081 Expect(Token::RPAREN, CHECK_OK);
2082
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002083 ++with_nesting_level_;
2084 top_scope_->DeclarationScope()->RecordWithStatement();
2085 Statement* stmt = ParseStatement(labels, CHECK_OK);
2086 --with_nesting_level_;
2087 return new(zone()) WithStatement(expr, stmt);
Steve Blocka7e24c12009-10-30 11:49:00 +00002088}
2089
2090
2091CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
2092 // CaseClause ::
2093 // 'case' Expression ':' Statement*
2094 // 'default' ':' Statement*
2095
2096 Expression* label = NULL; // NULL expression indicates default case
2097 if (peek() == Token::CASE) {
2098 Expect(Token::CASE, CHECK_OK);
2099 label = ParseExpression(true, CHECK_OK);
2100 } else {
2101 Expect(Token::DEFAULT, CHECK_OK);
2102 if (*default_seen_ptr) {
2103 ReportMessage("multiple_defaults_in_switch",
2104 Vector<const char*>::empty());
2105 *ok = false;
2106 return NULL;
2107 }
2108 *default_seen_ptr = true;
2109 }
2110 Expect(Token::COLON, CHECK_OK);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002111 int pos = scanner().location().beg_pos;
Ben Murdoch257744e2011-11-30 15:57:28 +00002112 ZoneList<Statement*>* statements = new(zone()) ZoneList<Statement*>(5);
Steve Blocka7e24c12009-10-30 11:49:00 +00002113 while (peek() != Token::CASE &&
2114 peek() != Token::DEFAULT &&
2115 peek() != Token::RBRACE) {
2116 Statement* stat = ParseStatement(NULL, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002117 statements->Add(stat);
Steve Blocka7e24c12009-10-30 11:49:00 +00002118 }
2119
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002120 return new(zone()) CaseClause(isolate(), label, statements, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002121}
2122
2123
2124SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels,
2125 bool* ok) {
2126 // SwitchStatement ::
2127 // 'switch' '(' Expression ')' '{' CaseClause* '}'
2128
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002129 SwitchStatement* statement = new(zone()) SwitchStatement(isolate(), labels);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002130 Target target(&this->target_stack_, statement);
Steve Blocka7e24c12009-10-30 11:49:00 +00002131
2132 Expect(Token::SWITCH, CHECK_OK);
2133 Expect(Token::LPAREN, CHECK_OK);
2134 Expression* tag = ParseExpression(true, CHECK_OK);
2135 Expect(Token::RPAREN, CHECK_OK);
2136
2137 bool default_seen = false;
Ben Murdoch257744e2011-11-30 15:57:28 +00002138 ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4);
Steve Blocka7e24c12009-10-30 11:49:00 +00002139 Expect(Token::LBRACE, CHECK_OK);
2140 while (peek() != Token::RBRACE) {
2141 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002142 cases->Add(clause);
Steve Blocka7e24c12009-10-30 11:49:00 +00002143 }
2144 Expect(Token::RBRACE, CHECK_OK);
2145
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002146 if (statement) statement->Initialize(tag, cases);
Steve Blocka7e24c12009-10-30 11:49:00 +00002147 return statement;
2148}
2149
2150
2151Statement* Parser::ParseThrowStatement(bool* ok) {
2152 // ThrowStatement ::
2153 // 'throw' Expression ';'
2154
2155 Expect(Token::THROW, CHECK_OK);
2156 int pos = scanner().location().beg_pos;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002157 if (scanner().HasAnyLineTerminatorBeforeNext()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002158 ReportMessage("newline_after_throw", Vector<const char*>::empty());
2159 *ok = false;
2160 return NULL;
2161 }
2162 Expression* exception = ParseExpression(true, CHECK_OK);
2163 ExpectSemicolon(CHECK_OK);
2164
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002165 return new(zone()) ExpressionStatement(
2166 new(zone()) Throw(isolate(), exception, pos));
Steve Blocka7e24c12009-10-30 11:49:00 +00002167}
2168
2169
2170TryStatement* Parser::ParseTryStatement(bool* ok) {
2171 // TryStatement ::
2172 // 'try' Block Catch
2173 // 'try' Block Finally
2174 // 'try' Block Catch Finally
2175 //
2176 // Catch ::
2177 // 'catch' '(' Identifier ')' Block
2178 //
2179 // Finally ::
2180 // 'finally' Block
2181
2182 Expect(Token::TRY, CHECK_OK);
2183
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002184 TargetCollector try_collector;
Steve Blocka7e24c12009-10-30 11:49:00 +00002185 Block* try_block;
2186
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002187 { Target target(&this->target_stack_, &try_collector);
Steve Blocka7e24c12009-10-30 11:49:00 +00002188 try_block = ParseBlock(NULL, CHECK_OK);
2189 }
2190
Steve Blocka7e24c12009-10-30 11:49:00 +00002191 Token::Value tok = peek();
2192 if (tok != Token::CATCH && tok != Token::FINALLY) {
2193 ReportMessage("no_catch_or_finally", Vector<const char*>::empty());
2194 *ok = false;
2195 return NULL;
2196 }
2197
2198 // If we can break out from the catch block and there is a finally block,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002199 // then we will need to collect escaping targets from the catch
2200 // block. Since we don't know yet if there will be a finally block, we
2201 // always collect the targets.
2202 TargetCollector catch_collector;
2203 Scope* catch_scope = NULL;
2204 Variable* catch_variable = NULL;
2205 Block* catch_block = NULL;
2206 Handle<String> name;
Steve Blocka7e24c12009-10-30 11:49:00 +00002207 if (tok == Token::CATCH) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002208 Consume(Token::CATCH);
2209
2210 Expect(Token::LPAREN, CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002211 name = ParseIdentifier(CHECK_OK);
Steve Block1e0659c2011-05-24 12:43:12 +01002212
Steve Block44f0eee2011-05-26 01:26:41 +01002213 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) {
Steve Block1e0659c2011-05-24 12:43:12 +01002214 ReportMessage("strict_catch_variable", Vector<const char*>::empty());
2215 *ok = false;
2216 return NULL;
2217 }
2218
Steve Blocka7e24c12009-10-30 11:49:00 +00002219 Expect(Token::RPAREN, CHECK_OK);
2220
2221 if (peek() == Token::LBRACE) {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002222 Target target(&this->target_stack_, &catch_collector);
2223 catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE, inside_with());
2224 if (top_scope_->is_strict_mode()) {
2225 catch_scope->EnableStrictMode();
Steve Blocka7e24c12009-10-30 11:49:00 +00002226 }
Ben Murdoch589d6972011-11-30 16:04:58 +00002227 Variable::Mode mode = harmony_block_scoping_
2228 ? Variable::LET : Variable::VAR;
2229 catch_variable = catch_scope->DeclareLocal(name, mode);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002230
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002231 Scope* saved_scope = top_scope_;
2232 top_scope_ = catch_scope;
Ben Murdoch589d6972011-11-30 16:04:58 +00002233 catch_block = ParseBlock(NULL, CHECK_OK);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002234 top_scope_ = saved_scope;
Steve Blocka7e24c12009-10-30 11:49:00 +00002235 } else {
2236 Expect(Token::LBRACE, CHECK_OK);
2237 }
2238
2239 tok = peek();
2240 }
2241
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002242 Block* finally_block = NULL;
2243 if (tok == Token::FINALLY || catch_block == NULL) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002244 Consume(Token::FINALLY);
Steve Blocka7e24c12009-10-30 11:49:00 +00002245 finally_block = ParseBlock(NULL, CHECK_OK);
2246 }
2247
2248 // Simplify the AST nodes by converting:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002249 // 'try B0 catch B1 finally B2'
Steve Blocka7e24c12009-10-30 11:49:00 +00002250 // to:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002251 // 'try { try B0 catch B1 } finally B2'
Steve Blocka7e24c12009-10-30 11:49:00 +00002252
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002253 if (catch_block != NULL && finally_block != NULL) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002254 // If we have both, create an inner try/catch.
2255 ASSERT(catch_scope != NULL && catch_variable != NULL);
Steve Block3ce2e202009-11-05 08:53:23 +00002256 TryCatchStatement* statement =
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002257 new(zone()) TryCatchStatement(try_block,
2258 catch_scope,
2259 catch_variable,
2260 catch_block);
2261 statement->set_escaping_targets(try_collector.targets());
2262 try_block = new(zone()) Block(isolate(), NULL, 1, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00002263 try_block->AddStatement(statement);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002264 catch_block = NULL; // Clear to indicate it's been handled.
Steve Blocka7e24c12009-10-30 11:49:00 +00002265 }
2266
2267 TryStatement* result = NULL;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002268 if (catch_block != NULL) {
2269 ASSERT(finally_block == NULL);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002270 ASSERT(catch_scope != NULL && catch_variable != NULL);
Ben Murdoch8b112d22011-06-08 16:22:53 +01002271 result =
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002272 new(zone()) TryCatchStatement(try_block,
2273 catch_scope,
2274 catch_variable,
2275 catch_block);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002276 } else {
2277 ASSERT(finally_block != NULL);
Ben Murdoch8b112d22011-06-08 16:22:53 +01002278 result = new(zone()) TryFinallyStatement(try_block, finally_block);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002279 // Combine the jump targets of the try block and the possible catch block.
2280 try_collector.targets()->AddAll(*catch_collector.targets());
Steve Blocka7e24c12009-10-30 11:49:00 +00002281 }
2282
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002283 result->set_escaping_targets(try_collector.targets());
Steve Blocka7e24c12009-10-30 11:49:00 +00002284 return result;
2285}
2286
2287
Steve Block3ce2e202009-11-05 08:53:23 +00002288DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels,
2289 bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002290 // DoStatement ::
2291 // 'do' Statement 'while' '(' Expression ')' ';'
2292
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002293 DoWhileStatement* loop = new(zone()) DoWhileStatement(isolate(), labels);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002294 Target target(&this->target_stack_, loop);
Steve Blocka7e24c12009-10-30 11:49:00 +00002295
2296 Expect(Token::DO, CHECK_OK);
2297 Statement* body = ParseStatement(NULL, CHECK_OK);
2298 Expect(Token::WHILE, CHECK_OK);
2299 Expect(Token::LPAREN, CHECK_OK);
Steve Blockd0582a62009-12-15 09:54:21 +00002300
2301 if (loop != NULL) {
2302 int position = scanner().location().beg_pos;
2303 loop->set_condition_position(position);
2304 }
2305
Steve Blocka7e24c12009-10-30 11:49:00 +00002306 Expression* cond = ParseExpression(true, CHECK_OK);
2307 Expect(Token::RPAREN, CHECK_OK);
2308
2309 // Allow do-statements to be terminated with and without
2310 // semi-colons. This allows code such as 'do;while(0)return' to
2311 // parse, which would not be the case if we had used the
2312 // ExpectSemicolon() functionality here.
2313 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
2314
Steve Block3ce2e202009-11-05 08:53:23 +00002315 if (loop != NULL) loop->Initialize(cond, body);
Steve Blocka7e24c12009-10-30 11:49:00 +00002316 return loop;
2317}
2318
2319
Steve Block3ce2e202009-11-05 08:53:23 +00002320WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002321 // WhileStatement ::
2322 // 'while' '(' Expression ')' Statement
2323
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002324 WhileStatement* loop = new(zone()) WhileStatement(isolate(), labels);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002325 Target target(&this->target_stack_, loop);
Steve Blocka7e24c12009-10-30 11:49:00 +00002326
2327 Expect(Token::WHILE, CHECK_OK);
2328 Expect(Token::LPAREN, CHECK_OK);
2329 Expression* cond = ParseExpression(true, CHECK_OK);
2330 Expect(Token::RPAREN, CHECK_OK);
2331 Statement* body = ParseStatement(NULL, CHECK_OK);
2332
Steve Block3ce2e202009-11-05 08:53:23 +00002333 if (loop != NULL) loop->Initialize(cond, body);
Steve Blocka7e24c12009-10-30 11:49:00 +00002334 return loop;
2335}
2336
2337
2338Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
2339 // ForStatement ::
2340 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
2341
2342 Statement* init = NULL;
2343
2344 Expect(Token::FOR, CHECK_OK);
2345 Expect(Token::LPAREN, CHECK_OK);
2346 if (peek() != Token::SEMICOLON) {
2347 if (peek() == Token::VAR || peek() == Token::CONST) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002348 Handle<String> name;
Steve Blocka7e24c12009-10-30 11:49:00 +00002349 Block* variable_statement =
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002350 ParseVariableDeclarations(kForStatement, &name, CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002351
2352 if (peek() == Token::IN && !name.is_null()) {
2353 VariableProxy* each = top_scope_->NewUnresolved(name, inside_with());
2354 ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002355 Target target(&this->target_stack_, loop);
Steve Blocka7e24c12009-10-30 11:49:00 +00002356
2357 Expect(Token::IN, CHECK_OK);
2358 Expression* enumerable = ParseExpression(true, CHECK_OK);
2359 Expect(Token::RPAREN, CHECK_OK);
2360
2361 Statement* body = ParseStatement(NULL, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002362 loop->Initialize(each, enumerable, body);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002363 Block* result = new(zone()) Block(isolate(), NULL, 2, false);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002364 result->AddStatement(variable_statement);
2365 result->AddStatement(loop);
2366 // Parsed for-in loop w/ variable/const declaration.
2367 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00002368 } else {
2369 init = variable_statement;
2370 }
2371
2372 } else {
2373 Expression* expression = ParseExpression(false, CHECK_OK);
2374 if (peek() == Token::IN) {
2375 // Signal a reference error if the expression is an invalid
2376 // left-hand side expression. We could report this as a syntax
2377 // error here but for compatibility with JSC we choose to report
2378 // the error at runtime.
2379 if (expression == NULL || !expression->IsValidLeftHandSide()) {
Steve Block44f0eee2011-05-26 01:26:41 +01002380 Handle<String> type =
2381 isolate()->factory()->invalid_lhs_in_for_in_symbol();
Steve Blocka7e24c12009-10-30 11:49:00 +00002382 expression = NewThrowReferenceError(type);
2383 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002384 ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002385 Target target(&this->target_stack_, loop);
Steve Blocka7e24c12009-10-30 11:49:00 +00002386
2387 Expect(Token::IN, CHECK_OK);
2388 Expression* enumerable = ParseExpression(true, CHECK_OK);
2389 Expect(Token::RPAREN, CHECK_OK);
2390
2391 Statement* body = ParseStatement(NULL, CHECK_OK);
2392 if (loop) loop->Initialize(expression, enumerable, body);
Steve Blocka7e24c12009-10-30 11:49:00 +00002393 // Parsed for-in loop.
2394 return loop;
2395
2396 } else {
Ben Murdoch8b112d22011-06-08 16:22:53 +01002397 init = new(zone()) ExpressionStatement(expression);
Steve Blocka7e24c12009-10-30 11:49:00 +00002398 }
2399 }
2400 }
2401
2402 // Standard 'for' loop
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002403 ForStatement* loop = new(zone()) ForStatement(isolate(), labels);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002404 Target target(&this->target_stack_, loop);
Steve Blocka7e24c12009-10-30 11:49:00 +00002405
2406 // Parsed initializer at this point.
2407 Expect(Token::SEMICOLON, CHECK_OK);
2408
2409 Expression* cond = NULL;
2410 if (peek() != Token::SEMICOLON) {
2411 cond = ParseExpression(true, CHECK_OK);
2412 }
2413 Expect(Token::SEMICOLON, CHECK_OK);
2414
2415 Statement* next = NULL;
2416 if (peek() != Token::RPAREN) {
2417 Expression* exp = ParseExpression(true, CHECK_OK);
Ben Murdoch8b112d22011-06-08 16:22:53 +01002418 next = new(zone()) ExpressionStatement(exp);
Steve Blocka7e24c12009-10-30 11:49:00 +00002419 }
2420 Expect(Token::RPAREN, CHECK_OK);
2421
2422 Statement* body = ParseStatement(NULL, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00002423 if (loop) loop->Initialize(init, cond, next, body);
2424 return loop;
2425}
2426
2427
2428// Precedence = 1
2429Expression* Parser::ParseExpression(bool accept_IN, bool* ok) {
2430 // Expression ::
2431 // AssignmentExpression
2432 // Expression ',' AssignmentExpression
2433
2434 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK);
2435 while (peek() == Token::COMMA) {
2436 Expect(Token::COMMA, CHECK_OK);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002437 int position = scanner().location().beg_pos;
Steve Blocka7e24c12009-10-30 11:49:00 +00002438 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002439 result = new(zone()) BinaryOperation(
2440 isolate(), Token::COMMA, result, right, position);
Steve Blocka7e24c12009-10-30 11:49:00 +00002441 }
2442 return result;
2443}
2444
2445
2446// Precedence = 2
2447Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
2448 // AssignmentExpression ::
2449 // ConditionalExpression
2450 // LeftHandSideExpression AssignmentOperator AssignmentExpression
2451
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002452 if (fni_ != NULL) fni_->Enter();
Steve Blocka7e24c12009-10-30 11:49:00 +00002453 Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK);
2454
2455 if (!Token::IsAssignmentOp(peek())) {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002456 if (fni_ != NULL) fni_->Leave();
Steve Blocka7e24c12009-10-30 11:49:00 +00002457 // Parsed conditional expression only (no assignment).
2458 return expression;
2459 }
2460
2461 // Signal a reference error if the expression is an invalid left-hand
2462 // side expression. We could report this as a syntax error here but
2463 // for compatibility with JSC we choose to report the error at
2464 // runtime.
2465 if (expression == NULL || !expression->IsValidLeftHandSide()) {
Steve Block44f0eee2011-05-26 01:26:41 +01002466 Handle<String> type =
2467 isolate()->factory()->invalid_lhs_in_assignment_symbol();
Steve Blocka7e24c12009-10-30 11:49:00 +00002468 expression = NewThrowReferenceError(type);
2469 }
2470
Steve Block44f0eee2011-05-26 01:26:41 +01002471 if (top_scope_->is_strict_mode()) {
Steve Block1e0659c2011-05-24 12:43:12 +01002472 // Assignment to eval or arguments is disallowed in strict mode.
2473 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK);
2474 }
2475
Steve Blocka7e24c12009-10-30 11:49:00 +00002476 Token::Value op = Next(); // Get assignment operator.
2477 int pos = scanner().location().beg_pos;
2478 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
2479
2480 // TODO(1231235): We try to estimate the set of properties set by
2481 // constructors. We define a new property whenever there is an
2482 // assignment to a property of 'this'. We should probably only add
2483 // properties if we haven't seen them before. Otherwise we'll
2484 // probably overestimate the number of properties.
2485 Property* property = expression ? expression->AsProperty() : NULL;
2486 if (op == Token::ASSIGN &&
2487 property != NULL &&
2488 property->obj()->AsVariableProxy() != NULL &&
2489 property->obj()->AsVariableProxy()->is_this()) {
Steve Block44f0eee2011-05-26 01:26:41 +01002490 lexical_scope_->AddProperty();
Steve Blocka7e24c12009-10-30 11:49:00 +00002491 }
2492
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08002493 // If we assign a function literal to a property we pretenure the
2494 // literal so it can be added as a constant function property.
2495 if (property != NULL && right->AsFunctionLiteral() != NULL) {
2496 right->AsFunctionLiteral()->set_pretenure(true);
2497 }
2498
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002499 if (fni_ != NULL) {
2500 // Check if the right hand side is a call to avoid inferring a
2501 // name if we're dealing with "a = function(){...}();"-like
2502 // expression.
2503 if ((op == Token::INIT_VAR
2504 || op == Token::INIT_CONST
2505 || op == Token::ASSIGN)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002506 && (right->AsCall() == NULL && right->AsCallNew() == NULL)) {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002507 fni_->Infer();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002508 } else {
2509 fni_->RemoveLastFunction();
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002510 }
2511 fni_->Leave();
2512 }
2513
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002514 return new(zone()) Assignment(isolate(), op, expression, right, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002515}
2516
2517
2518// Precedence = 3
2519Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) {
2520 // ConditionalExpression ::
2521 // LogicalOrExpression
2522 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
2523
2524 // We start using the binary expression parser for prec >= 4 only!
2525 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
2526 if (peek() != Token::CONDITIONAL) return expression;
2527 Consume(Token::CONDITIONAL);
2528 // In parsing the first assignment expression in conditional
2529 // expressions we always accept the 'in' keyword; see ECMA-262,
2530 // section 11.12, page 58.
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002531 int left_position = scanner().peek_location().beg_pos;
Steve Blocka7e24c12009-10-30 11:49:00 +00002532 Expression* left = ParseAssignmentExpression(true, CHECK_OK);
2533 Expect(Token::COLON, CHECK_OK);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002534 int right_position = scanner().peek_location().beg_pos;
Steve Blocka7e24c12009-10-30 11:49:00 +00002535 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002536 return new(zone()) Conditional(
2537 isolate(), expression, left, right, left_position, right_position);
Steve Blocka7e24c12009-10-30 11:49:00 +00002538}
2539
2540
2541static int Precedence(Token::Value tok, bool accept_IN) {
2542 if (tok == Token::IN && !accept_IN)
2543 return 0; // 0 precedence will terminate binary expression parsing
2544
2545 return Token::Precedence(tok);
2546}
2547
2548
2549// Precedence >= 4
2550Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
2551 ASSERT(prec >= 4);
2552 Expression* x = ParseUnaryExpression(CHECK_OK);
2553 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
2554 // prec1 >= 4
2555 while (Precedence(peek(), accept_IN) == prec1) {
2556 Token::Value op = Next();
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002557 int position = scanner().location().beg_pos;
Steve Blocka7e24c12009-10-30 11:49:00 +00002558 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
2559
2560 // Compute some expressions involving only number literals.
2561 if (x && x->AsLiteral() && x->AsLiteral()->handle()->IsNumber() &&
2562 y && y->AsLiteral() && y->AsLiteral()->handle()->IsNumber()) {
2563 double x_val = x->AsLiteral()->handle()->Number();
2564 double y_val = y->AsLiteral()->handle()->Number();
2565
2566 switch (op) {
2567 case Token::ADD:
2568 x = NewNumberLiteral(x_val + y_val);
2569 continue;
2570 case Token::SUB:
2571 x = NewNumberLiteral(x_val - y_val);
2572 continue;
2573 case Token::MUL:
2574 x = NewNumberLiteral(x_val * y_val);
2575 continue;
2576 case Token::DIV:
2577 x = NewNumberLiteral(x_val / y_val);
2578 continue;
2579 case Token::BIT_OR:
2580 x = NewNumberLiteral(DoubleToInt32(x_val) | DoubleToInt32(y_val));
2581 continue;
2582 case Token::BIT_AND:
2583 x = NewNumberLiteral(DoubleToInt32(x_val) & DoubleToInt32(y_val));
2584 continue;
2585 case Token::BIT_XOR:
2586 x = NewNumberLiteral(DoubleToInt32(x_val) ^ DoubleToInt32(y_val));
2587 continue;
2588 case Token::SHL: {
2589 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
2590 x = NewNumberLiteral(value);
2591 continue;
2592 }
2593 case Token::SHR: {
2594 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
2595 uint32_t value = DoubleToUint32(x_val) >> shift;
2596 x = NewNumberLiteral(value);
2597 continue;
2598 }
2599 case Token::SAR: {
2600 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
2601 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
2602 x = NewNumberLiteral(value);
2603 continue;
2604 }
2605 default:
2606 break;
2607 }
2608 }
2609
Steve Blocka7e24c12009-10-30 11:49:00 +00002610 // For now we distinguish between comparisons and other binary
2611 // operations. (We could combine the two and get rid of this
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002612 // code and AST node eventually.)
Steve Blocka7e24c12009-10-30 11:49:00 +00002613 if (Token::IsCompareOp(op)) {
2614 // We have a comparison.
2615 Token::Value cmp = op;
2616 switch (op) {
2617 case Token::NE: cmp = Token::EQ; break;
2618 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
2619 default: break;
2620 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002621 x = NewCompareNode(cmp, x, y, position);
Steve Blocka7e24c12009-10-30 11:49:00 +00002622 if (cmp != op) {
2623 // The comparison was negated - add a NOT.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002624 x = new(zone()) UnaryOperation(isolate(), Token::NOT, x, position);
Steve Blocka7e24c12009-10-30 11:49:00 +00002625 }
2626
2627 } else {
2628 // We have a "normal" binary operation.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002629 x = new(zone()) BinaryOperation(isolate(), op, x, y, position);
Steve Blocka7e24c12009-10-30 11:49:00 +00002630 }
2631 }
2632 }
2633 return x;
2634}
2635
2636
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002637Expression* Parser::NewCompareNode(Token::Value op,
2638 Expression* x,
2639 Expression* y,
2640 int position) {
2641 ASSERT(op != Token::NE && op != Token::NE_STRICT);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002642 if (op == Token::EQ || op == Token::EQ_STRICT) {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002643 bool is_strict = (op == Token::EQ_STRICT);
2644 Literal* x_literal = x->AsLiteral();
2645 if (x_literal != NULL && x_literal->IsNull()) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002646 return new(zone()) CompareToNull(isolate(), is_strict, y);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002647 }
2648
2649 Literal* y_literal = y->AsLiteral();
2650 if (y_literal != NULL && y_literal->IsNull()) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002651 return new(zone()) CompareToNull(isolate(), is_strict, x);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002652 }
2653 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002654 return new(zone()) CompareOperation(isolate(), op, x, y, position);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002655}
2656
2657
Steve Blocka7e24c12009-10-30 11:49:00 +00002658Expression* Parser::ParseUnaryExpression(bool* ok) {
2659 // UnaryExpression ::
2660 // PostfixExpression
2661 // 'delete' UnaryExpression
2662 // 'void' UnaryExpression
2663 // 'typeof' UnaryExpression
2664 // '++' UnaryExpression
2665 // '--' UnaryExpression
2666 // '+' UnaryExpression
2667 // '-' UnaryExpression
2668 // '~' UnaryExpression
2669 // '!' UnaryExpression
2670
2671 Token::Value op = peek();
2672 if (Token::IsUnaryOp(op)) {
2673 op = Next();
Ben Murdoch257744e2011-11-30 15:57:28 +00002674 int position = scanner().location().beg_pos;
Steve Blocka7e24c12009-10-30 11:49:00 +00002675 Expression* expression = ParseUnaryExpression(CHECK_OK);
2676
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002677 if (expression != NULL && (expression->AsLiteral() != NULL)) {
2678 Handle<Object> literal = expression->AsLiteral()->handle();
2679 if (op == Token::NOT) {
2680 // Convert the literal to a boolean condition and negate it.
2681 bool condition = literal->ToBoolean()->IsTrue();
2682 Handle<Object> result(isolate()->heap()->ToBoolean(!condition));
2683 return NewLiteral(result);
2684 } else if (literal->IsNumber()) {
2685 // Compute some expressions involving only number literals.
2686 double value = literal->Number();
2687 switch (op) {
2688 case Token::ADD:
2689 return expression;
2690 case Token::SUB:
2691 return NewNumberLiteral(-value);
2692 case Token::BIT_NOT:
2693 return NewNumberLiteral(~DoubleToInt32(value));
2694 default:
2695 break;
2696 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002697 }
2698 }
2699
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002700 // "delete identifier" is a syntax error in strict mode.
Steve Block44f0eee2011-05-26 01:26:41 +01002701 if (op == Token::DELETE && top_scope_->is_strict_mode()) {
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002702 VariableProxy* operand = expression->AsVariableProxy();
2703 if (operand != NULL && !operand->is_this()) {
2704 ReportMessage("strict_delete", Vector<const char*>::empty());
2705 *ok = false;
2706 return NULL;
2707 }
2708 }
2709
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002710 return new(zone()) UnaryOperation(isolate(), op, expression, position);
Steve Blocka7e24c12009-10-30 11:49:00 +00002711
2712 } else if (Token::IsCountOp(op)) {
2713 op = Next();
2714 Expression* expression = ParseUnaryExpression(CHECK_OK);
2715 // Signal a reference error if the expression is an invalid
2716 // left-hand side expression. We could report this as a syntax
2717 // error here but for compatibility with JSC we choose to report the
2718 // error at runtime.
2719 if (expression == NULL || !expression->IsValidLeftHandSide()) {
Steve Block44f0eee2011-05-26 01:26:41 +01002720 Handle<String> type =
2721 isolate()->factory()->invalid_lhs_in_prefix_op_symbol();
Steve Blocka7e24c12009-10-30 11:49:00 +00002722 expression = NewThrowReferenceError(type);
2723 }
Steve Block1e0659c2011-05-24 12:43:12 +01002724
Steve Block44f0eee2011-05-26 01:26:41 +01002725 if (top_scope_->is_strict_mode()) {
Steve Block1e0659c2011-05-24 12:43:12 +01002726 // Prefix expression operand in strict mode may not be eval or arguments.
2727 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
2728 }
2729
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002730 int position = scanner().location().beg_pos;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002731 return new(zone()) CountOperation(isolate(),
2732 op,
Ben Murdoch8b112d22011-06-08 16:22:53 +01002733 true /* prefix */,
2734 expression,
2735 position);
Steve Blocka7e24c12009-10-30 11:49:00 +00002736
2737 } else {
2738 return ParsePostfixExpression(ok);
2739 }
2740}
2741
2742
2743Expression* Parser::ParsePostfixExpression(bool* ok) {
2744 // PostfixExpression ::
2745 // LeftHandSideExpression ('++' | '--')?
2746
2747 Expression* expression = ParseLeftHandSideExpression(CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002748 if (!scanner().HasAnyLineTerminatorBeforeNext() &&
Ben Murdochb0fe1622011-05-05 13:52:32 +01002749 Token::IsCountOp(peek())) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002750 // Signal a reference error if the expression is an invalid
2751 // left-hand side expression. We could report this as a syntax
2752 // error here but for compatibility with JSC we choose to report the
2753 // error at runtime.
2754 if (expression == NULL || !expression->IsValidLeftHandSide()) {
Steve Block44f0eee2011-05-26 01:26:41 +01002755 Handle<String> type =
2756 isolate()->factory()->invalid_lhs_in_postfix_op_symbol();
Steve Blocka7e24c12009-10-30 11:49:00 +00002757 expression = NewThrowReferenceError(type);
2758 }
Steve Block1e0659c2011-05-24 12:43:12 +01002759
Steve Block44f0eee2011-05-26 01:26:41 +01002760 if (top_scope_->is_strict_mode()) {
Steve Block1e0659c2011-05-24 12:43:12 +01002761 // Postfix expression operand in strict mode may not be eval or arguments.
2762 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
2763 }
2764
Steve Blocka7e24c12009-10-30 11:49:00 +00002765 Token::Value next = Next();
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002766 int position = scanner().location().beg_pos;
Ben Murdoch8b112d22011-06-08 16:22:53 +01002767 expression =
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002768 new(zone()) CountOperation(isolate(),
2769 next,
Ben Murdoch8b112d22011-06-08 16:22:53 +01002770 false /* postfix */,
2771 expression,
2772 position);
Steve Blocka7e24c12009-10-30 11:49:00 +00002773 }
2774 return expression;
2775}
2776
2777
2778Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
2779 // LeftHandSideExpression ::
2780 // (NewExpression | MemberExpression) ...
2781
2782 Expression* result;
2783 if (peek() == Token::NEW) {
2784 result = ParseNewExpression(CHECK_OK);
2785 } else {
2786 result = ParseMemberExpression(CHECK_OK);
2787 }
2788
2789 while (true) {
2790 switch (peek()) {
2791 case Token::LBRACK: {
2792 Consume(Token::LBRACK);
2793 int pos = scanner().location().beg_pos;
2794 Expression* index = ParseExpression(true, CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002795 result = new(zone()) Property(isolate(), result, index, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002796 Expect(Token::RBRACK, CHECK_OK);
2797 break;
2798 }
2799
2800 case Token::LPAREN: {
2801 int pos = scanner().location().beg_pos;
2802 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
2803
2804 // Keep track of eval() calls since they disable all local variable
2805 // optimizations.
2806 // The calls that need special treatment are the
2807 // direct (i.e. not aliased) eval calls. These calls are all of the
2808 // form eval(...) with no explicit receiver object where eval is not
Ben Murdochb8e0da22011-05-16 14:20:40 +01002809 // declared in the current scope chain.
2810 // These calls are marked as potentially direct eval calls. Whether
2811 // they are actually direct calls to eval is determined at run time.
2812 // TODO(994): In ES5, it doesn't matter if the "eval" var is declared
2813 // in the local scope chain. It only matters that it's called "eval",
2814 // is called without a receiver and it refers to the original eval
2815 // function.
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002816 VariableProxy* callee = result->AsVariableProxy();
Steve Block44f0eee2011-05-26 01:26:41 +01002817 if (callee != NULL &&
2818 callee->IsVariable(isolate()->factory()->eval_symbol())) {
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002819 Handle<String> name = callee->name();
2820 Variable* var = top_scope_->Lookup(name);
2821 if (var == NULL) {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002822 top_scope_->DeclarationScope()->RecordEvalCall();
Steve Blocka7e24c12009-10-30 11:49:00 +00002823 }
2824 }
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002825 result = NewCall(result, args, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002826 break;
2827 }
2828
2829 case Token::PERIOD: {
2830 Consume(Token::PERIOD);
2831 int pos = scanner().location().beg_pos;
Ben Murdochbb769b22010-08-11 14:56:33 +01002832 Handle<String> name = ParseIdentifierName(CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002833 result = new(zone()) Property(isolate(),
2834 result,
2835 NewLiteral(name),
2836 pos);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002837 if (fni_ != NULL) fni_->PushLiteralName(name);
Steve Blocka7e24c12009-10-30 11:49:00 +00002838 break;
2839 }
2840
2841 default:
2842 return result;
2843 }
2844 }
2845}
2846
2847
Steve Blocka7e24c12009-10-30 11:49:00 +00002848Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) {
2849 // NewExpression ::
2850 // ('new')+ MemberExpression
2851
2852 // The grammar for new expressions is pretty warped. The keyword
2853 // 'new' can either be a part of the new expression (where it isn't
2854 // followed by an argument list) or a part of the member expression,
2855 // where it must be followed by an argument list. To accommodate
2856 // this, we parse the 'new' keywords greedily and keep track of how
2857 // many we have parsed. This information is then passed on to the
2858 // member expression parser, which is only allowed to match argument
2859 // lists as long as it has 'new' prefixes left
2860 Expect(Token::NEW, CHECK_OK);
2861 PositionStack::Element pos(stack, scanner().location().beg_pos);
2862
2863 Expression* result;
2864 if (peek() == Token::NEW) {
2865 result = ParseNewPrefix(stack, CHECK_OK);
2866 } else {
2867 result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK);
2868 }
2869
2870 if (!stack->is_empty()) {
2871 int last = stack->pop();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002872 result = new(zone()) CallNew(isolate(),
2873 result,
Ben Murdoch257744e2011-11-30 15:57:28 +00002874 new(zone()) ZoneList<Expression*>(0),
2875 last);
Steve Blocka7e24c12009-10-30 11:49:00 +00002876 }
2877 return result;
2878}
2879
2880
2881Expression* Parser::ParseNewExpression(bool* ok) {
2882 PositionStack stack(ok);
2883 return ParseNewPrefix(&stack, ok);
2884}
2885
2886
2887Expression* Parser::ParseMemberExpression(bool* ok) {
2888 return ParseMemberWithNewPrefixesExpression(NULL, ok);
2889}
2890
2891
2892Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
2893 bool* ok) {
2894 // MemberExpression ::
2895 // (PrimaryExpression | FunctionLiteral)
2896 // ('[' Expression ']' | '.' Identifier | Arguments)*
2897
2898 // Parse the initial primary or function expression.
2899 Expression* result = NULL;
2900 if (peek() == Token::FUNCTION) {
2901 Expect(Token::FUNCTION, CHECK_OK);
2902 int function_token_position = scanner().location().beg_pos;
2903 Handle<String> name;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002904 bool is_strict_reserved_name = false;
Steve Block1e0659c2011-05-24 12:43:12 +01002905 if (peek_any_identifier()) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002906 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
2907 CHECK_OK);
Steve Block1e0659c2011-05-24 12:43:12 +01002908 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002909 FunctionLiteral::Type type = name.is_null()
2910 ? FunctionLiteral::ANONYMOUS_EXPRESSION
2911 : FunctionLiteral::NAMED_EXPRESSION;
2912 result = ParseFunctionLiteral(name,
2913 is_strict_reserved_name,
2914 function_token_position,
2915 type,
2916 CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00002917 } else {
2918 result = ParsePrimaryExpression(CHECK_OK);
2919 }
2920
2921 while (true) {
2922 switch (peek()) {
2923 case Token::LBRACK: {
2924 Consume(Token::LBRACK);
2925 int pos = scanner().location().beg_pos;
2926 Expression* index = ParseExpression(true, CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002927 result = new(zone()) Property(isolate(), result, index, pos);
2928 if (fni_ != NULL) {
2929 if (index->IsPropertyName()) {
2930 fni_->PushLiteralName(index->AsLiteral()->AsPropertyName());
2931 } else {
2932 fni_->PushLiteralName(
2933 isolate()->factory()->anonymous_function_symbol());
2934 }
2935 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002936 Expect(Token::RBRACK, CHECK_OK);
2937 break;
2938 }
2939 case Token::PERIOD: {
2940 Consume(Token::PERIOD);
2941 int pos = scanner().location().beg_pos;
Ben Murdochbb769b22010-08-11 14:56:33 +01002942 Handle<String> name = ParseIdentifierName(CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002943 result = new(zone()) Property(isolate(),
2944 result,
2945 NewLiteral(name),
2946 pos);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002947 if (fni_ != NULL) fni_->PushLiteralName(name);
Steve Blocka7e24c12009-10-30 11:49:00 +00002948 break;
2949 }
2950 case Token::LPAREN: {
2951 if ((stack == NULL) || stack->is_empty()) return result;
2952 // Consume one of the new prefixes (already parsed).
2953 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
2954 int last = stack->pop();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002955 result = new(zone()) CallNew(isolate(), result, args, last);
Steve Blocka7e24c12009-10-30 11:49:00 +00002956 break;
2957 }
2958 default:
2959 return result;
2960 }
2961 }
2962}
2963
2964
2965DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
2966 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
2967 // contexts this is used as a statement which invokes the debugger as i a
2968 // break point is present.
2969 // DebuggerStatement ::
2970 // 'debugger' ';'
2971
2972 Expect(Token::DEBUGGER, CHECK_OK);
2973 ExpectSemicolon(CHECK_OK);
Ben Murdoch8b112d22011-06-08 16:22:53 +01002974 return new(zone()) DebuggerStatement();
Steve Blocka7e24c12009-10-30 11:49:00 +00002975}
2976
2977
2978void Parser::ReportUnexpectedToken(Token::Value token) {
2979 // We don't report stack overflows here, to avoid increasing the
2980 // stack depth even further. Instead we report it after parsing is
Leon Clarke4515c472010-02-03 11:58:03 +00002981 // over, in ParseProgram/ParseJson.
Ben Murdochb0fe1622011-05-05 13:52:32 +01002982 if (token == Token::ILLEGAL && stack_overflow_) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002983 // Four of the tokens are treated specially
2984 switch (token) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01002985 case Token::EOS:
2986 return ReportMessage("unexpected_eos", Vector<const char*>::empty());
2987 case Token::NUMBER:
2988 return ReportMessage("unexpected_token_number",
2989 Vector<const char*>::empty());
2990 case Token::STRING:
2991 return ReportMessage("unexpected_token_string",
2992 Vector<const char*>::empty());
2993 case Token::IDENTIFIER:
2994 return ReportMessage("unexpected_token_identifier",
2995 Vector<const char*>::empty());
Steve Block1e0659c2011-05-24 12:43:12 +01002996 case Token::FUTURE_RESERVED_WORD:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002997 return ReportMessage("unexpected_reserved",
2998 Vector<const char*>::empty());
2999 case Token::FUTURE_STRICT_RESERVED_WORD:
Steve Block44f0eee2011-05-26 01:26:41 +01003000 return ReportMessage(top_scope_->is_strict_mode() ?
Steve Block1e0659c2011-05-24 12:43:12 +01003001 "unexpected_strict_reserved" :
3002 "unexpected_token_identifier",
3003 Vector<const char*>::empty());
Ben Murdochb0fe1622011-05-05 13:52:32 +01003004 default:
3005 const char* name = Token::String(token);
3006 ASSERT(name != NULL);
3007 ReportMessage("unexpected_token", Vector<const char*>(&name, 1));
Steve Blocka7e24c12009-10-30 11:49:00 +00003008 }
3009}
3010
3011
Leon Clarkeac952652010-07-15 11:15:24 +01003012void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) {
Ben Murdoch589d6972011-11-30 16:04:58 +00003013 SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS);
Leon Clarkeac952652010-07-15 11:15:24 +01003014 const char* element[1] = { *name_string };
3015 ReportMessage("invalid_preparser_data",
3016 Vector<const char*>(element, 1));
3017 *ok = false;
3018}
3019
3020
Steve Blocka7e24c12009-10-30 11:49:00 +00003021Expression* Parser::ParsePrimaryExpression(bool* ok) {
3022 // PrimaryExpression ::
3023 // 'this'
3024 // 'null'
3025 // 'true'
3026 // 'false'
3027 // Identifier
3028 // Number
3029 // String
3030 // ArrayLiteral
3031 // ObjectLiteral
3032 // RegExpLiteral
3033 // '(' Expression ')'
3034
3035 Expression* result = NULL;
3036 switch (peek()) {
3037 case Token::THIS: {
3038 Consume(Token::THIS);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003039 result = new(zone()) VariableProxy(isolate(), top_scope_->receiver());
Steve Blocka7e24c12009-10-30 11:49:00 +00003040 break;
3041 }
3042
3043 case Token::NULL_LITERAL:
3044 Consume(Token::NULL_LITERAL);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003045 result = new(zone()) Literal(
3046 isolate(), isolate()->factory()->null_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00003047 break;
3048
3049 case Token::TRUE_LITERAL:
3050 Consume(Token::TRUE_LITERAL);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003051 result = new(zone()) Literal(
3052 isolate(), isolate()->factory()->true_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00003053 break;
3054
3055 case Token::FALSE_LITERAL:
3056 Consume(Token::FALSE_LITERAL);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003057 result = new(zone()) Literal(
3058 isolate(), isolate()->factory()->false_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00003059 break;
3060
Steve Block1e0659c2011-05-24 12:43:12 +01003061 case Token::IDENTIFIER:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003062 case Token::FUTURE_STRICT_RESERVED_WORD: {
Steve Blocka7e24c12009-10-30 11:49:00 +00003063 Handle<String> name = ParseIdentifier(CHECK_OK);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003064 if (fni_ != NULL) fni_->PushVariableName(name);
Ben Murdoch8b112d22011-06-08 16:22:53 +01003065 result = top_scope_->NewUnresolved(name,
3066 inside_with(),
3067 scanner().location().beg_pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00003068 break;
3069 }
3070
3071 case Token::NUMBER: {
3072 Consume(Token::NUMBER);
Steve Block9fac8402011-05-12 15:51:54 +01003073 ASSERT(scanner().is_literal_ascii());
Ben Murdoch8b112d22011-06-08 16:22:53 +01003074 double value = StringToDouble(isolate()->unicode_cache(),
3075 scanner().literal_ascii_string(),
Steve Block9fac8402011-05-12 15:51:54 +01003076 ALLOW_HEX | ALLOW_OCTALS);
Steve Blocka7e24c12009-10-30 11:49:00 +00003077 result = NewNumberLiteral(value);
3078 break;
3079 }
3080
3081 case Token::STRING: {
3082 Consume(Token::STRING);
Iain Merrick9ac36c92010-09-13 15:29:50 +01003083 Handle<String> symbol = GetSymbol(CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003084 result = NewLiteral(symbol);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003085 if (fni_ != NULL) fni_->PushLiteralName(symbol);
Steve Blocka7e24c12009-10-30 11:49:00 +00003086 break;
3087 }
3088
3089 case Token::ASSIGN_DIV:
3090 result = ParseRegExpLiteral(true, CHECK_OK);
3091 break;
3092
3093 case Token::DIV:
3094 result = ParseRegExpLiteral(false, CHECK_OK);
3095 break;
3096
3097 case Token::LBRACK:
3098 result = ParseArrayLiteral(CHECK_OK);
3099 break;
3100
3101 case Token::LBRACE:
3102 result = ParseObjectLiteral(CHECK_OK);
3103 break;
3104
3105 case Token::LPAREN:
3106 Consume(Token::LPAREN);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003107 // Heuristically try to detect immediately called functions before
3108 // seeing the call parentheses.
3109 parenthesized_function_ = (peek() == Token::FUNCTION);
Steve Blocka7e24c12009-10-30 11:49:00 +00003110 result = ParseExpression(true, CHECK_OK);
3111 Expect(Token::RPAREN, CHECK_OK);
3112 break;
3113
3114 case Token::MOD:
3115 if (allow_natives_syntax_ || extension_ != NULL) {
3116 result = ParseV8Intrinsic(CHECK_OK);
3117 break;
3118 }
3119 // If we're not allowing special syntax we fall-through to the
3120 // default case.
3121
3122 default: {
Ben Murdochbb769b22010-08-11 14:56:33 +01003123 Token::Value tok = Next();
Steve Blocka7e24c12009-10-30 11:49:00 +00003124 ReportUnexpectedToken(tok);
3125 *ok = false;
3126 return NULL;
3127 }
3128 }
3129
3130 return result;
3131}
3132
3133
Leon Clarke4515c472010-02-03 11:58:03 +00003134void Parser::BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* values,
3135 Handle<FixedArray> literals,
3136 bool* is_simple,
3137 int* depth) {
3138 // Fill in the literals.
3139 // Accumulate output values in local variables.
3140 bool is_simple_acc = true;
3141 int depth_acc = 1;
3142 for (int i = 0; i < values->length(); i++) {
3143 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral();
3144 if (m_literal != NULL && m_literal->depth() >= depth_acc) {
3145 depth_acc = m_literal->depth() + 1;
3146 }
3147 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i));
3148 if (boilerplate_value->IsUndefined()) {
3149 literals->set_the_hole(i);
3150 is_simple_acc = false;
3151 } else {
3152 literals->set(i, *boilerplate_value);
3153 }
3154 }
3155
3156 *is_simple = is_simple_acc;
3157 *depth = depth_acc;
3158}
3159
3160
Steve Blocka7e24c12009-10-30 11:49:00 +00003161Expression* Parser::ParseArrayLiteral(bool* ok) {
3162 // ArrayLiteral ::
3163 // '[' Expression? (',' Expression?)* ']'
3164
Ben Murdoch257744e2011-11-30 15:57:28 +00003165 ZoneList<Expression*>* values = new(zone()) ZoneList<Expression*>(4);
Steve Blocka7e24c12009-10-30 11:49:00 +00003166 Expect(Token::LBRACK, CHECK_OK);
3167 while (peek() != Token::RBRACK) {
3168 Expression* elem;
3169 if (peek() == Token::COMMA) {
3170 elem = GetLiteralTheHole();
3171 } else {
3172 elem = ParseAssignmentExpression(true, CHECK_OK);
3173 }
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003174 values->Add(elem);
Steve Blocka7e24c12009-10-30 11:49:00 +00003175 if (peek() != Token::RBRACK) {
3176 Expect(Token::COMMA, CHECK_OK);
3177 }
3178 }
3179 Expect(Token::RBRACK, CHECK_OK);
3180
3181 // Update the scope information before the pre-parsing bailout.
Steve Block44f0eee2011-05-26 01:26:41 +01003182 int literal_index = lexical_scope_->NextMaterializedLiteralIndex();
Steve Blocka7e24c12009-10-30 11:49:00 +00003183
Steve Blocka7e24c12009-10-30 11:49:00 +00003184 // Allocate a fixed array with all the literals.
3185 Handle<FixedArray> literals =
Steve Block44f0eee2011-05-26 01:26:41 +01003186 isolate()->factory()->NewFixedArray(values->length(), TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00003187
3188 // Fill in the literals.
3189 bool is_simple = true;
3190 int depth = 1;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003191 for (int i = 0, n = values->length(); i < n; i++) {
3192 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral();
Steve Blocka7e24c12009-10-30 11:49:00 +00003193 if (m_literal != NULL && m_literal->depth() + 1 > depth) {
3194 depth = m_literal->depth() + 1;
3195 }
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003196 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i));
Steve Blocka7e24c12009-10-30 11:49:00 +00003197 if (boilerplate_value->IsUndefined()) {
3198 literals->set_the_hole(i);
3199 is_simple = false;
3200 } else {
3201 literals->set(i, *boilerplate_value);
3202 }
3203 }
3204
Iain Merrick75681382010-08-19 15:07:18 +01003205 // Simple and shallow arrays can be lazily copied, we transform the
3206 // elements array to a copy-on-write array.
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003207 if (is_simple && depth == 1 && values->length() > 0) {
Steve Block44f0eee2011-05-26 01:26:41 +01003208 literals->set_map(isolate()->heap()->fixed_cow_array_map());
Iain Merrick75681382010-08-19 15:07:18 +01003209 }
3210
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003211 return new(zone()) ArrayLiteral(
3212 isolate(), literals, values, literal_index, is_simple, depth);
Steve Blocka7e24c12009-10-30 11:49:00 +00003213}
3214
3215
3216bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) {
3217 return property != NULL &&
3218 property->kind() != ObjectLiteral::Property::PROTOTYPE;
3219}
3220
3221
3222bool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01003223 if (expression->AsLiteral() != NULL) return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00003224 MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3225 return lit != NULL && lit->is_simple();
3226}
3227
Iain Merrick75681382010-08-19 15:07:18 +01003228
3229bool CompileTimeValue::ArrayLiteralElementNeedsInitialization(
3230 Expression* value) {
3231 // If value is a literal the property value is already set in the
3232 // boilerplate object.
3233 if (value->AsLiteral() != NULL) return false;
3234 // If value is a materialized literal the property value is already set
3235 // in the boilerplate object if it is simple.
3236 if (CompileTimeValue::IsCompileTimeValue(value)) return false;
3237 return true;
3238}
3239
3240
Steve Blocka7e24c12009-10-30 11:49:00 +00003241Handle<FixedArray> CompileTimeValue::GetValue(Expression* expression) {
3242 ASSERT(IsCompileTimeValue(expression));
Steve Block44f0eee2011-05-26 01:26:41 +01003243 Handle<FixedArray> result = FACTORY->NewFixedArray(2, TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00003244 ObjectLiteral* object_literal = expression->AsObjectLiteral();
3245 if (object_literal != NULL) {
3246 ASSERT(object_literal->is_simple());
Steve Block6ded16b2010-05-10 14:33:55 +01003247 if (object_literal->fast_elements()) {
3248 result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
3249 } else {
3250 result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
3251 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003252 result->set(kElementsSlot, *object_literal->constant_properties());
3253 } else {
3254 ArrayLiteral* array_literal = expression->AsArrayLiteral();
3255 ASSERT(array_literal != NULL && array_literal->is_simple());
3256 result->set(kTypeSlot, Smi::FromInt(ARRAY_LITERAL));
Leon Clarkee46be812010-01-19 14:06:41 +00003257 result->set(kElementsSlot, *array_literal->constant_elements());
Steve Blocka7e24c12009-10-30 11:49:00 +00003258 }
3259 return result;
3260}
3261
3262
3263CompileTimeValue::Type CompileTimeValue::GetType(Handle<FixedArray> value) {
3264 Smi* type_value = Smi::cast(value->get(kTypeSlot));
3265 return static_cast<Type>(type_value->value());
3266}
3267
3268
3269Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
3270 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
3271}
3272
3273
3274Handle<Object> Parser::GetBoilerplateValue(Expression* expression) {
3275 if (expression->AsLiteral() != NULL) {
3276 return expression->AsLiteral()->handle();
3277 }
3278 if (CompileTimeValue::IsCompileTimeValue(expression)) {
3279 return CompileTimeValue::GetValue(expression);
3280 }
Steve Block44f0eee2011-05-26 01:26:41 +01003281 return isolate()->factory()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00003282}
3283
Steve Block1e0659c2011-05-24 12:43:12 +01003284// Defined in ast.cc
3285bool IsEqualString(void* first, void* second);
3286bool IsEqualNumber(void* first, void* second);
3287
3288
3289// Validation per 11.1.5 Object Initialiser
3290class ObjectLiteralPropertyChecker {
3291 public:
3292 ObjectLiteralPropertyChecker(Parser* parser, bool strict) :
3293 props(&IsEqualString),
3294 elems(&IsEqualNumber),
3295 parser_(parser),
3296 strict_(strict) {
3297 }
3298
3299 void CheckProperty(
3300 ObjectLiteral::Property* property,
3301 Scanner::Location loc,
3302 bool* ok);
3303
3304 private:
3305 enum PropertyKind {
3306 kGetAccessor = 0x01,
3307 kSetAccessor = 0x02,
3308 kAccessor = kGetAccessor | kSetAccessor,
3309 kData = 0x04
3310 };
3311
3312 static intptr_t GetPropertyKind(ObjectLiteral::Property* property) {
3313 switch (property->kind()) {
3314 case ObjectLiteral::Property::GETTER:
3315 return kGetAccessor;
3316 case ObjectLiteral::Property::SETTER:
3317 return kSetAccessor;
3318 default:
3319 return kData;
3320 }
3321 }
3322
3323 HashMap props;
3324 HashMap elems;
3325 Parser* parser_;
3326 bool strict_;
3327};
3328
3329
3330void ObjectLiteralPropertyChecker::CheckProperty(
3331 ObjectLiteral::Property* property,
3332 Scanner::Location loc,
3333 bool* ok) {
3334
3335 ASSERT(property != NULL);
3336
3337 Literal *lit = property->key();
3338 Handle<Object> handle = lit->handle();
3339
3340 uint32_t hash;
3341 HashMap* map;
3342 void* key;
3343
3344 if (handle->IsSymbol()) {
3345 Handle<String> name(String::cast(*handle));
3346 if (name->AsArrayIndex(&hash)) {
Steve Block44f0eee2011-05-26 01:26:41 +01003347 Handle<Object> key_handle = FACTORY->NewNumberFromUint(hash);
Steve Block1e0659c2011-05-24 12:43:12 +01003348 key = key_handle.location();
3349 map = &elems;
3350 } else {
3351 key = handle.location();
3352 hash = name->Hash();
3353 map = &props;
3354 }
3355 } else if (handle->ToArrayIndex(&hash)) {
3356 key = handle.location();
3357 map = &elems;
3358 } else {
3359 ASSERT(handle->IsNumber());
3360 double num = handle->Number();
3361 char arr[100];
3362 Vector<char> buffer(arr, ARRAY_SIZE(arr));
3363 const char* str = DoubleToCString(num, buffer);
Steve Block44f0eee2011-05-26 01:26:41 +01003364 Handle<String> name = FACTORY->NewStringFromAscii(CStrVector(str));
Steve Block1e0659c2011-05-24 12:43:12 +01003365 key = name.location();
3366 hash = name->Hash();
3367 map = &props;
3368 }
3369
3370 // Lookup property previously defined, if any.
3371 HashMap::Entry* entry = map->Lookup(key, hash, true);
3372 intptr_t prev = reinterpret_cast<intptr_t> (entry->value);
3373 intptr_t curr = GetPropertyKind(property);
3374
3375 // Duplicate data properties are illegal in strict mode.
3376 if (strict_ && (curr & prev & kData) != 0) {
3377 parser_->ReportMessageAt(loc, "strict_duplicate_property",
3378 Vector<const char*>::empty());
3379 *ok = false;
3380 return;
3381 }
3382 // Data property conflicting with an accessor.
3383 if (((curr & kData) && (prev & kAccessor)) ||
3384 ((prev & kData) && (curr & kAccessor))) {
3385 parser_->ReportMessageAt(loc, "accessor_data_property",
3386 Vector<const char*>::empty());
3387 *ok = false;
3388 return;
3389 }
3390 // Two accessors of the same type conflicting
3391 if ((curr & prev & kAccessor) != 0) {
3392 parser_->ReportMessageAt(loc, "accessor_get_set",
3393 Vector<const char*>::empty());
3394 *ok = false;
3395 return;
3396 }
3397
3398 // Update map
3399 entry->value = reinterpret_cast<void*> (prev | curr);
3400 *ok = true;
3401}
3402
Steve Blocka7e24c12009-10-30 11:49:00 +00003403
Leon Clarke4515c472010-02-03 11:58:03 +00003404void Parser::BuildObjectLiteralConstantProperties(
3405 ZoneList<ObjectLiteral::Property*>* properties,
3406 Handle<FixedArray> constant_properties,
3407 bool* is_simple,
Steve Block6ded16b2010-05-10 14:33:55 +01003408 bool* fast_elements,
Leon Clarke4515c472010-02-03 11:58:03 +00003409 int* depth) {
3410 int position = 0;
3411 // Accumulate the value in local variables and store it at the end.
3412 bool is_simple_acc = true;
3413 int depth_acc = 1;
Steve Block6ded16b2010-05-10 14:33:55 +01003414 uint32_t max_element_index = 0;
3415 uint32_t elements = 0;
Leon Clarke4515c472010-02-03 11:58:03 +00003416 for (int i = 0; i < properties->length(); i++) {
3417 ObjectLiteral::Property* property = properties->at(i);
3418 if (!IsBoilerplateProperty(property)) {
3419 is_simple_acc = false;
3420 continue;
3421 }
3422 MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral();
3423 if (m_literal != NULL && m_literal->depth() >= depth_acc) {
3424 depth_acc = m_literal->depth() + 1;
3425 }
3426
3427 // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined
3428 // value for COMPUTED properties, the real value is filled in at
3429 // runtime. The enumeration order is maintained.
3430 Handle<Object> key = property->key()->handle();
3431 Handle<Object> value = GetBoilerplateValue(property->value());
3432 is_simple_acc = is_simple_acc && !value->IsUndefined();
3433
Steve Block6ded16b2010-05-10 14:33:55 +01003434 // Keep track of the number of elements in the object literal and
3435 // the largest element index. If the largest element index is
3436 // much larger than the number of elements, creating an object
3437 // literal with fast elements will be a waste of space.
3438 uint32_t element_index = 0;
3439 if (key->IsString()
3440 && Handle<String>::cast(key)->AsArrayIndex(&element_index)
3441 && element_index > max_element_index) {
3442 max_element_index = element_index;
3443 elements++;
3444 } else if (key->IsSmi()) {
3445 int key_value = Smi::cast(*key)->value();
3446 if (key_value > 0
3447 && static_cast<uint32_t>(key_value) > max_element_index) {
3448 max_element_index = key_value;
3449 }
3450 elements++;
3451 }
3452
Leon Clarke4515c472010-02-03 11:58:03 +00003453 // Add name, value pair to the fixed array.
3454 constant_properties->set(position++, *key);
3455 constant_properties->set(position++, *value);
3456 }
Steve Block6ded16b2010-05-10 14:33:55 +01003457 *fast_elements =
3458 (max_element_index <= 32) || ((2 * elements) >= max_element_index);
Leon Clarke4515c472010-02-03 11:58:03 +00003459 *is_simple = is_simple_acc;
3460 *depth = depth_acc;
3461}
3462
3463
Ben Murdochbb769b22010-08-11 14:56:33 +01003464ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
3465 bool* ok) {
3466 // Special handling of getter and setter syntax:
3467 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
3468 // We have already read the "get" or "set" keyword.
3469 Token::Value next = Next();
Steve Block9fac8402011-05-12 15:51:54 +01003470 bool is_keyword = Token::IsKeyword(next);
3471 if (next == Token::IDENTIFIER || next == Token::NUMBER ||
Steve Block1e0659c2011-05-24 12:43:12 +01003472 next == Token::FUTURE_RESERVED_WORD ||
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003473 next == Token::FUTURE_STRICT_RESERVED_WORD ||
Steve Block9fac8402011-05-12 15:51:54 +01003474 next == Token::STRING || is_keyword) {
3475 Handle<String> name;
3476 if (is_keyword) {
Steve Block44f0eee2011-05-26 01:26:41 +01003477 name = isolate_->factory()->LookupAsciiSymbol(Token::String(next));
Steve Block9fac8402011-05-12 15:51:54 +01003478 } else {
3479 name = GetSymbol(CHECK_OK);
3480 }
Ben Murdochbb769b22010-08-11 14:56:33 +01003481 FunctionLiteral* value =
3482 ParseFunctionLiteral(name,
Steve Block1e0659c2011-05-24 12:43:12 +01003483 false, // reserved words are allowed here
Ben Murdochbb769b22010-08-11 14:56:33 +01003484 RelocInfo::kNoPosition,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003485 FunctionLiteral::ANONYMOUS_EXPRESSION,
Ben Murdochbb769b22010-08-11 14:56:33 +01003486 CHECK_OK);
Steve Block9fac8402011-05-12 15:51:54 +01003487 // Allow any number of parameters for compatiabilty with JSC.
3488 // Specification only allows zero parameters for get and one for set.
Ben Murdochbb769b22010-08-11 14:56:33 +01003489 ObjectLiteral::Property* property =
Ben Murdoch8b112d22011-06-08 16:22:53 +01003490 new(zone()) ObjectLiteral::Property(is_getter, value);
Ben Murdochbb769b22010-08-11 14:56:33 +01003491 return property;
3492 } else {
3493 ReportUnexpectedToken(next);
3494 *ok = false;
3495 return NULL;
3496 }
3497}
3498
3499
Steve Blocka7e24c12009-10-30 11:49:00 +00003500Expression* Parser::ParseObjectLiteral(bool* ok) {
3501 // ObjectLiteral ::
3502 // '{' (
Ben Murdochbb769b22010-08-11 14:56:33 +01003503 // ((IdentifierName | String | Number) ':' AssignmentExpression)
3504 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +00003505 // )*[','] '}'
3506
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003507 ZoneList<ObjectLiteral::Property*>* properties =
Ben Murdoch257744e2011-11-30 15:57:28 +00003508 new(zone()) ZoneList<ObjectLiteral::Property*>(4);
Steve Blocka7e24c12009-10-30 11:49:00 +00003509 int number_of_boilerplate_properties = 0;
Steve Block44f0eee2011-05-26 01:26:41 +01003510 bool has_function = false;
Steve Blocka7e24c12009-10-30 11:49:00 +00003511
Steve Block44f0eee2011-05-26 01:26:41 +01003512 ObjectLiteralPropertyChecker checker(this, top_scope_->is_strict_mode());
Steve Block1e0659c2011-05-24 12:43:12 +01003513
Steve Blocka7e24c12009-10-30 11:49:00 +00003514 Expect(Token::LBRACE, CHECK_OK);
Steve Block1e0659c2011-05-24 12:43:12 +01003515
Steve Blocka7e24c12009-10-30 11:49:00 +00003516 while (peek() != Token::RBRACE) {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003517 if (fni_ != NULL) fni_->Enter();
3518
Steve Blocka7e24c12009-10-30 11:49:00 +00003519 Literal* key = NULL;
Ben Murdochbb769b22010-08-11 14:56:33 +01003520 Token::Value next = peek();
Steve Block1e0659c2011-05-24 12:43:12 +01003521
3522 // Location of the property name token
3523 Scanner::Location loc = scanner().peek_location();
3524
Ben Murdochbb769b22010-08-11 14:56:33 +01003525 switch (next) {
Steve Block1e0659c2011-05-24 12:43:12 +01003526 case Token::FUTURE_RESERVED_WORD:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003527 case Token::FUTURE_STRICT_RESERVED_WORD:
Steve Blocka7e24c12009-10-30 11:49:00 +00003528 case Token::IDENTIFIER: {
Steve Blocka7e24c12009-10-30 11:49:00 +00003529 bool is_getter = false;
3530 bool is_setter = false;
3531 Handle<String> id =
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003532 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003533 if (fni_ != NULL) fni_->PushLiteralName(id);
3534
Ben Murdochbb769b22010-08-11 14:56:33 +01003535 if ((is_getter || is_setter) && peek() != Token::COLON) {
Steve Block1e0659c2011-05-24 12:43:12 +01003536 // Update loc to point to the identifier
3537 loc = scanner().peek_location();
Steve Blocka7e24c12009-10-30 11:49:00 +00003538 ObjectLiteral::Property* property =
Ben Murdochbb769b22010-08-11 14:56:33 +01003539 ParseObjectLiteralGetSet(is_getter, CHECK_OK);
3540 if (IsBoilerplateProperty(property)) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003541 number_of_boilerplate_properties++;
Ben Murdochbb769b22010-08-11 14:56:33 +01003542 }
Steve Block1e0659c2011-05-24 12:43:12 +01003543 // Validate the property.
3544 checker.CheckProperty(property, loc, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003545 properties->Add(property);
Steve Blocka7e24c12009-10-30 11:49:00 +00003546 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003547
3548 if (fni_ != NULL) {
3549 fni_->Infer();
3550 fni_->Leave();
3551 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003552 continue; // restart the while
Steve Blocka7e24c12009-10-30 11:49:00 +00003553 }
Ben Murdochbb769b22010-08-11 14:56:33 +01003554 // Failed to parse as get/set property, so it's just a property
3555 // called "get" or "set".
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003556 key = NewLiteral(id);
Steve Blocka7e24c12009-10-30 11:49:00 +00003557 break;
3558 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003559 case Token::STRING: {
3560 Consume(Token::STRING);
Iain Merrick9ac36c92010-09-13 15:29:50 +01003561 Handle<String> string = GetSymbol(CHECK_OK);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003562 if (fni_ != NULL) fni_->PushLiteralName(string);
Steve Blocka7e24c12009-10-30 11:49:00 +00003563 uint32_t index;
Iain Merrick75681382010-08-19 15:07:18 +01003564 if (!string.is_null() && string->AsArrayIndex(&index)) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003565 key = NewNumberLiteral(index);
Ben Murdochbb769b22010-08-11 14:56:33 +01003566 break;
Steve Blocka7e24c12009-10-30 11:49:00 +00003567 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003568 key = NewLiteral(string);
Steve Blocka7e24c12009-10-30 11:49:00 +00003569 break;
3570 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003571 case Token::NUMBER: {
3572 Consume(Token::NUMBER);
Steve Block9fac8402011-05-12 15:51:54 +01003573 ASSERT(scanner().is_literal_ascii());
Ben Murdoch8b112d22011-06-08 16:22:53 +01003574 double value = StringToDouble(isolate()->unicode_cache(),
3575 scanner().literal_ascii_string(),
Steve Block9fac8402011-05-12 15:51:54 +01003576 ALLOW_HEX | ALLOW_OCTALS);
Steve Blocka7e24c12009-10-30 11:49:00 +00003577 key = NewNumberLiteral(value);
3578 break;
3579 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003580 default:
Ben Murdochbb769b22010-08-11 14:56:33 +01003581 if (Token::IsKeyword(next)) {
3582 Consume(next);
Iain Merrick9ac36c92010-09-13 15:29:50 +01003583 Handle<String> string = GetSymbol(CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003584 key = NewLiteral(string);
Ben Murdochbb769b22010-08-11 14:56:33 +01003585 } else {
3586 // Unexpected token.
3587 Token::Value next = Next();
3588 ReportUnexpectedToken(next);
3589 *ok = false;
3590 return NULL;
3591 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003592 }
3593
3594 Expect(Token::COLON, CHECK_OK);
3595 Expression* value = ParseAssignmentExpression(true, CHECK_OK);
3596
3597 ObjectLiteral::Property* property =
Ben Murdoch8b112d22011-06-08 16:22:53 +01003598 new(zone()) ObjectLiteral::Property(key, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003599
Steve Block44f0eee2011-05-26 01:26:41 +01003600 // Mark object literals that contain function literals and pretenure the
3601 // literal so it can be added as a constant function property.
3602 if (value->AsFunctionLiteral() != NULL) {
3603 has_function = true;
3604 value->AsFunctionLiteral()->set_pretenure(true);
3605 }
3606
Steve Blocka7e24c12009-10-30 11:49:00 +00003607 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
3608 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++;
Steve Block1e0659c2011-05-24 12:43:12 +01003609 // Validate the property
3610 checker.CheckProperty(property, loc, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003611 properties->Add(property);
Steve Blocka7e24c12009-10-30 11:49:00 +00003612
3613 // TODO(1240767): Consider allowing trailing comma.
3614 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003615
3616 if (fni_ != NULL) {
3617 fni_->Infer();
3618 fni_->Leave();
3619 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003620 }
3621 Expect(Token::RBRACE, CHECK_OK);
Steve Block1e0659c2011-05-24 12:43:12 +01003622
Steve Blocka7e24c12009-10-30 11:49:00 +00003623 // Computation of literal_index must happen before pre parse bailout.
Steve Block44f0eee2011-05-26 01:26:41 +01003624 int literal_index = lexical_scope_->NextMaterializedLiteralIndex();
Steve Blocka7e24c12009-10-30 11:49:00 +00003625
Steve Block44f0eee2011-05-26 01:26:41 +01003626 Handle<FixedArray> constant_properties = isolate()->factory()->NewFixedArray(
3627 number_of_boilerplate_properties * 2, TENURED);
Leon Clarke4515c472010-02-03 11:58:03 +00003628
Steve Blocka7e24c12009-10-30 11:49:00 +00003629 bool is_simple = true;
Steve Block6ded16b2010-05-10 14:33:55 +01003630 bool fast_elements = true;
Steve Blocka7e24c12009-10-30 11:49:00 +00003631 int depth = 1;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003632 BuildObjectLiteralConstantProperties(properties,
Leon Clarke4515c472010-02-03 11:58:03 +00003633 constant_properties,
3634 &is_simple,
Steve Block6ded16b2010-05-10 14:33:55 +01003635 &fast_elements,
Leon Clarke4515c472010-02-03 11:58:03 +00003636 &depth);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003637 return new(zone()) ObjectLiteral(isolate(),
3638 constant_properties,
3639 properties,
3640 literal_index,
3641 is_simple,
3642 fast_elements,
3643 depth,
3644 has_function);
Steve Blocka7e24c12009-10-30 11:49:00 +00003645}
3646
3647
3648Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01003649 if (!scanner().ScanRegExpPattern(seen_equal)) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003650 Next();
3651 ReportMessage("unterminated_regexp", Vector<const char*>::empty());
3652 *ok = false;
3653 return NULL;
3654 }
3655
Steve Block44f0eee2011-05-26 01:26:41 +01003656 int literal_index = lexical_scope_->NextMaterializedLiteralIndex();
Steve Blocka7e24c12009-10-30 11:49:00 +00003657
Steve Block9fac8402011-05-12 15:51:54 +01003658 Handle<String> js_pattern = NextLiteralString(TENURED);
Ben Murdochb0fe1622011-05-05 13:52:32 +01003659 scanner().ScanRegExpFlags();
Steve Block9fac8402011-05-12 15:51:54 +01003660 Handle<String> js_flags = NextLiteralString(TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00003661 Next();
3662
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003663 return new(zone()) RegExpLiteral(
3664 isolate(), js_pattern, js_flags, literal_index);
Steve Blocka7e24c12009-10-30 11:49:00 +00003665}
3666
3667
3668ZoneList<Expression*>* Parser::ParseArguments(bool* ok) {
3669 // Arguments ::
3670 // '(' (AssignmentExpression)*[','] ')'
3671
Ben Murdoch257744e2011-11-30 15:57:28 +00003672 ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4);
Steve Blocka7e24c12009-10-30 11:49:00 +00003673 Expect(Token::LPAREN, CHECK_OK);
3674 bool done = (peek() == Token::RPAREN);
3675 while (!done) {
3676 Expression* argument = ParseAssignmentExpression(true, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003677 result->Add(argument);
Steve Block053d10c2011-06-13 19:13:29 +01003678 if (result->length() > kMaxNumFunctionParameters) {
3679 ReportMessageAt(scanner().location(), "too_many_arguments",
3680 Vector<const char*>::empty());
3681 *ok = false;
3682 return NULL;
3683 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003684 done = (peek() == Token::RPAREN);
3685 if (!done) Expect(Token::COMMA, CHECK_OK);
3686 }
3687 Expect(Token::RPAREN, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003688 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00003689}
3690
3691
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003692FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
3693 bool name_is_strict_reserved,
Steve Blocka7e24c12009-10-30 11:49:00 +00003694 int function_token_position,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003695 FunctionLiteral::Type type,
Steve Blocka7e24c12009-10-30 11:49:00 +00003696 bool* ok) {
3697 // Function ::
3698 // '(' FormalParameterList? ')' '{' FunctionBody '}'
Steve Blocka7e24c12009-10-30 11:49:00 +00003699
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003700 // Anonymous functions were passed either the empty symbol or a null
3701 // handle as the function name. Remember if we were passed a non-empty
3702 // handle to decide whether to invoke function name inference.
3703 bool should_infer_name = function_name.is_null();
3704
3705 // We want a non-null handle as the function name.
3706 if (should_infer_name) {
3707 function_name = isolate()->factory()->empty_symbol();
Steve Blocka7e24c12009-10-30 11:49:00 +00003708 }
3709
3710 int num_parameters = 0;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003711 // Function declarations are function scoped in normal mode, so they are
3712 // hoisted. In harmony block scoping mode they are block scoped, so they
3713 // are not hoisted.
3714 Scope* scope = (type == FunctionLiteral::DECLARATION &&
3715 !harmony_block_scoping_)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003716 ? NewScope(top_scope_->DeclarationScope(), Scope::FUNCTION_SCOPE, false)
3717 : NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with());
Ben Murdoch257744e2011-11-30 15:57:28 +00003718 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8);
Ben Murdoch8b112d22011-06-08 16:22:53 +01003719 int materialized_literal_count;
3720 int expected_property_count;
3721 int start_pos;
3722 int end_pos;
3723 bool only_simple_this_property_assignments;
3724 Handle<FixedArray> this_property_assignments;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003725 bool has_duplicate_parameters = false;
Steve Blocka7e24c12009-10-30 11:49:00 +00003726 // Parse function body.
Ben Murdoch8b112d22011-06-08 16:22:53 +01003727 { LexicalScope lexical_scope(this, scope, isolate());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003728 top_scope_->SetScopeName(function_name);
Steve Blocka7e24c12009-10-30 11:49:00 +00003729
3730 // FormalParameterList ::
3731 // '(' (Identifier)*[','] ')'
3732 Expect(Token::LPAREN, CHECK_OK);
Ben Murdoch8b112d22011-06-08 16:22:53 +01003733 start_pos = scanner().location().beg_pos;
Ben Murdoch257744e2011-11-30 15:57:28 +00003734 Scanner::Location name_loc = Scanner::Location::invalid();
3735 Scanner::Location dupe_loc = Scanner::Location::invalid();
3736 Scanner::Location reserved_loc = Scanner::Location::invalid();
Steve Block1e0659c2011-05-24 12:43:12 +01003737
Steve Blocka7e24c12009-10-30 11:49:00 +00003738 bool done = (peek() == Token::RPAREN);
3739 while (!done) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003740 bool is_strict_reserved = false;
Steve Block1e0659c2011-05-24 12:43:12 +01003741 Handle<String> param_name =
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003742 ParseIdentifierOrStrictReservedWord(&is_strict_reserved,
3743 CHECK_OK);
Steve Block1e0659c2011-05-24 12:43:12 +01003744
3745 // Store locations for possible future error reports.
3746 if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) {
3747 name_loc = scanner().location();
3748 }
3749 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003750 has_duplicate_parameters = true;
Steve Block1e0659c2011-05-24 12:43:12 +01003751 dupe_loc = scanner().location();
3752 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003753 if (!reserved_loc.IsValid() && is_strict_reserved) {
Steve Block1e0659c2011-05-24 12:43:12 +01003754 reserved_loc = scanner().location();
3755 }
3756
Ben Murdoch589d6972011-11-30 16:04:58 +00003757 top_scope_->DeclareParameter(param_name,
3758 harmony_block_scoping_
3759 ? Variable::LET
3760 : Variable::VAR);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003761 num_parameters++;
Steve Block1e0659c2011-05-24 12:43:12 +01003762 if (num_parameters > kMaxNumFunctionParameters) {
3763 ReportMessageAt(scanner().location(), "too_many_parameters",
3764 Vector<const char*>::empty());
3765 *ok = false;
3766 return NULL;
3767 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003768 done = (peek() == Token::RPAREN);
3769 if (!done) Expect(Token::COMMA, CHECK_OK);
3770 }
3771 Expect(Token::RPAREN, CHECK_OK);
3772
3773 Expect(Token::LBRACE, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00003774
3775 // If we have a named function expression, we add a local variable
3776 // declaration to the body of the function with the name of the
3777 // function and let it refer to the function itself (closure).
3778 // NOTE: We create a proxy and resolve it here so that in the
3779 // future we can change the AST to only refer to VariableProxies
3780 // instead of Variables and Proxis as is the case now.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003781 if (type == FunctionLiteral::NAMED_EXPRESSION) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003782 Variable* fvar = top_scope_->DeclareFunctionVar(function_name);
3783 VariableProxy* fproxy =
3784 top_scope_->NewUnresolved(function_name, inside_with());
3785 fproxy->BindTo(fvar);
Ben Murdoch8b112d22011-06-08 16:22:53 +01003786 body->Add(new(zone()) ExpressionStatement(
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003787 new(zone()) Assignment(isolate(),
3788 Token::INIT_CONST,
3789 fproxy,
3790 new(zone()) ThisFunction(isolate()),
3791 RelocInfo::kNoPosition)));
Steve Blocka7e24c12009-10-30 11:49:00 +00003792 }
3793
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003794 // Determine if the function will be lazily compiled. The mode can only
3795 // be PARSE_LAZILY if the --lazy flag is true. We will not lazily
3796 // compile if we do not have preparser data for the function.
Ben Murdochb8e0da22011-05-16 14:20:40 +01003797 bool is_lazily_compiled = (mode() == PARSE_LAZILY &&
3798 top_scope_->outer_scope()->is_global_scope() &&
3799 top_scope_->HasTrivialOuterContext() &&
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003800 !parenthesized_function_ &&
3801 pre_data() != NULL);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003802 parenthesized_function_ = false; // The bit was set for this function only.
Steve Blocka7e24c12009-10-30 11:49:00 +00003803
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003804 if (is_lazily_compiled) {
3805 int function_block_pos = scanner().location().beg_pos;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003806 FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos);
Leon Clarkeac952652010-07-15 11:15:24 +01003807 if (!entry.is_valid()) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003808 // There is no preparser data for the function, we will not lazily
3809 // compile after all.
3810 is_lazily_compiled = false;
3811 } else {
3812 end_pos = entry.end_pos();
3813 if (end_pos <= function_block_pos) {
3814 // End position greater than end of stream is safe, and hard to check.
3815 ReportInvalidPreparseData(function_name, CHECK_OK);
3816 }
3817 isolate()->counters()->total_preparse_skipped()->Increment(
3818 end_pos - function_block_pos);
3819 // Seek to position just before terminal '}'.
3820 scanner().SeekForward(end_pos - 1);
3821 materialized_literal_count = entry.literal_count();
3822 expected_property_count = entry.property_count();
3823 if (entry.strict_mode()) top_scope_->EnableStrictMode();
3824 only_simple_this_property_assignments = false;
3825 this_property_assignments = isolate()->factory()->empty_fixed_array();
3826 Expect(Token::RBRACE, CHECK_OK);
Leon Clarkeac952652010-07-15 11:15:24 +01003827 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003828 }
3829
3830 if (!is_lazily_compiled) {
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003831 ParseSourceElements(body, Token::RBRACE, CHECK_OK);
3832
Steve Block44f0eee2011-05-26 01:26:41 +01003833 materialized_literal_count = lexical_scope.materialized_literal_count();
3834 expected_property_count = lexical_scope.expected_property_count();
Steve Blocka7e24c12009-10-30 11:49:00 +00003835 only_simple_this_property_assignments =
Steve Block44f0eee2011-05-26 01:26:41 +01003836 lexical_scope.only_simple_this_property_assignments();
3837 this_property_assignments = lexical_scope.this_property_assignments();
Steve Blocka7e24c12009-10-30 11:49:00 +00003838
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003839 Expect(Token::RBRACE, CHECK_OK);
Ben Murdochb0fe1622011-05-05 13:52:32 +01003840 end_pos = scanner().location().end_pos;
Steve Blocka7e24c12009-10-30 11:49:00 +00003841 }
3842
Steve Block1e0659c2011-05-24 12:43:12 +01003843 // Validate strict mode.
Steve Block44f0eee2011-05-26 01:26:41 +01003844 if (top_scope_->is_strict_mode()) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003845 if (IsEvalOrArguments(function_name)) {
Steve Block1e0659c2011-05-24 12:43:12 +01003846 int position = function_token_position != RelocInfo::kNoPosition
3847 ? function_token_position
3848 : (start_pos > 0 ? start_pos - 1 : start_pos);
3849 Scanner::Location location = Scanner::Location(position, start_pos);
3850 ReportMessageAt(location,
3851 "strict_function_name", Vector<const char*>::empty());
3852 *ok = false;
3853 return NULL;
3854 }
3855 if (name_loc.IsValid()) {
3856 ReportMessageAt(name_loc, "strict_param_name",
3857 Vector<const char*>::empty());
3858 *ok = false;
3859 return NULL;
3860 }
3861 if (dupe_loc.IsValid()) {
3862 ReportMessageAt(dupe_loc, "strict_param_dupe",
3863 Vector<const char*>::empty());
3864 *ok = false;
3865 return NULL;
3866 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003867 if (name_is_strict_reserved) {
Steve Block1e0659c2011-05-24 12:43:12 +01003868 int position = function_token_position != RelocInfo::kNoPosition
3869 ? function_token_position
3870 : (start_pos > 0 ? start_pos - 1 : start_pos);
3871 Scanner::Location location = Scanner::Location(position, start_pos);
3872 ReportMessageAt(location, "strict_reserved_word",
3873 Vector<const char*>::empty());
3874 *ok = false;
3875 return NULL;
3876 }
3877 if (reserved_loc.IsValid()) {
3878 ReportMessageAt(reserved_loc, "strict_reserved_word",
3879 Vector<const char*>::empty());
3880 *ok = false;
3881 return NULL;
3882 }
3883 CheckOctalLiteral(start_pos, end_pos, CHECK_OK);
3884 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003885 }
Ben Murdoch8b112d22011-06-08 16:22:53 +01003886
Ben Murdoch589d6972011-11-30 16:04:58 +00003887 if (harmony_block_scoping_) {
3888 CheckConflictingVarDeclarations(scope, CHECK_OK);
3889 }
3890
Ben Murdoch8b112d22011-06-08 16:22:53 +01003891 FunctionLiteral* function_literal =
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003892 new(zone()) FunctionLiteral(isolate(),
3893 function_name,
Ben Murdoch8b112d22011-06-08 16:22:53 +01003894 scope,
3895 body,
3896 materialized_literal_count,
3897 expected_property_count,
3898 only_simple_this_property_assignments,
3899 this_property_assignments,
3900 num_parameters,
3901 start_pos,
3902 end_pos,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003903 type,
3904 has_duplicate_parameters);
Ben Murdoch8b112d22011-06-08 16:22:53 +01003905 function_literal->set_function_token_position(function_token_position);
3906
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003907 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
Ben Murdoch8b112d22011-06-08 16:22:53 +01003908 return function_literal;
Steve Blocka7e24c12009-10-30 11:49:00 +00003909}
3910
3911
3912Expression* Parser::ParseV8Intrinsic(bool* ok) {
3913 // CallRuntime ::
3914 // '%' Identifier Arguments
3915
3916 Expect(Token::MOD, CHECK_OK);
3917 Handle<String> name = ParseIdentifier(CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00003918 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01003919
3920 if (extension_ != NULL) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003921 // The extension structures are only accessible while parsing the
3922 // very first time not when reparsing because of lazy compilation.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003923 top_scope_->DeclarationScope()->ForceEagerCompilation();
Steve Blocka7e24c12009-10-30 11:49:00 +00003924 }
3925
Steve Block44f0eee2011-05-26 01:26:41 +01003926 const Runtime::Function* function = Runtime::FunctionForSymbol(name);
Steve Blocka7e24c12009-10-30 11:49:00 +00003927
Kristian Monsen0d5e1162010-09-30 15:31:59 +01003928 // Check for built-in IS_VAR macro.
3929 if (function != NULL &&
3930 function->intrinsic_type == Runtime::RUNTIME &&
3931 function->function_id == Runtime::kIS_VAR) {
3932 // %IS_VAR(x) evaluates to x if x is a variable,
3933 // leads to a parse error otherwise. Could be implemented as an
3934 // inline function %_IS_VAR(x) to eliminate this special case.
3935 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
3936 return args->at(0);
3937 } else {
Steve Blocka7e24c12009-10-30 11:49:00 +00003938 ReportMessage("unable_to_parse", Vector<const char*>::empty());
Steve Block6ded16b2010-05-10 14:33:55 +01003939 *ok = false;
3940 return NULL;
Steve Block6ded16b2010-05-10 14:33:55 +01003941 }
3942 }
3943
Kristian Monsen0d5e1162010-09-30 15:31:59 +01003944 // Check that the expected number of arguments are being passed.
3945 if (function != NULL &&
3946 function->nargs != -1 &&
3947 function->nargs != args->length()) {
3948 ReportMessage("illegal_access", Vector<const char*>::empty());
3949 *ok = false;
3950 return NULL;
3951 }
3952
3953 // We have a valid intrinsics call or a call to a builtin.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003954 return new(zone()) CallRuntime(isolate(), name, function, args);
Steve Blocka7e24c12009-10-30 11:49:00 +00003955}
3956
3957
Steve Block1e0659c2011-05-24 12:43:12 +01003958bool Parser::peek_any_identifier() {
3959 Token::Value next = peek();
3960 return next == Token::IDENTIFIER ||
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003961 next == Token::FUTURE_RESERVED_WORD ||
3962 next == Token::FUTURE_STRICT_RESERVED_WORD;
Steve Block1e0659c2011-05-24 12:43:12 +01003963}
3964
3965
Steve Blocka7e24c12009-10-30 11:49:00 +00003966void Parser::Consume(Token::Value token) {
3967 Token::Value next = Next();
3968 USE(next);
3969 USE(token);
3970 ASSERT(next == token);
3971}
3972
3973
3974void Parser::Expect(Token::Value token, bool* ok) {
3975 Token::Value next = Next();
3976 if (next == token) return;
3977 ReportUnexpectedToken(next);
3978 *ok = false;
3979}
3980
3981
Leon Clarke4515c472010-02-03 11:58:03 +00003982bool Parser::Check(Token::Value token) {
3983 Token::Value next = peek();
3984 if (next == token) {
3985 Consume(next);
3986 return true;
3987 }
3988 return false;
3989}
3990
3991
Steve Blocka7e24c12009-10-30 11:49:00 +00003992void Parser::ExpectSemicolon(bool* ok) {
3993 // Check for automatic semicolon insertion according to
3994 // the rules given in ECMA-262, section 7.9, page 21.
3995 Token::Value tok = peek();
3996 if (tok == Token::SEMICOLON) {
3997 Next();
3998 return;
3999 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004000 if (scanner().HasAnyLineTerminatorBeforeNext() ||
Steve Blocka7e24c12009-10-30 11:49:00 +00004001 tok == Token::RBRACE ||
4002 tok == Token::EOS) {
4003 return;
4004 }
4005 Expect(Token::SEMICOLON, ok);
4006}
4007
4008
4009Literal* Parser::GetLiteralUndefined() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004010 return NewLiteral(isolate()->factory()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00004011}
4012
4013
4014Literal* Parser::GetLiteralTheHole() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004015 return NewLiteral(isolate()->factory()->the_hole_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00004016}
4017
4018
4019Literal* Parser::GetLiteralNumber(double value) {
4020 return NewNumberLiteral(value);
4021}
4022
4023
Ben Murdoch69a99ed2011-11-30 16:03:39 +00004024// Parses an identifier that is valid for the current scope, in particular it
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004025// fails on strict mode future reserved keywords in a strict scope.
Steve Blocka7e24c12009-10-30 11:49:00 +00004026Handle<String> Parser::ParseIdentifier(bool* ok) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004027 if (top_scope_->is_strict_mode()) {
4028 Expect(Token::IDENTIFIER, ok);
4029 } else if (!Check(Token::IDENTIFIER)) {
4030 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
4031 }
4032 if (!*ok) return Handle<String>();
4033 return GetSymbol(ok);
Steve Block1e0659c2011-05-24 12:43:12 +01004034}
4035
4036
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004037// Parses and identifier or a strict mode future reserved word, and indicate
4038// whether it is strict mode future reserved.
4039Handle<String> Parser::ParseIdentifierOrStrictReservedWord(
4040 bool* is_strict_reserved, bool* ok) {
4041 *is_strict_reserved = false;
4042 if (!Check(Token::IDENTIFIER)) {
4043 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
4044 *is_strict_reserved = true;
Steve Block1e0659c2011-05-24 12:43:12 +01004045 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004046 if (!*ok) return Handle<String>();
Iain Merrick9ac36c92010-09-13 15:29:50 +01004047 return GetSymbol(ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00004048}
4049
Ben Murdochbb769b22010-08-11 14:56:33 +01004050
4051Handle<String> Parser::ParseIdentifierName(bool* ok) {
4052 Token::Value next = Next();
Steve Block1e0659c2011-05-24 12:43:12 +01004053 if (next != Token::IDENTIFIER &&
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004054 next != Token::FUTURE_RESERVED_WORD &&
4055 next != Token::FUTURE_STRICT_RESERVED_WORD &&
4056 !Token::IsKeyword(next)) {
Ben Murdochbb769b22010-08-11 14:56:33 +01004057 ReportUnexpectedToken(next);
4058 *ok = false;
4059 return Handle<String>();
4060 }
Iain Merrick9ac36c92010-09-13 15:29:50 +01004061 return GetSymbol(ok);
Ben Murdochbb769b22010-08-11 14:56:33 +01004062}
4063
4064
Steve Block1e0659c2011-05-24 12:43:12 +01004065// Checks LHS expression for assignment and prefix/postfix increment/decrement
4066// in strict mode.
4067void Parser::CheckStrictModeLValue(Expression* expression,
4068 const char* error,
4069 bool* ok) {
Steve Block44f0eee2011-05-26 01:26:41 +01004070 ASSERT(top_scope_->is_strict_mode());
Steve Block1e0659c2011-05-24 12:43:12 +01004071 VariableProxy* lhs = expression != NULL
4072 ? expression->AsVariableProxy()
4073 : NULL;
4074
4075 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) {
4076 ReportMessage(error, Vector<const char*>::empty());
4077 *ok = false;
4078 }
4079}
4080
4081
Ben Murdoch257744e2011-11-30 15:57:28 +00004082// Checks whether an octal literal was last seen between beg_pos and end_pos.
4083// If so, reports an error. Only called for strict mode.
Steve Block1e0659c2011-05-24 12:43:12 +01004084void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
Ben Murdoch257744e2011-11-30 15:57:28 +00004085 Scanner::Location octal = scanner().octal_position();
4086 if (octal.IsValid() &&
4087 beg_pos <= octal.beg_pos &&
4088 octal.end_pos <= end_pos) {
4089 ReportMessageAt(octal, "strict_octal_literal",
Steve Block1e0659c2011-05-24 12:43:12 +01004090 Vector<const char*>::empty());
4091 scanner().clear_octal_position();
4092 *ok = false;
4093 }
4094}
4095
4096
Ben Murdoch589d6972011-11-30 16:04:58 +00004097void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
4098 Declaration* decl = scope->CheckConflictingVarDeclarations();
4099 if (decl != NULL) {
4100 // In harmony mode we treat conflicting variable bindinds as early
4101 // errors. See ES5 16 for a definition of early errors.
4102 Handle<String> name = decl->proxy()->name();
4103 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
4104 const char* elms[2] = { "Variable", *c_string };
4105 Vector<const char*> args(elms, 2);
4106 int position = decl->proxy()->position();
4107 Scanner::Location location = position == RelocInfo::kNoPosition
4108 ? Scanner::Location::invalid()
4109 : Scanner::Location(position, position + 1);
4110 ReportMessageAt(location, "redeclaration", args);
4111 *ok = false;
4112 }
4113}
4114
4115
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004116// This function reads an identifier name and determines whether or not it
Steve Block1e0659c2011-05-24 12:43:12 +01004117// is 'get' or 'set'.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004118Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get,
4119 bool* is_set,
4120 bool* ok) {
4121 Handle<String> result = ParseIdentifierName(ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00004122 if (!*ok) return Handle<String>();
Steve Block9fac8402011-05-12 15:51:54 +01004123 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) {
4124 const char* token = scanner().literal_ascii_string().start();
4125 *is_get = strncmp(token, "get", 3) == 0;
4126 *is_set = !*is_get && strncmp(token, "set", 3) == 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00004127 }
Steve Block1e0659c2011-05-24 12:43:12 +01004128 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00004129}
4130
4131
4132// ----------------------------------------------------------------------------
4133// Parser support
4134
4135
4136bool Parser::TargetStackContainsLabel(Handle<String> label) {
4137 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4138 BreakableStatement* stat = t->node()->AsBreakableStatement();
4139 if (stat != NULL && ContainsLabel(stat->labels(), label))
4140 return true;
4141 }
4142 return false;
4143}
4144
4145
4146BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) {
4147 bool anonymous = label.is_null();
4148 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4149 BreakableStatement* stat = t->node()->AsBreakableStatement();
4150 if (stat == NULL) continue;
4151 if ((anonymous && stat->is_target_for_anonymous()) ||
4152 (!anonymous && ContainsLabel(stat->labels(), label))) {
4153 RegisterTargetUse(stat->break_target(), t->previous());
4154 return stat;
4155 }
4156 }
4157 return NULL;
4158}
4159
4160
4161IterationStatement* Parser::LookupContinueTarget(Handle<String> label,
4162 bool* ok) {
4163 bool anonymous = label.is_null();
4164 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4165 IterationStatement* stat = t->node()->AsIterationStatement();
4166 if (stat == NULL) continue;
4167
4168 ASSERT(stat->is_target_for_anonymous());
4169 if (anonymous || ContainsLabel(stat->labels(), label)) {
4170 RegisterTargetUse(stat->continue_target(), t->previous());
4171 return stat;
4172 }
4173 }
4174 return NULL;
4175}
4176
4177
Ben Murdoch8b112d22011-06-08 16:22:53 +01004178void Parser::RegisterTargetUse(Label* target, Target* stop) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004179 // Register that a break target found at the given stop in the
4180 // target stack has been used from the top of the target stack. Add
4181 // the break target to any TargetCollectors passed on the stack.
4182 for (Target* t = target_stack_; t != stop; t = t->previous()) {
4183 TargetCollector* collector = t->node()->AsTargetCollector();
4184 if (collector != NULL) collector->AddTarget(target);
4185 }
4186}
4187
4188
4189Literal* Parser::NewNumberLiteral(double number) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004190 return NewLiteral(isolate()->factory()->NewNumber(number, TENURED));
Steve Blocka7e24c12009-10-30 11:49:00 +00004191}
4192
4193
4194Expression* Parser::NewThrowReferenceError(Handle<String> type) {
Steve Block44f0eee2011-05-26 01:26:41 +01004195 return NewThrowError(isolate()->factory()->MakeReferenceError_symbol(),
Steve Blocka7e24c12009-10-30 11:49:00 +00004196 type, HandleVector<Object>(NULL, 0));
4197}
4198
4199
4200Expression* Parser::NewThrowSyntaxError(Handle<String> type,
4201 Handle<Object> first) {
4202 int argc = first.is_null() ? 0 : 1;
4203 Vector< Handle<Object> > arguments = HandleVector<Object>(&first, argc);
Steve Block44f0eee2011-05-26 01:26:41 +01004204 return NewThrowError(
4205 isolate()->factory()->MakeSyntaxError_symbol(), type, arguments);
Steve Blocka7e24c12009-10-30 11:49:00 +00004206}
4207
4208
4209Expression* Parser::NewThrowTypeError(Handle<String> type,
4210 Handle<Object> first,
4211 Handle<Object> second) {
4212 ASSERT(!first.is_null() && !second.is_null());
4213 Handle<Object> elements[] = { first, second };
4214 Vector< Handle<Object> > arguments =
4215 HandleVector<Object>(elements, ARRAY_SIZE(elements));
Steve Block44f0eee2011-05-26 01:26:41 +01004216 return NewThrowError(
4217 isolate()->factory()->MakeTypeError_symbol(), type, arguments);
Steve Blocka7e24c12009-10-30 11:49:00 +00004218}
4219
4220
4221Expression* Parser::NewThrowError(Handle<String> constructor,
4222 Handle<String> type,
4223 Vector< Handle<Object> > arguments) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004224 int argc = arguments.length();
Steve Block44f0eee2011-05-26 01:26:41 +01004225 Handle<FixedArray> elements = isolate()->factory()->NewFixedArray(argc,
4226 TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00004227 for (int i = 0; i < argc; i++) {
4228 Handle<Object> element = arguments[i];
4229 if (!element.is_null()) {
Steve Block1e0659c2011-05-24 12:43:12 +01004230 elements->set(i, *element);
Steve Blocka7e24c12009-10-30 11:49:00 +00004231 }
4232 }
Steve Block44f0eee2011-05-26 01:26:41 +01004233 Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements(elements,
4234 TENURED);
Steve Block1e0659c2011-05-24 12:43:12 +01004235
Ben Murdoch257744e2011-11-30 15:57:28 +00004236 ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004237 args->Add(NewLiteral(type));
4238 args->Add(NewLiteral(array));
4239 CallRuntime* call_constructor = new(zone()) CallRuntime(isolate(),
4240 constructor,
4241 NULL,
4242 args);
4243 return new(zone()) Throw(isolate(),
4244 call_constructor,
4245 scanner().location().beg_pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00004246}
4247
Leon Clarke4515c472010-02-03 11:58:03 +00004248// ----------------------------------------------------------------------------
Steve Blocka7e24c12009-10-30 11:49:00 +00004249// Regular expressions
4250
4251
4252RegExpParser::RegExpParser(FlatStringReader* in,
4253 Handle<String>* error,
4254 bool multiline)
Steve Block44f0eee2011-05-26 01:26:41 +01004255 : isolate_(Isolate::Current()),
4256 error_(error),
4257 captures_(NULL),
4258 in_(in),
4259 current_(kEndMarker),
4260 next_pos_(0),
4261 capture_count_(0),
4262 has_more_(true),
4263 multiline_(multiline),
4264 simple_(false),
4265 contains_anchor_(false),
4266 is_scanned_for_captures_(false),
4267 failed_(false) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01004268 Advance();
Steve Blocka7e24c12009-10-30 11:49:00 +00004269}
4270
4271
4272uc32 RegExpParser::Next() {
4273 if (has_next()) {
4274 return in()->Get(next_pos_);
4275 } else {
4276 return kEndMarker;
4277 }
4278}
4279
4280
4281void RegExpParser::Advance() {
4282 if (next_pos_ < in()->length()) {
Steve Block44f0eee2011-05-26 01:26:41 +01004283 StackLimitCheck check(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00004284 if (check.HasOverflowed()) {
Steve Block44f0eee2011-05-26 01:26:41 +01004285 ReportError(CStrVector(Isolate::kStackOverflowMessage));
4286 } else if (isolate()->zone()->excess_allocation()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004287 ReportError(CStrVector("Regular expression too large"));
4288 } else {
4289 current_ = in()->Get(next_pos_);
4290 next_pos_++;
4291 }
4292 } else {
4293 current_ = kEndMarker;
4294 has_more_ = false;
4295 }
4296}
4297
4298
4299void RegExpParser::Reset(int pos) {
4300 next_pos_ = pos;
4301 Advance();
4302}
4303
4304
4305void RegExpParser::Advance(int dist) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01004306 next_pos_ += dist - 1;
4307 Advance();
Steve Blocka7e24c12009-10-30 11:49:00 +00004308}
4309
4310
4311bool RegExpParser::simple() {
4312 return simple_;
4313}
4314
4315RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
4316 failed_ = true;
Steve Block44f0eee2011-05-26 01:26:41 +01004317 *error_ = isolate()->factory()->NewStringFromAscii(message, NOT_TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00004318 // Zip to the end to make sure the no more input is read.
4319 current_ = kEndMarker;
4320 next_pos_ = in()->length();
4321 return NULL;
4322}
4323
4324
4325// Pattern ::
4326// Disjunction
4327RegExpTree* RegExpParser::ParsePattern() {
4328 RegExpTree* result = ParseDisjunction(CHECK_FAILED);
4329 ASSERT(!has_more());
4330 // If the result of parsing is a literal string atom, and it has the
4331 // same length as the input, then the atom is identical to the input.
4332 if (result->IsAtom() && result->AsAtom()->length() == in()->length()) {
4333 simple_ = true;
4334 }
4335 return result;
4336}
4337
4338
4339// Disjunction ::
4340// Alternative
4341// Alternative | Disjunction
4342// Alternative ::
4343// [empty]
4344// Term Alternative
4345// Term ::
4346// Assertion
4347// Atom
4348// Atom Quantifier
4349RegExpTree* RegExpParser::ParseDisjunction() {
4350 // Used to store current state while parsing subexpressions.
4351 RegExpParserState initial_state(NULL, INITIAL, 0);
4352 RegExpParserState* stored_state = &initial_state;
4353 // Cache the builder in a local variable for quick access.
4354 RegExpBuilder* builder = initial_state.builder();
4355 while (true) {
4356 switch (current()) {
4357 case kEndMarker:
4358 if (stored_state->IsSubexpression()) {
4359 // Inside a parenthesized group when hitting end of input.
4360 ReportError(CStrVector("Unterminated group") CHECK_FAILED);
4361 }
4362 ASSERT_EQ(INITIAL, stored_state->group_type());
4363 // Parsing completed successfully.
4364 return builder->ToRegExp();
4365 case ')': {
4366 if (!stored_state->IsSubexpression()) {
4367 ReportError(CStrVector("Unmatched ')'") CHECK_FAILED);
4368 }
4369 ASSERT_NE(INITIAL, stored_state->group_type());
4370
4371 Advance();
4372 // End disjunction parsing and convert builder content to new single
4373 // regexp atom.
4374 RegExpTree* body = builder->ToRegExp();
4375
4376 int end_capture_index = captures_started();
4377
4378 int capture_index = stored_state->capture_index();
4379 SubexpressionType type = stored_state->group_type();
4380
4381 // Restore previous state.
4382 stored_state = stored_state->previous_state();
4383 builder = stored_state->builder();
4384
4385 // Build result of subexpression.
4386 if (type == CAPTURE) {
Ben Murdoch8b112d22011-06-08 16:22:53 +01004387 RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index);
Steve Blocka7e24c12009-10-30 11:49:00 +00004388 captures_->at(capture_index - 1) = capture;
4389 body = capture;
4390 } else if (type != GROUPING) {
4391 ASSERT(type == POSITIVE_LOOKAHEAD || type == NEGATIVE_LOOKAHEAD);
4392 bool is_positive = (type == POSITIVE_LOOKAHEAD);
Ben Murdoch8b112d22011-06-08 16:22:53 +01004393 body = new(zone()) RegExpLookahead(body,
Steve Blocka7e24c12009-10-30 11:49:00 +00004394 is_positive,
4395 end_capture_index - capture_index,
4396 capture_index);
4397 }
4398 builder->AddAtom(body);
Ben Murdoche0cee9b2011-05-25 10:26:03 +01004399 // For compatability with JSC and ES3, we allow quantifiers after
4400 // lookaheads, and break in all cases.
Steve Blocka7e24c12009-10-30 11:49:00 +00004401 break;
4402 }
4403 case '|': {
4404 Advance();
4405 builder->NewAlternative();
4406 continue;
4407 }
4408 case '*':
4409 case '+':
4410 case '?':
4411 return ReportError(CStrVector("Nothing to repeat"));
4412 case '^': {
4413 Advance();
4414 if (multiline_) {
4415 builder->AddAssertion(
Ben Murdoch8b112d22011-06-08 16:22:53 +01004416 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE));
Steve Blocka7e24c12009-10-30 11:49:00 +00004417 } else {
4418 builder->AddAssertion(
Ben Murdoch8b112d22011-06-08 16:22:53 +01004419 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
Steve Blocka7e24c12009-10-30 11:49:00 +00004420 set_contains_anchor();
4421 }
4422 continue;
4423 }
4424 case '$': {
4425 Advance();
4426 RegExpAssertion::Type type =
4427 multiline_ ? RegExpAssertion::END_OF_LINE :
4428 RegExpAssertion::END_OF_INPUT;
Ben Murdoch8b112d22011-06-08 16:22:53 +01004429 builder->AddAssertion(new(zone()) RegExpAssertion(type));
Steve Blocka7e24c12009-10-30 11:49:00 +00004430 continue;
4431 }
4432 case '.': {
4433 Advance();
4434 // everything except \x0a, \x0d, \u2028 and \u2029
Ben Murdoch257744e2011-11-30 15:57:28 +00004435 ZoneList<CharacterRange>* ranges =
4436 new(zone()) ZoneList<CharacterRange>(2);
Steve Blocka7e24c12009-10-30 11:49:00 +00004437 CharacterRange::AddClassEscape('.', ranges);
Ben Murdoch8b112d22011-06-08 16:22:53 +01004438 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00004439 builder->AddAtom(atom);
4440 break;
4441 }
4442 case '(': {
4443 SubexpressionType type = CAPTURE;
4444 Advance();
4445 if (current() == '?') {
4446 switch (Next()) {
4447 case ':':
4448 type = GROUPING;
4449 break;
4450 case '=':
4451 type = POSITIVE_LOOKAHEAD;
4452 break;
4453 case '!':
4454 type = NEGATIVE_LOOKAHEAD;
4455 break;
4456 default:
4457 ReportError(CStrVector("Invalid group") CHECK_FAILED);
4458 break;
4459 }
4460 Advance(2);
4461 } else {
4462 if (captures_ == NULL) {
Ben Murdoch257744e2011-11-30 15:57:28 +00004463 captures_ = new(zone()) ZoneList<RegExpCapture*>(2);
Steve Blocka7e24c12009-10-30 11:49:00 +00004464 }
4465 if (captures_started() >= kMaxCaptures) {
4466 ReportError(CStrVector("Too many captures") CHECK_FAILED);
4467 }
4468 captures_->Add(NULL);
4469 }
4470 // Store current state and begin new disjunction parsing.
Ben Murdoch8b112d22011-06-08 16:22:53 +01004471 stored_state = new(zone()) RegExpParserState(stored_state,
Steve Blocka7e24c12009-10-30 11:49:00 +00004472 type,
4473 captures_started());
4474 builder = stored_state->builder();
Ben Murdoche0cee9b2011-05-25 10:26:03 +01004475 continue;
Steve Blocka7e24c12009-10-30 11:49:00 +00004476 }
4477 case '[': {
4478 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED);
4479 builder->AddAtom(atom);
4480 break;
4481 }
4482 // Atom ::
4483 // \ AtomEscape
4484 case '\\':
4485 switch (Next()) {
4486 case kEndMarker:
4487 return ReportError(CStrVector("\\ at end of pattern"));
4488 case 'b':
4489 Advance(2);
4490 builder->AddAssertion(
Ben Murdoch8b112d22011-06-08 16:22:53 +01004491 new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
Steve Blocka7e24c12009-10-30 11:49:00 +00004492 continue;
4493 case 'B':
4494 Advance(2);
4495 builder->AddAssertion(
Ben Murdoch8b112d22011-06-08 16:22:53 +01004496 new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
Steve Blocka7e24c12009-10-30 11:49:00 +00004497 continue;
Ben Murdoche0cee9b2011-05-25 10:26:03 +01004498 // AtomEscape ::
4499 // CharacterClassEscape
4500 //
4501 // CharacterClassEscape :: one of
4502 // d D s S w W
Steve Blocka7e24c12009-10-30 11:49:00 +00004503 case 'd': case 'D': case 's': case 'S': case 'w': case 'W': {
4504 uc32 c = Next();
4505 Advance(2);
Ben Murdoch257744e2011-11-30 15:57:28 +00004506 ZoneList<CharacterRange>* ranges =
4507 new(zone()) ZoneList<CharacterRange>(2);
Steve Blocka7e24c12009-10-30 11:49:00 +00004508 CharacterRange::AddClassEscape(c, ranges);
Ben Murdoch8b112d22011-06-08 16:22:53 +01004509 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00004510 builder->AddAtom(atom);
4511 break;
4512 }
4513 case '1': case '2': case '3': case '4': case '5': case '6':
4514 case '7': case '8': case '9': {
4515 int index = 0;
4516 if (ParseBackReferenceIndex(&index)) {
4517 RegExpCapture* capture = NULL;
4518 if (captures_ != NULL && index <= captures_->length()) {
4519 capture = captures_->at(index - 1);
4520 }
4521 if (capture == NULL) {
4522 builder->AddEmpty();
4523 break;
4524 }
Ben Murdoch8b112d22011-06-08 16:22:53 +01004525 RegExpTree* atom = new(zone()) RegExpBackReference(capture);
Steve Blocka7e24c12009-10-30 11:49:00 +00004526 builder->AddAtom(atom);
4527 break;
4528 }
4529 uc32 first_digit = Next();
4530 if (first_digit == '8' || first_digit == '9') {
4531 // Treat as identity escape
4532 builder->AddCharacter(first_digit);
4533 Advance(2);
4534 break;
4535 }
4536 }
4537 // FALLTHROUGH
4538 case '0': {
4539 Advance();
4540 uc32 octal = ParseOctalLiteral();
4541 builder->AddCharacter(octal);
4542 break;
4543 }
4544 // ControlEscape :: one of
4545 // f n r t v
4546 case 'f':
4547 Advance(2);
4548 builder->AddCharacter('\f');
4549 break;
4550 case 'n':
4551 Advance(2);
4552 builder->AddCharacter('\n');
4553 break;
4554 case 'r':
4555 Advance(2);
4556 builder->AddCharacter('\r');
4557 break;
4558 case 't':
4559 Advance(2);
4560 builder->AddCharacter('\t');
4561 break;
4562 case 'v':
4563 Advance(2);
4564 builder->AddCharacter('\v');
4565 break;
4566 case 'c': {
Ben Murdoch086aeea2011-05-13 15:57:08 +01004567 Advance();
4568 uc32 controlLetter = Next();
4569 // Special case if it is an ASCII letter.
4570 // Convert lower case letters to uppercase.
4571 uc32 letter = controlLetter & ~('a' ^ 'A');
4572 if (letter < 'A' || 'Z' < letter) {
4573 // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
4574 // This is outside the specification. We match JSC in
4575 // reading the backslash as a literal character instead
4576 // of as starting an escape.
4577 builder->AddCharacter('\\');
4578 } else {
4579 Advance(2);
4580 builder->AddCharacter(controlLetter & 0x1f);
4581 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004582 break;
4583 }
4584 case 'x': {
4585 Advance(2);
4586 uc32 value;
4587 if (ParseHexEscape(2, &value)) {
4588 builder->AddCharacter(value);
4589 } else {
4590 builder->AddCharacter('x');
4591 }
4592 break;
4593 }
4594 case 'u': {
4595 Advance(2);
4596 uc32 value;
4597 if (ParseHexEscape(4, &value)) {
4598 builder->AddCharacter(value);
4599 } else {
4600 builder->AddCharacter('u');
4601 }
4602 break;
4603 }
4604 default:
4605 // Identity escape.
4606 builder->AddCharacter(Next());
4607 Advance(2);
4608 break;
4609 }
4610 break;
4611 case '{': {
4612 int dummy;
4613 if (ParseIntervalQuantifier(&dummy, &dummy)) {
4614 ReportError(CStrVector("Nothing to repeat") CHECK_FAILED);
4615 }
4616 // fallthrough
4617 }
4618 default:
4619 builder->AddCharacter(current());
4620 Advance();
4621 break;
4622 } // end switch(current())
4623
4624 int min;
4625 int max;
4626 switch (current()) {
4627 // QuantifierPrefix ::
4628 // *
4629 // +
4630 // ?
4631 // {
4632 case '*':
4633 min = 0;
4634 max = RegExpTree::kInfinity;
4635 Advance();
4636 break;
4637 case '+':
4638 min = 1;
4639 max = RegExpTree::kInfinity;
4640 Advance();
4641 break;
4642 case '?':
4643 min = 0;
4644 max = 1;
4645 Advance();
4646 break;
4647 case '{':
4648 if (ParseIntervalQuantifier(&min, &max)) {
4649 if (max < min) {
4650 ReportError(CStrVector("numbers out of order in {} quantifier.")
4651 CHECK_FAILED);
4652 }
4653 break;
4654 } else {
4655 continue;
4656 }
4657 default:
4658 continue;
4659 }
Leon Clarkee46be812010-01-19 14:06:41 +00004660 RegExpQuantifier::Type type = RegExpQuantifier::GREEDY;
Steve Blocka7e24c12009-10-30 11:49:00 +00004661 if (current() == '?') {
Leon Clarkee46be812010-01-19 14:06:41 +00004662 type = RegExpQuantifier::NON_GREEDY;
4663 Advance();
4664 } else if (FLAG_regexp_possessive_quantifier && current() == '+') {
4665 // FLAG_regexp_possessive_quantifier is a debug-only flag.
4666 type = RegExpQuantifier::POSSESSIVE;
Steve Blocka7e24c12009-10-30 11:49:00 +00004667 Advance();
4668 }
Leon Clarkee46be812010-01-19 14:06:41 +00004669 builder->AddQuantifierToAtom(min, max, type);
Steve Blocka7e24c12009-10-30 11:49:00 +00004670 }
4671}
4672
Steve Blocka7e24c12009-10-30 11:49:00 +00004673
4674#ifdef DEBUG
4675// Currently only used in an ASSERT.
4676static bool IsSpecialClassEscape(uc32 c) {
4677 switch (c) {
4678 case 'd': case 'D':
4679 case 's': case 'S':
4680 case 'w': case 'W':
4681 return true;
4682 default:
4683 return false;
4684 }
4685}
4686#endif
4687
4688
4689// In order to know whether an escape is a backreference or not we have to scan
4690// the entire regexp and find the number of capturing parentheses. However we
4691// don't want to scan the regexp twice unless it is necessary. This mini-parser
4692// is called when needed. It can see the difference between capturing and
4693// noncapturing parentheses and can skip character classes and backslash-escaped
4694// characters.
4695void RegExpParser::ScanForCaptures() {
4696 // Start with captures started previous to current position
4697 int capture_count = captures_started();
4698 // Add count of captures after this position.
4699 int n;
4700 while ((n = current()) != kEndMarker) {
4701 Advance();
4702 switch (n) {
4703 case '\\':
4704 Advance();
4705 break;
4706 case '[': {
4707 int c;
4708 while ((c = current()) != kEndMarker) {
4709 Advance();
4710 if (c == '\\') {
4711 Advance();
4712 } else {
4713 if (c == ']') break;
4714 }
4715 }
4716 break;
4717 }
4718 case '(':
4719 if (current() != '?') capture_count++;
4720 break;
4721 }
4722 }
4723 capture_count_ = capture_count;
4724 is_scanned_for_captures_ = true;
4725}
4726
4727
4728bool RegExpParser::ParseBackReferenceIndex(int* index_out) {
4729 ASSERT_EQ('\\', current());
4730 ASSERT('1' <= Next() && Next() <= '9');
4731 // Try to parse a decimal literal that is no greater than the total number
4732 // of left capturing parentheses in the input.
4733 int start = position();
4734 int value = Next() - '0';
4735 Advance(2);
4736 while (true) {
4737 uc32 c = current();
4738 if (IsDecimalDigit(c)) {
4739 value = 10 * value + (c - '0');
4740 if (value > kMaxCaptures) {
4741 Reset(start);
4742 return false;
4743 }
4744 Advance();
4745 } else {
4746 break;
4747 }
4748 }
4749 if (value > captures_started()) {
4750 if (!is_scanned_for_captures_) {
4751 int saved_position = position();
4752 ScanForCaptures();
4753 Reset(saved_position);
4754 }
4755 if (value > capture_count_) {
4756 Reset(start);
4757 return false;
4758 }
4759 }
4760 *index_out = value;
4761 return true;
4762}
4763
4764
4765// QuantifierPrefix ::
4766// { DecimalDigits }
4767// { DecimalDigits , }
4768// { DecimalDigits , DecimalDigits }
4769//
4770// Returns true if parsing succeeds, and set the min_out and max_out
4771// values. Values are truncated to RegExpTree::kInfinity if they overflow.
4772bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
4773 ASSERT_EQ(current(), '{');
4774 int start = position();
4775 Advance();
4776 int min = 0;
4777 if (!IsDecimalDigit(current())) {
4778 Reset(start);
4779 return false;
4780 }
4781 while (IsDecimalDigit(current())) {
4782 int next = current() - '0';
4783 if (min > (RegExpTree::kInfinity - next) / 10) {
4784 // Overflow. Skip past remaining decimal digits and return -1.
4785 do {
4786 Advance();
4787 } while (IsDecimalDigit(current()));
4788 min = RegExpTree::kInfinity;
4789 break;
4790 }
4791 min = 10 * min + next;
4792 Advance();
4793 }
4794 int max = 0;
4795 if (current() == '}') {
4796 max = min;
4797 Advance();
4798 } else if (current() == ',') {
4799 Advance();
4800 if (current() == '}') {
4801 max = RegExpTree::kInfinity;
4802 Advance();
4803 } else {
4804 while (IsDecimalDigit(current())) {
4805 int next = current() - '0';
4806 if (max > (RegExpTree::kInfinity - next) / 10) {
4807 do {
4808 Advance();
4809 } while (IsDecimalDigit(current()));
4810 max = RegExpTree::kInfinity;
4811 break;
4812 }
4813 max = 10 * max + next;
4814 Advance();
4815 }
4816 if (current() != '}') {
4817 Reset(start);
4818 return false;
4819 }
4820 Advance();
4821 }
4822 } else {
4823 Reset(start);
4824 return false;
4825 }
4826 *min_out = min;
4827 *max_out = max;
4828 return true;
4829}
4830
4831
Steve Blocka7e24c12009-10-30 11:49:00 +00004832uc32 RegExpParser::ParseOctalLiteral() {
4833 ASSERT('0' <= current() && current() <= '7');
4834 // For compatibility with some other browsers (not all), we parse
4835 // up to three octal digits with a value below 256.
4836 uc32 value = current() - '0';
4837 Advance();
4838 if ('0' <= current() && current() <= '7') {
4839 value = value * 8 + current() - '0';
4840 Advance();
4841 if (value < 32 && '0' <= current() && current() <= '7') {
4842 value = value * 8 + current() - '0';
4843 Advance();
4844 }
4845 }
4846 return value;
4847}
4848
4849
4850bool RegExpParser::ParseHexEscape(int length, uc32 *value) {
4851 int start = position();
4852 uc32 val = 0;
4853 bool done = false;
4854 for (int i = 0; !done; i++) {
4855 uc32 c = current();
4856 int d = HexValue(c);
4857 if (d < 0) {
4858 Reset(start);
4859 return false;
4860 }
4861 val = val * 16 + d;
4862 Advance();
4863 if (i == length - 1) {
4864 done = true;
4865 }
4866 }
4867 *value = val;
4868 return true;
4869}
4870
4871
4872uc32 RegExpParser::ParseClassCharacterEscape() {
4873 ASSERT(current() == '\\');
4874 ASSERT(has_next() && !IsSpecialClassEscape(Next()));
4875 Advance();
4876 switch (current()) {
4877 case 'b':
4878 Advance();
4879 return '\b';
4880 // ControlEscape :: one of
4881 // f n r t v
4882 case 'f':
4883 Advance();
4884 return '\f';
4885 case 'n':
4886 Advance();
4887 return '\n';
4888 case 'r':
4889 Advance();
4890 return '\r';
4891 case 't':
4892 Advance();
4893 return '\t';
4894 case 'v':
4895 Advance();
4896 return '\v';
Ben Murdoch086aeea2011-05-13 15:57:08 +01004897 case 'c': {
4898 uc32 controlLetter = Next();
4899 uc32 letter = controlLetter & ~('A' ^ 'a');
4900 // For compatibility with JSC, inside a character class
4901 // we also accept digits and underscore as control characters.
4902 if ((controlLetter >= '0' && controlLetter <= '9') ||
4903 controlLetter == '_' ||
4904 (letter >= 'A' && letter <= 'Z')) {
4905 Advance(2);
4906 // Control letters mapped to ASCII control characters in the range
4907 // 0x00-0x1f.
4908 return controlLetter & 0x1f;
4909 }
4910 // We match JSC in reading the backslash as a literal
4911 // character instead of as starting an escape.
4912 return '\\';
4913 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004914 case '0': case '1': case '2': case '3': case '4': case '5':
4915 case '6': case '7':
4916 // For compatibility, we interpret a decimal escape that isn't
4917 // a back reference (and therefore either \0 or not valid according
4918 // to the specification) as a 1..3 digit octal character code.
4919 return ParseOctalLiteral();
4920 case 'x': {
4921 Advance();
4922 uc32 value;
4923 if (ParseHexEscape(2, &value)) {
4924 return value;
4925 }
4926 // If \x is not followed by a two-digit hexadecimal, treat it
4927 // as an identity escape.
4928 return 'x';
4929 }
4930 case 'u': {
4931 Advance();
4932 uc32 value;
4933 if (ParseHexEscape(4, &value)) {
4934 return value;
4935 }
4936 // If \u is not followed by a four-digit hexadecimal, treat it
4937 // as an identity escape.
4938 return 'u';
4939 }
4940 default: {
4941 // Extended identity escape. We accept any character that hasn't
4942 // been matched by a more specific case, not just the subset required
4943 // by the ECMAScript specification.
4944 uc32 result = current();
4945 Advance();
4946 return result;
4947 }
4948 }
4949 return 0;
4950}
4951
4952
4953CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) {
4954 ASSERT_EQ(0, *char_class);
4955 uc32 first = current();
4956 if (first == '\\') {
4957 switch (Next()) {
4958 case 'w': case 'W': case 'd': case 'D': case 's': case 'S': {
4959 *char_class = Next();
4960 Advance(2);
4961 return CharacterRange::Singleton(0); // Return dummy value.
4962 }
4963 case kEndMarker:
4964 return ReportError(CStrVector("\\ at end of pattern"));
4965 default:
4966 uc32 c = ParseClassCharacterEscape(CHECK_FAILED);
4967 return CharacterRange::Singleton(c);
4968 }
4969 } else {
4970 Advance();
4971 return CharacterRange::Singleton(first);
4972 }
4973}
4974
4975
Ben Murdochb0fe1622011-05-05 13:52:32 +01004976static const uc16 kNoCharClass = 0;
4977
4978// Adds range or pre-defined character class to character ranges.
4979// If char_class is not kInvalidClass, it's interpreted as a class
4980// escape (i.e., 's' means whitespace, from '\s').
4981static inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges,
4982 uc16 char_class,
4983 CharacterRange range) {
4984 if (char_class != kNoCharClass) {
4985 CharacterRange::AddClassEscape(char_class, ranges);
4986 } else {
4987 ranges->Add(range);
4988 }
4989}
4990
4991
Steve Blocka7e24c12009-10-30 11:49:00 +00004992RegExpTree* RegExpParser::ParseCharacterClass() {
4993 static const char* kUnterminated = "Unterminated character class";
4994 static const char* kRangeOutOfOrder = "Range out of order in character class";
4995
4996 ASSERT_EQ(current(), '[');
4997 Advance();
4998 bool is_negated = false;
4999 if (current() == '^') {
5000 is_negated = true;
5001 Advance();
5002 }
Ben Murdoch257744e2011-11-30 15:57:28 +00005003 ZoneList<CharacterRange>* ranges = new(zone()) ZoneList<CharacterRange>(2);
Steve Blocka7e24c12009-10-30 11:49:00 +00005004 while (has_more() && current() != ']') {
Ben Murdochb0fe1622011-05-05 13:52:32 +01005005 uc16 char_class = kNoCharClass;
Steve Blocka7e24c12009-10-30 11:49:00 +00005006 CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED);
Steve Blocka7e24c12009-10-30 11:49:00 +00005007 if (current() == '-') {
5008 Advance();
5009 if (current() == kEndMarker) {
5010 // If we reach the end we break out of the loop and let the
5011 // following code report an error.
5012 break;
5013 } else if (current() == ']') {
Ben Murdochb0fe1622011-05-05 13:52:32 +01005014 AddRangeOrEscape(ranges, char_class, first);
Steve Blocka7e24c12009-10-30 11:49:00 +00005015 ranges->Add(CharacterRange::Singleton('-'));
5016 break;
5017 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01005018 uc16 char_class_2 = kNoCharClass;
5019 CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED);
5020 if (char_class != kNoCharClass || char_class_2 != kNoCharClass) {
5021 // Either end is an escaped character class. Treat the '-' verbatim.
5022 AddRangeOrEscape(ranges, char_class, first);
Steve Blocka7e24c12009-10-30 11:49:00 +00005023 ranges->Add(CharacterRange::Singleton('-'));
Ben Murdochb0fe1622011-05-05 13:52:32 +01005024 AddRangeOrEscape(ranges, char_class_2, next);
Steve Blocka7e24c12009-10-30 11:49:00 +00005025 continue;
5026 }
5027 if (first.from() > next.to()) {
5028 return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED);
5029 }
5030 ranges->Add(CharacterRange::Range(first.from(), next.to()));
5031 } else {
Ben Murdochb0fe1622011-05-05 13:52:32 +01005032 AddRangeOrEscape(ranges, char_class, first);
Steve Blocka7e24c12009-10-30 11:49:00 +00005033 }
5034 }
5035 if (!has_more()) {
5036 return ReportError(CStrVector(kUnterminated) CHECK_FAILED);
5037 }
5038 Advance();
5039 if (ranges->length() == 0) {
5040 ranges->Add(CharacterRange::Everything());
5041 is_negated = !is_negated;
5042 }
Ben Murdoch8b112d22011-06-08 16:22:53 +01005043 return new(zone()) RegExpCharacterClass(ranges, is_negated);
Steve Blocka7e24c12009-10-30 11:49:00 +00005044}
5045
5046
5047// ----------------------------------------------------------------------------
5048// The Parser interface.
5049
Steve Blocka7e24c12009-10-30 11:49:00 +00005050ParserMessage::~ParserMessage() {
5051 for (int i = 0; i < args().length(); i++)
5052 DeleteArray(args()[i]);
5053 DeleteArray(args().start());
5054}
5055
5056
5057ScriptDataImpl::~ScriptDataImpl() {
Iain Merrick9ac36c92010-09-13 15:29:50 +01005058 if (owns_store_) store_.Dispose();
Steve Blocka7e24c12009-10-30 11:49:00 +00005059}
5060
5061
5062int ScriptDataImpl::Length() {
Leon Clarkef7060e22010-06-03 12:02:55 +01005063 return store_.length() * sizeof(unsigned);
Steve Blocka7e24c12009-10-30 11:49:00 +00005064}
5065
5066
Leon Clarkef7060e22010-06-03 12:02:55 +01005067const char* ScriptDataImpl::Data() {
5068 return reinterpret_cast<const char*>(store_.start());
Steve Blocka7e24c12009-10-30 11:49:00 +00005069}
5070
5071
Leon Clarkee46be812010-01-19 14:06:41 +00005072bool ScriptDataImpl::HasError() {
5073 return has_error();
5074}
5075
5076
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005077void ScriptDataImpl::Initialize() {
5078 // Prepares state for use.
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005079 if (store_.length() >= PreparseDataConstants::kHeaderSize) {
5080 function_index_ = PreparseDataConstants::kHeaderSize;
5081 int symbol_data_offset = PreparseDataConstants::kHeaderSize
5082 + store_[PreparseDataConstants::kFunctionsSizeOffset];
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005083 if (store_.length() > symbol_data_offset) {
5084 symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]);
5085 } else {
5086 // Partial preparse causes no symbol information.
5087 symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
5088 }
5089 symbol_data_end_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
5090 }
5091}
5092
5093
5094int ScriptDataImpl::ReadNumber(byte** source) {
5095 // Reads a number from symbol_data_ in base 128. The most significant
5096 // bit marks that there are more digits.
5097 // If the first byte is 0x80 (kNumberTerminator), it would normally
5098 // represent a leading zero. Since that is useless, and therefore won't
5099 // appear as the first digit of any actual value, it is used to
5100 // mark the end of the input stream.
5101 byte* data = *source;
5102 if (data >= symbol_data_end_) return -1;
5103 byte input = *data;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005104 if (input == PreparseDataConstants::kNumberTerminator) {
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005105 // End of stream marker.
5106 return -1;
5107 }
5108 int result = input & 0x7f;
5109 data++;
5110 while ((input & 0x80u) != 0) {
5111 if (data >= symbol_data_end_) return -1;
5112 input = *data;
5113 result = (result << 7) | (input & 0x7f);
5114 data++;
5115 }
5116 *source = data;
5117 return result;
5118}
5119
5120
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005121// Create a Scanner for the preparser to use as input, and preparse the source.
Ben Murdochb0fe1622011-05-05 13:52:32 +01005122static ScriptDataImpl* DoPreParse(UC16CharacterStream* source,
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005123 bool allow_lazy,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005124 ParserRecorder* recorder,
5125 bool harmony_block_scoping) {
Steve Block44f0eee2011-05-26 01:26:41 +01005126 Isolate* isolate = Isolate::Current();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005127 JavaScriptScanner scanner(isolate->unicode_cache());
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005128 scanner.SetHarmonyBlockScoping(harmony_block_scoping);
Steve Block9fac8402011-05-12 15:51:54 +01005129 scanner.Initialize(source);
Steve Block44f0eee2011-05-26 01:26:41 +01005130 intptr_t stack_limit = isolate->stack_guard()->real_climit();
Ben Murdochb0fe1622011-05-05 13:52:32 +01005131 if (!preparser::PreParser::PreParseProgram(&scanner,
5132 recorder,
5133 allow_lazy,
5134 stack_limit)) {
Steve Block44f0eee2011-05-26 01:26:41 +01005135 isolate->StackOverflow();
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005136 return NULL;
5137 }
5138
Kristian Monsen80d68ea2010-09-08 11:05:35 +01005139 // Extract the accumulated data from the recorder as a single
5140 // contiguous vector that we are responsible for disposing.
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005141 Vector<unsigned> store = recorder->ExtractData();
Steve Blocka7e24c12009-10-30 11:49:00 +00005142 return new ScriptDataImpl(store);
5143}
5144
5145
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005146// Preparse, but only collect data that is immediately useful,
5147// even if the preparser data is only used once.
Ben Murdochb0fe1622011-05-05 13:52:32 +01005148ScriptDataImpl* ParserApi::PartialPreParse(UC16CharacterStream* source,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005149 v8::Extension* extension,
5150 bool harmony_block_scoping) {
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005151 bool allow_lazy = FLAG_lazy && (extension == NULL);
5152 if (!allow_lazy) {
5153 // Partial preparsing is only about lazily compiled functions.
5154 // If we don't allow lazy compilation, the log data will be empty.
5155 return NULL;
5156 }
5157 PartialParserRecorder recorder;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005158 return DoPreParse(source, allow_lazy, &recorder, harmony_block_scoping);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08005159}
5160
5161
Ben Murdochb0fe1622011-05-05 13:52:32 +01005162ScriptDataImpl* ParserApi::PreParse(UC16CharacterStream* source,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005163 v8::Extension* extension,
5164 bool harmony_block_scoping) {
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005165 Handle<Script> no_script;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005166 bool allow_lazy = FLAG_lazy && (extension == NULL);
5167 CompleteParserRecorder recorder;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005168 return DoPreParse(source, allow_lazy, &recorder, harmony_block_scoping);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005169}
5170
5171
5172bool RegExpParser::ParseRegExp(FlatStringReader* input,
5173 bool multiline,
5174 RegExpCompileData* result) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005175 ASSERT(result != NULL);
5176 RegExpParser parser(input, &result->error, multiline);
5177 RegExpTree* tree = parser.ParsePattern();
5178 if (parser.failed()) {
5179 ASSERT(tree == NULL);
5180 ASSERT(!result->error.is_null());
5181 } else {
5182 ASSERT(tree != NULL);
5183 ASSERT(result->error.is_null());
5184 result->tree = tree;
5185 int capture_count = parser.captures_started();
5186 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
5187 result->contains_anchor = parser.contains_anchor();
5188 result->capture_count = capture_count;
5189 }
5190 return !parser.failed();
5191}
5192
5193
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005194bool ParserApi::Parse(CompilationInfo* info) {
Ben Murdochf87a2032010-10-22 12:50:53 +01005195 ASSERT(info->function() == NULL);
5196 FunctionLiteral* result = NULL;
5197 Handle<Script> script = info->script();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005198 bool harmony_block_scoping = !info->is_native() &&
5199 FLAG_harmony_block_scoping;
Ben Murdochf87a2032010-10-22 12:50:53 +01005200 if (info->is_lazy()) {
Ben Murdoch203a29f2011-10-20 14:36:23 +01005201 bool allow_natives_syntax =
5202 FLAG_allow_natives_syntax ||
5203 info->is_native();
5204 Parser parser(script, allow_natives_syntax, NULL, NULL);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005205 parser.SetHarmonyBlockScoping(harmony_block_scoping);
Steve Block44f0eee2011-05-26 01:26:41 +01005206 result = parser.ParseLazy(info);
Leon Clarke4515c472010-02-03 11:58:03 +00005207 } else {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005208 // Whether we allow %identifier(..) syntax.
Ben Murdochf87a2032010-10-22 12:50:53 +01005209 bool allow_natives_syntax =
Ben Murdoch203a29f2011-10-20 14:36:23 +01005210 info->is_native() || FLAG_allow_natives_syntax;
Ben Murdochf87a2032010-10-22 12:50:53 +01005211 ScriptDataImpl* pre_data = info->pre_parse_data();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005212 Parser parser(script,
5213 allow_natives_syntax,
5214 info->extension(),
5215 pre_data);
5216 parser.SetHarmonyBlockScoping(harmony_block_scoping);
Ben Murdochf87a2032010-10-22 12:50:53 +01005217 if (pre_data != NULL && pre_data->has_error()) {
5218 Scanner::Location loc = pre_data->MessageLocation();
5219 const char* message = pre_data->BuildMessage();
5220 Vector<const char*> args = pre_data->BuildArgs();
5221 parser.ReportMessageAt(loc, message, args);
5222 DeleteArray(message);
5223 for (int i = 0; i < args.length(); i++) {
5224 DeleteArray(args[i]);
5225 }
5226 DeleteArray(args.start());
Steve Block44f0eee2011-05-26 01:26:41 +01005227 ASSERT(info->isolate()->has_pending_exception());
Ben Murdochf87a2032010-10-22 12:50:53 +01005228 } else {
5229 Handle<String> source = Handle<String>(String::cast(script->source()));
Steve Block1e0659c2011-05-24 12:43:12 +01005230 result = parser.ParseProgram(source,
5231 info->is_global(),
5232 info->StrictMode());
Ben Murdochf87a2032010-10-22 12:50:53 +01005233 }
Leon Clarke4515c472010-02-03 11:58:03 +00005234 }
Ben Murdochf87a2032010-10-22 12:50:53 +01005235 info->SetFunction(result);
5236 return (result != NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00005237}
5238
Steve Blocka7e24c12009-10-30 11:49:00 +00005239} } // namespace v8::internal