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