blob: bfdeaa3276dbd047236ce6eec09470e55650230c [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005#include "src/v8.h"
Steve Blocka7e24c12009-10-30 11:49:00 +00006
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007#include "src/api.h"
8#include "src/ast.h"
9#include "src/bailout-reason.h"
10#include "src/base/platform/platform.h"
11#include "src/bootstrapper.h"
12#include "src/char-predicates-inl.h"
13#include "src/codegen.h"
14#include "src/compiler.h"
15#include "src/messages.h"
16#include "src/parser.h"
17#include "src/preparser.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040018#include "src/runtime/runtime.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000019#include "src/scanner-character-streams.h"
20#include "src/scopeinfo.h"
21#include "src/string-stream.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000022
23namespace v8 {
24namespace internal {
25
Ben Murdochb8a8cc12014-11-26 15:28:44 +000026RegExpBuilder::RegExpBuilder(Zone* zone)
27 : zone_(zone),
Ben Murdoch8b112d22011-06-08 16:22:53 +010028 pending_empty_(false),
29 characters_(NULL),
30 terms_(),
31 alternatives_()
Steve Blocka7e24c12009-10-30 11:49:00 +000032#ifdef DEBUG
Ben Murdoch8b112d22011-06-08 16:22:53 +010033 , last_added_(ADD_NONE)
Steve Blocka7e24c12009-10-30 11:49:00 +000034#endif
35 {}
36
37
38void RegExpBuilder::FlushCharacters() {
39 pending_empty_ = false;
40 if (characters_ != NULL) {
Ben Murdoch8b112d22011-06-08 16:22:53 +010041 RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector());
Steve Blocka7e24c12009-10-30 11:49:00 +000042 characters_ = NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000043 text_.Add(atom, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +000044 LAST(ADD_ATOM);
45 }
46}
47
48
49void RegExpBuilder::FlushText() {
50 FlushCharacters();
51 int num_text = text_.length();
52 if (num_text == 0) {
53 return;
54 } else if (num_text == 1) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000055 terms_.Add(text_.last(), zone());
Steve Blocka7e24c12009-10-30 11:49:00 +000056 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000057 RegExpText* text = new(zone()) RegExpText(zone());
Steve Blocka7e24c12009-10-30 11:49:00 +000058 for (int i = 0; i < num_text; i++)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000059 text_.Get(i)->AppendToText(text, zone());
60 terms_.Add(text, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +000061 }
62 text_.Clear();
63}
64
65
66void RegExpBuilder::AddCharacter(uc16 c) {
67 pending_empty_ = false;
68 if (characters_ == NULL) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000069 characters_ = new(zone()) ZoneList<uc16>(4, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +000070 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000071 characters_->Add(c, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +000072 LAST(ADD_CHAR);
73}
74
75
76void RegExpBuilder::AddEmpty() {
77 pending_empty_ = true;
78}
79
80
81void RegExpBuilder::AddAtom(RegExpTree* term) {
82 if (term->IsEmpty()) {
83 AddEmpty();
84 return;
85 }
86 if (term->IsTextElement()) {
87 FlushCharacters();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000088 text_.Add(term, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +000089 } else {
90 FlushText();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000091 terms_.Add(term, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +000092 }
93 LAST(ADD_ATOM);
94}
95
96
97void RegExpBuilder::AddAssertion(RegExpTree* assert) {
98 FlushText();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000099 terms_.Add(assert, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +0000100 LAST(ADD_ASSERT);
101}
102
103
104void RegExpBuilder::NewAlternative() {
105 FlushTerms();
106}
107
108
109void RegExpBuilder::FlushTerms() {
110 FlushText();
111 int num_terms = terms_.length();
112 RegExpTree* alternative;
113 if (num_terms == 0) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400114 alternative = new (zone()) RegExpEmpty();
Steve Blocka7e24c12009-10-30 11:49:00 +0000115 } else if (num_terms == 1) {
116 alternative = terms_.last();
117 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000118 alternative = new(zone()) RegExpAlternative(terms_.GetList(zone()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000119 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000120 alternatives_.Add(alternative, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +0000121 terms_.Clear();
122 LAST(ADD_NONE);
123}
124
125
126RegExpTree* RegExpBuilder::ToRegExp() {
127 FlushTerms();
128 int num_alternatives = alternatives_.length();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400129 if (num_alternatives == 0) return new (zone()) RegExpEmpty();
130 if (num_alternatives == 1) return alternatives_.last();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000131 return new(zone()) RegExpDisjunction(alternatives_.GetList(zone()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000132}
133
134
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000135void RegExpBuilder::AddQuantifierToAtom(
136 int min, int max, RegExpQuantifier::QuantifierType quantifier_type) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000137 if (pending_empty_) {
138 pending_empty_ = false;
139 return;
140 }
141 RegExpTree* atom;
142 if (characters_ != NULL) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000143 DCHECK(last_added_ == ADD_CHAR);
Steve Blocka7e24c12009-10-30 11:49:00 +0000144 // Last atom was character.
145 Vector<const uc16> char_vector = characters_->ToConstVector();
146 int num_chars = char_vector.length();
147 if (num_chars > 1) {
148 Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000149 text_.Add(new(zone()) RegExpAtom(prefix), zone());
Steve Blocka7e24c12009-10-30 11:49:00 +0000150 char_vector = char_vector.SubVector(num_chars - 1, num_chars);
151 }
152 characters_ = NULL;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100153 atom = new(zone()) RegExpAtom(char_vector);
Steve Blocka7e24c12009-10-30 11:49:00 +0000154 FlushText();
155 } else if (text_.length() > 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000156 DCHECK(last_added_ == ADD_ATOM);
Steve Blocka7e24c12009-10-30 11:49:00 +0000157 atom = text_.RemoveLast();
158 FlushText();
159 } else if (terms_.length() > 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000160 DCHECK(last_added_ == ADD_ATOM);
Steve Blocka7e24c12009-10-30 11:49:00 +0000161 atom = terms_.RemoveLast();
162 if (atom->max_match() == 0) {
163 // Guaranteed to only match an empty string.
164 LAST(ADD_TERM);
165 if (min == 0) {
166 return;
167 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000168 terms_.Add(atom, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +0000169 return;
170 }
171 } else {
172 // Only call immediately after adding an atom or character!
173 UNREACHABLE();
174 return;
175 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000176 terms_.Add(
177 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone());
Steve Blocka7e24c12009-10-30 11:49:00 +0000178 LAST(ADD_TERM);
179}
180
181
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000182FunctionEntry ParseData::GetFunctionEntry(int start) {
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100183 // The current pre-data entry must be a FunctionEntry with the given
184 // start position.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000185 if ((function_index_ + FunctionEntry::kSize <= Length()) &&
186 (static_cast<int>(Data()[function_index_]) == start)) {
Iain Merrick9ac36c92010-09-13 15:29:50 +0100187 int index = function_index_;
188 function_index_ += FunctionEntry::kSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000189 Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize);
190 return FunctionEntry(subvector);
Steve Blocka7e24c12009-10-30 11:49:00 +0000191 }
192 return FunctionEntry();
193}
194
195
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000196int ParseData::FunctionCount() {
197 int functions_size = FunctionsSize();
198 if (functions_size < 0) return 0;
199 if (functions_size % FunctionEntry::kSize != 0) return 0;
200 return functions_size / FunctionEntry::kSize;
Iain Merrick9ac36c92010-09-13 15:29:50 +0100201}
202
203
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000204bool ParseData::IsSane() {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400205 if (!IsAligned(script_data_->length(), sizeof(unsigned))) return false;
Iain Merrick9ac36c92010-09-13 15:29:50 +0100206 // Check that the header data is valid and doesn't specify
207 // point to positions outside the store.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000208 int data_length = Length();
209 if (data_length < PreparseDataConstants::kHeaderSize) return false;
210 if (Magic() != PreparseDataConstants::kMagicNumber) return false;
211 if (Version() != PreparseDataConstants::kCurrentVersion) return false;
212 if (HasError()) return false;
Iain Merrick9ac36c92010-09-13 15:29:50 +0100213 // Check that the space allocated for function entries is sane.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000214 int functions_size = FunctionsSize();
Iain Merrick9ac36c92010-09-13 15:29:50 +0100215 if (functions_size < 0) return false;
216 if (functions_size % FunctionEntry::kSize != 0) return false;
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100217 // Check that the total size has room for header and function entries.
Iain Merrick9ac36c92010-09-13 15:29:50 +0100218 int minimum_size =
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800219 PreparseDataConstants::kHeaderSize + functions_size;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000220 if (data_length < minimum_size) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +0000221 return true;
222}
223
224
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000225void ParseData::Initialize() {
226 // Prepares state for use.
227 int data_length = Length();
228 if (data_length >= PreparseDataConstants::kHeaderSize) {
229 function_index_ = PreparseDataConstants::kHeaderSize;
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100230 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000231}
232
233
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000234bool ParseData::HasError() {
235 return Data()[PreparseDataConstants::kHasErrorOffset];
Steve Blocka7e24c12009-10-30 11:49:00 +0000236}
237
238
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000239unsigned ParseData::Magic() {
240 return Data()[PreparseDataConstants::kMagicOffset];
241}
242
243
244unsigned ParseData::Version() {
245 return Data()[PreparseDataConstants::kVersionOffset];
246}
247
248
249int ParseData::FunctionsSize() {
250 return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]);
251}
252
253
254void Parser::SetCachedData() {
255 if (compile_options() == ScriptCompiler::kNoCompileOptions) {
256 cached_parse_data_ = NULL;
257 } else {
258 DCHECK(info_->cached_data() != NULL);
259 if (compile_options() == ScriptCompiler::kConsumeParserCache) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400260 cached_parse_data_ = ParseData::FromCachedData(*info_->cached_data());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000261 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000262 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000263}
264
265
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000266Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) {
267 DCHECK(ast_value_factory());
268 Scope* result =
269 new (zone()) Scope(parent, scope_type, ast_value_factory(), zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100270 result->Initialize();
Steve Blocka7e24c12009-10-30 11:49:00 +0000271 return result;
272}
273
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000274
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400275FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope,
276 int pos, int end_pos) {
277 int materialized_literal_count = -1;
278 int expected_property_count = -1;
279 int handler_count = 0;
280 int parameter_count = 0;
281 const AstRawString* name = ast_value_factory()->empty_string();
282
283 Scope* function_scope = NewScope(scope, FUNCTION_SCOPE);
284 function_scope->SetStrictMode(STRICT);
285 // Set start and end position to the same value
286 function_scope->set_start_position(pos);
287 function_scope->set_end_position(pos);
288 ZoneList<Statement*>* body = NULL;
289
290 {
291 AstNodeFactory function_factory(ast_value_factory());
292 FunctionState function_state(&function_state_, &scope_, function_scope,
293 &function_factory);
294
295 body = new (zone()) ZoneList<Statement*>(1, zone());
296 if (call_super) {
297 ZoneList<Expression*>* args =
298 new (zone()) ZoneList<Expression*>(0, zone());
299 CallRuntime* call = factory()->NewCallRuntime(
300 ast_value_factory()->empty_string(),
301 Runtime::FunctionForId(Runtime::kDefaultConstructorSuperCall), args,
302 pos);
303 body->Add(factory()->NewExpressionStatement(call, pos), zone());
304 function_scope->RecordSuperConstructorCallUsage();
305 }
306
307 materialized_literal_count = function_state.materialized_literal_count();
308 expected_property_count = function_state.expected_property_count();
309 handler_count = function_state.handler_count();
310 }
311
312 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
313 name, ast_value_factory(), function_scope, body,
314 materialized_literal_count, expected_property_count, handler_count,
315 parameter_count, FunctionLiteral::kNoDuplicateParameters,
316 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
317 FunctionLiteral::kNotParenthesized, FunctionKind::kDefaultConstructor,
318 pos);
319
320 return function_literal;
321}
322
323
Steve Blocka7e24c12009-10-30 11:49:00 +0000324// ----------------------------------------------------------------------------
325// Target is a support class to facilitate manipulation of the
326// Parser's target_stack_ (the stack of potential 'break' and
327// 'continue' statement targets). Upon construction, a new target is
328// added; it is removed upon destruction.
329
330class Target BASE_EMBEDDED {
331 public:
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800332 Target(Target** variable, AstNode* node)
333 : variable_(variable), node_(node), previous_(*variable) {
334 *variable = this;
Steve Blocka7e24c12009-10-30 11:49:00 +0000335 }
336
337 ~Target() {
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800338 *variable_ = previous_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000339 }
340
341 Target* previous() { return previous_; }
342 AstNode* node() { return node_; }
343
344 private:
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800345 Target** variable_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000346 AstNode* node_;
347 Target* previous_;
348};
349
350
351class TargetScope BASE_EMBEDDED {
352 public:
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800353 explicit TargetScope(Target** variable)
354 : variable_(variable), previous_(*variable) {
355 *variable = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +0000356 }
357
358 ~TargetScope() {
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800359 *variable_ = previous_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000360 }
361
362 private:
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800363 Target** variable_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000364 Target* previous_;
365};
366
367
368// ----------------------------------------------------------------------------
Steve Blocka7e24c12009-10-30 11:49:00 +0000369// The CHECK_OK macro is a convenient macro to enforce error
370// handling for functions that may fail (by returning !*ok).
371//
372// CAUTION: This macro appends extra statements after a call,
373// thus it must never be used where only a single statement
374// is correct (e.g. an if statement branch w/o braces)!
375
376#define CHECK_OK ok); \
377 if (!*ok) return NULL; \
378 ((void)0
379#define DUMMY ) // to make indentation work
380#undef DUMMY
381
382#define CHECK_FAILED /**/); \
383 if (failed_) return NULL; \
384 ((void)0
385#define DUMMY ) // to make indentation work
386#undef DUMMY
387
388// ----------------------------------------------------------------------------
389// Implementation of Parser
390
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000391bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const {
392 return identifier == parser_->ast_value_factory()->eval_string() ||
393 identifier == parser_->ast_value_factory()->arguments_string();
394}
395
396
397bool ParserTraits::IsPrototype(const AstRawString* identifier) const {
398 return identifier == parser_->ast_value_factory()->prototype_string();
399}
400
401
402bool ParserTraits::IsConstructor(const AstRawString* identifier) const {
403 return identifier == parser_->ast_value_factory()->constructor_string();
404}
405
406
407bool ParserTraits::IsThisProperty(Expression* expression) {
408 DCHECK(expression != NULL);
409 Property* property = expression->AsProperty();
410 return property != NULL &&
411 property->obj()->AsVariableProxy() != NULL &&
412 property->obj()->AsVariableProxy()->is_this();
413}
414
415
416bool ParserTraits::IsIdentifier(Expression* expression) {
417 VariableProxy* operand = expression->AsVariableProxy();
418 return operand != NULL && !operand->is_this();
419}
420
421
422void ParserTraits::PushPropertyName(FuncNameInferrer* fni,
423 Expression* expression) {
424 if (expression->IsPropertyName()) {
425 fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
426 } else {
427 fni->PushLiteralName(
428 parser_->ast_value_factory()->anonymous_function_string());
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100429 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000430}
431
432
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000433void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
434 Expression* right) {
435 DCHECK(left != NULL);
436 if (left->AsProperty() != NULL &&
437 right->AsFunctionLiteral() != NULL) {
438 right->AsFunctionLiteral()->set_pretenure();
439 }
440}
Steve Blocka7e24c12009-10-30 11:49:00 +0000441
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000442
443void ParserTraits::CheckPossibleEvalCall(Expression* expression,
444 Scope* scope) {
445 VariableProxy* callee = expression->AsVariableProxy();
446 if (callee != NULL &&
447 callee->raw_name() == parser_->ast_value_factory()->eval_string()) {
448 scope->DeclarationScope()->RecordEvalCall();
449 }
450}
451
452
453Expression* ParserTraits::MarkExpressionAsAssigned(Expression* expression) {
454 VariableProxy* proxy =
455 expression != NULL ? expression->AsVariableProxy() : NULL;
456 if (proxy != NULL) proxy->set_is_assigned();
457 return expression;
458}
459
460
461bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
462 Expression** x, Expression* y, Token::Value op, int pos,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400463 AstNodeFactory* factory) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000464 if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
465 y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) {
466 double x_val = (*x)->AsLiteral()->raw_value()->AsNumber();
467 double y_val = y->AsLiteral()->raw_value()->AsNumber();
468 switch (op) {
469 case Token::ADD:
470 *x = factory->NewNumberLiteral(x_val + y_val, pos);
471 return true;
472 case Token::SUB:
473 *x = factory->NewNumberLiteral(x_val - y_val, pos);
474 return true;
475 case Token::MUL:
476 *x = factory->NewNumberLiteral(x_val * y_val, pos);
477 return true;
478 case Token::DIV:
479 *x = factory->NewNumberLiteral(x_val / y_val, pos);
480 return true;
481 case Token::BIT_OR: {
482 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
483 *x = factory->NewNumberLiteral(value, pos);
484 return true;
485 }
486 case Token::BIT_AND: {
487 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
488 *x = factory->NewNumberLiteral(value, pos);
489 return true;
490 }
491 case Token::BIT_XOR: {
492 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
493 *x = factory->NewNumberLiteral(value, pos);
494 return true;
495 }
496 case Token::SHL: {
497 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
498 *x = factory->NewNumberLiteral(value, pos);
499 return true;
500 }
501 case Token::SHR: {
502 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
503 uint32_t value = DoubleToUint32(x_val) >> shift;
504 *x = factory->NewNumberLiteral(value, pos);
505 return true;
506 }
507 case Token::SAR: {
508 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
509 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
510 *x = factory->NewNumberLiteral(value, pos);
511 return true;
512 }
513 default:
514 break;
515 }
516 }
517 return false;
518}
519
520
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400521Expression* ParserTraits::BuildUnaryExpression(Expression* expression,
522 Token::Value op, int pos,
523 AstNodeFactory* factory) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000524 DCHECK(expression != NULL);
525 if (expression->IsLiteral()) {
526 const AstValue* literal = expression->AsLiteral()->raw_value();
527 if (op == Token::NOT) {
528 // Convert the literal to a boolean condition and negate it.
529 bool condition = literal->BooleanValue();
530 return factory->NewBooleanLiteral(!condition, pos);
531 } else if (literal->IsNumber()) {
532 // Compute some expressions involving only number literals.
533 double value = literal->AsNumber();
534 switch (op) {
535 case Token::ADD:
536 return expression;
537 case Token::SUB:
538 return factory->NewNumberLiteral(-value, pos);
539 case Token::BIT_NOT:
540 return factory->NewNumberLiteral(~DoubleToInt32(value), pos);
541 default:
542 break;
543 }
544 }
545 }
546 // Desugar '+foo' => 'foo*1'
547 if (op == Token::ADD) {
548 return factory->NewBinaryOperation(
549 Token::MUL, expression, factory->NewNumberLiteral(1, pos), pos);
550 }
551 // The same idea for '-foo' => 'foo*(-1)'.
552 if (op == Token::SUB) {
553 return factory->NewBinaryOperation(
554 Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos);
555 }
556 // ...and one more time for '~foo' => 'foo^(~0)'.
557 if (op == Token::BIT_NOT) {
558 return factory->NewBinaryOperation(
559 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos);
560 }
561 return factory->NewUnaryOperation(op, expression, pos);
562}
563
564
565Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) {
566 return NewThrowError(
567 parser_->ast_value_factory()->make_reference_error_string(), message,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400568 parser_->ast_value_factory()->empty_string(), pos);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000569}
570
571
572Expression* ParserTraits::NewThrowSyntaxError(
573 const char* message, const AstRawString* arg, int pos) {
574 return NewThrowError(parser_->ast_value_factory()->make_syntax_error_string(),
575 message, arg, pos);
576}
577
578
579Expression* ParserTraits::NewThrowTypeError(
580 const char* message, const AstRawString* arg, int pos) {
581 return NewThrowError(parser_->ast_value_factory()->make_type_error_string(),
582 message, arg, pos);
583}
584
585
586Expression* ParserTraits::NewThrowError(
587 const AstRawString* constructor, const char* message,
588 const AstRawString* arg, int pos) {
589 Zone* zone = parser_->zone();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000590 const AstRawString* type =
591 parser_->ast_value_factory()->GetOneByteString(message);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000592 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone);
593 args->Add(parser_->factory()->NewStringLiteral(type, pos), zone);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400594 args->Add(parser_->factory()->NewStringLiteral(arg, pos), zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000595 CallRuntime* call_constructor =
596 parser_->factory()->NewCallRuntime(constructor, NULL, args, pos);
597 return parser_->factory()->NewThrow(call_constructor, pos);
598}
599
600
601void ParserTraits::ReportMessageAt(Scanner::Location source_location,
602 const char* message,
603 const char* arg,
604 bool is_reference_error) {
605 if (parser_->stack_overflow()) {
606 // Suppress the error message (syntax error or such) in the presence of a
607 // stack overflow. The isolate allows only one pending exception at at time
608 // and we want to report the stack overflow later.
609 return;
610 }
611 parser_->has_pending_error_ = true;
612 parser_->pending_error_location_ = source_location;
613 parser_->pending_error_message_ = message;
614 parser_->pending_error_char_arg_ = arg;
615 parser_->pending_error_arg_ = NULL;
616 parser_->pending_error_is_reference_error_ = is_reference_error;
617}
618
619
620void ParserTraits::ReportMessage(const char* message,
621 const char* arg,
622 bool is_reference_error) {
623 Scanner::Location source_location = parser_->scanner()->location();
624 ReportMessageAt(source_location, message, arg, is_reference_error);
625}
626
627
628void ParserTraits::ReportMessage(const char* message,
629 const AstRawString* arg,
630 bool is_reference_error) {
631 Scanner::Location source_location = parser_->scanner()->location();
632 ReportMessageAt(source_location, message, arg, is_reference_error);
633}
634
635
636void ParserTraits::ReportMessageAt(Scanner::Location source_location,
637 const char* message,
638 const AstRawString* arg,
639 bool is_reference_error) {
640 if (parser_->stack_overflow()) {
641 // Suppress the error message (syntax error or such) in the presence of a
642 // stack overflow. The isolate allows only one pending exception at at time
643 // and we want to report the stack overflow later.
644 return;
645 }
646 parser_->has_pending_error_ = true;
647 parser_->pending_error_location_ = source_location;
648 parser_->pending_error_message_ = message;
649 parser_->pending_error_char_arg_ = NULL;
650 parser_->pending_error_arg_ = arg;
651 parser_->pending_error_is_reference_error_ = is_reference_error;
652}
653
654
655const AstRawString* ParserTraits::GetSymbol(Scanner* scanner) {
656 const AstRawString* result =
657 parser_->scanner()->CurrentSymbol(parser_->ast_value_factory());
658 DCHECK(result != NULL);
659 return result;
660}
661
662
663const AstRawString* ParserTraits::GetNumberAsSymbol(Scanner* scanner) {
664 double double_value = parser_->scanner()->DoubleValue();
665 char array[100];
666 const char* string =
667 DoubleToCString(double_value, Vector<char>(array, arraysize(array)));
668 return ast_value_factory()->GetOneByteString(string);
669}
670
671
672const AstRawString* ParserTraits::GetNextSymbol(Scanner* scanner) {
673 return parser_->scanner()->NextSymbol(parser_->ast_value_factory());
674}
675
676
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400677Expression* ParserTraits::ThisExpression(Scope* scope, AstNodeFactory* factory,
678 int pos) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000679 return factory->NewVariableProxy(scope->receiver(), pos);
680}
681
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400682Expression* ParserTraits::SuperReference(Scope* scope, AstNodeFactory* factory,
683 int pos) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000684 return factory->NewSuperReference(
685 ThisExpression(scope, factory, pos)->AsVariableProxy(),
686 pos);
687}
688
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400689
690Expression* ParserTraits::DefaultConstructor(bool call_super, Scope* scope,
691 int pos, int end_pos) {
692 return parser_->DefaultConstructor(call_super, scope, pos, end_pos);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000693}
694
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400695
696Literal* ParserTraits::ExpressionFromLiteral(Token::Value token, int pos,
697 Scanner* scanner,
698 AstNodeFactory* factory) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000699 switch (token) {
700 case Token::NULL_LITERAL:
701 return factory->NewNullLiteral(pos);
702 case Token::TRUE_LITERAL:
703 return factory->NewBooleanLiteral(true, pos);
704 case Token::FALSE_LITERAL:
705 return factory->NewBooleanLiteral(false, pos);
706 case Token::NUMBER: {
707 double value = scanner->DoubleValue();
708 return factory->NewNumberLiteral(value, pos);
709 }
710 default:
711 DCHECK(false);
712 }
713 return NULL;
714}
715
716
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400717Expression* ParserTraits::ExpressionFromIdentifier(const AstRawString* name,
718 int pos, Scope* scope,
719 AstNodeFactory* factory) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000720 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name);
721 // The name may refer to a module instance object, so its type is unknown.
722#ifdef DEBUG
723 if (FLAG_print_interface_details)
724 PrintF("# Variable %.*s ", name->length(), name->raw_data());
725#endif
726 Interface* interface = Interface::NewUnknown(parser_->zone());
727 return scope->NewUnresolved(factory, name, interface, pos);
728}
729
730
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400731Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner,
732 AstNodeFactory* factory) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000733 const AstRawString* symbol = GetSymbol(scanner);
734 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol);
735 return factory->NewStringLiteral(symbol, pos);
736}
737
738
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400739Expression* ParserTraits::GetIterator(Expression* iterable,
740 AstNodeFactory* factory) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000741 Expression* iterator_symbol_literal =
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400742 factory->NewSymbolLiteral("iterator_symbol", RelocInfo::kNoPosition);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000743 int pos = iterable->position();
744 Expression* prop =
745 factory->NewProperty(iterable, iterator_symbol_literal, pos);
746 Zone* zone = parser_->zone();
747 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(0, zone);
748 return factory->NewCall(prop, args, pos);
749}
750
751
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400752Literal* ParserTraits::GetLiteralTheHole(int position,
753 AstNodeFactory* factory) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000754 return factory->NewTheHoleLiteral(RelocInfo::kNoPosition);
755}
756
757
758Expression* ParserTraits::ParseV8Intrinsic(bool* ok) {
759 return parser_->ParseV8Intrinsic(ok);
760}
761
762
763FunctionLiteral* ParserTraits::ParseFunctionLiteral(
764 const AstRawString* name, Scanner::Location function_name_location,
765 bool name_is_strict_reserved, FunctionKind kind,
766 int function_token_position, FunctionLiteral::FunctionType type,
767 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
768 return parser_->ParseFunctionLiteral(
769 name, function_name_location, name_is_strict_reserved, kind,
770 function_token_position, type, arity_restriction, ok);
771}
772
773
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400774ClassLiteral* ParserTraits::ParseClassLiteral(
775 const AstRawString* name, Scanner::Location class_name_location,
776 bool name_is_strict_reserved, int pos, bool* ok) {
777 return parser_->ParseClassLiteral(name, class_name_location,
778 name_is_strict_reserved, pos, ok);
779}
780
781
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000782Parser::Parser(CompilationInfo* info, ParseInfo* parse_info)
783 : ParserBase<ParserTraits>(&scanner_, parse_info->stack_limit,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400784 info->extension(), NULL, info->zone(), this),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000785 scanner_(parse_info->unicode_cache),
786 reusable_preparser_(NULL),
787 original_scope_(NULL),
788 target_stack_(NULL),
789 cached_parse_data_(NULL),
790 info_(info),
791 has_pending_error_(false),
792 pending_error_message_(NULL),
793 pending_error_arg_(NULL),
794 pending_error_char_arg_(NULL),
795 total_preparse_skipped_(0),
796 pre_parse_timer_(NULL) {
797 DCHECK(!script().is_null() || info->source_stream() != NULL);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000798 set_allow_lazy(false); // Must be explicitly enabled.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400799 set_allow_natives(FLAG_allow_natives_syntax || info->is_native());
800 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping);
801 set_allow_harmony_modules(!info->is_native() && FLAG_harmony_modules);
802 set_allow_harmony_arrow_functions(FLAG_harmony_arrow_functions);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000803 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400804 set_allow_harmony_classes(FLAG_harmony_classes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000805 set_allow_harmony_object_literals(FLAG_harmony_object_literals);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400806 set_allow_harmony_templates(FLAG_harmony_templates);
807 set_allow_harmony_sloppy(FLAG_harmony_sloppy);
808 set_allow_harmony_unicode(FLAG_harmony_unicode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000809 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
810 ++feature) {
811 use_counts_[feature] = 0;
812 }
813 if (info->ast_value_factory() == NULL) {
814 // info takes ownership of AstValueFactory.
815 info->SetAstValueFactory(
816 new AstValueFactory(zone(), parse_info->hash_seed));
817 }
818}
819
820
821FunctionLiteral* Parser::ParseProgram() {
822 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
823 // see comment for HistogramTimerScope class.
824
825 // It's OK to use the counters here, since this function is only called in
826 // the main thread.
827 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true);
828 Handle<String> source(String::cast(script()->source()));
Steve Block44f0eee2011-05-26 01:26:41 +0100829 isolate()->counters()->total_parse_size()->Increment(source->length());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000830 base::ElapsedTimer timer;
831 if (FLAG_trace_parse) {
832 timer.Start();
833 }
834 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
Steve Blocka7e24c12009-10-30 11:49:00 +0000835
836 // Initialize parser state.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000837 CompleteParserRecorder recorder;
838
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400839 if (produce_cached_parse_data()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000840 log_ = &recorder;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400841 } else if (consume_cached_parse_data()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000842 cached_parse_data_->Initialize();
843 }
844
845 source = String::Flatten(source);
846 FunctionLiteral* result;
847
848 Scope* top_scope = NULL;
849 Scope* eval_scope = NULL;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100850 if (source->IsExternalTwoByteString()) {
851 // Notice that the stream is destroyed at the end of the branch block.
852 // The last line of the blocks can't be moved outside, even though they're
853 // identical calls.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100854 ExternalTwoByteStringUtf16CharacterStream stream(
Ben Murdochb0fe1622011-05-05 13:52:32 +0100855 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
Steve Block9fac8402011-05-12 15:51:54 +0100856 scanner_.Initialize(&stream);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000857 result = DoParseProgram(info(), &top_scope, &eval_scope);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100858 } else {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100859 GenericStringUtf16CharacterStream stream(source, 0, source->length());
Steve Block9fac8402011-05-12 15:51:54 +0100860 scanner_.Initialize(&stream);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000861 result = DoParseProgram(info(), &top_scope, &eval_scope);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100862 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000863 top_scope->set_end_position(source->length());
864 if (eval_scope != NULL) {
865 eval_scope->set_end_position(source->length());
Steve Blocka7e24c12009-10-30 11:49:00 +0000866 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000867 HandleSourceURLComments();
Steve Blocka7e24c12009-10-30 11:49:00 +0000868
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000869 if (FLAG_trace_parse && result != NULL) {
870 double ms = timer.Elapsed().InMillisecondsF();
871 if (info()->is_eval()) {
872 PrintF("[parsing eval");
873 } else if (info()->script()->name()->IsString()) {
874 String* name = String::cast(info()->script()->name());
875 SmartArrayPointer<char> name_chars = name->ToCString();
876 PrintF("[parsing script: %s", name_chars.get());
877 } else {
878 PrintF("[parsing script");
879 }
880 PrintF(" - took %0.3f ms]\n", ms);
881 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400882 if (produce_cached_parse_data()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000883 if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
884 log_ = NULL;
885 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000886 return result;
887}
888
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100889
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000890FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope,
891 Scope** eval_scope) {
892 DCHECK(scope_ == NULL);
893 DCHECK(target_stack_ == NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +0000894
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000895 FunctionLiteral* result = NULL;
896 {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400897 *scope = NewScope(scope_, SCRIPT_SCOPE);
898 info->SetScriptScope(*scope);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000899 if (!info->context().is_null() && !info->context()->IsNativeContext()) {
900 *scope = Scope::DeserializeScopeChain(*info->context(), *scope, zone());
901 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this
902 // means the Parser cannot operate independent of the V8 heap. Tell the
903 // string table to internalize strings and values right after they're
904 // created.
905 ast_value_factory()->Internalize(isolate());
906 }
907 original_scope_ = *scope;
908 if (info->is_eval()) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400909 if (!(*scope)->is_script_scope() || info->strict_mode() == STRICT) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000910 *scope = NewScope(*scope, EVAL_SCOPE);
911 }
912 } else if (info->is_global()) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400913 *scope = NewScope(*scope, SCRIPT_SCOPE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000914 }
915 (*scope)->set_start_position(0);
916 // End position will be set by the caller.
917
918 // Compute the parsing mode.
919 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400920 if (allow_natives() || extension_ != NULL ||
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000921 (*scope)->is_eval_scope()) {
922 mode = PARSE_EAGERLY;
923 }
924 ParsingModeScope parsing_mode(this, mode);
925
926 // Enters 'scope'.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400927 AstNodeFactory function_factory(ast_value_factory());
928 FunctionState function_state(&function_state_, &scope_, *scope,
929 &function_factory);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000930
931 scope_->SetStrictMode(info->strict_mode());
932 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
933 bool ok = true;
934 int beg_pos = scanner()->location().beg_pos;
935 ParseSourceElements(body, Token::EOS, info->is_eval(), true, eval_scope,
936 &ok);
937
938 if (ok && strict_mode() == STRICT) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400939 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000940 }
941
942 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) {
943 CheckConflictingVarDeclarations(scope_, &ok);
944 }
945
946 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
947 if (body->length() != 1 ||
948 !body->at(0)->IsExpressionStatement() ||
949 !body->at(0)->AsExpressionStatement()->
950 expression()->IsFunctionLiteral()) {
951 ReportMessage("single_function_literal");
952 ok = false;
953 }
954 }
955
956 if (ok) {
957 result = factory()->NewFunctionLiteral(
958 ast_value_factory()->empty_string(), ast_value_factory(), scope_,
959 body, function_state.materialized_literal_count(),
960 function_state.expected_property_count(),
961 function_state.handler_count(), 0,
962 FunctionLiteral::kNoDuplicateParameters,
963 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval,
964 FunctionLiteral::kNotParenthesized, FunctionKind::kNormalFunction, 0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000965 }
966 }
967
968 // Make sure the target stack is empty.
969 DCHECK(target_stack_ == NULL);
970
971 return result;
972}
973
974
975FunctionLiteral* Parser::ParseLazy() {
976 // It's OK to use the counters here, since this function is only called in
977 // the main thread.
978 HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy());
979 Handle<String> source(String::cast(script()->source()));
980 isolate()->counters()->total_parse_size()->Increment(source->length());
981 base::ElapsedTimer timer;
982 if (FLAG_trace_parse) {
983 timer.Start();
984 }
985 Handle<SharedFunctionInfo> shared_info = info()->shared_info();
986
Ben Murdochb0fe1622011-05-05 13:52:32 +0100987 // Initialize parser state.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000988 source = String::Flatten(source);
989 FunctionLiteral* result;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100990 if (source->IsExternalTwoByteString()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100991 ExternalTwoByteStringUtf16CharacterStream stream(
Ben Murdochb0fe1622011-05-05 13:52:32 +0100992 Handle<ExternalTwoByteString>::cast(source),
Steve Block44f0eee2011-05-26 01:26:41 +0100993 shared_info->start_position(),
994 shared_info->end_position());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000995 result = ParseLazy(&stream);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100996 } else {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100997 GenericStringUtf16CharacterStream stream(source,
998 shared_info->start_position(),
999 shared_info->end_position());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001000 result = ParseLazy(&stream);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001001 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001002
1003 if (FLAG_trace_parse && result != NULL) {
1004 double ms = timer.Elapsed().InMillisecondsF();
1005 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString();
1006 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
1007 }
1008 return result;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001009}
1010
1011
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001012FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) {
1013 Handle<SharedFunctionInfo> shared_info = info()->shared_info();
Steve Block9fac8402011-05-12 15:51:54 +01001014 scanner_.Initialize(source);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001015 DCHECK(scope_ == NULL);
1016 DCHECK(target_stack_ == NULL);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001017
Steve Block44f0eee2011-05-26 01:26:41 +01001018 Handle<String> name(String::cast(shared_info->name()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001019 DCHECK(ast_value_factory());
1020 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
1021 const AstRawString* raw_name = ast_value_factory()->GetString(name);
1022 fni_->PushEnclosingName(raw_name);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001023
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001024 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
Steve Blocka7e24c12009-10-30 11:49:00 +00001025
1026 // Place holder for the result.
1027 FunctionLiteral* result = NULL;
1028
1029 {
1030 // Parse the function literal.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001031 Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
1032 info()->SetScriptScope(scope);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001033 if (!info()->closure().is_null()) {
1034 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope,
1035 zone());
Steve Block44f0eee2011-05-26 01:26:41 +01001036 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001037 original_scope_ = scope;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001038 AstNodeFactory function_factory(ast_value_factory());
1039 FunctionState function_state(&function_state_, &scope_, scope,
1040 &function_factory);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001041 DCHECK(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT);
1042 DCHECK(info()->strict_mode() == shared_info->strict_mode());
1043 scope->SetStrictMode(shared_info->strict_mode());
1044 FunctionLiteral::FunctionType function_type = shared_info->is_expression()
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001045 ? (shared_info->is_anonymous()
1046 ? FunctionLiteral::ANONYMOUS_EXPRESSION
1047 : FunctionLiteral::NAMED_EXPRESSION)
1048 : FunctionLiteral::DECLARATION;
Steve Blocka7e24c12009-10-30 11:49:00 +00001049 bool ok = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001050
1051 if (shared_info->is_arrow()) {
1052 Expression* expression = ParseExpression(false, &ok);
1053 DCHECK(expression->IsFunctionLiteral());
1054 result = expression->AsFunctionLiteral();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001055 } else if (shared_info->is_default_constructor()) {
1056 result = DefaultConstructor(shared_info->uses_super_constructor_call(),
1057 scope, shared_info->start_position(),
1058 shared_info->end_position());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001059 } else {
1060 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(),
1061 false, // Strict mode name already checked.
1062 shared_info->kind(), RelocInfo::kNoPosition,
1063 function_type,
1064 FunctionLiteral::NORMAL_ARITY, &ok);
1065 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001066 // Make sure the results agree.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001067 DCHECK(ok == (result != NULL));
Steve Blocka7e24c12009-10-30 11:49:00 +00001068 }
1069
1070 // Make sure the target stack is empty.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001071 DCHECK(target_stack_ == NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00001072
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001073 if (result != NULL) {
Steve Block44f0eee2011-05-26 01:26:41 +01001074 Handle<String> inferred_name(shared_info->inferred_name());
Ben Murdochb0fe1622011-05-05 13:52:32 +01001075 result->set_inferred_name(inferred_name);
Steve Blocka7e24c12009-10-30 11:49:00 +00001076 }
1077 return result;
1078}
1079
Ben Murdochf87a2032010-10-22 12:50:53 +01001080
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001081void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001082 int end_token, bool is_eval, bool is_global,
1083 Scope** eval_scope, bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001084 // SourceElements ::
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001085 // (ModuleElement)* <end_token>
Steve Blocka7e24c12009-10-30 11:49:00 +00001086
1087 // Allocate a target stack to use for this set of source
1088 // elements. This way, all scripts and functions get their own
1089 // target stack thus avoiding illegal breaks and continues across
1090 // functions.
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001091 TargetScope scope(&this->target_stack_);
Steve Blocka7e24c12009-10-30 11:49:00 +00001092
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001093 DCHECK(processor != NULL);
Steve Block1e0659c2011-05-24 12:43:12 +01001094 bool directive_prologue = true; // Parsing directive prologue.
1095
Steve Blocka7e24c12009-10-30 11:49:00 +00001096 while (peek() != end_token) {
Steve Block1e0659c2011-05-24 12:43:12 +01001097 if (directive_prologue && peek() != Token::STRING) {
1098 directive_prologue = false;
1099 }
1100
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001101 Scanner::Location token_loc = scanner()->peek_location();
1102 Statement* stat;
1103 if (is_global && !is_eval) {
1104 stat = ParseModuleElement(NULL, CHECK_OK);
1105 } else {
1106 stat = ParseBlockElement(NULL, CHECK_OK);
1107 }
Steve Block1e0659c2011-05-24 12:43:12 +01001108 if (stat == NULL || stat->IsEmpty()) {
1109 directive_prologue = false; // End of directive prologue.
1110 continue;
1111 }
1112
1113 if (directive_prologue) {
1114 // A shot at a directive.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001115 ExpressionStatement* e_stat;
1116 Literal* literal;
Steve Block1e0659c2011-05-24 12:43:12 +01001117 // Still processing directive prologue?
1118 if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1119 (literal = e_stat->expression()->AsLiteral()) != NULL &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001120 literal->raw_value()->IsString()) {
1121 // Check "use strict" directive (ES5 14.1) and "use asm" directive. Only
1122 // one can be present.
1123 if (strict_mode() == SLOPPY &&
1124 literal->raw_value()->AsString() ==
1125 ast_value_factory()->use_strict_string() &&
Steve Block1e0659c2011-05-24 12:43:12 +01001126 token_loc.end_pos - token_loc.beg_pos ==
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001127 ast_value_factory()->use_strict_string()->length() + 2) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001128 // TODO(mstarzinger): Global strict eval calls, need their own scope
1129 // as specified in ES5 10.4.2(3). The correct fix would be to always
1130 // add this scope in DoParseProgram(), but that requires adaptations
1131 // all over the code base, so we go with a quick-fix for now.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001132 // In the same manner, we have to patch the parsing mode.
1133 if (is_eval && !scope_->is_eval_scope()) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001134 DCHECK(scope_->is_script_scope());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001135 Scope* scope = NewScope(scope_, EVAL_SCOPE);
1136 scope->set_start_position(scope_->start_position());
1137 scope->set_end_position(scope_->end_position());
1138 scope_ = scope;
1139 if (eval_scope != NULL) {
1140 // Caller will correct the positions of the ad hoc eval scope.
1141 *eval_scope = scope;
1142 }
1143 mode_ = PARSE_EAGERLY;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001144 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001145 scope_->SetStrictMode(STRICT);
Steve Block1e0659c2011-05-24 12:43:12 +01001146 // "use strict" is the only directive for now.
1147 directive_prologue = false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001148 } else if (literal->raw_value()->AsString() ==
1149 ast_value_factory()->use_asm_string() &&
1150 token_loc.end_pos - token_loc.beg_pos ==
1151 ast_value_factory()->use_asm_string()->length() + 2) {
1152 // Store the usage count; The actual use counter on the isolate is
1153 // incremented after parsing is done.
1154 ++use_counts_[v8::Isolate::kUseAsm];
1155 scope_->SetAsmModule();
Steve Block1e0659c2011-05-24 12:43:12 +01001156 }
1157 } else {
1158 // End of the directive prologue.
1159 directive_prologue = false;
1160 }
1161 }
1162
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001163 processor->Add(stat, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00001164 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001165
Steve Blocka7e24c12009-10-30 11:49:00 +00001166 return 0;
1167}
1168
1169
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001170Statement* Parser::ParseModuleElement(ZoneList<const AstRawString*>* labels,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001171 bool* ok) {
1172 // (Ecma 262 5th Edition, clause 14):
1173 // SourceElement:
1174 // Statement
1175 // FunctionDeclaration
1176 //
1177 // In harmony mode we allow additionally the following productions
1178 // ModuleElement:
1179 // LetDeclaration
1180 // ConstDeclaration
1181 // ModuleDeclaration
1182 // ImportDeclaration
1183 // ExportDeclaration
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001184 // GeneratorDeclaration
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001185
1186 switch (peek()) {
1187 case Token::FUNCTION:
1188 return ParseFunctionDeclaration(NULL, ok);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001189 case Token::CLASS:
1190 return ParseClassDeclaration(NULL, ok);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001191 case Token::IMPORT:
1192 return ParseImportDeclaration(ok);
1193 case Token::EXPORT:
1194 return ParseExportDeclaration(ok);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001195 case Token::CONST:
1196 return ParseVariableStatement(kModuleElement, NULL, ok);
1197 case Token::LET:
1198 DCHECK(allow_harmony_scoping());
1199 if (strict_mode() == STRICT) {
1200 return ParseVariableStatement(kModuleElement, NULL, ok);
1201 }
1202 // Fall through.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001203 default: {
1204 Statement* stmt = ParseStatement(labels, CHECK_OK);
1205 // Handle 'module' as a context-sensitive keyword.
1206 if (FLAG_harmony_modules &&
1207 peek() == Token::IDENTIFIER &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001208 !scanner()->HasAnyLineTerminatorBeforeNext() &&
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001209 stmt != NULL) {
1210 ExpressionStatement* estmt = stmt->AsExpressionStatement();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001211 if (estmt != NULL && estmt->expression()->AsVariableProxy() != NULL &&
1212 estmt->expression()->AsVariableProxy()->raw_name() ==
1213 ast_value_factory()->module_string() &&
1214 !scanner()->literal_contains_escapes()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001215 return ParseModuleDeclaration(NULL, ok);
1216 }
1217 }
1218 return stmt;
1219 }
1220 }
1221}
1222
1223
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001224Statement* Parser::ParseModuleDeclaration(ZoneList<const AstRawString*>* names,
1225 bool* ok) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001226 // ModuleDeclaration:
1227 // 'module' Identifier Module
1228
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001229 int pos = peek_position();
1230 const AstRawString* name =
1231 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001232
1233#ifdef DEBUG
1234 if (FLAG_print_interface_details)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001235 PrintF("# Module %.*s ", name->length(), name->raw_data());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001236#endif
1237
1238 Module* module = ParseModule(CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001239 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001240 Declaration* declaration =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001241 factory()->NewModuleDeclaration(proxy, module, scope_, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001242 Declare(declaration, true, CHECK_OK);
1243
1244#ifdef DEBUG
1245 if (FLAG_print_interface_details)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001246 PrintF("# Module %.*s ", name->length(), name->raw_data());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001247 if (FLAG_print_interfaces) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001248 PrintF("module %.*s: ", name->length(), name->raw_data());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001249 module->interface()->Print();
1250 }
1251#endif
1252
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001253 if (names) names->Add(name, zone());
1254 if (module->body() == NULL)
1255 return factory()->NewEmptyStatement(pos);
1256 else
1257 return factory()->NewModuleStatement(proxy, module->body(), pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001258}
1259
1260
1261Module* Parser::ParseModule(bool* ok) {
1262 // Module:
1263 // '{' ModuleElement '}'
1264 // '=' ModulePath ';'
1265 // 'at' String ';'
1266
1267 switch (peek()) {
1268 case Token::LBRACE:
1269 return ParseModuleLiteral(ok);
1270
1271 case Token::ASSIGN: {
1272 Expect(Token::ASSIGN, CHECK_OK);
1273 Module* result = ParseModulePath(CHECK_OK);
1274 ExpectSemicolon(CHECK_OK);
1275 return result;
1276 }
1277
1278 default: {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001279 ExpectContextualKeyword(CStrVector("at"), CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001280 Module* result = ParseModuleUrl(CHECK_OK);
1281 ExpectSemicolon(CHECK_OK);
1282 return result;
1283 }
1284 }
1285}
1286
1287
1288Module* Parser::ParseModuleLiteral(bool* ok) {
1289 // Module:
1290 // '{' ModuleElement '}'
1291
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001292 int pos = peek_position();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001293 // Construct block expecting 16 statements.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001294 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001295#ifdef DEBUG
1296 if (FLAG_print_interface_details) PrintF("# Literal ");
1297#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001298 Scope* scope = NewScope(scope_, MODULE_SCOPE);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001299
1300 Expect(Token::LBRACE, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001301 scope->set_start_position(scanner()->location().beg_pos);
1302 scope->SetStrictMode(STRICT);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001303
1304 {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001305 BlockState block_state(&scope_, scope);
1306 TargetCollector collector(zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001307 Target target(&this->target_stack_, &collector);
1308 Target target_body(&this->target_stack_, body);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001309
1310 while (peek() != Token::RBRACE) {
1311 Statement* stat = ParseModuleElement(NULL, CHECK_OK);
1312 if (stat && !stat->IsEmpty()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001313 body->AddStatement(stat, zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001314 }
1315 }
1316 }
1317
1318 Expect(Token::RBRACE, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001319 scope->set_end_position(scanner()->location().end_pos);
1320 body->set_scope(scope);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001321
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001322 // Check that all exports are bound.
1323 Interface* interface = scope->interface();
1324 for (Interface::Iterator it = interface->iterator();
1325 !it.done(); it.Advance()) {
1326 if (scope->LookupLocal(it.name()) == NULL) {
1327 ParserTraits::ReportMessage("module_export_undefined", it.name());
1328 *ok = false;
1329 return NULL;
1330 }
1331 }
1332
1333 interface->MakeModule(ok);
1334 DCHECK(*ok);
1335 interface->Freeze(ok);
1336 DCHECK(*ok);
1337 return factory()->NewModuleLiteral(body, interface, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001338}
1339
1340
1341Module* Parser::ParseModulePath(bool* ok) {
1342 // ModulePath:
1343 // Identifier
1344 // ModulePath '.' Identifier
1345
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001346 int pos = peek_position();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001347 Module* result = ParseModuleVariable(CHECK_OK);
1348 while (Check(Token::PERIOD)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001349 const AstRawString* name = ParseIdentifierName(CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001350#ifdef DEBUG
1351 if (FLAG_print_interface_details)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001352 PrintF("# Path .%.*s ", name->length(), name->raw_data());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001353#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001354 Module* member = factory()->NewModulePath(result, name, pos);
1355 result->interface()->Add(name, member->interface(), zone(), ok);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001356 if (!*ok) {
1357#ifdef DEBUG
1358 if (FLAG_print_interfaces) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001359 PrintF("PATH TYPE ERROR at '%.*s'\n", name->length(), name->raw_data());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001360 PrintF("result: ");
1361 result->interface()->Print();
1362 PrintF("member: ");
1363 member->interface()->Print();
1364 }
1365#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001366 ParserTraits::ReportMessage("invalid_module_path", name);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001367 return NULL;
1368 }
1369 result = member;
1370 }
1371
1372 return result;
1373}
1374
1375
1376Module* Parser::ParseModuleVariable(bool* ok) {
1377 // ModulePath:
1378 // Identifier
1379
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001380 int pos = peek_position();
1381 const AstRawString* name =
1382 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001383#ifdef DEBUG
1384 if (FLAG_print_interface_details)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001385 PrintF("# Module variable %.*s ", name->length(), name->raw_data());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001386#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001387 VariableProxy* proxy = scope_->NewUnresolved(
1388 factory(), name, Interface::NewModule(zone()),
1389 scanner()->location().beg_pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001390
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001391 return factory()->NewModuleVariable(proxy, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001392}
1393
1394
1395Module* Parser::ParseModuleUrl(bool* ok) {
1396 // Module:
1397 // String
1398
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001399 int pos = peek_position();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001400 Expect(Token::STRING, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001401 const AstRawString* symbol = GetSymbol(scanner());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001402
1403 // TODO(ES6): Request JS resource from environment...
1404
1405#ifdef DEBUG
1406 if (FLAG_print_interface_details) PrintF("# Url ");
1407#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001408
1409 // Create an empty literal as long as the feature isn't finished.
1410 USE(symbol);
1411 Scope* scope = NewScope(scope_, MODULE_SCOPE);
1412 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
1413 body->set_scope(scope);
1414 Interface* interface = scope->interface();
1415 Module* result = factory()->NewModuleLiteral(body, interface, pos);
1416 interface->Freeze(ok);
1417 DCHECK(*ok);
1418 interface->Unify(scope->interface(), zone(), ok);
1419 DCHECK(*ok);
1420 return result;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001421}
1422
1423
1424Module* Parser::ParseModuleSpecifier(bool* ok) {
1425 // ModuleSpecifier:
1426 // String
1427 // ModulePath
1428
1429 if (peek() == Token::STRING) {
1430 return ParseModuleUrl(ok);
1431 } else {
1432 return ParseModulePath(ok);
1433 }
1434}
1435
1436
1437Block* Parser::ParseImportDeclaration(bool* ok) {
1438 // ImportDeclaration:
1439 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';'
1440 //
1441 // TODO(ES6): implement destructuring ImportSpecifiers
1442
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001443 int pos = peek_position();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001444 Expect(Token::IMPORT, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001445 ZoneList<const AstRawString*> names(1, zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001446
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001447 const AstRawString* name = ParseIdentifierName(CHECK_OK);
1448 names.Add(name, zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001449 while (peek() == Token::COMMA) {
1450 Consume(Token::COMMA);
1451 name = ParseIdentifierName(CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001452 names.Add(name, zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001453 }
1454
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001455 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001456 Module* module = ParseModuleSpecifier(CHECK_OK);
1457 ExpectSemicolon(CHECK_OK);
1458
1459 // Generate a separate declaration for each identifier.
1460 // TODO(ES6): once we implement destructuring, make that one declaration.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001461 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001462 for (int i = 0; i < names.length(); ++i) {
1463#ifdef DEBUG
1464 if (FLAG_print_interface_details)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001465 PrintF("# Import %.*s ", name->length(), name->raw_data());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001466#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001467 Interface* interface = Interface::NewUnknown(zone());
1468 module->interface()->Add(names[i], interface, zone(), ok);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001469 if (!*ok) {
1470#ifdef DEBUG
1471 if (FLAG_print_interfaces) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001472 PrintF("IMPORT TYPE ERROR at '%.*s'\n", name->length(),
1473 name->raw_data());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001474 PrintF("module: ");
1475 module->interface()->Print();
1476 }
1477#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001478 ParserTraits::ReportMessage("invalid_module_path", name);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001479 return NULL;
1480 }
1481 VariableProxy* proxy = NewUnresolved(names[i], LET, interface);
1482 Declaration* declaration =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001483 factory()->NewImportDeclaration(proxy, module, scope_, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001484 Declare(declaration, true, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001485 }
1486
1487 return block;
1488}
1489
1490
1491Statement* Parser::ParseExportDeclaration(bool* ok) {
1492 // ExportDeclaration:
1493 // 'export' Identifier (',' Identifier)* ';'
1494 // 'export' VariableDeclaration
1495 // 'export' FunctionDeclaration
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001496 // 'export' GeneratorDeclaration
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001497 // 'export' ModuleDeclaration
1498 //
1499 // TODO(ES6): implement structuring ExportSpecifiers
1500
1501 Expect(Token::EXPORT, CHECK_OK);
1502
1503 Statement* result = NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001504 ZoneList<const AstRawString*> names(1, zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001505 switch (peek()) {
1506 case Token::IDENTIFIER: {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001507 int pos = position();
1508 const AstRawString* name =
1509 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001510 // Handle 'module' as a context-sensitive keyword.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001511 if (name != ast_value_factory()->module_string()) {
1512 names.Add(name, zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001513 while (peek() == Token::COMMA) {
1514 Consume(Token::COMMA);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001515 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1516 names.Add(name, zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001517 }
1518 ExpectSemicolon(CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001519 result = factory()->NewEmptyStatement(pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001520 } else {
1521 result = ParseModuleDeclaration(&names, CHECK_OK);
1522 }
1523 break;
1524 }
1525
1526 case Token::FUNCTION:
1527 result = ParseFunctionDeclaration(&names, CHECK_OK);
1528 break;
1529
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001530 case Token::CLASS:
1531 result = ParseClassDeclaration(&names, CHECK_OK);
1532 break;
1533
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001534 case Token::VAR:
1535 case Token::LET:
1536 case Token::CONST:
1537 result = ParseVariableStatement(kModuleElement, &names, CHECK_OK);
1538 break;
1539
1540 default:
1541 *ok = false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001542 ReportUnexpectedToken(scanner()->current_token());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001543 return NULL;
1544 }
1545
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001546 // Every export of a module may be assigned.
1547 for (int i = 0; i < names.length(); ++i) {
1548 Variable* var = scope_->Lookup(names[i]);
1549 if (var == NULL) {
1550 // TODO(sigurds) This is an export that has no definition yet,
1551 // not clear what to do in this case.
1552 continue;
1553 }
1554 if (!IsImmutableVariableMode(var->mode())) {
1555 var->set_maybe_assigned();
1556 }
1557 }
1558
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001559 // Extract declared names into export declarations and interface.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001560 Interface* interface = scope_->interface();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001561 for (int i = 0; i < names.length(); ++i) {
1562#ifdef DEBUG
1563 if (FLAG_print_interface_details)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001564 PrintF("# Export %.*s ", names[i]->length(), names[i]->raw_data());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001565#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001566 Interface* inner = Interface::NewUnknown(zone());
1567 interface->Add(names[i], inner, zone(), CHECK_OK);
1568 if (!*ok)
1569 return NULL;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001570 VariableProxy* proxy = NewUnresolved(names[i], LET, inner);
1571 USE(proxy);
1572 // TODO(rossberg): Rethink whether we actually need to store export
1573 // declarations (for compilation?).
1574 // ExportDeclaration* declaration =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001575 // factory()->NewExportDeclaration(proxy, scope_, position);
1576 // scope_->AddDeclaration(declaration);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001577 }
1578
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001579 DCHECK(result != NULL);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001580 return result;
1581}
1582
1583
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001584Statement* Parser::ParseBlockElement(ZoneList<const AstRawString*>* labels,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001585 bool* ok) {
1586 // (Ecma 262 5th Edition, clause 14):
1587 // SourceElement:
1588 // Statement
1589 // FunctionDeclaration
1590 //
1591 // In harmony mode we allow additionally the following productions
1592 // BlockElement (aka SourceElement):
1593 // LetDeclaration
1594 // ConstDeclaration
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001595 // GeneratorDeclaration
1596 // ClassDeclaration
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001597
1598 switch (peek()) {
1599 case Token::FUNCTION:
1600 return ParseFunctionDeclaration(NULL, ok);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001601 case Token::CLASS:
1602 return ParseClassDeclaration(NULL, ok);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001603 case Token::CONST:
1604 return ParseVariableStatement(kModuleElement, NULL, ok);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001605 case Token::LET:
1606 DCHECK(allow_harmony_scoping());
1607 if (strict_mode() == STRICT) {
1608 return ParseVariableStatement(kModuleElement, NULL, ok);
1609 }
1610 // Fall through.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001611 default:
1612 return ParseStatement(labels, ok);
1613 }
1614}
1615
1616
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001617Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels,
1618 bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001619 // Statement ::
1620 // Block
1621 // VariableStatement
1622 // EmptyStatement
1623 // ExpressionStatement
1624 // IfStatement
1625 // IterationStatement
1626 // ContinueStatement
1627 // BreakStatement
1628 // ReturnStatement
1629 // WithStatement
1630 // LabelledStatement
1631 // SwitchStatement
1632 // ThrowStatement
1633 // TryStatement
1634 // DebuggerStatement
1635
1636 // Note: Since labels can only be used by 'break' and 'continue'
1637 // statements, which themselves are only valid within blocks,
1638 // iterations or 'switch' statements (i.e., BreakableStatements),
1639 // labels can be simply ignored in all other cases; except for
1640 // trivial labeled break statements 'label: break label' which is
1641 // parsed into an empty statement.
Steve Blocka7e24c12009-10-30 11:49:00 +00001642 switch (peek()) {
1643 case Token::LBRACE:
1644 return ParseBlock(labels, ok);
1645
Steve Blocka7e24c12009-10-30 11:49:00 +00001646 case Token::SEMICOLON:
1647 Next();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001648 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
Steve Blocka7e24c12009-10-30 11:49:00 +00001649
1650 case Token::IF:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001651 return ParseIfStatement(labels, ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001652
1653 case Token::DO:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001654 return ParseDoWhileStatement(labels, ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001655
1656 case Token::WHILE:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001657 return ParseWhileStatement(labels, ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001658
1659 case Token::FOR:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001660 return ParseForStatement(labels, ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001661
1662 case Token::CONTINUE:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001663 return ParseContinueStatement(ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001664
1665 case Token::BREAK:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001666 return ParseBreakStatement(labels, ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001667
1668 case Token::RETURN:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001669 return ParseReturnStatement(ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001670
1671 case Token::WITH:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001672 return ParseWithStatement(labels, ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001673
1674 case Token::SWITCH:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001675 return ParseSwitchStatement(labels, ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001676
1677 case Token::THROW:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001678 return ParseThrowStatement(ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001679
1680 case Token::TRY: {
1681 // NOTE: It is somewhat complicated to have labels on
1682 // try-statements. When breaking out of a try-finally statement,
1683 // one must take great care not to treat it as a
1684 // fall-through. It is much easier just to wrap the entire
1685 // try-statement in a statement block and put the labels there
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001686 Block* result =
1687 factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001688 Target target(&this->target_stack_, result);
Steve Blocka7e24c12009-10-30 11:49:00 +00001689 TryStatement* statement = ParseTryStatement(CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001690 if (result) result->AddStatement(statement, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00001691 return result;
1692 }
1693
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001694 case Token::FUNCTION: {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001695 // FunctionDeclaration is only allowed in the context of SourceElements
1696 // (Ecma 262 5th Edition, clause 14):
1697 // SourceElement:
1698 // Statement
1699 // FunctionDeclaration
1700 // Common language extension is to allow function declaration in place
1701 // of any statement. This language extension is disabled in strict mode.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001702 //
1703 // In Harmony mode, this case also handles the extension:
1704 // Statement:
1705 // GeneratorDeclaration
1706 if (strict_mode() == STRICT) {
1707 ReportMessageAt(scanner()->peek_location(), "strict_function");
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001708 *ok = false;
1709 return NULL;
1710 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001711 return ParseFunctionDeclaration(NULL, ok);
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001712 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001713
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001714 case Token::CLASS:
1715 return ParseClassDeclaration(NULL, ok);
1716
Steve Blocka7e24c12009-10-30 11:49:00 +00001717 case Token::DEBUGGER:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001718 return ParseDebuggerStatement(ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001719
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001720 case Token::VAR:
1721 case Token::CONST:
1722 return ParseVariableStatement(kStatement, NULL, ok);
1723
1724 case Token::LET:
1725 DCHECK(allow_harmony_scoping());
1726 if (strict_mode() == STRICT) {
1727 return ParseVariableStatement(kStatement, NULL, ok);
1728 }
1729 // Fall through.
Steve Blocka7e24c12009-10-30 11:49:00 +00001730 default:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001731 return ParseExpressionOrLabelledStatement(labels, ok);
Steve Blocka7e24c12009-10-30 11:49:00 +00001732 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001733}
1734
1735
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001736VariableProxy* Parser::NewUnresolved(const AstRawString* name,
1737 VariableMode mode, Interface* interface) {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001738 // If we are inside a function, a declaration of a var/const variable is a
1739 // truly local variable, and the scope of the variable is always the function
1740 // scope.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001741 // Let/const variables in harmony mode are always added to the immediately
1742 // enclosing scope.
1743 return DeclarationScope(mode)->NewUnresolved(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001744 factory(), name, interface, position());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001745}
1746
1747
1748void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
1749 VariableProxy* proxy = declaration->proxy();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001750 DCHECK(proxy->raw_name() != NULL);
1751 const AstRawString* name = proxy->raw_name();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001752 VariableMode mode = declaration->mode();
1753 Scope* declaration_scope = DeclarationScope(mode);
1754 Variable* var = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00001755
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001756 // If a suitable scope exists, then we can statically declare this
Steve Blocka7e24c12009-10-30 11:49:00 +00001757 // variable and also set its mode. In any case, a Declaration node
1758 // will be added to the scope so that the declaration can be added
1759 // to the corresponding activation frame at runtime if necessary.
1760 // For instance declarations inside an eval scope need to be added
1761 // to the calling function context.
Ben Murdoch257744e2011-11-30 15:57:28 +00001762 // Similarly, strict mode eval scope does not leak variable declarations to
1763 // the caller's scope so we declare all locals, too.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001764 if (declaration_scope->is_function_scope() ||
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001765 declaration_scope->is_strict_eval_scope() ||
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001766 declaration_scope->is_block_scope() ||
1767 declaration_scope->is_module_scope() ||
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001768 declaration_scope->is_script_scope()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001769 // Declare the variable in the declaration scope.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001770 var = declaration_scope->LookupLocal(name);
Steve Blocka7e24c12009-10-30 11:49:00 +00001771 if (var == NULL) {
1772 // Declare the name.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001773 var = declaration_scope->DeclareLocal(name, mode,
1774 declaration->initialization(),
1775 kNotAssigned, proxy->interface());
1776 } else if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode())
1777 || ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) &&
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001778 !declaration_scope->is_script_scope())) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001779 // The name was declared in this scope before; check for conflicting
1780 // re-declarations. We have a conflict if either of the declarations is
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001781 // not a var (in script scope, we also have to ignore legacy const for
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001782 // compatibility). There is similar code in runtime.cc in the Declare
1783 // functions. The function CheckConflictingVarDeclarations checks for
Ben Murdoch589d6972011-11-30 16:04:58 +00001784 // var and let bindings from different scopes whereas this is a check for
1785 // conflicting declarations within the same scope. This check also covers
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001786 // the special case
Ben Murdoch589d6972011-11-30 16:04:58 +00001787 //
1788 // function () { let x; { var x; } }
1789 //
1790 // because the var declaration is hoisted to the function scope where 'x'
1791 // is already bound.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001792 DCHECK(IsDeclaredVariableMode(var->mode()));
1793 if (allow_harmony_scoping() && strict_mode() == STRICT) {
1794 // In harmony we treat re-declarations as early errors. See
1795 // ES5 16 for a definition of early errors.
1796 ParserTraits::ReportMessage("var_redeclaration", name);
1797 *ok = false;
1798 return;
Steve Blocka7e24c12009-10-30 11:49:00 +00001799 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001800 Expression* expression = NewThrowTypeError(
1801 "var_redeclaration", name, declaration->position());
1802 declaration_scope->SetIllegalRedeclaration(expression);
1803 } else if (mode == VAR) {
1804 var->set_maybe_assigned();
Steve Blocka7e24c12009-10-30 11:49:00 +00001805 }
1806 }
1807
1808 // We add a declaration node for every declaration. The compiler
1809 // will only generate code if necessary. In particular, declarations
1810 // for inner local variables that do not represent functions won't
1811 // result in any generated code.
1812 //
1813 // Note that we always add an unresolved proxy even if it's not
1814 // used, simply because we don't know in this method (w/o extra
1815 // parameters) if the proxy is needed or not. The proxy will be
1816 // bound during variable resolution time unless it was pre-bound
1817 // below.
1818 //
1819 // WARNING: This will lead to multiple declaration nodes for the
1820 // same variable if it is declared several times. This is not a
1821 // semantic issue as long as we keep the source order, but it may be
1822 // a performance issue since it may lead to repeated
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001823 // RuntimeHidden_DeclareLookupSlot calls.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001824 declaration_scope->AddDeclaration(declaration);
Steve Blocka7e24c12009-10-30 11:49:00 +00001825
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001826 if (mode == CONST_LEGACY && declaration_scope->is_script_scope()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001827 // For global const variables we bind the proxy to a variable.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001828 DCHECK(resolve); // should be set by all callers
Steve Blocka7e24c12009-10-30 11:49:00 +00001829 Variable::Kind kind = Variable::NORMAL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001830 var = new (zone())
1831 Variable(declaration_scope, name, mode, true, kind,
1832 kNeedsInitialization, kNotAssigned, proxy->interface());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001833 } else if (declaration_scope->is_eval_scope() &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001834 declaration_scope->strict_mode() == SLOPPY) {
1835 // For variable declarations in a sloppy eval scope the proxy is bound
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001836 // to a lookup variable to force a dynamic declaration using the
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001837 // DeclareLookupSlot runtime function.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001838 Variable::Kind kind = Variable::NORMAL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001839 // TODO(sigurds) figure out if kNotAssigned is OK here
1840 var = new (zone()) Variable(declaration_scope, name, mode, true, kind,
1841 declaration->initialization(), kNotAssigned,
1842 proxy->interface());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001843 var->AllocateTo(Variable::LOOKUP, -1);
1844 resolve = true;
Steve Blocka7e24c12009-10-30 11:49:00 +00001845 }
1846
1847 // If requested and we have a local variable, bind the proxy to the variable
1848 // at parse-time. This is used for functions (and consts) declared inside
1849 // statements: the corresponding function (or const) variable must be in the
1850 // function scope and not a statement-local scope, e.g. as provided with a
1851 // 'with' statement:
1852 //
1853 // with (obj) {
1854 // function f() {}
1855 // }
1856 //
1857 // which is translated into:
1858 //
1859 // with (obj) {
1860 // // in this case this is not: 'var f; f = function () {};'
1861 // var f = function () {};
1862 // }
1863 //
1864 // Note that if 'f' is accessed from inside the 'with' statement, it
1865 // will be allocated in the context (because we must be able to look
1866 // it up dynamically) but it will also be accessed statically, i.e.,
1867 // with a context slot index and a context chain length for this
1868 // initialization code. Thus, inside the 'with' statement, we need
1869 // both access to the static and the dynamic context chain; the
1870 // runtime needs to provide both.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001871 if (resolve && var != NULL) {
1872 proxy->BindTo(var);
Steve Blocka7e24c12009-10-30 11:49:00 +00001873
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001874 if (FLAG_harmony_modules) {
1875 bool ok;
1876#ifdef DEBUG
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001877 if (FLAG_print_interface_details) {
1878 PrintF("# Declare %.*s ", var->raw_name()->length(),
1879 var->raw_name()->raw_data());
1880 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001881#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001882 proxy->interface()->Unify(var->interface(), zone(), &ok);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001883 if (!ok) {
1884#ifdef DEBUG
1885 if (FLAG_print_interfaces) {
1886 PrintF("DECLARE TYPE ERROR\n");
1887 PrintF("proxy: ");
1888 proxy->interface()->Print();
1889 PrintF("var: ");
1890 var->interface()->Print();
1891 }
1892#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001893 ParserTraits::ReportMessage("module_type_error", name);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001894 }
1895 }
1896 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001897}
1898
1899
1900// Language extension which is only enabled for source files loaded
1901// through the API's extension mechanism. A native function
1902// declaration is resolved by looking up the function through a
1903// callback provided by the extension.
1904Statement* Parser::ParseNativeDeclaration(bool* ok) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001905 int pos = peek_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00001906 Expect(Token::FUNCTION, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001907 // Allow "eval" or "arguments" for backward compatibility.
1908 const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00001909 Expect(Token::LPAREN, CHECK_OK);
1910 bool done = (peek() == Token::RPAREN);
1911 while (!done) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001912 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00001913 done = (peek() == Token::RPAREN);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001914 if (!done) {
1915 Expect(Token::COMMA, CHECK_OK);
1916 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001917 }
1918 Expect(Token::RPAREN, CHECK_OK);
1919 Expect(Token::SEMICOLON, CHECK_OK);
1920
Steve Blocka7e24c12009-10-30 11:49:00 +00001921 // Make sure that the function containing the native declaration
1922 // isn't lazily compiled. The extension structures are only
1923 // accessible while parsing the first time not when reparsing
1924 // because of lazy compilation.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001925 DeclarationScope(VAR)->ForceEagerCompilation();
Steve Blocka7e24c12009-10-30 11:49:00 +00001926
Steve Blocka7e24c12009-10-30 11:49:00 +00001927 // TODO(1240846): It's weird that native function declarations are
1928 // introduced dynamically when we meet their declarations, whereas
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001929 // other functions are set up when entering the surrounding scope.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001930 VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001931 Declaration* declaration =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001932 factory()->NewVariableDeclaration(proxy, VAR, scope_, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001933 Declare(declaration, true, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001934 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral(
1935 name, extension_, RelocInfo::kNoPosition);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001936 return factory()->NewExpressionStatement(
1937 factory()->NewAssignment(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001938 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition),
1939 pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00001940}
1941
1942
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001943Statement* Parser::ParseFunctionDeclaration(
1944 ZoneList<const AstRawString*>* names, bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001945 // FunctionDeclaration ::
1946 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001947 // GeneratorDeclaration ::
1948 // 'function' '*' Identifier '(' FormalParameterListopt ')'
1949 // '{' FunctionBody '}'
Steve Blocka7e24c12009-10-30 11:49:00 +00001950 Expect(Token::FUNCTION, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001951 int pos = position();
1952 bool is_generator = Check(Token::MUL);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001953 bool is_strict_reserved = false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001954 const AstRawString* name = ParseIdentifierOrStrictReservedWord(
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001955 &is_strict_reserved, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001956 FunctionLiteral* fun =
1957 ParseFunctionLiteral(name, scanner()->location(), is_strict_reserved,
1958 is_generator ? FunctionKind::kGeneratorFunction
1959 : FunctionKind::kNormalFunction,
1960 pos, FunctionLiteral::DECLARATION,
1961 FunctionLiteral::NORMAL_ARITY, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00001962 // Even if we're not at the top-level of the global or a function
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001963 // scope, we treat it as such and introduce the function with its
Steve Blocka7e24c12009-10-30 11:49:00 +00001964 // initial value upon entering the corresponding scope.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001965 // In ES6, a function behaves as a lexical binding, except in
1966 // a script scope, or the initial scope of eval or another function.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001967 VariableMode mode =
1968 allow_harmony_scoping() && strict_mode() == STRICT &&
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001969 !(scope_->is_script_scope() || scope_->is_eval_scope() ||
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001970 scope_->is_function_scope()) ? LET : VAR;
1971 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001972 Declaration* declaration =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001973 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001974 Declare(declaration, true, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001975 if (names) names->Add(name, zone());
1976 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
Steve Blocka7e24c12009-10-30 11:49:00 +00001977}
1978
1979
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001980Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
1981 bool* ok) {
1982 // ClassDeclaration ::
1983 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
1984 //
1985 // A ClassDeclaration
1986 //
1987 // class C { ... }
1988 //
1989 // has the same semantics as:
1990 //
1991 // let C = class C { ... };
1992 //
1993 // so rewrite it as such.
1994
1995 Expect(Token::CLASS, CHECK_OK);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001996 if (!allow_harmony_sloppy() && strict_mode() == SLOPPY) {
1997 ReportMessage("sloppy_lexical");
1998 *ok = false;
1999 return NULL;
2000 }
2001
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002002 int pos = position();
2003 bool is_strict_reserved = false;
2004 const AstRawString* name =
2005 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002006 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(),
2007 is_strict_reserved, pos, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002008
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002009 VariableProxy* proxy = NewUnresolved(name, LET, Interface::NewValue());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002010 Declaration* declaration =
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002011 factory()->NewVariableDeclaration(proxy, LET, scope_, pos);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002012 Declare(declaration, true, CHECK_OK);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002013 proxy->var()->set_initializer_position(pos);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002014
2015 Token::Value init_op = Token::INIT_LET;
2016 Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002017 Statement* assignment_statement =
2018 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002019 if (names) names->Add(name, zone());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002020 return assignment_statement;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002021}
2022
2023
2024Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) {
2025 if (allow_harmony_scoping() && strict_mode() == STRICT) {
2026 return ParseScopedBlock(labels, ok);
2027 }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002028
Steve Blocka7e24c12009-10-30 11:49:00 +00002029 // Block ::
2030 // '{' Statement* '}'
2031
2032 // Note that a Block does not introduce a new execution scope!
2033 // (ECMA-262, 3rd, 12.2)
2034 //
2035 // Construct block expecting 16 statements.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002036 Block* result =
2037 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002038 Target target(&this->target_stack_, result);
Steve Blocka7e24c12009-10-30 11:49:00 +00002039 Expect(Token::LBRACE, CHECK_OK);
2040 while (peek() != Token::RBRACE) {
2041 Statement* stat = ParseStatement(NULL, CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002042 if (stat && !stat->IsEmpty()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002043 result->AddStatement(stat, zone());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002044 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002045 }
2046 Expect(Token::RBRACE, CHECK_OK);
2047 return result;
2048}
2049
2050
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002051Block* Parser::ParseScopedBlock(ZoneList<const AstRawString*>* labels,
2052 bool* ok) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002053 // The harmony mode uses block elements instead of statements.
2054 //
2055 // Block ::
2056 // '{' BlockElement* '}'
2057
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002058 // Construct block expecting 16 statements.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002059 Block* body =
2060 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2061 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002062
2063 // Parse the statements and collect escaping labels.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002064 Expect(Token::LBRACE, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002065 block_scope->set_start_position(scanner()->location().beg_pos);
2066 { BlockState block_state(&scope_, block_scope);
2067 TargetCollector collector(zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002068 Target target(&this->target_stack_, &collector);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002069 Target target_body(&this->target_stack_, body);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002070
2071 while (peek() != Token::RBRACE) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002072 Statement* stat = ParseBlockElement(NULL, CHECK_OK);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002073 if (stat && !stat->IsEmpty()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002074 body->AddStatement(stat, zone());
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002075 }
2076 }
2077 }
2078 Expect(Token::RBRACE, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002079 block_scope->set_end_position(scanner()->location().end_pos);
Ben Murdoch589d6972011-11-30 16:04:58 +00002080 block_scope = block_scope->FinalizeBlockScope();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002081 body->set_scope(block_scope);
Ben Murdoch589d6972011-11-30 16:04:58 +00002082 return body;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002083}
2084
2085
2086Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002087 ZoneList<const AstRawString*>* names,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002088 bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002089 // VariableStatement ::
2090 // VariableDeclarations ';'
2091
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002092 const AstRawString* ignore;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002093 Block* result =
2094 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00002095 ExpectSemicolon(CHECK_OK);
2096 return result;
2097}
2098
Steve Block44f0eee2011-05-26 01:26:41 +01002099
Steve Blocka7e24c12009-10-30 11:49:00 +00002100// If the variable declaration declares exactly one non-const
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002101// variable, then *out is set to that variable. In all other cases,
2102// *out is untouched; in particular, it is the caller's responsibility
Steve Blocka7e24c12009-10-30 11:49:00 +00002103// to initialize it properly. This mechanism is used for the parsing
2104// of 'for-in' loops.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002105Block* Parser::ParseVariableDeclarations(
2106 VariableDeclarationContext var_context,
2107 VariableDeclarationProperties* decl_props,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002108 ZoneList<const AstRawString*>* names,
2109 const AstRawString** out,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002110 bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002111 // VariableDeclarations ::
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002112 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
2113 //
2114 // The ES6 Draft Rev3 specifies the following grammar for const declarations
2115 //
2116 // ConstDeclaration ::
2117 // const ConstBinding (',' ConstBinding)* ';'
2118 // ConstBinding ::
2119 // Identifier '=' AssignmentExpression
2120 //
2121 // TODO(ES6):
2122 // ConstBinding ::
2123 // BindingPattern '=' AssignmentExpression
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002124
2125 int pos = peek_position();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002126 VariableMode mode = VAR;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002127 // True if the binding needs initialization. 'let' and 'const' declared
2128 // bindings are created uninitialized by their declaration nodes and
2129 // need initialization. 'var' declared bindings are always initialized
2130 // immediately by their declaration nodes.
2131 bool needs_init = false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002132 bool is_const = false;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002133 Token::Value init_op = Token::INIT_VAR;
Steve Blocka7e24c12009-10-30 11:49:00 +00002134 if (peek() == Token::VAR) {
2135 Consume(Token::VAR);
2136 } else if (peek() == Token::CONST) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002137 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
2138 //
2139 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
2140 //
2141 // * It is a Syntax Error if the code that matches this production is not
2142 // contained in extended code.
2143 //
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002144 // However disallowing const in sloppy mode will break compatibility with
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002145 // existing pages. Therefore we keep allowing const with the old
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002146 // non-harmony semantics in sloppy mode.
Steve Blocka7e24c12009-10-30 11:49:00 +00002147 Consume(Token::CONST);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002148 switch (strict_mode()) {
2149 case SLOPPY:
2150 mode = CONST_LEGACY;
2151 init_op = Token::INIT_CONST_LEGACY;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002152 break;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002153 case STRICT:
2154 if (allow_harmony_scoping()) {
2155 if (var_context == kStatement) {
2156 // In strict mode 'const' declarations are only allowed in source
2157 // element positions.
2158 ReportMessage("unprotected_const");
2159 *ok = false;
2160 return NULL;
2161 }
2162 mode = CONST;
2163 init_op = Token::INIT_CONST;
2164 } else {
2165 ReportMessage("strict_const");
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002166 *ok = false;
2167 return NULL;
2168 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002169 }
2170 is_const = true;
2171 needs_init = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002172 } else if (peek() == Token::LET && strict_mode() == STRICT) {
2173 DCHECK(allow_harmony_scoping());
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002174 Consume(Token::LET);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002175 if (var_context == kStatement) {
2176 // Let declarations are only allowed in source element positions.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002177 ReportMessage("unprotected_let");
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002178 *ok = false;
2179 return NULL;
2180 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002181 mode = LET;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002182 needs_init = true;
2183 init_op = Token::INIT_LET;
Steve Blocka7e24c12009-10-30 11:49:00 +00002184 } else {
2185 UNREACHABLE(); // by current callers
2186 }
2187
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002188 Scope* declaration_scope = DeclarationScope(mode);
2189
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002190 // The scope of a var/const declared variable anywhere inside a function
Steve Blocka7e24c12009-10-30 11:49:00 +00002191 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002192 // transform a source-level var/const declaration into a (Function)
Steve Blocka7e24c12009-10-30 11:49:00 +00002193 // Scope declaration, and rewrite the source-level initialization into an
2194 // assignment statement. We use a block to collect multiple assignments.
2195 //
2196 // We mark the block as initializer block because we don't want the
2197 // rewriter to add a '.result' assignment to such a block (to get compliant
2198 // behavior for code such as print(eval('var x = 7')), and for cosmetic
2199 // reasons when pretty-printing. Also, unless an assignment (initialization)
2200 // is inside an initializer block, it is ignored.
2201 //
2202 // Create new block with one expected declaration.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002203 Block* block = factory()->NewBlock(NULL, 1, true, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002204 int nvars = 0; // the number of variables declared
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002205 const AstRawString* name = NULL;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002206 bool is_for_iteration_variable;
Steve Blocka7e24c12009-10-30 11:49:00 +00002207 do {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002208 if (fni_ != NULL) fni_->Enter();
2209
Steve Blocka7e24c12009-10-30 11:49:00 +00002210 // Parse variable name.
2211 if (nvars > 0) Consume(Token::COMMA);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002212 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002213 if (fni_ != NULL) fni_->PushVariableName(name);
Steve Blocka7e24c12009-10-30 11:49:00 +00002214
2215 // Declare variable.
2216 // Note that we *always* must treat the initial value via a separate init
2217 // assignment for variables and constants because the value must be assigned
2218 // when the variable is encountered in the source. But the variable/constant
2219 // is declared (and set to 'undefined') upon entering the function within
2220 // which the variable or constant is declared. Only function variables have
2221 // an initial value in the declaration (because they are initialized upon
2222 // entering the function).
2223 //
2224 // If we have a const declaration, in an inner scope, the proxy is always
2225 // bound to the declared variable (independent of possibly surrounding with
2226 // statements).
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002227 // For let/const declarations in harmony mode, we can also immediately
2228 // pre-resolve the proxy because it resides in the same scope as the
2229 // declaration.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002230 is_for_iteration_variable =
2231 var_context == kForStatement &&
2232 (peek() == Token::IN || PeekContextualKeyword(CStrVector("of")));
2233 if (is_for_iteration_variable && mode == CONST) {
2234 needs_init = false;
2235 }
2236
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002237 Interface* interface =
2238 is_const ? Interface::NewConst() : Interface::NewValue();
2239 VariableProxy* proxy = NewUnresolved(name, mode, interface);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002240 Declaration* declaration =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002241 factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002242 Declare(declaration, mode != VAR, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00002243 nvars++;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002244 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002245 ReportMessage("too_many_variables");
Steve Block053d10c2011-06-13 19:13:29 +01002246 *ok = false;
2247 return NULL;
2248 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002249 if (names) names->Add(name, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00002250
2251 // Parse initialization expression if present and/or needed. A
2252 // declaration of the form:
2253 //
2254 // var v = x;
2255 //
2256 // is syntactic sugar for:
2257 //
2258 // var v; v = x;
2259 //
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002260 // In particular, we need to re-lookup 'v' (in scope_, not
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002261 // declaration_scope) as it may be a different 'v' than the 'v' in the
2262 // declaration (e.g., if we are inside a 'with' statement or 'catch'
2263 // block).
Steve Blocka7e24c12009-10-30 11:49:00 +00002264 //
2265 // However, note that const declarations are different! A const
2266 // declaration of the form:
2267 //
2268 // const c = x;
2269 //
2270 // is *not* syntactic sugar for:
2271 //
2272 // const c; c = x;
2273 //
2274 // The "variable" c initialized to x is the same as the declared
2275 // one - there is no re-lookup (see the last parameter of the
2276 // Declare() call above).
2277
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002278 Scope* initialization_scope = is_const ? declaration_scope : scope_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002279 Expression* value = NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002280 int pos = -1;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002281 // Harmony consts have non-optional initializers.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002282 if (peek() == Token::ASSIGN ||
2283 (mode == CONST && !is_for_iteration_variable)) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002284 Expect(Token::ASSIGN, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002285 pos = position();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002286 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002287 // Don't infer if it is "a = function(){...}();"-like expression.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002288 if (fni_ != NULL &&
2289 value->AsCall() == NULL &&
2290 value->AsCallNew() == NULL) {
2291 fni_->Infer();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002292 } else {
2293 fni_->RemoveLastFunction();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002294 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002295 if (decl_props != NULL) *decl_props = kHasInitializers;
2296 }
2297
2298 // Record the end position of the initializer.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002299 if (proxy->is_resolved()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002300 proxy->var()->set_initializer_position(position());
Steve Blocka7e24c12009-10-30 11:49:00 +00002301 }
2302
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002303 // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
2304 if (value == NULL && needs_init) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002305 value = GetLiteralUndefined(position());
Steve Blocka7e24c12009-10-30 11:49:00 +00002306 }
2307
2308 // Global variable declarations must be compiled in a specific
2309 // way. When the script containing the global variable declaration
2310 // is entered, the global variable must be declared, so that if it
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002311 // doesn't exist (on the global object itself, see ES5 errata) it
Steve Blocka7e24c12009-10-30 11:49:00 +00002312 // gets created with an initial undefined value. This is handled
2313 // by the declarations part of the function representing the
2314 // top-level global code; see Runtime::DeclareGlobalVariable. If
2315 // it already exists (in the object or in a prototype), it is
2316 // *not* touched until the variable declaration statement is
2317 // executed.
2318 //
2319 // Executing the variable declaration statement will always
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002320 // guarantee to give the global object an own property.
2321 // This way, global variable declarations can shadow
Steve Blocka7e24c12009-10-30 11:49:00 +00002322 // properties in the prototype chain, but only after the variable
2323 // declaration statement has been executed. This is important in
2324 // browsers where the global object (window) has lots of
2325 // properties defined in prototype objects.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002326 if (initialization_scope->is_script_scope() &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002327 !IsLexicalVariableMode(mode)) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002328 // Compute the arguments for the runtime call.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002329 ZoneList<Expression*>* arguments =
2330 new(zone()) ZoneList<Expression*>(3, zone());
Ben Murdoch8b112d22011-06-08 16:22:53 +01002331 // We have at least 1 parameter.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002332 arguments->Add(factory()->NewStringLiteral(name, pos), zone());
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002333 CallRuntime* initialize;
2334
2335 if (is_const) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002336 arguments->Add(value, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00002337 value = NULL; // zap the value to avoid the unnecessary assignment
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002338
2339 // Construct the call to Runtime_InitializeConstGlobal
2340 // and add it to the initialization statement block.
2341 // Note that the function does different things depending on
2342 // the number of arguments (1 or 2).
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002343 initialize = factory()->NewCallRuntime(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002344 ast_value_factory()->initialize_const_global_string(),
2345 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), arguments,
2346 pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002347 } else {
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002348 // Add strict mode.
2349 // We may want to pass singleton to avoid Literal allocations.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002350 StrictMode strict_mode = initialization_scope->strict_mode();
2351 arguments->Add(factory()->NewNumberLiteral(strict_mode, pos), zone());
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002352
2353 // Be careful not to assign a value to the global variable if
2354 // we're in a with. The initialization value should not
2355 // necessarily be stored in the global object in that case,
2356 // which is why we need to generate a separate assignment node.
2357 if (value != NULL && !inside_with()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002358 arguments->Add(value, zone());
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002359 value = NULL; // zap the value to avoid the unnecessary assignment
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002360 // Construct the call to Runtime_InitializeVarGlobal
2361 // and add it to the initialization statement block.
2362 initialize = factory()->NewCallRuntime(
2363 ast_value_factory()->initialize_var_global_string(),
2364 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), arguments,
2365 pos);
2366 } else {
2367 initialize = NULL;
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002368 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002369 }
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002370
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002371 if (initialize != NULL) {
2372 block->AddStatement(factory()->NewExpressionStatement(
2373 initialize, RelocInfo::kNoPosition),
2374 zone());
2375 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002376 } else if (needs_init) {
2377 // Constant initializations always assign to the declared constant which
2378 // is always at the function scope level. This is only relevant for
2379 // dynamically looked-up variables and constants (the start context for
2380 // constant lookups is always the function context, while it is the top
2381 // context for var declared variables). Sigh...
2382 // For 'let' and 'const' declared variables in harmony mode the
2383 // initialization also always assigns to the declared variable.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002384 DCHECK(proxy != NULL);
2385 DCHECK(proxy->var() != NULL);
2386 DCHECK(value != NULL);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002387 Assignment* assignment =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002388 factory()->NewAssignment(init_op, proxy, value, pos);
2389 block->AddStatement(
2390 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
2391 zone());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002392 value = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002393 }
2394
Ben Murdoch589d6972011-11-30 16:04:58 +00002395 // Add an assignment node to the initialization statement block if we still
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002396 // have a pending initialization value.
Steve Blocka7e24c12009-10-30 11:49:00 +00002397 if (value != NULL) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002398 DCHECK(mode == VAR);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002399 // 'var' initializations are simply assignments (with all the consequences
2400 // if they are inside a 'with' statement - they may change a 'with' object
2401 // property).
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002402 VariableProxy* proxy =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002403 initialization_scope->NewUnresolved(factory(), name, interface);
Ben Murdoch8b112d22011-06-08 16:22:53 +01002404 Assignment* assignment =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002405 factory()->NewAssignment(init_op, proxy, value, pos);
2406 block->AddStatement(
2407 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
2408 zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00002409 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002410
2411 if (fni_ != NULL) fni_->Leave();
Steve Blocka7e24c12009-10-30 11:49:00 +00002412 } while (peek() == Token::COMMA);
2413
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002414 // If there was a single non-const declaration, return it in the output
2415 // parameter for possible use by for/in.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002416 if (nvars == 1 && (!is_const || is_for_iteration_variable)) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002417 *out = name;
Steve Blocka7e24c12009-10-30 11:49:00 +00002418 }
2419
2420 return block;
2421}
2422
2423
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002424static bool ContainsLabel(ZoneList<const AstRawString*>* labels,
2425 const AstRawString* label) {
2426 DCHECK(label != NULL);
2427 if (labels != NULL) {
2428 for (int i = labels->length(); i-- > 0; ) {
2429 if (labels->at(i) == label) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002430 return true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002431 }
2432 }
2433 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002434 return false;
2435}
2436
2437
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002438Statement* Parser::ParseExpressionOrLabelledStatement(
2439 ZoneList<const AstRawString*>* labels, bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002440 // ExpressionStatement | LabelledStatement ::
2441 // Expression ';'
2442 // Identifier ':' Statement
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002443 int pos = peek_position();
Steve Block1e0659c2011-05-24 12:43:12 +01002444 bool starts_with_idenfifier = peek_any_identifier();
Steve Blocka7e24c12009-10-30 11:49:00 +00002445 Expression* expr = ParseExpression(true, CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002446 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
Steve Blocka7e24c12009-10-30 11:49:00 +00002447 expr->AsVariableProxy() != NULL &&
2448 !expr->AsVariableProxy()->is_this()) {
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08002449 // Expression is a single identifier, and not, e.g., a parenthesized
2450 // identifier.
Steve Blocka7e24c12009-10-30 11:49:00 +00002451 VariableProxy* var = expr->AsVariableProxy();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002452 const AstRawString* label = var->raw_name();
Steve Blocka7e24c12009-10-30 11:49:00 +00002453 // TODO(1240780): We don't check for redeclaration of labels
2454 // during preparsing since keeping track of the set of active
2455 // labels requires nontrivial changes to the way scopes are
2456 // structured. However, these are probably changes we want to
2457 // make later anyway so we should go back and fix this then.
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002458 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002459 ParserTraits::ReportMessage("label_redeclaration", label);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002460 *ok = false;
2461 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002462 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002463 if (labels == NULL) {
2464 labels = new(zone()) ZoneList<const AstRawString*>(4, zone());
2465 }
2466 labels->Add(label, zone());
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002467 // Remove the "ghost" variable that turned out to be a label
2468 // from the top scope. This way, we don't try to resolve it
2469 // during the scope processing.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002470 scope_->RemoveUnresolved(var);
Steve Blocka7e24c12009-10-30 11:49:00 +00002471 Expect(Token::COLON, CHECK_OK);
2472 return ParseStatement(labels, ok);
2473 }
2474
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002475 // If we have an extension, we allow a native function declaration.
2476 // A native function declaration starts with "native function" with
2477 // no line-terminator between the two words.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002478 if (extension_ != NULL && peek() == Token::FUNCTION &&
2479 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL &&
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002480 expr->AsVariableProxy() != NULL &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002481 expr->AsVariableProxy()->raw_name() ==
2482 ast_value_factory()->native_string() &&
2483 !scanner()->literal_contains_escapes()) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002484 return ParseNativeDeclaration(ok);
2485 }
2486
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002487 // Parsed expression statement, or the context-sensitive 'module' keyword.
2488 // Only expect semicolon in the former case.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002489 // Also detect attempts at 'let' declarations in sloppy mode.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002490 if (!FLAG_harmony_modules || peek() != Token::IDENTIFIER ||
2491 scanner()->HasAnyLineTerminatorBeforeNext() ||
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002492 expr->AsVariableProxy() == NULL ||
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002493 expr->AsVariableProxy()->raw_name() !=
2494 ast_value_factory()->module_string() ||
2495 scanner()->literal_contains_escapes()) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002496 if (peek() == Token::IDENTIFIER && expr->AsVariableProxy() != NULL &&
2497 expr->AsVariableProxy()->raw_name() ==
2498 ast_value_factory()->let_string()) {
2499 ReportMessage("sloppy_lexical", NULL);
2500 *ok = false;
2501 return NULL;
2502 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002503 ExpectSemicolon(CHECK_OK);
2504 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002505 return factory()->NewExpressionStatement(expr, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002506}
2507
2508
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002509IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels,
2510 bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002511 // IfStatement ::
2512 // 'if' '(' Expression ')' Statement ('else' Statement)?
2513
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002514 int pos = peek_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00002515 Expect(Token::IF, CHECK_OK);
2516 Expect(Token::LPAREN, CHECK_OK);
2517 Expression* condition = ParseExpression(true, CHECK_OK);
2518 Expect(Token::RPAREN, CHECK_OK);
2519 Statement* then_statement = ParseStatement(labels, CHECK_OK);
2520 Statement* else_statement = NULL;
2521 if (peek() == Token::ELSE) {
2522 Next();
2523 else_statement = ParseStatement(labels, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002524 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002525 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
Steve Blocka7e24c12009-10-30 11:49:00 +00002526 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002527 return factory()->NewIfStatement(
2528 condition, then_statement, else_statement, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002529}
2530
2531
2532Statement* Parser::ParseContinueStatement(bool* ok) {
2533 // ContinueStatement ::
2534 // 'continue' Identifier? ';'
2535
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002536 int pos = peek_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00002537 Expect(Token::CONTINUE, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002538 const AstRawString* label = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002539 Token::Value tok = peek();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002540 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
Steve Blocka7e24c12009-10-30 11:49:00 +00002541 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002542 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2543 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00002544 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002545 IterationStatement* target = LookupContinueTarget(label, CHECK_OK);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002546 if (target == NULL) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01002547 // Illegal continue statement.
2548 const char* message = "illegal_continue";
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002549 if (label != NULL) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01002550 message = "unknown_label";
Ben Murdochb8e0da22011-05-16 14:20:40 +01002551 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002552 ParserTraits::ReportMessage(message, label);
Ben Murdochb8e0da22011-05-16 14:20:40 +01002553 *ok = false;
2554 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002555 }
2556 ExpectSemicolon(CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002557 return factory()->NewContinueStatement(target, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002558}
2559
2560
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002561Statement* Parser::ParseBreakStatement(ZoneList<const AstRawString*>* labels,
2562 bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002563 // BreakStatement ::
2564 // 'break' Identifier? ';'
2565
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002566 int pos = peek_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00002567 Expect(Token::BREAK, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002568 const AstRawString* label = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002569 Token::Value tok = peek();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002570 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
Steve Blocka7e24c12009-10-30 11:49:00 +00002571 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002572 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2573 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00002574 }
2575 // Parse labeled break statements that target themselves into
2576 // empty statements, e.g. 'l1: l2: l3: break l2;'
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002577 if (label != NULL && ContainsLabel(labels, label)) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002578 ExpectSemicolon(CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002579 return factory()->NewEmptyStatement(pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002580 }
2581 BreakableStatement* target = NULL;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002582 target = LookupBreakTarget(label, CHECK_OK);
2583 if (target == NULL) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01002584 // Illegal break statement.
2585 const char* message = "illegal_break";
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002586 if (label != NULL) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01002587 message = "unknown_label";
Ben Murdochb8e0da22011-05-16 14:20:40 +01002588 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002589 ParserTraits::ReportMessage(message, label);
Ben Murdochb8e0da22011-05-16 14:20:40 +01002590 *ok = false;
2591 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002592 }
2593 ExpectSemicolon(CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002594 return factory()->NewBreakStatement(target, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002595}
2596
2597
2598Statement* Parser::ParseReturnStatement(bool* ok) {
2599 // ReturnStatement ::
2600 // 'return' Expression? ';'
2601
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002602 // Consume the return token. It is necessary to do that before
Steve Blocka7e24c12009-10-30 11:49:00 +00002603 // reporting any errors on it, because of the way errors are
2604 // reported (underlining).
2605 Expect(Token::RETURN, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002606 Scanner::Location loc = scanner()->location();
Steve Blocka7e24c12009-10-30 11:49:00 +00002607
Ben Murdoch692be652012-01-10 18:47:50 +00002608 Token::Value tok = peek();
2609 Statement* result;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002610 Expression* return_value;
2611 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
Ben Murdoch692be652012-01-10 18:47:50 +00002612 tok == Token::SEMICOLON ||
2613 tok == Token::RBRACE ||
2614 tok == Token::EOS) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002615 return_value = GetLiteralUndefined(position());
Ben Murdoch692be652012-01-10 18:47:50 +00002616 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002617 return_value = ParseExpression(true, CHECK_OK);
2618 }
2619 ExpectSemicolon(CHECK_OK);
2620 if (is_generator()) {
2621 Expression* generator = factory()->NewVariableProxy(
2622 function_state_->generator_object_variable());
2623 Expression* yield = factory()->NewYield(
2624 generator, return_value, Yield::kFinal, loc.beg_pos);
2625 result = factory()->NewExpressionStatement(yield, loc.beg_pos);
2626 } else {
2627 result = factory()->NewReturnStatement(return_value, loc.beg_pos);
Ben Murdoch692be652012-01-10 18:47:50 +00002628 }
2629
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002630 Scope* decl_scope = scope_->DeclarationScope();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002631 if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002632 ReportMessageAt(loc, "illegal_return");
2633 *ok = false;
2634 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002635 }
Ben Murdoch692be652012-01-10 18:47:50 +00002636 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00002637}
2638
2639
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002640Statement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels,
2641 bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002642 // WithStatement ::
2643 // 'with' '(' Expression ')' Statement
2644
2645 Expect(Token::WITH, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002646 int pos = position();
Steve Block1e0659c2011-05-24 12:43:12 +01002647
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002648 if (strict_mode() == STRICT) {
2649 ReportMessage("strict_mode_with");
Steve Block1e0659c2011-05-24 12:43:12 +01002650 *ok = false;
2651 return NULL;
2652 }
2653
Steve Blocka7e24c12009-10-30 11:49:00 +00002654 Expect(Token::LPAREN, CHECK_OK);
2655 Expression* expr = ParseExpression(true, CHECK_OK);
2656 Expect(Token::RPAREN, CHECK_OK);
2657
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002658 scope_->DeclarationScope()->RecordWithStatement();
2659 Scope* with_scope = NewScope(scope_, WITH_SCOPE);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002660 Statement* stmt;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002661 { BlockState block_state(&scope_, with_scope);
2662 with_scope->set_start_position(scanner()->peek_location().beg_pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002663 stmt = ParseStatement(labels, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002664 with_scope->set_end_position(scanner()->location().end_pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002665 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002666 return factory()->NewWithStatement(with_scope, expr, stmt, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002667}
2668
2669
2670CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
2671 // CaseClause ::
2672 // 'case' Expression ':' Statement*
2673 // 'default' ':' Statement*
2674
2675 Expression* label = NULL; // NULL expression indicates default case
2676 if (peek() == Token::CASE) {
2677 Expect(Token::CASE, CHECK_OK);
2678 label = ParseExpression(true, CHECK_OK);
2679 } else {
2680 Expect(Token::DEFAULT, CHECK_OK);
2681 if (*default_seen_ptr) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002682 ReportMessage("multiple_defaults_in_switch");
Steve Blocka7e24c12009-10-30 11:49:00 +00002683 *ok = false;
2684 return NULL;
2685 }
2686 *default_seen_ptr = true;
2687 }
2688 Expect(Token::COLON, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002689 int pos = position();
2690 ZoneList<Statement*>* statements =
2691 new(zone()) ZoneList<Statement*>(5, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00002692 while (peek() != Token::CASE &&
2693 peek() != Token::DEFAULT &&
2694 peek() != Token::RBRACE) {
2695 Statement* stat = ParseStatement(NULL, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002696 statements->Add(stat, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00002697 }
2698
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002699 return factory()->NewCaseClause(label, statements, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002700}
2701
2702
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002703SwitchStatement* Parser::ParseSwitchStatement(
2704 ZoneList<const AstRawString*>* labels, bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002705 // SwitchStatement ::
2706 // 'switch' '(' Expression ')' '{' CaseClause* '}'
2707
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002708 SwitchStatement* statement =
2709 factory()->NewSwitchStatement(labels, peek_position());
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002710 Target target(&this->target_stack_, statement);
Steve Blocka7e24c12009-10-30 11:49:00 +00002711
2712 Expect(Token::SWITCH, CHECK_OK);
2713 Expect(Token::LPAREN, CHECK_OK);
2714 Expression* tag = ParseExpression(true, CHECK_OK);
2715 Expect(Token::RPAREN, CHECK_OK);
2716
2717 bool default_seen = false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002718 ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00002719 Expect(Token::LBRACE, CHECK_OK);
2720 while (peek() != Token::RBRACE) {
2721 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002722 cases->Add(clause, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00002723 }
2724 Expect(Token::RBRACE, CHECK_OK);
2725
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002726 if (statement) statement->Initialize(tag, cases);
Steve Blocka7e24c12009-10-30 11:49:00 +00002727 return statement;
2728}
2729
2730
2731Statement* Parser::ParseThrowStatement(bool* ok) {
2732 // ThrowStatement ::
2733 // 'throw' Expression ';'
2734
2735 Expect(Token::THROW, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002736 int pos = position();
2737 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
2738 ReportMessage("newline_after_throw");
Steve Blocka7e24c12009-10-30 11:49:00 +00002739 *ok = false;
2740 return NULL;
2741 }
2742 Expression* exception = ParseExpression(true, CHECK_OK);
2743 ExpectSemicolon(CHECK_OK);
2744
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002745 return factory()->NewExpressionStatement(
2746 factory()->NewThrow(exception, pos), pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002747}
2748
2749
2750TryStatement* Parser::ParseTryStatement(bool* ok) {
2751 // TryStatement ::
2752 // 'try' Block Catch
2753 // 'try' Block Finally
2754 // 'try' Block Catch Finally
2755 //
2756 // Catch ::
2757 // 'catch' '(' Identifier ')' Block
2758 //
2759 // Finally ::
2760 // 'finally' Block
2761
2762 Expect(Token::TRY, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002763 int pos = position();
Steve Blocka7e24c12009-10-30 11:49:00 +00002764
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002765 TargetCollector try_collector(zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00002766 Block* try_block;
2767
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002768 { Target target(&this->target_stack_, &try_collector);
Steve Blocka7e24c12009-10-30 11:49:00 +00002769 try_block = ParseBlock(NULL, CHECK_OK);
2770 }
2771
Steve Blocka7e24c12009-10-30 11:49:00 +00002772 Token::Value tok = peek();
2773 if (tok != Token::CATCH && tok != Token::FINALLY) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002774 ReportMessage("no_catch_or_finally");
Steve Blocka7e24c12009-10-30 11:49:00 +00002775 *ok = false;
2776 return NULL;
2777 }
2778
2779 // If we can break out from the catch block and there is a finally block,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002780 // then we will need to collect escaping targets from the catch
2781 // block. Since we don't know yet if there will be a finally block, we
2782 // always collect the targets.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002783 TargetCollector catch_collector(zone());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002784 Scope* catch_scope = NULL;
2785 Variable* catch_variable = NULL;
2786 Block* catch_block = NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002787 const AstRawString* name = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00002788 if (tok == Token::CATCH) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002789 Consume(Token::CATCH);
2790
2791 Expect(Token::LPAREN, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002792 catch_scope = NewScope(scope_, CATCH_SCOPE);
2793 catch_scope->set_start_position(scanner()->location().beg_pos);
2794 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
Steve Block1e0659c2011-05-24 12:43:12 +01002795
Steve Blocka7e24c12009-10-30 11:49:00 +00002796 Expect(Token::RPAREN, CHECK_OK);
2797
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002798 Target target(&this->target_stack_, &catch_collector);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002799 catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002800 BlockState block_state(&scope_, catch_scope);
2801 catch_block = ParseBlock(NULL, CHECK_OK);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002802
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002803 catch_scope->set_end_position(scanner()->location().end_pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002804 tok = peek();
2805 }
2806
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002807 Block* finally_block = NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002808 DCHECK(tok == Token::FINALLY || catch_block != NULL);
2809 if (tok == Token::FINALLY) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002810 Consume(Token::FINALLY);
Steve Blocka7e24c12009-10-30 11:49:00 +00002811 finally_block = ParseBlock(NULL, CHECK_OK);
2812 }
2813
2814 // Simplify the AST nodes by converting:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002815 // 'try B0 catch B1 finally B2'
Steve Blocka7e24c12009-10-30 11:49:00 +00002816 // to:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002817 // 'try { try B0 catch B1 } finally B2'
Steve Blocka7e24c12009-10-30 11:49:00 +00002818
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002819 if (catch_block != NULL && finally_block != NULL) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002820 // If we have both, create an inner try/catch.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002821 DCHECK(catch_scope != NULL && catch_variable != NULL);
2822 int index = function_state_->NextHandlerIndex();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002823 TryCatchStatement* statement = factory()->NewTryCatchStatement(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002824 index, try_block, catch_scope, catch_variable, catch_block,
2825 RelocInfo::kNoPosition);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002826 statement->set_escaping_targets(try_collector.targets());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002827 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
2828 try_block->AddStatement(statement, zone());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002829 catch_block = NULL; // Clear to indicate it's been handled.
Steve Blocka7e24c12009-10-30 11:49:00 +00002830 }
2831
2832 TryStatement* result = NULL;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002833 if (catch_block != NULL) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002834 DCHECK(finally_block == NULL);
2835 DCHECK(catch_scope != NULL && catch_variable != NULL);
2836 int index = function_state_->NextHandlerIndex();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002837 result = factory()->NewTryCatchStatement(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002838 index, try_block, catch_scope, catch_variable, catch_block, pos);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002839 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002840 DCHECK(finally_block != NULL);
2841 int index = function_state_->NextHandlerIndex();
2842 result = factory()->NewTryFinallyStatement(
2843 index, try_block, finally_block, pos);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002844 // Combine the jump targets of the try block and the possible catch block.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002845 try_collector.targets()->AddAll(*catch_collector.targets(), zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00002846 }
2847
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002848 result->set_escaping_targets(try_collector.targets());
Steve Blocka7e24c12009-10-30 11:49:00 +00002849 return result;
2850}
2851
2852
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002853DoWhileStatement* Parser::ParseDoWhileStatement(
2854 ZoneList<const AstRawString*>* labels, bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002855 // DoStatement ::
2856 // 'do' Statement 'while' '(' Expression ')' ';'
2857
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002858 DoWhileStatement* loop =
2859 factory()->NewDoWhileStatement(labels, peek_position());
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002860 Target target(&this->target_stack_, loop);
Steve Blocka7e24c12009-10-30 11:49:00 +00002861
2862 Expect(Token::DO, CHECK_OK);
2863 Statement* body = ParseStatement(NULL, CHECK_OK);
2864 Expect(Token::WHILE, CHECK_OK);
2865 Expect(Token::LPAREN, CHECK_OK);
Steve Blockd0582a62009-12-15 09:54:21 +00002866
Steve Blocka7e24c12009-10-30 11:49:00 +00002867 Expression* cond = ParseExpression(true, CHECK_OK);
2868 Expect(Token::RPAREN, CHECK_OK);
2869
2870 // Allow do-statements to be terminated with and without
2871 // semi-colons. This allows code such as 'do;while(0)return' to
2872 // parse, which would not be the case if we had used the
2873 // ExpectSemicolon() functionality here.
2874 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
2875
Steve Block3ce2e202009-11-05 08:53:23 +00002876 if (loop != NULL) loop->Initialize(cond, body);
Steve Blocka7e24c12009-10-30 11:49:00 +00002877 return loop;
2878}
2879
2880
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002881WhileStatement* Parser::ParseWhileStatement(
2882 ZoneList<const AstRawString*>* labels, bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002883 // WhileStatement ::
2884 // 'while' '(' Expression ')' Statement
2885
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002886 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position());
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002887 Target target(&this->target_stack_, loop);
Steve Blocka7e24c12009-10-30 11:49:00 +00002888
2889 Expect(Token::WHILE, CHECK_OK);
2890 Expect(Token::LPAREN, CHECK_OK);
2891 Expression* cond = ParseExpression(true, CHECK_OK);
2892 Expect(Token::RPAREN, CHECK_OK);
2893 Statement* body = ParseStatement(NULL, CHECK_OK);
2894
Steve Block3ce2e202009-11-05 08:53:23 +00002895 if (loop != NULL) loop->Initialize(cond, body);
Steve Blocka7e24c12009-10-30 11:49:00 +00002896 return loop;
2897}
2898
2899
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002900bool Parser::CheckInOrOf(bool accept_OF,
2901 ForEachStatement::VisitMode* visit_mode) {
2902 if (Check(Token::IN)) {
2903 *visit_mode = ForEachStatement::ENUMERATE;
2904 return true;
2905 } else if (accept_OF && CheckContextualKeyword(CStrVector("of"))) {
2906 *visit_mode = ForEachStatement::ITERATE;
2907 return true;
2908 }
2909 return false;
2910}
2911
2912
2913void Parser::InitializeForEachStatement(ForEachStatement* stmt,
2914 Expression* each,
2915 Expression* subject,
2916 Statement* body) {
2917 ForOfStatement* for_of = stmt->AsForOfStatement();
2918
2919 if (for_of != NULL) {
2920 Variable* iterator = scope_->DeclarationScope()->NewTemporary(
2921 ast_value_factory()->dot_iterator_string());
2922 Variable* result = scope_->DeclarationScope()->NewTemporary(
2923 ast_value_factory()->dot_result_string());
2924
2925 Expression* assign_iterator;
2926 Expression* next_result;
2927 Expression* result_done;
2928 Expression* assign_each;
2929
2930 // var iterator = subject[Symbol.iterator]();
2931 assign_iterator = factory()->NewAssignment(
2932 Token::ASSIGN, factory()->NewVariableProxy(iterator),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002933 GetIterator(subject, factory()), subject->position());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002934
2935 // var result = iterator.next();
2936 {
2937 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
2938 Expression* next_literal = factory()->NewStringLiteral(
2939 ast_value_factory()->next_string(), RelocInfo::kNoPosition);
2940 Expression* next_property = factory()->NewProperty(
2941 iterator_proxy, next_literal, RelocInfo::kNoPosition);
2942 ZoneList<Expression*>* next_arguments =
2943 new(zone()) ZoneList<Expression*>(0, zone());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002944 Expression* next_call = factory()->NewCall(next_property, next_arguments,
2945 subject->position());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002946 Expression* result_proxy = factory()->NewVariableProxy(result);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002947 next_result = factory()->NewAssignment(Token::ASSIGN, result_proxy,
2948 next_call, subject->position());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002949 }
2950
2951 // result.done
2952 {
2953 Expression* done_literal = factory()->NewStringLiteral(
2954 ast_value_factory()->done_string(), RelocInfo::kNoPosition);
2955 Expression* result_proxy = factory()->NewVariableProxy(result);
2956 result_done = factory()->NewProperty(
2957 result_proxy, done_literal, RelocInfo::kNoPosition);
2958 }
2959
2960 // each = result.value
2961 {
2962 Expression* value_literal = factory()->NewStringLiteral(
2963 ast_value_factory()->value_string(), RelocInfo::kNoPosition);
2964 Expression* result_proxy = factory()->NewVariableProxy(result);
2965 Expression* result_value = factory()->NewProperty(
2966 result_proxy, value_literal, RelocInfo::kNoPosition);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002967 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value,
2968 each->position());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002969 }
2970
2971 for_of->Initialize(each, subject, body,
2972 assign_iterator,
2973 next_result,
2974 result_done,
2975 assign_each);
2976 } else {
2977 stmt->Initialize(each, subject, body);
2978 }
2979}
2980
2981
2982Statement* Parser::DesugarLetBindingsInForStatement(
2983 Scope* inner_scope, ZoneList<const AstRawString*>* names,
2984 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
2985 Statement* body, bool* ok) {
2986 // ES6 13.6.3.4 specifies that on each loop iteration the let variables are
2987 // copied into a new environment. After copying, the "next" statement of the
2988 // loop is executed to update the loop variables. The loop condition is
2989 // checked and the loop body is executed.
2990 //
2991 // We rewrite a for statement of the form
2992 //
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002993 // labels: for (let x = i; cond; next) body
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002994 //
2995 // into
2996 //
2997 // {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002998 // let x = i;
2999 // temp_x = x;
3000 // first = 1;
3001 // outer: for (;;) {
3002 // let x = temp_x;
3003 // if (first == 1) {
3004 // first = 0;
3005 // } else {
3006 // next;
3007 // }
3008 // flag = 1;
3009 // labels: for (; flag == 1; flag = 0, temp_x = x) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003010 // if (cond) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003011 // body
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003012 // } else {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003013 // break outer;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003014 // }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003015 // }
3016 // if (flag == 1) {
3017 // break;
3018 // }
3019 // }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003020 // }
3021
3022 DCHECK(names->length() > 0);
3023 Scope* for_scope = scope_;
3024 ZoneList<Variable*> temps(names->length(), zone());
3025
3026 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false,
3027 RelocInfo::kNoPosition);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003028
3029 // Add statement: let x = i.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003030 outer_block->AddStatement(init, zone());
3031
3032 const AstRawString* temp_name = ast_value_factory()->dot_for_string();
3033
3034 // For each let variable x:
3035 // make statement: temp_x = x.
3036 for (int i = 0; i < names->length(); i++) {
3037 VariableProxy* proxy =
3038 NewUnresolved(names->at(i), LET, Interface::NewValue());
3039 Variable* temp = scope_->DeclarationScope()->NewTemporary(temp_name);
3040 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
3041 Assignment* assignment = factory()->NewAssignment(
3042 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3043 Statement* assignment_statement = factory()->NewExpressionStatement(
3044 assignment, RelocInfo::kNoPosition);
3045 outer_block->AddStatement(assignment_statement, zone());
3046 temps.Add(temp, zone());
3047 }
3048
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003049 Variable* first = NULL;
3050 // Make statement: first = 1.
3051 if (next) {
3052 first = scope_->DeclarationScope()->NewTemporary(temp_name);
3053 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003054 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3055 Assignment* assignment = factory()->NewAssignment(
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003056 Token::ASSIGN, first_proxy, const1, RelocInfo::kNoPosition);
3057 Statement* assignment_statement =
3058 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003059 outer_block->AddStatement(assignment_statement, zone());
3060 }
3061
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003062 // Make statement: outer: for (;;)
3063 // Note that we don't actually create the label, or set this loop up as an
3064 // explicit break target, instead handing it directly to those nodes that
3065 // need to know about it. This should be safe because we don't run any code
3066 // in this function that looks up break targets.
3067 ForStatement* outer_loop =
3068 factory()->NewForStatement(NULL, RelocInfo::kNoPosition);
3069 outer_block->AddStatement(outer_loop, zone());
3070
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003071 outer_block->set_scope(for_scope);
3072 scope_ = inner_scope;
3073
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003074 Block* inner_block = factory()->NewBlock(NULL, names->length() + 4, false,
3075 RelocInfo::kNoPosition);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003076 int pos = scanner()->location().beg_pos;
3077 ZoneList<Variable*> inner_vars(names->length(), zone());
3078
3079 // For each let variable x:
3080 // make statement: let x = temp_x.
3081 for (int i = 0; i < names->length(); i++) {
3082 VariableProxy* proxy =
3083 NewUnresolved(names->at(i), LET, Interface::NewValue());
3084 Declaration* declaration =
3085 factory()->NewVariableDeclaration(proxy, LET, scope_, pos);
3086 Declare(declaration, true, CHECK_OK);
3087 inner_vars.Add(declaration->proxy()->var(), zone());
3088 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3089 Assignment* assignment = factory()->NewAssignment(
3090 Token::INIT_LET, proxy, temp_proxy, pos);
3091 Statement* assignment_statement = factory()->NewExpressionStatement(
3092 assignment, pos);
3093 proxy->var()->set_initializer_position(pos);
3094 inner_block->AddStatement(assignment_statement, zone());
3095 }
3096
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003097 // Make statement: if (first == 1) { first = 0; } else { next; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003098 if (next) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003099 DCHECK(first);
3100 Expression* compare = NULL;
3101 // Make compare expression: first == 1.
3102 {
3103 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3104 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3105 compare =
3106 factory()->NewCompareOperation(Token::EQ, first_proxy, const1, pos);
3107 }
3108 Statement* clear_first = NULL;
3109 // Make statement: first = 0.
3110 {
3111 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3112 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3113 Assignment* assignment = factory()->NewAssignment(
3114 Token::ASSIGN, first_proxy, const0, RelocInfo::kNoPosition);
3115 clear_first =
3116 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3117 }
3118 Statement* clear_first_or_next = factory()->NewIfStatement(
3119 compare, clear_first, next, RelocInfo::kNoPosition);
3120 inner_block->AddStatement(clear_first_or_next, zone());
3121 }
3122
3123 Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name);
3124 // Make statement: flag = 1.
3125 {
3126 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3127 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3128 Assignment* assignment = factory()->NewAssignment(
3129 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
3130 Statement* assignment_statement =
3131 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3132 inner_block->AddStatement(assignment_statement, zone());
3133 }
3134
3135 // Make cond expression for main loop: flag == 1.
3136 Expression* flag_cond = NULL;
3137 {
3138 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3139 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3140 flag_cond =
3141 factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, pos);
3142 }
3143
3144 // Create chain of expressions "flag = 0, temp_x = x, ..."
3145 Statement* compound_next_statement = NULL;
3146 {
3147 Expression* compound_next = NULL;
3148 // Make expression: flag = 0.
3149 {
3150 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3151 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3152 compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
3153 const0, RelocInfo::kNoPosition);
3154 }
3155
3156 // Make the comma-separated list of temp_x = x assignments.
3157 for (int i = 0; i < names->length(); i++) {
3158 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3159 VariableProxy* proxy = factory()->NewVariableProxy(inner_vars.at(i), pos);
3160 Assignment* assignment = factory()->NewAssignment(
3161 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3162 compound_next = factory()->NewBinaryOperation(
3163 Token::COMMA, compound_next, assignment, RelocInfo::kNoPosition);
3164 }
3165
3166 compound_next_statement = factory()->NewExpressionStatement(
3167 compound_next, RelocInfo::kNoPosition);
3168 }
3169
3170 // Make statement: if (cond) { body; } else { break outer; }
3171 Statement* body_or_stop = body;
3172 if (cond) {
3173 Statement* stop =
3174 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3175 body_or_stop =
3176 factory()->NewIfStatement(cond, body, stop, cond->position());
3177 }
3178
3179 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
3180 // Note that we re-use the original loop node, which retains it labels
3181 // and ensures that any break or continue statements in body point to
3182 // the right place.
3183 loop->Initialize(NULL, flag_cond, compound_next_statement, body_or_stop);
3184 inner_block->AddStatement(loop, zone());
3185
3186 // Make statement: if (flag == 1) { break; }
3187 {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003188 Expression* compare = NULL;
3189 // Make compare expresion: flag == 1.
3190 {
3191 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3192 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003193 compare =
3194 factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, pos);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003195 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003196 Statement* stop =
3197 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003198 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003199 Statement* if_flag_break =
3200 factory()->NewIfStatement(compare, stop, empty, RelocInfo::kNoPosition);
3201 inner_block->AddStatement(if_flag_break, zone());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003202 }
3203
3204 inner_scope->set_end_position(scanner()->location().end_pos);
3205 inner_block->set_scope(inner_scope);
3206 scope_ = for_scope;
3207
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003208 outer_loop->Initialize(NULL, NULL, NULL, inner_block);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003209 return outer_block;
3210}
3211
3212
3213Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
3214 bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003215 // ForStatement ::
3216 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
3217
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003218 int stmt_pos = peek_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00003219 Statement* init = NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003220 ZoneList<const AstRawString*> let_bindings(1, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00003221
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003222 // Create an in-between scope for let-bound iteration variables.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003223 Scope* saved_scope = scope_;
3224 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
3225 scope_ = for_scope;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003226
Steve Blocka7e24c12009-10-30 11:49:00 +00003227 Expect(Token::FOR, CHECK_OK);
3228 Expect(Token::LPAREN, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003229 for_scope->set_start_position(scanner()->location().beg_pos);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003230 bool is_let_identifier_expression = false;
Steve Blocka7e24c12009-10-30 11:49:00 +00003231 if (peek() != Token::SEMICOLON) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003232 if (peek() == Token::VAR ||
3233 (peek() == Token::CONST && strict_mode() == SLOPPY)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003234 bool is_const = peek() == Token::CONST;
3235 const AstRawString* name = NULL;
3236 VariableDeclarationProperties decl_props = kHasNoInitializers;
Steve Blocka7e24c12009-10-30 11:49:00 +00003237 Block* variable_statement =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003238 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
3239 CHECK_OK);
3240 bool accept_OF = decl_props == kHasNoInitializers;
3241 ForEachStatement::VisitMode mode;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003242 int each_pos = position();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003243
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003244 if (name != NULL && CheckInOrOf(accept_OF, &mode)) {
3245 Interface* interface =
3246 is_const ? Interface::NewConst() : Interface::NewValue();
3247 ForEachStatement* loop =
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003248 factory()->NewForEachStatement(mode, labels, stmt_pos);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003249 Target target(&this->target_stack_, loop);
Steve Blocka7e24c12009-10-30 11:49:00 +00003250
Steve Blocka7e24c12009-10-30 11:49:00 +00003251 Expression* enumerable = ParseExpression(true, CHECK_OK);
3252 Expect(Token::RPAREN, CHECK_OK);
3253
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003254 VariableProxy* each =
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003255 scope_->NewUnresolved(factory(), name, interface, each_pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00003256 Statement* body = ParseStatement(NULL, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003257 InitializeForEachStatement(loop, each, enumerable, body);
3258 Block* result =
3259 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3260 result->AddStatement(variable_statement, zone());
3261 result->AddStatement(loop, zone());
3262 scope_ = saved_scope;
3263 for_scope->set_end_position(scanner()->location().end_pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003264 for_scope = for_scope->FinalizeBlockScope();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003265 DCHECK(for_scope == NULL);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003266 // Parsed for-in loop w/ variable/const declaration.
3267 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00003268 } else {
3269 init = variable_statement;
3270 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003271 } else if ((peek() == Token::LET || peek() == Token::CONST) &&
3272 strict_mode() == STRICT) {
3273 bool is_const = peek() == Token::CONST;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003274 const AstRawString* name = NULL;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003275 VariableDeclarationProperties decl_props = kHasNoInitializers;
3276 Block* variable_statement =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003277 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings,
3278 &name, CHECK_OK);
3279 bool accept_IN = name != NULL && decl_props != kHasInitializers;
3280 bool accept_OF = decl_props == kHasNoInitializers;
3281 ForEachStatement::VisitMode mode;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003282 int each_pos = position();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003283
3284 if (accept_IN && CheckInOrOf(accept_OF, &mode)) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003285 // Rewrite a for-in statement of the form
3286 //
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003287 // for (let/const x in e) b
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003288 //
3289 // into
3290 //
3291 // <let x' be a temporary variable>
3292 // for (x' in e) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003293 // let/const x;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003294 // x = x';
3295 // b;
3296 // }
Steve Blocka7e24c12009-10-30 11:49:00 +00003297
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003298 // TODO(keuchel): Move the temporary variable to the block scope, after
3299 // implementing stack allocated block scoped variables.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003300 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3301 ast_value_factory()->dot_for_string());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003302 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp, each_pos);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003303 ForEachStatement* loop =
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003304 factory()->NewForEachStatement(mode, labels, stmt_pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003305 Target target(&this->target_stack_, loop);
3306
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003307 // The expression does not see the loop variable.
3308 scope_ = saved_scope;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003309 Expression* enumerable = ParseExpression(true, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003310 scope_ = for_scope;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003311 Expect(Token::RPAREN, CHECK_OK);
3312
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003313 VariableProxy* each = scope_->NewUnresolved(
3314 factory(), name, Interface::NewValue(), each_pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003315 Statement* body = ParseStatement(NULL, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003316 Block* body_block =
3317 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003318 Token::Value init_op = is_const ? Token::INIT_CONST : Token::ASSIGN;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003319 Assignment* assignment = factory()->NewAssignment(
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003320 init_op, each, temp_proxy, RelocInfo::kNoPosition);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003321 Statement* assignment_statement = factory()->NewExpressionStatement(
3322 assignment, RelocInfo::kNoPosition);
3323 body_block->AddStatement(variable_statement, zone());
3324 body_block->AddStatement(assignment_statement, zone());
3325 body_block->AddStatement(body, zone());
3326 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block);
3327 scope_ = saved_scope;
3328 for_scope->set_end_position(scanner()->location().end_pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003329 for_scope = for_scope->FinalizeBlockScope();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003330 body_block->set_scope(for_scope);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003331 // Parsed for-in loop w/ let declaration.
3332 return loop;
3333
3334 } else {
3335 init = variable_statement;
3336 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003337 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003338 Scanner::Location lhs_location = scanner()->peek_location();
Steve Blocka7e24c12009-10-30 11:49:00 +00003339 Expression* expression = ParseExpression(false, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003340 ForEachStatement::VisitMode mode;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003341 bool accept_OF = expression->IsVariableProxy();
3342 is_let_identifier_expression =
3343 expression->IsVariableProxy() &&
3344 expression->AsVariableProxy()->raw_name() ==
3345 ast_value_factory()->let_string();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003346
3347 if (CheckInOrOf(accept_OF, &mode)) {
3348 expression = this->CheckAndRewriteReferenceExpression(
3349 expression, lhs_location, "invalid_lhs_in_for", CHECK_OK);
3350
3351 ForEachStatement* loop =
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003352 factory()->NewForEachStatement(mode, labels, stmt_pos);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003353 Target target(&this->target_stack_, loop);
Steve Blocka7e24c12009-10-30 11:49:00 +00003354
Steve Blocka7e24c12009-10-30 11:49:00 +00003355 Expression* enumerable = ParseExpression(true, CHECK_OK);
3356 Expect(Token::RPAREN, CHECK_OK);
3357
3358 Statement* body = ParseStatement(NULL, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003359 InitializeForEachStatement(loop, expression, enumerable, body);
3360 scope_ = saved_scope;
3361 for_scope->set_end_position(scanner()->location().end_pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003362 for_scope = for_scope->FinalizeBlockScope();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003363 DCHECK(for_scope == NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00003364 // Parsed for-in loop.
3365 return loop;
3366
3367 } else {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003368 init = factory()->NewExpressionStatement(expression, position());
Steve Blocka7e24c12009-10-30 11:49:00 +00003369 }
3370 }
3371 }
3372
3373 // Standard 'for' loop
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003374 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003375 Target target(&this->target_stack_, loop);
Steve Blocka7e24c12009-10-30 11:49:00 +00003376
3377 // Parsed initializer at this point.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003378 // Detect attempts at 'let' declarations in sloppy mode.
3379 if (peek() == Token::IDENTIFIER && strict_mode() == SLOPPY &&
3380 is_let_identifier_expression) {
3381 ReportMessage("sloppy_lexical", NULL);
3382 *ok = false;
3383 return NULL;
3384 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003385 Expect(Token::SEMICOLON, CHECK_OK);
3386
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003387 // If there are let bindings, then condition and the next statement of the
3388 // for loop must be parsed in a new scope.
3389 Scope* inner_scope = NULL;
3390 if (let_bindings.length() > 0) {
3391 inner_scope = NewScope(for_scope, BLOCK_SCOPE);
3392 inner_scope->set_start_position(scanner()->location().beg_pos);
3393 scope_ = inner_scope;
3394 }
3395
Steve Blocka7e24c12009-10-30 11:49:00 +00003396 Expression* cond = NULL;
3397 if (peek() != Token::SEMICOLON) {
3398 cond = ParseExpression(true, CHECK_OK);
3399 }
3400 Expect(Token::SEMICOLON, CHECK_OK);
3401
3402 Statement* next = NULL;
3403 if (peek() != Token::RPAREN) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003404 int next_pos = position();
Steve Blocka7e24c12009-10-30 11:49:00 +00003405 Expression* exp = ParseExpression(true, CHECK_OK);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003406 next = factory()->NewExpressionStatement(exp, next_pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00003407 }
3408 Expect(Token::RPAREN, CHECK_OK);
3409
3410 Statement* body = ParseStatement(NULL, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003411
3412 Statement* result = NULL;
3413 if (let_bindings.length() > 0) {
3414 scope_ = for_scope;
3415 result = DesugarLetBindingsInForStatement(inner_scope, &let_bindings, loop,
3416 init, cond, next, body, CHECK_OK);
3417 scope_ = saved_scope;
3418 for_scope->set_end_position(scanner()->location().end_pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003419 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003420 scope_ = saved_scope;
3421 for_scope->set_end_position(scanner()->location().end_pos);
3422 for_scope = for_scope->FinalizeBlockScope();
3423 if (for_scope) {
3424 // Rewrite a for statement of the form
3425 // for (const x = i; c; n) b
3426 //
3427 // into
3428 //
3429 // {
3430 // const x = i;
3431 // for (; c; n) b
3432 // }
3433 DCHECK(init != NULL);
3434 Block* block =
3435 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3436 block->AddStatement(init, zone());
3437 block->AddStatement(loop, zone());
3438 block->set_scope(for_scope);
3439 loop->Initialize(NULL, cond, next, body);
3440 result = block;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003441 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003442 loop->Initialize(init, cond, next, body);
3443 result = loop;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003444 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003445 }
3446 return result;
3447}
3448
3449
Steve Blocka7e24c12009-10-30 11:49:00 +00003450DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
3451 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
3452 // contexts this is used as a statement which invokes the debugger as i a
3453 // break point is present.
3454 // DebuggerStatement ::
3455 // 'debugger' ';'
3456
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003457 int pos = peek_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00003458 Expect(Token::DEBUGGER, CHECK_OK);
3459 ExpectSemicolon(CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003460 return factory()->NewDebuggerStatement(pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00003461}
3462
3463
3464bool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003465 if (expression->IsLiteral()) return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00003466 MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3467 return lit != NULL && lit->is_simple();
3468}
3469
Iain Merrick75681382010-08-19 15:07:18 +01003470
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003471Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate,
3472 Expression* expression) {
3473 Factory* factory = isolate->factory();
3474 DCHECK(IsCompileTimeValue(expression));
3475 Handle<FixedArray> result = factory->NewFixedArray(2, TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00003476 ObjectLiteral* object_literal = expression->AsObjectLiteral();
3477 if (object_literal != NULL) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003478 DCHECK(object_literal->is_simple());
Steve Block6ded16b2010-05-10 14:33:55 +01003479 if (object_literal->fast_elements()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003480 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
Steve Block6ded16b2010-05-10 14:33:55 +01003481 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003482 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
Steve Block6ded16b2010-05-10 14:33:55 +01003483 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003484 result->set(kElementsSlot, *object_literal->constant_properties());
3485 } else {
3486 ArrayLiteral* array_literal = expression->AsArrayLiteral();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003487 DCHECK(array_literal != NULL && array_literal->is_simple());
3488 result->set(kLiteralTypeSlot, Smi::FromInt(ARRAY_LITERAL));
Leon Clarkee46be812010-01-19 14:06:41 +00003489 result->set(kElementsSlot, *array_literal->constant_elements());
Steve Blocka7e24c12009-10-30 11:49:00 +00003490 }
3491 return result;
3492}
3493
3494
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003495CompileTimeValue::LiteralType CompileTimeValue::GetLiteralType(
3496 Handle<FixedArray> value) {
3497 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot));
3498 return static_cast<LiteralType>(literal_type->value());
Steve Blocka7e24c12009-10-30 11:49:00 +00003499}
3500
3501
3502Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
3503 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
3504}
3505
3506
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003507bool CheckAndDeclareArrowParameter(ParserTraits* traits, Expression* expression,
3508 Scope* scope, int* num_params,
3509 Scanner::Location* dupe_loc) {
3510 // Case for empty parameter lists:
3511 // () => ...
3512 if (expression == NULL) return true;
3513
3514 // Too many parentheses around expression:
3515 // (( ... )) => ...
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003516 if (expression->is_multi_parenthesized()) return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003517
3518 // Case for a single parameter:
3519 // (foo) => ...
3520 // foo => ...
3521 if (expression->IsVariableProxy()) {
3522 if (expression->AsVariableProxy()->is_this()) return false;
3523
3524 const AstRawString* raw_name = expression->AsVariableProxy()->raw_name();
3525 if (traits->IsEvalOrArguments(raw_name) ||
3526 traits->IsFutureStrictReserved(raw_name))
3527 return false;
3528
3529 if (scope->IsDeclared(raw_name)) {
3530 *dupe_loc = Scanner::Location(
3531 expression->position(), expression->position() + raw_name->length());
3532 return false;
3533 }
3534
3535 scope->DeclareParameter(raw_name, VAR);
3536 ++(*num_params);
3537 return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00003538 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003539
3540 // Case for more than one parameter:
3541 // (foo, bar [, ...]) => ...
3542 if (expression->IsBinaryOperation()) {
3543 BinaryOperation* binop = expression->AsBinaryOperation();
3544 if (binop->op() != Token::COMMA || binop->left()->is_parenthesized() ||
3545 binop->right()->is_parenthesized())
3546 return false;
3547
3548 return CheckAndDeclareArrowParameter(traits, binop->left(), scope,
3549 num_params, dupe_loc) &&
3550 CheckAndDeclareArrowParameter(traits, binop->right(), scope,
3551 num_params, dupe_loc);
Steve Blocka7e24c12009-10-30 11:49:00 +00003552 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003553
3554 // Any other kind of expression is not a valid parameter list.
3555 return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00003556}
3557
Steve Block1e0659c2011-05-24 12:43:12 +01003558
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003559int ParserTraits::DeclareArrowParametersFromExpression(
3560 Expression* expression, Scope* scope, Scanner::Location* dupe_loc,
Steve Block1e0659c2011-05-24 12:43:12 +01003561 bool* ok) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003562 int num_params = 0;
3563 *ok = CheckAndDeclareArrowParameter(this, expression, scope, &num_params,
3564 dupe_loc);
3565 return num_params;
Steve Block1e0659c2011-05-24 12:43:12 +01003566}
3567
Steve Blocka7e24c12009-10-30 11:49:00 +00003568
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003569FunctionLiteral* Parser::ParseFunctionLiteral(
3570 const AstRawString* function_name, Scanner::Location function_name_location,
3571 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos,
3572 FunctionLiteral::FunctionType function_type,
3573 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003574 // Function ::
3575 // '(' FormalParameterList? ')' '{' FunctionBody '}'
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003576 //
3577 // Getter ::
3578 // '(' ')' '{' FunctionBody '}'
3579 //
3580 // Setter ::
3581 // '(' PropertySetParameterList ')' '{' FunctionBody '}'
3582
3583 int pos = function_token_pos == RelocInfo::kNoPosition
3584 ? peek_position() : function_token_pos;
3585
3586 bool is_generator = IsGeneratorFunction(kind);
Steve Blocka7e24c12009-10-30 11:49:00 +00003587
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003588 // Anonymous functions were passed either the empty symbol or a null
3589 // handle as the function name. Remember if we were passed a non-empty
3590 // handle to decide whether to invoke function name inference.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003591 bool should_infer_name = function_name == NULL;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003592
3593 // We want a non-null handle as the function name.
3594 if (should_infer_name) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003595 function_name = ast_value_factory()->empty_string();
Steve Blocka7e24c12009-10-30 11:49:00 +00003596 }
3597
3598 int num_parameters = 0;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003599 // Function declarations are function scoped in normal mode, so they are
3600 // hoisted. In harmony block scoping mode they are block scoped, so they
3601 // are not hoisted.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003602 //
3603 // One tricky case are function declarations in a local sloppy-mode eval:
3604 // their declaration is hoisted, but they still see the local scope. E.g.,
3605 //
3606 // function() {
3607 // var x = 0
3608 // try { throw 1 } catch (x) { eval("function g() { return x }") }
3609 // return g()
3610 // }
3611 //
3612 // needs to return 1. To distinguish such cases, we need to detect
3613 // (1) whether a function stems from a sloppy eval, and
3614 // (2) whether it actually hoists across the eval.
3615 // Unfortunately, we do not represent sloppy eval scopes, so we do not have
3616 // either information available directly, especially not when lazily compiling
3617 // a function like 'g'. We hence rely on the following invariants:
3618 // - (1) is the case iff the innermost scope of the deserialized scope chain
3619 // under which we compile is _not_ a declaration scope. This holds because
3620 // in all normal cases, function declarations are fully hoisted to a
3621 // declaration scope and compiled relative to that.
3622 // - (2) is the case iff the current declaration scope is still the original
3623 // one relative to the deserialized scope chain. Otherwise we must be
3624 // compiling a function in an inner declaration scope in the eval, e.g. a
3625 // nested function, and hoisting works normally relative to that.
3626 Scope* declaration_scope = scope_->DeclarationScope();
3627 Scope* original_declaration_scope = original_scope_->DeclarationScope();
3628 Scope* scope =
3629 function_type == FunctionLiteral::DECLARATION &&
3630 (!allow_harmony_scoping() || strict_mode() == SLOPPY) &&
3631 (original_scope_ == original_declaration_scope ||
3632 declaration_scope != original_declaration_scope)
3633 ? NewScope(declaration_scope, FUNCTION_SCOPE)
3634 : NewScope(scope_, FUNCTION_SCOPE);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003635 ZoneList<Statement*>* body = NULL;
3636 int materialized_literal_count = -1;
3637 int expected_property_count = -1;
3638 int handler_count = 0;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003639 FunctionLiteral::ParameterFlag duplicate_parameters =
3640 FunctionLiteral::kNoDuplicateParameters;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003641 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
3642 ? FunctionLiteral::kIsParenthesized
3643 : FunctionLiteral::kNotParenthesized;
Steve Blocka7e24c12009-10-30 11:49:00 +00003644 // Parse function body.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003645 {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003646 AstNodeFactory function_factory(ast_value_factory());
3647 FunctionState function_state(&function_state_, &scope_, scope,
3648 &function_factory);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003649 scope_->SetScopeName(function_name);
3650
3651 if (is_generator) {
3652 // For generators, allocating variables in contexts is currently a win
3653 // because it minimizes the work needed to suspend and resume an
3654 // activation.
3655 scope_->ForceContextAllocation();
3656
3657 // Calling a generator returns a generator object. That object is stored
3658 // in a temporary variable, a definition that is used by "yield"
3659 // expressions. This also marks the FunctionState as a generator.
3660 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3661 ast_value_factory()->dot_generator_object_string());
3662 function_state.set_generator_object_variable(temp);
3663 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003664
3665 // FormalParameterList ::
3666 // '(' (Identifier)*[','] ')'
3667 Expect(Token::LPAREN, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003668 scope->set_start_position(scanner()->location().beg_pos);
3669
3670 // We don't yet know if the function will be strict, so we cannot yet
3671 // produce errors for parameter names or duplicates. However, we remember
3672 // the locations of these errors if they occur and produce the errors later.
3673 Scanner::Location eval_args_error_log = Scanner::Location::invalid();
3674 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
Ben Murdoch257744e2011-11-30 15:57:28 +00003675 Scanner::Location reserved_loc = Scanner::Location::invalid();
Steve Block1e0659c2011-05-24 12:43:12 +01003676
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003677 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY ||
3678 (peek() == Token::RPAREN &&
3679 arity_restriction != FunctionLiteral::SETTER_ARITY);
Steve Blocka7e24c12009-10-30 11:49:00 +00003680 while (!done) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003681 bool is_strict_reserved = false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003682 const AstRawString* param_name =
3683 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
Steve Block1e0659c2011-05-24 12:43:12 +01003684
3685 // Store locations for possible future error reports.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003686 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) {
3687 eval_args_error_log = scanner()->location();
Steve Block1e0659c2011-05-24 12:43:12 +01003688 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003689 if (!reserved_loc.IsValid() && is_strict_reserved) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003690 reserved_loc = scanner()->location();
3691 }
3692 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) {
3693 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters;
3694 dupe_error_loc = scanner()->location();
Steve Block1e0659c2011-05-24 12:43:12 +01003695 }
3696
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003697 Variable* var = scope_->DeclareParameter(param_name, VAR);
3698 if (scope->strict_mode() == SLOPPY) {
3699 // TODO(sigurds) Mark every parameter as maybe assigned. This is a
3700 // conservative approximation necessary to account for parameters
3701 // that are assigned via the arguments array.
3702 var->set_maybe_assigned();
3703 }
3704
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08003705 num_parameters++;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003706 if (num_parameters > Code::kMaxArguments) {
3707 ReportMessage("too_many_parameters");
Steve Block1e0659c2011-05-24 12:43:12 +01003708 *ok = false;
3709 return NULL;
3710 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003711 if (arity_restriction == FunctionLiteral::SETTER_ARITY) break;
Steve Blocka7e24c12009-10-30 11:49:00 +00003712 done = (peek() == Token::RPAREN);
3713 if (!done) Expect(Token::COMMA, CHECK_OK);
3714 }
3715 Expect(Token::RPAREN, CHECK_OK);
3716
3717 Expect(Token::LBRACE, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00003718
3719 // If we have a named function expression, we add a local variable
3720 // declaration to the body of the function with the name of the
3721 // function and let it refer to the function itself (closure).
3722 // NOTE: We create a proxy and resolve it here so that in the
3723 // future we can change the AST to only refer to VariableProxies
3724 // instead of Variables and Proxis as is the case now.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003725 Variable* fvar = NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003726 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY;
3727 if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
3728 if (allow_harmony_scoping() && strict_mode() == STRICT) {
3729 fvar_init_op = Token::INIT_CONST;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003730 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003731 VariableMode fvar_mode =
3732 allow_harmony_scoping() && strict_mode() == STRICT
3733 ? CONST : CONST_LEGACY;
3734 DCHECK(function_name != NULL);
3735 fvar = new (zone())
3736 Variable(scope_, function_name, fvar_mode, true /* is valid LHS */,
3737 Variable::NORMAL, kCreatedInitialized, kNotAssigned,
3738 Interface::NewConst());
3739 VariableProxy* proxy = factory()->NewVariableProxy(fvar);
3740 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration(
3741 proxy, fvar_mode, scope_, RelocInfo::kNoPosition);
3742 scope_->DeclareFunctionVar(fvar_declaration);
Steve Blocka7e24c12009-10-30 11:49:00 +00003743 }
3744
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003745 // Determine if the function can be parsed lazily. Lazy parsing is different
3746 // from lazy compilation; we need to parse more eagerly than we compile.
3747
3748 // We can only parse lazily if we also compile lazily. The heuristics for
3749 // lazy compilation are:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003750 // - It must not have been prohibited by the caller to Parse (some callers
3751 // need a full AST).
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003752 // - The outer scope must allow lazy compilation of inner functions.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003753 // - The function mustn't be a function expression with an open parenthesis
3754 // before; we consider that a hint that the function will be called
3755 // immediately, and it would be a waste of time to make it lazily
3756 // compiled.
3757 // These are all things we can know at this point, without looking at the
3758 // function itself.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003759
3760 // In addition, we need to distinguish between these cases:
3761 // (function foo() {
3762 // bar = function() { return 1; }
3763 // })();
3764 // and
3765 // (function foo() {
3766 // var a = 1;
3767 // bar = function() { return a; }
3768 // })();
3769
3770 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
3771 // parenthesis before the function means that it will be called
3772 // immediately). The inner function *must* be parsed eagerly to resolve the
3773 // possible reference to the variable in foo's scope. However, it's possible
3774 // that it will be compiled lazily.
3775
3776 // To make this additional case work, both Parser and PreParser implement a
3777 // logic where only top-level functions will be parsed lazily.
3778 bool is_lazily_parsed = (mode() == PARSE_LAZILY &&
3779 scope_->AllowsLazyCompilation() &&
3780 !parenthesized_function_);
Ben Murdochb8e0da22011-05-16 14:20:40 +01003781 parenthesized_function_ = false; // The bit was set for this function only.
Steve Blocka7e24c12009-10-30 11:49:00 +00003782
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003783 if (is_lazily_parsed) {
3784 SkipLazyFunctionBody(function_name, &materialized_literal_count,
3785 &expected_property_count, CHECK_OK);
3786 } else {
3787 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
3788 is_generator, CHECK_OK);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003789 materialized_literal_count = function_state.materialized_literal_count();
3790 expected_property_count = function_state.expected_property_count();
3791 handler_count = function_state.handler_count();
Steve Blocka7e24c12009-10-30 11:49:00 +00003792 }
3793
Steve Block1e0659c2011-05-24 12:43:12 +01003794 // Validate strict mode.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003795 // Concise methods use StrictFormalParameters.
3796 if (strict_mode() == STRICT || IsConciseMethod(kind)) {
3797 CheckStrictFunctionNameAndParameters(function_name,
3798 name_is_strict_reserved,
3799 function_name_location,
3800 eval_args_error_log,
3801 dupe_error_loc,
3802 reserved_loc,
3803 CHECK_OK);
3804 }
3805 if (strict_mode() == STRICT) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003806 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
3807 CHECK_OK);
Steve Block1e0659c2011-05-24 12:43:12 +01003808 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003809 if (allow_harmony_scoping() && strict_mode() == STRICT) {
3810 CheckConflictingVarDeclarations(scope, CHECK_OK);
3811 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003812 }
Ben Murdoch8b112d22011-06-08 16:22:53 +01003813
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003814 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
3815 function_name, ast_value_factory(), scope, body,
3816 materialized_literal_count, expected_property_count, handler_count,
3817 num_parameters, duplicate_parameters, function_type,
3818 FunctionLiteral::kIsFunction, parenthesized, kind, pos);
3819 function_literal->set_function_token_position(function_token_pos);
Ben Murdoch8b112d22011-06-08 16:22:53 +01003820
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003821 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
Ben Murdoch8b112d22011-06-08 16:22:53 +01003822 return function_literal;
Steve Blocka7e24c12009-10-30 11:49:00 +00003823}
3824
3825
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003826void Parser::SkipLazyFunctionBody(const AstRawString* function_name,
3827 int* materialized_literal_count,
3828 int* expected_property_count,
3829 bool* ok) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003830 if (produce_cached_parse_data()) CHECK(log_);
3831
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003832 int function_block_pos = position();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003833 if (consume_cached_parse_data() && !cached_parse_data_->rejected()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003834 // If we have cached data, we use it to skip parsing the function body. The
3835 // data contains the information we need to construct the lazy function.
3836 FunctionEntry entry =
3837 cached_parse_data_->GetFunctionEntry(function_block_pos);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003838 // Check that cached data is valid. If not, mark it as invalid (the embedder
3839 // handles it). Note that end position greater than end of stream is safe,
3840 // and hard to check.
3841 if (entry.is_valid() && entry.end_pos() > function_block_pos) {
3842 scanner()->SeekForward(entry.end_pos() - 1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003843
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003844 scope_->set_end_position(entry.end_pos());
3845 Expect(Token::RBRACE, ok);
3846 if (!*ok) {
3847 return;
3848 }
3849 total_preparse_skipped_ += scope_->end_position() - function_block_pos;
3850 *materialized_literal_count = entry.literal_count();
3851 *expected_property_count = entry.property_count();
3852 scope_->SetStrictMode(entry.strict_mode());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003853 return;
3854 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003855 cached_parse_data_->Reject();
3856 }
3857 // With no cached data, we partially parse the function, without building an
3858 // AST. This gathers the data needed to build a lazy function.
3859 SingletonLogger logger;
3860 PreParser::PreParseResult result =
3861 ParseLazyFunctionBodyWithPreParser(&logger);
3862 if (result == PreParser::kPreParseStackOverflow) {
3863 // Propagate stack overflow.
3864 set_stack_overflow();
3865 *ok = false;
3866 return;
3867 }
3868 if (logger.has_error()) {
3869 ParserTraits::ReportMessageAt(
3870 Scanner::Location(logger.start(), logger.end()), logger.message(),
3871 logger.argument_opt(), logger.is_reference_error());
3872 *ok = false;
3873 return;
3874 }
3875 scope_->set_end_position(logger.end());
3876 Expect(Token::RBRACE, ok);
3877 if (!*ok) {
3878 return;
3879 }
3880 total_preparse_skipped_ += scope_->end_position() - function_block_pos;
3881 *materialized_literal_count = logger.literals();
3882 *expected_property_count = logger.properties();
3883 scope_->SetStrictMode(logger.strict_mode());
3884 if (produce_cached_parse_data()) {
3885 DCHECK(log_);
3886 // Position right after terminal '}'.
3887 int body_end = scanner()->location().end_pos;
3888 log_->LogFunction(function_block_pos, body_end, *materialized_literal_count,
3889 *expected_property_count, scope_->strict_mode());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003890 }
3891}
3892
3893
3894ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
3895 const AstRawString* function_name, int pos, Variable* fvar,
3896 Token::Value fvar_init_op, bool is_generator, bool* ok) {
3897 // Everything inside an eagerly parsed function will be parsed eagerly
3898 // (see comment above).
3899 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
3900 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone());
3901 if (fvar != NULL) {
3902 VariableProxy* fproxy = scope_->NewUnresolved(
3903 factory(), function_name, Interface::NewConst());
3904 fproxy->BindTo(fvar);
3905 body->Add(factory()->NewExpressionStatement(
3906 factory()->NewAssignment(fvar_init_op,
3907 fproxy,
3908 factory()->NewThisFunction(pos),
3909 RelocInfo::kNoPosition),
3910 RelocInfo::kNoPosition), zone());
3911 }
3912
3913 // For generators, allocate and yield an iterator on function entry.
3914 if (is_generator) {
3915 ZoneList<Expression*>* arguments =
3916 new(zone()) ZoneList<Expression*>(0, zone());
3917 CallRuntime* allocation = factory()->NewCallRuntime(
3918 ast_value_factory()->empty_string(),
3919 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), arguments,
3920 pos);
3921 VariableProxy* init_proxy = factory()->NewVariableProxy(
3922 function_state_->generator_object_variable());
3923 Assignment* assignment = factory()->NewAssignment(
3924 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
3925 VariableProxy* get_proxy = factory()->NewVariableProxy(
3926 function_state_->generator_object_variable());
3927 Yield* yield = factory()->NewYield(
3928 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition);
3929 body->Add(factory()->NewExpressionStatement(
3930 yield, RelocInfo::kNoPosition), zone());
3931 }
3932
3933 ParseSourceElements(body, Token::RBRACE, false, false, NULL, CHECK_OK);
3934
3935 if (is_generator) {
3936 VariableProxy* get_proxy = factory()->NewVariableProxy(
3937 function_state_->generator_object_variable());
3938 Expression* undefined =
3939 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition);
3940 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal,
3941 RelocInfo::kNoPosition);
3942 body->Add(factory()->NewExpressionStatement(
3943 yield, RelocInfo::kNoPosition), zone());
3944 }
3945
3946 Expect(Token::RBRACE, CHECK_OK);
3947 scope_->set_end_position(scanner()->location().end_pos);
3948
3949 return body;
3950}
3951
3952
3953PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003954 SingletonLogger* logger) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003955 // This function may be called on a background thread too; record only the
3956 // main thread preparse times.
3957 if (pre_parse_timer_ != NULL) {
3958 pre_parse_timer_->Start();
3959 }
3960 DCHECK_EQ(Token::LBRACE, scanner()->current_token());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003961
3962 if (reusable_preparser_ == NULL) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003963 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003964 reusable_preparser_->set_allow_lazy(true);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003965 reusable_preparser_->set_allow_natives(allow_natives());
3966 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping());
3967 reusable_preparser_->set_allow_harmony_modules(allow_harmony_modules());
3968 reusable_preparser_->set_allow_harmony_arrow_functions(
3969 allow_harmony_arrow_functions());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003970 reusable_preparser_->set_allow_harmony_numeric_literals(
3971 allow_harmony_numeric_literals());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003972 reusable_preparser_->set_allow_harmony_classes(allow_harmony_classes());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003973 reusable_preparser_->set_allow_harmony_object_literals(
3974 allow_harmony_object_literals());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003975 reusable_preparser_->set_allow_harmony_templates(allow_harmony_templates());
3976 reusable_preparser_->set_allow_harmony_sloppy(allow_harmony_sloppy());
3977 reusable_preparser_->set_allow_harmony_unicode(allow_harmony_unicode());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003978 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003979 PreParser::PreParseResult result =
3980 reusable_preparser_->PreParseLazyFunction(strict_mode(),
3981 is_generator(),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003982 logger);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003983 if (pre_parse_timer_ != NULL) {
3984 pre_parse_timer_->Stop();
3985 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003986 return result;
3987}
3988
3989
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003990ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name,
3991 Scanner::Location class_name_location,
3992 bool name_is_strict_reserved, int pos,
3993 bool* ok) {
3994 // All parts of a ClassDeclaration and ClassExpression are strict code.
3995 if (name_is_strict_reserved) {
3996 ReportMessageAt(class_name_location, "unexpected_strict_reserved");
3997 *ok = false;
3998 return NULL;
3999 }
4000 if (IsEvalOrArguments(name)) {
4001 ReportMessageAt(class_name_location, "strict_eval_arguments");
4002 *ok = false;
4003 return NULL;
4004 }
4005
4006 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
4007 BlockState block_state(&scope_, block_scope);
4008 scope_->SetStrictMode(STRICT);
4009 scope_->SetScopeName(name);
4010
4011 VariableProxy* proxy = NULL;
4012 if (name != NULL) {
4013 proxy = NewUnresolved(name, CONST, Interface::NewConst());
4014 Declaration* declaration =
4015 factory()->NewVariableDeclaration(proxy, CONST, block_scope, pos);
4016 Declare(declaration, true, CHECK_OK);
4017 }
4018
4019 Expression* extends = NULL;
4020 if (Check(Token::EXTENDS)) {
4021 block_scope->set_start_position(scanner()->location().end_pos);
4022 extends = ParseLeftHandSideExpression(CHECK_OK);
4023 } else {
4024 block_scope->set_start_position(scanner()->location().end_pos);
4025 }
4026
4027 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone());
4028 Expression* constructor = NULL;
4029 bool has_seen_constructor = false;
4030
4031 Expect(Token::LBRACE, CHECK_OK);
4032 while (peek() != Token::RBRACE) {
4033 if (Check(Token::SEMICOLON)) continue;
4034 if (fni_ != NULL) fni_->Enter();
4035 const bool in_class = true;
4036 const bool is_static = false;
4037 ObjectLiteral::Property* property = ParsePropertyDefinition(
4038 NULL, in_class, is_static, &has_seen_constructor, CHECK_OK);
4039
4040 if (has_seen_constructor && constructor == NULL) {
4041 constructor = GetPropertyValue(property);
4042 } else {
4043 properties->Add(property, zone());
4044 }
4045
4046 if (fni_ != NULL) {
4047 fni_->Infer();
4048 fni_->Leave();
4049 }
4050 }
4051
4052 Expect(Token::RBRACE, CHECK_OK);
4053 int end_pos = scanner()->location().end_pos;
4054
4055 if (constructor == NULL) {
4056 constructor =
4057 DefaultConstructor(extends != NULL, block_scope, pos, end_pos);
4058 }
4059
4060 block_scope->set_end_position(end_pos);
4061 block_scope = block_scope->FinalizeBlockScope();
4062
4063 if (name != NULL) {
4064 DCHECK_NOT_NULL(proxy);
4065 DCHECK_NOT_NULL(block_scope);
4066 proxy->var()->set_initializer_position(end_pos);
4067 }
4068
4069 return factory()->NewClassLiteral(name, block_scope, proxy, extends,
4070 constructor, properties, pos, end_pos);
4071}
4072
4073
Steve Blocka7e24c12009-10-30 11:49:00 +00004074Expression* Parser::ParseV8Intrinsic(bool* ok) {
4075 // CallRuntime ::
4076 // '%' Identifier Arguments
4077
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004078 int pos = peek_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00004079 Expect(Token::MOD, CHECK_OK);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004080 // Allow "eval" or "arguments" for backward compatibility.
4081 const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
Steve Blocka7e24c12009-10-30 11:49:00 +00004082 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01004083
4084 if (extension_ != NULL) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004085 // The extension structures are only accessible while parsing the
4086 // very first time not when reparsing because of lazy compilation.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004087 scope_->DeclarationScope()->ForceEagerCompilation();
Steve Blocka7e24c12009-10-30 11:49:00 +00004088 }
4089
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004090 const Runtime::Function* function = Runtime::FunctionForName(name->string());
Steve Blocka7e24c12009-10-30 11:49:00 +00004091
Kristian Monsen0d5e1162010-09-30 15:31:59 +01004092 // Check for built-in IS_VAR macro.
4093 if (function != NULL &&
4094 function->intrinsic_type == Runtime::RUNTIME &&
4095 function->function_id == Runtime::kIS_VAR) {
4096 // %IS_VAR(x) evaluates to x if x is a variable,
4097 // leads to a parse error otherwise. Could be implemented as an
4098 // inline function %_IS_VAR(x) to eliminate this special case.
4099 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
4100 return args->at(0);
4101 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004102 ReportMessage("not_isvar");
Steve Block6ded16b2010-05-10 14:33:55 +01004103 *ok = false;
4104 return NULL;
Steve Block6ded16b2010-05-10 14:33:55 +01004105 }
4106 }
4107
Kristian Monsen0d5e1162010-09-30 15:31:59 +01004108 // Check that the expected number of arguments are being passed.
4109 if (function != NULL &&
4110 function->nargs != -1 &&
4111 function->nargs != args->length()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004112 ReportMessage("illegal_access");
4113 *ok = false;
4114 return NULL;
4115 }
4116
4117 // Check that the function is defined if it's an inline runtime call.
4118 if (function == NULL && name->FirstCharacter() == '_') {
4119 ParserTraits::ReportMessage("not_defined", name);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01004120 *ok = false;
4121 return NULL;
4122 }
4123
4124 // We have a valid intrinsics call or a call to a builtin.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004125 return factory()->NewCallRuntime(name, function, args, pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00004126}
4127
4128
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004129Literal* Parser::GetLiteralUndefined(int position) {
4130 return factory()->NewUndefinedLiteral(position);
Steve Block1e0659c2011-05-24 12:43:12 +01004131}
4132
4133
Ben Murdoch589d6972011-11-30 16:04:58 +00004134void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
4135 Declaration* decl = scope->CheckConflictingVarDeclarations();
4136 if (decl != NULL) {
4137 // In harmony mode we treat conflicting variable bindinds as early
4138 // errors. See ES5 16 for a definition of early errors.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004139 const AstRawString* name = decl->proxy()->raw_name();
Ben Murdoch589d6972011-11-30 16:04:58 +00004140 int position = decl->proxy()->position();
4141 Scanner::Location location = position == RelocInfo::kNoPosition
4142 ? Scanner::Location::invalid()
4143 : Scanner::Location(position, position + 1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004144 ParserTraits::ReportMessageAt(location, "var_redeclaration", name);
Ben Murdoch589d6972011-11-30 16:04:58 +00004145 *ok = false;
4146 }
4147}
4148
4149
Steve Blocka7e24c12009-10-30 11:49:00 +00004150// ----------------------------------------------------------------------------
4151// Parser support
4152
4153
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004154bool Parser::TargetStackContainsLabel(const AstRawString* label) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004155 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4156 BreakableStatement* stat = t->node()->AsBreakableStatement();
4157 if (stat != NULL && ContainsLabel(stat->labels(), label))
4158 return true;
4159 }
4160 return false;
4161}
4162
4163
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004164BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
4165 bool* ok) {
4166 bool anonymous = label == NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00004167 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4168 BreakableStatement* stat = t->node()->AsBreakableStatement();
4169 if (stat == NULL) continue;
4170 if ((anonymous && stat->is_target_for_anonymous()) ||
4171 (!anonymous && ContainsLabel(stat->labels(), label))) {
4172 RegisterTargetUse(stat->break_target(), t->previous());
4173 return stat;
4174 }
4175 }
4176 return NULL;
4177}
4178
4179
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004180IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
Steve Blocka7e24c12009-10-30 11:49:00 +00004181 bool* ok) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004182 bool anonymous = label == NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00004183 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4184 IterationStatement* stat = t->node()->AsIterationStatement();
4185 if (stat == NULL) continue;
4186
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004187 DCHECK(stat->is_target_for_anonymous());
Steve Blocka7e24c12009-10-30 11:49:00 +00004188 if (anonymous || ContainsLabel(stat->labels(), label)) {
4189 RegisterTargetUse(stat->continue_target(), t->previous());
4190 return stat;
4191 }
4192 }
4193 return NULL;
4194}
4195
4196
Ben Murdoch8b112d22011-06-08 16:22:53 +01004197void Parser::RegisterTargetUse(Label* target, Target* stop) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004198 // Register that a break target found at the given stop in the
4199 // target stack has been used from the top of the target stack. Add
4200 // the break target to any TargetCollectors passed on the stack.
4201 for (Target* t = target_stack_; t != stop; t = t->previous()) {
4202 TargetCollector* collector = t->node()->AsTargetCollector();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004203 if (collector != NULL) collector->AddTarget(target, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00004204 }
4205}
4206
4207
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004208void Parser::HandleSourceURLComments() {
4209 if (scanner_.source_url()->length() > 0) {
4210 Handle<String> source_url = scanner_.source_url()->Internalize(isolate());
4211 info_->script()->set_source_url(*source_url);
4212 }
4213 if (scanner_.source_mapping_url()->length() > 0) {
4214 Handle<String> source_mapping_url =
4215 scanner_.source_mapping_url()->Internalize(isolate());
4216 info_->script()->set_source_mapping_url(*source_mapping_url);
4217 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004218}
4219
4220
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004221void Parser::ThrowPendingError() {
4222 DCHECK(ast_value_factory()->IsInternalized());
4223 if (has_pending_error_) {
4224 MessageLocation location(script(), pending_error_location_.beg_pos,
4225 pending_error_location_.end_pos);
4226 Factory* factory = isolate()->factory();
4227 bool has_arg =
4228 pending_error_arg_ != NULL || pending_error_char_arg_ != NULL;
4229 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0);
4230 if (pending_error_arg_ != NULL) {
4231 Handle<String> arg_string = pending_error_arg_->string();
4232 elements->set(0, *arg_string);
4233 } else if (pending_error_char_arg_ != NULL) {
4234 Handle<String> arg_string =
4235 factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_))
4236 .ToHandleChecked();
4237 elements->set(0, *arg_string);
4238 }
4239 isolate()->debug()->OnCompileError(script());
4240
4241 Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
4242 Handle<Object> error;
4243 MaybeHandle<Object> maybe_error =
4244 pending_error_is_reference_error_
4245 ? factory->NewReferenceError(pending_error_message_, array)
4246 : factory->NewSyntaxError(pending_error_message_, array);
4247 if (maybe_error.ToHandle(&error)) isolate()->Throw(*error, &location);
4248 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004249}
4250
4251
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004252void Parser::Internalize() {
4253 // Internalize strings.
4254 ast_value_factory()->Internalize(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00004255
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004256 // Error processing.
4257 if (info()->function() == NULL) {
4258 if (stack_overflow()) {
4259 isolate()->StackOverflow();
4260 } else {
4261 ThrowPendingError();
Steve Blocka7e24c12009-10-30 11:49:00 +00004262 }
4263 }
Steve Block1e0659c2011-05-24 12:43:12 +01004264
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004265 // Move statistics to Isolate.
4266 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
4267 ++feature) {
4268 for (int i = 0; i < use_counts_[feature]; ++i) {
4269 isolate()->CountUsage(v8::Isolate::UseCounterFeature(feature));
4270 }
4271 }
4272 isolate()->counters()->total_preparse_skipped()->Increment(
4273 total_preparse_skipped_);
Steve Blocka7e24c12009-10-30 11:49:00 +00004274}
4275
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004276
Leon Clarke4515c472010-02-03 11:58:03 +00004277// ----------------------------------------------------------------------------
Steve Blocka7e24c12009-10-30 11:49:00 +00004278// Regular expressions
4279
4280
4281RegExpParser::RegExpParser(FlatStringReader* in,
4282 Handle<String>* error,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004283 bool multiline,
4284 Zone* zone)
4285 : isolate_(zone->isolate()),
4286 zone_(zone),
Steve Block44f0eee2011-05-26 01:26:41 +01004287 error_(error),
4288 captures_(NULL),
4289 in_(in),
4290 current_(kEndMarker),
4291 next_pos_(0),
4292 capture_count_(0),
4293 has_more_(true),
4294 multiline_(multiline),
4295 simple_(false),
4296 contains_anchor_(false),
4297 is_scanned_for_captures_(false),
4298 failed_(false) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01004299 Advance();
Steve Blocka7e24c12009-10-30 11:49:00 +00004300}
4301
4302
4303uc32 RegExpParser::Next() {
4304 if (has_next()) {
4305 return in()->Get(next_pos_);
4306 } else {
4307 return kEndMarker;
4308 }
4309}
4310
4311
4312void RegExpParser::Advance() {
4313 if (next_pos_ < in()->length()) {
Steve Block44f0eee2011-05-26 01:26:41 +01004314 StackLimitCheck check(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00004315 if (check.HasOverflowed()) {
Steve Block44f0eee2011-05-26 01:26:41 +01004316 ReportError(CStrVector(Isolate::kStackOverflowMessage));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004317 } else if (zone()->excess_allocation()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004318 ReportError(CStrVector("Regular expression too large"));
4319 } else {
4320 current_ = in()->Get(next_pos_);
4321 next_pos_++;
4322 }
4323 } else {
4324 current_ = kEndMarker;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004325 // Advance so that position() points to 1-after-the-last-character. This is
4326 // important so that Reset() to this position works correctly.
4327 next_pos_ = in()->length() + 1;
Steve Blocka7e24c12009-10-30 11:49:00 +00004328 has_more_ = false;
4329 }
4330}
4331
4332
4333void RegExpParser::Reset(int pos) {
4334 next_pos_ = pos;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004335 has_more_ = (pos < in()->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00004336 Advance();
4337}
4338
4339
4340void RegExpParser::Advance(int dist) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01004341 next_pos_ += dist - 1;
4342 Advance();
Steve Blocka7e24c12009-10-30 11:49:00 +00004343}
4344
4345
4346bool RegExpParser::simple() {
4347 return simple_;
4348}
4349
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004350
Steve Blocka7e24c12009-10-30 11:49:00 +00004351RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
4352 failed_ = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004353 *error_ = isolate()->factory()->NewStringFromAscii(message).ToHandleChecked();
Steve Blocka7e24c12009-10-30 11:49:00 +00004354 // Zip to the end to make sure the no more input is read.
4355 current_ = kEndMarker;
4356 next_pos_ = in()->length();
4357 return NULL;
4358}
4359
4360
4361// Pattern ::
4362// Disjunction
4363RegExpTree* RegExpParser::ParsePattern() {
4364 RegExpTree* result = ParseDisjunction(CHECK_FAILED);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004365 DCHECK(!has_more());
Steve Blocka7e24c12009-10-30 11:49:00 +00004366 // If the result of parsing is a literal string atom, and it has the
4367 // same length as the input, then the atom is identical to the input.
4368 if (result->IsAtom() && result->AsAtom()->length() == in()->length()) {
4369 simple_ = true;
4370 }
4371 return result;
4372}
4373
4374
4375// Disjunction ::
4376// Alternative
4377// Alternative | Disjunction
4378// Alternative ::
4379// [empty]
4380// Term Alternative
4381// Term ::
4382// Assertion
4383// Atom
4384// Atom Quantifier
4385RegExpTree* RegExpParser::ParseDisjunction() {
4386 // Used to store current state while parsing subexpressions.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004387 RegExpParserState initial_state(NULL, INITIAL, 0, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00004388 RegExpParserState* stored_state = &initial_state;
4389 // Cache the builder in a local variable for quick access.
4390 RegExpBuilder* builder = initial_state.builder();
4391 while (true) {
4392 switch (current()) {
4393 case kEndMarker:
4394 if (stored_state->IsSubexpression()) {
4395 // Inside a parenthesized group when hitting end of input.
4396 ReportError(CStrVector("Unterminated group") CHECK_FAILED);
4397 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004398 DCHECK_EQ(INITIAL, stored_state->group_type());
Steve Blocka7e24c12009-10-30 11:49:00 +00004399 // Parsing completed successfully.
4400 return builder->ToRegExp();
4401 case ')': {
4402 if (!stored_state->IsSubexpression()) {
4403 ReportError(CStrVector("Unmatched ')'") CHECK_FAILED);
4404 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004405 DCHECK_NE(INITIAL, stored_state->group_type());
Steve Blocka7e24c12009-10-30 11:49:00 +00004406
4407 Advance();
4408 // End disjunction parsing and convert builder content to new single
4409 // regexp atom.
4410 RegExpTree* body = builder->ToRegExp();
4411
4412 int end_capture_index = captures_started();
4413
4414 int capture_index = stored_state->capture_index();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004415 SubexpressionType group_type = stored_state->group_type();
Steve Blocka7e24c12009-10-30 11:49:00 +00004416
4417 // Restore previous state.
4418 stored_state = stored_state->previous_state();
4419 builder = stored_state->builder();
4420
4421 // Build result of subexpression.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004422 if (group_type == CAPTURE) {
Ben Murdoch8b112d22011-06-08 16:22:53 +01004423 RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index);
Steve Blocka7e24c12009-10-30 11:49:00 +00004424 captures_->at(capture_index - 1) = capture;
4425 body = capture;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004426 } else if (group_type != GROUPING) {
4427 DCHECK(group_type == POSITIVE_LOOKAHEAD ||
4428 group_type == NEGATIVE_LOOKAHEAD);
4429 bool is_positive = (group_type == POSITIVE_LOOKAHEAD);
Ben Murdoch8b112d22011-06-08 16:22:53 +01004430 body = new(zone()) RegExpLookahead(body,
Steve Blocka7e24c12009-10-30 11:49:00 +00004431 is_positive,
4432 end_capture_index - capture_index,
4433 capture_index);
4434 }
4435 builder->AddAtom(body);
Ben Murdoche0cee9b2011-05-25 10:26:03 +01004436 // For compatability with JSC and ES3, we allow quantifiers after
4437 // lookaheads, and break in all cases.
Steve Blocka7e24c12009-10-30 11:49:00 +00004438 break;
4439 }
4440 case '|': {
4441 Advance();
4442 builder->NewAlternative();
4443 continue;
4444 }
4445 case '*':
4446 case '+':
4447 case '?':
4448 return ReportError(CStrVector("Nothing to repeat"));
4449 case '^': {
4450 Advance();
4451 if (multiline_) {
4452 builder->AddAssertion(
Ben Murdoch8b112d22011-06-08 16:22:53 +01004453 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE));
Steve Blocka7e24c12009-10-30 11:49:00 +00004454 } else {
4455 builder->AddAssertion(
Ben Murdoch8b112d22011-06-08 16:22:53 +01004456 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
Steve Blocka7e24c12009-10-30 11:49:00 +00004457 set_contains_anchor();
4458 }
4459 continue;
4460 }
4461 case '$': {
4462 Advance();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004463 RegExpAssertion::AssertionType assertion_type =
Steve Blocka7e24c12009-10-30 11:49:00 +00004464 multiline_ ? RegExpAssertion::END_OF_LINE :
4465 RegExpAssertion::END_OF_INPUT;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004466 builder->AddAssertion(new(zone()) RegExpAssertion(assertion_type));
Steve Blocka7e24c12009-10-30 11:49:00 +00004467 continue;
4468 }
4469 case '.': {
4470 Advance();
4471 // everything except \x0a, \x0d, \u2028 and \u2029
Ben Murdoch257744e2011-11-30 15:57:28 +00004472 ZoneList<CharacterRange>* ranges =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004473 new(zone()) ZoneList<CharacterRange>(2, zone());
4474 CharacterRange::AddClassEscape('.', ranges, zone());
Ben Murdoch8b112d22011-06-08 16:22:53 +01004475 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00004476 builder->AddAtom(atom);
4477 break;
4478 }
4479 case '(': {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004480 SubexpressionType subexpr_type = CAPTURE;
Steve Blocka7e24c12009-10-30 11:49:00 +00004481 Advance();
4482 if (current() == '?') {
4483 switch (Next()) {
4484 case ':':
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004485 subexpr_type = GROUPING;
Steve Blocka7e24c12009-10-30 11:49:00 +00004486 break;
4487 case '=':
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004488 subexpr_type = POSITIVE_LOOKAHEAD;
Steve Blocka7e24c12009-10-30 11:49:00 +00004489 break;
4490 case '!':
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004491 subexpr_type = NEGATIVE_LOOKAHEAD;
Steve Blocka7e24c12009-10-30 11:49:00 +00004492 break;
4493 default:
4494 ReportError(CStrVector("Invalid group") CHECK_FAILED);
4495 break;
4496 }
4497 Advance(2);
4498 } else {
4499 if (captures_ == NULL) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004500 captures_ = new(zone()) ZoneList<RegExpCapture*>(2, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00004501 }
4502 if (captures_started() >= kMaxCaptures) {
4503 ReportError(CStrVector("Too many captures") CHECK_FAILED);
4504 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004505 captures_->Add(NULL, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00004506 }
4507 // Store current state and begin new disjunction parsing.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004508 stored_state = new(zone()) RegExpParserState(stored_state, subexpr_type,
4509 captures_started(), zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00004510 builder = stored_state->builder();
Ben Murdoche0cee9b2011-05-25 10:26:03 +01004511 continue;
Steve Blocka7e24c12009-10-30 11:49:00 +00004512 }
4513 case '[': {
4514 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED);
4515 builder->AddAtom(atom);
4516 break;
4517 }
4518 // Atom ::
4519 // \ AtomEscape
4520 case '\\':
4521 switch (Next()) {
4522 case kEndMarker:
4523 return ReportError(CStrVector("\\ at end of pattern"));
4524 case 'b':
4525 Advance(2);
4526 builder->AddAssertion(
Ben Murdoch8b112d22011-06-08 16:22:53 +01004527 new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
Steve Blocka7e24c12009-10-30 11:49:00 +00004528 continue;
4529 case 'B':
4530 Advance(2);
4531 builder->AddAssertion(
Ben Murdoch8b112d22011-06-08 16:22:53 +01004532 new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
Steve Blocka7e24c12009-10-30 11:49:00 +00004533 continue;
Ben Murdoche0cee9b2011-05-25 10:26:03 +01004534 // AtomEscape ::
4535 // CharacterClassEscape
4536 //
4537 // CharacterClassEscape :: one of
4538 // d D s S w W
Steve Blocka7e24c12009-10-30 11:49:00 +00004539 case 'd': case 'D': case 's': case 'S': case 'w': case 'W': {
4540 uc32 c = Next();
4541 Advance(2);
Ben Murdoch257744e2011-11-30 15:57:28 +00004542 ZoneList<CharacterRange>* ranges =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004543 new(zone()) ZoneList<CharacterRange>(2, zone());
4544 CharacterRange::AddClassEscape(c, ranges, zone());
Ben Murdoch8b112d22011-06-08 16:22:53 +01004545 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00004546 builder->AddAtom(atom);
4547 break;
4548 }
4549 case '1': case '2': case '3': case '4': case '5': case '6':
4550 case '7': case '8': case '9': {
4551 int index = 0;
4552 if (ParseBackReferenceIndex(&index)) {
4553 RegExpCapture* capture = NULL;
4554 if (captures_ != NULL && index <= captures_->length()) {
4555 capture = captures_->at(index - 1);
4556 }
4557 if (capture == NULL) {
4558 builder->AddEmpty();
4559 break;
4560 }
Ben Murdoch8b112d22011-06-08 16:22:53 +01004561 RegExpTree* atom = new(zone()) RegExpBackReference(capture);
Steve Blocka7e24c12009-10-30 11:49:00 +00004562 builder->AddAtom(atom);
4563 break;
4564 }
4565 uc32 first_digit = Next();
4566 if (first_digit == '8' || first_digit == '9') {
4567 // Treat as identity escape
4568 builder->AddCharacter(first_digit);
4569 Advance(2);
4570 break;
4571 }
4572 }
4573 // FALLTHROUGH
4574 case '0': {
4575 Advance();
4576 uc32 octal = ParseOctalLiteral();
4577 builder->AddCharacter(octal);
4578 break;
4579 }
4580 // ControlEscape :: one of
4581 // f n r t v
4582 case 'f':
4583 Advance(2);
4584 builder->AddCharacter('\f');
4585 break;
4586 case 'n':
4587 Advance(2);
4588 builder->AddCharacter('\n');
4589 break;
4590 case 'r':
4591 Advance(2);
4592 builder->AddCharacter('\r');
4593 break;
4594 case 't':
4595 Advance(2);
4596 builder->AddCharacter('\t');
4597 break;
4598 case 'v':
4599 Advance(2);
4600 builder->AddCharacter('\v');
4601 break;
4602 case 'c': {
Ben Murdoch086aeea2011-05-13 15:57:08 +01004603 Advance();
4604 uc32 controlLetter = Next();
4605 // Special case if it is an ASCII letter.
4606 // Convert lower case letters to uppercase.
4607 uc32 letter = controlLetter & ~('a' ^ 'A');
4608 if (letter < 'A' || 'Z' < letter) {
4609 // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
4610 // This is outside the specification. We match JSC in
4611 // reading the backslash as a literal character instead
4612 // of as starting an escape.
4613 builder->AddCharacter('\\');
4614 } else {
4615 Advance(2);
4616 builder->AddCharacter(controlLetter & 0x1f);
4617 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004618 break;
4619 }
4620 case 'x': {
4621 Advance(2);
4622 uc32 value;
4623 if (ParseHexEscape(2, &value)) {
4624 builder->AddCharacter(value);
4625 } else {
4626 builder->AddCharacter('x');
4627 }
4628 break;
4629 }
4630 case 'u': {
4631 Advance(2);
4632 uc32 value;
4633 if (ParseHexEscape(4, &value)) {
4634 builder->AddCharacter(value);
4635 } else {
4636 builder->AddCharacter('u');
4637 }
4638 break;
4639 }
4640 default:
4641 // Identity escape.
4642 builder->AddCharacter(Next());
4643 Advance(2);
4644 break;
4645 }
4646 break;
4647 case '{': {
4648 int dummy;
4649 if (ParseIntervalQuantifier(&dummy, &dummy)) {
4650 ReportError(CStrVector("Nothing to repeat") CHECK_FAILED);
4651 }
4652 // fallthrough
4653 }
4654 default:
4655 builder->AddCharacter(current());
4656 Advance();
4657 break;
4658 } // end switch(current())
4659
4660 int min;
4661 int max;
4662 switch (current()) {
4663 // QuantifierPrefix ::
4664 // *
4665 // +
4666 // ?
4667 // {
4668 case '*':
4669 min = 0;
4670 max = RegExpTree::kInfinity;
4671 Advance();
4672 break;
4673 case '+':
4674 min = 1;
4675 max = RegExpTree::kInfinity;
4676 Advance();
4677 break;
4678 case '?':
4679 min = 0;
4680 max = 1;
4681 Advance();
4682 break;
4683 case '{':
4684 if (ParseIntervalQuantifier(&min, &max)) {
4685 if (max < min) {
4686 ReportError(CStrVector("numbers out of order in {} quantifier.")
4687 CHECK_FAILED);
4688 }
4689 break;
4690 } else {
4691 continue;
4692 }
4693 default:
4694 continue;
4695 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004696 RegExpQuantifier::QuantifierType quantifier_type = RegExpQuantifier::GREEDY;
Steve Blocka7e24c12009-10-30 11:49:00 +00004697 if (current() == '?') {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004698 quantifier_type = RegExpQuantifier::NON_GREEDY;
Leon Clarkee46be812010-01-19 14:06:41 +00004699 Advance();
4700 } else if (FLAG_regexp_possessive_quantifier && current() == '+') {
4701 // FLAG_regexp_possessive_quantifier is a debug-only flag.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004702 quantifier_type = RegExpQuantifier::POSSESSIVE;
Steve Blocka7e24c12009-10-30 11:49:00 +00004703 Advance();
4704 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004705 builder->AddQuantifierToAtom(min, max, quantifier_type);
Steve Blocka7e24c12009-10-30 11:49:00 +00004706 }
4707}
4708
Steve Blocka7e24c12009-10-30 11:49:00 +00004709
4710#ifdef DEBUG
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004711// Currently only used in an DCHECK.
Steve Blocka7e24c12009-10-30 11:49:00 +00004712static bool IsSpecialClassEscape(uc32 c) {
4713 switch (c) {
4714 case 'd': case 'D':
4715 case 's': case 'S':
4716 case 'w': case 'W':
4717 return true;
4718 default:
4719 return false;
4720 }
4721}
4722#endif
4723
4724
4725// In order to know whether an escape is a backreference or not we have to scan
4726// the entire regexp and find the number of capturing parentheses. However we
4727// don't want to scan the regexp twice unless it is necessary. This mini-parser
4728// is called when needed. It can see the difference between capturing and
4729// noncapturing parentheses and can skip character classes and backslash-escaped
4730// characters.
4731void RegExpParser::ScanForCaptures() {
4732 // Start with captures started previous to current position
4733 int capture_count = captures_started();
4734 // Add count of captures after this position.
4735 int n;
4736 while ((n = current()) != kEndMarker) {
4737 Advance();
4738 switch (n) {
4739 case '\\':
4740 Advance();
4741 break;
4742 case '[': {
4743 int c;
4744 while ((c = current()) != kEndMarker) {
4745 Advance();
4746 if (c == '\\') {
4747 Advance();
4748 } else {
4749 if (c == ']') break;
4750 }
4751 }
4752 break;
4753 }
4754 case '(':
4755 if (current() != '?') capture_count++;
4756 break;
4757 }
4758 }
4759 capture_count_ = capture_count;
4760 is_scanned_for_captures_ = true;
4761}
4762
4763
4764bool RegExpParser::ParseBackReferenceIndex(int* index_out) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004765 DCHECK_EQ('\\', current());
4766 DCHECK('1' <= Next() && Next() <= '9');
Steve Blocka7e24c12009-10-30 11:49:00 +00004767 // Try to parse a decimal literal that is no greater than the total number
4768 // of left capturing parentheses in the input.
4769 int start = position();
4770 int value = Next() - '0';
4771 Advance(2);
4772 while (true) {
4773 uc32 c = current();
4774 if (IsDecimalDigit(c)) {
4775 value = 10 * value + (c - '0');
4776 if (value > kMaxCaptures) {
4777 Reset(start);
4778 return false;
4779 }
4780 Advance();
4781 } else {
4782 break;
4783 }
4784 }
4785 if (value > captures_started()) {
4786 if (!is_scanned_for_captures_) {
4787 int saved_position = position();
4788 ScanForCaptures();
4789 Reset(saved_position);
4790 }
4791 if (value > capture_count_) {
4792 Reset(start);
4793 return false;
4794 }
4795 }
4796 *index_out = value;
4797 return true;
4798}
4799
4800
4801// QuantifierPrefix ::
4802// { DecimalDigits }
4803// { DecimalDigits , }
4804// { DecimalDigits , DecimalDigits }
4805//
4806// Returns true if parsing succeeds, and set the min_out and max_out
4807// values. Values are truncated to RegExpTree::kInfinity if they overflow.
4808bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004809 DCHECK_EQ(current(), '{');
Steve Blocka7e24c12009-10-30 11:49:00 +00004810 int start = position();
4811 Advance();
4812 int min = 0;
4813 if (!IsDecimalDigit(current())) {
4814 Reset(start);
4815 return false;
4816 }
4817 while (IsDecimalDigit(current())) {
4818 int next = current() - '0';
4819 if (min > (RegExpTree::kInfinity - next) / 10) {
4820 // Overflow. Skip past remaining decimal digits and return -1.
4821 do {
4822 Advance();
4823 } while (IsDecimalDigit(current()));
4824 min = RegExpTree::kInfinity;
4825 break;
4826 }
4827 min = 10 * min + next;
4828 Advance();
4829 }
4830 int max = 0;
4831 if (current() == '}') {
4832 max = min;
4833 Advance();
4834 } else if (current() == ',') {
4835 Advance();
4836 if (current() == '}') {
4837 max = RegExpTree::kInfinity;
4838 Advance();
4839 } else {
4840 while (IsDecimalDigit(current())) {
4841 int next = current() - '0';
4842 if (max > (RegExpTree::kInfinity - next) / 10) {
4843 do {
4844 Advance();
4845 } while (IsDecimalDigit(current()));
4846 max = RegExpTree::kInfinity;
4847 break;
4848 }
4849 max = 10 * max + next;
4850 Advance();
4851 }
4852 if (current() != '}') {
4853 Reset(start);
4854 return false;
4855 }
4856 Advance();
4857 }
4858 } else {
4859 Reset(start);
4860 return false;
4861 }
4862 *min_out = min;
4863 *max_out = max;
4864 return true;
4865}
4866
4867
Steve Blocka7e24c12009-10-30 11:49:00 +00004868uc32 RegExpParser::ParseOctalLiteral() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004869 DCHECK(('0' <= current() && current() <= '7') || current() == kEndMarker);
Steve Blocka7e24c12009-10-30 11:49:00 +00004870 // For compatibility with some other browsers (not all), we parse
4871 // up to three octal digits with a value below 256.
4872 uc32 value = current() - '0';
4873 Advance();
4874 if ('0' <= current() && current() <= '7') {
4875 value = value * 8 + current() - '0';
4876 Advance();
4877 if (value < 32 && '0' <= current() && current() <= '7') {
4878 value = value * 8 + current() - '0';
4879 Advance();
4880 }
4881 }
4882 return value;
4883}
4884
4885
4886bool RegExpParser::ParseHexEscape(int length, uc32 *value) {
4887 int start = position();
4888 uc32 val = 0;
4889 bool done = false;
4890 for (int i = 0; !done; i++) {
4891 uc32 c = current();
4892 int d = HexValue(c);
4893 if (d < 0) {
4894 Reset(start);
4895 return false;
4896 }
4897 val = val * 16 + d;
4898 Advance();
4899 if (i == length - 1) {
4900 done = true;
4901 }
4902 }
4903 *value = val;
4904 return true;
4905}
4906
4907
4908uc32 RegExpParser::ParseClassCharacterEscape() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004909 DCHECK(current() == '\\');
4910 DCHECK(has_next() && !IsSpecialClassEscape(Next()));
Steve Blocka7e24c12009-10-30 11:49:00 +00004911 Advance();
4912 switch (current()) {
4913 case 'b':
4914 Advance();
4915 return '\b';
4916 // ControlEscape :: one of
4917 // f n r t v
4918 case 'f':
4919 Advance();
4920 return '\f';
4921 case 'n':
4922 Advance();
4923 return '\n';
4924 case 'r':
4925 Advance();
4926 return '\r';
4927 case 't':
4928 Advance();
4929 return '\t';
4930 case 'v':
4931 Advance();
4932 return '\v';
Ben Murdoch086aeea2011-05-13 15:57:08 +01004933 case 'c': {
4934 uc32 controlLetter = Next();
4935 uc32 letter = controlLetter & ~('A' ^ 'a');
4936 // For compatibility with JSC, inside a character class
4937 // we also accept digits and underscore as control characters.
4938 if ((controlLetter >= '0' && controlLetter <= '9') ||
4939 controlLetter == '_' ||
4940 (letter >= 'A' && letter <= 'Z')) {
4941 Advance(2);
4942 // Control letters mapped to ASCII control characters in the range
4943 // 0x00-0x1f.
4944 return controlLetter & 0x1f;
4945 }
4946 // We match JSC in reading the backslash as a literal
4947 // character instead of as starting an escape.
4948 return '\\';
4949 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004950 case '0': case '1': case '2': case '3': case '4': case '5':
4951 case '6': case '7':
4952 // For compatibility, we interpret a decimal escape that isn't
4953 // a back reference (and therefore either \0 or not valid according
4954 // to the specification) as a 1..3 digit octal character code.
4955 return ParseOctalLiteral();
4956 case 'x': {
4957 Advance();
4958 uc32 value;
4959 if (ParseHexEscape(2, &value)) {
4960 return value;
4961 }
4962 // If \x is not followed by a two-digit hexadecimal, treat it
4963 // as an identity escape.
4964 return 'x';
4965 }
4966 case 'u': {
4967 Advance();
4968 uc32 value;
4969 if (ParseHexEscape(4, &value)) {
4970 return value;
4971 }
4972 // If \u is not followed by a four-digit hexadecimal, treat it
4973 // as an identity escape.
4974 return 'u';
4975 }
4976 default: {
4977 // Extended identity escape. We accept any character that hasn't
4978 // been matched by a more specific case, not just the subset required
4979 // by the ECMAScript specification.
4980 uc32 result = current();
4981 Advance();
4982 return result;
4983 }
4984 }
4985 return 0;
4986}
4987
4988
4989CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004990 DCHECK_EQ(0, *char_class);
Steve Blocka7e24c12009-10-30 11:49:00 +00004991 uc32 first = current();
4992 if (first == '\\') {
4993 switch (Next()) {
4994 case 'w': case 'W': case 'd': case 'D': case 's': case 'S': {
4995 *char_class = Next();
4996 Advance(2);
4997 return CharacterRange::Singleton(0); // Return dummy value.
4998 }
4999 case kEndMarker:
5000 return ReportError(CStrVector("\\ at end of pattern"));
5001 default:
5002 uc32 c = ParseClassCharacterEscape(CHECK_FAILED);
5003 return CharacterRange::Singleton(c);
5004 }
5005 } else {
5006 Advance();
5007 return CharacterRange::Singleton(first);
5008 }
5009}
5010
5011
Ben Murdochb0fe1622011-05-05 13:52:32 +01005012static const uc16 kNoCharClass = 0;
5013
5014// Adds range or pre-defined character class to character ranges.
5015// If char_class is not kInvalidClass, it's interpreted as a class
5016// escape (i.e., 's' means whitespace, from '\s').
5017static inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges,
5018 uc16 char_class,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005019 CharacterRange range,
5020 Zone* zone) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01005021 if (char_class != kNoCharClass) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005022 CharacterRange::AddClassEscape(char_class, ranges, zone);
Ben Murdochb0fe1622011-05-05 13:52:32 +01005023 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005024 ranges->Add(range, zone);
Ben Murdochb0fe1622011-05-05 13:52:32 +01005025 }
5026}
5027
5028
Steve Blocka7e24c12009-10-30 11:49:00 +00005029RegExpTree* RegExpParser::ParseCharacterClass() {
5030 static const char* kUnterminated = "Unterminated character class";
5031 static const char* kRangeOutOfOrder = "Range out of order in character class";
5032
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005033 DCHECK_EQ(current(), '[');
Steve Blocka7e24c12009-10-30 11:49:00 +00005034 Advance();
5035 bool is_negated = false;
5036 if (current() == '^') {
5037 is_negated = true;
5038 Advance();
5039 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005040 ZoneList<CharacterRange>* ranges =
5041 new(zone()) ZoneList<CharacterRange>(2, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00005042 while (has_more() && current() != ']') {
Ben Murdochb0fe1622011-05-05 13:52:32 +01005043 uc16 char_class = kNoCharClass;
Steve Blocka7e24c12009-10-30 11:49:00 +00005044 CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED);
Steve Blocka7e24c12009-10-30 11:49:00 +00005045 if (current() == '-') {
5046 Advance();
5047 if (current() == kEndMarker) {
5048 // If we reach the end we break out of the loop and let the
5049 // following code report an error.
5050 break;
5051 } else if (current() == ']') {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005052 AddRangeOrEscape(ranges, char_class, first, zone());
5053 ranges->Add(CharacterRange::Singleton('-'), zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00005054 break;
5055 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01005056 uc16 char_class_2 = kNoCharClass;
5057 CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED);
5058 if (char_class != kNoCharClass || char_class_2 != kNoCharClass) {
5059 // Either end is an escaped character class. Treat the '-' verbatim.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005060 AddRangeOrEscape(ranges, char_class, first, zone());
5061 ranges->Add(CharacterRange::Singleton('-'), zone());
5062 AddRangeOrEscape(ranges, char_class_2, next, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00005063 continue;
5064 }
5065 if (first.from() > next.to()) {
5066 return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED);
5067 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005068 ranges->Add(CharacterRange::Range(first.from(), next.to()), zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00005069 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005070 AddRangeOrEscape(ranges, char_class, first, zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00005071 }
5072 }
5073 if (!has_more()) {
5074 return ReportError(CStrVector(kUnterminated) CHECK_FAILED);
5075 }
5076 Advance();
5077 if (ranges->length() == 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005078 ranges->Add(CharacterRange::Everything(), zone());
Steve Blocka7e24c12009-10-30 11:49:00 +00005079 is_negated = !is_negated;
5080 }
Ben Murdoch8b112d22011-06-08 16:22:53 +01005081 return new(zone()) RegExpCharacterClass(ranges, is_negated);
Steve Blocka7e24c12009-10-30 11:49:00 +00005082}
5083
5084
5085// ----------------------------------------------------------------------------
5086// The Parser interface.
5087
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005088bool RegExpParser::ParseRegExp(FlatStringReader* input,
5089 bool multiline,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005090 RegExpCompileData* result,
5091 Zone* zone) {
5092 DCHECK(result != NULL);
5093 RegExpParser parser(input, &result->error, multiline, zone);
Steve Blocka7e24c12009-10-30 11:49:00 +00005094 RegExpTree* tree = parser.ParsePattern();
5095 if (parser.failed()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005096 DCHECK(tree == NULL);
5097 DCHECK(!result->error.is_null());
Steve Blocka7e24c12009-10-30 11:49:00 +00005098 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005099 DCHECK(tree != NULL);
5100 DCHECK(result->error.is_null());
Steve Blocka7e24c12009-10-30 11:49:00 +00005101 result->tree = tree;
5102 int capture_count = parser.captures_started();
5103 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
5104 result->contains_anchor = parser.contains_anchor();
5105 result->capture_count = capture_count;
5106 }
5107 return !parser.failed();
5108}
5109
5110
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005111bool Parser::Parse() {
5112 DCHECK(info()->function() == NULL);
Ben Murdochf87a2032010-10-22 12:50:53 +01005113 FunctionLiteral* result = NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005114 pre_parse_timer_ = isolate()->counters()->pre_parse();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005115 if (FLAG_trace_parse || allow_natives() || extension_ != NULL) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005116 // If intrinsics are allowed, the Parser cannot operate independent of the
5117 // V8 heap because of Runtime. Tell the string table to internalize strings
5118 // and values right after they're created.
5119 ast_value_factory()->Internalize(isolate());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005120 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005121
5122 if (info()->is_lazy()) {
5123 DCHECK(!info()->is_eval());
5124 if (info()->shared_info()->is_function()) {
5125 result = ParseLazy();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005126 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005127 result = ParseProgram();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005128 }
Leon Clarke4515c472010-02-03 11:58:03 +00005129 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005130 SetCachedData();
5131 result = ParseProgram();
Leon Clarke4515c472010-02-03 11:58:03 +00005132 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005133 info()->SetFunction(result);
5134
5135 Internalize();
5136 DCHECK(ast_value_factory()->IsInternalized());
Ben Murdochf87a2032010-10-22 12:50:53 +01005137 return (result != NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00005138}
5139
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005140
5141void Parser::ParseOnBackground() {
5142 DCHECK(info()->function() == NULL);
5143 FunctionLiteral* result = NULL;
5144 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
5145
5146 CompleteParserRecorder recorder;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005147 if (produce_cached_parse_data()) log_ = &recorder;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005148
5149 DCHECK(info()->source_stream() != NULL);
5150 ExternalStreamingStream stream(info()->source_stream(),
5151 info()->source_stream_encoding());
5152 scanner_.Initialize(&stream);
5153 DCHECK(info()->context().is_null() || info()->context()->IsNativeContext());
5154
5155 // When streaming, we don't know the length of the source until we have parsed
5156 // it. The raw data can be UTF-8, so we wouldn't know the source length until
5157 // we have decoded it anyway even if we knew the raw data length (which we
5158 // don't). We work around this by storing all the scopes which need their end
5159 // position set at the end of the script (the top scope and possible eval
5160 // scopes) and set their end position after we know the script length.
5161 Scope* top_scope = NULL;
5162 Scope* eval_scope = NULL;
5163 result = DoParseProgram(info(), &top_scope, &eval_scope);
5164
5165 top_scope->set_end_position(scanner()->location().end_pos);
5166 if (eval_scope != NULL) {
5167 eval_scope->set_end_position(scanner()->location().end_pos);
5168 }
5169
5170 info()->SetFunction(result);
5171
5172 // We cannot internalize on a background thread; a foreground task will take
5173 // care of calling Parser::Internalize just before compilation.
5174
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005175 if (produce_cached_parse_data()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005176 if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
5177 log_ = NULL;
5178 }
5179}
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005180
5181
5182ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
5183 return new (zone()) ParserTraits::TemplateLiteral(zone(), pos);
5184}
5185
5186
5187void Parser::AddTemplateSpan(TemplateLiteralState* state, bool tail) {
5188 int pos = scanner()->location().beg_pos;
5189 int end = scanner()->location().end_pos - (tail ? 1 : 2);
5190 const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory());
5191 const AstRawString* trv = scanner()->CurrentRawSymbol(ast_value_factory());
5192 Literal* cooked = factory()->NewStringLiteral(tv, pos);
5193 Literal* raw = factory()->NewStringLiteral(trv, pos);
5194 (*state)->AddTemplateSpan(cooked, raw, end, zone());
5195}
5196
5197
5198void Parser::AddTemplateExpression(TemplateLiteralState* state,
5199 Expression* expression) {
5200 (*state)->AddExpression(expression, zone());
5201}
5202
5203
5204Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
5205 Expression* tag) {
5206 TemplateLiteral* lit = *state;
5207 int pos = lit->position();
5208 const ZoneList<Expression*>* cooked_strings = lit->cooked();
5209 const ZoneList<Expression*>* raw_strings = lit->raw();
5210 const ZoneList<Expression*>* expressions = lit->expressions();
5211 DCHECK_EQ(cooked_strings->length(), raw_strings->length());
5212 DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
5213
5214 if (!tag) {
5215 // Build tree of BinaryOps to simplify code-generation
5216 Expression* expr = NULL;
5217
5218 if (expressions->length() == 0) {
5219 // Simple case: treat as string literal
5220 expr = cooked_strings->at(0);
5221 } else {
5222 int i;
5223 Expression* cooked_str = cooked_strings->at(0);
5224 expr = factory()->NewBinaryOperation(
5225 Token::ADD, cooked_str, expressions->at(0), cooked_str->position());
5226 for (i = 1; i < expressions->length(); ++i) {
5227 cooked_str = cooked_strings->at(i);
5228 expr = factory()->NewBinaryOperation(
5229 Token::ADD, expr, factory()->NewBinaryOperation(
5230 Token::ADD, cooked_str, expressions->at(i),
5231 cooked_str->position()),
5232 cooked_str->position());
5233 }
5234 cooked_str = cooked_strings->at(i);
5235 expr = factory()->NewBinaryOperation(Token::ADD, expr, cooked_str,
5236 cooked_str->position());
5237 }
5238 return expr;
5239 } else {
5240 uint32_t hash = ComputeTemplateLiteralHash(lit);
5241
5242 int cooked_idx = function_state_->NextMaterializedLiteralIndex();
5243 int raw_idx = function_state_->NextMaterializedLiteralIndex();
5244
5245 // GetTemplateCallSite
5246 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone());
5247 args->Add(factory()->NewArrayLiteral(
5248 const_cast<ZoneList<Expression*>*>(cooked_strings),
5249 cooked_idx, pos),
5250 zone());
5251 args->Add(
5252 factory()->NewArrayLiteral(
5253 const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx, pos),
5254 zone());
5255
5256 // Ensure hash is suitable as a Smi value
5257 Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash)));
5258 args->Add(factory()->NewSmiLiteral(hash_obj->value(), pos), zone());
5259
5260 this->CheckPossibleEvalCall(tag, scope_);
5261 Expression* call_site = factory()->NewCallRuntime(
5262 ast_value_factory()->get_template_callsite_string(), NULL, args, start);
5263
5264 // Call TagFn
5265 ZoneList<Expression*>* call_args =
5266 new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone());
5267 call_args->Add(call_site, zone());
5268 call_args->AddAll(*expressions, zone());
5269 return factory()->NewCall(tag, call_args, pos);
5270 }
5271}
5272
5273
5274uint32_t Parser::ComputeTemplateLiteralHash(const TemplateLiteral* lit) {
5275 const ZoneList<Expression*>* raw_strings = lit->raw();
5276 int total = raw_strings->length();
5277 DCHECK(total);
5278
5279 uint32_t running_hash = 0;
5280
5281 for (int index = 0; index < total; ++index) {
5282 if (index) {
5283 running_hash = StringHasher::ComputeRunningHashOneByte(
5284 running_hash, "${}", 3);
5285 }
5286
5287 const AstRawString* raw_string =
5288 raw_strings->at(index)->AsLiteral()->raw_value()->AsString();
5289 if (raw_string->is_one_byte()) {
5290 const char* data = reinterpret_cast<const char*>(raw_string->raw_data());
5291 running_hash = StringHasher::ComputeRunningHashOneByte(
5292 running_hash, data, raw_string->length());
5293 } else {
5294 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
5295 running_hash = StringHasher::ComputeRunningHash(running_hash, data,
5296 raw_string->length());
5297 }
5298 }
5299
5300 return running_hash;
5301}
Steve Blocka7e24c12009-10-30 11:49:00 +00005302} } // namespace v8::internal