Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: src/parser.cc

Issue 1481613002: Create ast/ and parsing/ subdirectories and move appropriate files (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parser.h ('k') | src/parsing/expression-classifier.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/parser.h"
6
7 #include "src/api.h"
8 #include "src/ast.h"
9 #include "src/ast-literal-reindexer.h"
10 #include "src/bailout-reason.h"
11 #include "src/base/platform/platform.h"
12 #include "src/bootstrapper.h"
13 #include "src/char-predicates-inl.h"
14 #include "src/codegen.h"
15 #include "src/compiler.h"
16 #include "src/messages.h"
17 #include "src/parameter-initializer-rewriter.h"
18 #include "src/preparser.h"
19 #include "src/rewriter.h"
20 #include "src/runtime/runtime.h"
21 #include "src/scanner-character-streams.h"
22 #include "src/scopeinfo.h"
23 #include "src/string-stream.h"
24
25 namespace v8 {
26 namespace internal {
27
28 ScriptData::ScriptData(const byte* data, int length)
29 : owns_data_(false), rejected_(false), data_(data), length_(length) {
30 if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) {
31 byte* copy = NewArray<byte>(length);
32 DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment));
33 CopyBytes(copy, data, length);
34 data_ = copy;
35 AcquireDataOwnership();
36 }
37 }
38
39
40 ParseInfo::ParseInfo(Zone* zone)
41 : zone_(zone),
42 flags_(0),
43 source_stream_(nullptr),
44 source_stream_encoding_(ScriptCompiler::StreamedSource::ONE_BYTE),
45 extension_(nullptr),
46 compile_options_(ScriptCompiler::kNoCompileOptions),
47 script_scope_(nullptr),
48 unicode_cache_(nullptr),
49 stack_limit_(0),
50 hash_seed_(0),
51 cached_data_(nullptr),
52 ast_value_factory_(nullptr),
53 literal_(nullptr),
54 scope_(nullptr) {}
55
56
57 ParseInfo::ParseInfo(Zone* zone, Handle<JSFunction> function)
58 : ParseInfo(zone, Handle<SharedFunctionInfo>(function->shared())) {
59 set_closure(function);
60 set_context(Handle<Context>(function->context()));
61 }
62
63
64 ParseInfo::ParseInfo(Zone* zone, Handle<SharedFunctionInfo> shared)
65 : ParseInfo(zone) {
66 isolate_ = shared->GetIsolate();
67
68 set_lazy();
69 set_hash_seed(isolate_->heap()->HashSeed());
70 set_stack_limit(isolate_->stack_guard()->real_climit());
71 set_unicode_cache(isolate_->unicode_cache());
72 set_language_mode(shared->language_mode());
73 set_shared_info(shared);
74
75 Handle<Script> script(Script::cast(shared->script()));
76 set_script(script);
77 if (!script.is_null() && script->type() == Script::TYPE_NATIVE) {
78 set_native();
79 }
80 }
81
82
83 ParseInfo::ParseInfo(Zone* zone, Handle<Script> script) : ParseInfo(zone) {
84 isolate_ = script->GetIsolate();
85
86 set_hash_seed(isolate_->heap()->HashSeed());
87 set_stack_limit(isolate_->stack_guard()->real_climit());
88 set_unicode_cache(isolate_->unicode_cache());
89 set_script(script);
90
91 if (script->type() == Script::TYPE_NATIVE) {
92 set_native();
93 }
94 }
95
96
97 RegExpBuilder::RegExpBuilder(Zone* zone)
98 : zone_(zone),
99 pending_empty_(false),
100 characters_(NULL),
101 terms_(),
102 alternatives_()
103 #ifdef DEBUG
104 , last_added_(ADD_NONE)
105 #endif
106 {}
107
108
109 void RegExpBuilder::FlushCharacters() {
110 pending_empty_ = false;
111 if (characters_ != NULL) {
112 RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector());
113 characters_ = NULL;
114 text_.Add(atom, zone());
115 LAST(ADD_ATOM);
116 }
117 }
118
119
120 void RegExpBuilder::FlushText() {
121 FlushCharacters();
122 int num_text = text_.length();
123 if (num_text == 0) {
124 return;
125 } else if (num_text == 1) {
126 terms_.Add(text_.last(), zone());
127 } else {
128 RegExpText* text = new(zone()) RegExpText(zone());
129 for (int i = 0; i < num_text; i++)
130 text_.Get(i)->AppendToText(text, zone());
131 terms_.Add(text, zone());
132 }
133 text_.Clear();
134 }
135
136
137 void RegExpBuilder::AddCharacter(uc16 c) {
138 pending_empty_ = false;
139 if (characters_ == NULL) {
140 characters_ = new(zone()) ZoneList<uc16>(4, zone());
141 }
142 characters_->Add(c, zone());
143 LAST(ADD_CHAR);
144 }
145
146
147 void RegExpBuilder::AddEmpty() {
148 pending_empty_ = true;
149 }
150
151
152 void RegExpBuilder::AddAtom(RegExpTree* term) {
153 if (term->IsEmpty()) {
154 AddEmpty();
155 return;
156 }
157 if (term->IsTextElement()) {
158 FlushCharacters();
159 text_.Add(term, zone());
160 } else {
161 FlushText();
162 terms_.Add(term, zone());
163 }
164 LAST(ADD_ATOM);
165 }
166
167
168 void RegExpBuilder::AddAssertion(RegExpTree* assert) {
169 FlushText();
170 terms_.Add(assert, zone());
171 LAST(ADD_ASSERT);
172 }
173
174
175 void RegExpBuilder::NewAlternative() {
176 FlushTerms();
177 }
178
179
180 void RegExpBuilder::FlushTerms() {
181 FlushText();
182 int num_terms = terms_.length();
183 RegExpTree* alternative;
184 if (num_terms == 0) {
185 alternative = new (zone()) RegExpEmpty();
186 } else if (num_terms == 1) {
187 alternative = terms_.last();
188 } else {
189 alternative = new(zone()) RegExpAlternative(terms_.GetList(zone()));
190 }
191 alternatives_.Add(alternative, zone());
192 terms_.Clear();
193 LAST(ADD_NONE);
194 }
195
196
197 RegExpTree* RegExpBuilder::ToRegExp() {
198 FlushTerms();
199 int num_alternatives = alternatives_.length();
200 if (num_alternatives == 0) return new (zone()) RegExpEmpty();
201 if (num_alternatives == 1) return alternatives_.last();
202 return new(zone()) RegExpDisjunction(alternatives_.GetList(zone()));
203 }
204
205
206 void RegExpBuilder::AddQuantifierToAtom(
207 int min, int max, RegExpQuantifier::QuantifierType quantifier_type) {
208 if (pending_empty_) {
209 pending_empty_ = false;
210 return;
211 }
212 RegExpTree* atom;
213 if (characters_ != NULL) {
214 DCHECK(last_added_ == ADD_CHAR);
215 // Last atom was character.
216 Vector<const uc16> char_vector = characters_->ToConstVector();
217 int num_chars = char_vector.length();
218 if (num_chars > 1) {
219 Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1);
220 text_.Add(new(zone()) RegExpAtom(prefix), zone());
221 char_vector = char_vector.SubVector(num_chars - 1, num_chars);
222 }
223 characters_ = NULL;
224 atom = new(zone()) RegExpAtom(char_vector);
225 FlushText();
226 } else if (text_.length() > 0) {
227 DCHECK(last_added_ == ADD_ATOM);
228 atom = text_.RemoveLast();
229 FlushText();
230 } else if (terms_.length() > 0) {
231 DCHECK(last_added_ == ADD_ATOM);
232 atom = terms_.RemoveLast();
233 if (atom->max_match() == 0) {
234 // Guaranteed to only match an empty string.
235 LAST(ADD_TERM);
236 if (min == 0) {
237 return;
238 }
239 terms_.Add(atom, zone());
240 return;
241 }
242 } else {
243 // Only call immediately after adding an atom or character!
244 UNREACHABLE();
245 return;
246 }
247 terms_.Add(
248 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone());
249 LAST(ADD_TERM);
250 }
251
252
253 FunctionEntry ParseData::GetFunctionEntry(int start) {
254 // The current pre-data entry must be a FunctionEntry with the given
255 // start position.
256 if ((function_index_ + FunctionEntry::kSize <= Length()) &&
257 (static_cast<int>(Data()[function_index_]) == start)) {
258 int index = function_index_;
259 function_index_ += FunctionEntry::kSize;
260 Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize);
261 return FunctionEntry(subvector);
262 }
263 return FunctionEntry();
264 }
265
266
267 int ParseData::FunctionCount() {
268 int functions_size = FunctionsSize();
269 if (functions_size < 0) return 0;
270 if (functions_size % FunctionEntry::kSize != 0) return 0;
271 return functions_size / FunctionEntry::kSize;
272 }
273
274
275 bool ParseData::IsSane() {
276 if (!IsAligned(script_data_->length(), sizeof(unsigned))) return false;
277 // Check that the header data is valid and doesn't specify
278 // point to positions outside the store.
279 int data_length = Length();
280 if (data_length < PreparseDataConstants::kHeaderSize) return false;
281 if (Magic() != PreparseDataConstants::kMagicNumber) return false;
282 if (Version() != PreparseDataConstants::kCurrentVersion) return false;
283 if (HasError()) return false;
284 // Check that the space allocated for function entries is sane.
285 int functions_size = FunctionsSize();
286 if (functions_size < 0) return false;
287 if (functions_size % FunctionEntry::kSize != 0) return false;
288 // Check that the total size has room for header and function entries.
289 int minimum_size =
290 PreparseDataConstants::kHeaderSize + functions_size;
291 if (data_length < minimum_size) return false;
292 return true;
293 }
294
295
296 void ParseData::Initialize() {
297 // Prepares state for use.
298 int data_length = Length();
299 if (data_length >= PreparseDataConstants::kHeaderSize) {
300 function_index_ = PreparseDataConstants::kHeaderSize;
301 }
302 }
303
304
305 bool ParseData::HasError() {
306 return Data()[PreparseDataConstants::kHasErrorOffset];
307 }
308
309
310 unsigned ParseData::Magic() {
311 return Data()[PreparseDataConstants::kMagicOffset];
312 }
313
314
315 unsigned ParseData::Version() {
316 return Data()[PreparseDataConstants::kVersionOffset];
317 }
318
319
320 int ParseData::FunctionsSize() {
321 return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]);
322 }
323
324
325 void Parser::SetCachedData(ParseInfo* info) {
326 if (compile_options_ == ScriptCompiler::kNoCompileOptions) {
327 cached_parse_data_ = NULL;
328 } else {
329 DCHECK(info->cached_data() != NULL);
330 if (compile_options_ == ScriptCompiler::kConsumeParserCache) {
331 cached_parse_data_ = ParseData::FromCachedData(*info->cached_data());
332 }
333 }
334 }
335
336
337 FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope,
338 int pos, int end_pos,
339 LanguageMode language_mode) {
340 int materialized_literal_count = -1;
341 int expected_property_count = -1;
342 int parameter_count = 0;
343 const AstRawString* name = ast_value_factory()->empty_string();
344
345
346 FunctionKind kind = call_super ? FunctionKind::kDefaultSubclassConstructor
347 : FunctionKind::kDefaultBaseConstructor;
348 Scope* function_scope = NewScope(scope, FUNCTION_SCOPE, kind);
349 SetLanguageMode(function_scope,
350 static_cast<LanguageMode>(language_mode | STRICT));
351 // Set start and end position to the same value
352 function_scope->set_start_position(pos);
353 function_scope->set_end_position(pos);
354 ZoneList<Statement*>* body = NULL;
355
356 {
357 AstNodeFactory function_factory(ast_value_factory());
358 FunctionState function_state(&function_state_, &scope_, function_scope,
359 kind, &function_factory);
360
361 body = new (zone()) ZoneList<Statement*>(call_super ? 2 : 1, zone());
362 if (call_super) {
363 // %_DefaultConstructorCallSuper(new.target, %GetPrototype(<this-fun>))
364 ZoneList<Expression*>* args =
365 new (zone()) ZoneList<Expression*>(2, zone());
366 VariableProxy* new_target_proxy = scope_->NewUnresolved(
367 factory(), ast_value_factory()->new_target_string(), Variable::NORMAL,
368 pos);
369 args->Add(new_target_proxy, zone());
370 VariableProxy* this_function_proxy = scope_->NewUnresolved(
371 factory(), ast_value_factory()->this_function_string(),
372 Variable::NORMAL, pos);
373 ZoneList<Expression*>* tmp =
374 new (zone()) ZoneList<Expression*>(1, zone());
375 tmp->Add(this_function_proxy, zone());
376 Expression* get_prototype =
377 factory()->NewCallRuntime(Runtime::kGetPrototype, tmp, pos);
378 args->Add(get_prototype, zone());
379 CallRuntime* call = factory()->NewCallRuntime(
380 Runtime::kInlineDefaultConstructorCallSuper, args, pos);
381 body->Add(factory()->NewReturnStatement(call, pos), zone());
382 }
383
384 materialized_literal_count = function_state.materialized_literal_count();
385 expected_property_count = function_state.expected_property_count();
386 }
387
388 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
389 name, ast_value_factory(), function_scope, body,
390 materialized_literal_count, expected_property_count, parameter_count,
391 FunctionLiteral::kNoDuplicateParameters,
392 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
393 FunctionLiteral::kShouldLazyCompile, kind, pos);
394
395 return function_literal;
396 }
397
398
399 // ----------------------------------------------------------------------------
400 // Target is a support class to facilitate manipulation of the
401 // Parser's target_stack_ (the stack of potential 'break' and
402 // 'continue' statement targets). Upon construction, a new target is
403 // added; it is removed upon destruction.
404
405 class Target BASE_EMBEDDED {
406 public:
407 Target(Target** variable, BreakableStatement* statement)
408 : variable_(variable), statement_(statement), previous_(*variable) {
409 *variable = this;
410 }
411
412 ~Target() {
413 *variable_ = previous_;
414 }
415
416 Target* previous() { return previous_; }
417 BreakableStatement* statement() { return statement_; }
418
419 private:
420 Target** variable_;
421 BreakableStatement* statement_;
422 Target* previous_;
423 };
424
425
426 class TargetScope BASE_EMBEDDED {
427 public:
428 explicit TargetScope(Target** variable)
429 : variable_(variable), previous_(*variable) {
430 *variable = NULL;
431 }
432
433 ~TargetScope() {
434 *variable_ = previous_;
435 }
436
437 private:
438 Target** variable_;
439 Target* previous_;
440 };
441
442
443 // ----------------------------------------------------------------------------
444 // The CHECK_OK macro is a convenient macro to enforce error
445 // handling for functions that may fail (by returning !*ok).
446 //
447 // CAUTION: This macro appends extra statements after a call,
448 // thus it must never be used where only a single statement
449 // is correct (e.g. an if statement branch w/o braces)!
450
451 #define CHECK_OK ok); \
452 if (!*ok) return NULL; \
453 ((void)0
454 #define DUMMY ) // to make indentation work
455 #undef DUMMY
456
457 #define CHECK_FAILED /**/); \
458 if (failed_) return NULL; \
459 ((void)0
460 #define DUMMY ) // to make indentation work
461 #undef DUMMY
462
463 // ----------------------------------------------------------------------------
464 // Implementation of Parser
465
466 bool ParserTraits::IsEval(const AstRawString* identifier) const {
467 return identifier == parser_->ast_value_factory()->eval_string();
468 }
469
470
471 bool ParserTraits::IsArguments(const AstRawString* identifier) const {
472 return identifier == parser_->ast_value_factory()->arguments_string();
473 }
474
475
476 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const {
477 return IsEval(identifier) || IsArguments(identifier);
478 }
479
480 bool ParserTraits::IsUndefined(const AstRawString* identifier) const {
481 return identifier == parser_->ast_value_factory()->undefined_string();
482 }
483
484 bool ParserTraits::IsPrototype(const AstRawString* identifier) const {
485 return identifier == parser_->ast_value_factory()->prototype_string();
486 }
487
488
489 bool ParserTraits::IsConstructor(const AstRawString* identifier) const {
490 return identifier == parser_->ast_value_factory()->constructor_string();
491 }
492
493
494 bool ParserTraits::IsThisProperty(Expression* expression) {
495 DCHECK(expression != NULL);
496 Property* property = expression->AsProperty();
497 return property != NULL && property->obj()->IsVariableProxy() &&
498 property->obj()->AsVariableProxy()->is_this();
499 }
500
501
502 bool ParserTraits::IsIdentifier(Expression* expression) {
503 VariableProxy* operand = expression->AsVariableProxy();
504 return operand != NULL && !operand->is_this();
505 }
506
507
508 void ParserTraits::PushPropertyName(FuncNameInferrer* fni,
509 Expression* expression) {
510 if (expression->IsPropertyName()) {
511 fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
512 } else {
513 fni->PushLiteralName(
514 parser_->ast_value_factory()->anonymous_function_string());
515 }
516 }
517
518
519 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
520 Expression* right) {
521 DCHECK(left != NULL);
522 if (left->IsProperty() && right->IsFunctionLiteral()) {
523 right->AsFunctionLiteral()->set_pretenure();
524 }
525 }
526
527
528 void ParserTraits::CheckPossibleEvalCall(Expression* expression,
529 Scope* scope) {
530 VariableProxy* callee = expression->AsVariableProxy();
531 if (callee != NULL &&
532 callee->raw_name() == parser_->ast_value_factory()->eval_string()) {
533 scope->DeclarationScope()->RecordEvalCall();
534 scope->RecordEvalCall();
535 }
536 }
537
538
539 Expression* ParserTraits::MarkExpressionAsAssigned(Expression* expression) {
540 VariableProxy* proxy =
541 expression != NULL ? expression->AsVariableProxy() : NULL;
542 if (proxy != NULL) proxy->set_is_assigned();
543 return expression;
544 }
545
546
547 bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
548 Expression** x, Expression* y, Token::Value op, int pos,
549 AstNodeFactory* factory) {
550 if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
551 y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) {
552 double x_val = (*x)->AsLiteral()->raw_value()->AsNumber();
553 double y_val = y->AsLiteral()->raw_value()->AsNumber();
554 switch (op) {
555 case Token::ADD:
556 *x = factory->NewNumberLiteral(x_val + y_val, pos);
557 return true;
558 case Token::SUB:
559 *x = factory->NewNumberLiteral(x_val - y_val, pos);
560 return true;
561 case Token::MUL:
562 *x = factory->NewNumberLiteral(x_val * y_val, pos);
563 return true;
564 case Token::DIV:
565 *x = factory->NewNumberLiteral(x_val / y_val, pos);
566 return true;
567 case Token::BIT_OR: {
568 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
569 *x = factory->NewNumberLiteral(value, pos);
570 return true;
571 }
572 case Token::BIT_AND: {
573 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
574 *x = factory->NewNumberLiteral(value, pos);
575 return true;
576 }
577 case Token::BIT_XOR: {
578 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
579 *x = factory->NewNumberLiteral(value, pos);
580 return true;
581 }
582 case Token::SHL: {
583 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
584 *x = factory->NewNumberLiteral(value, pos);
585 return true;
586 }
587 case Token::SHR: {
588 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
589 uint32_t value = DoubleToUint32(x_val) >> shift;
590 *x = factory->NewNumberLiteral(value, pos);
591 return true;
592 }
593 case Token::SAR: {
594 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
595 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
596 *x = factory->NewNumberLiteral(value, pos);
597 return true;
598 }
599 default:
600 break;
601 }
602 }
603 return false;
604 }
605
606
607 Expression* ParserTraits::BuildUnaryExpression(Expression* expression,
608 Token::Value op, int pos,
609 AstNodeFactory* factory) {
610 DCHECK(expression != NULL);
611 if (expression->IsLiteral()) {
612 const AstValue* literal = expression->AsLiteral()->raw_value();
613 if (op == Token::NOT) {
614 // Convert the literal to a boolean condition and negate it.
615 bool condition = literal->BooleanValue();
616 return factory->NewBooleanLiteral(!condition, pos);
617 } else if (literal->IsNumber()) {
618 // Compute some expressions involving only number literals.
619 double value = literal->AsNumber();
620 switch (op) {
621 case Token::ADD:
622 return expression;
623 case Token::SUB:
624 return factory->NewNumberLiteral(-value, pos);
625 case Token::BIT_NOT:
626 return factory->NewNumberLiteral(~DoubleToInt32(value), pos);
627 default:
628 break;
629 }
630 }
631 }
632 // Desugar '+foo' => 'foo*1'
633 if (op == Token::ADD) {
634 return factory->NewBinaryOperation(
635 Token::MUL, expression, factory->NewNumberLiteral(1, pos, true), pos);
636 }
637 // The same idea for '-foo' => 'foo*(-1)'.
638 if (op == Token::SUB) {
639 return factory->NewBinaryOperation(
640 Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos);
641 }
642 // ...and one more time for '~foo' => 'foo^(~0)'.
643 if (op == Token::BIT_NOT) {
644 return factory->NewBinaryOperation(
645 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos);
646 }
647 return factory->NewUnaryOperation(op, expression, pos);
648 }
649
650
651 Expression* ParserTraits::NewThrowReferenceError(
652 MessageTemplate::Template message, int pos) {
653 return NewThrowError(Runtime::kNewReferenceError, message,
654 parser_->ast_value_factory()->empty_string(), pos);
655 }
656
657
658 Expression* ParserTraits::NewThrowSyntaxError(MessageTemplate::Template message,
659 const AstRawString* arg,
660 int pos) {
661 return NewThrowError(Runtime::kNewSyntaxError, message, arg, pos);
662 }
663
664
665 Expression* ParserTraits::NewThrowTypeError(MessageTemplate::Template message,
666 const AstRawString* arg, int pos) {
667 return NewThrowError(Runtime::kNewTypeError, message, arg, pos);
668 }
669
670
671 Expression* ParserTraits::NewThrowError(Runtime::FunctionId id,
672 MessageTemplate::Template message,
673 const AstRawString* arg, int pos) {
674 Zone* zone = parser_->zone();
675 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone);
676 args->Add(parser_->factory()->NewSmiLiteral(message, pos), zone);
677 args->Add(parser_->factory()->NewStringLiteral(arg, pos), zone);
678 CallRuntime* call_constructor =
679 parser_->factory()->NewCallRuntime(id, args, pos);
680 return parser_->factory()->NewThrow(call_constructor, pos);
681 }
682
683
684 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
685 MessageTemplate::Template message,
686 const char* arg, ParseErrorType error_type) {
687 if (parser_->stack_overflow()) {
688 // Suppress the error message (syntax error or such) in the presence of a
689 // stack overflow. The isolate allows only one pending exception at at time
690 // and we want to report the stack overflow later.
691 return;
692 }
693 parser_->pending_error_handler_.ReportMessageAt(source_location.beg_pos,
694 source_location.end_pos,
695 message, arg, error_type);
696 }
697
698
699 void ParserTraits::ReportMessage(MessageTemplate::Template message,
700 const char* arg, ParseErrorType error_type) {
701 Scanner::Location source_location = parser_->scanner()->location();
702 ReportMessageAt(source_location, message, arg, error_type);
703 }
704
705
706 void ParserTraits::ReportMessage(MessageTemplate::Template message,
707 const AstRawString* arg,
708 ParseErrorType error_type) {
709 Scanner::Location source_location = parser_->scanner()->location();
710 ReportMessageAt(source_location, message, arg, error_type);
711 }
712
713
714 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
715 MessageTemplate::Template message,
716 const AstRawString* arg,
717 ParseErrorType error_type) {
718 if (parser_->stack_overflow()) {
719 // Suppress the error message (syntax error or such) in the presence of a
720 // stack overflow. The isolate allows only one pending exception at at time
721 // and we want to report the stack overflow later.
722 return;
723 }
724 parser_->pending_error_handler_.ReportMessageAt(source_location.beg_pos,
725 source_location.end_pos,
726 message, arg, error_type);
727 }
728
729
730 const AstRawString* ParserTraits::GetSymbol(Scanner* scanner) {
731 const AstRawString* result =
732 parser_->scanner()->CurrentSymbol(parser_->ast_value_factory());
733 DCHECK(result != NULL);
734 return result;
735 }
736
737
738 const AstRawString* ParserTraits::GetNumberAsSymbol(Scanner* scanner) {
739 double double_value = parser_->scanner()->DoubleValue();
740 char array[100];
741 const char* string =
742 DoubleToCString(double_value, Vector<char>(array, arraysize(array)));
743 return parser_->ast_value_factory()->GetOneByteString(string);
744 }
745
746
747 const AstRawString* ParserTraits::GetNextSymbol(Scanner* scanner) {
748 return parser_->scanner()->NextSymbol(parser_->ast_value_factory());
749 }
750
751
752 Expression* ParserTraits::ThisExpression(Scope* scope, AstNodeFactory* factory,
753 int pos) {
754 return scope->NewUnresolved(factory,
755 parser_->ast_value_factory()->this_string(),
756 Variable::THIS, pos, pos + 4);
757 }
758
759
760 Expression* ParserTraits::SuperPropertyReference(Scope* scope,
761 AstNodeFactory* factory,
762 int pos) {
763 // this_function[home_object_symbol]
764 VariableProxy* this_function_proxy = scope->NewUnresolved(
765 factory, parser_->ast_value_factory()->this_function_string(),
766 Variable::NORMAL, pos);
767 Expression* home_object_symbol_literal =
768 factory->NewSymbolLiteral("home_object_symbol", RelocInfo::kNoPosition);
769 Expression* home_object = factory->NewProperty(
770 this_function_proxy, home_object_symbol_literal, pos);
771 return factory->NewSuperPropertyReference(
772 ThisExpression(scope, factory, pos)->AsVariableProxy(), home_object, pos);
773 }
774
775
776 Expression* ParserTraits::SuperCallReference(Scope* scope,
777 AstNodeFactory* factory, int pos) {
778 VariableProxy* new_target_proxy = scope->NewUnresolved(
779 factory, parser_->ast_value_factory()->new_target_string(),
780 Variable::NORMAL, pos);
781 VariableProxy* this_function_proxy = scope->NewUnresolved(
782 factory, parser_->ast_value_factory()->this_function_string(),
783 Variable::NORMAL, pos);
784 return factory->NewSuperCallReference(
785 ThisExpression(scope, factory, pos)->AsVariableProxy(), new_target_proxy,
786 this_function_proxy, pos);
787 }
788
789
790 Expression* ParserTraits::NewTargetExpression(Scope* scope,
791 AstNodeFactory* factory,
792 int pos) {
793 static const int kNewTargetStringLength = 10;
794 auto proxy = scope->NewUnresolved(
795 factory, parser_->ast_value_factory()->new_target_string(),
796 Variable::NORMAL, pos, pos + kNewTargetStringLength);
797 proxy->set_is_new_target();
798 return proxy;
799 }
800
801
802 Expression* ParserTraits::DefaultConstructor(bool call_super, Scope* scope,
803 int pos, int end_pos,
804 LanguageMode mode) {
805 return parser_->DefaultConstructor(call_super, scope, pos, end_pos, mode);
806 }
807
808
809 Literal* ParserTraits::ExpressionFromLiteral(Token::Value token, int pos,
810 Scanner* scanner,
811 AstNodeFactory* factory) {
812 switch (token) {
813 case Token::NULL_LITERAL:
814 return factory->NewNullLiteral(pos);
815 case Token::TRUE_LITERAL:
816 return factory->NewBooleanLiteral(true, pos);
817 case Token::FALSE_LITERAL:
818 return factory->NewBooleanLiteral(false, pos);
819 case Token::SMI: {
820 int value = scanner->smi_value();
821 return factory->NewSmiLiteral(value, pos);
822 }
823 case Token::NUMBER: {
824 bool has_dot = scanner->ContainsDot();
825 double value = scanner->DoubleValue();
826 return factory->NewNumberLiteral(value, pos, has_dot);
827 }
828 default:
829 DCHECK(false);
830 }
831 return NULL;
832 }
833
834
835 Expression* ParserTraits::ExpressionFromIdentifier(const AstRawString* name,
836 int start_position,
837 int end_position,
838 Scope* scope,
839 AstNodeFactory* factory) {
840 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name);
841 return scope->NewUnresolved(factory, name, Variable::NORMAL, start_position,
842 end_position);
843 }
844
845
846 Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner,
847 AstNodeFactory* factory) {
848 const AstRawString* symbol = GetSymbol(scanner);
849 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol);
850 return factory->NewStringLiteral(symbol, pos);
851 }
852
853
854 Expression* ParserTraits::GetIterator(Expression* iterable,
855 AstNodeFactory* factory) {
856 Expression* iterator_symbol_literal =
857 factory->NewSymbolLiteral("iterator_symbol", RelocInfo::kNoPosition);
858 int pos = iterable->position();
859 Expression* prop =
860 factory->NewProperty(iterable, iterator_symbol_literal, pos);
861 Zone* zone = parser_->zone();
862 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(0, zone);
863 return factory->NewCall(prop, args, pos);
864 }
865
866
867 Literal* ParserTraits::GetLiteralTheHole(int position,
868 AstNodeFactory* factory) {
869 return factory->NewTheHoleLiteral(RelocInfo::kNoPosition);
870 }
871
872
873 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) {
874 return parser_->ParseV8Intrinsic(ok);
875 }
876
877
878 FunctionLiteral* ParserTraits::ParseFunctionLiteral(
879 const AstRawString* name, Scanner::Location function_name_location,
880 FunctionNameValidity function_name_validity, FunctionKind kind,
881 int function_token_position, FunctionLiteral::FunctionType type,
882 FunctionLiteral::ArityRestriction arity_restriction,
883 LanguageMode language_mode, bool* ok) {
884 return parser_->ParseFunctionLiteral(
885 name, function_name_location, function_name_validity, kind,
886 function_token_position, type, arity_restriction, language_mode, ok);
887 }
888
889
890 ClassLiteral* ParserTraits::ParseClassLiteral(
891 const AstRawString* name, Scanner::Location class_name_location,
892 bool name_is_strict_reserved, int pos, bool* ok) {
893 return parser_->ParseClassLiteral(name, class_name_location,
894 name_is_strict_reserved, pos, ok);
895 }
896
897
898 Parser::Parser(ParseInfo* info)
899 : ParserBase<ParserTraits>(info->zone(), &scanner_, info->stack_limit(),
900 info->extension(), info->ast_value_factory(),
901 NULL, this),
902 scanner_(info->unicode_cache()),
903 reusable_preparser_(NULL),
904 original_scope_(NULL),
905 target_stack_(NULL),
906 compile_options_(info->compile_options()),
907 cached_parse_data_(NULL),
908 total_preparse_skipped_(0),
909 pre_parse_timer_(NULL),
910 parsing_on_main_thread_(true) {
911 // Even though we were passed ParseInfo, we should not store it in
912 // Parser - this makes sure that Isolate is not accidentally accessed via
913 // ParseInfo during background parsing.
914 DCHECK(!info->script().is_null() || info->source_stream() != NULL);
915 set_allow_lazy(info->allow_lazy_parsing());
916 set_allow_natives(FLAG_allow_natives_syntax || info->is_native());
917 set_allow_harmony_sloppy(FLAG_harmony_sloppy);
918 set_allow_harmony_sloppy_function(FLAG_harmony_sloppy_function);
919 set_allow_harmony_sloppy_let(FLAG_harmony_sloppy_let);
920 set_allow_harmony_rest_parameters(FLAG_harmony_rest_parameters);
921 set_allow_harmony_default_parameters(FLAG_harmony_default_parameters);
922 set_allow_harmony_destructuring_bind(FLAG_harmony_destructuring_bind);
923 set_allow_strong_mode(FLAG_strong_mode);
924 set_allow_legacy_const(FLAG_legacy_const);
925 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions);
926 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
927 ++feature) {
928 use_counts_[feature] = 0;
929 }
930 if (info->ast_value_factory() == NULL) {
931 // info takes ownership of AstValueFactory.
932 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed()));
933 info->set_ast_value_factory_owned();
934 ast_value_factory_ = info->ast_value_factory();
935 }
936 }
937
938
939 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
940 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
941 // see comment for HistogramTimerScope class.
942
943 // It's OK to use the Isolate & counters here, since this function is only
944 // called in the main thread.
945 DCHECK(parsing_on_main_thread_);
946
947 HistogramTimerScope timer_scope(isolate->counters()->parse(), true);
948 Handle<String> source(String::cast(info->script()->source()));
949 isolate->counters()->total_parse_size()->Increment(source->length());
950 base::ElapsedTimer timer;
951 if (FLAG_trace_parse) {
952 timer.Start();
953 }
954 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
955
956 // Initialize parser state.
957 CompleteParserRecorder recorder;
958
959 if (produce_cached_parse_data()) {
960 log_ = &recorder;
961 } else if (consume_cached_parse_data()) {
962 cached_parse_data_->Initialize();
963 }
964
965 source = String::Flatten(source);
966 FunctionLiteral* result;
967
968 if (source->IsExternalTwoByteString()) {
969 // Notice that the stream is destroyed at the end of the branch block.
970 // The last line of the blocks can't be moved outside, even though they're
971 // identical calls.
972 ExternalTwoByteStringUtf16CharacterStream stream(
973 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
974 scanner_.Initialize(&stream);
975 result = DoParseProgram(info);
976 } else {
977 GenericStringUtf16CharacterStream stream(source, 0, source->length());
978 scanner_.Initialize(&stream);
979 result = DoParseProgram(info);
980 }
981 if (result != NULL) {
982 DCHECK_EQ(scanner_.peek_location().beg_pos, source->length());
983 }
984 HandleSourceURLComments(isolate, info->script());
985
986 if (FLAG_trace_parse && result != NULL) {
987 double ms = timer.Elapsed().InMillisecondsF();
988 if (info->is_eval()) {
989 PrintF("[parsing eval");
990 } else if (info->script()->name()->IsString()) {
991 String* name = String::cast(info->script()->name());
992 base::SmartArrayPointer<char> name_chars = name->ToCString();
993 PrintF("[parsing script: %s", name_chars.get());
994 } else {
995 PrintF("[parsing script");
996 }
997 PrintF(" - took %0.3f ms]\n", ms);
998 }
999 if (produce_cached_parse_data()) {
1000 if (result != NULL) *info->cached_data() = recorder.GetScriptData();
1001 log_ = NULL;
1002 }
1003 return result;
1004 }
1005
1006
1007 FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
1008 // Note that this function can be called from the main thread or from a
1009 // background thread. We should not access anything Isolate / heap dependent
1010 // via ParseInfo, and also not pass it forward.
1011 DCHECK(scope_ == NULL);
1012 DCHECK(target_stack_ == NULL);
1013
1014 Mode parsing_mode = FLAG_lazy && allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY;
1015 if (allow_natives() || extension_ != NULL) parsing_mode = PARSE_EAGERLY;
1016
1017 FunctionLiteral* result = NULL;
1018 {
1019 // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native
1020 // context, which will have the "this" binding for script scopes.
1021 Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
1022 info->set_script_scope(scope);
1023 if (!info->context().is_null() && !info->context()->IsNativeContext()) {
1024 scope = Scope::DeserializeScopeChain(info->isolate(), zone(),
1025 *info->context(), scope);
1026 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this
1027 // means the Parser cannot operate independent of the V8 heap. Tell the
1028 // string table to internalize strings and values right after they're
1029 // created. This kind of parsing can only be done in the main thread.
1030 DCHECK(parsing_on_main_thread_);
1031 ast_value_factory()->Internalize(info->isolate());
1032 }
1033 original_scope_ = scope;
1034 if (info->is_eval()) {
1035 if (!scope->is_script_scope() || is_strict(info->language_mode())) {
1036 parsing_mode = PARSE_EAGERLY;
1037 }
1038 scope = NewScope(scope, EVAL_SCOPE);
1039 } else if (info->is_module()) {
1040 scope = NewScope(scope, MODULE_SCOPE);
1041 }
1042
1043 scope->set_start_position(0);
1044
1045 // Enter 'scope' with the given parsing mode.
1046 ParsingModeScope parsing_mode_scope(this, parsing_mode);
1047 AstNodeFactory function_factory(ast_value_factory());
1048 FunctionState function_state(&function_state_, &scope_, scope,
1049 kNormalFunction, &function_factory);
1050
1051 // Don't count the mode in the use counters--give the program a chance
1052 // to enable script/module-wide strict/strong mode below.
1053 scope_->SetLanguageMode(info->language_mode());
1054 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
1055 bool ok = true;
1056 int beg_pos = scanner()->location().beg_pos;
1057 if (info->is_module()) {
1058 ParseModuleItemList(body, &ok);
1059 } else {
1060 ParseStatementList(body, Token::EOS, &ok);
1061 }
1062
1063 // The parser will peek but not consume EOS. Our scope logically goes all
1064 // the way to the EOS, though.
1065 scope->set_end_position(scanner()->peek_location().beg_pos);
1066
1067 if (ok && is_strict(language_mode())) {
1068 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
1069 }
1070 if (ok && is_sloppy(language_mode()) && allow_harmony_sloppy_function()) {
1071 // TODO(littledan): Function bindings on the global object that modify
1072 // pre-existing bindings should be made writable, enumerable and
1073 // nonconfigurable if possible, whereas this code will leave attributes
1074 // unchanged if the property already exists.
1075 InsertSloppyBlockFunctionVarBindings(scope, &ok);
1076 }
1077 if (ok && (is_strict(language_mode()) || allow_harmony_sloppy() ||
1078 allow_harmony_destructuring_bind())) {
1079 CheckConflictingVarDeclarations(scope_, &ok);
1080 }
1081
1082 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
1083 if (body->length() != 1 ||
1084 !body->at(0)->IsExpressionStatement() ||
1085 !body->at(0)->AsExpressionStatement()->
1086 expression()->IsFunctionLiteral()) {
1087 ReportMessage(MessageTemplate::kSingleFunctionLiteral);
1088 ok = false;
1089 }
1090 }
1091
1092 if (ok) {
1093 result = factory()->NewFunctionLiteral(
1094 ast_value_factory()->empty_string(), ast_value_factory(), scope_,
1095 body, function_state.materialized_literal_count(),
1096 function_state.expected_property_count(), 0,
1097 FunctionLiteral::kNoDuplicateParameters,
1098 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval,
1099 FunctionLiteral::kShouldLazyCompile, FunctionKind::kNormalFunction,
1100 0);
1101 }
1102 }
1103
1104 // Make sure the target stack is empty.
1105 DCHECK(target_stack_ == NULL);
1106
1107 return result;
1108 }
1109
1110
1111 FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info) {
1112 // It's OK to use the Isolate & counters here, since this function is only
1113 // called in the main thread.
1114 DCHECK(parsing_on_main_thread_);
1115 HistogramTimerScope timer_scope(isolate->counters()->parse_lazy());
1116 Handle<String> source(String::cast(info->script()->source()));
1117 isolate->counters()->total_parse_size()->Increment(source->length());
1118 base::ElapsedTimer timer;
1119 if (FLAG_trace_parse) {
1120 timer.Start();
1121 }
1122 Handle<SharedFunctionInfo> shared_info = info->shared_info();
1123
1124 // Initialize parser state.
1125 source = String::Flatten(source);
1126 FunctionLiteral* result;
1127 if (source->IsExternalTwoByteString()) {
1128 ExternalTwoByteStringUtf16CharacterStream stream(
1129 Handle<ExternalTwoByteString>::cast(source),
1130 shared_info->start_position(),
1131 shared_info->end_position());
1132 result = ParseLazy(isolate, info, &stream);
1133 } else {
1134 GenericStringUtf16CharacterStream stream(source,
1135 shared_info->start_position(),
1136 shared_info->end_position());
1137 result = ParseLazy(isolate, info, &stream);
1138 }
1139
1140 if (FLAG_trace_parse && result != NULL) {
1141 double ms = timer.Elapsed().InMillisecondsF();
1142 base::SmartArrayPointer<char> name_chars =
1143 result->debug_name()->ToCString();
1144 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
1145 }
1146 return result;
1147 }
1148
1149
1150 FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info,
1151 Utf16CharacterStream* source) {
1152 Handle<SharedFunctionInfo> shared_info = info->shared_info();
1153 scanner_.Initialize(source);
1154 DCHECK(scope_ == NULL);
1155 DCHECK(target_stack_ == NULL);
1156
1157 Handle<String> name(String::cast(shared_info->name()));
1158 DCHECK(ast_value_factory());
1159 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
1160 const AstRawString* raw_name = ast_value_factory()->GetString(name);
1161 fni_->PushEnclosingName(raw_name);
1162
1163 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1164
1165 // Place holder for the result.
1166 FunctionLiteral* result = NULL;
1167
1168 {
1169 // Parse the function literal.
1170 Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
1171 info->set_script_scope(scope);
1172 if (!info->closure().is_null()) {
1173 // Ok to use Isolate here, since lazy function parsing is only done in the
1174 // main thread.
1175 DCHECK(parsing_on_main_thread_);
1176 scope = Scope::DeserializeScopeChain(isolate, zone(),
1177 info->closure()->context(), scope);
1178 }
1179 original_scope_ = scope;
1180 AstNodeFactory function_factory(ast_value_factory());
1181 FunctionState function_state(&function_state_, &scope_, scope,
1182 shared_info->kind(), &function_factory);
1183 DCHECK(is_sloppy(scope->language_mode()) ||
1184 is_strict(info->language_mode()));
1185 DCHECK(info->language_mode() == shared_info->language_mode());
1186 FunctionLiteral::FunctionType function_type = shared_info->is_expression()
1187 ? (shared_info->is_anonymous()
1188 ? FunctionLiteral::ANONYMOUS_EXPRESSION
1189 : FunctionLiteral::NAMED_EXPRESSION)
1190 : FunctionLiteral::DECLARATION;
1191 bool ok = true;
1192
1193 if (shared_info->is_arrow()) {
1194 Scope* scope =
1195 NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction);
1196 SetLanguageMode(scope, shared_info->language_mode());
1197 scope->set_start_position(shared_info->start_position());
1198 ExpressionClassifier formals_classifier;
1199 ParserFormalParameters formals(scope);
1200 Checkpoint checkpoint(this);
1201 {
1202 // Parsing patterns as variable reference expression creates
1203 // NewUnresolved references in current scope. Entrer arrow function
1204 // scope for formal parameter parsing.
1205 BlockState block_state(&scope_, scope);
1206 if (Check(Token::LPAREN)) {
1207 // '(' StrictFormalParameters ')'
1208 ParseFormalParameterList(&formals, &formals_classifier, &ok);
1209 if (ok) ok = Check(Token::RPAREN);
1210 } else {
1211 // BindingIdentifier
1212 ParseFormalParameter(&formals, &formals_classifier, &ok);
1213 if (ok) {
1214 DeclareFormalParameter(formals.scope, formals.at(0),
1215 &formals_classifier);
1216 }
1217 }
1218 }
1219
1220 if (ok) {
1221 checkpoint.Restore(&formals.materialized_literals_count);
1222 // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should
1223 // not be observable, or else the preparser would have failed.
1224 Expression* expression =
1225 ParseArrowFunctionLiteral(true, formals, formals_classifier, &ok);
1226 if (ok) {
1227 // Scanning must end at the same position that was recorded
1228 // previously. If not, parsing has been interrupted due to a stack
1229 // overflow, at which point the partially parsed arrow function
1230 // concise body happens to be a valid expression. This is a problem
1231 // only for arrow functions with single expression bodies, since there
1232 // is no end token such as "}" for normal functions.
1233 if (scanner()->location().end_pos == shared_info->end_position()) {
1234 // The pre-parser saw an arrow function here, so the full parser
1235 // must produce a FunctionLiteral.
1236 DCHECK(expression->IsFunctionLiteral());
1237 result = expression->AsFunctionLiteral();
1238 } else {
1239 ok = false;
1240 }
1241 }
1242 }
1243 } else if (shared_info->is_default_constructor()) {
1244 result = DefaultConstructor(IsSubclassConstructor(shared_info->kind()),
1245 scope, shared_info->start_position(),
1246 shared_info->end_position(),
1247 shared_info->language_mode());
1248 } else {
1249 result = ParseFunctionLiteral(
1250 raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck,
1251 shared_info->kind(), RelocInfo::kNoPosition, function_type,
1252 FunctionLiteral::NORMAL_ARITY, shared_info->language_mode(), &ok);
1253 }
1254 // Make sure the results agree.
1255 DCHECK(ok == (result != NULL));
1256 }
1257
1258 // Make sure the target stack is empty.
1259 DCHECK(target_stack_ == NULL);
1260
1261 if (result != NULL) {
1262 Handle<String> inferred_name(shared_info->inferred_name());
1263 result->set_inferred_name(inferred_name);
1264 }
1265 return result;
1266 }
1267
1268
1269 void* Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token,
1270 bool* ok) {
1271 // StatementList ::
1272 // (StatementListItem)* <end_token>
1273
1274 // Allocate a target stack to use for this set of source
1275 // elements. This way, all scripts and functions get their own
1276 // target stack thus avoiding illegal breaks and continues across
1277 // functions.
1278 TargetScope scope(&this->target_stack_);
1279
1280 DCHECK(body != NULL);
1281 bool directive_prologue = true; // Parsing directive prologue.
1282
1283 while (peek() != end_token) {
1284 if (directive_prologue && peek() != Token::STRING) {
1285 directive_prologue = false;
1286 }
1287
1288 Scanner::Location token_loc = scanner()->peek_location();
1289 Scanner::Location old_this_loc = function_state_->this_location();
1290 Scanner::Location old_super_loc = function_state_->super_location();
1291 Statement* stat = ParseStatementListItem(CHECK_OK);
1292
1293 if (is_strong(language_mode()) && scope_->is_function_scope() &&
1294 IsClassConstructor(function_state_->kind())) {
1295 Scanner::Location this_loc = function_state_->this_location();
1296 Scanner::Location super_loc = function_state_->super_location();
1297 if (this_loc.beg_pos != old_this_loc.beg_pos &&
1298 this_loc.beg_pos != token_loc.beg_pos) {
1299 ReportMessageAt(this_loc, MessageTemplate::kStrongConstructorThis);
1300 *ok = false;
1301 return nullptr;
1302 }
1303 if (super_loc.beg_pos != old_super_loc.beg_pos &&
1304 super_loc.beg_pos != token_loc.beg_pos) {
1305 ReportMessageAt(super_loc, MessageTemplate::kStrongConstructorSuper);
1306 *ok = false;
1307 return nullptr;
1308 }
1309 }
1310
1311 if (stat == NULL || stat->IsEmpty()) {
1312 directive_prologue = false; // End of directive prologue.
1313 continue;
1314 }
1315
1316 if (directive_prologue) {
1317 // A shot at a directive.
1318 ExpressionStatement* e_stat;
1319 Literal* literal;
1320 // Still processing directive prologue?
1321 if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1322 (literal = e_stat->expression()->AsLiteral()) != NULL &&
1323 literal->raw_value()->IsString()) {
1324 // Check "use strict" directive (ES5 14.1), "use asm" directive, and
1325 // "use strong" directive (experimental).
1326 bool use_strict_found =
1327 literal->raw_value()->AsString() ==
1328 ast_value_factory()->use_strict_string() &&
1329 token_loc.end_pos - token_loc.beg_pos ==
1330 ast_value_factory()->use_strict_string()->length() + 2;
1331 bool use_strong_found =
1332 allow_strong_mode() &&
1333 literal->raw_value()->AsString() ==
1334 ast_value_factory()->use_strong_string() &&
1335 token_loc.end_pos - token_loc.beg_pos ==
1336 ast_value_factory()->use_strong_string()->length() + 2;
1337 if (use_strict_found || use_strong_found) {
1338 // Strong mode implies strict mode. If there are several "use strict"
1339 // / "use strong" directives, do the strict mode changes only once.
1340 if (is_sloppy(scope_->language_mode())) {
1341 RaiseLanguageMode(STRICT);
1342 }
1343
1344 if (use_strong_found) {
1345 RaiseLanguageMode(STRONG);
1346 if (IsClassConstructor(function_state_->kind())) {
1347 // "use strong" cannot occur in a class constructor body, to avoid
1348 // unintuitive strong class object semantics.
1349 ParserTraits::ReportMessageAt(
1350 token_loc, MessageTemplate::kStrongConstructorDirective);
1351 *ok = false;
1352 return nullptr;
1353 }
1354 }
1355 if (!scope_->HasSimpleParameters()) {
1356 // TC39 deemed "use strict" directives to be an error when occurring
1357 // in the body of a function with non-simple parameter list, on
1358 // 29/7/2015. https://goo.gl/ueA7Ln
1359 //
1360 // In V8, this also applies to "use strong " directives.
1361 const AstRawString* string = literal->raw_value()->AsString();
1362 ParserTraits::ReportMessageAt(
1363 token_loc, MessageTemplate::kIllegalLanguageModeDirective,
1364 string);
1365 *ok = false;
1366 return nullptr;
1367 }
1368 // Because declarations in strict eval code don't leak into the scope
1369 // of the eval call, it is likely that functions declared in strict
1370 // eval code will be used within the eval code, so lazy parsing is
1371 // probably not a win.
1372 if (scope_->is_eval_scope()) mode_ = PARSE_EAGERLY;
1373 } else if (literal->raw_value()->AsString() ==
1374 ast_value_factory()->use_asm_string() &&
1375 token_loc.end_pos - token_loc.beg_pos ==
1376 ast_value_factory()->use_asm_string()->length() + 2) {
1377 // Store the usage count; The actual use counter on the isolate is
1378 // incremented after parsing is done.
1379 ++use_counts_[v8::Isolate::kUseAsm];
1380 scope_->SetAsmModule();
1381 } else {
1382 // Should not change mode, but will increment UseCounter
1383 // if appropriate. Ditto usages below.
1384 RaiseLanguageMode(SLOPPY);
1385 }
1386 } else {
1387 // End of the directive prologue.
1388 directive_prologue = false;
1389 RaiseLanguageMode(SLOPPY);
1390 }
1391 } else {
1392 RaiseLanguageMode(SLOPPY);
1393 }
1394
1395 body->Add(stat, zone());
1396 }
1397
1398 return 0;
1399 }
1400
1401
1402 Statement* Parser::ParseStatementListItem(bool* ok) {
1403 // (Ecma 262 6th Edition, 13.1):
1404 // StatementListItem:
1405 // Statement
1406 // Declaration
1407
1408 if (peek() != Token::CLASS) {
1409 // No more classes follow; reset the start position for the consecutive
1410 // class declaration group.
1411 scope_->set_class_declaration_group_start(-1);
1412 }
1413
1414 switch (peek()) {
1415 case Token::FUNCTION:
1416 return ParseFunctionDeclaration(NULL, ok);
1417 case Token::CLASS:
1418 if (scope_->class_declaration_group_start() < 0) {
1419 scope_->set_class_declaration_group_start(
1420 scanner()->peek_location().beg_pos);
1421 }
1422 return ParseClassDeclaration(NULL, ok);
1423 case Token::CONST:
1424 if (allow_const()) {
1425 return ParseVariableStatement(kStatementListItem, NULL, ok);
1426 }
1427 break;
1428 case Token::VAR:
1429 return ParseVariableStatement(kStatementListItem, NULL, ok);
1430 case Token::LET:
1431 if (IsNextLetKeyword()) {
1432 return ParseVariableStatement(kStatementListItem, NULL, ok);
1433 }
1434 break;
1435 default:
1436 break;
1437 }
1438 return ParseStatement(NULL, ok);
1439 }
1440
1441
1442 Statement* Parser::ParseModuleItem(bool* ok) {
1443 // (Ecma 262 6th Edition, 15.2):
1444 // ModuleItem :
1445 // ImportDeclaration
1446 // ExportDeclaration
1447 // StatementListItem
1448
1449 switch (peek()) {
1450 case Token::IMPORT:
1451 return ParseImportDeclaration(ok);
1452 case Token::EXPORT:
1453 return ParseExportDeclaration(ok);
1454 default:
1455 return ParseStatementListItem(ok);
1456 }
1457 }
1458
1459
1460 void* Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) {
1461 // (Ecma 262 6th Edition, 15.2):
1462 // Module :
1463 // ModuleBody?
1464 //
1465 // ModuleBody :
1466 // ModuleItem*
1467
1468 DCHECK(scope_->is_module_scope());
1469 RaiseLanguageMode(STRICT);
1470
1471 while (peek() != Token::EOS) {
1472 Statement* stat = ParseModuleItem(CHECK_OK);
1473 if (stat && !stat->IsEmpty()) {
1474 body->Add(stat, zone());
1475 }
1476 }
1477
1478 // Check that all exports are bound.
1479 ModuleDescriptor* descriptor = scope_->module();
1480 for (ModuleDescriptor::Iterator it = descriptor->iterator(); !it.done();
1481 it.Advance()) {
1482 if (scope_->LookupLocal(it.local_name()) == NULL) {
1483 // TODO(adamk): Pass both local_name and export_name once ParserTraits
1484 // supports multiple arg error messages.
1485 // Also try to report this at a better location.
1486 ParserTraits::ReportMessage(MessageTemplate::kModuleExportUndefined,
1487 it.local_name());
1488 *ok = false;
1489 return NULL;
1490 }
1491 }
1492
1493 scope_->module()->Freeze();
1494 return NULL;
1495 }
1496
1497
1498 const AstRawString* Parser::ParseModuleSpecifier(bool* ok) {
1499 // ModuleSpecifier :
1500 // StringLiteral
1501
1502 Expect(Token::STRING, CHECK_OK);
1503 return GetSymbol(scanner());
1504 }
1505
1506
1507 void* Parser::ParseExportClause(ZoneList<const AstRawString*>* export_names,
1508 ZoneList<Scanner::Location>* export_locations,
1509 ZoneList<const AstRawString*>* local_names,
1510 Scanner::Location* reserved_loc, bool* ok) {
1511 // ExportClause :
1512 // '{' '}'
1513 // '{' ExportsList '}'
1514 // '{' ExportsList ',' '}'
1515 //
1516 // ExportsList :
1517 // ExportSpecifier
1518 // ExportsList ',' ExportSpecifier
1519 //
1520 // ExportSpecifier :
1521 // IdentifierName
1522 // IdentifierName 'as' IdentifierName
1523
1524 Expect(Token::LBRACE, CHECK_OK);
1525
1526 Token::Value name_tok;
1527 while ((name_tok = peek()) != Token::RBRACE) {
1528 // Keep track of the first reserved word encountered in case our
1529 // caller needs to report an error.
1530 if (!reserved_loc->IsValid() &&
1531 !Token::IsIdentifier(name_tok, STRICT, false)) {
1532 *reserved_loc = scanner()->location();
1533 }
1534 const AstRawString* local_name = ParseIdentifierName(CHECK_OK);
1535 const AstRawString* export_name = NULL;
1536 if (CheckContextualKeyword(CStrVector("as"))) {
1537 export_name = ParseIdentifierName(CHECK_OK);
1538 }
1539 if (export_name == NULL) {
1540 export_name = local_name;
1541 }
1542 export_names->Add(export_name, zone());
1543 local_names->Add(local_name, zone());
1544 export_locations->Add(scanner()->location(), zone());
1545 if (peek() == Token::RBRACE) break;
1546 Expect(Token::COMMA, CHECK_OK);
1547 }
1548
1549 Expect(Token::RBRACE, CHECK_OK);
1550
1551 return 0;
1552 }
1553
1554
1555 ZoneList<ImportDeclaration*>* Parser::ParseNamedImports(int pos, bool* ok) {
1556 // NamedImports :
1557 // '{' '}'
1558 // '{' ImportsList '}'
1559 // '{' ImportsList ',' '}'
1560 //
1561 // ImportsList :
1562 // ImportSpecifier
1563 // ImportsList ',' ImportSpecifier
1564 //
1565 // ImportSpecifier :
1566 // BindingIdentifier
1567 // IdentifierName 'as' BindingIdentifier
1568
1569 Expect(Token::LBRACE, CHECK_OK);
1570
1571 ZoneList<ImportDeclaration*>* result =
1572 new (zone()) ZoneList<ImportDeclaration*>(1, zone());
1573 while (peek() != Token::RBRACE) {
1574 const AstRawString* import_name = ParseIdentifierName(CHECK_OK);
1575 const AstRawString* local_name = import_name;
1576 // In the presence of 'as', the left-side of the 'as' can
1577 // be any IdentifierName. But without 'as', it must be a valid
1578 // BindingIdentifier.
1579 if (CheckContextualKeyword(CStrVector("as"))) {
1580 local_name = ParseIdentifierName(CHECK_OK);
1581 }
1582 if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false)) {
1583 *ok = false;
1584 ReportMessage(MessageTemplate::kUnexpectedReserved);
1585 return NULL;
1586 } else if (IsEvalOrArguments(local_name)) {
1587 *ok = false;
1588 ReportMessage(MessageTemplate::kStrictEvalArguments);
1589 return NULL;
1590 } else if (is_strong(language_mode()) && IsUndefined(local_name)) {
1591 *ok = false;
1592 ReportMessage(MessageTemplate::kStrongUndefined);
1593 return NULL;
1594 }
1595 VariableProxy* proxy = NewUnresolved(local_name, IMPORT);
1596 ImportDeclaration* declaration =
1597 factory()->NewImportDeclaration(proxy, import_name, NULL, scope_, pos);
1598 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
1599 result->Add(declaration, zone());
1600 if (peek() == Token::RBRACE) break;
1601 Expect(Token::COMMA, CHECK_OK);
1602 }
1603
1604 Expect(Token::RBRACE, CHECK_OK);
1605
1606 return result;
1607 }
1608
1609
1610 Statement* Parser::ParseImportDeclaration(bool* ok) {
1611 // ImportDeclaration :
1612 // 'import' ImportClause 'from' ModuleSpecifier ';'
1613 // 'import' ModuleSpecifier ';'
1614 //
1615 // ImportClause :
1616 // NameSpaceImport
1617 // NamedImports
1618 // ImportedDefaultBinding
1619 // ImportedDefaultBinding ',' NameSpaceImport
1620 // ImportedDefaultBinding ',' NamedImports
1621 //
1622 // NameSpaceImport :
1623 // '*' 'as' ImportedBinding
1624
1625 int pos = peek_position();
1626 Expect(Token::IMPORT, CHECK_OK);
1627
1628 Token::Value tok = peek();
1629
1630 // 'import' ModuleSpecifier ';'
1631 if (tok == Token::STRING) {
1632 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1633 scope_->module()->AddModuleRequest(module_specifier, zone());
1634 ExpectSemicolon(CHECK_OK);
1635 return factory()->NewEmptyStatement(pos);
1636 }
1637
1638 // Parse ImportedDefaultBinding if present.
1639 ImportDeclaration* import_default_declaration = NULL;
1640 if (tok != Token::MUL && tok != Token::LBRACE) {
1641 const AstRawString* local_name =
1642 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
1643 VariableProxy* proxy = NewUnresolved(local_name, IMPORT);
1644 import_default_declaration = factory()->NewImportDeclaration(
1645 proxy, ast_value_factory()->default_string(), NULL, scope_, pos);
1646 Declare(import_default_declaration, DeclarationDescriptor::NORMAL, true,
1647 CHECK_OK);
1648 }
1649
1650 const AstRawString* module_instance_binding = NULL;
1651 ZoneList<ImportDeclaration*>* named_declarations = NULL;
1652 if (import_default_declaration == NULL || Check(Token::COMMA)) {
1653 switch (peek()) {
1654 case Token::MUL: {
1655 Consume(Token::MUL);
1656 ExpectContextualKeyword(CStrVector("as"), CHECK_OK);
1657 module_instance_binding =
1658 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
1659 // TODO(ES6): Add an appropriate declaration.
1660 break;
1661 }
1662
1663 case Token::LBRACE:
1664 named_declarations = ParseNamedImports(pos, CHECK_OK);
1665 break;
1666
1667 default:
1668 *ok = false;
1669 ReportUnexpectedToken(scanner()->current_token());
1670 return NULL;
1671 }
1672 }
1673
1674 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1675 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1676 scope_->module()->AddModuleRequest(module_specifier, zone());
1677
1678 if (module_instance_binding != NULL) {
1679 // TODO(ES6): Set the module specifier for the module namespace binding.
1680 }
1681
1682 if (import_default_declaration != NULL) {
1683 import_default_declaration->set_module_specifier(module_specifier);
1684 }
1685
1686 if (named_declarations != NULL) {
1687 for (int i = 0; i < named_declarations->length(); ++i) {
1688 named_declarations->at(i)->set_module_specifier(module_specifier);
1689 }
1690 }
1691
1692 ExpectSemicolon(CHECK_OK);
1693 return factory()->NewEmptyStatement(pos);
1694 }
1695
1696
1697 Statement* Parser::ParseExportDefault(bool* ok) {
1698 // Supports the following productions, starting after the 'default' token:
1699 // 'export' 'default' FunctionDeclaration
1700 // 'export' 'default' ClassDeclaration
1701 // 'export' 'default' AssignmentExpression[In] ';'
1702
1703 Expect(Token::DEFAULT, CHECK_OK);
1704 Scanner::Location default_loc = scanner()->location();
1705
1706 ZoneList<const AstRawString*> names(1, zone());
1707 Statement* result = NULL;
1708 switch (peek()) {
1709 case Token::FUNCTION:
1710 // TODO(ES6): Support parsing anonymous function declarations here.
1711 result = ParseFunctionDeclaration(&names, CHECK_OK);
1712 break;
1713
1714 case Token::CLASS:
1715 // TODO(ES6): Support parsing anonymous class declarations here.
1716 result = ParseClassDeclaration(&names, CHECK_OK);
1717 break;
1718
1719 default: {
1720 int pos = peek_position();
1721 ExpressionClassifier classifier;
1722 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK);
1723 ValidateExpression(&classifier, CHECK_OK);
1724
1725 ExpectSemicolon(CHECK_OK);
1726 result = factory()->NewExpressionStatement(expr, pos);
1727 break;
1728 }
1729 }
1730
1731 const AstRawString* default_string = ast_value_factory()->default_string();
1732
1733 DCHECK_LE(names.length(), 1);
1734 if (names.length() == 1) {
1735 scope_->module()->AddLocalExport(default_string, names.first(), zone(), ok);
1736 if (!*ok) {
1737 ParserTraits::ReportMessageAt(
1738 default_loc, MessageTemplate::kDuplicateExport, default_string);
1739 return NULL;
1740 }
1741 } else {
1742 // TODO(ES6): Assign result to a const binding with the name "*default*"
1743 // and add an export entry with "*default*" as the local name.
1744 }
1745
1746 return result;
1747 }
1748
1749
1750 Statement* Parser::ParseExportDeclaration(bool* ok) {
1751 // ExportDeclaration:
1752 // 'export' '*' 'from' ModuleSpecifier ';'
1753 // 'export' ExportClause ('from' ModuleSpecifier)? ';'
1754 // 'export' VariableStatement
1755 // 'export' Declaration
1756 // 'export' 'default' ... (handled in ParseExportDefault)
1757
1758 int pos = peek_position();
1759 Expect(Token::EXPORT, CHECK_OK);
1760
1761 Statement* result = NULL;
1762 ZoneList<const AstRawString*> names(1, zone());
1763 switch (peek()) {
1764 case Token::DEFAULT:
1765 return ParseExportDefault(ok);
1766
1767 case Token::MUL: {
1768 Consume(Token::MUL);
1769 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1770 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1771 scope_->module()->AddModuleRequest(module_specifier, zone());
1772 // TODO(ES6): scope_->module()->AddStarExport(...)
1773 ExpectSemicolon(CHECK_OK);
1774 return factory()->NewEmptyStatement(pos);
1775 }
1776
1777 case Token::LBRACE: {
1778 // There are two cases here:
1779 //
1780 // 'export' ExportClause ';'
1781 // and
1782 // 'export' ExportClause FromClause ';'
1783 //
1784 // In the first case, the exported identifiers in ExportClause must
1785 // not be reserved words, while in the latter they may be. We
1786 // pass in a location that gets filled with the first reserved word
1787 // encountered, and then throw a SyntaxError if we are in the
1788 // non-FromClause case.
1789 Scanner::Location reserved_loc = Scanner::Location::invalid();
1790 ZoneList<const AstRawString*> export_names(1, zone());
1791 ZoneList<Scanner::Location> export_locations(1, zone());
1792 ZoneList<const AstRawString*> local_names(1, zone());
1793 ParseExportClause(&export_names, &export_locations, &local_names,
1794 &reserved_loc, CHECK_OK);
1795 const AstRawString* indirect_export_module_specifier = NULL;
1796 if (CheckContextualKeyword(CStrVector("from"))) {
1797 indirect_export_module_specifier = ParseModuleSpecifier(CHECK_OK);
1798 } else if (reserved_loc.IsValid()) {
1799 // No FromClause, so reserved words are invalid in ExportClause.
1800 *ok = false;
1801 ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
1802 return NULL;
1803 }
1804 ExpectSemicolon(CHECK_OK);
1805 const int length = export_names.length();
1806 DCHECK_EQ(length, local_names.length());
1807 DCHECK_EQ(length, export_locations.length());
1808 if (indirect_export_module_specifier == NULL) {
1809 for (int i = 0; i < length; ++i) {
1810 scope_->module()->AddLocalExport(export_names[i], local_names[i],
1811 zone(), ok);
1812 if (!*ok) {
1813 ParserTraits::ReportMessageAt(export_locations[i],
1814 MessageTemplate::kDuplicateExport,
1815 export_names[i]);
1816 return NULL;
1817 }
1818 }
1819 } else {
1820 scope_->module()->AddModuleRequest(indirect_export_module_specifier,
1821 zone());
1822 for (int i = 0; i < length; ++i) {
1823 // TODO(ES6): scope_->module()->AddIndirectExport(...);(
1824 }
1825 }
1826 return factory()->NewEmptyStatement(pos);
1827 }
1828
1829 case Token::FUNCTION:
1830 result = ParseFunctionDeclaration(&names, CHECK_OK);
1831 break;
1832
1833 case Token::CLASS:
1834 result = ParseClassDeclaration(&names, CHECK_OK);
1835 break;
1836
1837 case Token::VAR:
1838 case Token::LET:
1839 case Token::CONST:
1840 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK);
1841 break;
1842
1843 default:
1844 *ok = false;
1845 ReportUnexpectedToken(scanner()->current_token());
1846 return NULL;
1847 }
1848
1849 // Extract declared names into export declarations.
1850 ModuleDescriptor* descriptor = scope_->module();
1851 for (int i = 0; i < names.length(); ++i) {
1852 descriptor->AddLocalExport(names[i], names[i], zone(), ok);
1853 if (!*ok) {
1854 // TODO(adamk): Possibly report this error at the right place.
1855 ParserTraits::ReportMessage(MessageTemplate::kDuplicateExport, names[i]);
1856 return NULL;
1857 }
1858 }
1859
1860 DCHECK_NOT_NULL(result);
1861 return result;
1862 }
1863
1864
1865 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels,
1866 bool* ok) {
1867 // Statement ::
1868 // EmptyStatement
1869 // ...
1870
1871 if (peek() == Token::SEMICOLON) {
1872 Next();
1873 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1874 }
1875 return ParseSubStatement(labels, ok);
1876 }
1877
1878
1879 Statement* Parser::ParseSubStatement(ZoneList<const AstRawString*>* labels,
1880 bool* ok) {
1881 // Statement ::
1882 // Block
1883 // VariableStatement
1884 // EmptyStatement
1885 // ExpressionStatement
1886 // IfStatement
1887 // IterationStatement
1888 // ContinueStatement
1889 // BreakStatement
1890 // ReturnStatement
1891 // WithStatement
1892 // LabelledStatement
1893 // SwitchStatement
1894 // ThrowStatement
1895 // TryStatement
1896 // DebuggerStatement
1897
1898 // Note: Since labels can only be used by 'break' and 'continue'
1899 // statements, which themselves are only valid within blocks,
1900 // iterations or 'switch' statements (i.e., BreakableStatements),
1901 // labels can be simply ignored in all other cases; except for
1902 // trivial labeled break statements 'label: break label' which is
1903 // parsed into an empty statement.
1904 switch (peek()) {
1905 case Token::LBRACE:
1906 return ParseBlock(labels, ok);
1907
1908 case Token::SEMICOLON:
1909 if (is_strong(language_mode())) {
1910 ReportMessageAt(scanner()->peek_location(),
1911 MessageTemplate::kStrongEmpty);
1912 *ok = false;
1913 return NULL;
1914 }
1915 Next();
1916 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1917
1918 case Token::IF:
1919 return ParseIfStatement(labels, ok);
1920
1921 case Token::DO:
1922 return ParseDoWhileStatement(labels, ok);
1923
1924 case Token::WHILE:
1925 return ParseWhileStatement(labels, ok);
1926
1927 case Token::FOR:
1928 return ParseForStatement(labels, ok);
1929
1930 case Token::CONTINUE:
1931 case Token::BREAK:
1932 case Token::RETURN:
1933 case Token::THROW:
1934 case Token::TRY: {
1935 // These statements must have their labels preserved in an enclosing
1936 // block
1937 if (labels == NULL) {
1938 return ParseStatementAsUnlabelled(labels, ok);
1939 } else {
1940 Block* result =
1941 factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition);
1942 Target target(&this->target_stack_, result);
1943 Statement* statement = ParseStatementAsUnlabelled(labels, CHECK_OK);
1944 if (result) result->statements()->Add(statement, zone());
1945 return result;
1946 }
1947 }
1948
1949 case Token::WITH:
1950 return ParseWithStatement(labels, ok);
1951
1952 case Token::SWITCH:
1953 return ParseSwitchStatement(labels, ok);
1954
1955 case Token::FUNCTION: {
1956 // FunctionDeclaration is only allowed in the context of SourceElements
1957 // (Ecma 262 5th Edition, clause 14):
1958 // SourceElement:
1959 // Statement
1960 // FunctionDeclaration
1961 // Common language extension is to allow function declaration in place
1962 // of any statement. This language extension is disabled in strict mode.
1963 //
1964 // In Harmony mode, this case also handles the extension:
1965 // Statement:
1966 // GeneratorDeclaration
1967 if (is_strict(language_mode())) {
1968 ReportMessageAt(scanner()->peek_location(),
1969 MessageTemplate::kStrictFunction);
1970 *ok = false;
1971 return NULL;
1972 }
1973 return ParseFunctionDeclaration(NULL, ok);
1974 }
1975
1976 case Token::DEBUGGER:
1977 return ParseDebuggerStatement(ok);
1978
1979 case Token::VAR:
1980 return ParseVariableStatement(kStatement, NULL, ok);
1981
1982 case Token::CONST:
1983 // In ES6 CONST is not allowed as a Statement, only as a
1984 // LexicalDeclaration, however we continue to allow it in sloppy mode for
1985 // backwards compatibility.
1986 if (is_sloppy(language_mode()) && allow_legacy_const()) {
1987 return ParseVariableStatement(kStatement, NULL, ok);
1988 }
1989
1990 // Fall through.
1991 default:
1992 return ParseExpressionOrLabelledStatement(labels, ok);
1993 }
1994 }
1995
1996 Statement* Parser::ParseStatementAsUnlabelled(
1997 ZoneList<const AstRawString*>* labels, bool* ok) {
1998 switch (peek()) {
1999 case Token::CONTINUE:
2000 return ParseContinueStatement(ok);
2001
2002 case Token::BREAK:
2003 return ParseBreakStatement(labels, ok);
2004
2005 case Token::RETURN:
2006 return ParseReturnStatement(ok);
2007
2008 case Token::THROW:
2009 return ParseThrowStatement(ok);
2010
2011 case Token::TRY:
2012 return ParseTryStatement(ok);
2013
2014 default:
2015 UNREACHABLE();
2016 return NULL;
2017 }
2018 }
2019
2020
2021 VariableProxy* Parser::NewUnresolved(const AstRawString* name,
2022 VariableMode mode) {
2023 // If we are inside a function, a declaration of a var/const variable is a
2024 // truly local variable, and the scope of the variable is always the function
2025 // scope.
2026 // Let/const variables in harmony mode are always added to the immediately
2027 // enclosing scope.
2028 return DeclarationScope(mode)->NewUnresolved(
2029 factory(), name, Variable::NORMAL, scanner()->location().beg_pos,
2030 scanner()->location().end_pos);
2031 }
2032
2033
2034 Variable* Parser::Declare(Declaration* declaration,
2035 DeclarationDescriptor::Kind declaration_kind,
2036 bool resolve, bool* ok, Scope* scope) {
2037 VariableProxy* proxy = declaration->proxy();
2038 DCHECK(proxy->raw_name() != NULL);
2039 const AstRawString* name = proxy->raw_name();
2040 VariableMode mode = declaration->mode();
2041 if (scope == nullptr) scope = scope_;
2042 Scope* declaration_scope =
2043 IsLexicalVariableMode(mode) ? scope : scope->DeclarationScope();
2044 Variable* var = NULL;
2045
2046 // If a suitable scope exists, then we can statically declare this
2047 // variable and also set its mode. In any case, a Declaration node
2048 // will be added to the scope so that the declaration can be added
2049 // to the corresponding activation frame at runtime if necessary.
2050 // For instance, var declarations inside a sloppy eval scope need
2051 // to be added to the calling function context. Similarly, strict
2052 // mode eval scope and lexical eval bindings do not leak variable
2053 // declarations to the caller's scope so we declare all locals, too.
2054 if (declaration_scope->is_function_scope() ||
2055 declaration_scope->is_block_scope() ||
2056 declaration_scope->is_module_scope() ||
2057 declaration_scope->is_script_scope() ||
2058 (declaration_scope->is_eval_scope() &&
2059 (is_strict(declaration_scope->language_mode()) ||
2060 IsLexicalVariableMode(mode)))) {
2061 // Declare the variable in the declaration scope.
2062 var = declaration_scope->LookupLocal(name);
2063 if (var == NULL) {
2064 // Declare the name.
2065 Variable::Kind kind = Variable::NORMAL;
2066 int declaration_group_start = -1;
2067 if (declaration->IsFunctionDeclaration()) {
2068 kind = Variable::FUNCTION;
2069 } else if (declaration->IsVariableDeclaration() &&
2070 declaration->AsVariableDeclaration()->is_class_declaration()) {
2071 kind = Variable::CLASS;
2072 declaration_group_start =
2073 declaration->AsVariableDeclaration()->declaration_group_start();
2074 }
2075 var = declaration_scope->DeclareLocal(
2076 name, mode, declaration->initialization(), kind, kNotAssigned,
2077 declaration_group_start);
2078 } else if (IsLexicalVariableMode(mode) ||
2079 IsLexicalVariableMode(var->mode()) ||
2080 ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) &&
2081 !declaration_scope->is_script_scope())) {
2082 // The name was declared in this scope before; check for conflicting
2083 // re-declarations. We have a conflict if either of the declarations is
2084 // not a var (in script scope, we also have to ignore legacy const for
2085 // compatibility). There is similar code in runtime.cc in the Declare
2086 // functions. The function CheckConflictingVarDeclarations checks for
2087 // var and let bindings from different scopes whereas this is a check for
2088 // conflicting declarations within the same scope. This check also covers
2089 // the special case
2090 //
2091 // function () { let x; { var x; } }
2092 //
2093 // because the var declaration is hoisted to the function scope where 'x'
2094 // is already bound.
2095 DCHECK(IsDeclaredVariableMode(var->mode()));
2096 if (is_strict(language_mode()) || allow_harmony_sloppy()) {
2097 // In harmony we treat re-declarations as early errors. See
2098 // ES5 16 for a definition of early errors.
2099 if (declaration_kind == DeclarationDescriptor::NORMAL) {
2100 ParserTraits::ReportMessage(MessageTemplate::kVarRedeclaration, name);
2101 } else {
2102 ParserTraits::ReportMessage(MessageTemplate::kParamDupe);
2103 }
2104 *ok = false;
2105 return nullptr;
2106 }
2107 Expression* expression = NewThrowSyntaxError(
2108 MessageTemplate::kVarRedeclaration, name, declaration->position());
2109 declaration_scope->SetIllegalRedeclaration(expression);
2110 } else if (mode == VAR) {
2111 var->set_maybe_assigned();
2112 }
2113 } else if (declaration_scope->is_eval_scope() &&
2114 is_sloppy(declaration_scope->language_mode()) &&
2115 !IsLexicalVariableMode(mode)) {
2116 // In a var binding in a sloppy direct eval, pollute the enclosing scope
2117 // with this new binding by doing the following:
2118 // The proxy is bound to a lookup variable to force a dynamic declaration
2119 // using the DeclareLookupSlot runtime function.
2120 Variable::Kind kind = Variable::NORMAL;
2121 // TODO(sigurds) figure out if kNotAssigned is OK here
2122 var = new (zone()) Variable(declaration_scope, name, mode, kind,
2123 declaration->initialization(), kNotAssigned);
2124 var->AllocateTo(VariableLocation::LOOKUP, -1);
2125 var->SetFromEval();
2126 resolve = true;
2127 }
2128
2129
2130 // We add a declaration node for every declaration. The compiler
2131 // will only generate code if necessary. In particular, declarations
2132 // for inner local variables that do not represent functions won't
2133 // result in any generated code.
2134 //
2135 // Note that we always add an unresolved proxy even if it's not
2136 // used, simply because we don't know in this method (w/o extra
2137 // parameters) if the proxy is needed or not. The proxy will be
2138 // bound during variable resolution time unless it was pre-bound
2139 // below.
2140 //
2141 // WARNING: This will lead to multiple declaration nodes for the
2142 // same variable if it is declared several times. This is not a
2143 // semantic issue as long as we keep the source order, but it may be
2144 // a performance issue since it may lead to repeated
2145 // RuntimeHidden_DeclareLookupSlot calls.
2146 declaration_scope->AddDeclaration(declaration);
2147
2148 if (mode == CONST_LEGACY && declaration_scope->is_script_scope()) {
2149 // For global const variables we bind the proxy to a variable.
2150 DCHECK(resolve); // should be set by all callers
2151 Variable::Kind kind = Variable::NORMAL;
2152 var = new (zone()) Variable(declaration_scope, name, mode, kind,
2153 kNeedsInitialization, kNotAssigned);
2154 }
2155
2156 // If requested and we have a local variable, bind the proxy to the variable
2157 // at parse-time. This is used for functions (and consts) declared inside
2158 // statements: the corresponding function (or const) variable must be in the
2159 // function scope and not a statement-local scope, e.g. as provided with a
2160 // 'with' statement:
2161 //
2162 // with (obj) {
2163 // function f() {}
2164 // }
2165 //
2166 // which is translated into:
2167 //
2168 // with (obj) {
2169 // // in this case this is not: 'var f; f = function () {};'
2170 // var f = function () {};
2171 // }
2172 //
2173 // Note that if 'f' is accessed from inside the 'with' statement, it
2174 // will be allocated in the context (because we must be able to look
2175 // it up dynamically) but it will also be accessed statically, i.e.,
2176 // with a context slot index and a context chain length for this
2177 // initialization code. Thus, inside the 'with' statement, we need
2178 // both access to the static and the dynamic context chain; the
2179 // runtime needs to provide both.
2180 if (resolve && var != NULL) {
2181 proxy->BindTo(var);
2182 }
2183 return var;
2184 }
2185
2186
2187 // Language extension which is only enabled for source files loaded
2188 // through the API's extension mechanism. A native function
2189 // declaration is resolved by looking up the function through a
2190 // callback provided by the extension.
2191 Statement* Parser::ParseNativeDeclaration(bool* ok) {
2192 int pos = peek_position();
2193 Expect(Token::FUNCTION, CHECK_OK);
2194 // Allow "eval" or "arguments" for backward compatibility.
2195 const AstRawString* name =
2196 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2197 Expect(Token::LPAREN, CHECK_OK);
2198 bool done = (peek() == Token::RPAREN);
2199 while (!done) {
2200 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2201 done = (peek() == Token::RPAREN);
2202 if (!done) {
2203 Expect(Token::COMMA, CHECK_OK);
2204 }
2205 }
2206 Expect(Token::RPAREN, CHECK_OK);
2207 Expect(Token::SEMICOLON, CHECK_OK);
2208
2209 // Make sure that the function containing the native declaration
2210 // isn't lazily compiled. The extension structures are only
2211 // accessible while parsing the first time not when reparsing
2212 // because of lazy compilation.
2213 DeclarationScope(VAR)->ForceEagerCompilation();
2214
2215 // TODO(1240846): It's weird that native function declarations are
2216 // introduced dynamically when we meet their declarations, whereas
2217 // other functions are set up when entering the surrounding scope.
2218 VariableProxy* proxy = NewUnresolved(name, VAR);
2219 Declaration* declaration =
2220 factory()->NewVariableDeclaration(proxy, VAR, scope_, pos);
2221 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
2222 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral(
2223 name, extension_, RelocInfo::kNoPosition);
2224 return factory()->NewExpressionStatement(
2225 factory()->NewAssignment(Token::INIT, proxy, lit, RelocInfo::kNoPosition),
2226 pos);
2227 }
2228
2229
2230 Statement* Parser::ParseFunctionDeclaration(
2231 ZoneList<const AstRawString*>* names, bool* ok) {
2232 // FunctionDeclaration ::
2233 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
2234 // GeneratorDeclaration ::
2235 // 'function' '*' Identifier '(' FormalParameterListopt ')'
2236 // '{' FunctionBody '}'
2237 Expect(Token::FUNCTION, CHECK_OK);
2238 int pos = position();
2239 bool is_generator = Check(Token::MUL);
2240 bool is_strict_reserved = false;
2241 const AstRawString* name = ParseIdentifierOrStrictReservedWord(
2242 &is_strict_reserved, CHECK_OK);
2243
2244 if (fni_ != NULL) {
2245 fni_->Enter();
2246 fni_->PushEnclosingName(name);
2247 }
2248 FunctionLiteral* fun = ParseFunctionLiteral(
2249 name, scanner()->location(),
2250 is_strict_reserved ? kFunctionNameIsStrictReserved
2251 : kFunctionNameValidityUnknown,
2252 is_generator ? FunctionKind::kGeneratorFunction
2253 : FunctionKind::kNormalFunction,
2254 pos, FunctionLiteral::DECLARATION, FunctionLiteral::NORMAL_ARITY,
2255 language_mode(), CHECK_OK);
2256 if (fni_ != NULL) fni_->Leave();
2257
2258 // Even if we're not at the top-level of the global or a function
2259 // scope, we treat it as such and introduce the function with its
2260 // initial value upon entering the corresponding scope.
2261 // In ES6, a function behaves as a lexical binding, except in
2262 // a script scope, or the initial scope of eval or another function.
2263 VariableMode mode =
2264 is_strong(language_mode())
2265 ? CONST
2266 : (is_strict(language_mode()) || allow_harmony_sloppy_function()) &&
2267 !scope_->is_declaration_scope()
2268 ? LET
2269 : VAR;
2270 VariableProxy* proxy = NewUnresolved(name, mode);
2271 Declaration* declaration =
2272 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
2273 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
2274 if (names) names->Add(name, zone());
2275 EmptyStatement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2276 if (is_sloppy(language_mode()) && allow_harmony_sloppy_function() &&
2277 !scope_->is_declaration_scope()) {
2278 SloppyBlockFunctionStatement* delegate =
2279 factory()->NewSloppyBlockFunctionStatement(empty, scope_);
2280 scope_->DeclarationScope()->sloppy_block_function_map()->Declare(name,
2281 delegate);
2282 return delegate;
2283 }
2284 return empty;
2285 }
2286
2287
2288 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
2289 bool* ok) {
2290 // ClassDeclaration ::
2291 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
2292 //
2293 // A ClassDeclaration
2294 //
2295 // class C { ... }
2296 //
2297 // has the same semantics as:
2298 //
2299 // let C = class C { ... };
2300 //
2301 // so rewrite it as such.
2302
2303 Expect(Token::CLASS, CHECK_OK);
2304 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
2305 ReportMessage(MessageTemplate::kSloppyLexical);
2306 *ok = false;
2307 return NULL;
2308 }
2309
2310 int pos = position();
2311 bool is_strict_reserved = false;
2312 const AstRawString* name =
2313 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
2314 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(),
2315 is_strict_reserved, pos, CHECK_OK);
2316
2317 VariableMode mode = is_strong(language_mode()) ? CONST : LET;
2318 VariableProxy* proxy = NewUnresolved(name, mode);
2319 const bool is_class_declaration = true;
2320 Declaration* declaration = factory()->NewVariableDeclaration(
2321 proxy, mode, scope_, pos, is_class_declaration,
2322 scope_->class_declaration_group_start());
2323 Variable* outer_class_variable =
2324 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
2325 proxy->var()->set_initializer_position(position());
2326 // This is needed because a class ("class Name { }") creates two bindings (one
2327 // in the outer scope, and one in the class scope). The method is a function
2328 // scope inside the inner scope (class scope). The consecutive class
2329 // declarations are in the outer scope.
2330 if (value->class_variable_proxy() && value->class_variable_proxy()->var() &&
2331 outer_class_variable->is_class()) {
2332 // In some cases, the outer variable is not detected as a class variable;
2333 // this happens e.g., for lazy methods. They are excluded from strong mode
2334 // checks for now. TODO(marja, rossberg): re-create variables with the
2335 // correct Kind and remove this hack.
2336 value->class_variable_proxy()
2337 ->var()
2338 ->AsClassVariable()
2339 ->set_declaration_group_start(
2340 outer_class_variable->AsClassVariable()->declaration_group_start());
2341 }
2342
2343 Assignment* assignment =
2344 factory()->NewAssignment(Token::INIT, proxy, value, pos);
2345 Statement* assignment_statement =
2346 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
2347 if (names) names->Add(name, zone());
2348 return assignment_statement;
2349 }
2350
2351
2352 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) {
2353 // The harmony mode uses block elements instead of statements.
2354 //
2355 // Block ::
2356 // '{' StatementList '}'
2357
2358 // Construct block expecting 16 statements.
2359 Block* body =
2360 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2361 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
2362
2363 // Parse the statements and collect escaping labels.
2364 Expect(Token::LBRACE, CHECK_OK);
2365 block_scope->set_start_position(scanner()->location().beg_pos);
2366 { BlockState block_state(&scope_, block_scope);
2367 Target target(&this->target_stack_, body);
2368
2369 while (peek() != Token::RBRACE) {
2370 Statement* stat = ParseStatementListItem(CHECK_OK);
2371 if (stat && !stat->IsEmpty()) {
2372 body->statements()->Add(stat, zone());
2373 }
2374 }
2375 }
2376 Expect(Token::RBRACE, CHECK_OK);
2377 block_scope->set_end_position(scanner()->location().end_pos);
2378 block_scope = block_scope->FinalizeBlockScope();
2379 body->set_scope(block_scope);
2380 return body;
2381 }
2382
2383
2384 Block* Parser::DeclarationParsingResult::BuildInitializationBlock(
2385 ZoneList<const AstRawString*>* names, bool* ok) {
2386 Block* result = descriptor.parser->factory()->NewBlock(
2387 NULL, 1, true, descriptor.declaration_pos);
2388 for (auto declaration : declarations) {
2389 PatternRewriter::DeclareAndInitializeVariables(
2390 result, &descriptor, &declaration, names, CHECK_OK);
2391 }
2392 return result;
2393 }
2394
2395
2396 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
2397 ZoneList<const AstRawString*>* names,
2398 bool* ok) {
2399 // VariableStatement ::
2400 // VariableDeclarations ';'
2401
2402 // The scope of a var/const declared variable anywhere inside a function
2403 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
2404 // transform a source-level var/const declaration into a (Function)
2405 // Scope declaration, and rewrite the source-level initialization into an
2406 // assignment statement. We use a block to collect multiple assignments.
2407 //
2408 // We mark the block as initializer block because we don't want the
2409 // rewriter to add a '.result' assignment to such a block (to get compliant
2410 // behavior for code such as print(eval('var x = 7')), and for cosmetic
2411 // reasons when pretty-printing. Also, unless an assignment (initialization)
2412 // is inside an initializer block, it is ignored.
2413
2414 DeclarationParsingResult parsing_result;
2415 ParseVariableDeclarations(var_context, &parsing_result, CHECK_OK);
2416 ExpectSemicolon(CHECK_OK);
2417
2418 Block* result = parsing_result.BuildInitializationBlock(names, CHECK_OK);
2419 return result;
2420 }
2421
2422
2423 void Parser::ParseVariableDeclarations(VariableDeclarationContext var_context,
2424 DeclarationParsingResult* parsing_result,
2425 bool* ok) {
2426 // VariableDeclarations ::
2427 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
2428 //
2429 // The ES6 Draft Rev3 specifies the following grammar for const declarations
2430 //
2431 // ConstDeclaration ::
2432 // const ConstBinding (',' ConstBinding)* ';'
2433 // ConstBinding ::
2434 // Identifier '=' AssignmentExpression
2435 //
2436 // TODO(ES6):
2437 // ConstBinding ::
2438 // BindingPattern '=' AssignmentExpression
2439
2440 parsing_result->descriptor.parser = this;
2441 parsing_result->descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
2442 parsing_result->descriptor.declaration_pos = peek_position();
2443 parsing_result->descriptor.initialization_pos = peek_position();
2444 parsing_result->descriptor.mode = VAR;
2445 // True if the binding needs initialization. 'let' and 'const' declared
2446 // bindings are created uninitialized by their declaration nodes and
2447 // need initialization. 'var' declared bindings are always initialized
2448 // immediately by their declaration nodes.
2449 parsing_result->descriptor.needs_init = false;
2450 parsing_result->descriptor.is_const = false;
2451 if (peek() == Token::VAR) {
2452 if (is_strong(language_mode())) {
2453 Scanner::Location location = scanner()->peek_location();
2454 ReportMessageAt(location, MessageTemplate::kStrongVar);
2455 *ok = false;
2456 return;
2457 }
2458 Consume(Token::VAR);
2459 } else if (peek() == Token::CONST && allow_const()) {
2460 Consume(Token::CONST);
2461 if (is_sloppy(language_mode()) && allow_legacy_const()) {
2462 parsing_result->descriptor.mode = CONST_LEGACY;
2463 ++use_counts_[v8::Isolate::kLegacyConst];
2464 } else {
2465 DCHECK(is_strict(language_mode()) || allow_harmony_sloppy());
2466 DCHECK(var_context != kStatement);
2467 parsing_result->descriptor.mode = CONST;
2468 }
2469 parsing_result->descriptor.is_const = true;
2470 parsing_result->descriptor.needs_init = true;
2471 } else if (peek() == Token::LET && allow_let()) {
2472 Consume(Token::LET);
2473 DCHECK(var_context != kStatement);
2474 parsing_result->descriptor.mode = LET;
2475 parsing_result->descriptor.needs_init = true;
2476 } else {
2477 UNREACHABLE(); // by current callers
2478 }
2479
2480 parsing_result->descriptor.declaration_scope =
2481 DeclarationScope(parsing_result->descriptor.mode);
2482 parsing_result->descriptor.scope = scope_;
2483 parsing_result->descriptor.hoist_scope = nullptr;
2484
2485
2486 bool first_declaration = true;
2487 int bindings_start = peek_position();
2488 bool is_for_iteration_variable;
2489 do {
2490 if (fni_ != NULL) fni_->Enter();
2491
2492 // Parse name.
2493 if (!first_declaration) Consume(Token::COMMA);
2494
2495 Expression* pattern;
2496 int decl_pos = peek_position();
2497 {
2498 ExpressionClassifier pattern_classifier;
2499 Token::Value next = peek();
2500 pattern = ParsePrimaryExpression(&pattern_classifier, ok);
2501 if (!*ok) return;
2502 ValidateBindingPattern(&pattern_classifier, ok);
2503 if (!*ok) return;
2504 if (IsLexicalVariableMode(parsing_result->descriptor.mode)) {
2505 ValidateLetPattern(&pattern_classifier, ok);
2506 if (!*ok) return;
2507 }
2508 if (!allow_harmony_destructuring_bind() && !pattern->IsVariableProxy()) {
2509 ReportUnexpectedToken(next);
2510 *ok = false;
2511 return;
2512 }
2513 }
2514
2515 bool is_pattern = pattern->IsObjectLiteral() || pattern->IsArrayLiteral();
2516
2517 Scanner::Location variable_loc = scanner()->location();
2518 const AstRawString* single_name =
2519 pattern->IsVariableProxy() ? pattern->AsVariableProxy()->raw_name()
2520 : nullptr;
2521 if (single_name != nullptr) {
2522 if (fni_ != NULL) fni_->PushVariableName(single_name);
2523 }
2524
2525 is_for_iteration_variable =
2526 var_context == kForStatement &&
2527 (peek() == Token::IN || PeekContextualKeyword(CStrVector("of")));
2528 if (is_for_iteration_variable &&
2529 (parsing_result->descriptor.mode == CONST ||
2530 parsing_result->descriptor.mode == CONST_LEGACY)) {
2531 parsing_result->descriptor.needs_init = false;
2532 }
2533
2534 Expression* value = NULL;
2535 // Harmony consts have non-optional initializers.
2536 int initializer_position = RelocInfo::kNoPosition;
2537 if (Check(Token::ASSIGN)) {
2538 ExpressionClassifier classifier;
2539 value = ParseAssignmentExpression(var_context != kForStatement,
2540 &classifier, ok);
2541 if (!*ok) return;
2542 ValidateExpression(&classifier, ok);
2543 if (!*ok) return;
2544 variable_loc.end_pos = scanner()->location().end_pos;
2545
2546 if (!parsing_result->first_initializer_loc.IsValid()) {
2547 parsing_result->first_initializer_loc = variable_loc;
2548 }
2549
2550 // Don't infer if it is "a = function(){...}();"-like expression.
2551 if (single_name) {
2552 if (fni_ != NULL && value->AsCall() == NULL &&
2553 value->AsCallNew() == NULL) {
2554 fni_->Infer();
2555 } else {
2556 fni_->RemoveLastFunction();
2557 }
2558 }
2559 // End position of the initializer is after the assignment expression.
2560 initializer_position = scanner()->location().end_pos;
2561 } else {
2562 if ((parsing_result->descriptor.mode == CONST || is_pattern) &&
2563 !is_for_iteration_variable) {
2564 ParserTraits::ReportMessageAt(
2565 Scanner::Location(decl_pos, scanner()->location().end_pos),
2566 MessageTemplate::kDeclarationMissingInitializer,
2567 is_pattern ? "destructuring" : "const");
2568 *ok = false;
2569 return;
2570 }
2571 // End position of the initializer is after the variable.
2572 initializer_position = position();
2573 }
2574
2575 // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
2576 if (value == NULL && parsing_result->descriptor.needs_init) {
2577 value = GetLiteralUndefined(position());
2578 }
2579
2580 if (single_name && fni_ != NULL) fni_->Leave();
2581 parsing_result->declarations.Add(DeclarationParsingResult::Declaration(
2582 pattern, initializer_position, value));
2583 first_declaration = false;
2584 } while (peek() == Token::COMMA);
2585
2586 parsing_result->bindings_loc =
2587 Scanner::Location(bindings_start, scanner()->location().end_pos);
2588 }
2589
2590
2591 static bool ContainsLabel(ZoneList<const AstRawString*>* labels,
2592 const AstRawString* label) {
2593 DCHECK(label != NULL);
2594 if (labels != NULL) {
2595 for (int i = labels->length(); i-- > 0; ) {
2596 if (labels->at(i) == label) {
2597 return true;
2598 }
2599 }
2600 }
2601 return false;
2602 }
2603
2604
2605 Statement* Parser::ParseExpressionOrLabelledStatement(
2606 ZoneList<const AstRawString*>* labels, bool* ok) {
2607 // ExpressionStatement | LabelledStatement ::
2608 // Expression ';'
2609 // Identifier ':' Statement
2610 //
2611 // ExpressionStatement[Yield] :
2612 // [lookahead ∉ {{, function, class, let [}] Expression[In, ?Yield] ;
2613
2614 int pos = peek_position();
2615
2616 switch (peek()) {
2617 case Token::FUNCTION:
2618 case Token::LBRACE:
2619 UNREACHABLE(); // Always handled by the callers.
2620 case Token::CLASS:
2621 ReportUnexpectedToken(Next());
2622 *ok = false;
2623 return nullptr;
2624
2625 case Token::THIS:
2626 if (!FLAG_strong_this) break;
2627 // Fall through.
2628 case Token::SUPER:
2629 if (is_strong(language_mode()) &&
2630 IsClassConstructor(function_state_->kind())) {
2631 bool is_this = peek() == Token::THIS;
2632 Expression* expr;
2633 ExpressionClassifier classifier;
2634 if (is_this) {
2635 expr = ParseStrongInitializationExpression(&classifier, CHECK_OK);
2636 } else {
2637 expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK);
2638 }
2639 ValidateExpression(&classifier, CHECK_OK);
2640 switch (peek()) {
2641 case Token::SEMICOLON:
2642 Consume(Token::SEMICOLON);
2643 break;
2644 case Token::RBRACE:
2645 case Token::EOS:
2646 break;
2647 default:
2648 if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
2649 ReportMessageAt(function_state_->this_location(),
2650 is_this
2651 ? MessageTemplate::kStrongConstructorThis
2652 : MessageTemplate::kStrongConstructorSuper);
2653 *ok = false;
2654 return nullptr;
2655 }
2656 }
2657 return factory()->NewExpressionStatement(expr, pos);
2658 }
2659 break;
2660
2661 default:
2662 break;
2663 }
2664
2665 bool starts_with_idenfifier = peek_any_identifier();
2666 Expression* expr = ParseExpression(true, CHECK_OK);
2667 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
2668 expr->AsVariableProxy() != NULL &&
2669 !expr->AsVariableProxy()->is_this()) {
2670 // Expression is a single identifier, and not, e.g., a parenthesized
2671 // identifier.
2672 VariableProxy* var = expr->AsVariableProxy();
2673 const AstRawString* label = var->raw_name();
2674 // TODO(1240780): We don't check for redeclaration of labels
2675 // during preparsing since keeping track of the set of active
2676 // labels requires nontrivial changes to the way scopes are
2677 // structured. However, these are probably changes we want to
2678 // make later anyway so we should go back and fix this then.
2679 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
2680 ParserTraits::ReportMessage(MessageTemplate::kLabelRedeclaration, label);
2681 *ok = false;
2682 return NULL;
2683 }
2684 if (labels == NULL) {
2685 labels = new(zone()) ZoneList<const AstRawString*>(4, zone());
2686 }
2687 labels->Add(label, zone());
2688 // Remove the "ghost" variable that turned out to be a label
2689 // from the top scope. This way, we don't try to resolve it
2690 // during the scope processing.
2691 scope_->RemoveUnresolved(var);
2692 Expect(Token::COLON, CHECK_OK);
2693 return ParseStatement(labels, ok);
2694 }
2695
2696 // If we have an extension, we allow a native function declaration.
2697 // A native function declaration starts with "native function" with
2698 // no line-terminator between the two words.
2699 if (extension_ != NULL && peek() == Token::FUNCTION &&
2700 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL &&
2701 expr->AsVariableProxy() != NULL &&
2702 expr->AsVariableProxy()->raw_name() ==
2703 ast_value_factory()->native_string() &&
2704 !scanner()->literal_contains_escapes()) {
2705 return ParseNativeDeclaration(ok);
2706 }
2707
2708 // Parsed expression statement, followed by semicolon.
2709 // Detect attempts at 'let' declarations in sloppy mode.
2710 if (!allow_harmony_sloppy_let() && peek() == Token::IDENTIFIER &&
2711 expr->AsVariableProxy() != NULL &&
2712 expr->AsVariableProxy()->raw_name() ==
2713 ast_value_factory()->let_string()) {
2714 ReportMessage(MessageTemplate::kSloppyLexical, NULL);
2715 *ok = false;
2716 return NULL;
2717 }
2718 ExpectSemicolon(CHECK_OK);
2719 return factory()->NewExpressionStatement(expr, pos);
2720 }
2721
2722
2723 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels,
2724 bool* ok) {
2725 // IfStatement ::
2726 // 'if' '(' Expression ')' Statement ('else' Statement)?
2727
2728 int pos = peek_position();
2729 Expect(Token::IF, CHECK_OK);
2730 Expect(Token::LPAREN, CHECK_OK);
2731 Expression* condition = ParseExpression(true, CHECK_OK);
2732 Expect(Token::RPAREN, CHECK_OK);
2733 Statement* then_statement = ParseSubStatement(labels, CHECK_OK);
2734 Statement* else_statement = NULL;
2735 if (peek() == Token::ELSE) {
2736 Next();
2737 else_statement = ParseSubStatement(labels, CHECK_OK);
2738 } else {
2739 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2740 }
2741 return factory()->NewIfStatement(
2742 condition, then_statement, else_statement, pos);
2743 }
2744
2745
2746 Statement* Parser::ParseContinueStatement(bool* ok) {
2747 // ContinueStatement ::
2748 // 'continue' Identifier? ';'
2749
2750 int pos = peek_position();
2751 Expect(Token::CONTINUE, CHECK_OK);
2752 const AstRawString* label = NULL;
2753 Token::Value tok = peek();
2754 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2755 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2756 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2757 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2758 }
2759 IterationStatement* target = LookupContinueTarget(label, CHECK_OK);
2760 if (target == NULL) {
2761 // Illegal continue statement.
2762 MessageTemplate::Template message = MessageTemplate::kIllegalContinue;
2763 if (label != NULL) {
2764 message = MessageTemplate::kUnknownLabel;
2765 }
2766 ParserTraits::ReportMessage(message, label);
2767 *ok = false;
2768 return NULL;
2769 }
2770 ExpectSemicolon(CHECK_OK);
2771 return factory()->NewContinueStatement(target, pos);
2772 }
2773
2774
2775 Statement* Parser::ParseBreakStatement(ZoneList<const AstRawString*>* labels,
2776 bool* ok) {
2777 // BreakStatement ::
2778 // 'break' Identifier? ';'
2779
2780 int pos = peek_position();
2781 Expect(Token::BREAK, CHECK_OK);
2782 const AstRawString* label = NULL;
2783 Token::Value tok = peek();
2784 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2785 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2786 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2787 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2788 }
2789 // Parse labeled break statements that target themselves into
2790 // empty statements, e.g. 'l1: l2: l3: break l2;'
2791 if (label != NULL && ContainsLabel(labels, label)) {
2792 ExpectSemicolon(CHECK_OK);
2793 return factory()->NewEmptyStatement(pos);
2794 }
2795 BreakableStatement* target = NULL;
2796 target = LookupBreakTarget(label, CHECK_OK);
2797 if (target == NULL) {
2798 // Illegal break statement.
2799 MessageTemplate::Template message = MessageTemplate::kIllegalBreak;
2800 if (label != NULL) {
2801 message = MessageTemplate::kUnknownLabel;
2802 }
2803 ParserTraits::ReportMessage(message, label);
2804 *ok = false;
2805 return NULL;
2806 }
2807 ExpectSemicolon(CHECK_OK);
2808 return factory()->NewBreakStatement(target, pos);
2809 }
2810
2811
2812 Statement* Parser::ParseReturnStatement(bool* ok) {
2813 // ReturnStatement ::
2814 // 'return' Expression? ';'
2815
2816 // Consume the return token. It is necessary to do that before
2817 // reporting any errors on it, because of the way errors are
2818 // reported (underlining).
2819 Expect(Token::RETURN, CHECK_OK);
2820 Scanner::Location loc = scanner()->location();
2821 function_state_->set_return_location(loc);
2822
2823 Token::Value tok = peek();
2824 Statement* result;
2825 Expression* return_value;
2826 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
2827 tok == Token::SEMICOLON ||
2828 tok == Token::RBRACE ||
2829 tok == Token::EOS) {
2830 if (IsSubclassConstructor(function_state_->kind())) {
2831 return_value = ThisExpression(scope_, factory(), loc.beg_pos);
2832 } else {
2833 return_value = GetLiteralUndefined(position());
2834 }
2835 } else {
2836 if (is_strong(language_mode()) &&
2837 IsClassConstructor(function_state_->kind())) {
2838 int pos = peek_position();
2839 ReportMessageAt(Scanner::Location(pos, pos + 1),
2840 MessageTemplate::kStrongConstructorReturnValue);
2841 *ok = false;
2842 return NULL;
2843 }
2844
2845 int pos = peek_position();
2846 return_value = ParseExpression(true, CHECK_OK);
2847
2848 if (IsSubclassConstructor(function_state_->kind())) {
2849 // For subclass constructors we need to return this in case of undefined
2850 // and throw an exception in case of a non object.
2851 //
2852 // return expr;
2853 //
2854 // Is rewritten as:
2855 //
2856 // return (temp = expr) === undefined ? this :
2857 // %_IsSpecObject(temp) ? temp : throw new TypeError(...);
2858 Variable* temp = scope_->NewTemporary(
2859 ast_value_factory()->empty_string());
2860 Assignment* assign = factory()->NewAssignment(
2861 Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);
2862
2863 Expression* throw_expression =
2864 NewThrowTypeError(MessageTemplate::kDerivedConstructorReturn,
2865 ast_value_factory()->empty_string(), pos);
2866
2867 // %_IsSpecObject(temp)
2868 ZoneList<Expression*>* is_spec_object_args =
2869 new (zone()) ZoneList<Expression*>(1, zone());
2870 is_spec_object_args->Add(factory()->NewVariableProxy(temp), zone());
2871 Expression* is_spec_object_call = factory()->NewCallRuntime(
2872 Runtime::kInlineIsSpecObject, is_spec_object_args, pos);
2873
2874 // %_IsSpecObject(temp) ? temp : throw_expression
2875 Expression* is_object_conditional = factory()->NewConditional(
2876 is_spec_object_call, factory()->NewVariableProxy(temp),
2877 throw_expression, pos);
2878
2879 // temp === undefined
2880 Expression* is_undefined = factory()->NewCompareOperation(
2881 Token::EQ_STRICT, assign,
2882 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), pos);
2883
2884 // is_undefined ? this : is_object_conditional
2885 return_value = factory()->NewConditional(
2886 is_undefined, ThisExpression(scope_, factory(), pos),
2887 is_object_conditional, pos);
2888 }
2889 }
2890 ExpectSemicolon(CHECK_OK);
2891
2892 if (is_generator()) {
2893 Expression* generator = factory()->NewVariableProxy(
2894 function_state_->generator_object_variable());
2895 Expression* yield = factory()->NewYield(
2896 generator, return_value, Yield::kFinal, loc.beg_pos);
2897 result = factory()->NewExpressionStatement(yield, loc.beg_pos);
2898 } else {
2899 result = factory()->NewReturnStatement(return_value, loc.beg_pos);
2900 }
2901
2902 Scope* decl_scope = scope_->DeclarationScope();
2903 if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) {
2904 ReportMessageAt(loc, MessageTemplate::kIllegalReturn);
2905 *ok = false;
2906 return NULL;
2907 }
2908 return result;
2909 }
2910
2911
2912 Statement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels,
2913 bool* ok) {
2914 // WithStatement ::
2915 // 'with' '(' Expression ')' Statement
2916
2917 Expect(Token::WITH, CHECK_OK);
2918 int pos = position();
2919
2920 if (is_strict(language_mode())) {
2921 ReportMessage(MessageTemplate::kStrictWith);
2922 *ok = false;
2923 return NULL;
2924 }
2925
2926 Expect(Token::LPAREN, CHECK_OK);
2927 Expression* expr = ParseExpression(true, CHECK_OK);
2928 Expect(Token::RPAREN, CHECK_OK);
2929
2930 scope_->DeclarationScope()->RecordWithStatement();
2931 Scope* with_scope = NewScope(scope_, WITH_SCOPE);
2932 Block* body;
2933 { BlockState block_state(&scope_, with_scope);
2934 with_scope->set_start_position(scanner()->peek_location().beg_pos);
2935
2936 // The body of the with statement must be enclosed in an additional
2937 // lexical scope in case the body is a FunctionDeclaration.
2938 body = factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition);
2939 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
2940 block_scope->set_start_position(scanner()->location().beg_pos);
2941 {
2942 BlockState block_state(&scope_, block_scope);
2943 Target target(&this->target_stack_, body);
2944 Statement* stmt = ParseSubStatement(labels, CHECK_OK);
2945 body->statements()->Add(stmt, zone());
2946 block_scope->set_end_position(scanner()->location().end_pos);
2947 block_scope = block_scope->FinalizeBlockScope();
2948 body->set_scope(block_scope);
2949 }
2950
2951 with_scope->set_end_position(scanner()->location().end_pos);
2952 }
2953 return factory()->NewWithStatement(with_scope, expr, body, pos);
2954 }
2955
2956
2957 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
2958 // CaseClause ::
2959 // 'case' Expression ':' StatementList
2960 // 'default' ':' StatementList
2961
2962 Expression* label = NULL; // NULL expression indicates default case
2963 if (peek() == Token::CASE) {
2964 Expect(Token::CASE, CHECK_OK);
2965 label = ParseExpression(true, CHECK_OK);
2966 } else {
2967 Expect(Token::DEFAULT, CHECK_OK);
2968 if (*default_seen_ptr) {
2969 ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch);
2970 *ok = false;
2971 return NULL;
2972 }
2973 *default_seen_ptr = true;
2974 }
2975 Expect(Token::COLON, CHECK_OK);
2976 int pos = position();
2977 ZoneList<Statement*>* statements =
2978 new(zone()) ZoneList<Statement*>(5, zone());
2979 Statement* stat = NULL;
2980 while (peek() != Token::CASE &&
2981 peek() != Token::DEFAULT &&
2982 peek() != Token::RBRACE) {
2983 stat = ParseStatementListItem(CHECK_OK);
2984 statements->Add(stat, zone());
2985 }
2986 if (is_strong(language_mode()) && stat != NULL && !stat->IsJump() &&
2987 peek() != Token::RBRACE) {
2988 ReportMessageAt(scanner()->location(),
2989 MessageTemplate::kStrongSwitchFallthrough);
2990 *ok = false;
2991 return NULL;
2992 }
2993 return factory()->NewCaseClause(label, statements, pos);
2994 }
2995
2996
2997 Statement* Parser::ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
2998 bool* ok) {
2999 // SwitchStatement ::
3000 // 'switch' '(' Expression ')' '{' CaseClause* '}'
3001 // In order to get the CaseClauses to execute in their own lexical scope,
3002 // but without requiring downstream code to have special scope handling
3003 // code for switch statements, desugar into blocks as follows:
3004 // { // To group the statements--harmless to evaluate Expression in scope
3005 // .tag_variable = Expression;
3006 // { // To give CaseClauses a scope
3007 // switch (.tag_variable) { CaseClause* }
3008 // }
3009 // }
3010
3011 Block* switch_block =
3012 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3013 int switch_pos = peek_position();
3014
3015 Expect(Token::SWITCH, CHECK_OK);
3016 Expect(Token::LPAREN, CHECK_OK);
3017 Expression* tag = ParseExpression(true, CHECK_OK);
3018 Expect(Token::RPAREN, CHECK_OK);
3019
3020 Variable* tag_variable =
3021 scope_->NewTemporary(ast_value_factory()->dot_switch_tag_string());
3022 Assignment* tag_assign = factory()->NewAssignment(
3023 Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag,
3024 tag->position());
3025 Statement* tag_statement =
3026 factory()->NewExpressionStatement(tag_assign, RelocInfo::kNoPosition);
3027 switch_block->statements()->Add(tag_statement, zone());
3028
3029 // make statement: undefined;
3030 // This is needed so the tag isn't returned as the value, in case the switch
3031 // statements don't have a value.
3032 switch_block->statements()->Add(
3033 factory()->NewExpressionStatement(
3034 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
3035 RelocInfo::kNoPosition),
3036 zone());
3037
3038 Block* cases_block =
3039 factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
3040 Scope* cases_scope = NewScope(scope_, BLOCK_SCOPE);
3041 cases_scope->SetNonlinear();
3042
3043 SwitchStatement* switch_statement =
3044 factory()->NewSwitchStatement(labels, switch_pos);
3045
3046 cases_scope->set_start_position(scanner()->location().beg_pos);
3047 {
3048 BlockState cases_block_state(&scope_, cases_scope);
3049 Target target(&this->target_stack_, switch_statement);
3050
3051 Expression* tag_read = factory()->NewVariableProxy(tag_variable);
3052
3053 bool default_seen = false;
3054 ZoneList<CaseClause*>* cases =
3055 new (zone()) ZoneList<CaseClause*>(4, zone());
3056 Expect(Token::LBRACE, CHECK_OK);
3057 while (peek() != Token::RBRACE) {
3058 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
3059 cases->Add(clause, zone());
3060 }
3061 switch_statement->Initialize(tag_read, cases);
3062 cases_block->statements()->Add(switch_statement, zone());
3063 }
3064 Expect(Token::RBRACE, CHECK_OK);
3065
3066 cases_scope->set_end_position(scanner()->location().end_pos);
3067 cases_scope = cases_scope->FinalizeBlockScope();
3068 cases_block->set_scope(cases_scope);
3069
3070 switch_block->statements()->Add(cases_block, zone());
3071
3072 return switch_block;
3073 }
3074
3075
3076 Statement* Parser::ParseThrowStatement(bool* ok) {
3077 // ThrowStatement ::
3078 // 'throw' Expression ';'
3079
3080 Expect(Token::THROW, CHECK_OK);
3081 int pos = position();
3082 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
3083 ReportMessage(MessageTemplate::kNewlineAfterThrow);
3084 *ok = false;
3085 return NULL;
3086 }
3087 Expression* exception = ParseExpression(true, CHECK_OK);
3088 ExpectSemicolon(CHECK_OK);
3089
3090 return factory()->NewExpressionStatement(
3091 factory()->NewThrow(exception, pos), pos);
3092 }
3093
3094
3095 TryStatement* Parser::ParseTryStatement(bool* ok) {
3096 // TryStatement ::
3097 // 'try' Block Catch
3098 // 'try' Block Finally
3099 // 'try' Block Catch Finally
3100 //
3101 // Catch ::
3102 // 'catch' '(' Identifier ')' Block
3103 //
3104 // Finally ::
3105 // 'finally' Block
3106
3107 Expect(Token::TRY, CHECK_OK);
3108 int pos = position();
3109
3110 Block* try_block = ParseBlock(NULL, CHECK_OK);
3111
3112 Token::Value tok = peek();
3113 if (tok != Token::CATCH && tok != Token::FINALLY) {
3114 ReportMessage(MessageTemplate::kNoCatchOrFinally);
3115 *ok = false;
3116 return NULL;
3117 }
3118
3119 Scope* catch_scope = NULL;
3120 Variable* catch_variable = NULL;
3121 Block* catch_block = NULL;
3122 if (tok == Token::CATCH) {
3123 Consume(Token::CATCH);
3124
3125 Expect(Token::LPAREN, CHECK_OK);
3126 catch_scope = NewScope(scope_, CATCH_SCOPE);
3127 catch_scope->set_start_position(scanner()->location().beg_pos);
3128
3129 ExpressionClassifier pattern_classifier;
3130 Expression* pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
3131 ValidateBindingPattern(&pattern_classifier, CHECK_OK);
3132
3133 const AstRawString* name = ast_value_factory()->dot_catch_string();
3134 bool is_simple = pattern->IsVariableProxy();
3135 if (is_simple) {
3136 auto proxy = pattern->AsVariableProxy();
3137 scope_->RemoveUnresolved(proxy);
3138 name = proxy->raw_name();
3139 }
3140
3141 catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized,
3142 Variable::NORMAL);
3143
3144 Expect(Token::RPAREN, CHECK_OK);
3145
3146 {
3147 BlockState block_state(&scope_, catch_scope);
3148
3149 // TODO(adamk): Make a version of ParseBlock that takes a scope and
3150 // a block.
3151 catch_block =
3152 factory()->NewBlock(nullptr, 16, false, RelocInfo::kNoPosition);
3153 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
3154
3155 block_scope->set_start_position(scanner()->location().beg_pos);
3156 {
3157 BlockState block_state(&scope_, block_scope);
3158 Target target(&this->target_stack_, catch_block);
3159
3160 if (!is_simple) {
3161 DeclarationDescriptor descriptor;
3162 descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
3163 descriptor.parser = this;
3164 descriptor.declaration_scope = scope_;
3165 descriptor.scope = scope_;
3166 descriptor.hoist_scope = nullptr;
3167 descriptor.mode = LET;
3168 descriptor.is_const = false;
3169 descriptor.needs_init = true;
3170 descriptor.declaration_pos = pattern->position();
3171 descriptor.initialization_pos = pattern->position();
3172
3173 DeclarationParsingResult::Declaration decl(
3174 pattern, pattern->position(),
3175 factory()->NewVariableProxy(catch_variable));
3176
3177 PatternRewriter::DeclareAndInitializeVariables(
3178 catch_block, &descriptor, &decl, nullptr, CHECK_OK);
3179 }
3180
3181 Expect(Token::LBRACE, CHECK_OK);
3182 while (peek() != Token::RBRACE) {
3183 Statement* stat = ParseStatementListItem(CHECK_OK);
3184 if (stat && !stat->IsEmpty()) {
3185 catch_block->statements()->Add(stat, zone());
3186 }
3187 }
3188 Consume(Token::RBRACE);
3189 }
3190 block_scope->set_end_position(scanner()->location().end_pos);
3191 block_scope = block_scope->FinalizeBlockScope();
3192 catch_block->set_scope(block_scope);
3193 }
3194
3195 catch_scope->set_end_position(scanner()->location().end_pos);
3196 tok = peek();
3197 }
3198
3199 Block* finally_block = NULL;
3200 DCHECK(tok == Token::FINALLY || catch_block != NULL);
3201 if (tok == Token::FINALLY) {
3202 Consume(Token::FINALLY);
3203 finally_block = ParseBlock(NULL, CHECK_OK);
3204 }
3205
3206 // Simplify the AST nodes by converting:
3207 // 'try B0 catch B1 finally B2'
3208 // to:
3209 // 'try { try B0 catch B1 } finally B2'
3210
3211 if (catch_block != NULL && finally_block != NULL) {
3212 // If we have both, create an inner try/catch.
3213 DCHECK(catch_scope != NULL && catch_variable != NULL);
3214 TryCatchStatement* statement =
3215 factory()->NewTryCatchStatement(try_block, catch_scope, catch_variable,
3216 catch_block, RelocInfo::kNoPosition);
3217 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
3218 try_block->statements()->Add(statement, zone());
3219 catch_block = NULL; // Clear to indicate it's been handled.
3220 }
3221
3222 TryStatement* result = NULL;
3223 if (catch_block != NULL) {
3224 DCHECK(finally_block == NULL);
3225 DCHECK(catch_scope != NULL && catch_variable != NULL);
3226 result = factory()->NewTryCatchStatement(try_block, catch_scope,
3227 catch_variable, catch_block, pos);
3228 } else {
3229 DCHECK(finally_block != NULL);
3230 result = factory()->NewTryFinallyStatement(try_block, finally_block, pos);
3231 }
3232
3233 return result;
3234 }
3235
3236
3237 DoWhileStatement* Parser::ParseDoWhileStatement(
3238 ZoneList<const AstRawString*>* labels, bool* ok) {
3239 // DoStatement ::
3240 // 'do' Statement 'while' '(' Expression ')' ';'
3241
3242 DoWhileStatement* loop =
3243 factory()->NewDoWhileStatement(labels, peek_position());
3244 Target target(&this->target_stack_, loop);
3245
3246 Expect(Token::DO, CHECK_OK);
3247 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3248 Expect(Token::WHILE, CHECK_OK);
3249 Expect(Token::LPAREN, CHECK_OK);
3250
3251 Expression* cond = ParseExpression(true, CHECK_OK);
3252 Expect(Token::RPAREN, CHECK_OK);
3253
3254 // Allow do-statements to be terminated with and without
3255 // semi-colons. This allows code such as 'do;while(0)return' to
3256 // parse, which would not be the case if we had used the
3257 // ExpectSemicolon() functionality here.
3258 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
3259
3260 if (loop != NULL) loop->Initialize(cond, body);
3261 return loop;
3262 }
3263
3264
3265 WhileStatement* Parser::ParseWhileStatement(
3266 ZoneList<const AstRawString*>* labels, bool* ok) {
3267 // WhileStatement ::
3268 // 'while' '(' Expression ')' Statement
3269
3270 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position());
3271 Target target(&this->target_stack_, loop);
3272
3273 Expect(Token::WHILE, CHECK_OK);
3274 Expect(Token::LPAREN, CHECK_OK);
3275 Expression* cond = ParseExpression(true, CHECK_OK);
3276 Expect(Token::RPAREN, CHECK_OK);
3277 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3278
3279 if (loop != NULL) loop->Initialize(cond, body);
3280 return loop;
3281 }
3282
3283
3284 // !%_IsSpecObject(result = iterator.next()) &&
3285 // %ThrowIteratorResultNotAnObject(result)
3286 Expression* Parser::BuildIteratorNextResult(Expression* iterator,
3287 Variable* result, int pos) {
3288 Expression* next_literal = factory()->NewStringLiteral(
3289 ast_value_factory()->next_string(), RelocInfo::kNoPosition);
3290 Expression* next_property =
3291 factory()->NewProperty(iterator, next_literal, RelocInfo::kNoPosition);
3292 ZoneList<Expression*>* next_arguments =
3293 new (zone()) ZoneList<Expression*>(0, zone());
3294 Expression* next_call =
3295 factory()->NewCall(next_property, next_arguments, pos);
3296 Expression* result_proxy = factory()->NewVariableProxy(result);
3297 Expression* left =
3298 factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos);
3299
3300 // %_IsSpecObject(...)
3301 ZoneList<Expression*>* is_spec_object_args =
3302 new (zone()) ZoneList<Expression*>(1, zone());
3303 is_spec_object_args->Add(left, zone());
3304 Expression* is_spec_object_call = factory()->NewCallRuntime(
3305 Runtime::kInlineIsSpecObject, is_spec_object_args, pos);
3306
3307 // %ThrowIteratorResultNotAnObject(result)
3308 Expression* result_proxy_again = factory()->NewVariableProxy(result);
3309 ZoneList<Expression*>* throw_arguments =
3310 new (zone()) ZoneList<Expression*>(1, zone());
3311 throw_arguments->Add(result_proxy_again, zone());
3312 Expression* throw_call = factory()->NewCallRuntime(
3313 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos);
3314
3315 return factory()->NewBinaryOperation(
3316 Token::AND,
3317 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos),
3318 throw_call, pos);
3319 }
3320
3321
3322 void Parser::InitializeForEachStatement(ForEachStatement* stmt,
3323 Expression* each,
3324 Expression* subject,
3325 Statement* body) {
3326 ForOfStatement* for_of = stmt->AsForOfStatement();
3327
3328 if (for_of != NULL) {
3329 Variable* iterator = scope_->NewTemporary(
3330 ast_value_factory()->dot_iterator_string());
3331 Variable* result = scope_->NewTemporary(
3332 ast_value_factory()->dot_result_string());
3333
3334 Expression* assign_iterator;
3335 Expression* next_result;
3336 Expression* result_done;
3337 Expression* assign_each;
3338
3339 // iterator = subject[Symbol.iterator]()
3340 assign_iterator = factory()->NewAssignment(
3341 Token::ASSIGN, factory()->NewVariableProxy(iterator),
3342 GetIterator(subject, factory()), subject->position());
3343
3344 // !%_IsSpecObject(result = iterator.next()) &&
3345 // %ThrowIteratorResultNotAnObject(result)
3346 {
3347 // result = iterator.next()
3348 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
3349 next_result =
3350 BuildIteratorNextResult(iterator_proxy, result, subject->position());
3351 }
3352
3353 // result.done
3354 {
3355 Expression* done_literal = factory()->NewStringLiteral(
3356 ast_value_factory()->done_string(), RelocInfo::kNoPosition);
3357 Expression* result_proxy = factory()->NewVariableProxy(result);
3358 result_done = factory()->NewProperty(
3359 result_proxy, done_literal, RelocInfo::kNoPosition);
3360 }
3361
3362 // each = result.value
3363 {
3364 Expression* value_literal = factory()->NewStringLiteral(
3365 ast_value_factory()->value_string(), RelocInfo::kNoPosition);
3366 Expression* result_proxy = factory()->NewVariableProxy(result);
3367 Expression* result_value = factory()->NewProperty(
3368 result_proxy, value_literal, RelocInfo::kNoPosition);
3369 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value,
3370 RelocInfo::kNoPosition);
3371 }
3372
3373 for_of->Initialize(each, subject, body,
3374 assign_iterator,
3375 next_result,
3376 result_done,
3377 assign_each);
3378 } else {
3379 stmt->Initialize(each, subject, body);
3380 }
3381 }
3382
3383
3384 Statement* Parser::DesugarLexicalBindingsInForStatement(
3385 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names,
3386 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
3387 Statement* body, bool* ok) {
3388 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
3389 // copied into a new environment. Moreover, the "next" statement must be
3390 // evaluated not in the environment of the just completed iteration but in
3391 // that of the upcoming one. We achieve this with the following desugaring.
3392 // Extra care is needed to preserve the completion value of the original loop.
3393 //
3394 // We are given a for statement of the form
3395 //
3396 // labels: for (let/const x = i; cond; next) body
3397 //
3398 // and rewrite it as follows. Here we write {{ ... }} for init-blocks, ie.,
3399 // blocks whose ignore_completion_value_ flag is set.
3400 //
3401 // {
3402 // let/const x = i;
3403 // temp_x = x;
3404 // first = 1;
3405 // undefined;
3406 // outer: for (;;) {
3407 // let/const x = temp_x;
3408 // {{ if (first == 1) {
3409 // first = 0;
3410 // } else {
3411 // next;
3412 // }
3413 // flag = 1;
3414 // if (!cond) break;
3415 // }}
3416 // labels: for (; flag == 1; flag = 0, temp_x = x) {
3417 // body
3418 // }
3419 // {{ if (flag == 1) // Body used break.
3420 // break;
3421 // }}
3422 // }
3423 // }
3424
3425 DCHECK(names->length() > 0);
3426 Scope* for_scope = scope_;
3427 ZoneList<Variable*> temps(names->length(), zone());
3428
3429 Block* outer_block = factory()->NewBlock(NULL, names->length() + 4, false,
3430 RelocInfo::kNoPosition);
3431
3432 // Add statement: let/const x = i.
3433 outer_block->statements()->Add(init, zone());
3434
3435 const AstRawString* temp_name = ast_value_factory()->dot_for_string();
3436
3437 // For each lexical variable x:
3438 // make statement: temp_x = x.
3439 for (int i = 0; i < names->length(); i++) {
3440 VariableProxy* proxy = NewUnresolved(names->at(i), LET);
3441 Variable* temp = scope_->NewTemporary(temp_name);
3442 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
3443 Assignment* assignment = factory()->NewAssignment(
3444 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3445 Statement* assignment_statement = factory()->NewExpressionStatement(
3446 assignment, RelocInfo::kNoPosition);
3447 outer_block->statements()->Add(assignment_statement, zone());
3448 temps.Add(temp, zone());
3449 }
3450
3451 Variable* first = NULL;
3452 // Make statement: first = 1.
3453 if (next) {
3454 first = scope_->NewTemporary(temp_name);
3455 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3456 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3457 Assignment* assignment = factory()->NewAssignment(
3458 Token::ASSIGN, first_proxy, const1, RelocInfo::kNoPosition);
3459 Statement* assignment_statement =
3460 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3461 outer_block->statements()->Add(assignment_statement, zone());
3462 }
3463
3464 // make statement: undefined;
3465 outer_block->statements()->Add(
3466 factory()->NewExpressionStatement(
3467 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
3468 RelocInfo::kNoPosition),
3469 zone());
3470
3471 // Make statement: outer: for (;;)
3472 // Note that we don't actually create the label, or set this loop up as an
3473 // explicit break target, instead handing it directly to those nodes that
3474 // need to know about it. This should be safe because we don't run any code
3475 // in this function that looks up break targets.
3476 ForStatement* outer_loop =
3477 factory()->NewForStatement(NULL, RelocInfo::kNoPosition);
3478 outer_block->statements()->Add(outer_loop, zone());
3479
3480 outer_block->set_scope(for_scope);
3481 scope_ = inner_scope;
3482
3483 Block* inner_block =
3484 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3485 Block* ignore_completion_block = factory()->NewBlock(
3486 NULL, names->length() + 3, true, RelocInfo::kNoPosition);
3487 ZoneList<Variable*> inner_vars(names->length(), zone());
3488 // For each let variable x:
3489 // make statement: let/const x = temp_x.
3490 VariableMode mode = is_const ? CONST : LET;
3491 for (int i = 0; i < names->length(); i++) {
3492 VariableProxy* proxy = NewUnresolved(names->at(i), mode);
3493 Declaration* declaration = factory()->NewVariableDeclaration(
3494 proxy, mode, scope_, RelocInfo::kNoPosition);
3495 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
3496 inner_vars.Add(declaration->proxy()->var(), zone());
3497 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3498 Assignment* assignment = factory()->NewAssignment(
3499 Token::INIT, proxy, temp_proxy, RelocInfo::kNoPosition);
3500 Statement* assignment_statement =
3501 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3502 DCHECK(init->position() != RelocInfo::kNoPosition);
3503 proxy->var()->set_initializer_position(init->position());
3504 ignore_completion_block->statements()->Add(assignment_statement, zone());
3505 }
3506
3507 // Make statement: if (first == 1) { first = 0; } else { next; }
3508 if (next) {
3509 DCHECK(first);
3510 Expression* compare = NULL;
3511 // Make compare expression: first == 1.
3512 {
3513 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3514 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3515 compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
3516 RelocInfo::kNoPosition);
3517 }
3518 Statement* clear_first = NULL;
3519 // Make statement: first = 0.
3520 {
3521 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3522 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3523 Assignment* assignment = factory()->NewAssignment(
3524 Token::ASSIGN, first_proxy, const0, RelocInfo::kNoPosition);
3525 clear_first =
3526 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3527 }
3528 Statement* clear_first_or_next = factory()->NewIfStatement(
3529 compare, clear_first, next, RelocInfo::kNoPosition);
3530 ignore_completion_block->statements()->Add(clear_first_or_next, zone());
3531 }
3532
3533 Variable* flag = scope_->NewTemporary(temp_name);
3534 // Make statement: flag = 1.
3535 {
3536 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3537 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3538 Assignment* assignment = factory()->NewAssignment(
3539 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
3540 Statement* assignment_statement =
3541 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3542 ignore_completion_block->statements()->Add(assignment_statement, zone());
3543 }
3544
3545 // Make statement: if (!cond) break.
3546 if (cond) {
3547 Statement* stop =
3548 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3549 Statement* noop = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
3550 ignore_completion_block->statements()->Add(
3551 factory()->NewIfStatement(cond, noop, stop, cond->position()), zone());
3552 }
3553
3554 inner_block->statements()->Add(ignore_completion_block, zone());
3555 // Make cond expression for main loop: flag == 1.
3556 Expression* flag_cond = NULL;
3557 {
3558 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3559 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3560 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
3561 RelocInfo::kNoPosition);
3562 }
3563
3564 // Create chain of expressions "flag = 0, temp_x = x, ..."
3565 Statement* compound_next_statement = NULL;
3566 {
3567 Expression* compound_next = NULL;
3568 // Make expression: flag = 0.
3569 {
3570 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3571 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3572 compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
3573 const0, RelocInfo::kNoPosition);
3574 }
3575
3576 // Make the comma-separated list of temp_x = x assignments.
3577 int inner_var_proxy_pos = scanner()->location().beg_pos;
3578 for (int i = 0; i < names->length(); i++) {
3579 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3580 VariableProxy* proxy =
3581 factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos);
3582 Assignment* assignment = factory()->NewAssignment(
3583 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3584 compound_next = factory()->NewBinaryOperation(
3585 Token::COMMA, compound_next, assignment, RelocInfo::kNoPosition);
3586 }
3587
3588 compound_next_statement = factory()->NewExpressionStatement(
3589 compound_next, RelocInfo::kNoPosition);
3590 }
3591
3592 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
3593 // Note that we re-use the original loop node, which retains its labels
3594 // and ensures that any break or continue statements in body point to
3595 // the right place.
3596 loop->Initialize(NULL, flag_cond, compound_next_statement, body);
3597 inner_block->statements()->Add(loop, zone());
3598
3599 // Make statement: {{if (flag == 1) break;}}
3600 {
3601 Expression* compare = NULL;
3602 // Make compare expresion: flag == 1.
3603 {
3604 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3605 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3606 compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
3607 RelocInfo::kNoPosition);
3608 }
3609 Statement* stop =
3610 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3611 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
3612 Statement* if_flag_break =
3613 factory()->NewIfStatement(compare, stop, empty, RelocInfo::kNoPosition);
3614 Block* ignore_completion_block =
3615 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
3616 ignore_completion_block->statements()->Add(if_flag_break, zone());
3617 inner_block->statements()->Add(ignore_completion_block, zone());
3618 }
3619
3620 inner_scope->set_end_position(scanner()->location().end_pos);
3621 inner_block->set_scope(inner_scope);
3622 scope_ = for_scope;
3623
3624 outer_loop->Initialize(NULL, NULL, NULL, inner_block);
3625 return outer_block;
3626 }
3627
3628
3629 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
3630 bool* ok) {
3631 // ForStatement ::
3632 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
3633
3634 int stmt_pos = peek_position();
3635 bool is_const = false;
3636 Statement* init = NULL;
3637 ZoneList<const AstRawString*> lexical_bindings(1, zone());
3638
3639 // Create an in-between scope for let-bound iteration variables.
3640 Scope* saved_scope = scope_;
3641 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
3642 scope_ = for_scope;
3643 Expect(Token::FOR, CHECK_OK);
3644 Expect(Token::LPAREN, CHECK_OK);
3645 for_scope->set_start_position(scanner()->location().beg_pos);
3646 bool is_let_identifier_expression = false;
3647 DeclarationParsingResult parsing_result;
3648 if (peek() != Token::SEMICOLON) {
3649 if (peek() == Token::VAR || (peek() == Token::CONST && allow_const()) ||
3650 (peek() == Token::LET && IsNextLetKeyword())) {
3651 ParseVariableDeclarations(kForStatement, &parsing_result, CHECK_OK);
3652 is_const = parsing_result.descriptor.mode == CONST;
3653
3654 int num_decl = parsing_result.declarations.length();
3655 bool accept_IN = num_decl >= 1;
3656 ForEachStatement::VisitMode mode;
3657 int each_beg_pos = scanner()->location().beg_pos;
3658 int each_end_pos = scanner()->location().end_pos;
3659
3660 if (accept_IN && CheckInOrOf(&mode, ok)) {
3661 if (!*ok) return nullptr;
3662 if (num_decl != 1) {
3663 const char* loop_type =
3664 mode == ForEachStatement::ITERATE ? "for-of" : "for-in";
3665 ParserTraits::ReportMessageAt(
3666 parsing_result.bindings_loc,
3667 MessageTemplate::kForInOfLoopMultiBindings, loop_type);
3668 *ok = false;
3669 return nullptr;
3670 }
3671 DeclarationParsingResult::Declaration& decl =
3672 parsing_result.declarations[0];
3673 if (parsing_result.first_initializer_loc.IsValid() &&
3674 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE ||
3675 IsLexicalVariableMode(parsing_result.descriptor.mode) ||
3676 !decl.pattern->IsVariableProxy())) {
3677 if (mode == ForEachStatement::ITERATE) {
3678 ReportMessageAt(parsing_result.first_initializer_loc,
3679 MessageTemplate::kForOfLoopInitializer);
3680 } else {
3681 // TODO(caitp): This should be an error in sloppy mode too.
3682 ReportMessageAt(parsing_result.first_initializer_loc,
3683 MessageTemplate::kForInLoopInitializer);
3684 }
3685 *ok = false;
3686 return nullptr;
3687 }
3688
3689 Block* init_block = nullptr;
3690
3691 // special case for legacy for (var/const x =.... in)
3692 if (!IsLexicalVariableMode(parsing_result.descriptor.mode) &&
3693 decl.pattern->IsVariableProxy() && decl.initializer != nullptr) {
3694 const AstRawString* name =
3695 decl.pattern->AsVariableProxy()->raw_name();
3696 VariableProxy* single_var = scope_->NewUnresolved(
3697 factory(), name, Variable::NORMAL, each_beg_pos, each_end_pos);
3698 init_block = factory()->NewBlock(
3699 nullptr, 2, true, parsing_result.descriptor.declaration_pos);
3700 init_block->statements()->Add(
3701 factory()->NewExpressionStatement(
3702 factory()->NewAssignment(Token::ASSIGN, single_var,
3703 decl.initializer,
3704 RelocInfo::kNoPosition),
3705 RelocInfo::kNoPosition),
3706 zone());
3707 }
3708
3709 // Rewrite a for-in/of statement of the form
3710 //
3711 // for (let/const/var x in/of e) b
3712 //
3713 // into
3714 //
3715 // {
3716 // <let x' be a temporary variable>
3717 // for (x' in/of e) {
3718 // let/const/var x;
3719 // x = x';
3720 // b;
3721 // }
3722 // let x; // for TDZ
3723 // }
3724
3725 Variable* temp = scope_->NewTemporary(
3726 ast_value_factory()->dot_for_string());
3727 ForEachStatement* loop =
3728 factory()->NewForEachStatement(mode, labels, stmt_pos);
3729 Target target(&this->target_stack_, loop);
3730
3731 Expression* enumerable = ParseExpression(true, CHECK_OK);
3732
3733 Expect(Token::RPAREN, CHECK_OK);
3734
3735 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE);
3736 body_scope->set_start_position(scanner()->location().beg_pos);
3737 scope_ = body_scope;
3738
3739 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3740
3741 Block* body_block =
3742 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3743
3744 auto each_initialization_block =
3745 factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition);
3746 {
3747 auto descriptor = parsing_result.descriptor;
3748 descriptor.declaration_pos = RelocInfo::kNoPosition;
3749 descriptor.initialization_pos = RelocInfo::kNoPosition;
3750 decl.initializer = factory()->NewVariableProxy(temp);
3751
3752 PatternRewriter::DeclareAndInitializeVariables(
3753 each_initialization_block, &descriptor, &decl,
3754 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings
3755 : nullptr,
3756 CHECK_OK);
3757 }
3758
3759 body_block->statements()->Add(each_initialization_block, zone());
3760 body_block->statements()->Add(body, zone());
3761 VariableProxy* temp_proxy =
3762 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
3763 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block);
3764 scope_ = for_scope;
3765 body_scope->set_end_position(scanner()->location().end_pos);
3766 body_scope = body_scope->FinalizeBlockScope();
3767 if (body_scope != nullptr) {
3768 body_block->set_scope(body_scope);
3769 }
3770
3771 // Create a TDZ for any lexically-bound names.
3772 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) {
3773 DCHECK_NULL(init_block);
3774
3775 init_block =
3776 factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition);
3777
3778 for (int i = 0; i < lexical_bindings.length(); ++i) {
3779 // TODO(adamk): This needs to be some sort of special
3780 // INTERNAL variable that's invisible to the debugger
3781 // but visible to everything else.
3782 VariableProxy* tdz_proxy = NewUnresolved(lexical_bindings[i], LET);
3783 Declaration* tdz_decl = factory()->NewVariableDeclaration(
3784 tdz_proxy, LET, scope_, RelocInfo::kNoPosition);
3785 Variable* tdz_var = Declare(tdz_decl, DeclarationDescriptor::NORMAL,
3786 true, CHECK_OK);
3787 tdz_var->set_initializer_position(position());
3788 }
3789 }
3790
3791 scope_ = saved_scope;
3792 for_scope->set_end_position(scanner()->location().end_pos);
3793 for_scope = for_scope->FinalizeBlockScope();
3794 // Parsed for-in loop w/ variable declarations.
3795 if (init_block != nullptr) {
3796 init_block->statements()->Add(loop, zone());
3797 if (for_scope != nullptr) {
3798 init_block->set_scope(for_scope);
3799 }
3800 return init_block;
3801 } else {
3802 DCHECK_NULL(for_scope);
3803 return loop;
3804 }
3805 } else {
3806 init = parsing_result.BuildInitializationBlock(
3807 IsLexicalVariableMode(parsing_result.descriptor.mode)
3808 ? &lexical_bindings
3809 : nullptr,
3810 CHECK_OK);
3811 }
3812 } else {
3813 int lhs_beg_pos = peek_position();
3814 Expression* expression = ParseExpression(false, CHECK_OK);
3815 int lhs_end_pos = scanner()->location().end_pos;
3816 ForEachStatement::VisitMode mode;
3817 is_let_identifier_expression =
3818 expression->IsVariableProxy() &&
3819 expression->AsVariableProxy()->raw_name() ==
3820 ast_value_factory()->let_string();
3821
3822 if (CheckInOrOf(&mode, ok)) {
3823 if (!*ok) return nullptr;
3824 expression = this->CheckAndRewriteReferenceExpression(
3825 expression, lhs_beg_pos, lhs_end_pos,
3826 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK);
3827
3828 ForEachStatement* loop =
3829 factory()->NewForEachStatement(mode, labels, stmt_pos);
3830 Target target(&this->target_stack_, loop);
3831
3832 Expression* enumerable = ParseExpression(true, CHECK_OK);
3833 Expect(Token::RPAREN, CHECK_OK);
3834
3835 // Make a block around the statement in case a lexical binding
3836 // is introduced, e.g. by a FunctionDeclaration.
3837 // This block must not use for_scope as its scope because if a
3838 // lexical binding is introduced which overlaps with the for-in/of,
3839 // expressions in head of the loop should actually have variables
3840 // resolved in the outer scope.
3841 Scope* body_scope = NewScope(for_scope, BLOCK_SCOPE);
3842 scope_ = body_scope;
3843 Block* block =
3844 factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
3845 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3846 block->statements()->Add(body, zone());
3847 InitializeForEachStatement(loop, expression, enumerable, block);
3848 scope_ = saved_scope;
3849 body_scope->set_end_position(scanner()->location().end_pos);
3850 body_scope = body_scope->FinalizeBlockScope();
3851 if (body_scope != nullptr) {
3852 block->set_scope(body_scope);
3853 }
3854 for_scope->set_end_position(scanner()->location().end_pos);
3855 for_scope = for_scope->FinalizeBlockScope();
3856 DCHECK(for_scope == nullptr);
3857 // Parsed for-in loop.
3858 return loop;
3859
3860 } else {
3861 init = factory()->NewExpressionStatement(expression, lhs_beg_pos);
3862 }
3863 }
3864 }
3865
3866 // Standard 'for' loop
3867 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos);
3868 Target target(&this->target_stack_, loop);
3869
3870 // Parsed initializer at this point.
3871 // Detect attempts at 'let' declarations in sloppy mode.
3872 if (!allow_harmony_sloppy_let() && peek() == Token::IDENTIFIER &&
3873 is_sloppy(language_mode()) && is_let_identifier_expression) {
3874 ReportMessage(MessageTemplate::kSloppyLexical, NULL);
3875 *ok = false;
3876 return NULL;
3877 }
3878 Expect(Token::SEMICOLON, CHECK_OK);
3879
3880 // If there are let bindings, then condition and the next statement of the
3881 // for loop must be parsed in a new scope.
3882 Scope* inner_scope = NULL;
3883 if (lexical_bindings.length() > 0) {
3884 inner_scope = NewScope(for_scope, BLOCK_SCOPE);
3885 inner_scope->set_start_position(scanner()->location().beg_pos);
3886 scope_ = inner_scope;
3887 }
3888
3889 Expression* cond = NULL;
3890 if (peek() != Token::SEMICOLON) {
3891 cond = ParseExpression(true, CHECK_OK);
3892 }
3893 Expect(Token::SEMICOLON, CHECK_OK);
3894
3895 Statement* next = NULL;
3896 if (peek() != Token::RPAREN) {
3897 Expression* exp = ParseExpression(true, CHECK_OK);
3898 next = factory()->NewExpressionStatement(exp, exp->position());
3899 }
3900 Expect(Token::RPAREN, CHECK_OK);
3901
3902 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3903
3904 Statement* result = NULL;
3905 if (lexical_bindings.length() > 0) {
3906 scope_ = for_scope;
3907 result = DesugarLexicalBindingsInForStatement(
3908 inner_scope, is_const, &lexical_bindings, loop, init, cond,
3909 next, body, CHECK_OK);
3910 scope_ = saved_scope;
3911 for_scope->set_end_position(scanner()->location().end_pos);
3912 } else {
3913 scope_ = saved_scope;
3914 for_scope->set_end_position(scanner()->location().end_pos);
3915 for_scope = for_scope->FinalizeBlockScope();
3916 if (for_scope) {
3917 // Rewrite a for statement of the form
3918 // for (const x = i; c; n) b
3919 //
3920 // into
3921 //
3922 // {
3923 // const x = i;
3924 // for (; c; n) b
3925 // }
3926 //
3927 // or, desugar
3928 // for (; c; n) b
3929 // into
3930 // {
3931 // for (; c; n) b
3932 // }
3933 // just in case b introduces a lexical binding some other way, e.g., if b
3934 // is a FunctionDeclaration.
3935 Block* block =
3936 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3937 if (init != nullptr) {
3938 block->statements()->Add(init, zone());
3939 }
3940 block->statements()->Add(loop, zone());
3941 block->set_scope(for_scope);
3942 loop->Initialize(NULL, cond, next, body);
3943 result = block;
3944 } else {
3945 loop->Initialize(init, cond, next, body);
3946 result = loop;
3947 }
3948 }
3949 return result;
3950 }
3951
3952
3953 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
3954 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
3955 // contexts this is used as a statement which invokes the debugger as i a
3956 // break point is present.
3957 // DebuggerStatement ::
3958 // 'debugger' ';'
3959
3960 int pos = peek_position();
3961 Expect(Token::DEBUGGER, CHECK_OK);
3962 ExpectSemicolon(CHECK_OK);
3963 return factory()->NewDebuggerStatement(pos);
3964 }
3965
3966
3967 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
3968 if (expression->IsLiteral()) return true;
3969 MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3970 return lit != NULL && lit->is_simple();
3971 }
3972
3973
3974 Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate,
3975 Expression* expression) {
3976 Factory* factory = isolate->factory();
3977 DCHECK(IsCompileTimeValue(expression));
3978 Handle<FixedArray> result = factory->NewFixedArray(2, TENURED);
3979 ObjectLiteral* object_literal = expression->AsObjectLiteral();
3980 if (object_literal != NULL) {
3981 DCHECK(object_literal->is_simple());
3982 if (object_literal->fast_elements()) {
3983 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
3984 } else {
3985 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
3986 }
3987 result->set(kElementsSlot, *object_literal->constant_properties());
3988 } else {
3989 ArrayLiteral* array_literal = expression->AsArrayLiteral();
3990 DCHECK(array_literal != NULL && array_literal->is_simple());
3991 result->set(kLiteralTypeSlot, Smi::FromInt(ARRAY_LITERAL));
3992 result->set(kElementsSlot, *array_literal->constant_elements());
3993 }
3994 return result;
3995 }
3996
3997
3998 CompileTimeValue::LiteralType CompileTimeValue::GetLiteralType(
3999 Handle<FixedArray> value) {
4000 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot));
4001 return static_cast<LiteralType>(literal_type->value());
4002 }
4003
4004
4005 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
4006 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
4007 }
4008
4009
4010 void ParserTraits::ParseArrowFunctionFormalParameters(
4011 ParserFormalParameters* parameters, Expression* expr,
4012 const Scanner::Location& params_loc, bool* ok) {
4013 if (parameters->Arity() >= Code::kMaxArguments) {
4014 ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
4015 *ok = false;
4016 return;
4017 }
4018
4019 // ArrowFunctionFormals ::
4020 // Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail)
4021 // Tail
4022 // NonTailArrowFunctionFormals ::
4023 // Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy)
4024 // VariableProxy
4025 // Tail ::
4026 // VariableProxy
4027 // Spread(VariableProxy)
4028 //
4029 // As we need to visit the parameters in left-to-right order, we recurse on
4030 // the left-hand side of comma expressions.
4031 //
4032 if (expr->IsBinaryOperation()) {
4033 BinaryOperation* binop = expr->AsBinaryOperation();
4034 // The classifier has already run, so we know that the expression is a valid
4035 // arrow function formals production.
4036 DCHECK_EQ(binop->op(), Token::COMMA);
4037 Expression* left = binop->left();
4038 Expression* right = binop->right();
4039 ParseArrowFunctionFormalParameters(parameters, left, params_loc, ok);
4040 if (!*ok) return;
4041 // LHS of comma expression should be unparenthesized.
4042 expr = right;
4043 }
4044
4045 // Only the right-most expression may be a rest parameter.
4046 DCHECK(!parameters->has_rest);
4047
4048 bool is_rest = expr->IsSpread();
4049 if (is_rest) {
4050 expr = expr->AsSpread()->expression();
4051 parameters->has_rest = true;
4052 parameters->rest_array_literal_index =
4053 parser_->function_state_->NextMaterializedLiteralIndex();
4054 ++parameters->materialized_literals_count;
4055 }
4056 if (parameters->is_simple) {
4057 parameters->is_simple = !is_rest && expr->IsVariableProxy();
4058 }
4059
4060 Expression* initializer = nullptr;
4061 if (expr->IsVariableProxy()) {
4062 // When the formal parameter was originally seen, it was parsed as a
4063 // VariableProxy and recorded as unresolved in the scope. Here we undo that
4064 // parse-time side-effect for parameters that are single-names (not
4065 // patterns; for patterns that happens uniformly in
4066 // PatternRewriter::VisitVariableProxy).
4067 parser_->scope_->RemoveUnresolved(expr->AsVariableProxy());
4068 } else if (expr->IsAssignment()) {
4069 Assignment* assignment = expr->AsAssignment();
4070 DCHECK(parser_->allow_harmony_default_parameters());
4071 DCHECK(!assignment->is_compound());
4072 initializer = assignment->value();
4073 expr = assignment->target();
4074
4075 // TODO(adamk): Only call this if necessary.
4076 RewriteParameterInitializerScope(parser_->stack_limit(), initializer,
4077 parser_->scope_, parameters->scope);
4078 }
4079
4080 // TODO(adamk): params_loc.end_pos is not the correct initializer position,
4081 // but it should be conservative enough to trigger hole checks for variables
4082 // referenced in the initializer (if any).
4083 AddFormalParameter(parameters, expr, initializer, params_loc.end_pos,
4084 is_rest);
4085 }
4086
4087
4088 DoExpression* Parser::ParseDoExpression(bool* ok) {
4089 // AssignmentExpression ::
4090 // do '{' StatementList '}'
4091 int pos = peek_position();
4092
4093 Expect(Token::DO, CHECK_OK);
4094 Variable* result =
4095 scope_->NewTemporary(ast_value_factory()->dot_result_string());
4096 Block* block = ParseBlock(nullptr, CHECK_OK);
4097 DoExpression* expr = factory()->NewDoExpression(block, result, pos);
4098 if (!Rewriter::Rewrite(this, expr, ast_value_factory())) {
4099 *ok = false;
4100 return nullptr;
4101 }
4102 return expr;
4103 }
4104
4105
4106 void ParserTraits::ParseArrowFunctionFormalParameterList(
4107 ParserFormalParameters* parameters, Expression* expr,
4108 const Scanner::Location& params_loc,
4109 Scanner::Location* duplicate_loc, bool* ok) {
4110 if (expr->IsEmptyParentheses()) return;
4111
4112 ParseArrowFunctionFormalParameters(parameters, expr, params_loc, ok);
4113 if (!*ok) return;
4114
4115 ExpressionClassifier classifier;
4116 if (!parameters->is_simple) {
4117 classifier.RecordNonSimpleParameter();
4118 }
4119 for (int i = 0; i < parameters->Arity(); ++i) {
4120 auto parameter = parameters->at(i);
4121 DeclareFormalParameter(parameters->scope, parameter, &classifier);
4122 if (!duplicate_loc->IsValid()) {
4123 *duplicate_loc = classifier.duplicate_formal_parameter_error().location;
4124 }
4125 }
4126 DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters());
4127 }
4128
4129
4130 void ParserTraits::ReindexLiterals(const ParserFormalParameters& parameters) {
4131 if (parser_->function_state_->materialized_literal_count() > 0) {
4132 AstLiteralReindexer reindexer;
4133
4134 for (const auto p : parameters.params) {
4135 if (p.pattern != nullptr) reindexer.Reindex(p.pattern);
4136 if (p.initializer != nullptr) reindexer.Reindex(p.initializer);
4137 }
4138
4139 if (parameters.has_rest) {
4140 parameters.rest_array_literal_index = reindexer.NextIndex();
4141 }
4142
4143 DCHECK(reindexer.count() <=
4144 parser_->function_state_->materialized_literal_count());
4145 }
4146 }
4147
4148
4149 FunctionLiteral* Parser::ParseFunctionLiteral(
4150 const AstRawString* function_name, Scanner::Location function_name_location,
4151 FunctionNameValidity function_name_validity, FunctionKind kind,
4152 int function_token_pos, FunctionLiteral::FunctionType function_type,
4153 FunctionLiteral::ArityRestriction arity_restriction,
4154 LanguageMode language_mode, bool* ok) {
4155 // Function ::
4156 // '(' FormalParameterList? ')' '{' FunctionBody '}'
4157 //
4158 // Getter ::
4159 // '(' ')' '{' FunctionBody '}'
4160 //
4161 // Setter ::
4162 // '(' PropertySetParameterList ')' '{' FunctionBody '}'
4163
4164 int pos = function_token_pos == RelocInfo::kNoPosition
4165 ? peek_position() : function_token_pos;
4166
4167 bool is_generator = IsGeneratorFunction(kind);
4168
4169 // Anonymous functions were passed either the empty symbol or a null
4170 // handle as the function name. Remember if we were passed a non-empty
4171 // handle to decide whether to invoke function name inference.
4172 bool should_infer_name = function_name == NULL;
4173
4174 // We want a non-null handle as the function name.
4175 if (should_infer_name) {
4176 function_name = ast_value_factory()->empty_string();
4177 }
4178
4179 // Function declarations are function scoped in normal mode, so they are
4180 // hoisted. In harmony block scoping mode they are block scoped, so they
4181 // are not hoisted.
4182 //
4183 // One tricky case are function declarations in a local sloppy-mode eval:
4184 // their declaration is hoisted, but they still see the local scope. E.g.,
4185 //
4186 // function() {
4187 // var x = 0
4188 // try { throw 1 } catch (x) { eval("function g() { return x }") }
4189 // return g()
4190 // }
4191 //
4192 // needs to return 1. To distinguish such cases, we need to detect
4193 // (1) whether a function stems from a sloppy eval, and
4194 // (2) whether it actually hoists across the eval.
4195 // Unfortunately, we do not represent sloppy eval scopes, so we do not have
4196 // either information available directly, especially not when lazily compiling
4197 // a function like 'g'. We hence rely on the following invariants:
4198 // - (1) is the case iff the innermost scope of the deserialized scope chain
4199 // under which we compile is _not_ a declaration scope. This holds because
4200 // in all normal cases, function declarations are fully hoisted to a
4201 // declaration scope and compiled relative to that.
4202 // - (2) is the case iff the current declaration scope is still the original
4203 // one relative to the deserialized scope chain. Otherwise we must be
4204 // compiling a function in an inner declaration scope in the eval, e.g. a
4205 // nested function, and hoisting works normally relative to that.
4206 Scope* declaration_scope = scope_->DeclarationScope();
4207 Scope* original_declaration_scope = original_scope_->DeclarationScope();
4208 Scope* scope = function_type == FunctionLiteral::DECLARATION &&
4209 is_sloppy(language_mode) &&
4210 !allow_harmony_sloppy_function() &&
4211 (original_scope_ == original_declaration_scope ||
4212 declaration_scope != original_declaration_scope)
4213 ? NewScope(declaration_scope, FUNCTION_SCOPE, kind)
4214 : NewScope(scope_, FUNCTION_SCOPE, kind);
4215 SetLanguageMode(scope, language_mode);
4216 ZoneList<Statement*>* body = NULL;
4217 int arity = -1;
4218 int materialized_literal_count = -1;
4219 int expected_property_count = -1;
4220 DuplicateFinder duplicate_finder(scanner()->unicode_cache());
4221 ExpressionClassifier formals_classifier(&duplicate_finder);
4222 FunctionLiteral::EagerCompileHint eager_compile_hint =
4223 parenthesized_function_ ? FunctionLiteral::kShouldEagerCompile
4224 : FunctionLiteral::kShouldLazyCompile;
4225 bool should_be_used_once_hint = false;
4226 // Parse function.
4227 {
4228 AstNodeFactory function_factory(ast_value_factory());
4229 FunctionState function_state(&function_state_, &scope_, scope, kind,
4230 &function_factory);
4231 scope_->SetScopeName(function_name);
4232
4233 if (is_generator) {
4234 // For generators, allocating variables in contexts is currently a win
4235 // because it minimizes the work needed to suspend and resume an
4236 // activation.
4237 scope_->ForceContextAllocation();
4238
4239 // Calling a generator returns a generator object. That object is stored
4240 // in a temporary variable, a definition that is used by "yield"
4241 // expressions. This also marks the FunctionState as a generator.
4242 Variable* temp = scope_->NewTemporary(
4243 ast_value_factory()->dot_generator_object_string());
4244 function_state.set_generator_object_variable(temp);
4245 }
4246
4247 Expect(Token::LPAREN, CHECK_OK);
4248 int start_position = scanner()->location().beg_pos;
4249 scope_->set_start_position(start_position);
4250 ParserFormalParameters formals(scope);
4251 ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
4252 arity = formals.Arity();
4253 Expect(Token::RPAREN, CHECK_OK);
4254 int formals_end_position = scanner()->location().end_pos;
4255
4256 CheckArityRestrictions(arity, arity_restriction,
4257 formals.has_rest, start_position,
4258 formals_end_position, CHECK_OK);
4259 Expect(Token::LBRACE, CHECK_OK);
4260
4261 // Determine if the function can be parsed lazily. Lazy parsing is different
4262 // from lazy compilation; we need to parse more eagerly than we compile.
4263
4264 // We can only parse lazily if we also compile lazily. The heuristics for
4265 // lazy compilation are:
4266 // - It must not have been prohibited by the caller to Parse (some callers
4267 // need a full AST).
4268 // - The outer scope must allow lazy compilation of inner functions.
4269 // - The function mustn't be a function expression with an open parenthesis
4270 // before; we consider that a hint that the function will be called
4271 // immediately, and it would be a waste of time to make it lazily
4272 // compiled.
4273 // These are all things we can know at this point, without looking at the
4274 // function itself.
4275
4276 // In addition, we need to distinguish between these cases:
4277 // (function foo() {
4278 // bar = function() { return 1; }
4279 // })();
4280 // and
4281 // (function foo() {
4282 // var a = 1;
4283 // bar = function() { return a; }
4284 // })();
4285
4286 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
4287 // parenthesis before the function means that it will be called
4288 // immediately). The inner function *must* be parsed eagerly to resolve the
4289 // possible reference to the variable in foo's scope. However, it's possible
4290 // that it will be compiled lazily.
4291
4292 // To make this additional case work, both Parser and PreParser implement a
4293 // logic where only top-level functions will be parsed lazily.
4294 bool is_lazily_parsed = mode() == PARSE_LAZILY &&
4295 scope_->AllowsLazyParsing() &&
4296 !parenthesized_function_;
4297 parenthesized_function_ = false; // The bit was set for this function only.
4298
4299 // Eager or lazy parse?
4300 // If is_lazily_parsed, we'll parse lazy. If we can set a bookmark, we'll
4301 // pass it to SkipLazyFunctionBody, which may use it to abort lazy
4302 // parsing if it suspect that wasn't a good idea. If so, or if we didn't
4303 // try to lazy parse in the first place, we'll have to parse eagerly.
4304 Scanner::BookmarkScope bookmark(scanner());
4305 if (is_lazily_parsed) {
4306 Scanner::BookmarkScope* maybe_bookmark =
4307 bookmark.Set() ? &bookmark : nullptr;
4308 SkipLazyFunctionBody(&materialized_literal_count,
4309 &expected_property_count, /*CHECK_OK*/ ok,
4310 maybe_bookmark);
4311
4312 materialized_literal_count += formals.materialized_literals_count +
4313 function_state.materialized_literal_count();
4314
4315 if (bookmark.HasBeenReset()) {
4316 // Trigger eager (re-)parsing, just below this block.
4317 is_lazily_parsed = false;
4318
4319 // This is probably an initialization function. Inform the compiler it
4320 // should also eager-compile this function, and that we expect it to be
4321 // used once.
4322 eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
4323 should_be_used_once_hint = true;
4324 }
4325 }
4326 if (!is_lazily_parsed) {
4327 // Determine whether the function body can be discarded after parsing.
4328 // The preconditions are:
4329 // - Lazy compilation has to be enabled.
4330 // - Neither V8 natives nor native function declarations can be allowed,
4331 // since parsing one would retroactively force the function to be
4332 // eagerly compiled.
4333 // - The invoker of this parser can't depend on the AST being eagerly
4334 // built (either because the function is about to be compiled, or
4335 // because the AST is going to be inspected for some reason).
4336 // - Because of the above, we can't be attempting to parse a
4337 // FunctionExpression; even without enclosing parentheses it might be
4338 // immediately invoked.
4339 // - The function literal shouldn't be hinted to eagerly compile.
4340 bool use_temp_zone =
4341 FLAG_lazy && !allow_natives() && extension_ == NULL && allow_lazy() &&
4342 function_type == FunctionLiteral::DECLARATION &&
4343 eager_compile_hint != FunctionLiteral::kShouldEagerCompile;
4344 // Open a new BodyScope, which sets our AstNodeFactory to allocate in the
4345 // new temporary zone if the preconditions are satisfied, and ensures that
4346 // the previous zone is always restored after parsing the body.
4347 // For the purpose of scope analysis, some ZoneObjects allocated by the
4348 // factory must persist after the function body is thrown away and
4349 // temp_zone is deallocated. These objects are instead allocated in a
4350 // parser-persistent zone (see parser_zone_ in AstNodeFactory).
4351 {
4352 Zone temp_zone;
4353 AstNodeFactory::BodyScope inner(factory(), &temp_zone, use_temp_zone);
4354
4355 body = ParseEagerFunctionBody(function_name, pos, formals, kind,
4356 function_type, CHECK_OK);
4357 }
4358 materialized_literal_count = function_state.materialized_literal_count();
4359 expected_property_count = function_state.expected_property_count();
4360 if (use_temp_zone) {
4361 // If the preconditions are correct the function body should never be
4362 // accessed, but do this anyway for better behaviour if they're wrong.
4363 body = NULL;
4364 }
4365 }
4366
4367 // Parsing the body may change the language mode in our scope.
4368 language_mode = scope->language_mode();
4369
4370 if (is_strong(language_mode) && IsSubclassConstructor(kind)) {
4371 if (!function_state.super_location().IsValid()) {
4372 ReportMessageAt(function_name_location,
4373 MessageTemplate::kStrongSuperCallMissing,
4374 kReferenceError);
4375 *ok = false;
4376 return nullptr;
4377 }
4378 }
4379
4380 // Validate name and parameter names. We can do this only after parsing the
4381 // function, since the function can declare itself strict.
4382 CheckFunctionName(language_mode, function_name, function_name_validity,
4383 function_name_location, CHECK_OK);
4384 const bool allow_duplicate_parameters =
4385 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind);
4386 ValidateFormalParameters(&formals_classifier, language_mode,
4387 allow_duplicate_parameters, CHECK_OK);
4388
4389 if (is_strict(language_mode)) {
4390 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
4391 CHECK_OK);
4392 }
4393 if (is_sloppy(language_mode) && allow_harmony_sloppy_function()) {
4394 InsertSloppyBlockFunctionVarBindings(scope, CHECK_OK);
4395 }
4396 if (is_strict(language_mode) || allow_harmony_sloppy() ||
4397 allow_harmony_destructuring_bind()) {
4398 CheckConflictingVarDeclarations(scope, CHECK_OK);
4399 }
4400 }
4401
4402 bool has_duplicate_parameters =
4403 !formals_classifier.is_valid_formal_parameter_list_without_duplicates();
4404 FunctionLiteral::ParameterFlag duplicate_parameters =
4405 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
4406 : FunctionLiteral::kNoDuplicateParameters;
4407
4408 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
4409 function_name, ast_value_factory(), scope, body,
4410 materialized_literal_count, expected_property_count, arity,
4411 duplicate_parameters, function_type, FunctionLiteral::kIsFunction,
4412 eager_compile_hint, kind, pos);
4413 function_literal->set_function_token_position(function_token_pos);
4414 if (should_be_used_once_hint)
4415 function_literal->set_should_be_used_once_hint();
4416
4417 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
4418 return function_literal;
4419 }
4420
4421
4422 void Parser::SkipLazyFunctionBody(int* materialized_literal_count,
4423 int* expected_property_count, bool* ok,
4424 Scanner::BookmarkScope* bookmark) {
4425 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet());
4426 if (produce_cached_parse_data()) CHECK(log_);
4427
4428 int function_block_pos = position();
4429 if (consume_cached_parse_data() && !cached_parse_data_->rejected()) {
4430 // If we have cached data, we use it to skip parsing the function body. The
4431 // data contains the information we need to construct the lazy function.
4432 FunctionEntry entry =
4433 cached_parse_data_->GetFunctionEntry(function_block_pos);
4434 // Check that cached data is valid. If not, mark it as invalid (the embedder
4435 // handles it). Note that end position greater than end of stream is safe,
4436 // and hard to check.
4437 if (entry.is_valid() && entry.end_pos() > function_block_pos) {
4438 scanner()->SeekForward(entry.end_pos() - 1);
4439
4440 scope_->set_end_position(entry.end_pos());
4441 Expect(Token::RBRACE, ok);
4442 if (!*ok) {
4443 return;
4444 }
4445 total_preparse_skipped_ += scope_->end_position() - function_block_pos;
4446 *materialized_literal_count = entry.literal_count();
4447 *expected_property_count = entry.property_count();
4448 SetLanguageMode(scope_, entry.language_mode());
4449 if (entry.uses_super_property()) scope_->RecordSuperPropertyUsage();
4450 if (entry.calls_eval()) scope_->RecordEvalCall();
4451 return;
4452 }
4453 cached_parse_data_->Reject();
4454 }
4455 // With no cached data, we partially parse the function, without building an
4456 // AST. This gathers the data needed to build a lazy function.
4457 SingletonLogger logger;
4458 PreParser::PreParseResult result =
4459 ParseLazyFunctionBodyWithPreParser(&logger, bookmark);
4460 if (bookmark && bookmark->HasBeenReset()) {
4461 return; // Return immediately if pre-parser devided to abort parsing.
4462 }
4463 if (result == PreParser::kPreParseStackOverflow) {
4464 // Propagate stack overflow.
4465 set_stack_overflow();
4466 *ok = false;
4467 return;
4468 }
4469 if (logger.has_error()) {
4470 ParserTraits::ReportMessageAt(
4471 Scanner::Location(logger.start(), logger.end()), logger.message(),
4472 logger.argument_opt(), logger.error_type());
4473 *ok = false;
4474 return;
4475 }
4476 scope_->set_end_position(logger.end());
4477 Expect(Token::RBRACE, ok);
4478 if (!*ok) {
4479 return;
4480 }
4481 total_preparse_skipped_ += scope_->end_position() - function_block_pos;
4482 *materialized_literal_count = logger.literals();
4483 *expected_property_count = logger.properties();
4484 SetLanguageMode(scope_, logger.language_mode());
4485 if (logger.uses_super_property()) {
4486 scope_->RecordSuperPropertyUsage();
4487 }
4488 if (logger.calls_eval()) {
4489 scope_->RecordEvalCall();
4490 }
4491 if (produce_cached_parse_data()) {
4492 DCHECK(log_);
4493 // Position right after terminal '}'.
4494 int body_end = scanner()->location().end_pos;
4495 log_->LogFunction(function_block_pos, body_end, *materialized_literal_count,
4496 *expected_property_count, scope_->language_mode(),
4497 scope_->uses_super_property(), scope_->calls_eval());
4498 }
4499 }
4500
4501
4502 Statement* Parser::BuildAssertIsCoercible(Variable* var) {
4503 // if (var === null || var === undefined)
4504 // throw /* type error kNonCoercible) */;
4505
4506 Expression* condition = factory()->NewBinaryOperation(
4507 Token::OR, factory()->NewCompareOperation(
4508 Token::EQ_STRICT, factory()->NewVariableProxy(var),
4509 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
4510 RelocInfo::kNoPosition),
4511 factory()->NewCompareOperation(
4512 Token::EQ_STRICT, factory()->NewVariableProxy(var),
4513 factory()->NewNullLiteral(RelocInfo::kNoPosition),
4514 RelocInfo::kNoPosition),
4515 RelocInfo::kNoPosition);
4516 Expression* throw_type_error = this->NewThrowTypeError(
4517 MessageTemplate::kNonCoercible, ast_value_factory()->empty_string(),
4518 RelocInfo::kNoPosition);
4519 IfStatement* if_statement = factory()->NewIfStatement(
4520 condition, factory()->NewExpressionStatement(throw_type_error,
4521 RelocInfo::kNoPosition),
4522 factory()->NewEmptyStatement(RelocInfo::kNoPosition),
4523 RelocInfo::kNoPosition);
4524 return if_statement;
4525 }
4526
4527
4528 Block* Parser::BuildParameterInitializationBlock(
4529 const ParserFormalParameters& parameters, bool* ok) {
4530 DCHECK(!parameters.is_simple);
4531 DCHECK(scope_->is_function_scope());
4532 Block* init_block =
4533 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
4534 for (int i = 0; i < parameters.params.length(); ++i) {
4535 auto parameter = parameters.params[i];
4536 DeclarationDescriptor descriptor;
4537 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
4538 descriptor.parser = this;
4539 descriptor.declaration_scope = scope_;
4540 descriptor.scope = scope_;
4541 descriptor.hoist_scope = nullptr;
4542 descriptor.mode = LET;
4543 descriptor.is_const = false;
4544 descriptor.needs_init = true;
4545 descriptor.declaration_pos = parameter.pattern->position();
4546 // The position that will be used by the AssignmentExpression
4547 // which copies from the temp parameter to the pattern.
4548 //
4549 // TODO(adamk): Should this be RelocInfo::kNoPosition, since
4550 // it's just copying from a temp var to the real param var?
4551 descriptor.initialization_pos = parameter.pattern->position();
4552 // The initializer position which will end up in,
4553 // Variable::initializer_position(), used for hole check elimination.
4554 int initializer_position = parameter.pattern->position();
4555 Expression* initial_value =
4556 factory()->NewVariableProxy(parameters.scope->parameter(i));
4557 if (parameter.initializer != nullptr) {
4558 // IS_UNDEFINED($param) ? initializer : $param
4559 DCHECK(!parameter.is_rest);
4560 auto condition = factory()->NewCompareOperation(
4561 Token::EQ_STRICT,
4562 factory()->NewVariableProxy(parameters.scope->parameter(i)),
4563 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
4564 RelocInfo::kNoPosition);
4565 initial_value = factory()->NewConditional(
4566 condition, parameter.initializer, initial_value,
4567 RelocInfo::kNoPosition);
4568 descriptor.initialization_pos = parameter.initializer->position();
4569 initializer_position = parameter.initializer_end_position;
4570 } else if (parameter.is_rest) {
4571 // $rest = [];
4572 // for (var $argument_index = $rest_index;
4573 // $argument_index < %_ArgumentsLength();
4574 // ++$argument_index) {
4575 // %AppendElement($rest, %_Arguments($argument_index));
4576 // }
4577 // let <param> = $rest;
4578 DCHECK(parameter.pattern->IsVariableProxy());
4579 DCHECK_EQ(i, parameters.params.length() - 1);
4580
4581 Variable* temp_var = parameters.scope->parameter(i);
4582 auto empty_values = new (zone()) ZoneList<Expression*>(0, zone());
4583 auto empty_array = factory()->NewArrayLiteral(
4584 empty_values, parameters.rest_array_literal_index,
4585 is_strong(language_mode()), RelocInfo::kNoPosition);
4586
4587 auto init_array = factory()->NewAssignment(
4588 Token::INIT, factory()->NewVariableProxy(temp_var), empty_array,
4589 RelocInfo::kNoPosition);
4590
4591 auto loop = factory()->NewForStatement(NULL, RelocInfo::kNoPosition);
4592
4593 auto argument_index =
4594 parameters.scope->NewTemporary(ast_value_factory()->empty_string());
4595 auto init = factory()->NewExpressionStatement(
4596 factory()->NewAssignment(
4597 Token::INIT, factory()->NewVariableProxy(argument_index),
4598 factory()->NewSmiLiteral(i, RelocInfo::kNoPosition),
4599 RelocInfo::kNoPosition),
4600 RelocInfo::kNoPosition);
4601
4602 auto empty_arguments = new (zone()) ZoneList<Expression*>(0, zone());
4603
4604 // $arguments_index < arguments.length
4605 auto cond = factory()->NewCompareOperation(
4606 Token::LT, factory()->NewVariableProxy(argument_index),
4607 factory()->NewCallRuntime(Runtime::kInlineArgumentsLength,
4608 empty_arguments, RelocInfo::kNoPosition),
4609 RelocInfo::kNoPosition);
4610
4611 // ++argument_index
4612 auto next = factory()->NewExpressionStatement(
4613 factory()->NewCountOperation(
4614 Token::INC, true, factory()->NewVariableProxy(argument_index),
4615 RelocInfo::kNoPosition),
4616 RelocInfo::kNoPosition);
4617
4618 // %_Arguments($arguments_index)
4619 auto arguments_args = new (zone()) ZoneList<Expression*>(1, zone());
4620 arguments_args->Add(factory()->NewVariableProxy(argument_index), zone());
4621
4622 // %AppendElement($rest, %_Arguments($arguments_index))
4623 auto append_element_args = new (zone()) ZoneList<Expression*>(2, zone());
4624
4625 append_element_args->Add(factory()->NewVariableProxy(temp_var), zone());
4626 append_element_args->Add(
4627 factory()->NewCallRuntime(Runtime::kInlineArguments, arguments_args,
4628 RelocInfo::kNoPosition),
4629 zone());
4630
4631 auto body = factory()->NewExpressionStatement(
4632 factory()->NewCallRuntime(Runtime::kAppendElement,
4633 append_element_args,
4634 RelocInfo::kNoPosition),
4635 RelocInfo::kNoPosition);
4636
4637 loop->Initialize(init, cond, next, body);
4638
4639 init_block->statements()->Add(
4640 factory()->NewExpressionStatement(init_array, RelocInfo::kNoPosition),
4641 zone());
4642
4643 init_block->statements()->Add(loop, zone());
4644 }
4645
4646 Scope* param_scope = scope_;
4647 Block* param_block = init_block;
4648 if (!parameter.is_simple() && scope_->calls_sloppy_eval()) {
4649 param_scope = NewScope(scope_, BLOCK_SCOPE);
4650 param_scope->set_is_declaration_scope();
4651 param_scope->set_start_position(parameter.pattern->position());
4652 param_scope->set_end_position(RelocInfo::kNoPosition);
4653 param_scope->RecordEvalCall();
4654 param_block = factory()->NewBlock(NULL, 8, true, RelocInfo::kNoPosition);
4655 param_block->set_scope(param_scope);
4656 descriptor.hoist_scope = scope_;
4657 }
4658
4659 {
4660 BlockState block_state(&scope_, param_scope);
4661 DeclarationParsingResult::Declaration decl(
4662 parameter.pattern, initializer_position, initial_value);
4663 PatternRewriter::DeclareAndInitializeVariables(param_block, &descriptor,
4664 &decl, nullptr, CHECK_OK);
4665 }
4666
4667 if (!parameter.is_simple() && scope_->calls_sloppy_eval()) {
4668 param_scope = param_scope->FinalizeBlockScope();
4669 if (param_scope != nullptr) {
4670 CheckConflictingVarDeclarations(param_scope, CHECK_OK);
4671 }
4672 init_block->statements()->Add(param_block, zone());
4673 }
4674 }
4675 return init_block;
4676 }
4677
4678
4679 ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
4680 const AstRawString* function_name, int pos,
4681 const ParserFormalParameters& parameters, FunctionKind kind,
4682 FunctionLiteral::FunctionType function_type, bool* ok) {
4683 // Everything inside an eagerly parsed function will be parsed eagerly
4684 // (see comment above).
4685 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
4686 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone());
4687
4688 static const int kFunctionNameAssignmentIndex = 0;
4689 if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
4690 DCHECK(function_name != NULL);
4691 // If we have a named function expression, we add a local variable
4692 // declaration to the body of the function with the name of the
4693 // function and let it refer to the function itself (closure).
4694 // Not having parsed the function body, the language mode may still change,
4695 // so we reserve a spot and create the actual const assignment later.
4696 DCHECK_EQ(kFunctionNameAssignmentIndex, result->length());
4697 result->Add(NULL, zone());
4698 }
4699
4700 ZoneList<Statement*>* body = result;
4701 Scope* inner_scope = scope_;
4702 Block* inner_block = nullptr;
4703 if (!parameters.is_simple) {
4704 inner_scope = NewScope(scope_, BLOCK_SCOPE);
4705 inner_scope->set_is_declaration_scope();
4706 inner_scope->set_start_position(scanner()->location().beg_pos);
4707 inner_block = factory()->NewBlock(NULL, 8, true, RelocInfo::kNoPosition);
4708 inner_block->set_scope(inner_scope);
4709 body = inner_block->statements();
4710 }
4711
4712 {
4713 BlockState block_state(&scope_, inner_scope);
4714
4715 // For generators, allocate and yield an iterator on function entry.
4716 if (IsGeneratorFunction(kind)) {
4717 ZoneList<Expression*>* arguments =
4718 new(zone()) ZoneList<Expression*>(0, zone());
4719 CallRuntime* allocation = factory()->NewCallRuntime(
4720 Runtime::kCreateJSGeneratorObject, arguments, pos);
4721 VariableProxy* init_proxy = factory()->NewVariableProxy(
4722 function_state_->generator_object_variable());
4723 Assignment* assignment = factory()->NewAssignment(
4724 Token::INIT, init_proxy, allocation, RelocInfo::kNoPosition);
4725 VariableProxy* get_proxy = factory()->NewVariableProxy(
4726 function_state_->generator_object_variable());
4727 Yield* yield = factory()->NewYield(
4728 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition);
4729 body->Add(factory()->NewExpressionStatement(
4730 yield, RelocInfo::kNoPosition), zone());
4731 }
4732
4733 ParseStatementList(body, Token::RBRACE, CHECK_OK);
4734
4735 if (IsGeneratorFunction(kind)) {
4736 VariableProxy* get_proxy = factory()->NewVariableProxy(
4737 function_state_->generator_object_variable());
4738 Expression* undefined =
4739 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition);
4740 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal,
4741 RelocInfo::kNoPosition);
4742 body->Add(factory()->NewExpressionStatement(
4743 yield, RelocInfo::kNoPosition), zone());
4744 }
4745
4746 if (IsSubclassConstructor(kind)) {
4747 body->Add(
4748 factory()->NewReturnStatement(
4749 this->ThisExpression(scope_, factory(), RelocInfo::kNoPosition),
4750 RelocInfo::kNoPosition),
4751 zone());
4752 }
4753 }
4754
4755 Expect(Token::RBRACE, CHECK_OK);
4756 scope_->set_end_position(scanner()->location().end_pos);
4757
4758 if (!parameters.is_simple) {
4759 DCHECK_NOT_NULL(inner_scope);
4760 DCHECK_EQ(body, inner_block->statements());
4761 SetLanguageMode(scope_, inner_scope->language_mode());
4762 Block* init_block = BuildParameterInitializationBlock(parameters, CHECK_OK);
4763 DCHECK_NOT_NULL(init_block);
4764
4765 inner_scope->set_end_position(scanner()->location().end_pos);
4766 inner_scope = inner_scope->FinalizeBlockScope();
4767 if (inner_scope != nullptr) {
4768 CheckConflictingVarDeclarations(inner_scope, CHECK_OK);
4769 InsertShadowingVarBindingInitializers(inner_block);
4770 }
4771
4772 result->Add(init_block, zone());
4773 result->Add(inner_block, zone());
4774 }
4775
4776 if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
4777 // Now that we know the language mode, we can create the const assignment
4778 // in the previously reserved spot.
4779 // NOTE: We create a proxy and resolve it here so that in the
4780 // future we can change the AST to only refer to VariableProxies
4781 // instead of Variables and Proxies as is the case now.
4782 VariableMode fvar_mode = is_strict(language_mode()) ? CONST : CONST_LEGACY;
4783 Variable* fvar = new (zone())
4784 Variable(scope_, function_name, fvar_mode, Variable::NORMAL,
4785 kCreatedInitialized, kNotAssigned);
4786 VariableProxy* proxy = factory()->NewVariableProxy(fvar);
4787 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration(
4788 proxy, fvar_mode, scope_, RelocInfo::kNoPosition);
4789 scope_->DeclareFunctionVar(fvar_declaration);
4790
4791 VariableProxy* fproxy = factory()->NewVariableProxy(fvar);
4792 result->Set(kFunctionNameAssignmentIndex,
4793 factory()->NewExpressionStatement(
4794 factory()->NewAssignment(Token::INIT, fproxy,
4795 factory()->NewThisFunction(pos),
4796 RelocInfo::kNoPosition),
4797 RelocInfo::kNoPosition));
4798 }
4799
4800 return result;
4801 }
4802
4803
4804 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
4805 SingletonLogger* logger, Scanner::BookmarkScope* bookmark) {
4806 // This function may be called on a background thread too; record only the
4807 // main thread preparse times.
4808 if (pre_parse_timer_ != NULL) {
4809 pre_parse_timer_->Start();
4810 }
4811 DCHECK_EQ(Token::LBRACE, scanner()->current_token());
4812
4813 if (reusable_preparser_ == NULL) {
4814 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(),
4815 NULL, stack_limit_);
4816 reusable_preparser_->set_allow_lazy(true);
4817 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
4818 SET_ALLOW(natives);
4819 SET_ALLOW(harmony_sloppy);
4820 SET_ALLOW(harmony_sloppy_let);
4821 SET_ALLOW(harmony_rest_parameters);
4822 SET_ALLOW(harmony_default_parameters);
4823 SET_ALLOW(harmony_destructuring_bind);
4824 SET_ALLOW(strong_mode);
4825 SET_ALLOW(harmony_do_expressions);
4826 #undef SET_ALLOW
4827 }
4828 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
4829 language_mode(), function_state_->kind(), scope_->has_simple_parameters(),
4830 logger, bookmark);
4831 if (pre_parse_timer_ != NULL) {
4832 pre_parse_timer_->Stop();
4833 }
4834 return result;
4835 }
4836
4837
4838 ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name,
4839 Scanner::Location class_name_location,
4840 bool name_is_strict_reserved, int pos,
4841 bool* ok) {
4842 // All parts of a ClassDeclaration and ClassExpression are strict code.
4843 if (name_is_strict_reserved) {
4844 ReportMessageAt(class_name_location,
4845 MessageTemplate::kUnexpectedStrictReserved);
4846 *ok = false;
4847 return NULL;
4848 }
4849 if (IsEvalOrArguments(name)) {
4850 ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments);
4851 *ok = false;
4852 return NULL;
4853 }
4854 if (is_strong(language_mode()) && IsUndefined(name)) {
4855 ReportMessageAt(class_name_location, MessageTemplate::kStrongUndefined);
4856 *ok = false;
4857 return NULL;
4858 }
4859
4860 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
4861 BlockState block_state(&scope_, block_scope);
4862 RaiseLanguageMode(STRICT);
4863 scope_->SetScopeName(name);
4864
4865 VariableProxy* proxy = NULL;
4866 if (name != NULL) {
4867 proxy = NewUnresolved(name, CONST);
4868 const bool is_class_declaration = true;
4869 Declaration* declaration = factory()->NewVariableDeclaration(
4870 proxy, CONST, block_scope, pos, is_class_declaration,
4871 scope_->class_declaration_group_start());
4872 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
4873 }
4874
4875 Expression* extends = NULL;
4876 if (Check(Token::EXTENDS)) {
4877 block_scope->set_start_position(scanner()->location().end_pos);
4878 ExpressionClassifier classifier;
4879 extends = ParseLeftHandSideExpression(&classifier, CHECK_OK);
4880 ValidateExpression(&classifier, CHECK_OK);
4881 } else {
4882 block_scope->set_start_position(scanner()->location().end_pos);
4883 }
4884
4885
4886 ClassLiteralChecker checker(this);
4887 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone());
4888 FunctionLiteral* constructor = NULL;
4889 bool has_seen_constructor = false;
4890
4891 Expect(Token::LBRACE, CHECK_OK);
4892
4893 const bool has_extends = extends != nullptr;
4894 while (peek() != Token::RBRACE) {
4895 if (Check(Token::SEMICOLON)) continue;
4896 if (fni_ != NULL) fni_->Enter();
4897 const bool in_class = true;
4898 const bool is_static = false;
4899 bool is_computed_name = false; // Classes do not care about computed
4900 // property names here.
4901 ExpressionClassifier classifier;
4902 ObjectLiteral::Property* property = ParsePropertyDefinition(
4903 &checker, in_class, has_extends, is_static, &is_computed_name,
4904 &has_seen_constructor, &classifier, CHECK_OK);
4905 ValidateExpression(&classifier, CHECK_OK);
4906
4907 if (has_seen_constructor && constructor == NULL) {
4908 constructor = GetPropertyValue(property)->AsFunctionLiteral();
4909 DCHECK_NOT_NULL(constructor);
4910 } else {
4911 properties->Add(property, zone());
4912 }
4913
4914 if (fni_ != NULL) {
4915 fni_->Infer();
4916 fni_->Leave();
4917 }
4918 }
4919
4920 Expect(Token::RBRACE, CHECK_OK);
4921 int end_pos = scanner()->location().end_pos;
4922
4923 if (constructor == NULL) {
4924 constructor = DefaultConstructor(extends != NULL, block_scope, pos, end_pos,
4925 block_scope->language_mode());
4926 }
4927
4928 // Note that we do not finalize this block scope because strong
4929 // mode uses it as a sentinel value indicating an anonymous class.
4930 block_scope->set_end_position(end_pos);
4931
4932 if (name != NULL) {
4933 DCHECK_NOT_NULL(proxy);
4934 proxy->var()->set_initializer_position(end_pos);
4935 }
4936
4937 return factory()->NewClassLiteral(name, block_scope, proxy, extends,
4938 constructor, properties, pos, end_pos);
4939 }
4940
4941
4942 Expression* Parser::ParseV8Intrinsic(bool* ok) {
4943 // CallRuntime ::
4944 // '%' Identifier Arguments
4945
4946 int pos = peek_position();
4947 Expect(Token::MOD, CHECK_OK);
4948 // Allow "eval" or "arguments" for backward compatibility.
4949 const AstRawString* name = ParseIdentifier(kAllowRestrictedIdentifiers,
4950 CHECK_OK);
4951 Scanner::Location spread_pos;
4952 ExpressionClassifier classifier;
4953 ZoneList<Expression*>* args =
4954 ParseArguments(&spread_pos, &classifier, CHECK_OK);
4955 ValidateExpression(&classifier, CHECK_OK);
4956
4957 DCHECK(!spread_pos.IsValid());
4958
4959 if (extension_ != NULL) {
4960 // The extension structures are only accessible while parsing the
4961 // very first time not when reparsing because of lazy compilation.
4962 scope_->DeclarationScope()->ForceEagerCompilation();
4963 }
4964
4965 const Runtime::Function* function = Runtime::FunctionForName(name->string());
4966
4967 if (function != NULL) {
4968 // Check for possible name clash.
4969 DCHECK_EQ(Context::kNotFound,
4970 Context::IntrinsicIndexForName(name->string()));
4971 // Check for built-in IS_VAR macro.
4972 if (function->function_id == Runtime::kIS_VAR) {
4973 DCHECK_EQ(Runtime::RUNTIME, function->intrinsic_type);
4974 // %IS_VAR(x) evaluates to x if x is a variable,
4975 // leads to a parse error otherwise. Could be implemented as an
4976 // inline function %_IS_VAR(x) to eliminate this special case.
4977 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
4978 return args->at(0);
4979 } else {
4980 ReportMessage(MessageTemplate::kNotIsvar);
4981 *ok = false;
4982 return NULL;
4983 }
4984 }
4985
4986 // Check that the expected number of arguments are being passed.
4987 if (function->nargs != -1 && function->nargs != args->length()) {
4988 ReportMessage(MessageTemplate::kIllegalAccess);
4989 *ok = false;
4990 return NULL;
4991 }
4992
4993 return factory()->NewCallRuntime(function, args, pos);
4994 }
4995
4996 int context_index = Context::IntrinsicIndexForName(name->string());
4997
4998 // Check that the function is defined.
4999 if (context_index == Context::kNotFound) {
5000 ParserTraits::ReportMessage(MessageTemplate::kNotDefined, name);
5001 *ok = false;
5002 return NULL;
5003 }
5004
5005 return factory()->NewCallRuntime(context_index, args, pos);
5006 }
5007
5008
5009 Literal* Parser::GetLiteralUndefined(int position) {
5010 return factory()->NewUndefinedLiteral(position);
5011 }
5012
5013
5014 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
5015 Declaration* decl = scope->CheckConflictingVarDeclarations();
5016 if (decl != NULL) {
5017 // In ES6, conflicting variable bindings are early errors.
5018 const AstRawString* name = decl->proxy()->raw_name();
5019 int position = decl->proxy()->position();
5020 Scanner::Location location = position == RelocInfo::kNoPosition
5021 ? Scanner::Location::invalid()
5022 : Scanner::Location(position, position + 1);
5023 ParserTraits::ReportMessageAt(location, MessageTemplate::kVarRedeclaration,
5024 name);
5025 *ok = false;
5026 }
5027 }
5028
5029
5030 void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) {
5031 // For each var-binding that shadows a parameter, insert an assignment
5032 // initializing the variable with the parameter.
5033 Scope* inner_scope = inner_block->scope();
5034 DCHECK(inner_scope->is_declaration_scope());
5035 Scope* function_scope = inner_scope->outer_scope();
5036 DCHECK(function_scope->is_function_scope());
5037 ZoneList<Declaration*>* decls = inner_scope->declarations();
5038 for (int i = 0; i < decls->length(); ++i) {
5039 Declaration* decl = decls->at(i);
5040 if (decl->mode() != VAR || !decl->IsVariableDeclaration()) continue;
5041 const AstRawString* name = decl->proxy()->raw_name();
5042 Variable* parameter = function_scope->LookupLocal(name);
5043 if (parameter == nullptr) continue;
5044 VariableProxy* to = inner_scope->NewUnresolved(factory(), name);
5045 VariableProxy* from = factory()->NewVariableProxy(parameter);
5046 Expression* assignment = factory()->NewAssignment(
5047 Token::ASSIGN, to, from, RelocInfo::kNoPosition);
5048 Statement* statement = factory()->NewExpressionStatement(
5049 assignment, RelocInfo::kNoPosition);
5050 inner_block->statements()->InsertAt(0, statement, zone());
5051 }
5052 }
5053
5054
5055 void Parser::InsertSloppyBlockFunctionVarBindings(Scope* scope, bool* ok) {
5056 // For each variable which is used as a function declaration in a sloppy
5057 // block,
5058 DCHECK(scope->is_declaration_scope());
5059 SloppyBlockFunctionMap* map = scope->sloppy_block_function_map();
5060 for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
5061 AstRawString* name = static_cast<AstRawString*>(p->key);
5062 // If the variable wouldn't conflict with a lexical declaration,
5063 Variable* var = scope->LookupLocal(name);
5064 if (var == nullptr || !IsLexicalVariableMode(var->mode())) {
5065 // Declare a var-style binding for the function in the outer scope
5066 VariableProxy* proxy = scope->NewUnresolved(factory(), name);
5067 Declaration* declaration = factory()->NewVariableDeclaration(
5068 proxy, VAR, scope, RelocInfo::kNoPosition);
5069 Declare(declaration, DeclarationDescriptor::NORMAL, true, ok, scope);
5070 DCHECK(ok); // Based on the preceding check, this should not fail
5071 if (!ok) return;
5072
5073 // Write in assignments to var for each block-scoped function declaration
5074 auto delegates = static_cast<SloppyBlockFunctionMap::Vector*>(p->value);
5075 for (SloppyBlockFunctionStatement* delegate : *delegates) {
5076 // Read from the local lexical scope and write to the function scope
5077 VariableProxy* to = scope->NewUnresolved(factory(), name);
5078 VariableProxy* from = delegate->scope()->NewUnresolved(factory(), name);
5079 Expression* assignment = factory()->NewAssignment(
5080 Token::ASSIGN, to, from, RelocInfo::kNoPosition);
5081 Statement* statement = factory()->NewExpressionStatement(
5082 assignment, RelocInfo::kNoPosition);
5083 delegate->set_statement(statement);
5084 }
5085 }
5086 }
5087 }
5088
5089
5090 // ----------------------------------------------------------------------------
5091 // Parser support
5092
5093 bool Parser::TargetStackContainsLabel(const AstRawString* label) {
5094 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
5095 if (ContainsLabel(t->statement()->labels(), label)) return true;
5096 }
5097 return false;
5098 }
5099
5100
5101 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
5102 bool* ok) {
5103 bool anonymous = label == NULL;
5104 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
5105 BreakableStatement* stat = t->statement();
5106 if ((anonymous && stat->is_target_for_anonymous()) ||
5107 (!anonymous && ContainsLabel(stat->labels(), label))) {
5108 return stat;
5109 }
5110 }
5111 return NULL;
5112 }
5113
5114
5115 IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
5116 bool* ok) {
5117 bool anonymous = label == NULL;
5118 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
5119 IterationStatement* stat = t->statement()->AsIterationStatement();
5120 if (stat == NULL) continue;
5121
5122 DCHECK(stat->is_target_for_anonymous());
5123 if (anonymous || ContainsLabel(stat->labels(), label)) {
5124 return stat;
5125 }
5126 }
5127 return NULL;
5128 }
5129
5130
5131 void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
5132 if (scanner_.source_url()->length() > 0) {
5133 Handle<String> source_url = scanner_.source_url()->Internalize(isolate);
5134 script->set_source_url(*source_url);
5135 }
5136 if (scanner_.source_mapping_url()->length() > 0) {
5137 Handle<String> source_mapping_url =
5138 scanner_.source_mapping_url()->Internalize(isolate);
5139 script->set_source_mapping_url(*source_mapping_url);
5140 }
5141 }
5142
5143
5144 void Parser::Internalize(Isolate* isolate, Handle<Script> script, bool error) {
5145 // Internalize strings.
5146 ast_value_factory()->Internalize(isolate);
5147
5148 // Error processing.
5149 if (error) {
5150 if (stack_overflow()) {
5151 isolate->StackOverflow();
5152 } else {
5153 DCHECK(pending_error_handler_.has_pending_error());
5154 pending_error_handler_.ThrowPendingError(isolate, script);
5155 }
5156 }
5157
5158 // Move statistics to Isolate.
5159 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
5160 ++feature) {
5161 for (int i = 0; i < use_counts_[feature]; ++i) {
5162 isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
5163 }
5164 }
5165 isolate->counters()->total_preparse_skipped()->Increment(
5166 total_preparse_skipped_);
5167 }
5168
5169
5170 // ----------------------------------------------------------------------------
5171 // Regular expressions
5172
5173
5174 RegExpParser::RegExpParser(FlatStringReader* in, Handle<String>* error,
5175 bool multiline, bool unicode, Isolate* isolate,
5176 Zone* zone)
5177 : isolate_(isolate),
5178 zone_(zone),
5179 error_(error),
5180 captures_(NULL),
5181 in_(in),
5182 current_(kEndMarker),
5183 next_pos_(0),
5184 captures_started_(0),
5185 capture_count_(0),
5186 has_more_(true),
5187 multiline_(multiline),
5188 unicode_(unicode),
5189 simple_(false),
5190 contains_anchor_(false),
5191 is_scanned_for_captures_(false),
5192 failed_(false) {
5193 Advance();
5194 }
5195
5196
5197 uc32 RegExpParser::Next() {
5198 if (has_next()) {
5199 return in()->Get(next_pos_);
5200 } else {
5201 return kEndMarker;
5202 }
5203 }
5204
5205
5206 void RegExpParser::Advance() {
5207 if (next_pos_ < in()->length()) {
5208 StackLimitCheck check(isolate());
5209 if (check.HasOverflowed()) {
5210 ReportError(CStrVector(Isolate::kStackOverflowMessage));
5211 } else if (zone()->excess_allocation()) {
5212 ReportError(CStrVector("Regular expression too large"));
5213 } else {
5214 current_ = in()->Get(next_pos_);
5215 next_pos_++;
5216 }
5217 } else {
5218 current_ = kEndMarker;
5219 // Advance so that position() points to 1-after-the-last-character. This is
5220 // important so that Reset() to this position works correctly.
5221 next_pos_ = in()->length() + 1;
5222 has_more_ = false;
5223 }
5224 }
5225
5226
5227 void RegExpParser::Reset(int pos) {
5228 next_pos_ = pos;
5229 has_more_ = (pos < in()->length());
5230 Advance();
5231 }
5232
5233
5234 void RegExpParser::Advance(int dist) {
5235 next_pos_ += dist - 1;
5236 Advance();
5237 }
5238
5239
5240 bool RegExpParser::simple() {
5241 return simple_;
5242 }
5243
5244
5245 bool RegExpParser::IsSyntaxCharacter(uc32 c) {
5246 return c == '^' || c == '$' || c == '\\' || c == '.' || c == '*' ||
5247 c == '+' || c == '?' || c == '(' || c == ')' || c == '[' || c == ']' ||
5248 c == '{' || c == '}' || c == '|';
5249 }
5250
5251
5252 RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
5253 failed_ = true;
5254 *error_ = isolate()->factory()->NewStringFromAscii(message).ToHandleChecked();
5255 // Zip to the end to make sure the no more input is read.
5256 current_ = kEndMarker;
5257 next_pos_ = in()->length();
5258 return NULL;
5259 }
5260
5261
5262 // Pattern ::
5263 // Disjunction
5264 RegExpTree* RegExpParser::ParsePattern() {
5265 RegExpTree* result = ParseDisjunction(CHECK_FAILED);
5266 DCHECK(!has_more());
5267 // If the result of parsing is a literal string atom, and it has the
5268 // same length as the input, then the atom is identical to the input.
5269 if (result->IsAtom() && result->AsAtom()->length() == in()->length()) {
5270 simple_ = true;
5271 }
5272 return result;
5273 }
5274
5275
5276 // Disjunction ::
5277 // Alternative
5278 // Alternative | Disjunction
5279 // Alternative ::
5280 // [empty]
5281 // Term Alternative
5282 // Term ::
5283 // Assertion
5284 // Atom
5285 // Atom Quantifier
5286 RegExpTree* RegExpParser::ParseDisjunction() {
5287 // Used to store current state while parsing subexpressions.
5288 RegExpParserState initial_state(NULL, INITIAL, RegExpLookaround::LOOKAHEAD, 0,
5289 zone());
5290 RegExpParserState* state = &initial_state;
5291 // Cache the builder in a local variable for quick access.
5292 RegExpBuilder* builder = initial_state.builder();
5293 while (true) {
5294 switch (current()) {
5295 case kEndMarker:
5296 if (state->IsSubexpression()) {
5297 // Inside a parenthesized group when hitting end of input.
5298 ReportError(CStrVector("Unterminated group") CHECK_FAILED);
5299 }
5300 DCHECK_EQ(INITIAL, state->group_type());
5301 // Parsing completed successfully.
5302 return builder->ToRegExp();
5303 case ')': {
5304 if (!state->IsSubexpression()) {
5305 ReportError(CStrVector("Unmatched ')'") CHECK_FAILED);
5306 }
5307 DCHECK_NE(INITIAL, state->group_type());
5308
5309 Advance();
5310 // End disjunction parsing and convert builder content to new single
5311 // regexp atom.
5312 RegExpTree* body = builder->ToRegExp();
5313
5314 int end_capture_index = captures_started();
5315
5316 int capture_index = state->capture_index();
5317 SubexpressionType group_type = state->group_type();
5318
5319 // Build result of subexpression.
5320 if (group_type == CAPTURE) {
5321 RegExpCapture* capture = GetCapture(capture_index);
5322 capture->set_body(body);
5323 body = capture;
5324 } else if (group_type != GROUPING) {
5325 DCHECK(group_type == POSITIVE_LOOKAROUND ||
5326 group_type == NEGATIVE_LOOKAROUND);
5327 bool is_positive = (group_type == POSITIVE_LOOKAROUND);
5328 body = new (zone()) RegExpLookaround(
5329 body, is_positive, end_capture_index - capture_index, capture_index,
5330 state->lookaround_type());
5331 }
5332
5333 // Restore previous state.
5334 state = state->previous_state();
5335 builder = state->builder();
5336
5337 builder->AddAtom(body);
5338 // For compatability with JSC and ES3, we allow quantifiers after
5339 // lookaheads, and break in all cases.
5340 break;
5341 }
5342 case '|': {
5343 Advance();
5344 builder->NewAlternative();
5345 continue;
5346 }
5347 case '*':
5348 case '+':
5349 case '?':
5350 return ReportError(CStrVector("Nothing to repeat"));
5351 case '^': {
5352 Advance();
5353 if (multiline_) {
5354 builder->AddAssertion(
5355 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE));
5356 } else {
5357 builder->AddAssertion(
5358 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
5359 set_contains_anchor();
5360 }
5361 continue;
5362 }
5363 case '$': {
5364 Advance();
5365 RegExpAssertion::AssertionType assertion_type =
5366 multiline_ ? RegExpAssertion::END_OF_LINE :
5367 RegExpAssertion::END_OF_INPUT;
5368 builder->AddAssertion(new(zone()) RegExpAssertion(assertion_type));
5369 continue;
5370 }
5371 case '.': {
5372 Advance();
5373 // everything except \x0a, \x0d, \u2028 and \u2029
5374 ZoneList<CharacterRange>* ranges =
5375 new(zone()) ZoneList<CharacterRange>(2, zone());
5376 CharacterRange::AddClassEscape('.', ranges, zone());
5377 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
5378 builder->AddAtom(atom);
5379 break;
5380 }
5381 case '(': {
5382 SubexpressionType subexpr_type = CAPTURE;
5383 RegExpLookaround::Type lookaround_type = state->lookaround_type();
5384 Advance();
5385 if (current() == '?') {
5386 switch (Next()) {
5387 case ':':
5388 subexpr_type = GROUPING;
5389 break;
5390 case '=':
5391 lookaround_type = RegExpLookaround::LOOKAHEAD;
5392 subexpr_type = POSITIVE_LOOKAROUND;
5393 break;
5394 case '!':
5395 lookaround_type = RegExpLookaround::LOOKAHEAD;
5396 subexpr_type = NEGATIVE_LOOKAROUND;
5397 break;
5398 case '<':
5399 if (FLAG_harmony_regexp_lookbehind) {
5400 Advance();
5401 lookaround_type = RegExpLookaround::LOOKBEHIND;
5402 if (Next() == '=') {
5403 subexpr_type = POSITIVE_LOOKAROUND;
5404 break;
5405 } else if (Next() == '!') {
5406 subexpr_type = NEGATIVE_LOOKAROUND;
5407 break;
5408 }
5409 }
5410 // Fall through.
5411 default:
5412 ReportError(CStrVector("Invalid group") CHECK_FAILED);
5413 break;
5414 }
5415 Advance(2);
5416 } else {
5417 if (captures_started_ >= kMaxCaptures) {
5418 ReportError(CStrVector("Too many captures") CHECK_FAILED);
5419 }
5420 captures_started_++;
5421 }
5422 // Store current state and begin new disjunction parsing.
5423 state = new (zone()) RegExpParserState(
5424 state, subexpr_type, lookaround_type, captures_started_, zone());
5425 builder = state->builder();
5426 continue;
5427 }
5428 case '[': {
5429 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED);
5430 builder->AddAtom(atom);
5431 break;
5432 }
5433 // Atom ::
5434 // \ AtomEscape
5435 case '\\':
5436 switch (Next()) {
5437 case kEndMarker:
5438 return ReportError(CStrVector("\\ at end of pattern"));
5439 case 'b':
5440 Advance(2);
5441 builder->AddAssertion(
5442 new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
5443 continue;
5444 case 'B':
5445 Advance(2);
5446 builder->AddAssertion(
5447 new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
5448 continue;
5449 // AtomEscape ::
5450 // CharacterClassEscape
5451 //
5452 // CharacterClassEscape :: one of
5453 // d D s S w W
5454 case 'd': case 'D': case 's': case 'S': case 'w': case 'W': {
5455 uc32 c = Next();
5456 Advance(2);
5457 ZoneList<CharacterRange>* ranges =
5458 new(zone()) ZoneList<CharacterRange>(2, zone());
5459 CharacterRange::AddClassEscape(c, ranges, zone());
5460 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
5461 builder->AddAtom(atom);
5462 break;
5463 }
5464 case '1': case '2': case '3': case '4': case '5': case '6':
5465 case '7': case '8': case '9': {
5466 int index = 0;
5467 if (ParseBackReferenceIndex(&index)) {
5468 if (state->IsInsideCaptureGroup(index)) {
5469 // The backreference is inside the capture group it refers to.
5470 // Nothing can possibly have been captured yet.
5471 builder->AddEmpty();
5472 } else {
5473 RegExpCapture* capture = GetCapture(index);
5474 RegExpTree* atom = new (zone()) RegExpBackReference(capture);
5475 builder->AddAtom(atom);
5476 }
5477 break;
5478 }
5479 uc32 first_digit = Next();
5480 if (first_digit == '8' || first_digit == '9') {
5481 // If the 'u' flag is present, only syntax characters can be escaped,
5482 // no other identity escapes are allowed. If the 'u' flag is not
5483 // present, all identity escapes are allowed.
5484 if (!FLAG_harmony_unicode_regexps || !unicode_) {
5485 builder->AddCharacter(first_digit);
5486 Advance(2);
5487 } else {
5488 return ReportError(CStrVector("Invalid escape"));
5489 }
5490 break;
5491 }
5492 }
5493 // FALLTHROUGH
5494 case '0': {
5495 Advance();
5496 uc32 octal = ParseOctalLiteral();
5497 builder->AddCharacter(octal);
5498 break;
5499 }
5500 // ControlEscape :: one of
5501 // f n r t v
5502 case 'f':
5503 Advance(2);
5504 builder->AddCharacter('\f');
5505 break;
5506 case 'n':
5507 Advance(2);
5508 builder->AddCharacter('\n');
5509 break;
5510 case 'r':
5511 Advance(2);
5512 builder->AddCharacter('\r');
5513 break;
5514 case 't':
5515 Advance(2);
5516 builder->AddCharacter('\t');
5517 break;
5518 case 'v':
5519 Advance(2);
5520 builder->AddCharacter('\v');
5521 break;
5522 case 'c': {
5523 Advance();
5524 uc32 controlLetter = Next();
5525 // Special case if it is an ASCII letter.
5526 // Convert lower case letters to uppercase.
5527 uc32 letter = controlLetter & ~('a' ^ 'A');
5528 if (letter < 'A' || 'Z' < letter) {
5529 // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
5530 // This is outside the specification. We match JSC in
5531 // reading the backslash as a literal character instead
5532 // of as starting an escape.
5533 builder->AddCharacter('\\');
5534 } else {
5535 Advance(2);
5536 builder->AddCharacter(controlLetter & 0x1f);
5537 }
5538 break;
5539 }
5540 case 'x': {
5541 Advance(2);
5542 uc32 value;
5543 if (ParseHexEscape(2, &value)) {
5544 builder->AddCharacter(value);
5545 } else if (!FLAG_harmony_unicode_regexps || !unicode_) {
5546 builder->AddCharacter('x');
5547 } else {
5548 // If the 'u' flag is present, invalid escapes are not treated as
5549 // identity escapes.
5550 return ReportError(CStrVector("Invalid escape"));
5551 }
5552 break;
5553 }
5554 case 'u': {
5555 Advance(2);
5556 uc32 value;
5557 if (ParseUnicodeEscape(&value)) {
5558 builder->AddCharacter(value);
5559 } else if (!FLAG_harmony_unicode_regexps || !unicode_) {
5560 builder->AddCharacter('u');
5561 } else {
5562 // If the 'u' flag is present, invalid escapes are not treated as
5563 // identity escapes.
5564 return ReportError(CStrVector("Invalid unicode escape"));
5565 }
5566 break;
5567 }
5568 default:
5569 Advance();
5570 // If the 'u' flag is present, only syntax characters can be escaped, no
5571 // other identity escapes are allowed. If the 'u' flag is not present,
5572 // all identity escapes are allowed.
5573 if (!FLAG_harmony_unicode_regexps || !unicode_ ||
5574 IsSyntaxCharacter(current())) {
5575 builder->AddCharacter(current());
5576 Advance();
5577 } else {
5578 return ReportError(CStrVector("Invalid escape"));
5579 }
5580 break;
5581 }
5582 break;
5583 case '{': {
5584 int dummy;
5585 if (ParseIntervalQuantifier(&dummy, &dummy)) {
5586 ReportError(CStrVector("Nothing to repeat") CHECK_FAILED);
5587 }
5588 // fallthrough
5589 }
5590 default:
5591 builder->AddCharacter(current());
5592 Advance();
5593 break;
5594 } // end switch(current())
5595
5596 int min;
5597 int max;
5598 switch (current()) {
5599 // QuantifierPrefix ::
5600 // *
5601 // +
5602 // ?
5603 // {
5604 case '*':
5605 min = 0;
5606 max = RegExpTree::kInfinity;
5607 Advance();
5608 break;
5609 case '+':
5610 min = 1;
5611 max = RegExpTree::kInfinity;
5612 Advance();
5613 break;
5614 case '?':
5615 min = 0;
5616 max = 1;
5617 Advance();
5618 break;
5619 case '{':
5620 if (ParseIntervalQuantifier(&min, &max)) {
5621 if (max < min) {
5622 ReportError(CStrVector("numbers out of order in {} quantifier.")
5623 CHECK_FAILED);
5624 }
5625 break;
5626 } else {
5627 continue;
5628 }
5629 default:
5630 continue;
5631 }
5632 RegExpQuantifier::QuantifierType quantifier_type = RegExpQuantifier::GREEDY;
5633 if (current() == '?') {
5634 quantifier_type = RegExpQuantifier::NON_GREEDY;
5635 Advance();
5636 } else if (FLAG_regexp_possessive_quantifier && current() == '+') {
5637 // FLAG_regexp_possessive_quantifier is a debug-only flag.
5638 quantifier_type = RegExpQuantifier::POSSESSIVE;
5639 Advance();
5640 }
5641 builder->AddQuantifierToAtom(min, max, quantifier_type);
5642 }
5643 }
5644
5645
5646 #ifdef DEBUG
5647 // Currently only used in an DCHECK.
5648 static bool IsSpecialClassEscape(uc32 c) {
5649 switch (c) {
5650 case 'd': case 'D':
5651 case 's': case 'S':
5652 case 'w': case 'W':
5653 return true;
5654 default:
5655 return false;
5656 }
5657 }
5658 #endif
5659
5660
5661 // In order to know whether an escape is a backreference or not we have to scan
5662 // the entire regexp and find the number of capturing parentheses. However we
5663 // don't want to scan the regexp twice unless it is necessary. This mini-parser
5664 // is called when needed. It can see the difference between capturing and
5665 // noncapturing parentheses and can skip character classes and backslash-escaped
5666 // characters.
5667 void RegExpParser::ScanForCaptures() {
5668 // Start with captures started previous to current position
5669 int capture_count = captures_started();
5670 // Add count of captures after this position.
5671 int n;
5672 while ((n = current()) != kEndMarker) {
5673 Advance();
5674 switch (n) {
5675 case '\\':
5676 Advance();
5677 break;
5678 case '[': {
5679 int c;
5680 while ((c = current()) != kEndMarker) {
5681 Advance();
5682 if (c == '\\') {
5683 Advance();
5684 } else {
5685 if (c == ']') break;
5686 }
5687 }
5688 break;
5689 }
5690 case '(':
5691 if (current() != '?') capture_count++;
5692 break;
5693 }
5694 }
5695 capture_count_ = capture_count;
5696 is_scanned_for_captures_ = true;
5697 }
5698
5699
5700 bool RegExpParser::ParseBackReferenceIndex(int* index_out) {
5701 DCHECK_EQ('\\', current());
5702 DCHECK('1' <= Next() && Next() <= '9');
5703 // Try to parse a decimal literal that is no greater than the total number
5704 // of left capturing parentheses in the input.
5705 int start = position();
5706 int value = Next() - '0';
5707 Advance(2);
5708 while (true) {
5709 uc32 c = current();
5710 if (IsDecimalDigit(c)) {
5711 value = 10 * value + (c - '0');
5712 if (value > kMaxCaptures) {
5713 Reset(start);
5714 return false;
5715 }
5716 Advance();
5717 } else {
5718 break;
5719 }
5720 }
5721 if (value > captures_started()) {
5722 if (!is_scanned_for_captures_) {
5723 int saved_position = position();
5724 ScanForCaptures();
5725 Reset(saved_position);
5726 }
5727 if (value > capture_count_) {
5728 Reset(start);
5729 return false;
5730 }
5731 }
5732 *index_out = value;
5733 return true;
5734 }
5735
5736
5737 RegExpCapture* RegExpParser::GetCapture(int index) {
5738 // The index for the capture groups are one-based. Its index in the list is
5739 // zero-based.
5740 int know_captures =
5741 is_scanned_for_captures_ ? capture_count_ : captures_started_;
5742 DCHECK(index <= know_captures);
5743 if (captures_ == NULL) {
5744 captures_ = new (zone()) ZoneList<RegExpCapture*>(know_captures, zone());
5745 }
5746 while (captures_->length() < know_captures) {
5747 captures_->Add(new (zone()) RegExpCapture(captures_->length() + 1), zone());
5748 }
5749 return captures_->at(index - 1);
5750 }
5751
5752
5753 bool RegExpParser::RegExpParserState::IsInsideCaptureGroup(int index) {
5754 for (RegExpParserState* s = this; s != NULL; s = s->previous_state()) {
5755 if (s->group_type() != CAPTURE) continue;
5756 // Return true if we found the matching capture index.
5757 if (index == s->capture_index()) return true;
5758 // Abort if index is larger than what has been parsed up till this state.
5759 if (index > s->capture_index()) return false;
5760 }
5761 return false;
5762 }
5763
5764
5765 // QuantifierPrefix ::
5766 // { DecimalDigits }
5767 // { DecimalDigits , }
5768 // { DecimalDigits , DecimalDigits }
5769 //
5770 // Returns true if parsing succeeds, and set the min_out and max_out
5771 // values. Values are truncated to RegExpTree::kInfinity if they overflow.
5772 bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
5773 DCHECK_EQ(current(), '{');
5774 int start = position();
5775 Advance();
5776 int min = 0;
5777 if (!IsDecimalDigit(current())) {
5778 Reset(start);
5779 return false;
5780 }
5781 while (IsDecimalDigit(current())) {
5782 int next = current() - '0';
5783 if (min > (RegExpTree::kInfinity - next) / 10) {
5784 // Overflow. Skip past remaining decimal digits and return -1.
5785 do {
5786 Advance();
5787 } while (IsDecimalDigit(current()));
5788 min = RegExpTree::kInfinity;
5789 break;
5790 }
5791 min = 10 * min + next;
5792 Advance();
5793 }
5794 int max = 0;
5795 if (current() == '}') {
5796 max = min;
5797 Advance();
5798 } else if (current() == ',') {
5799 Advance();
5800 if (current() == '}') {
5801 max = RegExpTree::kInfinity;
5802 Advance();
5803 } else {
5804 while (IsDecimalDigit(current())) {
5805 int next = current() - '0';
5806 if (max > (RegExpTree::kInfinity - next) / 10) {
5807 do {
5808 Advance();
5809 } while (IsDecimalDigit(current()));
5810 max = RegExpTree::kInfinity;
5811 break;
5812 }
5813 max = 10 * max + next;
5814 Advance();
5815 }
5816 if (current() != '}') {
5817 Reset(start);
5818 return false;
5819 }
5820 Advance();
5821 }
5822 } else {
5823 Reset(start);
5824 return false;
5825 }
5826 *min_out = min;
5827 *max_out = max;
5828 return true;
5829 }
5830
5831
5832 uc32 RegExpParser::ParseOctalLiteral() {
5833 DCHECK(('0' <= current() && current() <= '7') || current() == kEndMarker);
5834 // For compatibility with some other browsers (not all), we parse
5835 // up to three octal digits with a value below 256.
5836 uc32 value = current() - '0';
5837 Advance();
5838 if ('0' <= current() && current() <= '7') {
5839 value = value * 8 + current() - '0';
5840 Advance();
5841 if (value < 32 && '0' <= current() && current() <= '7') {
5842 value = value * 8 + current() - '0';
5843 Advance();
5844 }
5845 }
5846 return value;
5847 }
5848
5849
5850 bool RegExpParser::ParseHexEscape(int length, uc32* value) {
5851 int start = position();
5852 uc32 val = 0;
5853 for (int i = 0; i < length; ++i) {
5854 uc32 c = current();
5855 int d = HexValue(c);
5856 if (d < 0) {
5857 Reset(start);
5858 return false;
5859 }
5860 val = val * 16 + d;
5861 Advance();
5862 }
5863 *value = val;
5864 return true;
5865 }
5866
5867
5868 bool RegExpParser::ParseUnicodeEscape(uc32* value) {
5869 // Accept both \uxxxx and \u{xxxxxx} (if harmony unicode escapes are
5870 // allowed). In the latter case, the number of hex digits between { } is
5871 // arbitrary. \ and u have already been read.
5872 if (current() == '{' && FLAG_harmony_unicode_regexps && unicode_) {
5873 int start = position();
5874 Advance();
5875 if (ParseUnlimitedLengthHexNumber(0x10ffff, value)) {
5876 if (current() == '}') {
5877 Advance();
5878 return true;
5879 }
5880 }
5881 Reset(start);
5882 return false;
5883 }
5884 // \u but no {, or \u{...} escapes not allowed.
5885 return ParseHexEscape(4, value);
5886 }
5887
5888
5889 bool RegExpParser::ParseUnlimitedLengthHexNumber(int max_value, uc32* value) {
5890 uc32 x = 0;
5891 int d = HexValue(current());
5892 if (d < 0) {
5893 return false;
5894 }
5895 while (d >= 0) {
5896 x = x * 16 + d;
5897 if (x > max_value) {
5898 return false;
5899 }
5900 Advance();
5901 d = HexValue(current());
5902 }
5903 *value = x;
5904 return true;
5905 }
5906
5907
5908 uc32 RegExpParser::ParseClassCharacterEscape() {
5909 DCHECK(current() == '\\');
5910 DCHECK(has_next() && !IsSpecialClassEscape(Next()));
5911 Advance();
5912 switch (current()) {
5913 case 'b':
5914 Advance();
5915 return '\b';
5916 // ControlEscape :: one of
5917 // f n r t v
5918 case 'f':
5919 Advance();
5920 return '\f';
5921 case 'n':
5922 Advance();
5923 return '\n';
5924 case 'r':
5925 Advance();
5926 return '\r';
5927 case 't':
5928 Advance();
5929 return '\t';
5930 case 'v':
5931 Advance();
5932 return '\v';
5933 case 'c': {
5934 uc32 controlLetter = Next();
5935 uc32 letter = controlLetter & ~('A' ^ 'a');
5936 // For compatibility with JSC, inside a character class
5937 // we also accept digits and underscore as control characters.
5938 if ((controlLetter >= '0' && controlLetter <= '9') ||
5939 controlLetter == '_' ||
5940 (letter >= 'A' && letter <= 'Z')) {
5941 Advance(2);
5942 // Control letters mapped to ASCII control characters in the range
5943 // 0x00-0x1f.
5944 return controlLetter & 0x1f;
5945 }
5946 // We match JSC in reading the backslash as a literal
5947 // character instead of as starting an escape.
5948 return '\\';
5949 }
5950 case '0': case '1': case '2': case '3': case '4': case '5':
5951 case '6': case '7':
5952 // For compatibility, we interpret a decimal escape that isn't
5953 // a back reference (and therefore either \0 or not valid according
5954 // to the specification) as a 1..3 digit octal character code.
5955 return ParseOctalLiteral();
5956 case 'x': {
5957 Advance();
5958 uc32 value;
5959 if (ParseHexEscape(2, &value)) {
5960 return value;
5961 }
5962 if (!FLAG_harmony_unicode_regexps || !unicode_) {
5963 // If \x is not followed by a two-digit hexadecimal, treat it
5964 // as an identity escape.
5965 return 'x';
5966 }
5967 // If the 'u' flag is present, invalid escapes are not treated as
5968 // identity escapes.
5969 ReportError(CStrVector("Invalid escape"));
5970 return 0;
5971 }
5972 case 'u': {
5973 Advance();
5974 uc32 value;
5975 if (ParseUnicodeEscape(&value)) {
5976 return value;
5977 }
5978 if (!FLAG_harmony_unicode_regexps || !unicode_) {
5979 return 'u';
5980 }
5981 // If the 'u' flag is present, invalid escapes are not treated as
5982 // identity escapes.
5983 ReportError(CStrVector("Invalid unicode escape"));
5984 return 0;
5985 }
5986 default: {
5987 uc32 result = current();
5988 // If the 'u' flag is present, only syntax characters can be escaped, no
5989 // other identity escapes are allowed. If the 'u' flag is not present, all
5990 // identity escapes are allowed.
5991 if (!FLAG_harmony_unicode_regexps || !unicode_ ||
5992 IsSyntaxCharacter(result)) {
5993 Advance();
5994 return result;
5995 }
5996 ReportError(CStrVector("Invalid escape"));
5997 return 0;
5998 }
5999 }
6000 return 0;
6001 }
6002
6003
6004 CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) {
6005 DCHECK_EQ(0, *char_class);
6006 uc32 first = current();
6007 if (first == '\\') {
6008 switch (Next()) {
6009 case 'w': case 'W': case 'd': case 'D': case 's': case 'S': {
6010 *char_class = Next();
6011 Advance(2);
6012 return CharacterRange::Singleton(0); // Return dummy value.
6013 }
6014 case kEndMarker:
6015 return ReportError(CStrVector("\\ at end of pattern"));
6016 default:
6017 uc32 c = ParseClassCharacterEscape(CHECK_FAILED);
6018 return CharacterRange::Singleton(c);
6019 }
6020 } else {
6021 Advance();
6022 return CharacterRange::Singleton(first);
6023 }
6024 }
6025
6026
6027 static const uc16 kNoCharClass = 0;
6028
6029 // Adds range or pre-defined character class to character ranges.
6030 // If char_class is not kInvalidClass, it's interpreted as a class
6031 // escape (i.e., 's' means whitespace, from '\s').
6032 static inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges,
6033 uc16 char_class,
6034 CharacterRange range,
6035 Zone* zone) {
6036 if (char_class != kNoCharClass) {
6037 CharacterRange::AddClassEscape(char_class, ranges, zone);
6038 } else {
6039 ranges->Add(range, zone);
6040 }
6041 }
6042
6043
6044 RegExpTree* RegExpParser::ParseCharacterClass() {
6045 static const char* kUnterminated = "Unterminated character class";
6046 static const char* kRangeOutOfOrder = "Range out of order in character class";
6047
6048 DCHECK_EQ(current(), '[');
6049 Advance();
6050 bool is_negated = false;
6051 if (current() == '^') {
6052 is_negated = true;
6053 Advance();
6054 }
6055 ZoneList<CharacterRange>* ranges =
6056 new(zone()) ZoneList<CharacterRange>(2, zone());
6057 while (has_more() && current() != ']') {
6058 uc16 char_class = kNoCharClass;
6059 CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED);
6060 if (current() == '-') {
6061 Advance();
6062 if (current() == kEndMarker) {
6063 // If we reach the end we break out of the loop and let the
6064 // following code report an error.
6065 break;
6066 } else if (current() == ']') {
6067 AddRangeOrEscape(ranges, char_class, first, zone());
6068 ranges->Add(CharacterRange::Singleton('-'), zone());
6069 break;
6070 }
6071 uc16 char_class_2 = kNoCharClass;
6072 CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED);
6073 if (char_class != kNoCharClass || char_class_2 != kNoCharClass) {
6074 // Either end is an escaped character class. Treat the '-' verbatim.
6075 AddRangeOrEscape(ranges, char_class, first, zone());
6076 ranges->Add(CharacterRange::Singleton('-'), zone());
6077 AddRangeOrEscape(ranges, char_class_2, next, zone());
6078 continue;
6079 }
6080 if (first.from() > next.to()) {
6081 return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED);
6082 }
6083 ranges->Add(CharacterRange::Range(first.from(), next.to()), zone());
6084 } else {
6085 AddRangeOrEscape(ranges, char_class, first, zone());
6086 }
6087 }
6088 if (!has_more()) {
6089 return ReportError(CStrVector(kUnterminated) CHECK_FAILED);
6090 }
6091 Advance();
6092 if (ranges->length() == 0) {
6093 ranges->Add(CharacterRange::Everything(), zone());
6094 is_negated = !is_negated;
6095 }
6096 return new (zone()) RegExpCharacterClass(ranges, is_negated);
6097 }
6098
6099
6100 // ----------------------------------------------------------------------------
6101 // The Parser interface.
6102
6103 bool RegExpParser::ParseRegExp(Isolate* isolate, Zone* zone,
6104 FlatStringReader* input, bool multiline,
6105 bool unicode, RegExpCompileData* result) {
6106 DCHECK(result != NULL);
6107 RegExpParser parser(input, &result->error, multiline, unicode, isolate, zone);
6108 RegExpTree* tree = parser.ParsePattern();
6109 if (parser.failed()) {
6110 DCHECK(tree == NULL);
6111 DCHECK(!result->error.is_null());
6112 } else {
6113 DCHECK(tree != NULL);
6114 DCHECK(result->error.is_null());
6115 result->tree = tree;
6116 int capture_count = parser.captures_started();
6117 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
6118 result->contains_anchor = parser.contains_anchor();
6119 result->capture_count = capture_count;
6120 }
6121 return !parser.failed();
6122 }
6123
6124
6125 bool Parser::ParseStatic(ParseInfo* info) {
6126 Parser parser(info);
6127 if (parser.Parse(info)) {
6128 info->set_language_mode(info->literal()->language_mode());
6129 return true;
6130 }
6131 return false;
6132 }
6133
6134
6135 bool Parser::Parse(ParseInfo* info) {
6136 DCHECK(info->literal() == NULL);
6137 FunctionLiteral* result = NULL;
6138 // Ok to use Isolate here; this function is only called in the main thread.
6139 DCHECK(parsing_on_main_thread_);
6140 Isolate* isolate = info->isolate();
6141 pre_parse_timer_ = isolate->counters()->pre_parse();
6142 if (FLAG_trace_parse || allow_natives() || extension_ != NULL) {
6143 // If intrinsics are allowed, the Parser cannot operate independent of the
6144 // V8 heap because of Runtime. Tell the string table to internalize strings
6145 // and values right after they're created.
6146 ast_value_factory()->Internalize(isolate);
6147 }
6148
6149 if (info->is_lazy()) {
6150 DCHECK(!info->is_eval());
6151 if (info->shared_info()->is_function()) {
6152 result = ParseLazy(isolate, info);
6153 } else {
6154 result = ParseProgram(isolate, info);
6155 }
6156 } else {
6157 SetCachedData(info);
6158 result = ParseProgram(isolate, info);
6159 }
6160 info->set_literal(result);
6161
6162 Internalize(isolate, info->script(), result == NULL);
6163 DCHECK(ast_value_factory()->IsInternalized());
6164 return (result != NULL);
6165 }
6166
6167
6168 void Parser::ParseOnBackground(ParseInfo* info) {
6169 parsing_on_main_thread_ = false;
6170
6171 DCHECK(info->literal() == NULL);
6172 FunctionLiteral* result = NULL;
6173 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
6174
6175 CompleteParserRecorder recorder;
6176 if (produce_cached_parse_data()) log_ = &recorder;
6177
6178 DCHECK(info->source_stream() != NULL);
6179 ExternalStreamingStream stream(info->source_stream(),
6180 info->source_stream_encoding());
6181 scanner_.Initialize(&stream);
6182 DCHECK(info->context().is_null() || info->context()->IsNativeContext());
6183
6184 // When streaming, we don't know the length of the source until we have parsed
6185 // it. The raw data can be UTF-8, so we wouldn't know the source length until
6186 // we have decoded it anyway even if we knew the raw data length (which we
6187 // don't). We work around this by storing all the scopes which need their end
6188 // position set at the end of the script (the top scope and possible eval
6189 // scopes) and set their end position after we know the script length.
6190 result = DoParseProgram(info);
6191
6192 info->set_literal(result);
6193
6194 // We cannot internalize on a background thread; a foreground task will take
6195 // care of calling Parser::Internalize just before compilation.
6196
6197 if (produce_cached_parse_data()) {
6198 if (result != NULL) *info->cached_data() = recorder.GetScriptData();
6199 log_ = NULL;
6200 }
6201 }
6202
6203
6204 ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
6205 return new (zone()) ParserTraits::TemplateLiteral(zone(), pos);
6206 }
6207
6208
6209 void Parser::AddTemplateSpan(TemplateLiteralState* state, bool tail) {
6210 int pos = scanner()->location().beg_pos;
6211 int end = scanner()->location().end_pos - (tail ? 1 : 2);
6212 const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory());
6213 const AstRawString* trv = scanner()->CurrentRawSymbol(ast_value_factory());
6214 Literal* cooked = factory()->NewStringLiteral(tv, pos);
6215 Literal* raw = factory()->NewStringLiteral(trv, pos);
6216 (*state)->AddTemplateSpan(cooked, raw, end, zone());
6217 }
6218
6219
6220 void Parser::AddTemplateExpression(TemplateLiteralState* state,
6221 Expression* expression) {
6222 (*state)->AddExpression(expression, zone());
6223 }
6224
6225
6226 Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
6227 Expression* tag) {
6228 TemplateLiteral* lit = *state;
6229 int pos = lit->position();
6230 const ZoneList<Expression*>* cooked_strings = lit->cooked();
6231 const ZoneList<Expression*>* raw_strings = lit->raw();
6232 const ZoneList<Expression*>* expressions = lit->expressions();
6233 DCHECK_EQ(cooked_strings->length(), raw_strings->length());
6234 DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
6235
6236 if (!tag) {
6237 // Build tree of BinaryOps to simplify code-generation
6238 Expression* expr = cooked_strings->at(0);
6239 int i = 0;
6240 while (i < expressions->length()) {
6241 Expression* sub = expressions->at(i++);
6242 Expression* cooked_str = cooked_strings->at(i);
6243
6244 // Let middle be ToString(sub).
6245 ZoneList<Expression*>* args =
6246 new (zone()) ZoneList<Expression*>(1, zone());
6247 args->Add(sub, zone());
6248 Expression* middle = factory()->NewCallRuntime(Runtime::kInlineToString,
6249 args, sub->position());
6250
6251 expr = factory()->NewBinaryOperation(
6252 Token::ADD, factory()->NewBinaryOperation(
6253 Token::ADD, expr, middle, expr->position()),
6254 cooked_str, sub->position());
6255 }
6256 return expr;
6257 } else {
6258 uint32_t hash = ComputeTemplateLiteralHash(lit);
6259
6260 int cooked_idx = function_state_->NextMaterializedLiteralIndex();
6261 int raw_idx = function_state_->NextMaterializedLiteralIndex();
6262
6263 // $getTemplateCallSite
6264 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone());
6265 args->Add(factory()->NewArrayLiteral(
6266 const_cast<ZoneList<Expression*>*>(cooked_strings),
6267 cooked_idx, is_strong(language_mode()), pos),
6268 zone());
6269 args->Add(
6270 factory()->NewArrayLiteral(
6271 const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx,
6272 is_strong(language_mode()), pos),
6273 zone());
6274
6275 // Ensure hash is suitable as a Smi value
6276 Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash)));
6277 args->Add(factory()->NewSmiLiteral(hash_obj->value(), pos), zone());
6278
6279 this->CheckPossibleEvalCall(tag, scope_);
6280 Expression* call_site = factory()->NewCallRuntime(
6281 Context::GET_TEMPLATE_CALL_SITE_INDEX, args, start);
6282
6283 // Call TagFn
6284 ZoneList<Expression*>* call_args =
6285 new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone());
6286 call_args->Add(call_site, zone());
6287 call_args->AddAll(*expressions, zone());
6288 return factory()->NewCall(tag, call_args, pos);
6289 }
6290 }
6291
6292
6293 uint32_t Parser::ComputeTemplateLiteralHash(const TemplateLiteral* lit) {
6294 const ZoneList<Expression*>* raw_strings = lit->raw();
6295 int total = raw_strings->length();
6296 DCHECK(total);
6297
6298 uint32_t running_hash = 0;
6299
6300 for (int index = 0; index < total; ++index) {
6301 if (index) {
6302 running_hash = StringHasher::ComputeRunningHashOneByte(
6303 running_hash, "${}", 3);
6304 }
6305
6306 const AstRawString* raw_string =
6307 raw_strings->at(index)->AsLiteral()->raw_value()->AsString();
6308 if (raw_string->is_one_byte()) {
6309 const char* data = reinterpret_cast<const char*>(raw_string->raw_data());
6310 running_hash = StringHasher::ComputeRunningHashOneByte(
6311 running_hash, data, raw_string->length());
6312 } else {
6313 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
6314 running_hash = StringHasher::ComputeRunningHash(running_hash, data,
6315 raw_string->length());
6316 }
6317 }
6318
6319 return running_hash;
6320 }
6321
6322
6323 ZoneList<v8::internal::Expression*>* Parser::PrepareSpreadArguments(
6324 ZoneList<v8::internal::Expression*>* list) {
6325 ZoneList<v8::internal::Expression*>* args =
6326 new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
6327 if (list->length() == 1) {
6328 // Spread-call with single spread argument produces an InternalArray
6329 // containing the values from the array.
6330 //
6331 // Function is called or constructed with the produced array of arguments
6332 //
6333 // EG: Apply(Func, Spread(spread0))
6334 ZoneList<Expression*>* spread_list =
6335 new (zone()) ZoneList<Expression*>(0, zone());
6336 spread_list->Add(list->at(0)->AsSpread()->expression(), zone());
6337 args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX,
6338 spread_list, RelocInfo::kNoPosition),
6339 zone());
6340 return args;
6341 } else {
6342 // Spread-call with multiple arguments produces array literals for each
6343 // sequences of unspread arguments, and converts each spread iterable to
6344 // an Internal array. Finally, all of these produced arrays are flattened
6345 // into a single InternalArray, containing the arguments for the call.
6346 //
6347 // EG: Apply(Func, Flatten([unspread0, unspread1], Spread(spread0),
6348 // Spread(spread1), [unspread2, unspread3]))
6349 int i = 0;
6350 int n = list->length();
6351 while (i < n) {
6352 if (!list->at(i)->IsSpread()) {
6353 ZoneList<v8::internal::Expression*>* unspread =
6354 new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
6355
6356 // Push array of unspread parameters
6357 while (i < n && !list->at(i)->IsSpread()) {
6358 unspread->Add(list->at(i++), zone());
6359 }
6360 int literal_index = function_state_->NextMaterializedLiteralIndex();
6361 args->Add(factory()->NewArrayLiteral(unspread, literal_index,
6362 is_strong(language_mode()),
6363 RelocInfo::kNoPosition),
6364 zone());
6365
6366 if (i == n) break;
6367 }
6368
6369 // Push eagerly spread argument
6370 ZoneList<v8::internal::Expression*>* spread_list =
6371 new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
6372 spread_list->Add(list->at(i++)->AsSpread()->expression(), zone());
6373 args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX,
6374 spread_list, RelocInfo::kNoPosition),
6375 zone());
6376 }
6377
6378 list = new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
6379 list->Add(factory()->NewCallRuntime(Context::SPREAD_ARGUMENTS_INDEX, args,
6380 RelocInfo::kNoPosition),
6381 zone());
6382 return list;
6383 }
6384 UNREACHABLE();
6385 }
6386
6387
6388 Expression* Parser::SpreadCall(Expression* function,
6389 ZoneList<v8::internal::Expression*>* args,
6390 int pos) {
6391 if (function->IsSuperCallReference()) {
6392 // Super calls
6393 // %reflect_construct(%GetPrototype(<this-function>), args, new.target))
6394 ZoneList<Expression*>* tmp = new (zone()) ZoneList<Expression*>(1, zone());
6395 tmp->Add(function->AsSuperCallReference()->this_function_var(), zone());
6396 Expression* get_prototype =
6397 factory()->NewCallRuntime(Runtime::kGetPrototype, tmp, pos);
6398 args->InsertAt(0, get_prototype, zone());
6399 args->Add(function->AsSuperCallReference()->new_target_var(), zone());
6400 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args,
6401 pos);
6402 } else {
6403 if (function->IsProperty()) {
6404 // Method calls
6405 if (function->AsProperty()->IsSuperAccess()) {
6406 Expression* home =
6407 ThisExpression(scope_, factory(), RelocInfo::kNoPosition);
6408 args->InsertAt(0, function, zone());
6409 args->InsertAt(1, home, zone());
6410 } else {
6411 Variable* temp =
6412 scope_->NewTemporary(ast_value_factory()->empty_string());
6413 VariableProxy* obj = factory()->NewVariableProxy(temp);
6414 Assignment* assign_obj = factory()->NewAssignment(
6415 Token::ASSIGN, obj, function->AsProperty()->obj(),
6416 RelocInfo::kNoPosition);
6417 function = factory()->NewProperty(
6418 assign_obj, function->AsProperty()->key(), RelocInfo::kNoPosition);
6419 args->InsertAt(0, function, zone());
6420 obj = factory()->NewVariableProxy(temp);
6421 args->InsertAt(1, obj, zone());
6422 }
6423 } else {
6424 // Non-method calls
6425 args->InsertAt(0, function, zone());
6426 args->InsertAt(1, factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
6427 zone());
6428 }
6429 return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos);
6430 }
6431 }
6432
6433
6434 Expression* Parser::SpreadCallNew(Expression* function,
6435 ZoneList<v8::internal::Expression*>* args,
6436 int pos) {
6437 args->InsertAt(0, function, zone());
6438
6439 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
6440 }
6441
6442
6443 void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) {
6444 v8::Isolate::UseCounterFeature feature;
6445 if (is_sloppy(mode))
6446 feature = v8::Isolate::kSloppyMode;
6447 else if (is_strong(mode))
6448 feature = v8::Isolate::kStrongMode;
6449 else if (is_strict(mode))
6450 feature = v8::Isolate::kStrictMode;
6451 else
6452 UNREACHABLE();
6453 ++use_counts_[feature];
6454 scope->SetLanguageMode(mode);
6455 }
6456
6457
6458 void Parser::RaiseLanguageMode(LanguageMode mode) {
6459 SetLanguageMode(scope_,
6460 static_cast<LanguageMode>(scope_->language_mode() | mode));
6461 }
6462
6463 } // namespace internal
6464 } // namespace v8
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/parsing/expression-classifier.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698