1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "src/parser.h"
9 #include "src/ast-literal-reindexer.h"
10 #include "src/bailout-reason.h"
11 #include "src/base/platform/platform.h"
12 #include "src/bootstrapper.h"
13 #include "src/char-predicates-inl.h"
14 #include "src/codegen.h"
15 #include "src/compiler.h"
16 #include "src/messages.h"
17 #include "src/preparser.h"
18 #include "src/runtime/runtime.h"
19 #include "src/scanner-character-streams.h"
20 #include "src/scopeinfo.h"
21 #include "src/string-stream.h"
26 ScriptData::ScriptData(const byte* data, int length)
27 : owns_data_(false), rejected_(false), data_(data), length_(length) {
28 if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) {
29 byte* copy = NewArray<byte>(length);
30 DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment));
31 CopyBytes(copy, data, length);
33 AcquireDataOwnership();
38 ParseInfo::ParseInfo(Zone* zone)
41 source_stream_(nullptr),
42 source_stream_encoding_(ScriptCompiler::StreamedSource::ONE_BYTE),
44 compile_options_(ScriptCompiler::kNoCompileOptions),
45 script_scope_(nullptr),
46 unicode_cache_(nullptr),
49 cached_data_(nullptr),
50 ast_value_factory_(nullptr),
55 ParseInfo::ParseInfo(Zone* zone, Handle<JSFunction> function)
56 : ParseInfo(zone, Handle<SharedFunctionInfo>(function->shared())) {
57 set_closure(function);
58 set_context(Handle<Context>(function->context()));
62 ParseInfo::ParseInfo(Zone* zone, Handle<SharedFunctionInfo> shared)
64 isolate_ = shared->GetIsolate();
67 set_hash_seed(isolate_->heap()->HashSeed());
68 set_stack_limit(isolate_->stack_guard()->real_climit());
69 set_unicode_cache(isolate_->unicode_cache());
70 set_language_mode(shared->language_mode());
71 set_shared_info(shared);
73 Handle<Script> script(Script::cast(shared->script()));
75 if (!script.is_null() && script->type()->value() == Script::TYPE_NATIVE) {
81 ParseInfo::ParseInfo(Zone* zone, Handle<Script> script) : ParseInfo(zone) {
82 isolate_ = script->GetIsolate();
84 set_hash_seed(isolate_->heap()->HashSeed());
85 set_stack_limit(isolate_->stack_guard()->real_climit());
86 set_unicode_cache(isolate_->unicode_cache());
89 if (script->type()->value() == Script::TYPE_NATIVE) {
95 RegExpBuilder::RegExpBuilder(Zone* zone)
97 pending_empty_(false),
102 , last_added_(ADD_NONE)
107 void RegExpBuilder::FlushCharacters() {
108 pending_empty_ = false;
109 if (characters_ != NULL) {
110 RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector());
112 text_.Add(atom, zone());
118 void RegExpBuilder::FlushText() {
120 int num_text = text_.length();
123 } else if (num_text == 1) {
124 terms_.Add(text_.last(), zone());
126 RegExpText* text = new(zone()) RegExpText(zone());
127 for (int i = 0; i < num_text; i++)
128 text_.Get(i)->AppendToText(text, zone());
129 terms_.Add(text, zone());
135 void RegExpBuilder::AddCharacter(uc16 c) {
136 pending_empty_ = false;
137 if (characters_ == NULL) {
138 characters_ = new(zone()) ZoneList<uc16>(4, zone());
140 characters_->Add(c, zone());
145 void RegExpBuilder::AddEmpty() {
146 pending_empty_ = true;
150 void RegExpBuilder::AddAtom(RegExpTree* term) {
151 if (term->IsEmpty()) {
155 if (term->IsTextElement()) {
157 text_.Add(term, zone());
160 terms_.Add(term, zone());
166 void RegExpBuilder::AddAssertion(RegExpTree* assert) {
168 terms_.Add(assert, zone());
173 void RegExpBuilder::NewAlternative() {
178 void RegExpBuilder::FlushTerms() {
180 int num_terms = terms_.length();
181 RegExpTree* alternative;
182 if (num_terms == 0) {
183 alternative = new (zone()) RegExpEmpty();
184 } else if (num_terms == 1) {
185 alternative = terms_.last();
187 alternative = new(zone()) RegExpAlternative(terms_.GetList(zone()));
189 alternatives_.Add(alternative, zone());
195 RegExpTree* RegExpBuilder::ToRegExp() {
197 int num_alternatives = alternatives_.length();
198 if (num_alternatives == 0) return new (zone()) RegExpEmpty();
199 if (num_alternatives == 1) return alternatives_.last();
200 return new(zone()) RegExpDisjunction(alternatives_.GetList(zone()));
204 void RegExpBuilder::AddQuantifierToAtom(
205 int min, int max, RegExpQuantifier::QuantifierType quantifier_type) {
206 if (pending_empty_) {
207 pending_empty_ = false;
211 if (characters_ != NULL) {
212 DCHECK(last_added_ == ADD_CHAR);
213 // Last atom was character.
214 Vector<const uc16> char_vector = characters_->ToConstVector();
215 int num_chars = char_vector.length();
217 Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1);
218 text_.Add(new(zone()) RegExpAtom(prefix), zone());
219 char_vector = char_vector.SubVector(num_chars - 1, num_chars);
222 atom = new(zone()) RegExpAtom(char_vector);
224 } else if (text_.length() > 0) {
225 DCHECK(last_added_ == ADD_ATOM);
226 atom = text_.RemoveLast();
228 } else if (terms_.length() > 0) {
229 DCHECK(last_added_ == ADD_ATOM);
230 atom = terms_.RemoveLast();
231 if (atom->max_match() == 0) {
232 // Guaranteed to only match an empty string.
237 terms_.Add(atom, zone());
241 // Only call immediately after adding an atom or character!
246 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone());
251 FunctionEntry ParseData::GetFunctionEntry(int start) {
252 // The current pre-data entry must be a FunctionEntry with the given
254 if ((function_index_ + FunctionEntry::kSize <= Length()) &&
255 (static_cast<int>(Data()[function_index_]) == start)) {
256 int index = function_index_;
257 function_index_ += FunctionEntry::kSize;
258 Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize);
259 return FunctionEntry(subvector);
261 return FunctionEntry();
265 int ParseData::FunctionCount() {
266 int functions_size = FunctionsSize();
267 if (functions_size < 0) return 0;
268 if (functions_size % FunctionEntry::kSize != 0) return 0;
269 return functions_size / FunctionEntry::kSize;
273 bool ParseData::IsSane() {
274 if (!IsAligned(script_data_->length(), sizeof(unsigned))) return false;
275 // Check that the header data is valid and doesn't specify
276 // point to positions outside the store.
277 int data_length = Length();
278 if (data_length < PreparseDataConstants::kHeaderSize) return false;
279 if (Magic() != PreparseDataConstants::kMagicNumber) return false;
280 if (Version() != PreparseDataConstants::kCurrentVersion) return false;
281 if (HasError()) return false;
282 // Check that the space allocated for function entries is sane.
283 int functions_size = FunctionsSize();
284 if (functions_size < 0) return false;
285 if (functions_size % FunctionEntry::kSize != 0) return false;
286 // Check that the total size has room for header and function entries.
288 PreparseDataConstants::kHeaderSize + functions_size;
289 if (data_length < minimum_size) return false;
294 void ParseData::Initialize() {
295 // Prepares state for use.
296 int data_length = Length();
297 if (data_length >= PreparseDataConstants::kHeaderSize) {
298 function_index_ = PreparseDataConstants::kHeaderSize;
303 bool ParseData::HasError() {
304 return Data()[PreparseDataConstants::kHasErrorOffset];
308 unsigned ParseData::Magic() {
309 return Data()[PreparseDataConstants::kMagicOffset];
313 unsigned ParseData::Version() {
314 return Data()[PreparseDataConstants::kVersionOffset];
318 int ParseData::FunctionsSize() {
319 return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]);
323 void Parser::SetCachedData(ParseInfo* info) {
324 if (compile_options_ == ScriptCompiler::kNoCompileOptions) {
325 cached_parse_data_ = NULL;
327 DCHECK(info->cached_data() != NULL);
328 if (compile_options_ == ScriptCompiler::kConsumeParserCache) {
329 cached_parse_data_ = ParseData::FromCachedData(*info->cached_data());
335 FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope,
336 int pos, int end_pos,
337 LanguageMode language_mode) {
338 int materialized_literal_count = -1;
339 int expected_property_count = -1;
340 int parameter_count = 0;
341 const AstRawString* name = ast_value_factory()->empty_string();
344 FunctionKind kind = call_super ? FunctionKind::kDefaultSubclassConstructor
345 : FunctionKind::kDefaultBaseConstructor;
346 Scope* function_scope = NewScope(scope, FUNCTION_SCOPE, kind);
347 function_scope->SetLanguageMode(
348 static_cast<LanguageMode>(language_mode | STRICT));
349 // Set start and end position to the same value
350 function_scope->set_start_position(pos);
351 function_scope->set_end_position(pos);
352 ZoneList<Statement*>* body = NULL;
355 AstNodeFactory function_factory(ast_value_factory());
356 FunctionState function_state(&function_state_, &scope_, function_scope,
357 kind, &function_factory);
359 body = new (zone()) ZoneList<Statement*>(call_super ? 2 : 1, zone());
360 AddAssertIsConstruct(body, pos);
362 // %_DefaultConstructorCallSuper(new.target, %GetPrototype(<this-fun>))
363 ZoneList<Expression*>* args =
364 new (zone()) ZoneList<Expression*>(2, zone());
365 VariableProxy* new_target_proxy = scope_->NewUnresolved(
366 factory(), ast_value_factory()->new_target_string(), Variable::NORMAL,
368 args->Add(new_target_proxy, zone());
369 VariableProxy* this_function_proxy = scope_->NewUnresolved(
370 factory(), ast_value_factory()->this_function_string(),
371 Variable::NORMAL, pos);
372 ZoneList<Expression*>* tmp =
373 new (zone()) ZoneList<Expression*>(1, zone());
374 tmp->Add(this_function_proxy, zone());
375 Expression* get_prototype =
376 factory()->NewCallRuntime(Runtime::kGetPrototype, tmp, pos);
377 args->Add(get_prototype, zone());
378 CallRuntime* call = factory()->NewCallRuntime(
379 Runtime::kInlineDefaultConstructorCallSuper, args, pos);
380 body->Add(factory()->NewReturnStatement(call, pos), zone());
383 materialized_literal_count = function_state.materialized_literal_count();
384 expected_property_count = function_state.expected_property_count();
387 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
388 name, ast_value_factory(), function_scope, body,
389 materialized_literal_count, expected_property_count, parameter_count,
390 FunctionLiteral::kNoDuplicateParameters,
391 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
392 FunctionLiteral::kShouldLazyCompile, kind, pos);
394 return function_literal;
398 // ----------------------------------------------------------------------------
399 // Target is a support class to facilitate manipulation of the
400 // Parser's target_stack_ (the stack of potential 'break' and
401 // 'continue' statement targets). Upon construction, a new target is
402 // added; it is removed upon destruction.
404 class Target BASE_EMBEDDED {
406 Target(Target** variable, BreakableStatement* statement)
407 : variable_(variable), statement_(statement), previous_(*variable) {
412 *variable_ = previous_;
415 Target* previous() { return previous_; }
416 BreakableStatement* statement() { return statement_; }
420 BreakableStatement* statement_;
425 class TargetScope BASE_EMBEDDED {
427 explicit TargetScope(Target** variable)
428 : variable_(variable), previous_(*variable) {
433 *variable_ = previous_;
442 // ----------------------------------------------------------------------------
443 // The CHECK_OK macro is a convenient macro to enforce error
444 // handling for functions that may fail (by returning !*ok).
446 // CAUTION: This macro appends extra statements after a call,
447 // thus it must never be used where only a single statement
448 // is correct (e.g. an if statement branch w/o braces)!
450 #define CHECK_OK ok); \
451 if (!*ok) return NULL; \
453 #define DUMMY ) // to make indentation work
456 #define CHECK_FAILED /**/); \
457 if (failed_) return NULL; \
459 #define DUMMY ) // to make indentation work
462 // ----------------------------------------------------------------------------
463 // Implementation of Parser
465 bool ParserTraits::IsEval(const AstRawString* identifier) const {
466 return identifier == parser_->ast_value_factory()->eval_string();
470 bool ParserTraits::IsArguments(const AstRawString* identifier) const {
471 return identifier == parser_->ast_value_factory()->arguments_string();
475 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const {
476 return IsEval(identifier) || IsArguments(identifier);
479 bool ParserTraits::IsUndefined(const AstRawString* identifier) const {
480 return identifier == parser_->ast_value_factory()->undefined_string();
483 bool ParserTraits::IsPrototype(const AstRawString* identifier) const {
484 return identifier == parser_->ast_value_factory()->prototype_string();
488 bool ParserTraits::IsConstructor(const AstRawString* identifier) const {
489 return identifier == parser_->ast_value_factory()->constructor_string();
493 bool ParserTraits::IsThisProperty(Expression* expression) {
494 DCHECK(expression != NULL);
495 Property* property = expression->AsProperty();
496 return property != NULL && property->obj()->IsVariableProxy() &&
497 property->obj()->AsVariableProxy()->is_this();
501 bool ParserTraits::IsIdentifier(Expression* expression) {
502 VariableProxy* operand = expression->AsVariableProxy();
503 return operand != NULL && !operand->is_this();
507 void ParserTraits::PushPropertyName(FuncNameInferrer* fni,
508 Expression* expression) {
509 if (expression->IsPropertyName()) {
510 fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
512 fni->PushLiteralName(
513 parser_->ast_value_factory()->anonymous_function_string());
518 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
520 DCHECK(left != NULL);
521 if (left->IsProperty() && right->IsFunctionLiteral()) {
522 right->AsFunctionLiteral()->set_pretenure();
527 void ParserTraits::CheckPossibleEvalCall(Expression* expression,
529 VariableProxy* callee = expression->AsVariableProxy();
530 if (callee != NULL &&
531 callee->raw_name() == parser_->ast_value_factory()->eval_string()) {
532 scope->DeclarationScope()->RecordEvalCall();
533 scope->RecordEvalCall();
538 Expression* ParserTraits::MarkExpressionAsAssigned(Expression* expression) {
539 VariableProxy* proxy =
540 expression != NULL ? expression->AsVariableProxy() : NULL;
541 if (proxy != NULL) proxy->set_is_assigned();
546 bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
547 Expression** x, Expression* y, Token::Value op, int pos,
548 AstNodeFactory* factory) {
549 if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
550 y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) {
551 double x_val = (*x)->AsLiteral()->raw_value()->AsNumber();
552 double y_val = y->AsLiteral()->raw_value()->AsNumber();
555 *x = factory->NewNumberLiteral(x_val + y_val, pos);
558 *x = factory->NewNumberLiteral(x_val - y_val, pos);
561 *x = factory->NewNumberLiteral(x_val * y_val, pos);
564 *x = factory->NewNumberLiteral(x_val / y_val, pos);
566 case Token::BIT_OR: {
567 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
568 *x = factory->NewNumberLiteral(value, pos);
571 case Token::BIT_AND: {
572 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
573 *x = factory->NewNumberLiteral(value, pos);
576 case Token::BIT_XOR: {
577 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
578 *x = factory->NewNumberLiteral(value, pos);
582 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
583 *x = factory->NewNumberLiteral(value, pos);
587 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
588 uint32_t value = DoubleToUint32(x_val) >> shift;
589 *x = factory->NewNumberLiteral(value, pos);
593 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
594 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
595 *x = factory->NewNumberLiteral(value, pos);
606 Expression* ParserTraits::BuildUnaryExpression(Expression* expression,
607 Token::Value op, int pos,
608 AstNodeFactory* factory) {
609 DCHECK(expression != NULL);
610 if (expression->IsLiteral()) {
611 const AstValue* literal = expression->AsLiteral()->raw_value();
612 if (op == Token::NOT) {
613 // Convert the literal to a boolean condition and negate it.
614 bool condition = literal->BooleanValue();
615 return factory->NewBooleanLiteral(!condition, pos);
616 } else if (literal->IsNumber()) {
617 // Compute some expressions involving only number literals.
618 double value = literal->AsNumber();
623 return factory->NewNumberLiteral(-value, pos);
625 return factory->NewNumberLiteral(~DoubleToInt32(value), pos);
631 // Desugar '+foo' => 'foo*1'
632 if (op == Token::ADD) {
633 return factory->NewBinaryOperation(
634 Token::MUL, expression, factory->NewNumberLiteral(1, pos, true), pos);
636 // The same idea for '-foo' => 'foo*(-1)'.
637 if (op == Token::SUB) {
638 return factory->NewBinaryOperation(
639 Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos);
641 // ...and one more time for '~foo' => 'foo^(~0)'.
642 if (op == Token::BIT_NOT) {
643 return factory->NewBinaryOperation(
644 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos);
646 return factory->NewUnaryOperation(op, expression, pos);
650 Expression* ParserTraits::NewThrowReferenceError(
651 MessageTemplate::Template message, int pos) {
652 return NewThrowError(Runtime::kNewReferenceError, message,
653 parser_->ast_value_factory()->empty_string(), pos);
657 Expression* ParserTraits::NewThrowSyntaxError(MessageTemplate::Template message,
658 const AstRawString* arg,
660 return NewThrowError(Runtime::kNewSyntaxError, message, arg, pos);
664 Expression* ParserTraits::NewThrowTypeError(MessageTemplate::Template message,
665 const AstRawString* arg, int pos) {
666 return NewThrowError(Runtime::kNewTypeError, message, arg, pos);
670 Expression* ParserTraits::NewThrowError(Runtime::FunctionId id,
671 MessageTemplate::Template message,
672 const AstRawString* arg, int pos) {
673 Zone* zone = parser_->zone();
674 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone);
675 args->Add(parser_->factory()->NewSmiLiteral(message, pos), zone);
676 args->Add(parser_->factory()->NewStringLiteral(arg, pos), zone);
677 CallRuntime* call_constructor =
678 parser_->factory()->NewCallRuntime(id, args, pos);
679 return parser_->factory()->NewThrow(call_constructor, pos);
683 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
684 MessageTemplate::Template message,
685 const char* arg, ParseErrorType error_type) {
686 if (parser_->stack_overflow()) {
687 // Suppress the error message (syntax error or such) in the presence of a
688 // stack overflow. The isolate allows only one pending exception at at time
689 // and we want to report the stack overflow later.
692 parser_->pending_error_handler_.ReportMessageAt(source_location.beg_pos,
693 source_location.end_pos,
694 message, arg, error_type);
698 void ParserTraits::ReportMessage(MessageTemplate::Template message,
699 const char* arg, ParseErrorType error_type) {
700 Scanner::Location source_location = parser_->scanner()->location();
701 ReportMessageAt(source_location, message, arg, error_type);
705 void ParserTraits::ReportMessage(MessageTemplate::Template message,
706 const AstRawString* arg,
707 ParseErrorType error_type) {
708 Scanner::Location source_location = parser_->scanner()->location();
709 ReportMessageAt(source_location, message, arg, error_type);
713 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
714 MessageTemplate::Template message,
715 const AstRawString* arg,
716 ParseErrorType error_type) {
717 if (parser_->stack_overflow()) {
718 // Suppress the error message (syntax error or such) in the presence of a
719 // stack overflow. The isolate allows only one pending exception at at time
720 // and we want to report the stack overflow later.
723 parser_->pending_error_handler_.ReportMessageAt(source_location.beg_pos,
724 source_location.end_pos,
725 message, arg, error_type);
729 const AstRawString* ParserTraits::GetSymbol(Scanner* scanner) {
730 const AstRawString* result =
731 parser_->scanner()->CurrentSymbol(parser_->ast_value_factory());
732 DCHECK(result != NULL);
737 const AstRawString* ParserTraits::GetNumberAsSymbol(Scanner* scanner) {
738 double double_value = parser_->scanner()->DoubleValue();
741 DoubleToCString(double_value, Vector<char>(array, arraysize(array)));
742 return parser_->ast_value_factory()->GetOneByteString(string);
746 const AstRawString* ParserTraits::GetNextSymbol(Scanner* scanner) {
747 return parser_->scanner()->NextSymbol(parser_->ast_value_factory());
751 Expression* ParserTraits::ThisExpression(Scope* scope, AstNodeFactory* factory,
753 return scope->NewUnresolved(factory,
754 parser_->ast_value_factory()->this_string(),
755 Variable::THIS, pos, pos + 4);
759 Expression* ParserTraits::SuperPropertyReference(Scope* scope,
760 AstNodeFactory* factory,
762 // this_function[home_object_symbol]
763 VariableProxy* this_function_proxy = scope->NewUnresolved(
764 factory, parser_->ast_value_factory()->this_function_string(),
765 Variable::NORMAL, pos);
766 Expression* home_object_symbol_literal =
767 factory->NewSymbolLiteral("home_object_symbol", RelocInfo::kNoPosition);
768 Expression* home_object = factory->NewProperty(
769 this_function_proxy, home_object_symbol_literal, pos);
770 return factory->NewSuperPropertyReference(
771 ThisExpression(scope, factory, pos)->AsVariableProxy(), home_object, pos);
775 Expression* ParserTraits::SuperCallReference(Scope* scope,
776 AstNodeFactory* factory, int pos) {
777 VariableProxy* new_target_proxy = scope->NewUnresolved(
778 factory, parser_->ast_value_factory()->new_target_string(),
779 Variable::NORMAL, pos);
780 VariableProxy* this_function_proxy = scope->NewUnresolved(
781 factory, parser_->ast_value_factory()->this_function_string(),
782 Variable::NORMAL, pos);
783 return factory->NewSuperCallReference(
784 ThisExpression(scope, factory, pos)->AsVariableProxy(), new_target_proxy,
785 this_function_proxy, pos);
789 Expression* ParserTraits::NewTargetExpression(Scope* scope,
790 AstNodeFactory* factory,
792 static const int kNewTargetStringLength = 10;
793 auto proxy = scope->NewUnresolved(
794 factory, parser_->ast_value_factory()->new_target_string(),
795 Variable::NORMAL, pos, pos + kNewTargetStringLength);
796 proxy->set_is_new_target();
801 Expression* ParserTraits::DefaultConstructor(bool call_super, Scope* scope,
802 int pos, int end_pos,
804 return parser_->DefaultConstructor(call_super, scope, pos, end_pos, mode);
808 Literal* ParserTraits::ExpressionFromLiteral(Token::Value token, int pos,
810 AstNodeFactory* factory) {
812 case Token::NULL_LITERAL:
813 return factory->NewNullLiteral(pos);
814 case Token::TRUE_LITERAL:
815 return factory->NewBooleanLiteral(true, pos);
816 case Token::FALSE_LITERAL:
817 return factory->NewBooleanLiteral(false, pos);
819 int value = scanner->smi_value();
820 return factory->NewSmiLiteral(value, pos);
822 case Token::NUMBER: {
823 bool has_dot = scanner->ContainsDot();
824 double value = scanner->DoubleValue();
825 return factory->NewNumberLiteral(value, pos, has_dot);
834 Expression* ParserTraits::ExpressionFromIdentifier(const AstRawString* name,
838 AstNodeFactory* factory) {
839 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name);
840 return scope->NewUnresolved(factory, name, Variable::NORMAL, start_position,
845 Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner,
846 AstNodeFactory* factory) {
847 const AstRawString* symbol = GetSymbol(scanner);
848 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol);
849 return factory->NewStringLiteral(symbol, pos);
853 Expression* ParserTraits::GetIterator(Expression* iterable,
854 AstNodeFactory* factory) {
855 Expression* iterator_symbol_literal =
856 factory->NewSymbolLiteral("iterator_symbol", RelocInfo::kNoPosition);
857 int pos = iterable->position();
859 factory->NewProperty(iterable, iterator_symbol_literal, pos);
860 Zone* zone = parser_->zone();
861 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(0, zone);
862 return factory->NewCall(prop, args, pos);
866 Literal* ParserTraits::GetLiteralTheHole(int position,
867 AstNodeFactory* factory) {
868 return factory->NewTheHoleLiteral(RelocInfo::kNoPosition);
872 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) {
873 return parser_->ParseV8Intrinsic(ok);
877 FunctionLiteral* ParserTraits::ParseFunctionLiteral(
878 const AstRawString* name, Scanner::Location function_name_location,
879 FunctionNameValidity function_name_validity, FunctionKind kind,
880 int function_token_position, FunctionLiteral::FunctionType type,
881 FunctionLiteral::ArityRestriction arity_restriction,
882 LanguageMode language_mode, bool* ok) {
883 return parser_->ParseFunctionLiteral(
884 name, function_name_location, function_name_validity, kind,
885 function_token_position, type, arity_restriction, language_mode, ok);
889 ClassLiteral* ParserTraits::ParseClassLiteral(
890 const AstRawString* name, Scanner::Location class_name_location,
891 bool name_is_strict_reserved, int pos, bool* ok) {
892 return parser_->ParseClassLiteral(name, class_name_location,
893 name_is_strict_reserved, pos, ok);
897 Parser::Parser(ParseInfo* info)
898 : ParserBase<ParserTraits>(info->zone(), &scanner_, info->stack_limit(),
899 info->extension(), info->ast_value_factory(),
901 scanner_(info->unicode_cache()),
902 reusable_preparser_(NULL),
903 original_scope_(NULL),
905 compile_options_(info->compile_options()),
906 cached_parse_data_(NULL),
907 total_preparse_skipped_(0),
908 pre_parse_timer_(NULL),
909 parsing_on_main_thread_(true) {
910 // Even though we were passed ParseInfo, we should not store it in
911 // Parser - this makes sure that Isolate is not accidentally accessed via
912 // ParseInfo during background parsing.
913 DCHECK(!info->script().is_null() || info->source_stream() != NULL);
914 set_allow_lazy(info->allow_lazy_parsing());
915 set_allow_natives(FLAG_allow_natives_syntax || info->is_native());
916 set_allow_harmony_arrow_functions(FLAG_harmony_arrow_functions);
917 set_allow_harmony_sloppy(FLAG_harmony_sloppy);
918 set_allow_harmony_sloppy_function(FLAG_harmony_sloppy_function);
919 set_allow_harmony_sloppy_let(FLAG_harmony_sloppy_let);
920 set_allow_harmony_rest_parameters(FLAG_harmony_rest_parameters);
921 set_allow_harmony_default_parameters(FLAG_harmony_default_parameters);
922 set_allow_harmony_spreadcalls(FLAG_harmony_spreadcalls);
923 set_allow_harmony_destructuring(FLAG_harmony_destructuring);
924 set_allow_harmony_spread_arrays(FLAG_harmony_spread_arrays);
925 set_allow_harmony_new_target(FLAG_harmony_new_target);
926 set_allow_strong_mode(FLAG_strong_mode);
927 set_allow_legacy_const(FLAG_legacy_const);
928 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
930 use_counts_[feature] = 0;
932 if (info->ast_value_factory() == NULL) {
933 // info takes ownership of AstValueFactory.
934 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed()));
935 info->set_ast_value_factory_owned();
936 ast_value_factory_ = info->ast_value_factory();
941 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
942 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
943 // see comment for HistogramTimerScope class.
945 // It's OK to use the Isolate & counters here, since this function is only
946 // called in the main thread.
947 DCHECK(parsing_on_main_thread_);
949 HistogramTimerScope timer_scope(isolate->counters()->parse(), true);
950 Handle<String> source(String::cast(info->script()->source()));
951 isolate->counters()->total_parse_size()->Increment(source->length());
952 base::ElapsedTimer timer;
953 if (FLAG_trace_parse) {
956 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
958 // Initialize parser state.
959 CompleteParserRecorder recorder;
961 if (produce_cached_parse_data()) {
963 } else if (consume_cached_parse_data()) {
964 cached_parse_data_->Initialize();
967 source = String::Flatten(source);
968 FunctionLiteral* result;
970 if (source->IsExternalTwoByteString()) {
971 // Notice that the stream is destroyed at the end of the branch block.
972 // The last line of the blocks can't be moved outside, even though they're
974 ExternalTwoByteStringUtf16CharacterStream stream(
975 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
976 scanner_.Initialize(&stream);
977 result = DoParseProgram(info);
979 GenericStringUtf16CharacterStream stream(source, 0, source->length());
980 scanner_.Initialize(&stream);
981 result = DoParseProgram(info);
983 if (result != NULL) {
984 DCHECK_EQ(scanner_.peek_location().beg_pos, source->length());
986 HandleSourceURLComments(isolate, info->script());
988 if (FLAG_trace_parse && result != NULL) {
989 double ms = timer.Elapsed().InMillisecondsF();
990 if (info->is_eval()) {
991 PrintF("[parsing eval");
992 } else if (info->script()->name()->IsString()) {
993 String* name = String::cast(info->script()->name());
994 base::SmartArrayPointer<char> name_chars = name->ToCString();
995 PrintF("[parsing script: %s", name_chars.get());
997 PrintF("[parsing script");
999 PrintF(" - took %0.3f ms]\n", ms);
1001 if (produce_cached_parse_data()) {
1002 if (result != NULL) *info->cached_data() = recorder.GetScriptData();
1009 FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
1010 // Note that this function can be called from the main thread or from a
1011 // background thread. We should not access anything Isolate / heap dependent
1012 // via ParseInfo, and also not pass it forward.
1013 DCHECK(scope_ == NULL);
1014 DCHECK(target_stack_ == NULL);
1016 Mode parsing_mode = FLAG_lazy && allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY;
1017 if (allow_natives() || extension_ != NULL) parsing_mode = PARSE_EAGERLY;
1019 FunctionLiteral* result = NULL;
1021 // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native
1022 // context, which will have the "this" binding for script scopes.
1023 Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
1024 info->set_script_scope(scope);
1025 if (!info->context().is_null() && !info->context()->IsNativeContext()) {
1026 scope = Scope::DeserializeScopeChain(info->isolate(), zone(),
1027 *info->context(), scope);
1028 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this
1029 // means the Parser cannot operate independent of the V8 heap. Tell the
1030 // string table to internalize strings and values right after they're
1031 // created. This kind of parsing can only be done in the main thread.
1032 DCHECK(parsing_on_main_thread_);
1033 ast_value_factory()->Internalize(info->isolate());
1035 original_scope_ = scope;
1036 if (info->is_eval()) {
1037 if (!scope->is_script_scope() || is_strict(info->language_mode())) {
1038 parsing_mode = PARSE_EAGERLY;
1040 scope = NewScope(scope, EVAL_SCOPE);
1041 } else if (info->is_module()) {
1042 scope = NewScope(scope, MODULE_SCOPE);
1045 scope->set_start_position(0);
1047 // Enter 'scope' with the given parsing mode.
1048 ParsingModeScope parsing_mode_scope(this, parsing_mode);
1049 AstNodeFactory function_factory(ast_value_factory());
1050 FunctionState function_state(&function_state_, &scope_, scope,
1051 kNormalFunction, &function_factory);
1053 scope_->SetLanguageMode(info->language_mode());
1054 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
1056 int beg_pos = scanner()->location().beg_pos;
1057 if (info->is_module()) {
1058 ParseModuleItemList(body, &ok);
1060 ParseStatementList(body, Token::EOS, &ok);
1063 // The parser will peek but not consume EOS. Our scope logically goes all
1064 // the way to the EOS, though.
1065 scope->set_end_position(scanner()->peek_location().beg_pos);
1067 if (ok && is_strict(language_mode())) {
1068 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
1070 if (ok && (is_strict(language_mode()) || allow_harmony_sloppy())) {
1071 CheckConflictingVarDeclarations(scope_, &ok);
1074 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
1075 if (body->length() != 1 ||
1076 !body->at(0)->IsExpressionStatement() ||
1077 !body->at(0)->AsExpressionStatement()->
1078 expression()->IsFunctionLiteral()) {
1079 ReportMessage(MessageTemplate::kSingleFunctionLiteral);
1085 result = factory()->NewFunctionLiteral(
1086 ast_value_factory()->empty_string(), ast_value_factory(), scope_,
1087 body, function_state.materialized_literal_count(),
1088 function_state.expected_property_count(), 0,
1089 FunctionLiteral::kNoDuplicateParameters,
1090 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval,
1091 FunctionLiteral::kShouldLazyCompile, FunctionKind::kNormalFunction,
1096 // Make sure the target stack is empty.
1097 DCHECK(target_stack_ == NULL);
1103 FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info) {
1104 // It's OK to use the Isolate & counters here, since this function is only
1105 // called in the main thread.
1106 DCHECK(parsing_on_main_thread_);
1107 HistogramTimerScope timer_scope(isolate->counters()->parse_lazy());
1108 Handle<String> source(String::cast(info->script()->source()));
1109 isolate->counters()->total_parse_size()->Increment(source->length());
1110 base::ElapsedTimer timer;
1111 if (FLAG_trace_parse) {
1114 Handle<SharedFunctionInfo> shared_info = info->shared_info();
1116 // Initialize parser state.
1117 source = String::Flatten(source);
1118 FunctionLiteral* result;
1119 if (source->IsExternalTwoByteString()) {
1120 ExternalTwoByteStringUtf16CharacterStream stream(
1121 Handle<ExternalTwoByteString>::cast(source),
1122 shared_info->start_position(),
1123 shared_info->end_position());
1124 result = ParseLazy(isolate, info, &stream);
1126 GenericStringUtf16CharacterStream stream(source,
1127 shared_info->start_position(),
1128 shared_info->end_position());
1129 result = ParseLazy(isolate, info, &stream);
1132 if (FLAG_trace_parse && result != NULL) {
1133 double ms = timer.Elapsed().InMillisecondsF();
1134 base::SmartArrayPointer<char> name_chars =
1135 result->debug_name()->ToCString();
1136 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
1142 FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info,
1143 Utf16CharacterStream* source) {
1144 Handle<SharedFunctionInfo> shared_info = info->shared_info();
1145 scanner_.Initialize(source);
1146 DCHECK(scope_ == NULL);
1147 DCHECK(target_stack_ == NULL);
1149 Handle<String> name(String::cast(shared_info->name()));
1150 DCHECK(ast_value_factory());
1151 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
1152 const AstRawString* raw_name = ast_value_factory()->GetString(name);
1153 fni_->PushEnclosingName(raw_name);
1155 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1157 // Place holder for the result.
1158 FunctionLiteral* result = NULL;
1161 // Parse the function literal.
1162 Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
1163 info->set_script_scope(scope);
1164 if (!info->closure().is_null()) {
1165 // Ok to use Isolate here, since lazy function parsing is only done in the
1167 DCHECK(parsing_on_main_thread_);
1168 scope = Scope::DeserializeScopeChain(isolate, zone(),
1169 info->closure()->context(), scope);
1171 original_scope_ = scope;
1172 AstNodeFactory function_factory(ast_value_factory());
1173 FunctionState function_state(&function_state_, &scope_, scope,
1174 shared_info->kind(), &function_factory);
1175 DCHECK(is_sloppy(scope->language_mode()) ||
1176 is_strict(info->language_mode()));
1177 DCHECK(info->language_mode() == shared_info->language_mode());
1178 FunctionLiteral::FunctionType function_type = shared_info->is_expression()
1179 ? (shared_info->is_anonymous()
1180 ? FunctionLiteral::ANONYMOUS_EXPRESSION
1181 : FunctionLiteral::NAMED_EXPRESSION)
1182 : FunctionLiteral::DECLARATION;
1185 if (shared_info->is_arrow()) {
1187 NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
1188 scope->SetLanguageMode(shared_info->language_mode());
1189 scope->set_start_position(shared_info->start_position());
1190 ExpressionClassifier formals_classifier;
1191 ParserFormalParameters formals(scope);
1192 Checkpoint checkpoint(this);
1194 // Parsing patterns as variable reference expression creates
1195 // NewUnresolved references in current scope. Entrer arrow function
1196 // scope for formal parameter parsing.
1197 BlockState block_state(&scope_, scope);
1198 if (Check(Token::LPAREN)) {
1199 // '(' StrictFormalParameters ')'
1200 ParseFormalParameterList(&formals, &formals_classifier, &ok);
1201 if (ok) ok = Check(Token::RPAREN);
1203 // BindingIdentifier
1204 ParseFormalParameter(&formals, &formals_classifier, &ok);
1206 DeclareFormalParameter(formals.scope, formals.at(0),
1207 &formals_classifier);
1213 checkpoint.Restore(&formals.materialized_literals_count);
1214 Expression* expression =
1215 ParseArrowFunctionLiteral(formals, formals_classifier, &ok);
1217 // Scanning must end at the same position that was recorded
1218 // previously. If not, parsing has been interrupted due to a stack
1219 // overflow, at which point the partially parsed arrow function
1220 // concise body happens to be a valid expression. This is a problem
1221 // only for arrow functions with single expression bodies, since there
1222 // is no end token such as "}" for normal functions.
1223 if (scanner()->location().end_pos == shared_info->end_position()) {
1224 // The pre-parser saw an arrow function here, so the full parser
1225 // must produce a FunctionLiteral.
1226 DCHECK(expression->IsFunctionLiteral());
1227 result = expression->AsFunctionLiteral();
1233 } else if (shared_info->is_default_constructor()) {
1234 result = DefaultConstructor(IsSubclassConstructor(shared_info->kind()),
1235 scope, shared_info->start_position(),
1236 shared_info->end_position(),
1237 shared_info->language_mode());
1239 result = ParseFunctionLiteral(
1240 raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck,
1241 shared_info->kind(), RelocInfo::kNoPosition, function_type,
1242 FunctionLiteral::NORMAL_ARITY, shared_info->language_mode(), &ok);
1244 // Make sure the results agree.
1245 DCHECK(ok == (result != NULL));
1248 // Make sure the target stack is empty.
1249 DCHECK(target_stack_ == NULL);
1251 if (result != NULL) {
1252 Handle<String> inferred_name(shared_info->inferred_name());
1253 result->set_inferred_name(inferred_name);
1259 void* Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token,
1262 // (StatementListItem)* <end_token>
1264 // Allocate a target stack to use for this set of source
1265 // elements. This way, all scripts and functions get their own
1266 // target stack thus avoiding illegal breaks and continues across
1268 TargetScope scope(&this->target_stack_);
1270 DCHECK(body != NULL);
1271 bool directive_prologue = true; // Parsing directive prologue.
1273 while (peek() != end_token) {
1274 if (directive_prologue && peek() != Token::STRING) {
1275 directive_prologue = false;
1278 Scanner::Location token_loc = scanner()->peek_location();
1279 Scanner::Location old_this_loc = function_state_->this_location();
1280 Scanner::Location old_super_loc = function_state_->super_location();
1281 Statement* stat = ParseStatementListItem(CHECK_OK);
1283 if (is_strong(language_mode()) &&
1284 scope_->is_function_scope() &&
1285 i::IsConstructor(function_state_->kind())) {
1286 Scanner::Location this_loc = function_state_->this_location();
1287 Scanner::Location super_loc = function_state_->super_location();
1288 if (this_loc.beg_pos != old_this_loc.beg_pos &&
1289 this_loc.beg_pos != token_loc.beg_pos) {
1290 ReportMessageAt(this_loc, MessageTemplate::kStrongConstructorThis);
1294 if (super_loc.beg_pos != old_super_loc.beg_pos &&
1295 super_loc.beg_pos != token_loc.beg_pos) {
1296 ReportMessageAt(super_loc, MessageTemplate::kStrongConstructorSuper);
1302 if (stat == NULL || stat->IsEmpty()) {
1303 directive_prologue = false; // End of directive prologue.
1307 if (directive_prologue) {
1308 // A shot at a directive.
1309 ExpressionStatement* e_stat;
1311 // Still processing directive prologue?
1312 if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1313 (literal = e_stat->expression()->AsLiteral()) != NULL &&
1314 literal->raw_value()->IsString()) {
1315 // Check "use strict" directive (ES5 14.1), "use asm" directive, and
1316 // "use strong" directive (experimental).
1317 bool use_strict_found =
1318 literal->raw_value()->AsString() ==
1319 ast_value_factory()->use_strict_string() &&
1320 token_loc.end_pos - token_loc.beg_pos ==
1321 ast_value_factory()->use_strict_string()->length() + 2;
1322 bool use_strong_found =
1323 allow_strong_mode() &&
1324 literal->raw_value()->AsString() ==
1325 ast_value_factory()->use_strong_string() &&
1326 token_loc.end_pos - token_loc.beg_pos ==
1327 ast_value_factory()->use_strong_string()->length() + 2;
1328 if (use_strict_found || use_strong_found) {
1329 // Strong mode implies strict mode. If there are several "use strict"
1330 // / "use strong" directives, do the strict mode changes only once.
1331 if (is_sloppy(scope_->language_mode())) {
1332 scope_->SetLanguageMode(
1333 static_cast<LanguageMode>(scope_->language_mode() | STRICT));
1336 if (use_strong_found) {
1337 scope_->SetLanguageMode(
1338 static_cast<LanguageMode>(scope_->language_mode() | STRONG));
1339 if (i::IsConstructor(function_state_->kind())) {
1340 // "use strong" cannot occur in a class constructor body, to avoid
1341 // unintuitive strong class object semantics.
1342 ParserTraits::ReportMessageAt(
1343 token_loc, MessageTemplate::kStrongConstructorDirective);
1348 if (!scope_->HasSimpleParameters()) {
1349 // TC39 deemed "use strict" directives to be an error when occurring
1350 // in the body of a function with non-simple parameter list, on
1351 // 29/7/2015. https://goo.gl/ueA7Ln
1353 // In V8, this also applies to "use strong " directives.
1354 const AstRawString* string = literal->raw_value()->AsString();
1355 ParserTraits::ReportMessageAt(
1356 token_loc, MessageTemplate::kIllegalLanguageModeDirective,
1361 // Because declarations in strict eval code don't leak into the scope
1362 // of the eval call, it is likely that functions declared in strict
1363 // eval code will be used within the eval code, so lazy parsing is
1364 // probably not a win.
1365 if (scope_->is_eval_scope()) mode_ = PARSE_EAGERLY;
1366 } else if (literal->raw_value()->AsString() ==
1367 ast_value_factory()->use_asm_string() &&
1368 token_loc.end_pos - token_loc.beg_pos ==
1369 ast_value_factory()->use_asm_string()->length() + 2) {
1370 // Store the usage count; The actual use counter on the isolate is
1371 // incremented after parsing is done.
1372 ++use_counts_[v8::Isolate::kUseAsm];
1373 scope_->SetAsmModule();
1376 // End of the directive prologue.
1377 directive_prologue = false;
1381 body->Add(stat, zone());
1388 Statement* Parser::ParseStatementListItem(bool* ok) {
1389 // (Ecma 262 6th Edition, 13.1):
1390 // StatementListItem:
1394 if (peek() != Token::CLASS) {
1395 // No more classes follow; reset the start position for the consecutive
1396 // class declaration group.
1397 scope_->set_class_declaration_group_start(-1);
1401 case Token::FUNCTION:
1402 return ParseFunctionDeclaration(NULL, ok);
1404 if (scope_->class_declaration_group_start() < 0) {
1405 scope_->set_class_declaration_group_start(
1406 scanner()->peek_location().beg_pos);
1408 return ParseClassDeclaration(NULL, ok);
1410 if (allow_const()) {
1411 return ParseVariableStatement(kStatementListItem, NULL, ok);
1415 return ParseVariableStatement(kStatementListItem, NULL, ok);
1417 if (IsNextLetKeyword()) {
1418 return ParseVariableStatement(kStatementListItem, NULL, ok);
1424 return ParseStatement(NULL, ok);
1428 Statement* Parser::ParseModuleItem(bool* ok) {
1429 // (Ecma 262 6th Edition, 15.2):
1431 // ImportDeclaration
1432 // ExportDeclaration
1433 // StatementListItem
1437 return ParseImportDeclaration(ok);
1439 return ParseExportDeclaration(ok);
1441 return ParseStatementListItem(ok);
1446 void* Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) {
1447 // (Ecma 262 6th Edition, 15.2):
1454 DCHECK(scope_->is_module_scope());
1455 scope_->SetLanguageMode(
1456 static_cast<LanguageMode>(scope_->language_mode() | STRICT));
1458 while (peek() != Token::EOS) {
1459 Statement* stat = ParseModuleItem(CHECK_OK);
1460 if (stat && !stat->IsEmpty()) {
1461 body->Add(stat, zone());
1465 // Check that all exports are bound.
1466 ModuleDescriptor* descriptor = scope_->module();
1467 for (ModuleDescriptor::Iterator it = descriptor->iterator(); !it.done();
1469 if (scope_->LookupLocal(it.local_name()) == NULL) {
1470 // TODO(adamk): Pass both local_name and export_name once ParserTraits
1471 // supports multiple arg error messages.
1472 // Also try to report this at a better location.
1473 ParserTraits::ReportMessage(MessageTemplate::kModuleExportUndefined,
1480 scope_->module()->Freeze();
1485 const AstRawString* Parser::ParseModuleSpecifier(bool* ok) {
1486 // ModuleSpecifier :
1489 Expect(Token::STRING, CHECK_OK);
1490 return GetSymbol(scanner());
1494 void* Parser::ParseExportClause(ZoneList<const AstRawString*>* export_names,
1495 ZoneList<Scanner::Location>* export_locations,
1496 ZoneList<const AstRawString*>* local_names,
1497 Scanner::Location* reserved_loc, bool* ok) {
1500 // '{' ExportsList '}'
1501 // '{' ExportsList ',' '}'
1505 // ExportsList ',' ExportSpecifier
1507 // ExportSpecifier :
1509 // IdentifierName 'as' IdentifierName
1511 Expect(Token::LBRACE, CHECK_OK);
1513 Token::Value name_tok;
1514 while ((name_tok = peek()) != Token::RBRACE) {
1515 // Keep track of the first reserved word encountered in case our
1516 // caller needs to report an error.
1517 if (!reserved_loc->IsValid() &&
1518 !Token::IsIdentifier(name_tok, STRICT, false)) {
1519 *reserved_loc = scanner()->location();
1521 const AstRawString* local_name = ParseIdentifierName(CHECK_OK);
1522 const AstRawString* export_name = NULL;
1523 if (CheckContextualKeyword(CStrVector("as"))) {
1524 export_name = ParseIdentifierName(CHECK_OK);
1526 if (export_name == NULL) {
1527 export_name = local_name;
1529 export_names->Add(export_name, zone());
1530 local_names->Add(local_name, zone());
1531 export_locations->Add(scanner()->location(), zone());
1532 if (peek() == Token::RBRACE) break;
1533 Expect(Token::COMMA, CHECK_OK);
1536 Expect(Token::RBRACE, CHECK_OK);
1542 ZoneList<ImportDeclaration*>* Parser::ParseNamedImports(int pos, bool* ok) {
1545 // '{' ImportsList '}'
1546 // '{' ImportsList ',' '}'
1550 // ImportsList ',' ImportSpecifier
1552 // ImportSpecifier :
1553 // BindingIdentifier
1554 // IdentifierName 'as' BindingIdentifier
1556 Expect(Token::LBRACE, CHECK_OK);
1558 ZoneList<ImportDeclaration*>* result =
1559 new (zone()) ZoneList<ImportDeclaration*>(1, zone());
1560 while (peek() != Token::RBRACE) {
1561 const AstRawString* import_name = ParseIdentifierName(CHECK_OK);
1562 const AstRawString* local_name = import_name;
1563 // In the presence of 'as', the left-side of the 'as' can
1564 // be any IdentifierName. But without 'as', it must be a valid
1565 // BindingIdentifier.
1566 if (CheckContextualKeyword(CStrVector("as"))) {
1567 local_name = ParseIdentifierName(CHECK_OK);
1569 if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false)) {
1571 ReportMessage(MessageTemplate::kUnexpectedReserved);
1573 } else if (IsEvalOrArguments(local_name)) {
1575 ReportMessage(MessageTemplate::kStrictEvalArguments);
1577 } else if (is_strong(language_mode()) && IsUndefined(local_name)) {
1579 ReportMessage(MessageTemplate::kStrongUndefined);
1582 VariableProxy* proxy = NewUnresolved(local_name, IMPORT);
1583 ImportDeclaration* declaration =
1584 factory()->NewImportDeclaration(proxy, import_name, NULL, scope_, pos);
1585 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
1586 result->Add(declaration, zone());
1587 if (peek() == Token::RBRACE) break;
1588 Expect(Token::COMMA, CHECK_OK);
1591 Expect(Token::RBRACE, CHECK_OK);
1597 Statement* Parser::ParseImportDeclaration(bool* ok) {
1598 // ImportDeclaration :
1599 // 'import' ImportClause 'from' ModuleSpecifier ';'
1600 // 'import' ModuleSpecifier ';'
1605 // ImportedDefaultBinding
1606 // ImportedDefaultBinding ',' NameSpaceImport
1607 // ImportedDefaultBinding ',' NamedImports
1609 // NameSpaceImport :
1610 // '*' 'as' ImportedBinding
1612 int pos = peek_position();
1613 Expect(Token::IMPORT, CHECK_OK);
1615 Token::Value tok = peek();
1617 // 'import' ModuleSpecifier ';'
1618 if (tok == Token::STRING) {
1619 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1620 scope_->module()->AddModuleRequest(module_specifier, zone());
1621 ExpectSemicolon(CHECK_OK);
1622 return factory()->NewEmptyStatement(pos);
1625 // Parse ImportedDefaultBinding if present.
1626 ImportDeclaration* import_default_declaration = NULL;
1627 if (tok != Token::MUL && tok != Token::LBRACE) {
1628 const AstRawString* local_name =
1629 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
1630 VariableProxy* proxy = NewUnresolved(local_name, IMPORT);
1631 import_default_declaration = factory()->NewImportDeclaration(
1632 proxy, ast_value_factory()->default_string(), NULL, scope_, pos);
1633 Declare(import_default_declaration, DeclarationDescriptor::NORMAL, true,
1637 const AstRawString* module_instance_binding = NULL;
1638 ZoneList<ImportDeclaration*>* named_declarations = NULL;
1639 if (import_default_declaration == NULL || Check(Token::COMMA)) {
1642 Consume(Token::MUL);
1643 ExpectContextualKeyword(CStrVector("as"), CHECK_OK);
1644 module_instance_binding =
1645 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
1646 // TODO(ES6): Add an appropriate declaration.
1651 named_declarations = ParseNamedImports(pos, CHECK_OK);
1656 ReportUnexpectedToken(scanner()->current_token());
1661 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1662 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1663 scope_->module()->AddModuleRequest(module_specifier, zone());
1665 if (module_instance_binding != NULL) {
1666 // TODO(ES6): Set the module specifier for the module namespace binding.
1669 if (import_default_declaration != NULL) {
1670 import_default_declaration->set_module_specifier(module_specifier);
1673 if (named_declarations != NULL) {
1674 for (int i = 0; i < named_declarations->length(); ++i) {
1675 named_declarations->at(i)->set_module_specifier(module_specifier);
1679 ExpectSemicolon(CHECK_OK);
1680 return factory()->NewEmptyStatement(pos);
1684 Statement* Parser::ParseExportDefault(bool* ok) {
1685 // Supports the following productions, starting after the 'default' token:
1686 // 'export' 'default' FunctionDeclaration
1687 // 'export' 'default' ClassDeclaration
1688 // 'export' 'default' AssignmentExpression[In] ';'
1690 Expect(Token::DEFAULT, CHECK_OK);
1691 Scanner::Location default_loc = scanner()->location();
1693 ZoneList<const AstRawString*> names(1, zone());
1694 Statement* result = NULL;
1696 case Token::FUNCTION:
1697 // TODO(ES6): Support parsing anonymous function declarations here.
1698 result = ParseFunctionDeclaration(&names, CHECK_OK);
1702 // TODO(ES6): Support parsing anonymous class declarations here.
1703 result = ParseClassDeclaration(&names, CHECK_OK);
1707 int pos = peek_position();
1708 ExpressionClassifier classifier;
1709 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK);
1710 ValidateExpression(&classifier, CHECK_OK);
1712 ExpectSemicolon(CHECK_OK);
1713 result = factory()->NewExpressionStatement(expr, pos);
1718 const AstRawString* default_string = ast_value_factory()->default_string();
1720 DCHECK_LE(names.length(), 1);
1721 if (names.length() == 1) {
1722 scope_->module()->AddLocalExport(default_string, names.first(), zone(), ok);
1724 ParserTraits::ReportMessageAt(
1725 default_loc, MessageTemplate::kDuplicateExport, default_string);
1729 // TODO(ES6): Assign result to a const binding with the name "*default*"
1730 // and add an export entry with "*default*" as the local name.
1737 Statement* Parser::ParseExportDeclaration(bool* ok) {
1738 // ExportDeclaration:
1739 // 'export' '*' 'from' ModuleSpecifier ';'
1740 // 'export' ExportClause ('from' ModuleSpecifier)? ';'
1741 // 'export' VariableStatement
1742 // 'export' Declaration
1743 // 'export' 'default' ... (handled in ParseExportDefault)
1745 int pos = peek_position();
1746 Expect(Token::EXPORT, CHECK_OK);
1748 Statement* result = NULL;
1749 ZoneList<const AstRawString*> names(1, zone());
1751 case Token::DEFAULT:
1752 return ParseExportDefault(ok);
1755 Consume(Token::MUL);
1756 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1757 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1758 scope_->module()->AddModuleRequest(module_specifier, zone());
1759 // TODO(ES6): scope_->module()->AddStarExport(...)
1760 ExpectSemicolon(CHECK_OK);
1761 return factory()->NewEmptyStatement(pos);
1764 case Token::LBRACE: {
1765 // There are two cases here:
1767 // 'export' ExportClause ';'
1769 // 'export' ExportClause FromClause ';'
1771 // In the first case, the exported identifiers in ExportClause must
1772 // not be reserved words, while in the latter they may be. We
1773 // pass in a location that gets filled with the first reserved word
1774 // encountered, and then throw a SyntaxError if we are in the
1775 // non-FromClause case.
1776 Scanner::Location reserved_loc = Scanner::Location::invalid();
1777 ZoneList<const AstRawString*> export_names(1, zone());
1778 ZoneList<Scanner::Location> export_locations(1, zone());
1779 ZoneList<const AstRawString*> local_names(1, zone());
1780 ParseExportClause(&export_names, &export_locations, &local_names,
1781 &reserved_loc, CHECK_OK);
1782 const AstRawString* indirect_export_module_specifier = NULL;
1783 if (CheckContextualKeyword(CStrVector("from"))) {
1784 indirect_export_module_specifier = ParseModuleSpecifier(CHECK_OK);
1785 } else if (reserved_loc.IsValid()) {
1786 // No FromClause, so reserved words are invalid in ExportClause.
1788 ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
1791 ExpectSemicolon(CHECK_OK);
1792 const int length = export_names.length();
1793 DCHECK_EQ(length, local_names.length());
1794 DCHECK_EQ(length, export_locations.length());
1795 if (indirect_export_module_specifier == NULL) {
1796 for (int i = 0; i < length; ++i) {
1797 scope_->module()->AddLocalExport(export_names[i], local_names[i],
1800 ParserTraits::ReportMessageAt(export_locations[i],
1801 MessageTemplate::kDuplicateExport,
1807 scope_->module()->AddModuleRequest(indirect_export_module_specifier,
1809 for (int i = 0; i < length; ++i) {
1810 // TODO(ES6): scope_->module()->AddIndirectExport(...);(
1813 return factory()->NewEmptyStatement(pos);
1816 case Token::FUNCTION:
1817 result = ParseFunctionDeclaration(&names, CHECK_OK);
1821 result = ParseClassDeclaration(&names, CHECK_OK);
1827 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK);
1832 ReportUnexpectedToken(scanner()->current_token());
1836 // Extract declared names into export declarations.
1837 ModuleDescriptor* descriptor = scope_->module();
1838 for (int i = 0; i < names.length(); ++i) {
1839 descriptor->AddLocalExport(names[i], names[i], zone(), ok);
1841 // TODO(adamk): Possibly report this error at the right place.
1842 ParserTraits::ReportMessage(MessageTemplate::kDuplicateExport, names[i]);
1847 DCHECK_NOT_NULL(result);
1852 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels,
1858 if (peek() == Token::SEMICOLON) {
1860 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1862 return ParseSubStatement(labels, ok);
1866 Statement* Parser::ParseSubStatement(ZoneList<const AstRawString*>* labels,
1870 // VariableStatement
1872 // ExpressionStatement
1874 // IterationStatement
1875 // ContinueStatement
1879 // LabelledStatement
1883 // DebuggerStatement
1885 // Note: Since labels can only be used by 'break' and 'continue'
1886 // statements, which themselves are only valid within blocks,
1887 // iterations or 'switch' statements (i.e., BreakableStatements),
1888 // labels can be simply ignored in all other cases; except for
1889 // trivial labeled break statements 'label: break label' which is
1890 // parsed into an empty statement.
1893 return ParseBlock(labels, ok);
1895 case Token::SEMICOLON:
1896 if (is_strong(language_mode())) {
1897 ReportMessageAt(scanner()->peek_location(),
1898 MessageTemplate::kStrongEmpty);
1903 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1906 return ParseIfStatement(labels, ok);
1909 return ParseDoWhileStatement(labels, ok);
1912 return ParseWhileStatement(labels, ok);
1915 return ParseForStatement(labels, ok);
1917 case Token::CONTINUE:
1922 // These statements must have their labels preserved in an enclosing
1924 if (labels == NULL) {
1925 return ParseStatementAsUnlabelled(labels, ok);
1928 factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition);
1929 Target target(&this->target_stack_, result);
1930 Statement* statement = ParseStatementAsUnlabelled(labels, CHECK_OK);
1931 if (result) result->AddStatement(statement, zone());
1937 return ParseWithStatement(labels, ok);
1940 return ParseSwitchStatement(labels, ok);
1942 case Token::FUNCTION: {
1943 // FunctionDeclaration is only allowed in the context of SourceElements
1944 // (Ecma 262 5th Edition, clause 14):
1947 // FunctionDeclaration
1948 // Common language extension is to allow function declaration in place
1949 // of any statement. This language extension is disabled in strict mode.
1951 // In Harmony mode, this case also handles the extension:
1953 // GeneratorDeclaration
1954 if (is_strict(language_mode())) {
1955 ReportMessageAt(scanner()->peek_location(),
1956 MessageTemplate::kStrictFunction);
1960 return ParseFunctionDeclaration(NULL, ok);
1963 case Token::DEBUGGER:
1964 return ParseDebuggerStatement(ok);
1967 return ParseVariableStatement(kStatement, NULL, ok);
1970 // In ES6 CONST is not allowed as a Statement, only as a
1971 // LexicalDeclaration, however we continue to allow it in sloppy mode for
1972 // backwards compatibility.
1973 if (is_sloppy(language_mode()) && allow_legacy_const()) {
1974 return ParseVariableStatement(kStatement, NULL, ok);
1979 return ParseExpressionOrLabelledStatement(labels, ok);
1983 Statement* Parser::ParseStatementAsUnlabelled(
1984 ZoneList<const AstRawString*>* labels, bool* ok) {
1986 case Token::CONTINUE:
1987 return ParseContinueStatement(ok);
1990 return ParseBreakStatement(labels, ok);
1993 return ParseReturnStatement(ok);
1996 return ParseThrowStatement(ok);
1999 return ParseTryStatement(ok);
2008 VariableProxy* Parser::NewUnresolved(const AstRawString* name,
2009 VariableMode mode) {
2010 // If we are inside a function, a declaration of a var/const variable is a
2011 // truly local variable, and the scope of the variable is always the function
2013 // Let/const variables in harmony mode are always added to the immediately
2015 return DeclarationScope(mode)->NewUnresolved(
2016 factory(), name, Variable::NORMAL, scanner()->location().beg_pos,
2017 scanner()->location().end_pos);
2021 Variable* Parser::Declare(Declaration* declaration,
2022 DeclarationDescriptor::Kind declaration_kind,
2023 bool resolve, bool* ok, Scope* scope) {
2024 VariableProxy* proxy = declaration->proxy();
2025 DCHECK(proxy->raw_name() != NULL);
2026 const AstRawString* name = proxy->raw_name();
2027 VariableMode mode = declaration->mode();
2028 if (scope == nullptr) scope = scope_;
2029 Scope* declaration_scope =
2030 IsLexicalVariableMode(mode) ? scope : scope->DeclarationScope();
2031 Variable* var = NULL;
2033 // If a suitable scope exists, then we can statically declare this
2034 // variable and also set its mode. In any case, a Declaration node
2035 // will be added to the scope so that the declaration can be added
2036 // to the corresponding activation frame at runtime if necessary.
2037 // For instance, var declarations inside a sloppy eval scope need
2038 // to be added to the calling function context. Similarly, strict
2039 // mode eval scope and lexical eval bindings do not leak variable
2040 // declarations to the caller's scope so we declare all locals, too.
2041 if (declaration_scope->is_function_scope() ||
2042 declaration_scope->is_block_scope() ||
2043 declaration_scope->is_module_scope() ||
2044 declaration_scope->is_script_scope() ||
2045 (declaration_scope->is_eval_scope() &&
2046 (is_strict(declaration_scope->language_mode()) ||
2047 IsLexicalVariableMode(mode)))) {
2048 // Declare the variable in the declaration scope.
2049 var = declaration_scope->LookupLocal(name);
2051 // Declare the name.
2052 Variable::Kind kind = Variable::NORMAL;
2053 int declaration_group_start = -1;
2054 if (declaration->IsFunctionDeclaration()) {
2055 kind = Variable::FUNCTION;
2056 } else if (declaration->IsVariableDeclaration() &&
2057 declaration->AsVariableDeclaration()->is_class_declaration()) {
2058 kind = Variable::CLASS;
2059 declaration_group_start =
2060 declaration->AsVariableDeclaration()->declaration_group_start();
2062 var = declaration_scope->DeclareLocal(
2063 name, mode, declaration->initialization(), kind, kNotAssigned,
2064 declaration_group_start);
2065 } else if (IsLexicalVariableMode(mode) ||
2066 IsLexicalVariableMode(var->mode()) ||
2067 ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) &&
2068 !declaration_scope->is_script_scope())) {
2069 // The name was declared in this scope before; check for conflicting
2070 // re-declarations. We have a conflict if either of the declarations is
2071 // not a var (in script scope, we also have to ignore legacy const for
2072 // compatibility). There is similar code in runtime.cc in the Declare
2073 // functions. The function CheckConflictingVarDeclarations checks for
2074 // var and let bindings from different scopes whereas this is a check for
2075 // conflicting declarations within the same scope. This check also covers
2078 // function () { let x; { var x; } }
2080 // because the var declaration is hoisted to the function scope where 'x'
2081 // is already bound.
2082 DCHECK(IsDeclaredVariableMode(var->mode()));
2083 if (is_strict(language_mode()) || allow_harmony_sloppy()) {
2084 // In harmony we treat re-declarations as early errors. See
2085 // ES5 16 for a definition of early errors.
2086 if (declaration_kind == DeclarationDescriptor::NORMAL) {
2087 ParserTraits::ReportMessage(MessageTemplate::kVarRedeclaration, name);
2089 ParserTraits::ReportMessage(MessageTemplate::kParamDupe);
2094 Expression* expression = NewThrowSyntaxError(
2095 MessageTemplate::kVarRedeclaration, name, declaration->position());
2096 declaration_scope->SetIllegalRedeclaration(expression);
2097 } else if (mode == VAR) {
2098 var->set_maybe_assigned();
2100 } else if (declaration_scope->is_eval_scope() &&
2101 is_sloppy(declaration_scope->language_mode()) &&
2102 !IsLexicalVariableMode(mode)) {
2103 // In a var binding in a sloppy direct eval, pollute the enclosing scope
2104 // with this new binding by doing the following:
2105 // The proxy is bound to a lookup variable to force a dynamic declaration
2106 // using the DeclareLookupSlot runtime function.
2107 Variable::Kind kind = Variable::NORMAL;
2108 // TODO(sigurds) figure out if kNotAssigned is OK here
2109 var = new (zone()) Variable(declaration_scope, name, mode, kind,
2110 declaration->initialization(), kNotAssigned);
2111 var->AllocateTo(VariableLocation::LOOKUP, -1);
2116 // We add a declaration node for every declaration. The compiler
2117 // will only generate code if necessary. In particular, declarations
2118 // for inner local variables that do not represent functions won't
2119 // result in any generated code.
2121 // Note that we always add an unresolved proxy even if it's not
2122 // used, simply because we don't know in this method (w/o extra
2123 // parameters) if the proxy is needed or not. The proxy will be
2124 // bound during variable resolution time unless it was pre-bound
2127 // WARNING: This will lead to multiple declaration nodes for the
2128 // same variable if it is declared several times. This is not a
2129 // semantic issue as long as we keep the source order, but it may be
2130 // a performance issue since it may lead to repeated
2131 // RuntimeHidden_DeclareLookupSlot calls.
2132 declaration_scope->AddDeclaration(declaration);
2134 if (mode == CONST_LEGACY && declaration_scope->is_script_scope()) {
2135 // For global const variables we bind the proxy to a variable.
2136 DCHECK(resolve); // should be set by all callers
2137 Variable::Kind kind = Variable::NORMAL;
2138 var = new (zone()) Variable(declaration_scope, name, mode, kind,
2139 kNeedsInitialization, kNotAssigned);
2142 // If requested and we have a local variable, bind the proxy to the variable
2143 // at parse-time. This is used for functions (and consts) declared inside
2144 // statements: the corresponding function (or const) variable must be in the
2145 // function scope and not a statement-local scope, e.g. as provided with a
2146 // 'with' statement:
2152 // which is translated into:
2155 // // in this case this is not: 'var f; f = function () {};'
2156 // var f = function () {};
2159 // Note that if 'f' is accessed from inside the 'with' statement, it
2160 // will be allocated in the context (because we must be able to look
2161 // it up dynamically) but it will also be accessed statically, i.e.,
2162 // with a context slot index and a context chain length for this
2163 // initialization code. Thus, inside the 'with' statement, we need
2164 // both access to the static and the dynamic context chain; the
2165 // runtime needs to provide both.
2166 if (resolve && var != NULL) {
2173 // Language extension which is only enabled for source files loaded
2174 // through the API's extension mechanism. A native function
2175 // declaration is resolved by looking up the function through a
2176 // callback provided by the extension.
2177 Statement* Parser::ParseNativeDeclaration(bool* ok) {
2178 int pos = peek_position();
2179 Expect(Token::FUNCTION, CHECK_OK);
2180 // Allow "eval" or "arguments" for backward compatibility.
2181 const AstRawString* name =
2182 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2183 Expect(Token::LPAREN, CHECK_OK);
2184 bool done = (peek() == Token::RPAREN);
2186 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2187 done = (peek() == Token::RPAREN);
2189 Expect(Token::COMMA, CHECK_OK);
2192 Expect(Token::RPAREN, CHECK_OK);
2193 Expect(Token::SEMICOLON, CHECK_OK);
2195 // Make sure that the function containing the native declaration
2196 // isn't lazily compiled. The extension structures are only
2197 // accessible while parsing the first time not when reparsing
2198 // because of lazy compilation.
2199 DeclarationScope(VAR)->ForceEagerCompilation();
2201 // TODO(1240846): It's weird that native function declarations are
2202 // introduced dynamically when we meet their declarations, whereas
2203 // other functions are set up when entering the surrounding scope.
2204 VariableProxy* proxy = NewUnresolved(name, VAR);
2205 Declaration* declaration =
2206 factory()->NewVariableDeclaration(proxy, VAR, scope_, pos);
2207 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
2208 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral(
2209 name, extension_, RelocInfo::kNoPosition);
2210 return factory()->NewExpressionStatement(
2211 factory()->NewAssignment(
2212 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition),
2217 Statement* Parser::ParseFunctionDeclaration(
2218 ZoneList<const AstRawString*>* names, bool* ok) {
2219 // FunctionDeclaration ::
2220 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
2221 // GeneratorDeclaration ::
2222 // 'function' '*' Identifier '(' FormalParameterListopt ')'
2223 // '{' FunctionBody '}'
2224 Expect(Token::FUNCTION, CHECK_OK);
2225 int pos = position();
2226 bool is_generator = Check(Token::MUL);
2227 bool is_strict_reserved = false;
2228 const AstRawString* name = ParseIdentifierOrStrictReservedWord(
2229 &is_strict_reserved, CHECK_OK);
2233 fni_->PushEnclosingName(name);
2235 FunctionLiteral* fun = ParseFunctionLiteral(
2236 name, scanner()->location(),
2237 is_strict_reserved ? kFunctionNameIsStrictReserved
2238 : kFunctionNameValidityUnknown,
2239 is_generator ? FunctionKind::kGeneratorFunction
2240 : FunctionKind::kNormalFunction,
2241 pos, FunctionLiteral::DECLARATION, FunctionLiteral::NORMAL_ARITY,
2242 language_mode(), CHECK_OK);
2243 if (fni_ != NULL) fni_->Leave();
2245 // Even if we're not at the top-level of the global or a function
2246 // scope, we treat it as such and introduce the function with its
2247 // initial value upon entering the corresponding scope.
2248 // In ES6, a function behaves as a lexical binding, except in
2249 // a script scope, or the initial scope of eval or another function.
2251 is_strong(language_mode())
2253 : (is_strict(language_mode()) || allow_harmony_sloppy_function()) &&
2254 !scope_->is_declaration_scope()
2257 VariableProxy* proxy = NewUnresolved(name, mode);
2258 Declaration* declaration =
2259 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
2260 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
2261 if (names) names->Add(name, zone());
2262 EmptyStatement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2263 if (is_sloppy(language_mode()) && allow_harmony_sloppy_function() &&
2264 !scope_->is_declaration_scope()) {
2265 SloppyBlockFunctionStatement* delegate =
2266 factory()->NewSloppyBlockFunctionStatement(empty, scope_);
2267 scope_->DeclarationScope()->sloppy_block_function_map()->Declare(name,
2275 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
2277 // ClassDeclaration ::
2278 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
2280 // A ClassDeclaration
2284 // has the same semantics as:
2286 // let C = class C { ... };
2288 // so rewrite it as such.
2290 Expect(Token::CLASS, CHECK_OK);
2291 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
2292 ReportMessage(MessageTemplate::kSloppyLexical);
2297 int pos = position();
2298 bool is_strict_reserved = false;
2299 const AstRawString* name =
2300 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
2301 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(),
2302 is_strict_reserved, pos, CHECK_OK);
2304 VariableMode mode = is_strong(language_mode()) ? CONST : LET;
2305 VariableProxy* proxy = NewUnresolved(name, mode);
2306 const bool is_class_declaration = true;
2307 Declaration* declaration = factory()->NewVariableDeclaration(
2308 proxy, mode, scope_, pos, is_class_declaration,
2309 scope_->class_declaration_group_start());
2310 Variable* outer_class_variable =
2311 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
2312 proxy->var()->set_initializer_position(position());
2313 // This is needed because a class ("class Name { }") creates two bindings (one
2314 // in the outer scope, and one in the class scope). The method is a function
2315 // scope inside the inner scope (class scope). The consecutive class
2316 // declarations are in the outer scope.
2317 if (value->class_variable_proxy() && value->class_variable_proxy()->var() &&
2318 outer_class_variable->is_class()) {
2319 // In some cases, the outer variable is not detected as a class variable;
2320 // this happens e.g., for lazy methods. They are excluded from strong mode
2321 // checks for now. TODO(marja, rossberg): re-create variables with the
2322 // correct Kind and remove this hack.
2323 value->class_variable_proxy()
2326 ->set_declaration_group_start(
2327 outer_class_variable->AsClassVariable()->declaration_group_start());
2330 Token::Value init_op =
2331 is_strong(language_mode()) ? Token::INIT_CONST : Token::INIT_LET;
2332 Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos);
2333 Statement* assignment_statement =
2334 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
2335 if (names) names->Add(name, zone());
2336 return assignment_statement;
2340 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) {
2341 if (is_strict(language_mode()) || allow_harmony_sloppy()) {
2342 return ParseScopedBlock(labels, ok);
2346 // '{' Statement* '}'
2348 // Note that a Block does not introduce a new execution scope!
2349 // (ECMA-262, 3rd, 12.2)
2351 // Construct block expecting 16 statements.
2353 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2354 Target target(&this->target_stack_, result);
2355 Expect(Token::LBRACE, CHECK_OK);
2356 while (peek() != Token::RBRACE) {
2357 Statement* stat = ParseStatement(NULL, CHECK_OK);
2358 if (stat && !stat->IsEmpty()) {
2359 result->AddStatement(stat, zone());
2362 Expect(Token::RBRACE, CHECK_OK);
2367 Block* Parser::ParseScopedBlock(ZoneList<const AstRawString*>* labels,
2369 // The harmony mode uses block elements instead of statements.
2372 // '{' StatementList '}'
2374 // Construct block expecting 16 statements.
2376 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2377 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
2379 // Parse the statements and collect escaping labels.
2380 Expect(Token::LBRACE, CHECK_OK);
2381 block_scope->set_start_position(scanner()->location().beg_pos);
2382 { BlockState block_state(&scope_, block_scope);
2383 Target target(&this->target_stack_, body);
2385 while (peek() != Token::RBRACE) {
2386 Statement* stat = ParseStatementListItem(CHECK_OK);
2387 if (stat && !stat->IsEmpty()) {
2388 body->AddStatement(stat, zone());
2392 Expect(Token::RBRACE, CHECK_OK);
2393 block_scope->set_end_position(scanner()->location().end_pos);
2394 block_scope = block_scope->FinalizeBlockScope();
2395 body->set_scope(block_scope);
2400 const AstRawString* Parser::DeclarationParsingResult::SingleName() const {
2401 if (declarations.length() != 1) return nullptr;
2402 const Declaration& declaration = declarations.at(0);
2403 if (declaration.pattern->IsVariableProxy()) {
2404 return declaration.pattern->AsVariableProxy()->raw_name();
2410 Block* Parser::DeclarationParsingResult::BuildInitializationBlock(
2411 ZoneList<const AstRawString*>* names, bool* ok) {
2412 Block* result = descriptor.parser->factory()->NewBlock(
2413 NULL, 1, true, descriptor.declaration_pos);
2414 for (auto declaration : declarations) {
2415 PatternRewriter::DeclareAndInitializeVariables(
2416 result, &descriptor, &declaration, names, CHECK_OK);
2422 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
2423 ZoneList<const AstRawString*>* names,
2425 // VariableStatement ::
2426 // VariableDeclarations ';'
2428 // The scope of a var/const declared variable anywhere inside a function
2429 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
2430 // transform a source-level var/const declaration into a (Function)
2431 // Scope declaration, and rewrite the source-level initialization into an
2432 // assignment statement. We use a block to collect multiple assignments.
2434 // We mark the block as initializer block because we don't want the
2435 // rewriter to add a '.result' assignment to such a block (to get compliant
2436 // behavior for code such as print(eval('var x = 7')), and for cosmetic
2437 // reasons when pretty-printing. Also, unless an assignment (initialization)
2438 // is inside an initializer block, it is ignored.
2440 DeclarationParsingResult parsing_result;
2441 ParseVariableDeclarations(var_context, &parsing_result, CHECK_OK);
2442 ExpectSemicolon(CHECK_OK);
2444 Block* result = parsing_result.BuildInitializationBlock(names, CHECK_OK);
2449 void Parser::ParseVariableDeclarations(VariableDeclarationContext var_context,
2450 DeclarationParsingResult* parsing_result,
2452 // VariableDeclarations ::
2453 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
2455 // The ES6 Draft Rev3 specifies the following grammar for const declarations
2457 // ConstDeclaration ::
2458 // const ConstBinding (',' ConstBinding)* ';'
2460 // Identifier '=' AssignmentExpression
2464 // BindingPattern '=' AssignmentExpression
2466 parsing_result->descriptor.parser = this;
2467 parsing_result->descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
2468 parsing_result->descriptor.declaration_pos = peek_position();
2469 parsing_result->descriptor.initialization_pos = peek_position();
2470 parsing_result->descriptor.mode = VAR;
2471 // True if the binding needs initialization. 'let' and 'const' declared
2472 // bindings are created uninitialized by their declaration nodes and
2473 // need initialization. 'var' declared bindings are always initialized
2474 // immediately by their declaration nodes.
2475 parsing_result->descriptor.needs_init = false;
2476 parsing_result->descriptor.is_const = false;
2477 parsing_result->descriptor.init_op = Token::INIT_VAR;
2478 if (peek() == Token::VAR) {
2479 if (is_strong(language_mode())) {
2480 Scanner::Location location = scanner()->peek_location();
2481 ReportMessageAt(location, MessageTemplate::kStrongVar);
2485 Consume(Token::VAR);
2486 } else if (peek() == Token::CONST && allow_const()) {
2487 Consume(Token::CONST);
2488 if (is_sloppy(language_mode()) && allow_legacy_const()) {
2489 parsing_result->descriptor.mode = CONST_LEGACY;
2490 parsing_result->descriptor.init_op = Token::INIT_CONST_LEGACY;
2491 ++use_counts_[v8::Isolate::kLegacyConst];
2493 DCHECK(is_strict(language_mode()) || allow_harmony_sloppy());
2494 DCHECK(var_context != kStatement);
2495 parsing_result->descriptor.mode = CONST;
2496 parsing_result->descriptor.init_op = Token::INIT_CONST;
2498 parsing_result->descriptor.is_const = true;
2499 parsing_result->descriptor.needs_init = true;
2500 } else if (peek() == Token::LET && allow_let()) {
2501 Consume(Token::LET);
2502 DCHECK(var_context != kStatement);
2503 parsing_result->descriptor.mode = LET;
2504 parsing_result->descriptor.needs_init = true;
2505 parsing_result->descriptor.init_op = Token::INIT_LET;
2507 UNREACHABLE(); // by current callers
2510 parsing_result->descriptor.declaration_scope =
2511 DeclarationScope(parsing_result->descriptor.mode);
2512 parsing_result->descriptor.scope = scope_;
2513 parsing_result->descriptor.hoist_scope = nullptr;
2516 bool first_declaration = true;
2517 int bindings_start = peek_position();
2518 bool is_for_iteration_variable;
2520 if (fni_ != NULL) fni_->Enter();
2523 if (!first_declaration) Consume(Token::COMMA);
2525 Expression* pattern;
2527 ExpressionClassifier pattern_classifier;
2528 Token::Value next = peek();
2529 pattern = ParsePrimaryExpression(&pattern_classifier, ok);
2531 ValidateBindingPattern(&pattern_classifier, ok);
2533 if (!allow_harmony_destructuring() && !pattern->IsVariableProxy()) {
2534 ReportUnexpectedToken(next);
2540 Scanner::Location variable_loc = scanner()->location();
2541 const AstRawString* single_name =
2542 pattern->IsVariableProxy() ? pattern->AsVariableProxy()->raw_name()
2544 if (single_name != nullptr) {
2545 if (fni_ != NULL) fni_->PushVariableName(single_name);
2548 is_for_iteration_variable =
2549 var_context == kForStatement &&
2550 (peek() == Token::IN || PeekContextualKeyword(CStrVector("of")));
2551 if (is_for_iteration_variable && parsing_result->descriptor.mode == CONST) {
2552 parsing_result->descriptor.needs_init = false;
2555 Expression* value = NULL;
2556 // Harmony consts have non-optional initializers.
2557 int initializer_position = RelocInfo::kNoPosition;
2558 if (peek() == Token::ASSIGN || (parsing_result->descriptor.mode == CONST &&
2559 !is_for_iteration_variable)) {
2560 Expect(Token::ASSIGN, ok);
2562 ExpressionClassifier classifier;
2563 value = ParseAssignmentExpression(var_context != kForStatement,
2566 ValidateExpression(&classifier, ok);
2568 variable_loc.end_pos = scanner()->location().end_pos;
2570 if (!parsing_result->first_initializer_loc.IsValid()) {
2571 parsing_result->first_initializer_loc = variable_loc;
2574 // Don't infer if it is "a = function(){...}();"-like expression.
2576 if (fni_ != NULL && value->AsCall() == NULL &&
2577 value->AsCallNew() == NULL) {
2580 fni_->RemoveLastFunction();
2583 // End position of the initializer is after the assignment expression.
2584 initializer_position = scanner()->location().end_pos;
2586 // End position of the initializer is after the variable.
2587 initializer_position = position();
2590 // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
2591 if (value == NULL && parsing_result->descriptor.needs_init) {
2592 value = GetLiteralUndefined(position());
2595 if (single_name && fni_ != NULL) fni_->Leave();
2596 parsing_result->declarations.Add(DeclarationParsingResult::Declaration(
2597 pattern, initializer_position, value));
2598 first_declaration = false;
2599 } while (peek() == Token::COMMA);
2601 parsing_result->bindings_loc =
2602 Scanner::Location(bindings_start, scanner()->location().end_pos);
2606 static bool ContainsLabel(ZoneList<const AstRawString*>* labels,
2607 const AstRawString* label) {
2608 DCHECK(label != NULL);
2609 if (labels != NULL) {
2610 for (int i = labels->length(); i-- > 0; ) {
2611 if (labels->at(i) == label) {
2620 Statement* Parser::ParseExpressionOrLabelledStatement(
2621 ZoneList<const AstRawString*>* labels, bool* ok) {
2622 // ExpressionStatement | LabelledStatement ::
2624 // Identifier ':' Statement
2626 // ExpressionStatement[Yield] :
2627 // [lookahead ∉ {{, function, class, let [}] Expression[In, ?Yield] ;
2629 int pos = peek_position();
2632 case Token::FUNCTION:
2634 UNREACHABLE(); // Always handled by the callers.
2636 ReportUnexpectedToken(Next());
2641 if (!FLAG_strong_this) break;
2644 if (is_strong(language_mode()) &&
2645 i::IsConstructor(function_state_->kind())) {
2646 bool is_this = peek() == Token::THIS;
2648 ExpressionClassifier classifier;
2650 expr = ParseStrongInitializationExpression(&classifier, CHECK_OK);
2652 expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK);
2654 ValidateExpression(&classifier, CHECK_OK);
2656 case Token::SEMICOLON:
2657 Consume(Token::SEMICOLON);
2663 if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
2664 ReportMessageAt(function_state_->this_location(),
2666 ? MessageTemplate::kStrongConstructorThis
2667 : MessageTemplate::kStrongConstructorSuper);
2672 return factory()->NewExpressionStatement(expr, pos);
2680 bool starts_with_idenfifier = peek_any_identifier();
2681 Expression* expr = ParseExpression(true, CHECK_OK);
2682 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
2683 expr->AsVariableProxy() != NULL &&
2684 !expr->AsVariableProxy()->is_this()) {
2685 // Expression is a single identifier, and not, e.g., a parenthesized
2687 VariableProxy* var = expr->AsVariableProxy();
2688 const AstRawString* label = var->raw_name();
2689 // TODO(1240780): We don't check for redeclaration of labels
2690 // during preparsing since keeping track of the set of active
2691 // labels requires nontrivial changes to the way scopes are
2692 // structured. However, these are probably changes we want to
2693 // make later anyway so we should go back and fix this then.
2694 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
2695 ParserTraits::ReportMessage(MessageTemplate::kLabelRedeclaration, label);
2699 if (labels == NULL) {
2700 labels = new(zone()) ZoneList<const AstRawString*>(4, zone());
2702 labels->Add(label, zone());
2703 // Remove the "ghost" variable that turned out to be a label
2704 // from the top scope. This way, we don't try to resolve it
2705 // during the scope processing.
2706 scope_->RemoveUnresolved(var);
2707 Expect(Token::COLON, CHECK_OK);
2708 return ParseStatement(labels, ok);
2711 // If we have an extension, we allow a native function declaration.
2712 // A native function declaration starts with "native function" with
2713 // no line-terminator between the two words.
2714 if (extension_ != NULL && peek() == Token::FUNCTION &&
2715 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL &&
2716 expr->AsVariableProxy() != NULL &&
2717 expr->AsVariableProxy()->raw_name() ==
2718 ast_value_factory()->native_string() &&
2719 !scanner()->literal_contains_escapes()) {
2720 return ParseNativeDeclaration(ok);
2723 // Parsed expression statement, followed by semicolon.
2724 // Detect attempts at 'let' declarations in sloppy mode.
2725 if (!allow_harmony_sloppy_let() && peek() == Token::IDENTIFIER &&
2726 expr->AsVariableProxy() != NULL &&
2727 expr->AsVariableProxy()->raw_name() ==
2728 ast_value_factory()->let_string()) {
2729 ReportMessage(MessageTemplate::kSloppyLexical, NULL);
2733 ExpectSemicolon(CHECK_OK);
2734 return factory()->NewExpressionStatement(expr, pos);
2738 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels,
2741 // 'if' '(' Expression ')' Statement ('else' Statement)?
2743 int pos = peek_position();
2744 Expect(Token::IF, CHECK_OK);
2745 Expect(Token::LPAREN, CHECK_OK);
2746 Expression* condition = ParseExpression(true, CHECK_OK);
2747 Expect(Token::RPAREN, CHECK_OK);
2748 Statement* then_statement = ParseSubStatement(labels, CHECK_OK);
2749 Statement* else_statement = NULL;
2750 if (peek() == Token::ELSE) {
2752 else_statement = ParseSubStatement(labels, CHECK_OK);
2754 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2756 return factory()->NewIfStatement(
2757 condition, then_statement, else_statement, pos);
2761 Statement* Parser::ParseContinueStatement(bool* ok) {
2762 // ContinueStatement ::
2763 // 'continue' Identifier? ';'
2765 int pos = peek_position();
2766 Expect(Token::CONTINUE, CHECK_OK);
2767 const AstRawString* label = NULL;
2768 Token::Value tok = peek();
2769 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2770 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2771 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2772 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2774 IterationStatement* target = LookupContinueTarget(label, CHECK_OK);
2775 if (target == NULL) {
2776 // Illegal continue statement.
2777 MessageTemplate::Template message = MessageTemplate::kIllegalContinue;
2778 if (label != NULL) {
2779 message = MessageTemplate::kUnknownLabel;
2781 ParserTraits::ReportMessage(message, label);
2785 ExpectSemicolon(CHECK_OK);
2786 return factory()->NewContinueStatement(target, pos);
2790 Statement* Parser::ParseBreakStatement(ZoneList<const AstRawString*>* labels,
2792 // BreakStatement ::
2793 // 'break' Identifier? ';'
2795 int pos = peek_position();
2796 Expect(Token::BREAK, CHECK_OK);
2797 const AstRawString* label = NULL;
2798 Token::Value tok = peek();
2799 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2800 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2801 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2802 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2804 // Parse labeled break statements that target themselves into
2805 // empty statements, e.g. 'l1: l2: l3: break l2;'
2806 if (label != NULL && ContainsLabel(labels, label)) {
2807 ExpectSemicolon(CHECK_OK);
2808 return factory()->NewEmptyStatement(pos);
2810 BreakableStatement* target = NULL;
2811 target = LookupBreakTarget(label, CHECK_OK);
2812 if (target == NULL) {
2813 // Illegal break statement.
2814 MessageTemplate::Template message = MessageTemplate::kIllegalBreak;
2815 if (label != NULL) {
2816 message = MessageTemplate::kUnknownLabel;
2818 ParserTraits::ReportMessage(message, label);
2822 ExpectSemicolon(CHECK_OK);
2823 return factory()->NewBreakStatement(target, pos);
2827 Statement* Parser::ParseReturnStatement(bool* ok) {
2828 // ReturnStatement ::
2829 // 'return' Expression? ';'
2831 // Consume the return token. It is necessary to do that before
2832 // reporting any errors on it, because of the way errors are
2833 // reported (underlining).
2834 Expect(Token::RETURN, CHECK_OK);
2835 Scanner::Location loc = scanner()->location();
2836 function_state_->set_return_location(loc);
2838 Token::Value tok = peek();
2840 Expression* return_value;
2841 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
2842 tok == Token::SEMICOLON ||
2843 tok == Token::RBRACE ||
2844 tok == Token::EOS) {
2845 if (IsSubclassConstructor(function_state_->kind())) {
2846 return_value = ThisExpression(scope_, factory(), loc.beg_pos);
2848 return_value = GetLiteralUndefined(position());
2851 if (is_strong(language_mode()) &&
2852 i::IsConstructor(function_state_->kind())) {
2853 int pos = peek_position();
2854 ReportMessageAt(Scanner::Location(pos, pos + 1),
2855 MessageTemplate::kStrongConstructorReturnValue);
2860 int pos = peek_position();
2861 return_value = ParseExpression(true, CHECK_OK);
2863 if (IsSubclassConstructor(function_state_->kind())) {
2864 // For subclass constructors we need to return this in case of undefined
2865 // and throw an exception in case of a non object.
2871 // return (temp = expr) === undefined ? this :
2872 // %_IsSpecObject(temp) ? temp : throw new TypeError(...);
2873 Variable* temp = scope_->NewTemporary(
2874 ast_value_factory()->empty_string());
2875 Assignment* assign = factory()->NewAssignment(
2876 Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);
2878 Expression* throw_expression =
2879 NewThrowTypeError(MessageTemplate::kDerivedConstructorReturn,
2880 ast_value_factory()->empty_string(), pos);
2882 // %_IsSpecObject(temp)
2883 ZoneList<Expression*>* is_spec_object_args =
2884 new (zone()) ZoneList<Expression*>(1, zone());
2885 is_spec_object_args->Add(factory()->NewVariableProxy(temp), zone());
2886 Expression* is_spec_object_call = factory()->NewCallRuntime(
2887 Runtime::kInlineIsSpecObject, is_spec_object_args, pos);
2889 // %_IsSpecObject(temp) ? temp : throw_expression
2890 Expression* is_object_conditional = factory()->NewConditional(
2891 is_spec_object_call, factory()->NewVariableProxy(temp),
2892 throw_expression, pos);
2894 // temp === undefined
2895 Expression* is_undefined = factory()->NewCompareOperation(
2896 Token::EQ_STRICT, assign,
2897 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), pos);
2899 // is_undefined ? this : is_object_conditional
2900 return_value = factory()->NewConditional(
2901 is_undefined, ThisExpression(scope_, factory(), pos),
2902 is_object_conditional, pos);
2905 ExpectSemicolon(CHECK_OK);
2907 if (is_generator()) {
2908 Expression* generator = factory()->NewVariableProxy(
2909 function_state_->generator_object_variable());
2910 Expression* yield = factory()->NewYield(
2911 generator, return_value, Yield::kFinal, loc.beg_pos);
2912 result = factory()->NewExpressionStatement(yield, loc.beg_pos);
2914 result = factory()->NewReturnStatement(return_value, loc.beg_pos);
2917 Scope* decl_scope = scope_->DeclarationScope();
2918 if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) {
2919 ReportMessageAt(loc, MessageTemplate::kIllegalReturn);
2927 Statement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels,
2930 // 'with' '(' Expression ')' Statement
2932 Expect(Token::WITH, CHECK_OK);
2933 int pos = position();
2935 if (is_strict(language_mode())) {
2936 ReportMessage(MessageTemplate::kStrictWith);
2941 Expect(Token::LPAREN, CHECK_OK);
2942 Expression* expr = ParseExpression(true, CHECK_OK);
2943 Expect(Token::RPAREN, CHECK_OK);
2945 scope_->DeclarationScope()->RecordWithStatement();
2946 Scope* with_scope = NewScope(scope_, WITH_SCOPE);
2948 { BlockState block_state(&scope_, with_scope);
2949 with_scope->set_start_position(scanner()->peek_location().beg_pos);
2950 stmt = ParseSubStatement(labels, CHECK_OK);
2951 with_scope->set_end_position(scanner()->location().end_pos);
2953 return factory()->NewWithStatement(with_scope, expr, stmt, pos);
2957 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
2959 // 'case' Expression ':' StatementList
2960 // 'default' ':' StatementList
2962 Expression* label = NULL; // NULL expression indicates default case
2963 if (peek() == Token::CASE) {
2964 Expect(Token::CASE, CHECK_OK);
2965 label = ParseExpression(true, CHECK_OK);
2967 Expect(Token::DEFAULT, CHECK_OK);
2968 if (*default_seen_ptr) {
2969 ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch);
2973 *default_seen_ptr = true;
2975 Expect(Token::COLON, CHECK_OK);
2976 int pos = position();
2977 ZoneList<Statement*>* statements =
2978 new(zone()) ZoneList<Statement*>(5, zone());
2979 Statement* stat = NULL;
2980 while (peek() != Token::CASE &&
2981 peek() != Token::DEFAULT &&
2982 peek() != Token::RBRACE) {
2983 stat = ParseStatementListItem(CHECK_OK);
2984 statements->Add(stat, zone());
2986 if (is_strong(language_mode()) && stat != NULL && !stat->IsJump() &&
2987 peek() != Token::RBRACE) {
2988 ReportMessageAt(scanner()->location(),
2989 MessageTemplate::kStrongSwitchFallthrough);
2993 return factory()->NewCaseClause(label, statements, pos);
2997 Statement* Parser::ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
2999 // SwitchStatement ::
3000 // 'switch' '(' Expression ')' '{' CaseClause* '}'
3001 // In order to get the CaseClauses to execute in their own lexical scope,
3002 // but without requiring downstream code to have special scope handling
3003 // code for switch statements, desugar into blocks as follows:
3004 // { // To group the statements--harmless to evaluate Expression in scope
3005 // .tag_variable = Expression;
3006 // { // To give CaseClauses a scope
3007 // switch (.tag_variable) { CaseClause* }
3011 Block* switch_block =
3012 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3013 int switch_pos = peek_position();
3015 Expect(Token::SWITCH, CHECK_OK);
3016 Expect(Token::LPAREN, CHECK_OK);
3017 Expression* tag = ParseExpression(true, CHECK_OK);
3018 Expect(Token::RPAREN, CHECK_OK);
3020 Variable* tag_variable =
3021 scope_->NewTemporary(ast_value_factory()->dot_switch_tag_string());
3022 Assignment* tag_assign = factory()->NewAssignment(
3023 Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag,
3025 Statement* tag_statement =
3026 factory()->NewExpressionStatement(tag_assign, RelocInfo::kNoPosition);
3027 switch_block->AddStatement(tag_statement, zone());
3029 // make statement: undefined;
3030 // This is needed so the tag isn't returned as the value, in case the switch
3031 // statements don't have a value.
3032 switch_block->AddStatement(
3033 factory()->NewExpressionStatement(
3034 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
3035 RelocInfo::kNoPosition),
3038 Block* cases_block =
3039 factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
3040 Scope* cases_scope = NewScope(scope_, BLOCK_SCOPE);
3041 cases_scope->SetNonlinear();
3043 SwitchStatement* switch_statement =
3044 factory()->NewSwitchStatement(labels, switch_pos);
3046 cases_scope->set_start_position(scanner()->location().beg_pos);
3048 BlockState cases_block_state(&scope_, cases_scope);
3049 Target target(&this->target_stack_, switch_statement);
3051 Expression* tag_read = factory()->NewVariableProxy(tag_variable);
3053 bool default_seen = false;
3054 ZoneList<CaseClause*>* cases =
3055 new (zone()) ZoneList<CaseClause*>(4, zone());
3056 Expect(Token::LBRACE, CHECK_OK);
3057 while (peek() != Token::RBRACE) {
3058 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
3059 cases->Add(clause, zone());
3061 switch_statement->Initialize(tag_read, cases);
3062 cases_block->AddStatement(switch_statement, zone());
3064 Expect(Token::RBRACE, CHECK_OK);
3066 cases_scope->set_end_position(scanner()->location().end_pos);
3067 cases_scope = cases_scope->FinalizeBlockScope();
3068 cases_block->set_scope(cases_scope);
3070 switch_block->AddStatement(cases_block, zone());
3072 return switch_block;
3076 Statement* Parser::ParseThrowStatement(bool* ok) {
3077 // ThrowStatement ::
3078 // 'throw' Expression ';'
3080 Expect(Token::THROW, CHECK_OK);
3081 int pos = position();
3082 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
3083 ReportMessage(MessageTemplate::kNewlineAfterThrow);
3087 Expression* exception = ParseExpression(true, CHECK_OK);
3088 ExpectSemicolon(CHECK_OK);
3090 return factory()->NewExpressionStatement(
3091 factory()->NewThrow(exception, pos), pos);
3095 TryStatement* Parser::ParseTryStatement(bool* ok) {
3097 // 'try' Block Catch
3098 // 'try' Block Finally
3099 // 'try' Block Catch Finally
3102 // 'catch' '(' Identifier ')' Block
3107 Expect(Token::TRY, CHECK_OK);
3108 int pos = position();
3110 Block* try_block = ParseBlock(NULL, CHECK_OK);
3112 Token::Value tok = peek();
3113 if (tok != Token::CATCH && tok != Token::FINALLY) {
3114 ReportMessage(MessageTemplate::kNoCatchOrFinally);
3119 Scope* catch_scope = NULL;
3120 Variable* catch_variable = NULL;
3121 Block* catch_block = NULL;
3122 const AstRawString* name = NULL;
3123 if (tok == Token::CATCH) {
3124 Consume(Token::CATCH);
3126 Expect(Token::LPAREN, CHECK_OK);
3127 catch_scope = NewScope(scope_, CATCH_SCOPE);
3128 catch_scope->set_start_position(scanner()->location().beg_pos);
3129 name = ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
3131 Expect(Token::RPAREN, CHECK_OK);
3133 catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized,
3135 BlockState block_state(&scope_, catch_scope);
3136 catch_block = ParseBlock(NULL, CHECK_OK);
3138 catch_scope->set_end_position(scanner()->location().end_pos);
3142 Block* finally_block = NULL;
3143 DCHECK(tok == Token::FINALLY || catch_block != NULL);
3144 if (tok == Token::FINALLY) {
3145 Consume(Token::FINALLY);
3146 finally_block = ParseBlock(NULL, CHECK_OK);
3149 // Simplify the AST nodes by converting:
3150 // 'try B0 catch B1 finally B2'
3152 // 'try { try B0 catch B1 } finally B2'
3154 if (catch_block != NULL && finally_block != NULL) {
3155 // If we have both, create an inner try/catch.
3156 DCHECK(catch_scope != NULL && catch_variable != NULL);
3157 TryCatchStatement* statement =
3158 factory()->NewTryCatchStatement(try_block, catch_scope, catch_variable,
3159 catch_block, RelocInfo::kNoPosition);
3160 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
3161 try_block->AddStatement(statement, zone());
3162 catch_block = NULL; // Clear to indicate it's been handled.
3165 TryStatement* result = NULL;
3166 if (catch_block != NULL) {
3167 DCHECK(finally_block == NULL);
3168 DCHECK(catch_scope != NULL && catch_variable != NULL);
3169 result = factory()->NewTryCatchStatement(try_block, catch_scope,
3170 catch_variable, catch_block, pos);
3172 DCHECK(finally_block != NULL);
3173 result = factory()->NewTryFinallyStatement(try_block, finally_block, pos);
3180 DoWhileStatement* Parser::ParseDoWhileStatement(
3181 ZoneList<const AstRawString*>* labels, bool* ok) {
3183 // 'do' Statement 'while' '(' Expression ')' ';'
3185 DoWhileStatement* loop =
3186 factory()->NewDoWhileStatement(labels, peek_position());
3187 Target target(&this->target_stack_, loop);
3189 Expect(Token::DO, CHECK_OK);
3190 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3191 Expect(Token::WHILE, CHECK_OK);
3192 Expect(Token::LPAREN, CHECK_OK);
3194 Expression* cond = ParseExpression(true, CHECK_OK);
3195 Expect(Token::RPAREN, CHECK_OK);
3197 // Allow do-statements to be terminated with and without
3198 // semi-colons. This allows code such as 'do;while(0)return' to
3199 // parse, which would not be the case if we had used the
3200 // ExpectSemicolon() functionality here.
3201 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
3203 if (loop != NULL) loop->Initialize(cond, body);
3208 WhileStatement* Parser::ParseWhileStatement(
3209 ZoneList<const AstRawString*>* labels, bool* ok) {
3210 // WhileStatement ::
3211 // 'while' '(' Expression ')' Statement
3213 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position());
3214 Target target(&this->target_stack_, loop);
3216 Expect(Token::WHILE, CHECK_OK);
3217 Expect(Token::LPAREN, CHECK_OK);
3218 Expression* cond = ParseExpression(true, CHECK_OK);
3219 Expect(Token::RPAREN, CHECK_OK);
3220 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3222 if (loop != NULL) loop->Initialize(cond, body);
3227 // !%_IsSpecObject(result = iterator.next()) &&
3228 // %ThrowIteratorResultNotAnObject(result)
3229 Expression* Parser::BuildIteratorNextResult(Expression* iterator,
3230 Variable* result, int pos) {
3231 Expression* next_literal = factory()->NewStringLiteral(
3232 ast_value_factory()->next_string(), RelocInfo::kNoPosition);
3233 Expression* next_property =
3234 factory()->NewProperty(iterator, next_literal, RelocInfo::kNoPosition);
3235 ZoneList<Expression*>* next_arguments =
3236 new (zone()) ZoneList<Expression*>(0, zone());
3237 Expression* next_call =
3238 factory()->NewCall(next_property, next_arguments, pos);
3239 Expression* result_proxy = factory()->NewVariableProxy(result);
3241 factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos);
3243 // %_IsSpecObject(...)
3244 ZoneList<Expression*>* is_spec_object_args =
3245 new (zone()) ZoneList<Expression*>(1, zone());
3246 is_spec_object_args->Add(left, zone());
3247 Expression* is_spec_object_call = factory()->NewCallRuntime(
3248 Runtime::kInlineIsSpecObject, is_spec_object_args, pos);
3250 // %ThrowIteratorResultNotAnObject(result)
3251 Expression* result_proxy_again = factory()->NewVariableProxy(result);
3252 ZoneList<Expression*>* throw_arguments =
3253 new (zone()) ZoneList<Expression*>(1, zone());
3254 throw_arguments->Add(result_proxy_again, zone());
3255 Expression* throw_call = factory()->NewCallRuntime(
3256 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos);
3258 return factory()->NewBinaryOperation(
3260 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos),
3265 void Parser::InitializeForEachStatement(ForEachStatement* stmt,
3267 Expression* subject,
3269 ForOfStatement* for_of = stmt->AsForOfStatement();
3271 if (for_of != NULL) {
3272 Variable* iterator = scope_->NewTemporary(
3273 ast_value_factory()->dot_iterator_string());
3274 Variable* result = scope_->NewTemporary(
3275 ast_value_factory()->dot_result_string());
3277 Expression* assign_iterator;
3278 Expression* next_result;
3279 Expression* result_done;
3280 Expression* assign_each;
3282 // iterator = subject[Symbol.iterator]()
3283 assign_iterator = factory()->NewAssignment(
3284 Token::ASSIGN, factory()->NewVariableProxy(iterator),
3285 GetIterator(subject, factory()), subject->position());
3287 // !%_IsSpecObject(result = iterator.next()) &&
3288 // %ThrowIteratorResultNotAnObject(result)
3290 // result = iterator.next()
3291 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
3293 BuildIteratorNextResult(iterator_proxy, result, subject->position());
3298 Expression* done_literal = factory()->NewStringLiteral(
3299 ast_value_factory()->done_string(), RelocInfo::kNoPosition);
3300 Expression* result_proxy = factory()->NewVariableProxy(result);
3301 result_done = factory()->NewProperty(
3302 result_proxy, done_literal, RelocInfo::kNoPosition);
3305 // each = result.value
3307 Expression* value_literal = factory()->NewStringLiteral(
3308 ast_value_factory()->value_string(), RelocInfo::kNoPosition);
3309 Expression* result_proxy = factory()->NewVariableProxy(result);
3310 Expression* result_value = factory()->NewProperty(
3311 result_proxy, value_literal, RelocInfo::kNoPosition);
3312 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value,
3313 RelocInfo::kNoPosition);
3316 for_of->Initialize(each, subject, body,
3322 stmt->Initialize(each, subject, body);
3327 Statement* Parser::DesugarLexicalBindingsInForStatement(
3328 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names,
3329 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
3330 Statement* body, bool* ok) {
3331 // ES6 13.6.3.4 specifies that on each loop iteration the let variables are
3332 // copied into a new environment. After copying, the "next" statement of the
3333 // loop is executed to update the loop variables. The loop condition is
3334 // checked and the loop body is executed.
3336 // We rewrite a for statement of the form
3338 // labels: for (let/const x = i; cond; next) body
3347 // outer: for (;;) {
3348 // { // This block's only function is to ensure that the statements it
3349 // // contains do not affect the normal completion value. This is
3350 // // accomplished by setting its ignore_completion_value bit.
3351 // // No new lexical scope is introduced, so lexically scoped variables
3352 // // declared here will be scoped to the outer for loop.
3353 // let/const x = temp_x;
3354 // if (first == 1) {
3361 // labels: for (; flag == 1; flag = 0, temp_x = x) {
3374 DCHECK(names->length() > 0);
3375 Scope* for_scope = scope_;
3376 ZoneList<Variable*> temps(names->length(), zone());
3378 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false,
3379 RelocInfo::kNoPosition);
3381 // Add statement: let/const x = i.
3382 outer_block->AddStatement(init, zone());
3384 const AstRawString* temp_name = ast_value_factory()->dot_for_string();
3386 // For each lexical variable x:
3387 // make statement: temp_x = x.
3388 for (int i = 0; i < names->length(); i++) {
3389 VariableProxy* proxy = NewUnresolved(names->at(i), LET);
3390 Variable* temp = scope_->NewTemporary(temp_name);
3391 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
3392 Assignment* assignment = factory()->NewAssignment(
3393 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3394 Statement* assignment_statement = factory()->NewExpressionStatement(
3395 assignment, RelocInfo::kNoPosition);
3396 outer_block->AddStatement(assignment_statement, zone());
3397 temps.Add(temp, zone());
3400 Variable* first = NULL;
3401 // Make statement: first = 1.
3403 first = scope_->NewTemporary(temp_name);
3404 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3405 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3406 Assignment* assignment = factory()->NewAssignment(
3407 Token::ASSIGN, first_proxy, const1, RelocInfo::kNoPosition);
3408 Statement* assignment_statement =
3409 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3410 outer_block->AddStatement(assignment_statement, zone());
3413 // make statement: undefined;
3414 outer_block->AddStatement(
3415 factory()->NewExpressionStatement(
3416 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
3417 RelocInfo::kNoPosition),
3420 // Make statement: outer: for (;;)
3421 // Note that we don't actually create the label, or set this loop up as an
3422 // explicit break target, instead handing it directly to those nodes that
3423 // need to know about it. This should be safe because we don't run any code
3424 // in this function that looks up break targets.
3425 ForStatement* outer_loop =
3426 factory()->NewForStatement(NULL, RelocInfo::kNoPosition);
3427 outer_block->AddStatement(outer_loop, zone());
3429 outer_block->set_scope(for_scope);
3430 scope_ = inner_scope;
3432 Block* inner_block =
3433 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3434 Block* ignore_completion_block = factory()->NewBlock(
3435 NULL, names->length() + 2, true, RelocInfo::kNoPosition);
3436 ZoneList<Variable*> inner_vars(names->length(), zone());
3437 // For each let variable x:
3438 // make statement: let/const x = temp_x.
3439 VariableMode mode = is_const ? CONST : LET;
3440 for (int i = 0; i < names->length(); i++) {
3441 VariableProxy* proxy = NewUnresolved(names->at(i), mode);
3442 Declaration* declaration = factory()->NewVariableDeclaration(
3443 proxy, mode, scope_, RelocInfo::kNoPosition);
3444 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
3445 inner_vars.Add(declaration->proxy()->var(), zone());
3446 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3447 Assignment* assignment =
3448 factory()->NewAssignment(is_const ? Token::INIT_CONST : Token::INIT_LET,
3449 proxy, temp_proxy, RelocInfo::kNoPosition);
3450 Statement* assignment_statement =
3451 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3452 DCHECK(init->position() != RelocInfo::kNoPosition);
3453 proxy->var()->set_initializer_position(init->position());
3454 ignore_completion_block->AddStatement(assignment_statement, zone());
3457 // Make statement: if (first == 1) { first = 0; } else { next; }
3460 Expression* compare = NULL;
3461 // Make compare expression: first == 1.
3463 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3464 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3465 compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
3466 RelocInfo::kNoPosition);
3468 Statement* clear_first = NULL;
3469 // Make statement: first = 0.
3471 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3472 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3473 Assignment* assignment = factory()->NewAssignment(
3474 Token::ASSIGN, first_proxy, const0, RelocInfo::kNoPosition);
3476 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3478 Statement* clear_first_or_next = factory()->NewIfStatement(
3479 compare, clear_first, next, RelocInfo::kNoPosition);
3480 ignore_completion_block->AddStatement(clear_first_or_next, zone());
3483 Variable* flag = scope_->NewTemporary(temp_name);
3484 // Make statement: flag = 1.
3486 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3487 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3488 Assignment* assignment = factory()->NewAssignment(
3489 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
3490 Statement* assignment_statement =
3491 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3492 ignore_completion_block->AddStatement(assignment_statement, zone());
3494 inner_block->AddStatement(ignore_completion_block, zone());
3495 // Make cond expression for main loop: flag == 1.
3496 Expression* flag_cond = NULL;
3498 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3499 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3500 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
3501 RelocInfo::kNoPosition);
3504 // Create chain of expressions "flag = 0, temp_x = x, ..."
3505 Statement* compound_next_statement = NULL;
3507 Expression* compound_next = NULL;
3508 // Make expression: flag = 0.
3510 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3511 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3512 compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
3513 const0, RelocInfo::kNoPosition);
3516 // Make the comma-separated list of temp_x = x assignments.
3517 int inner_var_proxy_pos = scanner()->location().beg_pos;
3518 for (int i = 0; i < names->length(); i++) {
3519 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3520 VariableProxy* proxy =
3521 factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos);
3522 Assignment* assignment = factory()->NewAssignment(
3523 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3524 compound_next = factory()->NewBinaryOperation(
3525 Token::COMMA, compound_next, assignment, RelocInfo::kNoPosition);
3528 compound_next_statement = factory()->NewExpressionStatement(
3529 compound_next, RelocInfo::kNoPosition);
3532 // Make statement: if (cond) { body; } else { break outer; }
3533 Statement* body_or_stop = body;
3536 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3538 factory()->NewIfStatement(cond, body, stop, cond->position());
3541 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
3542 // Note that we re-use the original loop node, which retains its labels
3543 // and ensures that any break or continue statements in body point to
3545 loop->Initialize(NULL, flag_cond, compound_next_statement, body_or_stop);
3546 inner_block->AddStatement(loop, zone());
3548 // Make statement: if (flag == 1) { break; }
3550 Expression* compare = NULL;
3551 // Make compare expresion: flag == 1.
3553 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3554 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3555 compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
3556 RelocInfo::kNoPosition);
3559 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3560 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
3561 Statement* if_flag_break =
3562 factory()->NewIfStatement(compare, stop, empty, RelocInfo::kNoPosition);
3563 inner_block->AddStatement(if_flag_break, zone());
3566 inner_scope->set_end_position(scanner()->location().end_pos);
3567 inner_block->set_scope(inner_scope);
3570 outer_loop->Initialize(NULL, NULL, NULL, inner_block);
3575 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
3578 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
3580 int stmt_pos = peek_position();
3581 bool is_const = false;
3582 Statement* init = NULL;
3583 ZoneList<const AstRawString*> lexical_bindings(1, zone());
3585 // Create an in-between scope for let-bound iteration variables.
3586 Scope* saved_scope = scope_;
3587 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
3589 Expect(Token::FOR, CHECK_OK);
3590 Expect(Token::LPAREN, CHECK_OK);
3591 for_scope->set_start_position(scanner()->location().beg_pos);
3592 bool is_let_identifier_expression = false;
3593 DeclarationParsingResult parsing_result;
3594 if (peek() != Token::SEMICOLON) {
3595 if (peek() == Token::VAR || (peek() == Token::CONST && allow_const()) ||
3596 (peek() == Token::LET && IsNextLetKeyword())) {
3597 ParseVariableDeclarations(kForStatement, &parsing_result, CHECK_OK);
3598 is_const = parsing_result.descriptor.mode == CONST;
3600 int num_decl = parsing_result.declarations.length();
3601 bool accept_IN = num_decl >= 1;
3602 bool accept_OF = true;
3603 ForEachStatement::VisitMode mode;
3604 int each_beg_pos = scanner()->location().beg_pos;
3605 int each_end_pos = scanner()->location().end_pos;
3607 if (accept_IN && CheckInOrOf(accept_OF, &mode, ok)) {
3608 if (!*ok) return nullptr;
3609 if (num_decl != 1) {
3610 const char* loop_type =
3611 mode == ForEachStatement::ITERATE ? "for-of" : "for-in";
3612 ParserTraits::ReportMessageAt(
3613 parsing_result.bindings_loc,
3614 MessageTemplate::kForInOfLoopMultiBindings, loop_type);
3618 if (parsing_result.first_initializer_loc.IsValid() &&
3619 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE ||
3620 IsLexicalVariableMode(parsing_result.descriptor.mode))) {
3621 if (mode == ForEachStatement::ITERATE) {
3622 ReportMessageAt(parsing_result.first_initializer_loc,
3623 MessageTemplate::kForOfLoopInitializer);
3625 // TODO(caitp): This should be an error in sloppy mode too.
3626 ReportMessageAt(parsing_result.first_initializer_loc,
3627 MessageTemplate::kForInLoopInitializer);
3633 DCHECK(parsing_result.declarations.length() == 1);
3634 Block* init_block = nullptr;
3636 // special case for legacy for (var/const x =.... in)
3637 if (!IsLexicalVariableMode(parsing_result.descriptor.mode) &&
3638 parsing_result.declarations[0].initializer != nullptr) {
3639 VariableProxy* single_var = scope_->NewUnresolved(
3640 factory(), parsing_result.SingleName(), Variable::NORMAL,
3641 each_beg_pos, each_end_pos);
3642 init_block = factory()->NewBlock(
3643 nullptr, 2, true, parsing_result.descriptor.declaration_pos);
3644 init_block->AddStatement(
3645 factory()->NewExpressionStatement(
3646 factory()->NewAssignment(
3647 Token::ASSIGN, single_var,
3648 parsing_result.declarations[0].initializer,
3649 RelocInfo::kNoPosition),
3650 RelocInfo::kNoPosition),
3654 // Rewrite a for-in/of statement of the form
3656 // for (let/const/var x in/of e) b
3661 // <let x' be a temporary variable>
3662 // for (x' in/of e) {
3667 // let x; // for TDZ
3670 Variable* temp = scope_->NewTemporary(
3671 ast_value_factory()->dot_for_string());
3672 ForEachStatement* loop =
3673 factory()->NewForEachStatement(mode, labels, stmt_pos);
3674 Target target(&this->target_stack_, loop);
3676 Expression* enumerable = ParseExpression(true, CHECK_OK);
3678 Expect(Token::RPAREN, CHECK_OK);
3680 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE);
3681 body_scope->set_start_position(scanner()->location().beg_pos);
3682 scope_ = body_scope;
3684 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3687 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3689 auto each_initialization_block =
3690 factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition);
3692 DCHECK(parsing_result.declarations.length() == 1);
3693 DeclarationParsingResult::Declaration decl =
3694 parsing_result.declarations[0];
3695 auto descriptor = parsing_result.descriptor;
3696 descriptor.declaration_pos = RelocInfo::kNoPosition;
3697 descriptor.initialization_pos = RelocInfo::kNoPosition;
3698 decl.initializer = factory()->NewVariableProxy(temp);
3700 PatternRewriter::DeclareAndInitializeVariables(
3701 each_initialization_block, &descriptor, &decl,
3702 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings
3707 body_block->AddStatement(each_initialization_block, zone());
3708 body_block->AddStatement(body, zone());
3709 VariableProxy* temp_proxy =
3710 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
3711 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block);
3713 body_scope->set_end_position(scanner()->location().end_pos);
3714 body_scope = body_scope->FinalizeBlockScope();
3715 if (body_scope != nullptr) {
3716 body_block->set_scope(body_scope);
3719 // Create a TDZ for any lexically-bound names.
3720 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) {
3721 DCHECK_NULL(init_block);
3724 factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition);
3726 for (int i = 0; i < lexical_bindings.length(); ++i) {
3727 // TODO(adamk): This needs to be some sort of special
3728 // INTERNAL variable that's invisible to the debugger
3729 // but visible to everything else.
3730 VariableProxy* tdz_proxy = NewUnresolved(lexical_bindings[i], LET);
3731 Declaration* tdz_decl = factory()->NewVariableDeclaration(
3732 tdz_proxy, LET, scope_, RelocInfo::kNoPosition);
3733 Variable* tdz_var = Declare(tdz_decl, DeclarationDescriptor::NORMAL,
3735 tdz_var->set_initializer_position(position());
3739 scope_ = saved_scope;
3740 for_scope->set_end_position(scanner()->location().end_pos);
3741 for_scope = for_scope->FinalizeBlockScope();
3742 // Parsed for-in loop w/ variable declarations.
3743 if (init_block != nullptr) {
3744 init_block->AddStatement(loop, zone());
3745 if (for_scope != nullptr) {
3746 init_block->set_scope(for_scope);
3750 DCHECK_NULL(for_scope);
3754 init = parsing_result.BuildInitializationBlock(
3755 IsLexicalVariableMode(parsing_result.descriptor.mode)
3761 int lhs_beg_pos = peek_position();
3762 Expression* expression = ParseExpression(false, CHECK_OK);
3763 int lhs_end_pos = scanner()->location().end_pos;
3764 ForEachStatement::VisitMode mode;
3765 bool accept_OF = expression->IsVariableProxy();
3766 is_let_identifier_expression =
3767 expression->IsVariableProxy() &&
3768 expression->AsVariableProxy()->raw_name() ==
3769 ast_value_factory()->let_string();
3771 if (CheckInOrOf(accept_OF, &mode, ok)) {
3772 if (!*ok) return nullptr;
3773 expression = this->CheckAndRewriteReferenceExpression(
3774 expression, lhs_beg_pos, lhs_end_pos,
3775 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK);
3777 ForEachStatement* loop =
3778 factory()->NewForEachStatement(mode, labels, stmt_pos);
3779 Target target(&this->target_stack_, loop);
3781 Expression* enumerable = ParseExpression(true, CHECK_OK);
3782 Expect(Token::RPAREN, CHECK_OK);
3784 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3785 InitializeForEachStatement(loop, expression, enumerable, body);
3786 scope_ = saved_scope;
3787 for_scope->set_end_position(scanner()->location().end_pos);
3788 for_scope = for_scope->FinalizeBlockScope();
3789 DCHECK(for_scope == NULL);
3790 // Parsed for-in loop.
3794 init = factory()->NewExpressionStatement(expression, lhs_beg_pos);
3799 // Standard 'for' loop
3800 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos);
3801 Target target(&this->target_stack_, loop);
3803 // Parsed initializer at this point.
3804 // Detect attempts at 'let' declarations in sloppy mode.
3805 if (!allow_harmony_sloppy_let() && peek() == Token::IDENTIFIER &&
3806 is_sloppy(language_mode()) && is_let_identifier_expression) {
3807 ReportMessage(MessageTemplate::kSloppyLexical, NULL);
3811 Expect(Token::SEMICOLON, CHECK_OK);
3813 // If there are let bindings, then condition and the next statement of the
3814 // for loop must be parsed in a new scope.
3815 Scope* inner_scope = NULL;
3816 if (lexical_bindings.length() > 0) {
3817 inner_scope = NewScope(for_scope, BLOCK_SCOPE);
3818 inner_scope->set_start_position(scanner()->location().beg_pos);
3819 scope_ = inner_scope;
3822 Expression* cond = NULL;
3823 if (peek() != Token::SEMICOLON) {
3824 cond = ParseExpression(true, CHECK_OK);
3826 Expect(Token::SEMICOLON, CHECK_OK);
3828 Statement* next = NULL;
3829 if (peek() != Token::RPAREN) {
3830 Expression* exp = ParseExpression(true, CHECK_OK);
3831 next = factory()->NewExpressionStatement(exp, exp->position());
3833 Expect(Token::RPAREN, CHECK_OK);
3835 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3837 Statement* result = NULL;
3838 if (lexical_bindings.length() > 0) {
3840 result = DesugarLexicalBindingsInForStatement(
3841 inner_scope, is_const, &lexical_bindings, loop, init, cond,
3842 next, body, CHECK_OK);
3843 scope_ = saved_scope;
3844 for_scope->set_end_position(scanner()->location().end_pos);
3846 scope_ = saved_scope;
3847 for_scope->set_end_position(scanner()->location().end_pos);
3848 for_scope = for_scope->FinalizeBlockScope();
3850 // Rewrite a for statement of the form
3851 // for (const x = i; c; n) b
3859 DCHECK(init != NULL);
3861 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3862 block->AddStatement(init, zone());
3863 block->AddStatement(loop, zone());
3864 block->set_scope(for_scope);
3865 loop->Initialize(NULL, cond, next, body);
3868 loop->Initialize(init, cond, next, body);
3876 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
3877 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
3878 // contexts this is used as a statement which invokes the debugger as i a
3879 // break point is present.
3880 // DebuggerStatement ::
3883 int pos = peek_position();
3884 Expect(Token::DEBUGGER, CHECK_OK);
3885 ExpectSemicolon(CHECK_OK);
3886 return factory()->NewDebuggerStatement(pos);
3890 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
3891 if (expression->IsLiteral()) return true;
3892 MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3893 return lit != NULL && lit->is_simple();
3897 Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate,
3898 Expression* expression) {
3899 Factory* factory = isolate->factory();
3900 DCHECK(IsCompileTimeValue(expression));
3901 Handle<FixedArray> result = factory->NewFixedArray(2, TENURED);
3902 ObjectLiteral* object_literal = expression->AsObjectLiteral();
3903 if (object_literal != NULL) {
3904 DCHECK(object_literal->is_simple());
3905 if (object_literal->fast_elements()) {
3906 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
3908 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
3910 result->set(kElementsSlot, *object_literal->constant_properties());
3912 ArrayLiteral* array_literal = expression->AsArrayLiteral();
3913 DCHECK(array_literal != NULL && array_literal->is_simple());
3914 result->set(kLiteralTypeSlot, Smi::FromInt(ARRAY_LITERAL));
3915 result->set(kElementsSlot, *array_literal->constant_elements());
3921 CompileTimeValue::LiteralType CompileTimeValue::GetLiteralType(
3922 Handle<FixedArray> value) {
3923 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot));
3924 return static_cast<LiteralType>(literal_type->value());
3928 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
3929 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
3933 void ParserTraits::ParseArrowFunctionFormalParameters(
3934 ParserFormalParameters* parameters, Expression* expr,
3935 const Scanner::Location& params_loc, bool* ok) {
3936 if (parameters->Arity() >= Code::kMaxArguments) {
3937 ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
3942 // ArrowFunctionFormals ::
3943 // Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail)
3945 // NonTailArrowFunctionFormals ::
3946 // Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy)
3950 // Spread(VariableProxy)
3952 // As we need to visit the parameters in left-to-right order, we recurse on
3953 // the left-hand side of comma expressions.
3955 if (expr->IsBinaryOperation()) {
3956 BinaryOperation* binop = expr->AsBinaryOperation();
3957 // The classifier has already run, so we know that the expression is a valid
3958 // arrow function formals production.
3959 DCHECK_EQ(binop->op(), Token::COMMA);
3960 Expression* left = binop->left();
3961 Expression* right = binop->right();
3962 ParseArrowFunctionFormalParameters(parameters, left, params_loc, ok);
3964 // LHS of comma expression should be unparenthesized.
3968 // Only the right-most expression may be a rest parameter.
3969 DCHECK(!parameters->has_rest);
3971 bool is_rest = expr->IsSpread();
3973 expr = expr->AsSpread()->expression();
3974 parameters->has_rest = true;
3975 parameters->rest_array_literal_index =
3976 parser_->function_state_->NextMaterializedLiteralIndex();
3977 ++parameters->materialized_literals_count;
3979 if (parameters->is_simple) {
3980 parameters->is_simple = !is_rest && expr->IsVariableProxy();
3983 Expression* initializer = nullptr;
3984 if (expr->IsVariableProxy()) {
3985 // When the formal parameter was originally seen, it was parsed as a
3986 // VariableProxy and recorded as unresolved in the scope. Here we undo that
3987 // parse-time side-effect for parameters that are single-names (not
3988 // patterns; for patterns that happens uniformly in
3989 // PatternRewriter::VisitVariableProxy).
3990 parser_->scope_->RemoveUnresolved(expr->AsVariableProxy());
3991 } else if (expr->IsAssignment()) {
3992 Assignment* assignment = expr->AsAssignment();
3993 DCHECK(parser_->allow_harmony_default_parameters());
3994 DCHECK(!assignment->is_compound());
3995 initializer = assignment->value();
3996 expr = assignment->target();
3999 AddFormalParameter(parameters, expr, initializer, is_rest);
4003 void ParserTraits::ParseArrowFunctionFormalParameterList(
4004 ParserFormalParameters* parameters, Expression* expr,
4005 const Scanner::Location& params_loc,
4006 Scanner::Location* duplicate_loc, bool* ok) {
4007 if (expr->IsEmptyParentheses()) return;
4009 ParseArrowFunctionFormalParameters(parameters, expr, params_loc, ok);
4012 ExpressionClassifier classifier;
4013 if (!parameters->is_simple) {
4014 classifier.RecordNonSimpleParameter();
4016 for (int i = 0; i < parameters->Arity(); ++i) {
4017 auto parameter = parameters->at(i);
4018 DeclareFormalParameter(parameters->scope, parameter, &classifier);
4019 if (!duplicate_loc->IsValid()) {
4020 *duplicate_loc = classifier.duplicate_formal_parameter_error().location;
4023 DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters());
4027 void ParserTraits::ReindexLiterals(const ParserFormalParameters& parameters) {
4028 if (parser_->function_state_->materialized_literal_count() > 0) {
4029 AstLiteralReindexer reindexer;
4031 for (const auto p : parameters.params) {
4032 if (p.pattern != nullptr) reindexer.Reindex(p.pattern);
4035 if (parameters.has_rest) {
4036 parameters.rest_array_literal_index = reindexer.NextIndex();
4039 DCHECK(reindexer.count() <=
4040 parser_->function_state_->materialized_literal_count());
4045 FunctionLiteral* Parser::ParseFunctionLiteral(
4046 const AstRawString* function_name, Scanner::Location function_name_location,
4047 FunctionNameValidity function_name_validity, FunctionKind kind,
4048 int function_token_pos, FunctionLiteral::FunctionType function_type,
4049 FunctionLiteral::ArityRestriction arity_restriction,
4050 LanguageMode language_mode, bool* ok) {
4052 // '(' FormalParameterList? ')' '{' FunctionBody '}'
4055 // '(' ')' '{' FunctionBody '}'
4058 // '(' PropertySetParameterList ')' '{' FunctionBody '}'
4060 int pos = function_token_pos == RelocInfo::kNoPosition
4061 ? peek_position() : function_token_pos;
4063 bool is_generator = IsGeneratorFunction(kind);
4065 // Anonymous functions were passed either the empty symbol or a null
4066 // handle as the function name. Remember if we were passed a non-empty
4067 // handle to decide whether to invoke function name inference.
4068 bool should_infer_name = function_name == NULL;
4070 // We want a non-null handle as the function name.
4071 if (should_infer_name) {
4072 function_name = ast_value_factory()->empty_string();
4075 // Function declarations are function scoped in normal mode, so they are
4076 // hoisted. In harmony block scoping mode they are block scoped, so they
4079 // One tricky case are function declarations in a local sloppy-mode eval:
4080 // their declaration is hoisted, but they still see the local scope. E.g.,
4084 // try { throw 1 } catch (x) { eval("function g() { return x }") }
4088 // needs to return 1. To distinguish such cases, we need to detect
4089 // (1) whether a function stems from a sloppy eval, and
4090 // (2) whether it actually hoists across the eval.
4091 // Unfortunately, we do not represent sloppy eval scopes, so we do not have
4092 // either information available directly, especially not when lazily compiling
4093 // a function like 'g'. We hence rely on the following invariants:
4094 // - (1) is the case iff the innermost scope of the deserialized scope chain
4095 // under which we compile is _not_ a declaration scope. This holds because
4096 // in all normal cases, function declarations are fully hoisted to a
4097 // declaration scope and compiled relative to that.
4098 // - (2) is the case iff the current declaration scope is still the original
4099 // one relative to the deserialized scope chain. Otherwise we must be
4100 // compiling a function in an inner declaration scope in the eval, e.g. a
4101 // nested function, and hoisting works normally relative to that.
4102 Scope* declaration_scope = scope_->DeclarationScope();
4103 Scope* original_declaration_scope = original_scope_->DeclarationScope();
4104 Scope* scope = function_type == FunctionLiteral::DECLARATION &&
4105 is_sloppy(language_mode) &&
4106 !allow_harmony_sloppy_function() &&
4107 (original_scope_ == original_declaration_scope ||
4108 declaration_scope != original_declaration_scope)
4109 ? NewScope(declaration_scope, FUNCTION_SCOPE, kind)
4110 : NewScope(scope_, FUNCTION_SCOPE, kind);
4111 scope->SetLanguageMode(language_mode);
4112 ZoneList<Statement*>* body = NULL;
4114 int materialized_literal_count = -1;
4115 int expected_property_count = -1;
4116 DuplicateFinder duplicate_finder(scanner()->unicode_cache());
4117 ExpressionClassifier formals_classifier(&duplicate_finder);
4118 FunctionLiteral::EagerCompileHint eager_compile_hint =
4119 parenthesized_function_ ? FunctionLiteral::kShouldEagerCompile
4120 : FunctionLiteral::kShouldLazyCompile;
4121 bool should_be_used_once_hint = false;
4124 AstNodeFactory function_factory(ast_value_factory());
4125 FunctionState function_state(&function_state_, &scope_, scope, kind,
4127 scope_->SetScopeName(function_name);
4130 // For generators, allocating variables in contexts is currently a win
4131 // because it minimizes the work needed to suspend and resume an
4133 scope_->ForceContextAllocation();
4135 // Calling a generator returns a generator object. That object is stored
4136 // in a temporary variable, a definition that is used by "yield"
4137 // expressions. This also marks the FunctionState as a generator.
4138 Variable* temp = scope_->NewTemporary(
4139 ast_value_factory()->dot_generator_object_string());
4140 function_state.set_generator_object_variable(temp);
4143 Expect(Token::LPAREN, CHECK_OK);
4144 int start_position = scanner()->location().beg_pos;
4145 scope_->set_start_position(start_position);
4146 ParserFormalParameters formals(scope);
4147 ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
4148 arity = formals.Arity();
4149 Expect(Token::RPAREN, CHECK_OK);
4150 int formals_end_position = scanner()->location().end_pos;
4152 CheckArityRestrictions(arity, arity_restriction,
4153 formals.has_rest, start_position,
4154 formals_end_position, CHECK_OK);
4155 Expect(Token::LBRACE, CHECK_OK);
4157 // Determine if the function can be parsed lazily. Lazy parsing is different
4158 // from lazy compilation; we need to parse more eagerly than we compile.
4160 // We can only parse lazily if we also compile lazily. The heuristics for
4161 // lazy compilation are:
4162 // - It must not have been prohibited by the caller to Parse (some callers
4163 // need a full AST).
4164 // - The outer scope must allow lazy compilation of inner functions.
4165 // - The function mustn't be a function expression with an open parenthesis
4166 // before; we consider that a hint that the function will be called
4167 // immediately, and it would be a waste of time to make it lazily
4169 // These are all things we can know at this point, without looking at the
4172 // In addition, we need to distinguish between these cases:
4173 // (function foo() {
4174 // bar = function() { return 1; }
4177 // (function foo() {
4179 // bar = function() { return a; }
4182 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
4183 // parenthesis before the function means that it will be called
4184 // immediately). The inner function *must* be parsed eagerly to resolve the
4185 // possible reference to the variable in foo's scope. However, it's possible
4186 // that it will be compiled lazily.
4188 // To make this additional case work, both Parser and PreParser implement a
4189 // logic where only top-level functions will be parsed lazily.
4190 bool is_lazily_parsed = mode() == PARSE_LAZILY &&
4191 scope_->AllowsLazyParsing() &&
4192 !parenthesized_function_;
4193 parenthesized_function_ = false; // The bit was set for this function only.
4195 // Eager or lazy parse?
4196 // If is_lazily_parsed, we'll parse lazy. If we can set a bookmark, we'll
4197 // pass it to SkipLazyFunctionBody, which may use it to abort lazy
4198 // parsing if it suspect that wasn't a good idea. If so, or if we didn't
4199 // try to lazy parse in the first place, we'll have to parse eagerly.
4200 Scanner::BookmarkScope bookmark(scanner());
4201 if (is_lazily_parsed) {
4202 Scanner::BookmarkScope* maybe_bookmark =
4203 bookmark.Set() ? &bookmark : nullptr;
4204 SkipLazyFunctionBody(&materialized_literal_count,
4205 &expected_property_count, /*CHECK_OK*/ ok,
4208 materialized_literal_count += formals.materialized_literals_count +
4209 function_state.materialized_literal_count();
4211 if (bookmark.HasBeenReset()) {
4212 // Trigger eager (re-)parsing, just below this block.
4213 is_lazily_parsed = false;
4215 // This is probably an initialization function. Inform the compiler it
4216 // should also eager-compile this function, and that we expect it to be
4218 eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
4219 should_be_used_once_hint = true;
4222 if (!is_lazily_parsed) {
4223 // Determine whether the function body can be discarded after parsing.
4224 // The preconditions are:
4225 // - Lazy compilation has to be enabled.
4226 // - Neither V8 natives nor native function declarations can be allowed,
4227 // since parsing one would retroactively force the function to be
4228 // eagerly compiled.
4229 // - The invoker of this parser can't depend on the AST being eagerly
4230 // built (either because the function is about to be compiled, or
4231 // because the AST is going to be inspected for some reason).
4232 // - Because of the above, we can't be attempting to parse a
4233 // FunctionExpression; even without enclosing parentheses it might be
4234 // immediately invoked.
4235 // - The function literal shouldn't be hinted to eagerly compile.
4236 bool use_temp_zone =
4237 FLAG_lazy && !allow_natives() && extension_ == NULL && allow_lazy() &&
4238 function_type == FunctionLiteral::DECLARATION &&
4239 eager_compile_hint != FunctionLiteral::kShouldEagerCompile;
4240 // Open a new BodyScope, which sets our AstNodeFactory to allocate in the
4241 // new temporary zone if the preconditions are satisfied, and ensures that
4242 // the previous zone is always restored after parsing the body.
4243 // For the purpose of scope analysis, some ZoneObjects allocated by the
4244 // factory must persist after the function body is thrown away and
4245 // temp_zone is deallocated. These objects are instead allocated in a
4246 // parser-persistent zone (see parser_zone_ in AstNodeFactory).
4249 AstNodeFactory::BodyScope inner(factory(), &temp_zone, use_temp_zone);
4251 body = ParseEagerFunctionBody(function_name, pos, formals, kind,
4252 function_type, CHECK_OK);
4254 materialized_literal_count = function_state.materialized_literal_count();
4255 expected_property_count = function_state.expected_property_count();
4256 if (use_temp_zone) {
4257 // If the preconditions are correct the function body should never be
4258 // accessed, but do this anyway for better behaviour if they're wrong.
4263 // Parsing the body may change the language mode in our scope.
4264 language_mode = scope->language_mode();
4266 if (is_strong(language_mode) && IsSubclassConstructor(kind)) {
4267 if (!function_state.super_location().IsValid()) {
4268 ReportMessageAt(function_name_location,
4269 MessageTemplate::kStrongSuperCallMissing,
4276 // Validate name and parameter names. We can do this only after parsing the
4277 // function, since the function can declare itself strict.
4278 CheckFunctionName(language_mode, function_name, function_name_validity,
4279 function_name_location, CHECK_OK);
4280 const bool allow_duplicate_parameters =
4281 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind);
4282 ValidateFormalParameters(&formals_classifier, language_mode,
4283 allow_duplicate_parameters, CHECK_OK);
4285 if (is_strict(language_mode)) {
4286 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
4289 if (is_sloppy(language_mode) && allow_harmony_sloppy_function()) {
4290 InsertSloppyBlockFunctionVarBindings(scope, CHECK_OK);
4292 if (is_strict(language_mode) || allow_harmony_sloppy()) {
4293 CheckConflictingVarDeclarations(scope, CHECK_OK);
4297 bool has_duplicate_parameters =
4298 !formals_classifier.is_valid_formal_parameter_list_without_duplicates();
4299 FunctionLiteral::ParameterFlag duplicate_parameters =
4300 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
4301 : FunctionLiteral::kNoDuplicateParameters;
4303 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
4304 function_name, ast_value_factory(), scope, body,
4305 materialized_literal_count, expected_property_count, arity,
4306 duplicate_parameters, function_type, FunctionLiteral::kIsFunction,
4307 eager_compile_hint, kind, pos);
4308 function_literal->set_function_token_position(function_token_pos);
4309 if (should_be_used_once_hint)
4310 function_literal->set_should_be_used_once_hint();
4312 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
4313 return function_literal;
4317 void Parser::SkipLazyFunctionBody(int* materialized_literal_count,
4318 int* expected_property_count, bool* ok,
4319 Scanner::BookmarkScope* bookmark) {
4320 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet());
4321 if (produce_cached_parse_data()) CHECK(log_);
4323 int function_block_pos = position();
4324 if (consume_cached_parse_data() && !cached_parse_data_->rejected()) {
4325 // If we have cached data, we use it to skip parsing the function body. The
4326 // data contains the information we need to construct the lazy function.
4327 FunctionEntry entry =
4328 cached_parse_data_->GetFunctionEntry(function_block_pos);
4329 // Check that cached data is valid. If not, mark it as invalid (the embedder
4330 // handles it). Note that end position greater than end of stream is safe,
4331 // and hard to check.
4332 if (entry.is_valid() && entry.end_pos() > function_block_pos) {
4333 scanner()->SeekForward(entry.end_pos() - 1);
4335 scope_->set_end_position(entry.end_pos());
4336 Expect(Token::RBRACE, ok);
4340 total_preparse_skipped_ += scope_->end_position() - function_block_pos;
4341 *materialized_literal_count = entry.literal_count();
4342 *expected_property_count = entry.property_count();
4343 scope_->SetLanguageMode(entry.language_mode());
4344 if (entry.uses_super_property()) scope_->RecordSuperPropertyUsage();
4345 if (entry.calls_eval()) scope_->RecordEvalCall();
4348 cached_parse_data_->Reject();
4350 // With no cached data, we partially parse the function, without building an
4351 // AST. This gathers the data needed to build a lazy function.
4352 SingletonLogger logger;
4353 PreParser::PreParseResult result =
4354 ParseLazyFunctionBodyWithPreParser(&logger, bookmark);
4355 if (bookmark && bookmark->HasBeenReset()) {
4356 return; // Return immediately if pre-parser devided to abort parsing.
4358 if (result == PreParser::kPreParseStackOverflow) {
4359 // Propagate stack overflow.
4360 set_stack_overflow();
4364 if (logger.has_error()) {
4365 ParserTraits::ReportMessageAt(
4366 Scanner::Location(logger.start(), logger.end()), logger.message(),
4367 logger.argument_opt(), logger.error_type());
4371 scope_->set_end_position(logger.end());
4372 Expect(Token::RBRACE, ok);
4376 total_preparse_skipped_ += scope_->end_position() - function_block_pos;
4377 *materialized_literal_count = logger.literals();
4378 *expected_property_count = logger.properties();
4379 scope_->SetLanguageMode(logger.language_mode());
4380 if (logger.uses_super_property()) {
4381 scope_->RecordSuperPropertyUsage();
4383 if (logger.calls_eval()) {
4384 scope_->RecordEvalCall();
4386 if (produce_cached_parse_data()) {
4388 // Position right after terminal '}'.
4389 int body_end = scanner()->location().end_pos;
4390 log_->LogFunction(function_block_pos, body_end, *materialized_literal_count,
4391 *expected_property_count, scope_->language_mode(),
4392 scope_->uses_super_property(), scope_->calls_eval());
4397 void Parser::AddAssertIsConstruct(ZoneList<Statement*>* body, int pos) {
4398 ZoneList<Expression*>* arguments =
4399 new (zone()) ZoneList<Expression*>(0, zone());
4400 CallRuntime* construct_check = factory()->NewCallRuntime(
4401 Runtime::kInlineIsConstructCall, arguments, pos);
4402 CallRuntime* non_callable_error = factory()->NewCallRuntime(
4403 Runtime::kThrowConstructorNonCallableError, arguments, pos);
4404 IfStatement* if_statement = factory()->NewIfStatement(
4405 factory()->NewUnaryOperation(Token::NOT, construct_check, pos),
4406 factory()->NewReturnStatement(non_callable_error, pos),
4407 factory()->NewEmptyStatement(pos), pos);
4408 body->Add(if_statement, zone());
4412 Statement* Parser::BuildAssertIsCoercible(Variable* var) {
4413 // if (var === null || var === undefined)
4414 // throw /* type error kNonCoercible) */;
4416 Expression* condition = factory()->NewBinaryOperation(
4417 Token::OR, factory()->NewCompareOperation(
4418 Token::EQ_STRICT, factory()->NewVariableProxy(var),
4419 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
4420 RelocInfo::kNoPosition),
4421 factory()->NewCompareOperation(
4422 Token::EQ_STRICT, factory()->NewVariableProxy(var),
4423 factory()->NewNullLiteral(RelocInfo::kNoPosition),
4424 RelocInfo::kNoPosition),
4425 RelocInfo::kNoPosition);
4426 Expression* throw_type_error = this->NewThrowTypeError(
4427 MessageTemplate::kNonCoercible, ast_value_factory()->empty_string(),
4428 RelocInfo::kNoPosition);
4429 IfStatement* if_statement = factory()->NewIfStatement(
4430 condition, factory()->NewExpressionStatement(throw_type_error,
4431 RelocInfo::kNoPosition),
4432 factory()->NewEmptyStatement(RelocInfo::kNoPosition),
4433 RelocInfo::kNoPosition);
4434 return if_statement;
4438 Block* Parser::BuildParameterInitializationBlock(
4439 const ParserFormalParameters& parameters, bool* ok) {
4440 DCHECK(!parameters.is_simple);
4441 DCHECK(scope_->is_function_scope());
4443 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
4444 for (int i = 0; i < parameters.params.length(); ++i) {
4445 auto parameter = parameters.params[i];
4446 DeclarationDescriptor descriptor;
4447 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
4448 descriptor.parser = this;
4449 descriptor.declaration_scope = scope_;
4450 descriptor.scope = scope_;
4451 descriptor.hoist_scope = nullptr;
4452 descriptor.mode = LET;
4453 descriptor.is_const = false;
4454 descriptor.needs_init = true;
4455 descriptor.declaration_pos = parameter.pattern->position();
4456 descriptor.initialization_pos = parameter.pattern->position();
4457 descriptor.init_op = Token::INIT_LET;
4458 Expression* initial_value =
4459 factory()->NewVariableProxy(parameters.scope->parameter(i));
4460 if (parameter.initializer != nullptr) {
4461 // IS_UNDEFINED($param) ? initializer : $param
4462 DCHECK(!parameter.is_rest);
4463 auto condition = factory()->NewCompareOperation(
4465 factory()->NewVariableProxy(parameters.scope->parameter(i)),
4466 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
4467 RelocInfo::kNoPosition);
4468 initial_value = factory()->NewConditional(
4469 condition, parameter.initializer, initial_value,
4470 RelocInfo::kNoPosition);
4471 descriptor.initialization_pos = parameter.initializer->position();
4472 } else if (parameter.is_rest) {
4474 // for (var $argument_index = $rest_index;
4475 // $argument_index < %_ArgumentsLength();
4476 // ++$argument_index) {
4477 // %AppendElement($rest, %_Arguments($argument_index));
4479 // let <param> = $rest;
4480 DCHECK(parameter.pattern->IsVariableProxy());
4481 DCHECK_EQ(i, parameters.params.length() - 1);
4483 int pos = parameter.pattern->position();
4484 Variable* temp_var = parameters.scope->parameter(i);
4485 auto empty_values = new (zone()) ZoneList<Expression*>(0, zone());
4486 auto empty_array = factory()->NewArrayLiteral(
4487 empty_values, parameters.rest_array_literal_index,
4488 is_strong(language_mode()), RelocInfo::kNoPosition);
4490 auto init_array = factory()->NewAssignment(
4491 Token::INIT_VAR, factory()->NewVariableProxy(temp_var), empty_array,
4492 RelocInfo::kNoPosition);
4494 auto loop = factory()->NewForStatement(NULL, RelocInfo::kNoPosition);
4496 auto argument_index =
4497 parameters.scope->NewTemporary(ast_value_factory()->empty_string());
4498 auto init = factory()->NewExpressionStatement(
4499 factory()->NewAssignment(
4500 Token::INIT_VAR, factory()->NewVariableProxy(argument_index),
4501 factory()->NewSmiLiteral(i, RelocInfo::kNoPosition),
4502 RelocInfo::kNoPosition),
4503 RelocInfo::kNoPosition);
4505 auto empty_arguments = new (zone()) ZoneList<Expression*>(0, zone());
4507 // $arguments_index < arguments.length
4508 auto cond = factory()->NewCompareOperation(
4509 Token::LT, factory()->NewVariableProxy(argument_index),
4510 factory()->NewCallRuntime(Runtime::kInlineArgumentsLength,
4511 empty_arguments, RelocInfo::kNoPosition),
4512 RelocInfo::kNoPosition);
4515 auto next = factory()->NewExpressionStatement(
4516 factory()->NewCountOperation(
4517 Token::INC, true, factory()->NewVariableProxy(argument_index),
4518 RelocInfo::kNoPosition),
4519 RelocInfo::kNoPosition);
4521 // %_Arguments($arguments_index)
4522 auto arguments_args = new (zone()) ZoneList<Expression*>(1, zone());
4523 arguments_args->Add(factory()->NewVariableProxy(argument_index), zone());
4525 // %AppendElement($rest, %_Arguments($arguments_index))
4526 auto append_element_args = new (zone()) ZoneList<Expression*>(2, zone());
4528 append_element_args->Add(factory()->NewVariableProxy(temp_var), zone());
4529 append_element_args->Add(
4530 factory()->NewCallRuntime(Runtime::kInlineArguments, arguments_args,
4531 RelocInfo::kNoPosition),
4534 auto body = factory()->NewExpressionStatement(
4535 factory()->NewCallRuntime(Runtime::kAppendElement,
4536 append_element_args,
4537 RelocInfo::kNoPosition),
4538 RelocInfo::kNoPosition);
4540 loop->Initialize(init, cond, next, body);
4542 init_block->AddStatement(
4543 factory()->NewExpressionStatement(init_array, RelocInfo::kNoPosition),
4546 init_block->AddStatement(loop, zone());
4548 descriptor.initialization_pos = pos;
4551 Scope* param_scope = scope_;
4552 Block* param_block = init_block;
4553 if (!parameter.is_simple() && scope_->calls_sloppy_eval()) {
4554 param_scope = NewScope(scope_, BLOCK_SCOPE);
4555 param_scope->set_is_declaration_scope();
4556 param_scope->set_start_position(parameter.pattern->position());
4557 param_scope->set_end_position(RelocInfo::kNoPosition);
4558 param_scope->RecordEvalCall();
4559 param_block = factory()->NewBlock(NULL, 8, true, RelocInfo::kNoPosition);
4560 param_block->set_scope(param_scope);
4561 descriptor.hoist_scope = scope_;
4565 BlockState block_state(&scope_, param_scope);
4566 DeclarationParsingResult::Declaration decl(
4567 parameter.pattern, parameter.pattern->position(), initial_value);
4568 PatternRewriter::DeclareAndInitializeVariables(param_block, &descriptor,
4569 &decl, nullptr, CHECK_OK);
4572 if (!parameter.is_simple() && scope_->calls_sloppy_eval()) {
4573 param_scope = param_scope->FinalizeBlockScope();
4574 if (param_scope != nullptr) {
4575 CheckConflictingVarDeclarations(param_scope, CHECK_OK);
4577 init_block->AddStatement(param_block, zone());
4584 ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
4585 const AstRawString* function_name, int pos,
4586 const ParserFormalParameters& parameters, FunctionKind kind,
4587 FunctionLiteral::FunctionType function_type, bool* ok) {
4588 // Everything inside an eagerly parsed function will be parsed eagerly
4589 // (see comment above).
4590 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
4591 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone());
4593 static const int kFunctionNameAssignmentIndex = 0;
4594 if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
4595 DCHECK(function_name != NULL);
4596 // If we have a named function expression, we add a local variable
4597 // declaration to the body of the function with the name of the
4598 // function and let it refer to the function itself (closure).
4599 // Not having parsed the function body, the language mode may still change,
4600 // so we reserve a spot and create the actual const assignment later.
4601 DCHECK_EQ(kFunctionNameAssignmentIndex, result->length());
4602 result->Add(NULL, zone());
4605 // For concise constructors, check that they are constructed,
4607 if (i::IsConstructor(kind)) {
4608 AddAssertIsConstruct(result, pos);
4611 ZoneList<Statement*>* body = result;
4612 Scope* inner_scope = scope_;
4613 Block* inner_block = nullptr;
4614 if (!parameters.is_simple) {
4615 inner_scope = NewScope(scope_, BLOCK_SCOPE);
4616 inner_scope->set_is_declaration_scope();
4617 inner_scope->set_start_position(scanner()->location().beg_pos);
4618 inner_block = factory()->NewBlock(NULL, 8, true, RelocInfo::kNoPosition);
4619 inner_block->set_scope(inner_scope);
4620 body = inner_block->statements();
4624 BlockState block_state(&scope_, inner_scope);
4626 // For generators, allocate and yield an iterator on function entry.
4627 if (IsGeneratorFunction(kind)) {
4628 ZoneList<Expression*>* arguments =
4629 new(zone()) ZoneList<Expression*>(0, zone());
4630 CallRuntime* allocation = factory()->NewCallRuntime(
4631 Runtime::kCreateJSGeneratorObject, arguments, pos);
4632 VariableProxy* init_proxy = factory()->NewVariableProxy(
4633 function_state_->generator_object_variable());
4634 Assignment* assignment = factory()->NewAssignment(
4635 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
4636 VariableProxy* get_proxy = factory()->NewVariableProxy(
4637 function_state_->generator_object_variable());
4638 Yield* yield = factory()->NewYield(
4639 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition);
4640 body->Add(factory()->NewExpressionStatement(
4641 yield, RelocInfo::kNoPosition), zone());
4644 ParseStatementList(body, Token::RBRACE, CHECK_OK);
4646 if (IsGeneratorFunction(kind)) {
4647 VariableProxy* get_proxy = factory()->NewVariableProxy(
4648 function_state_->generator_object_variable());
4649 Expression* undefined =
4650 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition);
4651 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal,
4652 RelocInfo::kNoPosition);
4653 body->Add(factory()->NewExpressionStatement(
4654 yield, RelocInfo::kNoPosition), zone());
4657 if (IsSubclassConstructor(kind)) {
4659 factory()->NewReturnStatement(
4660 this->ThisExpression(scope_, factory(), RelocInfo::kNoPosition),
4661 RelocInfo::kNoPosition),
4666 Expect(Token::RBRACE, CHECK_OK);
4667 scope_->set_end_position(scanner()->location().end_pos);
4669 if (!parameters.is_simple) {
4670 DCHECK_NOT_NULL(inner_scope);
4671 DCHECK_EQ(body, inner_block->statements());
4672 scope_->SetLanguageMode(inner_scope->language_mode());
4673 Block* init_block = BuildParameterInitializationBlock(parameters, CHECK_OK);
4674 DCHECK_NOT_NULL(init_block);
4676 inner_scope->set_end_position(scanner()->location().end_pos);
4677 inner_scope = inner_scope->FinalizeBlockScope();
4678 if (inner_scope != nullptr) {
4679 CheckConflictingVarDeclarations(inner_scope, CHECK_OK);
4682 result->Add(init_block, zone());
4683 result->Add(inner_block, zone());
4686 if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
4687 // Now that we know the language mode, we can create the const assignment
4688 // in the previously reserved spot.
4689 // NOTE: We create a proxy and resolve it here so that in the
4690 // future we can change the AST to only refer to VariableProxies
4691 // instead of Variables and Proxies as is the case now.
4692 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY;
4693 bool use_strict_const = is_strict(scope_->language_mode()) ||
4694 (!allow_legacy_const() && allow_harmony_sloppy());
4695 if (use_strict_const) {
4696 fvar_init_op = Token::INIT_CONST;
4698 VariableMode fvar_mode = use_strict_const ? CONST : CONST_LEGACY;
4699 Variable* fvar = new (zone())
4700 Variable(scope_, function_name, fvar_mode, Variable::NORMAL,
4701 kCreatedInitialized, kNotAssigned);
4702 VariableProxy* proxy = factory()->NewVariableProxy(fvar);
4703 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration(
4704 proxy, fvar_mode, scope_, RelocInfo::kNoPosition);
4705 scope_->DeclareFunctionVar(fvar_declaration);
4707 VariableProxy* fproxy = scope_->NewUnresolved(factory(), function_name);
4708 fproxy->BindTo(fvar);
4709 result->Set(kFunctionNameAssignmentIndex,
4710 factory()->NewExpressionStatement(
4711 factory()->NewAssignment(fvar_init_op, fproxy,
4712 factory()->NewThisFunction(pos),
4713 RelocInfo::kNoPosition),
4714 RelocInfo::kNoPosition));
4721 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
4722 SingletonLogger* logger, Scanner::BookmarkScope* bookmark) {
4723 // This function may be called on a background thread too; record only the
4724 // main thread preparse times.
4725 if (pre_parse_timer_ != NULL) {
4726 pre_parse_timer_->Start();
4728 DCHECK_EQ(Token::LBRACE, scanner()->current_token());
4730 if (reusable_preparser_ == NULL) {
4731 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(),
4732 NULL, stack_limit_);
4733 reusable_preparser_->set_allow_lazy(true);
4734 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
4736 SET_ALLOW(harmony_arrow_functions);
4737 SET_ALLOW(harmony_sloppy);
4738 SET_ALLOW(harmony_sloppy_let);
4739 SET_ALLOW(harmony_rest_parameters);
4740 SET_ALLOW(harmony_default_parameters);
4741 SET_ALLOW(harmony_spreadcalls);
4742 SET_ALLOW(harmony_destructuring);
4743 SET_ALLOW(harmony_spread_arrays);
4744 SET_ALLOW(harmony_new_target);
4745 SET_ALLOW(strong_mode);
4748 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
4749 language_mode(), function_state_->kind(), scope_->has_simple_parameters(),
4751 if (pre_parse_timer_ != NULL) {
4752 pre_parse_timer_->Stop();
4758 ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name,
4759 Scanner::Location class_name_location,
4760 bool name_is_strict_reserved, int pos,
4762 // All parts of a ClassDeclaration and ClassExpression are strict code.
4763 if (name_is_strict_reserved) {
4764 ReportMessageAt(class_name_location,
4765 MessageTemplate::kUnexpectedStrictReserved);
4769 if (IsEvalOrArguments(name)) {
4770 ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments);
4774 if (is_strong(language_mode()) && IsUndefined(name)) {
4775 ReportMessageAt(class_name_location, MessageTemplate::kStrongUndefined);
4780 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
4781 BlockState block_state(&scope_, block_scope);
4782 scope_->SetLanguageMode(
4783 static_cast<LanguageMode>(scope_->language_mode() | STRICT));
4784 scope_->SetScopeName(name);
4786 VariableProxy* proxy = NULL;
4788 proxy = NewUnresolved(name, CONST);
4789 const bool is_class_declaration = true;
4790 Declaration* declaration = factory()->NewVariableDeclaration(
4791 proxy, CONST, block_scope, pos, is_class_declaration,
4792 scope_->class_declaration_group_start());
4793 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
4796 Expression* extends = NULL;
4797 if (Check(Token::EXTENDS)) {
4798 block_scope->set_start_position(scanner()->location().end_pos);
4799 ExpressionClassifier classifier;
4800 extends = ParseLeftHandSideExpression(&classifier, CHECK_OK);
4801 ValidateExpression(&classifier, CHECK_OK);
4803 block_scope->set_start_position(scanner()->location().end_pos);
4807 ClassLiteralChecker checker(this);
4808 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone());
4809 FunctionLiteral* constructor = NULL;
4810 bool has_seen_constructor = false;
4812 Expect(Token::LBRACE, CHECK_OK);
4814 const bool has_extends = extends != nullptr;
4815 while (peek() != Token::RBRACE) {
4816 if (Check(Token::SEMICOLON)) continue;
4817 if (fni_ != NULL) fni_->Enter();
4818 const bool in_class = true;
4819 const bool is_static = false;
4820 bool is_computed_name = false; // Classes do not care about computed
4821 // property names here.
4822 ExpressionClassifier classifier;
4823 ObjectLiteral::Property* property = ParsePropertyDefinition(
4824 &checker, in_class, has_extends, is_static, &is_computed_name,
4825 &has_seen_constructor, &classifier, CHECK_OK);
4826 ValidateExpression(&classifier, CHECK_OK);
4828 if (has_seen_constructor && constructor == NULL) {
4829 constructor = GetPropertyValue(property)->AsFunctionLiteral();
4830 DCHECK_NOT_NULL(constructor);
4832 properties->Add(property, zone());
4841 Expect(Token::RBRACE, CHECK_OK);
4842 int end_pos = scanner()->location().end_pos;
4844 if (constructor == NULL) {
4845 constructor = DefaultConstructor(extends != NULL, block_scope, pos, end_pos,
4846 block_scope->language_mode());
4849 block_scope->set_end_position(end_pos);
4852 DCHECK_NOT_NULL(proxy);
4853 proxy->var()->set_initializer_position(end_pos);
4855 // Unnamed classes should not have scopes (the scope will be empty).
4856 DCHECK_EQ(block_scope->num_var_or_const(), 0);
4857 block_scope = nullptr;
4860 return factory()->NewClassLiteral(name, block_scope, proxy, extends,
4861 constructor, properties, pos, end_pos);
4865 Expression* Parser::ParseV8Intrinsic(bool* ok) {
4867 // '%' Identifier Arguments
4869 int pos = peek_position();
4870 Expect(Token::MOD, CHECK_OK);
4871 // Allow "eval" or "arguments" for backward compatibility.
4872 const AstRawString* name = ParseIdentifier(kAllowRestrictedIdentifiers,
4874 Scanner::Location spread_pos;
4875 ExpressionClassifier classifier;
4876 ZoneList<Expression*>* args =
4877 ParseArguments(&spread_pos, &classifier, CHECK_OK);
4878 ValidateExpression(&classifier, CHECK_OK);
4880 DCHECK(!spread_pos.IsValid());
4882 if (extension_ != NULL) {
4883 // The extension structures are only accessible while parsing the
4884 // very first time not when reparsing because of lazy compilation.
4885 scope_->DeclarationScope()->ForceEagerCompilation();
4888 const Runtime::Function* function = Runtime::FunctionForName(name->string());
4890 if (function != NULL) {
4891 // Check for possible name clash.
4892 DCHECK_EQ(Context::kNotFound,
4893 Context::IntrinsicIndexForName(name->string()));
4894 // Check for built-in IS_VAR macro.
4895 if (function->function_id == Runtime::kIS_VAR) {
4896 DCHECK_EQ(Runtime::RUNTIME, function->intrinsic_type);
4897 // %IS_VAR(x) evaluates to x if x is a variable,
4898 // leads to a parse error otherwise. Could be implemented as an
4899 // inline function %_IS_VAR(x) to eliminate this special case.
4900 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
4903 ReportMessage(MessageTemplate::kNotIsvar);
4909 // Check that the expected number of arguments are being passed.
4910 if (function->nargs != -1 && function->nargs != args->length()) {
4911 ReportMessage(MessageTemplate::kIllegalAccess);
4916 return factory()->NewCallRuntime(function, args, pos);
4919 int context_index = Context::IntrinsicIndexForName(name->string());
4921 // Check that the function is defined.
4922 if (context_index == Context::kNotFound) {
4923 ParserTraits::ReportMessage(MessageTemplate::kNotDefined, name);
4928 return factory()->NewCallRuntime(context_index, args, pos);
4932 Literal* Parser::GetLiteralUndefined(int position) {
4933 return factory()->NewUndefinedLiteral(position);
4937 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
4938 Declaration* decl = scope->CheckConflictingVarDeclarations();
4940 // In harmony mode we treat conflicting variable bindinds as early
4941 // errors. See ES5 16 for a definition of early errors.
4942 const AstRawString* name = decl->proxy()->raw_name();
4943 int position = decl->proxy()->position();
4944 Scanner::Location location = position == RelocInfo::kNoPosition
4945 ? Scanner::Location::invalid()
4946 : Scanner::Location(position, position + 1);
4947 ParserTraits::ReportMessageAt(location, MessageTemplate::kVarRedeclaration,
4954 void Parser::InsertSloppyBlockFunctionVarBindings(Scope* scope, bool* ok) {
4955 // For each variable which is used as a function declaration in a sloppy
4957 DCHECK(scope->is_declaration_scope());
4958 SloppyBlockFunctionMap* map = scope->sloppy_block_function_map();
4959 for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
4960 AstRawString* name = static_cast<AstRawString*>(p->key);
4961 // If the variable wouldn't conflict with a lexical declaration,
4962 Variable* var = scope->LookupLocal(name);
4963 if (var == nullptr || !IsLexicalVariableMode(var->mode())) {
4964 // Declare a var-style binding for the function in the outer scope
4965 VariableProxy* proxy = scope->NewUnresolved(factory(), name);
4966 Declaration* declaration = factory()->NewVariableDeclaration(
4967 proxy, VAR, scope, RelocInfo::kNoPosition);
4968 Declare(declaration, DeclarationDescriptor::NORMAL, true, ok, scope);
4969 DCHECK(ok); // Based on the preceding check, this should not fail
4972 // Write in assignments to var for each block-scoped function declaration
4973 auto delegates = static_cast<SloppyBlockFunctionMap::Vector*>(p->value);
4974 for (SloppyBlockFunctionStatement* delegate : *delegates) {
4975 // Read from the local lexical scope and write to the function scope
4976 VariableProxy* to = scope->NewUnresolved(factory(), name);
4977 VariableProxy* from = delegate->scope()->NewUnresolved(factory(), name);
4978 Expression* assignment = factory()->NewAssignment(
4979 Token::ASSIGN, to, from, RelocInfo::kNoPosition);
4980 Statement* statement = factory()->NewExpressionStatement(
4981 assignment, RelocInfo::kNoPosition);
4982 delegate->set_statement(statement);
4989 // ----------------------------------------------------------------------------
4992 bool Parser::TargetStackContainsLabel(const AstRawString* label) {
4993 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4994 if (ContainsLabel(t->statement()->labels(), label)) return true;
5000 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
5002 bool anonymous = label == NULL;
5003 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
5004 BreakableStatement* stat = t->statement();
5005 if ((anonymous && stat->is_target_for_anonymous()) ||
5006 (!anonymous && ContainsLabel(stat->labels(), label))) {
5014 IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
5016 bool anonymous = label == NULL;
5017 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
5018 IterationStatement* stat = t->statement()->AsIterationStatement();
5019 if (stat == NULL) continue;
5021 DCHECK(stat->is_target_for_anonymous());
5022 if (anonymous || ContainsLabel(stat->labels(), label)) {
5030 void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
5031 if (scanner_.source_url()->length() > 0) {
5032 Handle<String> source_url = scanner_.source_url()->Internalize(isolate);
5033 script->set_source_url(*source_url);
5035 if (scanner_.source_mapping_url()->length() > 0) {
5036 Handle<String> source_mapping_url =
5037 scanner_.source_mapping_url()->Internalize(isolate);
5038 script->set_source_mapping_url(*source_mapping_url);
5043 void Parser::Internalize(Isolate* isolate, Handle<Script> script, bool error) {
5044 // Internalize strings.
5045 ast_value_factory()->Internalize(isolate);
5047 // Error processing.
5049 if (stack_overflow()) {
5050 isolate->StackOverflow();
5052 DCHECK(pending_error_handler_.has_pending_error());
5053 pending_error_handler_.ThrowPendingError(isolate, script);
5057 // Move statistics to Isolate.
5058 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
5060 for (int i = 0; i < use_counts_[feature]; ++i) {
5061 isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
5064 isolate->counters()->total_preparse_skipped()->Increment(
5065 total_preparse_skipped_);
5069 // ----------------------------------------------------------------------------
5070 // Regular expressions
5073 RegExpParser::RegExpParser(FlatStringReader* in, Handle<String>* error,
5074 bool multiline, bool unicode, Isolate* isolate,
5076 : isolate_(isolate),
5081 current_(kEndMarker),
5085 multiline_(multiline),
5088 contains_anchor_(false),
5089 is_scanned_for_captures_(false),
5095 uc32 RegExpParser::Next() {
5097 return in()->Get(next_pos_);
5104 void RegExpParser::Advance() {
5105 if (next_pos_ < in()->length()) {
5106 StackLimitCheck check(isolate());
5107 if (check.HasOverflowed()) {
5108 ReportError(CStrVector(Isolate::kStackOverflowMessage));
5109 } else if (zone()->excess_allocation()) {
5110 ReportError(CStrVector("Regular expression too large"));
5112 current_ = in()->Get(next_pos_);
5116 current_ = kEndMarker;
5117 // Advance so that position() points to 1-after-the-last-character. This is
5118 // important so that Reset() to this position works correctly.
5119 next_pos_ = in()->length() + 1;
5125 void RegExpParser::Reset(int pos) {
5127 has_more_ = (pos < in()->length());
5132 void RegExpParser::Advance(int dist) {
5133 next_pos_ += dist - 1;
5138 bool RegExpParser::simple() {
5143 bool RegExpParser::IsSyntaxCharacter(uc32 c) {
5144 return c == '^' || c == '$' || c == '\\' || c == '.' || c == '*' ||
5145 c == '+' || c == '?' || c == '(' || c == ')' || c == '[' || c == ']' ||
5146 c == '{' || c == '}' || c == '|';
5150 RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
5152 *error_ = isolate()->factory()->NewStringFromAscii(message).ToHandleChecked();
5153 // Zip to the end to make sure the no more input is read.
5154 current_ = kEndMarker;
5155 next_pos_ = in()->length();
5162 RegExpTree* RegExpParser::ParsePattern() {
5163 RegExpTree* result = ParseDisjunction(CHECK_FAILED);
5164 DCHECK(!has_more());
5165 // If the result of parsing is a literal string atom, and it has the
5166 // same length as the input, then the atom is identical to the input.
5167 if (result->IsAtom() && result->AsAtom()->length() == in()->length()) {
5176 // Alternative | Disjunction
5184 RegExpTree* RegExpParser::ParseDisjunction() {
5185 // Used to store current state while parsing subexpressions.
5186 RegExpParserState initial_state(NULL, INITIAL, 0, zone());
5187 RegExpParserState* stored_state = &initial_state;
5188 // Cache the builder in a local variable for quick access.
5189 RegExpBuilder* builder = initial_state.builder();
5191 switch (current()) {
5193 if (stored_state->IsSubexpression()) {
5194 // Inside a parenthesized group when hitting end of input.
5195 ReportError(CStrVector("Unterminated group") CHECK_FAILED);
5197 DCHECK_EQ(INITIAL, stored_state->group_type());
5198 // Parsing completed successfully.
5199 return builder->ToRegExp();
5201 if (!stored_state->IsSubexpression()) {
5202 ReportError(CStrVector("Unmatched ')'") CHECK_FAILED);
5204 DCHECK_NE(INITIAL, stored_state->group_type());
5207 // End disjunction parsing and convert builder content to new single
5209 RegExpTree* body = builder->ToRegExp();
5211 int end_capture_index = captures_started();
5213 int capture_index = stored_state->capture_index();
5214 SubexpressionType group_type = stored_state->group_type();
5216 // Restore previous state.
5217 stored_state = stored_state->previous_state();
5218 builder = stored_state->builder();
5220 // Build result of subexpression.
5221 if (group_type == CAPTURE) {
5222 RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index);
5223 captures_->at(capture_index - 1) = capture;
5225 } else if (group_type != GROUPING) {
5226 DCHECK(group_type == POSITIVE_LOOKAHEAD ||
5227 group_type == NEGATIVE_LOOKAHEAD);
5228 bool is_positive = (group_type == POSITIVE_LOOKAHEAD);
5229 body = new(zone()) RegExpLookahead(body,
5231 end_capture_index - capture_index,
5234 builder->AddAtom(body);
5235 // For compatability with JSC and ES3, we allow quantifiers after
5236 // lookaheads, and break in all cases.
5241 builder->NewAlternative();
5247 return ReportError(CStrVector("Nothing to repeat"));
5251 builder->AddAssertion(
5252 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE));
5254 builder->AddAssertion(
5255 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
5256 set_contains_anchor();
5262 RegExpAssertion::AssertionType assertion_type =
5263 multiline_ ? RegExpAssertion::END_OF_LINE :
5264 RegExpAssertion::END_OF_INPUT;
5265 builder->AddAssertion(new(zone()) RegExpAssertion(assertion_type));
5270 // everything except \x0a, \x0d, \u2028 and \u2029
5271 ZoneList<CharacterRange>* ranges =
5272 new(zone()) ZoneList<CharacterRange>(2, zone());
5273 CharacterRange::AddClassEscape('.', ranges, zone());
5274 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
5275 builder->AddAtom(atom);
5279 SubexpressionType subexpr_type = CAPTURE;
5281 if (current() == '?') {
5284 subexpr_type = GROUPING;
5287 subexpr_type = POSITIVE_LOOKAHEAD;
5290 subexpr_type = NEGATIVE_LOOKAHEAD;
5293 ReportError(CStrVector("Invalid group") CHECK_FAILED);
5298 if (captures_ == NULL) {
5299 captures_ = new(zone()) ZoneList<RegExpCapture*>(2, zone());
5301 if (captures_started() >= kMaxCaptures) {
5302 ReportError(CStrVector("Too many captures") CHECK_FAILED);
5304 captures_->Add(NULL, zone());
5306 // Store current state and begin new disjunction parsing.
5307 stored_state = new(zone()) RegExpParserState(stored_state, subexpr_type,
5308 captures_started(), zone());
5309 builder = stored_state->builder();
5313 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED);
5314 builder->AddAtom(atom);
5322 return ReportError(CStrVector("\\ at end of pattern"));
5325 builder->AddAssertion(
5326 new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
5330 builder->AddAssertion(
5331 new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
5334 // CharacterClassEscape
5336 // CharacterClassEscape :: one of
5338 case 'd': case 'D': case 's': case 'S': case 'w': case 'W': {
5341 ZoneList<CharacterRange>* ranges =
5342 new(zone()) ZoneList<CharacterRange>(2, zone());
5343 CharacterRange::AddClassEscape(c, ranges, zone());
5344 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
5345 builder->AddAtom(atom);
5348 case '1': case '2': case '3': case '4': case '5': case '6':
5349 case '7': case '8': case '9': {
5351 if (ParseBackReferenceIndex(&index)) {
5352 RegExpCapture* capture = NULL;
5353 if (captures_ != NULL && index <= captures_->length()) {
5354 capture = captures_->at(index - 1);
5356 if (capture == NULL) {
5357 builder->AddEmpty();
5360 RegExpTree* atom = new(zone()) RegExpBackReference(capture);
5361 builder->AddAtom(atom);
5364 uc32 first_digit = Next();
5365 if (first_digit == '8' || first_digit == '9') {
5366 // If the 'u' flag is present, only syntax characters can be escaped,
5367 // no other identity escapes are allowed. If the 'u' flag is not
5368 // present, all identity escapes are allowed.
5369 if (!FLAG_harmony_unicode_regexps || !unicode_) {
5370 builder->AddCharacter(first_digit);
5373 return ReportError(CStrVector("Invalid escape"));
5381 uc32 octal = ParseOctalLiteral();
5382 builder->AddCharacter(octal);
5385 // ControlEscape :: one of
5389 builder->AddCharacter('\f');
5393 builder->AddCharacter('\n');
5397 builder->AddCharacter('\r');
5401 builder->AddCharacter('\t');
5405 builder->AddCharacter('\v');
5409 uc32 controlLetter = Next();
5410 // Special case if it is an ASCII letter.
5411 // Convert lower case letters to uppercase.
5412 uc32 letter = controlLetter & ~('a' ^ 'A');
5413 if (letter < 'A' || 'Z' < letter) {
5414 // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
5415 // This is outside the specification. We match JSC in
5416 // reading the backslash as a literal character instead
5417 // of as starting an escape.
5418 builder->AddCharacter('\\');
5421 builder->AddCharacter(controlLetter & 0x1f);
5428 if (ParseHexEscape(2, &value)) {
5429 builder->AddCharacter(value);
5430 } else if (!FLAG_harmony_unicode_regexps || !unicode_) {
5431 builder->AddCharacter('x');
5433 // If the 'u' flag is present, invalid escapes are not treated as
5434 // identity escapes.
5435 return ReportError(CStrVector("Invalid escape"));
5442 if (ParseUnicodeEscape(&value)) {
5443 builder->AddCharacter(value);
5444 } else if (!FLAG_harmony_unicode_regexps || !unicode_) {
5445 builder->AddCharacter('u');
5447 // If the 'u' flag is present, invalid escapes are not treated as
5448 // identity escapes.
5449 return ReportError(CStrVector("Invalid unicode escape"));
5455 // If the 'u' flag is present, only syntax characters can be escaped, no
5456 // other identity escapes are allowed. If the 'u' flag is not present,
5457 // all identity escapes are allowed.
5458 if (!FLAG_harmony_unicode_regexps || !unicode_ ||
5459 IsSyntaxCharacter(current())) {
5460 builder->AddCharacter(current());
5463 return ReportError(CStrVector("Invalid escape"));
5470 if (ParseIntervalQuantifier(&dummy, &dummy)) {
5471 ReportError(CStrVector("Nothing to repeat") CHECK_FAILED);
5476 builder->AddCharacter(current());
5479 } // end switch(current())
5483 switch (current()) {
5484 // QuantifierPrefix ::
5491 max = RegExpTree::kInfinity;
5496 max = RegExpTree::kInfinity;
5505 if (ParseIntervalQuantifier(&min, &max)) {
5507 ReportError(CStrVector("numbers out of order in {} quantifier.")
5517 RegExpQuantifier::QuantifierType quantifier_type = RegExpQuantifier::GREEDY;
5518 if (current() == '?') {
5519 quantifier_type = RegExpQuantifier::NON_GREEDY;
5521 } else if (FLAG_regexp_possessive_quantifier && current() == '+') {
5522 // FLAG_regexp_possessive_quantifier is a debug-only flag.
5523 quantifier_type = RegExpQuantifier::POSSESSIVE;
5526 builder->AddQuantifierToAtom(min, max, quantifier_type);
5532 // Currently only used in an DCHECK.
5533 static bool IsSpecialClassEscape(uc32 c) {
5546 // In order to know whether an escape is a backreference or not we have to scan
5547 // the entire regexp and find the number of capturing parentheses. However we
5548 // don't want to scan the regexp twice unless it is necessary. This mini-parser
5549 // is called when needed. It can see the difference between capturing and
5550 // noncapturing parentheses and can skip character classes and backslash-escaped
5552 void RegExpParser::ScanForCaptures() {
5553 // Start with captures started previous to current position
5554 int capture_count = captures_started();
5555 // Add count of captures after this position.
5557 while ((n = current()) != kEndMarker) {
5565 while ((c = current()) != kEndMarker) {
5570 if (c == ']') break;
5576 if (current() != '?') capture_count++;
5580 capture_count_ = capture_count;
5581 is_scanned_for_captures_ = true;
5585 bool RegExpParser::ParseBackReferenceIndex(int* index_out) {
5586 DCHECK_EQ('\\', current());
5587 DCHECK('1' <= Next() && Next() <= '9');
5588 // Try to parse a decimal literal that is no greater than the total number
5589 // of left capturing parentheses in the input.
5590 int start = position();
5591 int value = Next() - '0';
5595 if (IsDecimalDigit(c)) {
5596 value = 10 * value + (c - '0');
5597 if (value > kMaxCaptures) {
5606 if (value > captures_started()) {
5607 if (!is_scanned_for_captures_) {
5608 int saved_position = position();
5610 Reset(saved_position);
5612 if (value > capture_count_) {
5622 // QuantifierPrefix ::
5623 // { DecimalDigits }
5624 // { DecimalDigits , }
5625 // { DecimalDigits , DecimalDigits }
5627 // Returns true if parsing succeeds, and set the min_out and max_out
5628 // values. Values are truncated to RegExpTree::kInfinity if they overflow.
5629 bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
5630 DCHECK_EQ(current(), '{');
5631 int start = position();
5634 if (!IsDecimalDigit(current())) {
5638 while (IsDecimalDigit(current())) {
5639 int next = current() - '0';
5640 if (min > (RegExpTree::kInfinity - next) / 10) {
5641 // Overflow. Skip past remaining decimal digits and return -1.
5644 } while (IsDecimalDigit(current()));
5645 min = RegExpTree::kInfinity;
5648 min = 10 * min + next;
5652 if (current() == '}') {
5655 } else if (current() == ',') {
5657 if (current() == '}') {
5658 max = RegExpTree::kInfinity;
5661 while (IsDecimalDigit(current())) {
5662 int next = current() - '0';
5663 if (max > (RegExpTree::kInfinity - next) / 10) {
5666 } while (IsDecimalDigit(current()));
5667 max = RegExpTree::kInfinity;
5670 max = 10 * max + next;
5673 if (current() != '}') {
5689 uc32 RegExpParser::ParseOctalLiteral() {
5690 DCHECK(('0' <= current() && current() <= '7') || current() == kEndMarker);
5691 // For compatibility with some other browsers (not all), we parse
5692 // up to three octal digits with a value below 256.
5693 uc32 value = current() - '0';
5695 if ('0' <= current() && current() <= '7') {
5696 value = value * 8 + current() - '0';
5698 if (value < 32 && '0' <= current() && current() <= '7') {
5699 value = value * 8 + current() - '0';
5707 bool RegExpParser::ParseHexEscape(int length, uc32* value) {
5708 int start = position();
5710 for (int i = 0; i < length; ++i) {
5712 int d = HexValue(c);
5725 bool RegExpParser::ParseUnicodeEscape(uc32* value) {
5726 // Accept both \uxxxx and \u{xxxxxx} (if harmony unicode escapes are
5727 // allowed). In the latter case, the number of hex digits between { } is
5728 // arbitrary. \ and u have already been read.
5729 if (current() == '{' && FLAG_harmony_unicode_regexps && unicode_) {
5730 int start = position();
5732 if (ParseUnlimitedLengthHexNumber(0x10ffff, value)) {
5733 if (current() == '}') {
5741 // \u but no {, or \u{...} escapes not allowed.
5742 return ParseHexEscape(4, value);
5746 bool RegExpParser::ParseUnlimitedLengthHexNumber(int max_value, uc32* value) {
5748 int d = HexValue(current());
5754 if (x > max_value) {
5758 d = HexValue(current());
5765 uc32 RegExpParser::ParseClassCharacterEscape() {
5766 DCHECK(current() == '\\');
5767 DCHECK(has_next() && !IsSpecialClassEscape(Next()));
5769 switch (current()) {
5773 // ControlEscape :: one of
5791 uc32 controlLetter = Next();
5792 uc32 letter = controlLetter & ~('A' ^ 'a');
5793 // For compatibility with JSC, inside a character class
5794 // we also accept digits and underscore as control characters.
5795 if ((controlLetter >= '0' && controlLetter <= '9') ||
5796 controlLetter == '_' ||
5797 (letter >= 'A' && letter <= 'Z')) {
5799 // Control letters mapped to ASCII control characters in the range
5801 return controlLetter & 0x1f;
5803 // We match JSC in reading the backslash as a literal
5804 // character instead of as starting an escape.
5807 case '0': case '1': case '2': case '3': case '4': case '5':
5809 // For compatibility, we interpret a decimal escape that isn't
5810 // a back reference (and therefore either \0 or not valid according
5811 // to the specification) as a 1..3 digit octal character code.
5812 return ParseOctalLiteral();
5816 if (ParseHexEscape(2, &value)) {
5819 if (!FLAG_harmony_unicode_regexps || !unicode_) {
5820 // If \x is not followed by a two-digit hexadecimal, treat it
5821 // as an identity escape.
5824 // If the 'u' flag is present, invalid escapes are not treated as
5825 // identity escapes.
5826 ReportError(CStrVector("Invalid escape"));
5832 if (ParseUnicodeEscape(&value)) {
5835 if (!FLAG_harmony_unicode_regexps || !unicode_) {
5838 // If the 'u' flag is present, invalid escapes are not treated as
5839 // identity escapes.
5840 ReportError(CStrVector("Invalid unicode escape"));
5844 uc32 result = current();
5845 // If the 'u' flag is present, only syntax characters can be escaped, no
5846 // other identity escapes are allowed. If the 'u' flag is not present, all
5847 // identity escapes are allowed.
5848 if (!FLAG_harmony_unicode_regexps || !unicode_ ||
5849 IsSyntaxCharacter(result)) {
5853 ReportError(CStrVector("Invalid escape"));
5861 CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) {
5862 DCHECK_EQ(0, *char_class);
5863 uc32 first = current();
5864 if (first == '\\') {
5866 case 'w': case 'W': case 'd': case 'D': case 's': case 'S': {
5867 *char_class = Next();
5869 return CharacterRange::Singleton(0); // Return dummy value.
5872 return ReportError(CStrVector("\\ at end of pattern"));
5874 uc32 c = ParseClassCharacterEscape(CHECK_FAILED);
5875 return CharacterRange::Singleton(c);
5879 return CharacterRange::Singleton(first);
5884 static const uc16 kNoCharClass = 0;
5886 // Adds range or pre-defined character class to character ranges.
5887 // If char_class is not kInvalidClass, it's interpreted as a class
5888 // escape (i.e., 's' means whitespace, from '\s').
5889 static inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges,
5891 CharacterRange range,
5893 if (char_class != kNoCharClass) {
5894 CharacterRange::AddClassEscape(char_class, ranges, zone);
5896 ranges->Add(range, zone);
5901 RegExpTree* RegExpParser::ParseCharacterClass() {
5902 static const char* kUnterminated = "Unterminated character class";
5903 static const char* kRangeOutOfOrder = "Range out of order in character class";
5905 DCHECK_EQ(current(), '[');
5907 bool is_negated = false;
5908 if (current() == '^') {
5912 ZoneList<CharacterRange>* ranges =
5913 new(zone()) ZoneList<CharacterRange>(2, zone());
5914 while (has_more() && current() != ']') {
5915 uc16 char_class = kNoCharClass;
5916 CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED);
5917 if (current() == '-') {
5919 if (current() == kEndMarker) {
5920 // If we reach the end we break out of the loop and let the
5921 // following code report an error.
5923 } else if (current() == ']') {
5924 AddRangeOrEscape(ranges, char_class, first, zone());
5925 ranges->Add(CharacterRange::Singleton('-'), zone());
5928 uc16 char_class_2 = kNoCharClass;
5929 CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED);
5930 if (char_class != kNoCharClass || char_class_2 != kNoCharClass) {
5931 // Either end is an escaped character class. Treat the '-' verbatim.
5932 AddRangeOrEscape(ranges, char_class, first, zone());
5933 ranges->Add(CharacterRange::Singleton('-'), zone());
5934 AddRangeOrEscape(ranges, char_class_2, next, zone());
5937 if (first.from() > next.to()) {
5938 return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED);
5940 ranges->Add(CharacterRange::Range(first.from(), next.to()), zone());
5942 AddRangeOrEscape(ranges, char_class, first, zone());
5946 return ReportError(CStrVector(kUnterminated) CHECK_FAILED);
5949 if (ranges->length() == 0) {
5950 ranges->Add(CharacterRange::Everything(), zone());
5951 is_negated = !is_negated;
5953 return new(zone()) RegExpCharacterClass(ranges, is_negated);
5957 // ----------------------------------------------------------------------------
5958 // The Parser interface.
5960 bool RegExpParser::ParseRegExp(Isolate* isolate, Zone* zone,
5961 FlatStringReader* input, bool multiline,
5962 bool unicode, RegExpCompileData* result) {
5963 DCHECK(result != NULL);
5964 RegExpParser parser(input, &result->error, multiline, unicode, isolate, zone);
5965 RegExpTree* tree = parser.ParsePattern();
5966 if (parser.failed()) {
5967 DCHECK(tree == NULL);
5968 DCHECK(!result->error.is_null());
5970 DCHECK(tree != NULL);
5971 DCHECK(result->error.is_null());
5972 result->tree = tree;
5973 int capture_count = parser.captures_started();
5974 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
5975 result->contains_anchor = parser.contains_anchor();
5976 result->capture_count = capture_count;
5978 return !parser.failed();
5982 bool Parser::ParseStatic(ParseInfo* info) {
5983 Parser parser(info);
5984 if (parser.Parse(info)) {
5985 info->set_language_mode(info->literal()->language_mode());
5992 bool Parser::Parse(ParseInfo* info) {
5993 DCHECK(info->literal() == NULL);
5994 FunctionLiteral* result = NULL;
5995 // Ok to use Isolate here; this function is only called in the main thread.
5996 DCHECK(parsing_on_main_thread_);
5997 Isolate* isolate = info->isolate();
5998 pre_parse_timer_ = isolate->counters()->pre_parse();
5999 if (FLAG_trace_parse || allow_natives() || extension_ != NULL) {
6000 // If intrinsics are allowed, the Parser cannot operate independent of the
6001 // V8 heap because of Runtime. Tell the string table to internalize strings
6002 // and values right after they're created.
6003 ast_value_factory()->Internalize(isolate);
6006 if (info->is_lazy()) {
6007 DCHECK(!info->is_eval());
6008 if (info->shared_info()->is_function()) {
6009 result = ParseLazy(isolate, info);
6011 result = ParseProgram(isolate, info);
6014 SetCachedData(info);
6015 result = ParseProgram(isolate, info);
6017 info->set_literal(result);
6019 Internalize(isolate, info->script(), result == NULL);
6020 DCHECK(ast_value_factory()->IsInternalized());
6021 return (result != NULL);
6025 void Parser::ParseOnBackground(ParseInfo* info) {
6026 parsing_on_main_thread_ = false;
6028 DCHECK(info->literal() == NULL);
6029 FunctionLiteral* result = NULL;
6030 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
6032 CompleteParserRecorder recorder;
6033 if (produce_cached_parse_data()) log_ = &recorder;
6035 DCHECK(info->source_stream() != NULL);
6036 ExternalStreamingStream stream(info->source_stream(),
6037 info->source_stream_encoding());
6038 scanner_.Initialize(&stream);
6039 DCHECK(info->context().is_null() || info->context()->IsNativeContext());
6041 // When streaming, we don't know the length of the source until we have parsed
6042 // it. The raw data can be UTF-8, so we wouldn't know the source length until
6043 // we have decoded it anyway even if we knew the raw data length (which we
6044 // don't). We work around this by storing all the scopes which need their end
6045 // position set at the end of the script (the top scope and possible eval
6046 // scopes) and set their end position after we know the script length.
6047 result = DoParseProgram(info);
6049 info->set_literal(result);
6051 // We cannot internalize on a background thread; a foreground task will take
6052 // care of calling Parser::Internalize just before compilation.
6054 if (produce_cached_parse_data()) {
6055 if (result != NULL) *info->cached_data() = recorder.GetScriptData();
6061 ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
6062 return new (zone()) ParserTraits::TemplateLiteral(zone(), pos);
6066 void Parser::AddTemplateSpan(TemplateLiteralState* state, bool tail) {
6067 int pos = scanner()->location().beg_pos;
6068 int end = scanner()->location().end_pos - (tail ? 1 : 2);
6069 const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory());
6070 const AstRawString* trv = scanner()->CurrentRawSymbol(ast_value_factory());
6071 Literal* cooked = factory()->NewStringLiteral(tv, pos);
6072 Literal* raw = factory()->NewStringLiteral(trv, pos);
6073 (*state)->AddTemplateSpan(cooked, raw, end, zone());
6077 void Parser::AddTemplateExpression(TemplateLiteralState* state,
6078 Expression* expression) {
6079 (*state)->AddExpression(expression, zone());
6083 Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
6085 TemplateLiteral* lit = *state;
6086 int pos = lit->position();
6087 const ZoneList<Expression*>* cooked_strings = lit->cooked();
6088 const ZoneList<Expression*>* raw_strings = lit->raw();
6089 const ZoneList<Expression*>* expressions = lit->expressions();
6090 DCHECK_EQ(cooked_strings->length(), raw_strings->length());
6091 DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
6094 // Build tree of BinaryOps to simplify code-generation
6095 Expression* expr = cooked_strings->at(0);
6097 while (i < expressions->length()) {
6098 Expression* sub = expressions->at(i++);
6099 Expression* cooked_str = cooked_strings->at(i);
6101 // Let middle be ToString(sub).
6102 ZoneList<Expression*>* args =
6103 new (zone()) ZoneList<Expression*>(1, zone());
6104 args->Add(sub, zone());
6105 Expression* middle = factory()->NewCallRuntime(Runtime::kInlineToString,
6106 args, sub->position());
6108 expr = factory()->NewBinaryOperation(
6109 Token::ADD, factory()->NewBinaryOperation(
6110 Token::ADD, expr, middle, expr->position()),
6111 cooked_str, sub->position());
6115 uint32_t hash = ComputeTemplateLiteralHash(lit);
6117 int cooked_idx = function_state_->NextMaterializedLiteralIndex();
6118 int raw_idx = function_state_->NextMaterializedLiteralIndex();
6120 // $getTemplateCallSite
6121 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone());
6122 args->Add(factory()->NewArrayLiteral(
6123 const_cast<ZoneList<Expression*>*>(cooked_strings),
6124 cooked_idx, is_strong(language_mode()), pos),
6127 factory()->NewArrayLiteral(
6128 const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx,
6129 is_strong(language_mode()), pos),
6132 // Ensure hash is suitable as a Smi value
6133 Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash)));
6134 args->Add(factory()->NewSmiLiteral(hash_obj->value(), pos), zone());
6136 this->CheckPossibleEvalCall(tag, scope_);
6137 Expression* call_site = factory()->NewCallRuntime(
6138 Context::GET_TEMPLATE_CALL_SITE_INDEX, args, start);
6141 ZoneList<Expression*>* call_args =
6142 new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone());
6143 call_args->Add(call_site, zone());
6144 call_args->AddAll(*expressions, zone());
6145 return factory()->NewCall(tag, call_args, pos);
6150 uint32_t Parser::ComputeTemplateLiteralHash(const TemplateLiteral* lit) {
6151 const ZoneList<Expression*>* raw_strings = lit->raw();
6152 int total = raw_strings->length();
6155 uint32_t running_hash = 0;
6157 for (int index = 0; index < total; ++index) {
6159 running_hash = StringHasher::ComputeRunningHashOneByte(
6160 running_hash, "${}", 3);
6163 const AstRawString* raw_string =
6164 raw_strings->at(index)->AsLiteral()->raw_value()->AsString();
6165 if (raw_string->is_one_byte()) {
6166 const char* data = reinterpret_cast<const char*>(raw_string->raw_data());
6167 running_hash = StringHasher::ComputeRunningHashOneByte(
6168 running_hash, data, raw_string->length());
6170 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
6171 running_hash = StringHasher::ComputeRunningHash(running_hash, data,
6172 raw_string->length());
6176 return running_hash;
6180 ZoneList<v8::internal::Expression*>* Parser::PrepareSpreadArguments(
6181 ZoneList<v8::internal::Expression*>* list) {
6182 ZoneList<v8::internal::Expression*>* args =
6183 new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
6184 if (list->length() == 1) {
6185 // Spread-call with single spread argument produces an InternalArray
6186 // containing the values from the array.
6188 // Function is called or constructed with the produced array of arguments
6190 // EG: Apply(Func, Spread(spread0))
6191 ZoneList<Expression*>* spread_list =
6192 new (zone()) ZoneList<Expression*>(0, zone());
6193 spread_list->Add(list->at(0)->AsSpread()->expression(), zone());
6194 args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX,
6195 spread_list, RelocInfo::kNoPosition),
6199 // Spread-call with multiple arguments produces array literals for each
6200 // sequences of unspread arguments, and converts each spread iterable to
6201 // an Internal array. Finally, all of these produced arrays are flattened
6202 // into a single InternalArray, containing the arguments for the call.
6204 // EG: Apply(Func, Flatten([unspread0, unspread1], Spread(spread0),
6205 // Spread(spread1), [unspread2, unspread3]))
6207 int n = list->length();
6209 if (!list->at(i)->IsSpread()) {
6210 ZoneList<v8::internal::Expression*>* unspread =
6211 new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
6213 // Push array of unspread parameters
6214 while (i < n && !list->at(i)->IsSpread()) {
6215 unspread->Add(list->at(i++), zone());
6217 int literal_index = function_state_->NextMaterializedLiteralIndex();
6218 args->Add(factory()->NewArrayLiteral(unspread, literal_index,
6219 is_strong(language_mode()),
6220 RelocInfo::kNoPosition),
6226 // Push eagerly spread argument
6227 ZoneList<v8::internal::Expression*>* spread_list =
6228 new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
6229 spread_list->Add(list->at(i++)->AsSpread()->expression(), zone());
6230 args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX,
6231 spread_list, RelocInfo::kNoPosition),
6235 list = new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
6236 list->Add(factory()->NewCallRuntime(Context::SPREAD_ARGUMENTS_INDEX, args,
6237 RelocInfo::kNoPosition),
6245 Expression* Parser::SpreadCall(Expression* function,
6246 ZoneList<v8::internal::Expression*>* args,
6248 if (function->IsSuperCallReference()) {
6250 // %reflect_construct(%GetPrototype(<this-function>), args, new.target))
6251 ZoneList<Expression*>* tmp = new (zone()) ZoneList<Expression*>(1, zone());
6252 tmp->Add(function->AsSuperCallReference()->this_function_var(), zone());
6253 Expression* get_prototype =
6254 factory()->NewCallRuntime(Runtime::kGetPrototype, tmp, pos);
6255 args->InsertAt(0, get_prototype, zone());
6256 args->Add(function->AsSuperCallReference()->new_target_var(), zone());
6257 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args,
6260 if (function->IsProperty()) {
6262 if (function->AsProperty()->IsSuperAccess()) {
6264 ThisExpression(scope_, factory(), RelocInfo::kNoPosition);
6265 args->InsertAt(0, function, zone());
6266 args->InsertAt(1, home, zone());
6269 scope_->NewTemporary(ast_value_factory()->empty_string());
6270 VariableProxy* obj = factory()->NewVariableProxy(temp);
6271 Assignment* assign_obj = factory()->NewAssignment(
6272 Token::ASSIGN, obj, function->AsProperty()->obj(),
6273 RelocInfo::kNoPosition);
6274 function = factory()->NewProperty(
6275 assign_obj, function->AsProperty()->key(), RelocInfo::kNoPosition);
6276 args->InsertAt(0, function, zone());
6277 obj = factory()->NewVariableProxy(temp);
6278 args->InsertAt(1, obj, zone());
6282 args->InsertAt(0, function, zone());
6283 args->InsertAt(1, factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
6286 return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos);
6291 Expression* Parser::SpreadCallNew(Expression* function,
6292 ZoneList<v8::internal::Expression*>* args,
6294 args->InsertAt(0, function, zone());
6296 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
6298 } // namespace internal