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, .this_function)
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 args->Add(this_function_proxy, zone());
373 CallRuntime* call = factory()->NewCallRuntime(
374 Runtime::kInlineDefaultConstructorCallSuper, args, pos);
375 body->Add(factory()->NewReturnStatement(call, pos), zone());
378 materialized_literal_count = function_state.materialized_literal_count();
379 expected_property_count = function_state.expected_property_count();
382 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
383 name, ast_value_factory(), function_scope, body,
384 materialized_literal_count, expected_property_count, parameter_count,
385 FunctionLiteral::kNoDuplicateParameters,
386 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
387 FunctionLiteral::kShouldLazyCompile, kind, pos);
389 return function_literal;
393 // ----------------------------------------------------------------------------
394 // Target is a support class to facilitate manipulation of the
395 // Parser's target_stack_ (the stack of potential 'break' and
396 // 'continue' statement targets). Upon construction, a new target is
397 // added; it is removed upon destruction.
399 class Target BASE_EMBEDDED {
401 Target(Target** variable, BreakableStatement* statement)
402 : variable_(variable), statement_(statement), previous_(*variable) {
407 *variable_ = previous_;
410 Target* previous() { return previous_; }
411 BreakableStatement* statement() { return statement_; }
415 BreakableStatement* statement_;
420 class TargetScope BASE_EMBEDDED {
422 explicit TargetScope(Target** variable)
423 : variable_(variable), previous_(*variable) {
428 *variable_ = previous_;
437 // ----------------------------------------------------------------------------
438 // The CHECK_OK macro is a convenient macro to enforce error
439 // handling for functions that may fail (by returning !*ok).
441 // CAUTION: This macro appends extra statements after a call,
442 // thus it must never be used where only a single statement
443 // is correct (e.g. an if statement branch w/o braces)!
445 #define CHECK_OK ok); \
446 if (!*ok) return NULL; \
448 #define DUMMY ) // to make indentation work
451 #define CHECK_FAILED /**/); \
452 if (failed_) return NULL; \
454 #define DUMMY ) // to make indentation work
457 // ----------------------------------------------------------------------------
458 // Implementation of Parser
460 bool ParserTraits::IsEval(const AstRawString* identifier) const {
461 return identifier == parser_->ast_value_factory()->eval_string();
465 bool ParserTraits::IsArguments(const AstRawString* identifier) const {
466 return identifier == parser_->ast_value_factory()->arguments_string();
470 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const {
471 return IsEval(identifier) || IsArguments(identifier);
474 bool ParserTraits::IsUndefined(const AstRawString* identifier) const {
475 return identifier == parser_->ast_value_factory()->undefined_string();
478 bool ParserTraits::IsPrototype(const AstRawString* identifier) const {
479 return identifier == parser_->ast_value_factory()->prototype_string();
483 bool ParserTraits::IsConstructor(const AstRawString* identifier) const {
484 return identifier == parser_->ast_value_factory()->constructor_string();
488 bool ParserTraits::IsThisProperty(Expression* expression) {
489 DCHECK(expression != NULL);
490 Property* property = expression->AsProperty();
491 return property != NULL && property->obj()->IsVariableProxy() &&
492 property->obj()->AsVariableProxy()->is_this();
496 bool ParserTraits::IsIdentifier(Expression* expression) {
497 VariableProxy* operand = expression->AsVariableProxy();
498 return operand != NULL && !operand->is_this();
502 void ParserTraits::PushPropertyName(FuncNameInferrer* fni,
503 Expression* expression) {
504 if (expression->IsPropertyName()) {
505 fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
507 fni->PushLiteralName(
508 parser_->ast_value_factory()->anonymous_function_string());
513 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
515 DCHECK(left != NULL);
516 if (left->IsProperty() && right->IsFunctionLiteral()) {
517 right->AsFunctionLiteral()->set_pretenure();
522 void ParserTraits::CheckPossibleEvalCall(Expression* expression,
524 VariableProxy* callee = expression->AsVariableProxy();
525 if (callee != NULL &&
526 callee->raw_name() == parser_->ast_value_factory()->eval_string()) {
527 scope->DeclarationScope()->RecordEvalCall();
528 scope->RecordEvalCall();
533 Expression* ParserTraits::MarkExpressionAsAssigned(Expression* expression) {
534 VariableProxy* proxy =
535 expression != NULL ? expression->AsVariableProxy() : NULL;
536 if (proxy != NULL) proxy->set_is_assigned();
541 bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
542 Expression** x, Expression* y, Token::Value op, int pos,
543 AstNodeFactory* factory) {
544 if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
545 y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) {
546 double x_val = (*x)->AsLiteral()->raw_value()->AsNumber();
547 double y_val = y->AsLiteral()->raw_value()->AsNumber();
550 *x = factory->NewNumberLiteral(x_val + y_val, pos);
553 *x = factory->NewNumberLiteral(x_val - y_val, pos);
556 *x = factory->NewNumberLiteral(x_val * y_val, pos);
559 *x = factory->NewNumberLiteral(x_val / y_val, pos);
561 case Token::BIT_OR: {
562 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
563 *x = factory->NewNumberLiteral(value, pos);
566 case Token::BIT_AND: {
567 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
568 *x = factory->NewNumberLiteral(value, pos);
571 case Token::BIT_XOR: {
572 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
573 *x = factory->NewNumberLiteral(value, pos);
577 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
578 *x = factory->NewNumberLiteral(value, pos);
582 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
583 uint32_t value = DoubleToUint32(x_val) >> shift;
584 *x = factory->NewNumberLiteral(value, pos);
588 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
589 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
590 *x = factory->NewNumberLiteral(value, pos);
601 Expression* ParserTraits::BuildUnaryExpression(Expression* expression,
602 Token::Value op, int pos,
603 AstNodeFactory* factory) {
604 DCHECK(expression != NULL);
605 if (expression->IsLiteral()) {
606 const AstValue* literal = expression->AsLiteral()->raw_value();
607 if (op == Token::NOT) {
608 // Convert the literal to a boolean condition and negate it.
609 bool condition = literal->BooleanValue();
610 return factory->NewBooleanLiteral(!condition, pos);
611 } else if (literal->IsNumber()) {
612 // Compute some expressions involving only number literals.
613 double value = literal->AsNumber();
618 return factory->NewNumberLiteral(-value, pos);
620 return factory->NewNumberLiteral(~DoubleToInt32(value), pos);
626 // Desugar '+foo' => 'foo*1'
627 if (op == Token::ADD) {
628 return factory->NewBinaryOperation(
629 Token::MUL, expression, factory->NewNumberLiteral(1, pos, true), pos);
631 // The same idea for '-foo' => 'foo*(-1)'.
632 if (op == Token::SUB) {
633 return factory->NewBinaryOperation(
634 Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos);
636 // ...and one more time for '~foo' => 'foo^(~0)'.
637 if (op == Token::BIT_NOT) {
638 return factory->NewBinaryOperation(
639 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos);
641 return factory->NewUnaryOperation(op, expression, pos);
645 Expression* ParserTraits::NewThrowReferenceError(
646 MessageTemplate::Template message, int pos) {
647 return NewThrowError(Runtime::kNewReferenceError, message,
648 parser_->ast_value_factory()->empty_string(), pos);
652 Expression* ParserTraits::NewThrowSyntaxError(MessageTemplate::Template message,
653 const AstRawString* arg,
655 return NewThrowError(Runtime::kNewSyntaxError, message, arg, pos);
659 Expression* ParserTraits::NewThrowTypeError(MessageTemplate::Template message,
660 const AstRawString* arg, int pos) {
661 return NewThrowError(Runtime::kNewTypeError, message, arg, pos);
665 Expression* ParserTraits::NewThrowError(Runtime::FunctionId id,
666 MessageTemplate::Template message,
667 const AstRawString* arg, int pos) {
668 Zone* zone = parser_->zone();
669 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone);
670 args->Add(parser_->factory()->NewSmiLiteral(message, pos), zone);
671 args->Add(parser_->factory()->NewStringLiteral(arg, pos), zone);
672 CallRuntime* call_constructor =
673 parser_->factory()->NewCallRuntime(id, args, pos);
674 return parser_->factory()->NewThrow(call_constructor, pos);
678 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
679 MessageTemplate::Template message,
680 const char* arg, ParseErrorType error_type) {
681 if (parser_->stack_overflow()) {
682 // Suppress the error message (syntax error or such) in the presence of a
683 // stack overflow. The isolate allows only one pending exception at at time
684 // and we want to report the stack overflow later.
687 parser_->pending_error_handler_.ReportMessageAt(source_location.beg_pos,
688 source_location.end_pos,
689 message, arg, error_type);
693 void ParserTraits::ReportMessage(MessageTemplate::Template message,
694 const char* arg, ParseErrorType error_type) {
695 Scanner::Location source_location = parser_->scanner()->location();
696 ReportMessageAt(source_location, message, arg, error_type);
700 void ParserTraits::ReportMessage(MessageTemplate::Template message,
701 const AstRawString* arg,
702 ParseErrorType error_type) {
703 Scanner::Location source_location = parser_->scanner()->location();
704 ReportMessageAt(source_location, message, arg, error_type);
708 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
709 MessageTemplate::Template message,
710 const AstRawString* arg,
711 ParseErrorType error_type) {
712 if (parser_->stack_overflow()) {
713 // Suppress the error message (syntax error or such) in the presence of a
714 // stack overflow. The isolate allows only one pending exception at at time
715 // and we want to report the stack overflow later.
718 parser_->pending_error_handler_.ReportMessageAt(source_location.beg_pos,
719 source_location.end_pos,
720 message, arg, error_type);
724 const AstRawString* ParserTraits::GetSymbol(Scanner* scanner) {
725 const AstRawString* result =
726 parser_->scanner()->CurrentSymbol(parser_->ast_value_factory());
727 DCHECK(result != NULL);
732 const AstRawString* ParserTraits::GetNumberAsSymbol(Scanner* scanner) {
733 double double_value = parser_->scanner()->DoubleValue();
736 DoubleToCString(double_value, Vector<char>(array, arraysize(array)));
737 return parser_->ast_value_factory()->GetOneByteString(string);
741 const AstRawString* ParserTraits::GetNextSymbol(Scanner* scanner) {
742 return parser_->scanner()->NextSymbol(parser_->ast_value_factory());
746 Expression* ParserTraits::ThisExpression(Scope* scope, AstNodeFactory* factory,
748 return scope->NewUnresolved(factory,
749 parser_->ast_value_factory()->this_string(),
750 Variable::THIS, pos, pos + 4);
754 Expression* ParserTraits::SuperPropertyReference(Scope* scope,
755 AstNodeFactory* factory,
757 // this_function[home_object_symbol]
758 VariableProxy* this_function_proxy = scope->NewUnresolved(
759 factory, parser_->ast_value_factory()->this_function_string(),
760 Variable::NORMAL, pos);
761 Expression* home_object_symbol_literal =
762 factory->NewSymbolLiteral("home_object_symbol", RelocInfo::kNoPosition);
763 Expression* home_object = factory->NewProperty(
764 this_function_proxy, home_object_symbol_literal, pos);
765 return factory->NewSuperPropertyReference(
766 ThisExpression(scope, factory, pos)->AsVariableProxy(), home_object, pos);
770 Expression* ParserTraits::SuperCallReference(Scope* scope,
771 AstNodeFactory* factory, int pos) {
772 VariableProxy* new_target_proxy = scope->NewUnresolved(
773 factory, parser_->ast_value_factory()->new_target_string(),
774 Variable::NORMAL, pos);
775 VariableProxy* this_function_proxy = scope->NewUnresolved(
776 factory, parser_->ast_value_factory()->this_function_string(),
777 Variable::NORMAL, pos);
778 return factory->NewSuperCallReference(
779 ThisExpression(scope, factory, pos)->AsVariableProxy(), new_target_proxy,
780 this_function_proxy, pos);
784 Expression* ParserTraits::NewTargetExpression(Scope* scope,
785 AstNodeFactory* factory,
787 static const int kNewTargetStringLength = 10;
788 auto proxy = scope->NewUnresolved(
789 factory, parser_->ast_value_factory()->new_target_string(),
790 Variable::NORMAL, pos, pos + kNewTargetStringLength);
791 proxy->set_is_new_target();
796 Expression* ParserTraits::DefaultConstructor(bool call_super, Scope* scope,
797 int pos, int end_pos,
799 return parser_->DefaultConstructor(call_super, scope, pos, end_pos, mode);
803 Literal* ParserTraits::ExpressionFromLiteral(Token::Value token, int pos,
805 AstNodeFactory* factory) {
807 case Token::NULL_LITERAL:
808 return factory->NewNullLiteral(pos);
809 case Token::TRUE_LITERAL:
810 return factory->NewBooleanLiteral(true, pos);
811 case Token::FALSE_LITERAL:
812 return factory->NewBooleanLiteral(false, pos);
814 int value = scanner->smi_value();
815 return factory->NewSmiLiteral(value, pos);
817 case Token::NUMBER: {
818 bool has_dot = scanner->ContainsDot();
819 double value = scanner->DoubleValue();
820 return factory->NewNumberLiteral(value, pos, has_dot);
829 Expression* ParserTraits::ExpressionFromIdentifier(const AstRawString* name,
833 AstNodeFactory* factory) {
834 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name);
835 return scope->NewUnresolved(factory, name, Variable::NORMAL, start_position,
840 Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner,
841 AstNodeFactory* factory) {
842 const AstRawString* symbol = GetSymbol(scanner);
843 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol);
844 return factory->NewStringLiteral(symbol, pos);
848 Expression* ParserTraits::GetIterator(Expression* iterable,
849 AstNodeFactory* factory) {
850 Expression* iterator_symbol_literal =
851 factory->NewSymbolLiteral("iterator_symbol", RelocInfo::kNoPosition);
852 int pos = iterable->position();
854 factory->NewProperty(iterable, iterator_symbol_literal, pos);
855 Zone* zone = parser_->zone();
856 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(0, zone);
857 return factory->NewCall(prop, args, pos);
861 Literal* ParserTraits::GetLiteralTheHole(int position,
862 AstNodeFactory* factory) {
863 return factory->NewTheHoleLiteral(RelocInfo::kNoPosition);
867 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) {
868 return parser_->ParseV8Intrinsic(ok);
872 FunctionLiteral* ParserTraits::ParseFunctionLiteral(
873 const AstRawString* name, Scanner::Location function_name_location,
874 FunctionNameValidity function_name_validity, FunctionKind kind,
875 int function_token_position, FunctionLiteral::FunctionType type,
876 FunctionLiteral::ArityRestriction arity_restriction,
877 LanguageMode language_mode, bool* ok) {
878 return parser_->ParseFunctionLiteral(
879 name, function_name_location, function_name_validity, kind,
880 function_token_position, type, arity_restriction, language_mode, ok);
884 ClassLiteral* ParserTraits::ParseClassLiteral(
885 const AstRawString* name, Scanner::Location class_name_location,
886 bool name_is_strict_reserved, int pos, bool* ok) {
887 return parser_->ParseClassLiteral(name, class_name_location,
888 name_is_strict_reserved, pos, ok);
892 Parser::Parser(ParseInfo* info)
893 : ParserBase<ParserTraits>(info->zone(), &scanner_, info->stack_limit(),
894 info->extension(), info->ast_value_factory(),
896 scanner_(info->unicode_cache()),
897 reusable_preparser_(NULL),
898 original_scope_(NULL),
900 compile_options_(info->compile_options()),
901 cached_parse_data_(NULL),
902 total_preparse_skipped_(0),
903 pre_parse_timer_(NULL),
904 parsing_on_main_thread_(true) {
905 // Even though we were passed ParseInfo, we should not store it in
906 // Parser - this makes sure that Isolate is not accidentally accessed via
907 // ParseInfo during background parsing.
908 DCHECK(!info->script().is_null() || info->source_stream() != NULL);
909 set_allow_lazy(info->allow_lazy_parsing());
910 set_allow_natives(FLAG_allow_natives_syntax || info->is_native());
911 set_allow_harmony_arrow_functions(FLAG_harmony_arrow_functions);
912 set_allow_harmony_sloppy(FLAG_harmony_sloppy);
913 set_allow_harmony_sloppy_function(FLAG_harmony_sloppy_function);
914 set_allow_harmony_sloppy_let(FLAG_harmony_sloppy_let);
915 set_allow_harmony_rest_parameters(FLAG_harmony_rest_parameters);
916 set_allow_harmony_default_parameters(FLAG_harmony_default_parameters);
917 set_allow_harmony_spreadcalls(FLAG_harmony_spreadcalls);
918 set_allow_harmony_destructuring(FLAG_harmony_destructuring);
919 set_allow_harmony_spread_arrays(FLAG_harmony_spread_arrays);
920 set_allow_harmony_new_target(FLAG_harmony_new_target);
921 set_allow_strong_mode(FLAG_strong_mode);
922 set_allow_legacy_const(FLAG_legacy_const);
923 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
925 use_counts_[feature] = 0;
927 if (info->ast_value_factory() == NULL) {
928 // info takes ownership of AstValueFactory.
929 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed()));
930 info->set_ast_value_factory_owned();
931 ast_value_factory_ = info->ast_value_factory();
936 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
937 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
938 // see comment for HistogramTimerScope class.
940 // It's OK to use the Isolate & counters here, since this function is only
941 // called in the main thread.
942 DCHECK(parsing_on_main_thread_);
944 HistogramTimerScope timer_scope(isolate->counters()->parse(), true);
945 Handle<String> source(String::cast(info->script()->source()));
946 isolate->counters()->total_parse_size()->Increment(source->length());
947 base::ElapsedTimer timer;
948 if (FLAG_trace_parse) {
951 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
953 // Initialize parser state.
954 CompleteParserRecorder recorder;
956 if (produce_cached_parse_data()) {
958 } else if (consume_cached_parse_data()) {
959 cached_parse_data_->Initialize();
962 source = String::Flatten(source);
963 FunctionLiteral* result;
965 if (source->IsExternalTwoByteString()) {
966 // Notice that the stream is destroyed at the end of the branch block.
967 // The last line of the blocks can't be moved outside, even though they're
969 ExternalTwoByteStringUtf16CharacterStream stream(
970 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
971 scanner_.Initialize(&stream);
972 result = DoParseProgram(info);
974 GenericStringUtf16CharacterStream stream(source, 0, source->length());
975 scanner_.Initialize(&stream);
976 result = DoParseProgram(info);
978 if (result != NULL) {
979 DCHECK_EQ(scanner_.peek_location().beg_pos, source->length());
981 HandleSourceURLComments(isolate, info->script());
983 if (FLAG_trace_parse && result != NULL) {
984 double ms = timer.Elapsed().InMillisecondsF();
985 if (info->is_eval()) {
986 PrintF("[parsing eval");
987 } else if (info->script()->name()->IsString()) {
988 String* name = String::cast(info->script()->name());
989 base::SmartArrayPointer<char> name_chars = name->ToCString();
990 PrintF("[parsing script: %s", name_chars.get());
992 PrintF("[parsing script");
994 PrintF(" - took %0.3f ms]\n", ms);
996 if (produce_cached_parse_data()) {
997 if (result != NULL) *info->cached_data() = recorder.GetScriptData();
1004 FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
1005 // Note that this function can be called from the main thread or from a
1006 // background thread. We should not access anything Isolate / heap dependent
1007 // via ParseInfo, and also not pass it forward.
1008 DCHECK(scope_ == NULL);
1009 DCHECK(target_stack_ == NULL);
1011 Mode parsing_mode = FLAG_lazy && allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY;
1012 if (allow_natives() || extension_ != NULL) parsing_mode = PARSE_EAGERLY;
1014 FunctionLiteral* result = NULL;
1016 // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native
1017 // context, which will have the "this" binding for script scopes.
1018 Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
1019 info->set_script_scope(scope);
1020 if (!info->context().is_null() && !info->context()->IsNativeContext()) {
1021 scope = Scope::DeserializeScopeChain(info->isolate(), zone(),
1022 *info->context(), scope);
1023 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this
1024 // means the Parser cannot operate independent of the V8 heap. Tell the
1025 // string table to internalize strings and values right after they're
1026 // created. This kind of parsing can only be done in the main thread.
1027 DCHECK(parsing_on_main_thread_);
1028 ast_value_factory()->Internalize(info->isolate());
1030 original_scope_ = scope;
1031 if (info->is_eval()) {
1032 if (!scope->is_script_scope() || is_strict(info->language_mode())) {
1033 parsing_mode = PARSE_EAGERLY;
1035 scope = NewScope(scope, EVAL_SCOPE);
1036 } else if (info->is_module()) {
1037 scope = NewScope(scope, MODULE_SCOPE);
1040 scope->set_start_position(0);
1042 // Enter 'scope' with the given parsing mode.
1043 ParsingModeScope parsing_mode_scope(this, parsing_mode);
1044 AstNodeFactory function_factory(ast_value_factory());
1045 FunctionState function_state(&function_state_, &scope_, scope,
1046 kNormalFunction, &function_factory);
1048 scope_->SetLanguageMode(info->language_mode());
1049 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
1051 int beg_pos = scanner()->location().beg_pos;
1052 if (info->is_module()) {
1053 ParseModuleItemList(body, &ok);
1055 ParseStatementList(body, Token::EOS, &ok);
1058 // The parser will peek but not consume EOS. Our scope logically goes all
1059 // the way to the EOS, though.
1060 scope->set_end_position(scanner()->peek_location().beg_pos);
1062 if (ok && is_strict(language_mode())) {
1063 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
1065 if (ok && (is_strict(language_mode()) || allow_harmony_sloppy())) {
1066 CheckConflictingVarDeclarations(scope_, &ok);
1069 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
1070 if (body->length() != 1 ||
1071 !body->at(0)->IsExpressionStatement() ||
1072 !body->at(0)->AsExpressionStatement()->
1073 expression()->IsFunctionLiteral()) {
1074 ReportMessage(MessageTemplate::kSingleFunctionLiteral);
1080 result = factory()->NewFunctionLiteral(
1081 ast_value_factory()->empty_string(), ast_value_factory(), scope_,
1082 body, function_state.materialized_literal_count(),
1083 function_state.expected_property_count(), 0,
1084 FunctionLiteral::kNoDuplicateParameters,
1085 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval,
1086 FunctionLiteral::kShouldLazyCompile, FunctionKind::kNormalFunction,
1091 // Make sure the target stack is empty.
1092 DCHECK(target_stack_ == NULL);
1098 FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info) {
1099 // It's OK to use the Isolate & counters here, since this function is only
1100 // called in the main thread.
1101 DCHECK(parsing_on_main_thread_);
1102 HistogramTimerScope timer_scope(isolate->counters()->parse_lazy());
1103 Handle<String> source(String::cast(info->script()->source()));
1104 isolate->counters()->total_parse_size()->Increment(source->length());
1105 base::ElapsedTimer timer;
1106 if (FLAG_trace_parse) {
1109 Handle<SharedFunctionInfo> shared_info = info->shared_info();
1111 // Initialize parser state.
1112 source = String::Flatten(source);
1113 FunctionLiteral* result;
1114 if (source->IsExternalTwoByteString()) {
1115 ExternalTwoByteStringUtf16CharacterStream stream(
1116 Handle<ExternalTwoByteString>::cast(source),
1117 shared_info->start_position(),
1118 shared_info->end_position());
1119 result = ParseLazy(isolate, info, &stream);
1121 GenericStringUtf16CharacterStream stream(source,
1122 shared_info->start_position(),
1123 shared_info->end_position());
1124 result = ParseLazy(isolate, info, &stream);
1127 if (FLAG_trace_parse && result != NULL) {
1128 double ms = timer.Elapsed().InMillisecondsF();
1129 base::SmartArrayPointer<char> name_chars =
1130 result->debug_name()->ToCString();
1131 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
1137 FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info,
1138 Utf16CharacterStream* source) {
1139 Handle<SharedFunctionInfo> shared_info = info->shared_info();
1140 scanner_.Initialize(source);
1141 DCHECK(scope_ == NULL);
1142 DCHECK(target_stack_ == NULL);
1144 Handle<String> name(String::cast(shared_info->name()));
1145 DCHECK(ast_value_factory());
1146 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
1147 const AstRawString* raw_name = ast_value_factory()->GetString(name);
1148 fni_->PushEnclosingName(raw_name);
1150 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1152 // Place holder for the result.
1153 FunctionLiteral* result = NULL;
1156 // Parse the function literal.
1157 Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
1158 info->set_script_scope(scope);
1159 if (!info->closure().is_null()) {
1160 // Ok to use Isolate here, since lazy function parsing is only done in the
1162 DCHECK(parsing_on_main_thread_);
1163 scope = Scope::DeserializeScopeChain(isolate, zone(),
1164 info->closure()->context(), scope);
1166 original_scope_ = scope;
1167 AstNodeFactory function_factory(ast_value_factory());
1168 FunctionState function_state(&function_state_, &scope_, scope,
1169 shared_info->kind(), &function_factory);
1170 DCHECK(is_sloppy(scope->language_mode()) ||
1171 is_strict(info->language_mode()));
1172 DCHECK(info->language_mode() == shared_info->language_mode());
1173 FunctionLiteral::FunctionType function_type = shared_info->is_expression()
1174 ? (shared_info->is_anonymous()
1175 ? FunctionLiteral::ANONYMOUS_EXPRESSION
1176 : FunctionLiteral::NAMED_EXPRESSION)
1177 : FunctionLiteral::DECLARATION;
1180 if (shared_info->is_arrow()) {
1182 NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
1183 scope->SetLanguageMode(shared_info->language_mode());
1184 scope->set_start_position(shared_info->start_position());
1185 ExpressionClassifier formals_classifier;
1186 ParserFormalParameters formals(scope);
1187 Checkpoint checkpoint(this);
1189 // Parsing patterns as variable reference expression creates
1190 // NewUnresolved references in current scope. Entrer arrow function
1191 // scope for formal parameter parsing.
1192 BlockState block_state(&scope_, scope);
1193 if (Check(Token::LPAREN)) {
1194 // '(' StrictFormalParameters ')'
1195 ParseFormalParameterList(&formals, &formals_classifier, &ok);
1196 if (ok) ok = Check(Token::RPAREN);
1198 // BindingIdentifier
1199 ParseFormalParameter(&formals, &formals_classifier, &ok);
1201 DeclareFormalParameter(formals.scope, formals.at(0),
1202 &formals_classifier);
1208 checkpoint.Restore(&formals.materialized_literals_count);
1209 Expression* expression =
1210 ParseArrowFunctionLiteral(formals, formals_classifier, &ok);
1212 // Scanning must end at the same position that was recorded
1213 // previously. If not, parsing has been interrupted due to a stack
1214 // overflow, at which point the partially parsed arrow function
1215 // concise body happens to be a valid expression. This is a problem
1216 // only for arrow functions with single expression bodies, since there
1217 // is no end token such as "}" for normal functions.
1218 if (scanner()->location().end_pos == shared_info->end_position()) {
1219 // The pre-parser saw an arrow function here, so the full parser
1220 // must produce a FunctionLiteral.
1221 DCHECK(expression->IsFunctionLiteral());
1222 result = expression->AsFunctionLiteral();
1228 } else if (shared_info->is_default_constructor()) {
1229 result = DefaultConstructor(IsSubclassConstructor(shared_info->kind()),
1230 scope, shared_info->start_position(),
1231 shared_info->end_position(),
1232 shared_info->language_mode());
1234 result = ParseFunctionLiteral(
1235 raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck,
1236 shared_info->kind(), RelocInfo::kNoPosition, function_type,
1237 FunctionLiteral::NORMAL_ARITY, shared_info->language_mode(), &ok);
1239 // Make sure the results agree.
1240 DCHECK(ok == (result != NULL));
1243 // Make sure the target stack is empty.
1244 DCHECK(target_stack_ == NULL);
1246 if (result != NULL) {
1247 Handle<String> inferred_name(shared_info->inferred_name());
1248 result->set_inferred_name(inferred_name);
1254 void* Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token,
1257 // (StatementListItem)* <end_token>
1259 // Allocate a target stack to use for this set of source
1260 // elements. This way, all scripts and functions get their own
1261 // target stack thus avoiding illegal breaks and continues across
1263 TargetScope scope(&this->target_stack_);
1265 DCHECK(body != NULL);
1266 bool directive_prologue = true; // Parsing directive prologue.
1268 while (peek() != end_token) {
1269 if (directive_prologue && peek() != Token::STRING) {
1270 directive_prologue = false;
1273 Scanner::Location token_loc = scanner()->peek_location();
1274 Scanner::Location old_this_loc = function_state_->this_location();
1275 Scanner::Location old_super_loc = function_state_->super_location();
1276 Statement* stat = ParseStatementListItem(CHECK_OK);
1278 if (is_strong(language_mode()) &&
1279 scope_->is_function_scope() &&
1280 i::IsConstructor(function_state_->kind())) {
1281 Scanner::Location this_loc = function_state_->this_location();
1282 Scanner::Location super_loc = function_state_->super_location();
1283 if (this_loc.beg_pos != old_this_loc.beg_pos &&
1284 this_loc.beg_pos != token_loc.beg_pos) {
1285 ReportMessageAt(this_loc, MessageTemplate::kStrongConstructorThis);
1289 if (super_loc.beg_pos != old_super_loc.beg_pos &&
1290 super_loc.beg_pos != token_loc.beg_pos) {
1291 ReportMessageAt(super_loc, MessageTemplate::kStrongConstructorSuper);
1297 if (stat == NULL || stat->IsEmpty()) {
1298 directive_prologue = false; // End of directive prologue.
1302 if (directive_prologue) {
1303 // A shot at a directive.
1304 ExpressionStatement* e_stat;
1306 // Still processing directive prologue?
1307 if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1308 (literal = e_stat->expression()->AsLiteral()) != NULL &&
1309 literal->raw_value()->IsString()) {
1310 // Check "use strict" directive (ES5 14.1), "use asm" directive, and
1311 // "use strong" directive (experimental).
1312 bool use_strict_found =
1313 literal->raw_value()->AsString() ==
1314 ast_value_factory()->use_strict_string() &&
1315 token_loc.end_pos - token_loc.beg_pos ==
1316 ast_value_factory()->use_strict_string()->length() + 2;
1317 bool use_strong_found =
1318 allow_strong_mode() &&
1319 literal->raw_value()->AsString() ==
1320 ast_value_factory()->use_strong_string() &&
1321 token_loc.end_pos - token_loc.beg_pos ==
1322 ast_value_factory()->use_strong_string()->length() + 2;
1323 if (use_strict_found || use_strong_found) {
1324 // Strong mode implies strict mode. If there are several "use strict"
1325 // / "use strong" directives, do the strict mode changes only once.
1326 if (is_sloppy(scope_->language_mode())) {
1327 scope_->SetLanguageMode(
1328 static_cast<LanguageMode>(scope_->language_mode() | STRICT));
1331 if (use_strong_found) {
1332 scope_->SetLanguageMode(
1333 static_cast<LanguageMode>(scope_->language_mode() | STRONG));
1334 if (i::IsConstructor(function_state_->kind())) {
1335 // "use strong" cannot occur in a class constructor body, to avoid
1336 // unintuitive strong class object semantics.
1337 ParserTraits::ReportMessageAt(
1338 token_loc, MessageTemplate::kStrongConstructorDirective);
1343 if (!scope_->HasSimpleParameters()) {
1344 // TC39 deemed "use strict" directives to be an error when occurring
1345 // in the body of a function with non-simple parameter list, on
1346 // 29/7/2015. https://goo.gl/ueA7Ln
1348 // In V8, this also applies to "use strong " directives.
1349 const AstRawString* string = literal->raw_value()->AsString();
1350 ParserTraits::ReportMessageAt(
1351 token_loc, MessageTemplate::kIllegalLanguageModeDirective,
1356 // Because declarations in strict eval code don't leak into the scope
1357 // of the eval call, it is likely that functions declared in strict
1358 // eval code will be used within the eval code, so lazy parsing is
1359 // probably not a win.
1360 if (scope_->is_eval_scope()) mode_ = PARSE_EAGERLY;
1361 } else if (literal->raw_value()->AsString() ==
1362 ast_value_factory()->use_asm_string() &&
1363 token_loc.end_pos - token_loc.beg_pos ==
1364 ast_value_factory()->use_asm_string()->length() + 2) {
1365 // Store the usage count; The actual use counter on the isolate is
1366 // incremented after parsing is done.
1367 ++use_counts_[v8::Isolate::kUseAsm];
1368 scope_->SetAsmModule();
1371 // End of the directive prologue.
1372 directive_prologue = false;
1376 body->Add(stat, zone());
1383 Statement* Parser::ParseStatementListItem(bool* ok) {
1384 // (Ecma 262 6th Edition, 13.1):
1385 // StatementListItem:
1389 if (peek() != Token::CLASS) {
1390 // No more classes follow; reset the start position for the consecutive
1391 // class declaration group.
1392 scope_->set_class_declaration_group_start(-1);
1396 case Token::FUNCTION:
1397 return ParseFunctionDeclaration(NULL, ok);
1399 if (scope_->class_declaration_group_start() < 0) {
1400 scope_->set_class_declaration_group_start(
1401 scanner()->peek_location().beg_pos);
1403 return ParseClassDeclaration(NULL, ok);
1405 if (allow_const()) {
1406 return ParseVariableStatement(kStatementListItem, NULL, ok);
1410 return ParseVariableStatement(kStatementListItem, NULL, ok);
1412 if (IsNextLetKeyword()) {
1413 return ParseVariableStatement(kStatementListItem, NULL, ok);
1419 return ParseStatement(NULL, ok);
1423 Statement* Parser::ParseModuleItem(bool* ok) {
1424 // (Ecma 262 6th Edition, 15.2):
1426 // ImportDeclaration
1427 // ExportDeclaration
1428 // StatementListItem
1432 return ParseImportDeclaration(ok);
1434 return ParseExportDeclaration(ok);
1436 return ParseStatementListItem(ok);
1441 void* Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) {
1442 // (Ecma 262 6th Edition, 15.2):
1449 DCHECK(scope_->is_module_scope());
1450 scope_->SetLanguageMode(
1451 static_cast<LanguageMode>(scope_->language_mode() | STRICT));
1453 while (peek() != Token::EOS) {
1454 Statement* stat = ParseModuleItem(CHECK_OK);
1455 if (stat && !stat->IsEmpty()) {
1456 body->Add(stat, zone());
1460 // Check that all exports are bound.
1461 ModuleDescriptor* descriptor = scope_->module();
1462 for (ModuleDescriptor::Iterator it = descriptor->iterator(); !it.done();
1464 if (scope_->LookupLocal(it.local_name()) == NULL) {
1465 // TODO(adamk): Pass both local_name and export_name once ParserTraits
1466 // supports multiple arg error messages.
1467 // Also try to report this at a better location.
1468 ParserTraits::ReportMessage(MessageTemplate::kModuleExportUndefined,
1475 scope_->module()->Freeze();
1480 const AstRawString* Parser::ParseModuleSpecifier(bool* ok) {
1481 // ModuleSpecifier :
1484 Expect(Token::STRING, CHECK_OK);
1485 return GetSymbol(scanner());
1489 void* Parser::ParseExportClause(ZoneList<const AstRawString*>* export_names,
1490 ZoneList<Scanner::Location>* export_locations,
1491 ZoneList<const AstRawString*>* local_names,
1492 Scanner::Location* reserved_loc, bool* ok) {
1495 // '{' ExportsList '}'
1496 // '{' ExportsList ',' '}'
1500 // ExportsList ',' ExportSpecifier
1502 // ExportSpecifier :
1504 // IdentifierName 'as' IdentifierName
1506 Expect(Token::LBRACE, CHECK_OK);
1508 Token::Value name_tok;
1509 while ((name_tok = peek()) != Token::RBRACE) {
1510 // Keep track of the first reserved word encountered in case our
1511 // caller needs to report an error.
1512 if (!reserved_loc->IsValid() &&
1513 !Token::IsIdentifier(name_tok, STRICT, false)) {
1514 *reserved_loc = scanner()->location();
1516 const AstRawString* local_name = ParseIdentifierName(CHECK_OK);
1517 const AstRawString* export_name = NULL;
1518 if (CheckContextualKeyword(CStrVector("as"))) {
1519 export_name = ParseIdentifierName(CHECK_OK);
1521 if (export_name == NULL) {
1522 export_name = local_name;
1524 export_names->Add(export_name, zone());
1525 local_names->Add(local_name, zone());
1526 export_locations->Add(scanner()->location(), zone());
1527 if (peek() == Token::RBRACE) break;
1528 Expect(Token::COMMA, CHECK_OK);
1531 Expect(Token::RBRACE, CHECK_OK);
1537 ZoneList<ImportDeclaration*>* Parser::ParseNamedImports(int pos, bool* ok) {
1540 // '{' ImportsList '}'
1541 // '{' ImportsList ',' '}'
1545 // ImportsList ',' ImportSpecifier
1547 // ImportSpecifier :
1548 // BindingIdentifier
1549 // IdentifierName 'as' BindingIdentifier
1551 Expect(Token::LBRACE, CHECK_OK);
1553 ZoneList<ImportDeclaration*>* result =
1554 new (zone()) ZoneList<ImportDeclaration*>(1, zone());
1555 while (peek() != Token::RBRACE) {
1556 const AstRawString* import_name = ParseIdentifierName(CHECK_OK);
1557 const AstRawString* local_name = import_name;
1558 // In the presence of 'as', the left-side of the 'as' can
1559 // be any IdentifierName. But without 'as', it must be a valid
1560 // BindingIdentifier.
1561 if (CheckContextualKeyword(CStrVector("as"))) {
1562 local_name = ParseIdentifierName(CHECK_OK);
1564 if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false)) {
1566 ReportMessage(MessageTemplate::kUnexpectedReserved);
1568 } else if (IsEvalOrArguments(local_name)) {
1570 ReportMessage(MessageTemplate::kStrictEvalArguments);
1572 } else if (is_strong(language_mode()) && IsUndefined(local_name)) {
1574 ReportMessage(MessageTemplate::kStrongUndefined);
1577 VariableProxy* proxy = NewUnresolved(local_name, IMPORT);
1578 ImportDeclaration* declaration =
1579 factory()->NewImportDeclaration(proxy, import_name, NULL, scope_, pos);
1580 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
1581 result->Add(declaration, zone());
1582 if (peek() == Token::RBRACE) break;
1583 Expect(Token::COMMA, CHECK_OK);
1586 Expect(Token::RBRACE, CHECK_OK);
1592 Statement* Parser::ParseImportDeclaration(bool* ok) {
1593 // ImportDeclaration :
1594 // 'import' ImportClause 'from' ModuleSpecifier ';'
1595 // 'import' ModuleSpecifier ';'
1600 // ImportedDefaultBinding
1601 // ImportedDefaultBinding ',' NameSpaceImport
1602 // ImportedDefaultBinding ',' NamedImports
1604 // NameSpaceImport :
1605 // '*' 'as' ImportedBinding
1607 int pos = peek_position();
1608 Expect(Token::IMPORT, CHECK_OK);
1610 Token::Value tok = peek();
1612 // 'import' ModuleSpecifier ';'
1613 if (tok == Token::STRING) {
1614 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1615 scope_->module()->AddModuleRequest(module_specifier, zone());
1616 ExpectSemicolon(CHECK_OK);
1617 return factory()->NewEmptyStatement(pos);
1620 // Parse ImportedDefaultBinding if present.
1621 ImportDeclaration* import_default_declaration = NULL;
1622 if (tok != Token::MUL && tok != Token::LBRACE) {
1623 const AstRawString* local_name =
1624 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
1625 VariableProxy* proxy = NewUnresolved(local_name, IMPORT);
1626 import_default_declaration = factory()->NewImportDeclaration(
1627 proxy, ast_value_factory()->default_string(), NULL, scope_, pos);
1628 Declare(import_default_declaration, DeclarationDescriptor::NORMAL, true,
1632 const AstRawString* module_instance_binding = NULL;
1633 ZoneList<ImportDeclaration*>* named_declarations = NULL;
1634 if (import_default_declaration == NULL || Check(Token::COMMA)) {
1637 Consume(Token::MUL);
1638 ExpectContextualKeyword(CStrVector("as"), CHECK_OK);
1639 module_instance_binding =
1640 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
1641 // TODO(ES6): Add an appropriate declaration.
1646 named_declarations = ParseNamedImports(pos, CHECK_OK);
1651 ReportUnexpectedToken(scanner()->current_token());
1656 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1657 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1658 scope_->module()->AddModuleRequest(module_specifier, zone());
1660 if (module_instance_binding != NULL) {
1661 // TODO(ES6): Set the module specifier for the module namespace binding.
1664 if (import_default_declaration != NULL) {
1665 import_default_declaration->set_module_specifier(module_specifier);
1668 if (named_declarations != NULL) {
1669 for (int i = 0; i < named_declarations->length(); ++i) {
1670 named_declarations->at(i)->set_module_specifier(module_specifier);
1674 ExpectSemicolon(CHECK_OK);
1675 return factory()->NewEmptyStatement(pos);
1679 Statement* Parser::ParseExportDefault(bool* ok) {
1680 // Supports the following productions, starting after the 'default' token:
1681 // 'export' 'default' FunctionDeclaration
1682 // 'export' 'default' ClassDeclaration
1683 // 'export' 'default' AssignmentExpression[In] ';'
1685 Expect(Token::DEFAULT, CHECK_OK);
1686 Scanner::Location default_loc = scanner()->location();
1688 ZoneList<const AstRawString*> names(1, zone());
1689 Statement* result = NULL;
1691 case Token::FUNCTION:
1692 // TODO(ES6): Support parsing anonymous function declarations here.
1693 result = ParseFunctionDeclaration(&names, CHECK_OK);
1697 // TODO(ES6): Support parsing anonymous class declarations here.
1698 result = ParseClassDeclaration(&names, CHECK_OK);
1702 int pos = peek_position();
1703 ExpressionClassifier classifier;
1704 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK);
1705 ValidateExpression(&classifier, CHECK_OK);
1707 ExpectSemicolon(CHECK_OK);
1708 result = factory()->NewExpressionStatement(expr, pos);
1713 const AstRawString* default_string = ast_value_factory()->default_string();
1715 DCHECK_LE(names.length(), 1);
1716 if (names.length() == 1) {
1717 scope_->module()->AddLocalExport(default_string, names.first(), zone(), ok);
1719 ParserTraits::ReportMessageAt(
1720 default_loc, MessageTemplate::kDuplicateExport, default_string);
1724 // TODO(ES6): Assign result to a const binding with the name "*default*"
1725 // and add an export entry with "*default*" as the local name.
1732 Statement* Parser::ParseExportDeclaration(bool* ok) {
1733 // ExportDeclaration:
1734 // 'export' '*' 'from' ModuleSpecifier ';'
1735 // 'export' ExportClause ('from' ModuleSpecifier)? ';'
1736 // 'export' VariableStatement
1737 // 'export' Declaration
1738 // 'export' 'default' ... (handled in ParseExportDefault)
1740 int pos = peek_position();
1741 Expect(Token::EXPORT, CHECK_OK);
1743 Statement* result = NULL;
1744 ZoneList<const AstRawString*> names(1, zone());
1746 case Token::DEFAULT:
1747 return ParseExportDefault(ok);
1750 Consume(Token::MUL);
1751 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1752 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1753 scope_->module()->AddModuleRequest(module_specifier, zone());
1754 // TODO(ES6): scope_->module()->AddStarExport(...)
1755 ExpectSemicolon(CHECK_OK);
1756 return factory()->NewEmptyStatement(pos);
1759 case Token::LBRACE: {
1760 // There are two cases here:
1762 // 'export' ExportClause ';'
1764 // 'export' ExportClause FromClause ';'
1766 // In the first case, the exported identifiers in ExportClause must
1767 // not be reserved words, while in the latter they may be. We
1768 // pass in a location that gets filled with the first reserved word
1769 // encountered, and then throw a SyntaxError if we are in the
1770 // non-FromClause case.
1771 Scanner::Location reserved_loc = Scanner::Location::invalid();
1772 ZoneList<const AstRawString*> export_names(1, zone());
1773 ZoneList<Scanner::Location> export_locations(1, zone());
1774 ZoneList<const AstRawString*> local_names(1, zone());
1775 ParseExportClause(&export_names, &export_locations, &local_names,
1776 &reserved_loc, CHECK_OK);
1777 const AstRawString* indirect_export_module_specifier = NULL;
1778 if (CheckContextualKeyword(CStrVector("from"))) {
1779 indirect_export_module_specifier = ParseModuleSpecifier(CHECK_OK);
1780 } else if (reserved_loc.IsValid()) {
1781 // No FromClause, so reserved words are invalid in ExportClause.
1783 ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
1786 ExpectSemicolon(CHECK_OK);
1787 const int length = export_names.length();
1788 DCHECK_EQ(length, local_names.length());
1789 DCHECK_EQ(length, export_locations.length());
1790 if (indirect_export_module_specifier == NULL) {
1791 for (int i = 0; i < length; ++i) {
1792 scope_->module()->AddLocalExport(export_names[i], local_names[i],
1795 ParserTraits::ReportMessageAt(export_locations[i],
1796 MessageTemplate::kDuplicateExport,
1802 scope_->module()->AddModuleRequest(indirect_export_module_specifier,
1804 for (int i = 0; i < length; ++i) {
1805 // TODO(ES6): scope_->module()->AddIndirectExport(...);(
1808 return factory()->NewEmptyStatement(pos);
1811 case Token::FUNCTION:
1812 result = ParseFunctionDeclaration(&names, CHECK_OK);
1816 result = ParseClassDeclaration(&names, CHECK_OK);
1822 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK);
1827 ReportUnexpectedToken(scanner()->current_token());
1831 // Extract declared names into export declarations.
1832 ModuleDescriptor* descriptor = scope_->module();
1833 for (int i = 0; i < names.length(); ++i) {
1834 descriptor->AddLocalExport(names[i], names[i], zone(), ok);
1836 // TODO(adamk): Possibly report this error at the right place.
1837 ParserTraits::ReportMessage(MessageTemplate::kDuplicateExport, names[i]);
1842 DCHECK_NOT_NULL(result);
1847 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels,
1853 if (peek() == Token::SEMICOLON) {
1855 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1857 return ParseSubStatement(labels, ok);
1861 Statement* Parser::ParseSubStatement(ZoneList<const AstRawString*>* labels,
1865 // VariableStatement
1867 // ExpressionStatement
1869 // IterationStatement
1870 // ContinueStatement
1874 // LabelledStatement
1878 // DebuggerStatement
1880 // Note: Since labels can only be used by 'break' and 'continue'
1881 // statements, which themselves are only valid within blocks,
1882 // iterations or 'switch' statements (i.e., BreakableStatements),
1883 // labels can be simply ignored in all other cases; except for
1884 // trivial labeled break statements 'label: break label' which is
1885 // parsed into an empty statement.
1888 return ParseBlock(labels, ok);
1890 case Token::SEMICOLON:
1891 if (is_strong(language_mode())) {
1892 ReportMessageAt(scanner()->peek_location(),
1893 MessageTemplate::kStrongEmpty);
1898 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1901 return ParseIfStatement(labels, ok);
1904 return ParseDoWhileStatement(labels, ok);
1907 return ParseWhileStatement(labels, ok);
1910 return ParseForStatement(labels, ok);
1912 case Token::CONTINUE:
1917 // These statements must have their labels preserved in an enclosing
1919 if (labels == NULL) {
1920 return ParseStatementAsUnlabelled(labels, ok);
1923 factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition);
1924 Target target(&this->target_stack_, result);
1925 Statement* statement = ParseStatementAsUnlabelled(labels, CHECK_OK);
1926 if (result) result->AddStatement(statement, zone());
1932 return ParseWithStatement(labels, ok);
1935 return ParseSwitchStatement(labels, ok);
1937 case Token::FUNCTION: {
1938 // FunctionDeclaration is only allowed in the context of SourceElements
1939 // (Ecma 262 5th Edition, clause 14):
1942 // FunctionDeclaration
1943 // Common language extension is to allow function declaration in place
1944 // of any statement. This language extension is disabled in strict mode.
1946 // In Harmony mode, this case also handles the extension:
1948 // GeneratorDeclaration
1949 if (is_strict(language_mode())) {
1950 ReportMessageAt(scanner()->peek_location(),
1951 MessageTemplate::kStrictFunction);
1955 return ParseFunctionDeclaration(NULL, ok);
1958 case Token::DEBUGGER:
1959 return ParseDebuggerStatement(ok);
1962 return ParseVariableStatement(kStatement, NULL, ok);
1965 // In ES6 CONST is not allowed as a Statement, only as a
1966 // LexicalDeclaration, however we continue to allow it in sloppy mode for
1967 // backwards compatibility.
1968 if (is_sloppy(language_mode()) && allow_legacy_const()) {
1969 return ParseVariableStatement(kStatement, NULL, ok);
1974 return ParseExpressionOrLabelledStatement(labels, ok);
1978 Statement* Parser::ParseStatementAsUnlabelled(
1979 ZoneList<const AstRawString*>* labels, bool* ok) {
1981 case Token::CONTINUE:
1982 return ParseContinueStatement(ok);
1985 return ParseBreakStatement(labels, ok);
1988 return ParseReturnStatement(ok);
1991 return ParseThrowStatement(ok);
1994 return ParseTryStatement(ok);
2003 VariableProxy* Parser::NewUnresolved(const AstRawString* name,
2004 VariableMode mode) {
2005 // If we are inside a function, a declaration of a var/const variable is a
2006 // truly local variable, and the scope of the variable is always the function
2008 // Let/const variables in harmony mode are always added to the immediately
2010 return DeclarationScope(mode)->NewUnresolved(
2011 factory(), name, Variable::NORMAL, scanner()->location().beg_pos,
2012 scanner()->location().end_pos);
2016 Variable* Parser::Declare(Declaration* declaration,
2017 DeclarationDescriptor::Kind declaration_kind,
2018 bool resolve, bool* ok, Scope* scope) {
2019 VariableProxy* proxy = declaration->proxy();
2020 DCHECK(proxy->raw_name() != NULL);
2021 const AstRawString* name = proxy->raw_name();
2022 VariableMode mode = declaration->mode();
2023 if (scope == nullptr) scope = scope_;
2024 Scope* declaration_scope =
2025 IsLexicalVariableMode(mode) ? scope : scope->DeclarationScope();
2026 Variable* var = NULL;
2028 // If a suitable scope exists, then we can statically declare this
2029 // variable and also set its mode. In any case, a Declaration node
2030 // will be added to the scope so that the declaration can be added
2031 // to the corresponding activation frame at runtime if necessary.
2032 // For instance, var declarations inside a sloppy eval scope need
2033 // to be added to the calling function context. Similarly, strict
2034 // mode eval scope and lexical eval bindings do not leak variable
2035 // declarations to the caller's scope so we declare all locals, too.
2036 if (declaration_scope->is_function_scope() ||
2037 declaration_scope->is_block_scope() ||
2038 declaration_scope->is_module_scope() ||
2039 declaration_scope->is_script_scope() ||
2040 (declaration_scope->is_eval_scope() &&
2041 (is_strict(declaration_scope->language_mode()) ||
2042 IsLexicalVariableMode(mode)))) {
2043 // Declare the variable in the declaration scope.
2044 var = declaration_scope->LookupLocal(name);
2046 // Declare the name.
2047 Variable::Kind kind = Variable::NORMAL;
2048 int declaration_group_start = -1;
2049 if (declaration->IsFunctionDeclaration()) {
2050 kind = Variable::FUNCTION;
2051 } else if (declaration->IsVariableDeclaration() &&
2052 declaration->AsVariableDeclaration()->is_class_declaration()) {
2053 kind = Variable::CLASS;
2054 declaration_group_start =
2055 declaration->AsVariableDeclaration()->declaration_group_start();
2057 var = declaration_scope->DeclareLocal(
2058 name, mode, declaration->initialization(), kind, kNotAssigned,
2059 declaration_group_start);
2060 } else if (IsLexicalVariableMode(mode) ||
2061 IsLexicalVariableMode(var->mode()) ||
2062 ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) &&
2063 !declaration_scope->is_script_scope())) {
2064 // The name was declared in this scope before; check for conflicting
2065 // re-declarations. We have a conflict if either of the declarations is
2066 // not a var (in script scope, we also have to ignore legacy const for
2067 // compatibility). There is similar code in runtime.cc in the Declare
2068 // functions. The function CheckConflictingVarDeclarations checks for
2069 // var and let bindings from different scopes whereas this is a check for
2070 // conflicting declarations within the same scope. This check also covers
2073 // function () { let x; { var x; } }
2075 // because the var declaration is hoisted to the function scope where 'x'
2076 // is already bound.
2077 DCHECK(IsDeclaredVariableMode(var->mode()));
2078 if (is_strict(language_mode()) || allow_harmony_sloppy()) {
2079 // In harmony we treat re-declarations as early errors. See
2080 // ES5 16 for a definition of early errors.
2081 if (declaration_kind == DeclarationDescriptor::NORMAL) {
2082 ParserTraits::ReportMessage(MessageTemplate::kVarRedeclaration, name);
2084 ParserTraits::ReportMessage(MessageTemplate::kParamDupe);
2089 Expression* expression = NewThrowSyntaxError(
2090 MessageTemplate::kVarRedeclaration, name, declaration->position());
2091 declaration_scope->SetIllegalRedeclaration(expression);
2092 } else if (mode == VAR) {
2093 var->set_maybe_assigned();
2095 } else if (declaration_scope->is_eval_scope() &&
2096 is_sloppy(declaration_scope->language_mode()) &&
2097 !IsLexicalVariableMode(mode)) {
2098 // In a var binding in a sloppy direct eval, pollute the enclosing scope
2099 // with this new binding by doing the following:
2100 // The proxy is bound to a lookup variable to force a dynamic declaration
2101 // using the DeclareLookupSlot runtime function.
2102 Variable::Kind kind = Variable::NORMAL;
2103 // TODO(sigurds) figure out if kNotAssigned is OK here
2104 var = new (zone()) Variable(declaration_scope, name, mode, kind,
2105 declaration->initialization(), kNotAssigned);
2106 var->AllocateTo(VariableLocation::LOOKUP, -1);
2111 // We add a declaration node for every declaration. The compiler
2112 // will only generate code if necessary. In particular, declarations
2113 // for inner local variables that do not represent functions won't
2114 // result in any generated code.
2116 // Note that we always add an unresolved proxy even if it's not
2117 // used, simply because we don't know in this method (w/o extra
2118 // parameters) if the proxy is needed or not. The proxy will be
2119 // bound during variable resolution time unless it was pre-bound
2122 // WARNING: This will lead to multiple declaration nodes for the
2123 // same variable if it is declared several times. This is not a
2124 // semantic issue as long as we keep the source order, but it may be
2125 // a performance issue since it may lead to repeated
2126 // RuntimeHidden_DeclareLookupSlot calls.
2127 declaration_scope->AddDeclaration(declaration);
2129 if (mode == CONST_LEGACY && declaration_scope->is_script_scope()) {
2130 // For global const variables we bind the proxy to a variable.
2131 DCHECK(resolve); // should be set by all callers
2132 Variable::Kind kind = Variable::NORMAL;
2133 var = new (zone()) Variable(declaration_scope, name, mode, kind,
2134 kNeedsInitialization, kNotAssigned);
2137 // If requested and we have a local variable, bind the proxy to the variable
2138 // at parse-time. This is used for functions (and consts) declared inside
2139 // statements: the corresponding function (or const) variable must be in the
2140 // function scope and not a statement-local scope, e.g. as provided with a
2141 // 'with' statement:
2147 // which is translated into:
2150 // // in this case this is not: 'var f; f = function () {};'
2151 // var f = function () {};
2154 // Note that if 'f' is accessed from inside the 'with' statement, it
2155 // will be allocated in the context (because we must be able to look
2156 // it up dynamically) but it will also be accessed statically, i.e.,
2157 // with a context slot index and a context chain length for this
2158 // initialization code. Thus, inside the 'with' statement, we need
2159 // both access to the static and the dynamic context chain; the
2160 // runtime needs to provide both.
2161 if (resolve && var != NULL) {
2168 // Language extension which is only enabled for source files loaded
2169 // through the API's extension mechanism. A native function
2170 // declaration is resolved by looking up the function through a
2171 // callback provided by the extension.
2172 Statement* Parser::ParseNativeDeclaration(bool* ok) {
2173 int pos = peek_position();
2174 Expect(Token::FUNCTION, CHECK_OK);
2175 // Allow "eval" or "arguments" for backward compatibility.
2176 const AstRawString* name =
2177 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2178 Expect(Token::LPAREN, CHECK_OK);
2179 bool done = (peek() == Token::RPAREN);
2181 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2182 done = (peek() == Token::RPAREN);
2184 Expect(Token::COMMA, CHECK_OK);
2187 Expect(Token::RPAREN, CHECK_OK);
2188 Expect(Token::SEMICOLON, CHECK_OK);
2190 // Make sure that the function containing the native declaration
2191 // isn't lazily compiled. The extension structures are only
2192 // accessible while parsing the first time not when reparsing
2193 // because of lazy compilation.
2194 DeclarationScope(VAR)->ForceEagerCompilation();
2196 // TODO(1240846): It's weird that native function declarations are
2197 // introduced dynamically when we meet their declarations, whereas
2198 // other functions are set up when entering the surrounding scope.
2199 VariableProxy* proxy = NewUnresolved(name, VAR);
2200 Declaration* declaration =
2201 factory()->NewVariableDeclaration(proxy, VAR, scope_, pos);
2202 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
2203 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral(
2204 name, extension_, RelocInfo::kNoPosition);
2205 return factory()->NewExpressionStatement(
2206 factory()->NewAssignment(
2207 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition),
2212 Statement* Parser::ParseFunctionDeclaration(
2213 ZoneList<const AstRawString*>* names, bool* ok) {
2214 // FunctionDeclaration ::
2215 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
2216 // GeneratorDeclaration ::
2217 // 'function' '*' Identifier '(' FormalParameterListopt ')'
2218 // '{' FunctionBody '}'
2219 Expect(Token::FUNCTION, CHECK_OK);
2220 int pos = position();
2221 bool is_generator = Check(Token::MUL);
2222 bool is_strict_reserved = false;
2223 const AstRawString* name = ParseIdentifierOrStrictReservedWord(
2224 &is_strict_reserved, CHECK_OK);
2228 fni_->PushEnclosingName(name);
2230 FunctionLiteral* fun = ParseFunctionLiteral(
2231 name, scanner()->location(),
2232 is_strict_reserved ? kFunctionNameIsStrictReserved
2233 : kFunctionNameValidityUnknown,
2234 is_generator ? FunctionKind::kGeneratorFunction
2235 : FunctionKind::kNormalFunction,
2236 pos, FunctionLiteral::DECLARATION, FunctionLiteral::NORMAL_ARITY,
2237 language_mode(), CHECK_OK);
2238 if (fni_ != NULL) fni_->Leave();
2240 // Even if we're not at the top-level of the global or a function
2241 // scope, we treat it as such and introduce the function with its
2242 // initial value upon entering the corresponding scope.
2243 // In ES6, a function behaves as a lexical binding, except in
2244 // a script scope, or the initial scope of eval or another function.
2246 is_strong(language_mode())
2248 : (is_strict(language_mode()) || allow_harmony_sloppy_function()) &&
2249 !scope_->is_declaration_scope()
2252 VariableProxy* proxy = NewUnresolved(name, mode);
2253 Declaration* declaration =
2254 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
2255 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
2256 if (names) names->Add(name, zone());
2257 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2261 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
2263 // ClassDeclaration ::
2264 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
2266 // A ClassDeclaration
2270 // has the same semantics as:
2272 // let C = class C { ... };
2274 // so rewrite it as such.
2276 Expect(Token::CLASS, CHECK_OK);
2277 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
2278 ReportMessage(MessageTemplate::kSloppyLexical);
2283 int pos = position();
2284 bool is_strict_reserved = false;
2285 const AstRawString* name =
2286 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
2287 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(),
2288 is_strict_reserved, pos, CHECK_OK);
2290 VariableMode mode = is_strong(language_mode()) ? CONST : LET;
2291 VariableProxy* proxy = NewUnresolved(name, mode);
2292 const bool is_class_declaration = true;
2293 Declaration* declaration = factory()->NewVariableDeclaration(
2294 proxy, mode, scope_, pos, is_class_declaration,
2295 scope_->class_declaration_group_start());
2296 Variable* outer_class_variable =
2297 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
2298 proxy->var()->set_initializer_position(position());
2299 // This is needed because a class ("class Name { }") creates two bindings (one
2300 // in the outer scope, and one in the class scope). The method is a function
2301 // scope inside the inner scope (class scope). The consecutive class
2302 // declarations are in the outer scope.
2303 if (value->class_variable_proxy() && value->class_variable_proxy()->var() &&
2304 outer_class_variable->is_class()) {
2305 // In some cases, the outer variable is not detected as a class variable;
2306 // this happens e.g., for lazy methods. They are excluded from strong mode
2307 // checks for now. TODO(marja, rossberg): re-create variables with the
2308 // correct Kind and remove this hack.
2309 value->class_variable_proxy()
2312 ->set_declaration_group_start(
2313 outer_class_variable->AsClassVariable()->declaration_group_start());
2316 Token::Value init_op =
2317 is_strong(language_mode()) ? Token::INIT_CONST : Token::INIT_LET;
2318 Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos);
2319 Statement* assignment_statement =
2320 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
2321 if (names) names->Add(name, zone());
2322 return assignment_statement;
2326 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) {
2327 if (is_strict(language_mode()) || allow_harmony_sloppy()) {
2328 return ParseScopedBlock(labels, ok);
2332 // '{' Statement* '}'
2334 // Note that a Block does not introduce a new execution scope!
2335 // (ECMA-262, 3rd, 12.2)
2337 // Construct block expecting 16 statements.
2339 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2340 Target target(&this->target_stack_, result);
2341 Expect(Token::LBRACE, CHECK_OK);
2342 while (peek() != Token::RBRACE) {
2343 Statement* stat = ParseStatement(NULL, CHECK_OK);
2344 if (stat && !stat->IsEmpty()) {
2345 result->AddStatement(stat, zone());
2348 Expect(Token::RBRACE, CHECK_OK);
2353 Block* Parser::ParseScopedBlock(ZoneList<const AstRawString*>* labels,
2355 // The harmony mode uses block elements instead of statements.
2358 // '{' StatementList '}'
2360 // Construct block expecting 16 statements.
2362 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2363 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
2365 // Parse the statements and collect escaping labels.
2366 Expect(Token::LBRACE, CHECK_OK);
2367 block_scope->set_start_position(scanner()->location().beg_pos);
2368 { BlockState block_state(&scope_, block_scope);
2369 Target target(&this->target_stack_, body);
2371 while (peek() != Token::RBRACE) {
2372 Statement* stat = ParseStatementListItem(CHECK_OK);
2373 if (stat && !stat->IsEmpty()) {
2374 body->AddStatement(stat, zone());
2378 Expect(Token::RBRACE, CHECK_OK);
2379 block_scope->set_end_position(scanner()->location().end_pos);
2380 block_scope = block_scope->FinalizeBlockScope();
2381 body->set_scope(block_scope);
2386 const AstRawString* Parser::DeclarationParsingResult::SingleName() const {
2387 if (declarations.length() != 1) return nullptr;
2388 const Declaration& declaration = declarations.at(0);
2389 if (declaration.pattern->IsVariableProxy()) {
2390 return declaration.pattern->AsVariableProxy()->raw_name();
2396 Block* Parser::DeclarationParsingResult::BuildInitializationBlock(
2397 ZoneList<const AstRawString*>* names, bool* ok) {
2398 Block* result = descriptor.parser->factory()->NewBlock(
2399 NULL, 1, true, descriptor.declaration_pos);
2400 for (auto declaration : declarations) {
2401 PatternRewriter::DeclareAndInitializeVariables(
2402 result, &descriptor, &declaration, names, CHECK_OK);
2408 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
2409 ZoneList<const AstRawString*>* names,
2411 // VariableStatement ::
2412 // VariableDeclarations ';'
2414 // The scope of a var/const declared variable anywhere inside a function
2415 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
2416 // transform a source-level var/const declaration into a (Function)
2417 // Scope declaration, and rewrite the source-level initialization into an
2418 // assignment statement. We use a block to collect multiple assignments.
2420 // We mark the block as initializer block because we don't want the
2421 // rewriter to add a '.result' assignment to such a block (to get compliant
2422 // behavior for code such as print(eval('var x = 7')), and for cosmetic
2423 // reasons when pretty-printing. Also, unless an assignment (initialization)
2424 // is inside an initializer block, it is ignored.
2426 DeclarationParsingResult parsing_result;
2427 ParseVariableDeclarations(var_context, &parsing_result, CHECK_OK);
2428 ExpectSemicolon(CHECK_OK);
2430 Block* result = parsing_result.BuildInitializationBlock(names, CHECK_OK);
2435 void Parser::ParseVariableDeclarations(VariableDeclarationContext var_context,
2436 DeclarationParsingResult* parsing_result,
2438 // VariableDeclarations ::
2439 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
2441 // The ES6 Draft Rev3 specifies the following grammar for const declarations
2443 // ConstDeclaration ::
2444 // const ConstBinding (',' ConstBinding)* ';'
2446 // Identifier '=' AssignmentExpression
2450 // BindingPattern '=' AssignmentExpression
2452 parsing_result->descriptor.parser = this;
2453 parsing_result->descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
2454 parsing_result->descriptor.declaration_pos = peek_position();
2455 parsing_result->descriptor.initialization_pos = peek_position();
2456 parsing_result->descriptor.mode = VAR;
2457 // True if the binding needs initialization. 'let' and 'const' declared
2458 // bindings are created uninitialized by their declaration nodes and
2459 // need initialization. 'var' declared bindings are always initialized
2460 // immediately by their declaration nodes.
2461 parsing_result->descriptor.needs_init = false;
2462 parsing_result->descriptor.is_const = false;
2463 parsing_result->descriptor.init_op = Token::INIT_VAR;
2464 if (peek() == Token::VAR) {
2465 if (is_strong(language_mode())) {
2466 Scanner::Location location = scanner()->peek_location();
2467 ReportMessageAt(location, MessageTemplate::kStrongVar);
2471 Consume(Token::VAR);
2472 } else if (peek() == Token::CONST && allow_const()) {
2473 Consume(Token::CONST);
2474 if (is_sloppy(language_mode()) && allow_legacy_const()) {
2475 parsing_result->descriptor.mode = CONST_LEGACY;
2476 parsing_result->descriptor.init_op = Token::INIT_CONST_LEGACY;
2477 ++use_counts_[v8::Isolate::kLegacyConst];
2479 DCHECK(is_strict(language_mode()) || allow_harmony_sloppy());
2480 DCHECK(var_context != kStatement);
2481 parsing_result->descriptor.mode = CONST;
2482 parsing_result->descriptor.init_op = Token::INIT_CONST;
2484 parsing_result->descriptor.is_const = true;
2485 parsing_result->descriptor.needs_init = true;
2486 } else if (peek() == Token::LET && allow_let()) {
2487 Consume(Token::LET);
2488 DCHECK(var_context != kStatement);
2489 parsing_result->descriptor.mode = LET;
2490 parsing_result->descriptor.needs_init = true;
2491 parsing_result->descriptor.init_op = Token::INIT_LET;
2493 UNREACHABLE(); // by current callers
2496 parsing_result->descriptor.declaration_scope =
2497 DeclarationScope(parsing_result->descriptor.mode);
2498 parsing_result->descriptor.scope = scope_;
2499 parsing_result->descriptor.hoist_scope = nullptr;
2502 bool first_declaration = true;
2503 int bindings_start = peek_position();
2504 bool is_for_iteration_variable;
2506 if (fni_ != NULL) fni_->Enter();
2509 if (!first_declaration) Consume(Token::COMMA);
2511 Expression* pattern;
2513 ExpressionClassifier pattern_classifier;
2514 Token::Value next = peek();
2515 pattern = ParsePrimaryExpression(&pattern_classifier, ok);
2517 ValidateBindingPattern(&pattern_classifier, ok);
2519 if (!allow_harmony_destructuring() && !pattern->IsVariableProxy()) {
2520 ReportUnexpectedToken(next);
2526 Scanner::Location variable_loc = scanner()->location();
2527 const AstRawString* single_name =
2528 pattern->IsVariableProxy() ? pattern->AsVariableProxy()->raw_name()
2530 if (single_name != nullptr) {
2531 if (fni_ != NULL) fni_->PushVariableName(single_name);
2534 is_for_iteration_variable =
2535 var_context == kForStatement &&
2536 (peek() == Token::IN || PeekContextualKeyword(CStrVector("of")));
2537 if (is_for_iteration_variable && parsing_result->descriptor.mode == CONST) {
2538 parsing_result->descriptor.needs_init = false;
2541 Expression* value = NULL;
2542 // Harmony consts have non-optional initializers.
2543 int initializer_position = RelocInfo::kNoPosition;
2544 if (peek() == Token::ASSIGN || (parsing_result->descriptor.mode == CONST &&
2545 !is_for_iteration_variable)) {
2546 Expect(Token::ASSIGN, ok);
2548 ExpressionClassifier classifier;
2549 value = ParseAssignmentExpression(var_context != kForStatement,
2552 ValidateExpression(&classifier, ok);
2554 variable_loc.end_pos = scanner()->location().end_pos;
2556 if (!parsing_result->first_initializer_loc.IsValid()) {
2557 parsing_result->first_initializer_loc = variable_loc;
2560 // Don't infer if it is "a = function(){...}();"-like expression.
2562 if (fni_ != NULL && value->AsCall() == NULL &&
2563 value->AsCallNew() == NULL) {
2566 fni_->RemoveLastFunction();
2569 // End position of the initializer is after the assignment expression.
2570 initializer_position = scanner()->location().end_pos;
2572 // End position of the initializer is after the variable.
2573 initializer_position = position();
2576 // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
2577 if (value == NULL && parsing_result->descriptor.needs_init) {
2578 value = GetLiteralUndefined(position());
2581 if (single_name && fni_ != NULL) fni_->Leave();
2582 parsing_result->declarations.Add(DeclarationParsingResult::Declaration(
2583 pattern, initializer_position, value));
2584 first_declaration = false;
2585 } while (peek() == Token::COMMA);
2587 parsing_result->bindings_loc =
2588 Scanner::Location(bindings_start, scanner()->location().end_pos);
2592 static bool ContainsLabel(ZoneList<const AstRawString*>* labels,
2593 const AstRawString* label) {
2594 DCHECK(label != NULL);
2595 if (labels != NULL) {
2596 for (int i = labels->length(); i-- > 0; ) {
2597 if (labels->at(i) == label) {
2606 Statement* Parser::ParseExpressionOrLabelledStatement(
2607 ZoneList<const AstRawString*>* labels, bool* ok) {
2608 // ExpressionStatement | LabelledStatement ::
2610 // Identifier ':' Statement
2612 // ExpressionStatement[Yield] :
2613 // [lookahead ∉ {{, function, class, let [}] Expression[In, ?Yield] ;
2615 int pos = peek_position();
2618 case Token::FUNCTION:
2620 UNREACHABLE(); // Always handled by the callers.
2622 ReportUnexpectedToken(Next());
2627 if (!FLAG_strong_this) break;
2630 if (is_strong(language_mode()) &&
2631 i::IsConstructor(function_state_->kind())) {
2632 bool is_this = peek() == Token::THIS;
2634 ExpressionClassifier classifier;
2636 expr = ParseStrongInitializationExpression(&classifier, CHECK_OK);
2638 expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK);
2640 ValidateExpression(&classifier, CHECK_OK);
2642 case Token::SEMICOLON:
2643 Consume(Token::SEMICOLON);
2649 if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
2650 ReportMessageAt(function_state_->this_location(),
2652 ? MessageTemplate::kStrongConstructorThis
2653 : MessageTemplate::kStrongConstructorSuper);
2658 return factory()->NewExpressionStatement(expr, pos);
2666 bool starts_with_idenfifier = peek_any_identifier();
2667 Expression* expr = ParseExpression(true, CHECK_OK);
2668 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
2669 expr->AsVariableProxy() != NULL &&
2670 !expr->AsVariableProxy()->is_this()) {
2671 // Expression is a single identifier, and not, e.g., a parenthesized
2673 VariableProxy* var = expr->AsVariableProxy();
2674 const AstRawString* label = var->raw_name();
2675 // TODO(1240780): We don't check for redeclaration of labels
2676 // during preparsing since keeping track of the set of active
2677 // labels requires nontrivial changes to the way scopes are
2678 // structured. However, these are probably changes we want to
2679 // make later anyway so we should go back and fix this then.
2680 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
2681 ParserTraits::ReportMessage(MessageTemplate::kLabelRedeclaration, label);
2685 if (labels == NULL) {
2686 labels = new(zone()) ZoneList<const AstRawString*>(4, zone());
2688 labels->Add(label, zone());
2689 // Remove the "ghost" variable that turned out to be a label
2690 // from the top scope. This way, we don't try to resolve it
2691 // during the scope processing.
2692 scope_->RemoveUnresolved(var);
2693 Expect(Token::COLON, CHECK_OK);
2694 return ParseStatement(labels, ok);
2697 // If we have an extension, we allow a native function declaration.
2698 // A native function declaration starts with "native function" with
2699 // no line-terminator between the two words.
2700 if (extension_ != NULL && peek() == Token::FUNCTION &&
2701 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL &&
2702 expr->AsVariableProxy() != NULL &&
2703 expr->AsVariableProxy()->raw_name() ==
2704 ast_value_factory()->native_string() &&
2705 !scanner()->literal_contains_escapes()) {
2706 return ParseNativeDeclaration(ok);
2709 // Parsed expression statement, followed by semicolon.
2710 // Detect attempts at 'let' declarations in sloppy mode.
2711 if (peek() == Token::IDENTIFIER && expr->AsVariableProxy() != NULL &&
2712 expr->AsVariableProxy()->raw_name() ==
2713 ast_value_factory()->let_string()) {
2714 ReportMessage(MessageTemplate::kSloppyLexical, NULL);
2718 ExpectSemicolon(CHECK_OK);
2719 return factory()->NewExpressionStatement(expr, pos);
2723 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels,
2726 // 'if' '(' Expression ')' Statement ('else' Statement)?
2728 int pos = peek_position();
2729 Expect(Token::IF, CHECK_OK);
2730 Expect(Token::LPAREN, CHECK_OK);
2731 Expression* condition = ParseExpression(true, CHECK_OK);
2732 Expect(Token::RPAREN, CHECK_OK);
2733 Statement* then_statement = ParseSubStatement(labels, CHECK_OK);
2734 Statement* else_statement = NULL;
2735 if (peek() == Token::ELSE) {
2737 else_statement = ParseSubStatement(labels, CHECK_OK);
2739 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2741 return factory()->NewIfStatement(
2742 condition, then_statement, else_statement, pos);
2746 Statement* Parser::ParseContinueStatement(bool* ok) {
2747 // ContinueStatement ::
2748 // 'continue' Identifier? ';'
2750 int pos = peek_position();
2751 Expect(Token::CONTINUE, CHECK_OK);
2752 const AstRawString* label = NULL;
2753 Token::Value tok = peek();
2754 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2755 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2756 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2757 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2759 IterationStatement* target = LookupContinueTarget(label, CHECK_OK);
2760 if (target == NULL) {
2761 // Illegal continue statement.
2762 MessageTemplate::Template message = MessageTemplate::kIllegalContinue;
2763 if (label != NULL) {
2764 message = MessageTemplate::kUnknownLabel;
2766 ParserTraits::ReportMessage(message, label);
2770 ExpectSemicolon(CHECK_OK);
2771 return factory()->NewContinueStatement(target, pos);
2775 Statement* Parser::ParseBreakStatement(ZoneList<const AstRawString*>* labels,
2777 // BreakStatement ::
2778 // 'break' Identifier? ';'
2780 int pos = peek_position();
2781 Expect(Token::BREAK, CHECK_OK);
2782 const AstRawString* label = NULL;
2783 Token::Value tok = peek();
2784 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2785 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2786 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2787 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2789 // Parse labeled break statements that target themselves into
2790 // empty statements, e.g. 'l1: l2: l3: break l2;'
2791 if (label != NULL && ContainsLabel(labels, label)) {
2792 ExpectSemicolon(CHECK_OK);
2793 return factory()->NewEmptyStatement(pos);
2795 BreakableStatement* target = NULL;
2796 target = LookupBreakTarget(label, CHECK_OK);
2797 if (target == NULL) {
2798 // Illegal break statement.
2799 MessageTemplate::Template message = MessageTemplate::kIllegalBreak;
2800 if (label != NULL) {
2801 message = MessageTemplate::kUnknownLabel;
2803 ParserTraits::ReportMessage(message, label);
2807 ExpectSemicolon(CHECK_OK);
2808 return factory()->NewBreakStatement(target, pos);
2812 Statement* Parser::ParseReturnStatement(bool* ok) {
2813 // ReturnStatement ::
2814 // 'return' Expression? ';'
2816 // Consume the return token. It is necessary to do that before
2817 // reporting any errors on it, because of the way errors are
2818 // reported (underlining).
2819 Expect(Token::RETURN, CHECK_OK);
2820 Scanner::Location loc = scanner()->location();
2821 function_state_->set_return_location(loc);
2823 Token::Value tok = peek();
2825 Expression* return_value;
2826 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
2827 tok == Token::SEMICOLON ||
2828 tok == Token::RBRACE ||
2829 tok == Token::EOS) {
2830 if (IsSubclassConstructor(function_state_->kind())) {
2831 return_value = ThisExpression(scope_, factory(), loc.beg_pos);
2833 return_value = GetLiteralUndefined(position());
2836 if (is_strong(language_mode()) &&
2837 i::IsConstructor(function_state_->kind())) {
2838 int pos = peek_position();
2839 ReportMessageAt(Scanner::Location(pos, pos + 1),
2840 MessageTemplate::kStrongConstructorReturnValue);
2845 int pos = peek_position();
2846 return_value = ParseExpression(true, CHECK_OK);
2848 if (IsSubclassConstructor(function_state_->kind())) {
2849 // For subclass constructors we need to return this in case of undefined
2850 // and throw an exception in case of a non object.
2856 // return (temp = expr) === undefined ? this :
2857 // %_IsSpecObject(temp) ? temp : throw new TypeError(...);
2858 Variable* temp = scope_->NewTemporary(
2859 ast_value_factory()->empty_string());
2860 Assignment* assign = factory()->NewAssignment(
2861 Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);
2863 Expression* throw_expression =
2864 NewThrowTypeError(MessageTemplate::kDerivedConstructorReturn,
2865 ast_value_factory()->empty_string(), pos);
2867 // %_IsSpecObject(temp)
2868 ZoneList<Expression*>* is_spec_object_args =
2869 new (zone()) ZoneList<Expression*>(1, zone());
2870 is_spec_object_args->Add(factory()->NewVariableProxy(temp), zone());
2871 Expression* is_spec_object_call = factory()->NewCallRuntime(
2872 Runtime::kInlineIsSpecObject, is_spec_object_args, pos);
2874 // %_IsSpecObject(temp) ? temp : throw_expression
2875 Expression* is_object_conditional = factory()->NewConditional(
2876 is_spec_object_call, factory()->NewVariableProxy(temp),
2877 throw_expression, pos);
2879 // temp === undefined
2880 Expression* is_undefined = factory()->NewCompareOperation(
2881 Token::EQ_STRICT, assign,
2882 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), pos);
2884 // is_undefined ? this : is_object_conditional
2885 return_value = factory()->NewConditional(
2886 is_undefined, ThisExpression(scope_, factory(), pos),
2887 is_object_conditional, pos);
2890 ExpectSemicolon(CHECK_OK);
2892 if (is_generator()) {
2893 Expression* generator = factory()->NewVariableProxy(
2894 function_state_->generator_object_variable());
2895 Expression* yield = factory()->NewYield(
2896 generator, return_value, Yield::kFinal, loc.beg_pos);
2897 result = factory()->NewExpressionStatement(yield, loc.beg_pos);
2899 result = factory()->NewReturnStatement(return_value, loc.beg_pos);
2902 Scope* decl_scope = scope_->DeclarationScope();
2903 if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) {
2904 ReportMessageAt(loc, MessageTemplate::kIllegalReturn);
2912 Statement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels,
2915 // 'with' '(' Expression ')' Statement
2917 Expect(Token::WITH, CHECK_OK);
2918 int pos = position();
2920 if (is_strict(language_mode())) {
2921 ReportMessage(MessageTemplate::kStrictWith);
2926 Expect(Token::LPAREN, CHECK_OK);
2927 Expression* expr = ParseExpression(true, CHECK_OK);
2928 Expect(Token::RPAREN, CHECK_OK);
2930 scope_->DeclarationScope()->RecordWithStatement();
2931 Scope* with_scope = NewScope(scope_, WITH_SCOPE);
2933 { BlockState block_state(&scope_, with_scope);
2934 with_scope->set_start_position(scanner()->peek_location().beg_pos);
2935 stmt = ParseSubStatement(labels, CHECK_OK);
2936 with_scope->set_end_position(scanner()->location().end_pos);
2938 return factory()->NewWithStatement(with_scope, expr, stmt, pos);
2942 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
2944 // 'case' Expression ':' StatementList
2945 // 'default' ':' StatementList
2947 Expression* label = NULL; // NULL expression indicates default case
2948 if (peek() == Token::CASE) {
2949 Expect(Token::CASE, CHECK_OK);
2950 label = ParseExpression(true, CHECK_OK);
2952 Expect(Token::DEFAULT, CHECK_OK);
2953 if (*default_seen_ptr) {
2954 ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch);
2958 *default_seen_ptr = true;
2960 Expect(Token::COLON, CHECK_OK);
2961 int pos = position();
2962 ZoneList<Statement*>* statements =
2963 new(zone()) ZoneList<Statement*>(5, zone());
2964 Statement* stat = NULL;
2965 while (peek() != Token::CASE &&
2966 peek() != Token::DEFAULT &&
2967 peek() != Token::RBRACE) {
2968 stat = ParseStatementListItem(CHECK_OK);
2969 statements->Add(stat, zone());
2971 if (is_strong(language_mode()) && stat != NULL && !stat->IsJump() &&
2972 peek() != Token::RBRACE) {
2973 ReportMessageAt(scanner()->location(),
2974 MessageTemplate::kStrongSwitchFallthrough);
2978 return factory()->NewCaseClause(label, statements, pos);
2982 Statement* Parser::ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
2984 // SwitchStatement ::
2985 // 'switch' '(' Expression ')' '{' CaseClause* '}'
2986 // In order to get the CaseClauses to execute in their own lexical scope,
2987 // but without requiring downstream code to have special scope handling
2988 // code for switch statements, desugar into blocks as follows:
2989 // { // To group the statements--harmless to evaluate Expression in scope
2990 // .tag_variable = Expression;
2991 // { // To give CaseClauses a scope
2992 // switch (.tag_variable) { CaseClause* }
2996 Block* switch_block =
2997 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
2998 int switch_pos = peek_position();
3000 Expect(Token::SWITCH, CHECK_OK);
3001 Expect(Token::LPAREN, CHECK_OK);
3002 Expression* tag = ParseExpression(true, CHECK_OK);
3003 Expect(Token::RPAREN, CHECK_OK);
3005 Variable* tag_variable =
3006 scope_->NewTemporary(ast_value_factory()->dot_switch_tag_string());
3007 Assignment* tag_assign = factory()->NewAssignment(
3008 Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag,
3010 Statement* tag_statement =
3011 factory()->NewExpressionStatement(tag_assign, RelocInfo::kNoPosition);
3012 switch_block->AddStatement(tag_statement, zone());
3014 // make statement: undefined;
3015 // This is needed so the tag isn't returned as the value, in case the switch
3016 // statements don't have a value.
3017 switch_block->AddStatement(
3018 factory()->NewExpressionStatement(
3019 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
3020 RelocInfo::kNoPosition),
3023 Block* cases_block =
3024 factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
3025 Scope* cases_scope = NewScope(scope_, BLOCK_SCOPE);
3026 cases_scope->SetNonlinear();
3028 SwitchStatement* switch_statement =
3029 factory()->NewSwitchStatement(labels, switch_pos);
3031 cases_scope->set_start_position(scanner()->location().beg_pos);
3033 BlockState cases_block_state(&scope_, cases_scope);
3034 Target target(&this->target_stack_, switch_statement);
3036 Expression* tag_read = factory()->NewVariableProxy(tag_variable);
3038 bool default_seen = false;
3039 ZoneList<CaseClause*>* cases =
3040 new (zone()) ZoneList<CaseClause*>(4, zone());
3041 Expect(Token::LBRACE, CHECK_OK);
3042 while (peek() != Token::RBRACE) {
3043 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
3044 cases->Add(clause, zone());
3046 switch_statement->Initialize(tag_read, cases);
3047 cases_block->AddStatement(switch_statement, zone());
3049 Expect(Token::RBRACE, CHECK_OK);
3051 cases_scope->set_end_position(scanner()->location().end_pos);
3052 cases_scope = cases_scope->FinalizeBlockScope();
3053 cases_block->set_scope(cases_scope);
3055 switch_block->AddStatement(cases_block, zone());
3057 return switch_block;
3061 Statement* Parser::ParseThrowStatement(bool* ok) {
3062 // ThrowStatement ::
3063 // 'throw' Expression ';'
3065 Expect(Token::THROW, CHECK_OK);
3066 int pos = position();
3067 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
3068 ReportMessage(MessageTemplate::kNewlineAfterThrow);
3072 Expression* exception = ParseExpression(true, CHECK_OK);
3073 ExpectSemicolon(CHECK_OK);
3075 return factory()->NewExpressionStatement(
3076 factory()->NewThrow(exception, pos), pos);
3080 TryStatement* Parser::ParseTryStatement(bool* ok) {
3082 // 'try' Block Catch
3083 // 'try' Block Finally
3084 // 'try' Block Catch Finally
3087 // 'catch' '(' Identifier ')' Block
3092 Expect(Token::TRY, CHECK_OK);
3093 int pos = position();
3095 Block* try_block = ParseBlock(NULL, CHECK_OK);
3097 Token::Value tok = peek();
3098 if (tok != Token::CATCH && tok != Token::FINALLY) {
3099 ReportMessage(MessageTemplate::kNoCatchOrFinally);
3104 Scope* catch_scope = NULL;
3105 Variable* catch_variable = NULL;
3106 Block* catch_block = NULL;
3107 const AstRawString* name = NULL;
3108 if (tok == Token::CATCH) {
3109 Consume(Token::CATCH);
3111 Expect(Token::LPAREN, CHECK_OK);
3112 catch_scope = NewScope(scope_, CATCH_SCOPE);
3113 catch_scope->set_start_position(scanner()->location().beg_pos);
3114 name = ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
3116 Expect(Token::RPAREN, CHECK_OK);
3118 catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized,
3120 BlockState block_state(&scope_, catch_scope);
3121 catch_block = ParseBlock(NULL, CHECK_OK);
3123 catch_scope->set_end_position(scanner()->location().end_pos);
3127 Block* finally_block = NULL;
3128 DCHECK(tok == Token::FINALLY || catch_block != NULL);
3129 if (tok == Token::FINALLY) {
3130 Consume(Token::FINALLY);
3131 finally_block = ParseBlock(NULL, CHECK_OK);
3134 // Simplify the AST nodes by converting:
3135 // 'try B0 catch B1 finally B2'
3137 // 'try { try B0 catch B1 } finally B2'
3139 if (catch_block != NULL && finally_block != NULL) {
3140 // If we have both, create an inner try/catch.
3141 DCHECK(catch_scope != NULL && catch_variable != NULL);
3142 TryCatchStatement* statement =
3143 factory()->NewTryCatchStatement(try_block, catch_scope, catch_variable,
3144 catch_block, RelocInfo::kNoPosition);
3145 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
3146 try_block->AddStatement(statement, zone());
3147 catch_block = NULL; // Clear to indicate it's been handled.
3150 TryStatement* result = NULL;
3151 if (catch_block != NULL) {
3152 DCHECK(finally_block == NULL);
3153 DCHECK(catch_scope != NULL && catch_variable != NULL);
3154 result = factory()->NewTryCatchStatement(try_block, catch_scope,
3155 catch_variable, catch_block, pos);
3157 DCHECK(finally_block != NULL);
3158 result = factory()->NewTryFinallyStatement(try_block, finally_block, pos);
3165 DoWhileStatement* Parser::ParseDoWhileStatement(
3166 ZoneList<const AstRawString*>* labels, bool* ok) {
3168 // 'do' Statement 'while' '(' Expression ')' ';'
3170 DoWhileStatement* loop =
3171 factory()->NewDoWhileStatement(labels, peek_position());
3172 Target target(&this->target_stack_, loop);
3174 Expect(Token::DO, CHECK_OK);
3175 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3176 Expect(Token::WHILE, CHECK_OK);
3177 Expect(Token::LPAREN, CHECK_OK);
3179 Expression* cond = ParseExpression(true, CHECK_OK);
3180 Expect(Token::RPAREN, CHECK_OK);
3182 // Allow do-statements to be terminated with and without
3183 // semi-colons. This allows code such as 'do;while(0)return' to
3184 // parse, which would not be the case if we had used the
3185 // ExpectSemicolon() functionality here.
3186 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
3188 if (loop != NULL) loop->Initialize(cond, body);
3193 WhileStatement* Parser::ParseWhileStatement(
3194 ZoneList<const AstRawString*>* labels, bool* ok) {
3195 // WhileStatement ::
3196 // 'while' '(' Expression ')' Statement
3198 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position());
3199 Target target(&this->target_stack_, loop);
3201 Expect(Token::WHILE, CHECK_OK);
3202 Expect(Token::LPAREN, CHECK_OK);
3203 Expression* cond = ParseExpression(true, CHECK_OK);
3204 Expect(Token::RPAREN, CHECK_OK);
3205 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3207 if (loop != NULL) loop->Initialize(cond, body);
3212 // !%_IsSpecObject(result = iterator.next()) &&
3213 // %ThrowIteratorResultNotAnObject(result)
3214 Expression* Parser::BuildIteratorNextResult(Expression* iterator,
3215 Variable* result, int pos) {
3216 Expression* next_literal = factory()->NewStringLiteral(
3217 ast_value_factory()->next_string(), RelocInfo::kNoPosition);
3218 Expression* next_property =
3219 factory()->NewProperty(iterator, next_literal, RelocInfo::kNoPosition);
3220 ZoneList<Expression*>* next_arguments =
3221 new (zone()) ZoneList<Expression*>(0, zone());
3222 Expression* next_call =
3223 factory()->NewCall(next_property, next_arguments, pos);
3224 Expression* result_proxy = factory()->NewVariableProxy(result);
3226 factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos);
3228 // %_IsSpecObject(...)
3229 ZoneList<Expression*>* is_spec_object_args =
3230 new (zone()) ZoneList<Expression*>(1, zone());
3231 is_spec_object_args->Add(left, zone());
3232 Expression* is_spec_object_call = factory()->NewCallRuntime(
3233 Runtime::kInlineIsSpecObject, is_spec_object_args, pos);
3235 // %ThrowIteratorResultNotAnObject(result)
3236 Expression* result_proxy_again = factory()->NewVariableProxy(result);
3237 ZoneList<Expression*>* throw_arguments =
3238 new (zone()) ZoneList<Expression*>(1, zone());
3239 throw_arguments->Add(result_proxy_again, zone());
3240 Expression* throw_call = factory()->NewCallRuntime(
3241 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos);
3243 return factory()->NewBinaryOperation(
3245 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos),
3250 void Parser::InitializeForEachStatement(ForEachStatement* stmt,
3252 Expression* subject,
3254 ForOfStatement* for_of = stmt->AsForOfStatement();
3256 if (for_of != NULL) {
3257 Variable* iterator = scope_->NewTemporary(
3258 ast_value_factory()->dot_iterator_string());
3259 Variable* result = scope_->NewTemporary(
3260 ast_value_factory()->dot_result_string());
3262 Expression* assign_iterator;
3263 Expression* next_result;
3264 Expression* result_done;
3265 Expression* assign_each;
3267 // iterator = subject[Symbol.iterator]()
3268 assign_iterator = factory()->NewAssignment(
3269 Token::ASSIGN, factory()->NewVariableProxy(iterator),
3270 GetIterator(subject, factory()), subject->position());
3272 // !%_IsSpecObject(result = iterator.next()) &&
3273 // %ThrowIteratorResultNotAnObject(result)
3275 // result = iterator.next()
3276 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
3278 BuildIteratorNextResult(iterator_proxy, result, subject->position());
3283 Expression* done_literal = factory()->NewStringLiteral(
3284 ast_value_factory()->done_string(), RelocInfo::kNoPosition);
3285 Expression* result_proxy = factory()->NewVariableProxy(result);
3286 result_done = factory()->NewProperty(
3287 result_proxy, done_literal, RelocInfo::kNoPosition);
3290 // each = result.value
3292 Expression* value_literal = factory()->NewStringLiteral(
3293 ast_value_factory()->value_string(), RelocInfo::kNoPosition);
3294 Expression* result_proxy = factory()->NewVariableProxy(result);
3295 Expression* result_value = factory()->NewProperty(
3296 result_proxy, value_literal, RelocInfo::kNoPosition);
3297 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value,
3298 RelocInfo::kNoPosition);
3301 for_of->Initialize(each, subject, body,
3307 stmt->Initialize(each, subject, body);
3312 Statement* Parser::DesugarLexicalBindingsInForStatement(
3313 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names,
3314 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
3315 Statement* body, bool* ok) {
3316 // ES6 13.6.3.4 specifies that on each loop iteration the let variables are
3317 // copied into a new environment. After copying, the "next" statement of the
3318 // loop is executed to update the loop variables. The loop condition is
3319 // checked and the loop body is executed.
3321 // We rewrite a for statement of the form
3323 // labels: for (let/const x = i; cond; next) body
3332 // outer: for (;;) {
3333 // { // This block's only function is to ensure that the statements it
3334 // // contains do not affect the normal completion value. This is
3335 // // accomplished by setting its ignore_completion_value bit.
3336 // // No new lexical scope is introduced, so lexically scoped variables
3337 // // declared here will be scoped to the outer for loop.
3338 // let/const x = temp_x;
3339 // if (first == 1) {
3346 // labels: for (; flag == 1; flag = 0, temp_x = x) {
3359 DCHECK(names->length() > 0);
3360 Scope* for_scope = scope_;
3361 ZoneList<Variable*> temps(names->length(), zone());
3363 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false,
3364 RelocInfo::kNoPosition);
3366 // Add statement: let/const x = i.
3367 outer_block->AddStatement(init, zone());
3369 const AstRawString* temp_name = ast_value_factory()->dot_for_string();
3371 // For each lexical variable x:
3372 // make statement: temp_x = x.
3373 for (int i = 0; i < names->length(); i++) {
3374 VariableProxy* proxy = NewUnresolved(names->at(i), LET);
3375 Variable* temp = scope_->NewTemporary(temp_name);
3376 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
3377 Assignment* assignment = factory()->NewAssignment(
3378 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3379 Statement* assignment_statement = factory()->NewExpressionStatement(
3380 assignment, RelocInfo::kNoPosition);
3381 outer_block->AddStatement(assignment_statement, zone());
3382 temps.Add(temp, zone());
3385 Variable* first = NULL;
3386 // Make statement: first = 1.
3388 first = scope_->NewTemporary(temp_name);
3389 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3390 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3391 Assignment* assignment = factory()->NewAssignment(
3392 Token::ASSIGN, first_proxy, const1, RelocInfo::kNoPosition);
3393 Statement* assignment_statement =
3394 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3395 outer_block->AddStatement(assignment_statement, zone());
3398 // make statement: undefined;
3399 outer_block->AddStatement(
3400 factory()->NewExpressionStatement(
3401 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
3402 RelocInfo::kNoPosition),
3405 // Make statement: outer: for (;;)
3406 // Note that we don't actually create the label, or set this loop up as an
3407 // explicit break target, instead handing it directly to those nodes that
3408 // need to know about it. This should be safe because we don't run any code
3409 // in this function that looks up break targets.
3410 ForStatement* outer_loop =
3411 factory()->NewForStatement(NULL, RelocInfo::kNoPosition);
3412 outer_block->AddStatement(outer_loop, zone());
3414 outer_block->set_scope(for_scope);
3415 scope_ = inner_scope;
3417 Block* inner_block =
3418 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3419 Block* ignore_completion_block = factory()->NewBlock(
3420 NULL, names->length() + 2, true, RelocInfo::kNoPosition);
3421 ZoneList<Variable*> inner_vars(names->length(), zone());
3422 // For each let variable x:
3423 // make statement: let/const x = temp_x.
3424 VariableMode mode = is_const ? CONST : LET;
3425 for (int i = 0; i < names->length(); i++) {
3426 VariableProxy* proxy = NewUnresolved(names->at(i), mode);
3427 Declaration* declaration = factory()->NewVariableDeclaration(
3428 proxy, mode, scope_, RelocInfo::kNoPosition);
3429 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
3430 inner_vars.Add(declaration->proxy()->var(), zone());
3431 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3432 Assignment* assignment =
3433 factory()->NewAssignment(is_const ? Token::INIT_CONST : Token::INIT_LET,
3434 proxy, temp_proxy, RelocInfo::kNoPosition);
3435 Statement* assignment_statement =
3436 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3437 DCHECK(init->position() != RelocInfo::kNoPosition);
3438 proxy->var()->set_initializer_position(init->position());
3439 ignore_completion_block->AddStatement(assignment_statement, zone());
3442 // Make statement: if (first == 1) { first = 0; } else { next; }
3445 Expression* compare = NULL;
3446 // Make compare expression: first == 1.
3448 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3449 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3450 compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
3451 RelocInfo::kNoPosition);
3453 Statement* clear_first = NULL;
3454 // Make statement: first = 0.
3456 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3457 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3458 Assignment* assignment = factory()->NewAssignment(
3459 Token::ASSIGN, first_proxy, const0, RelocInfo::kNoPosition);
3461 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3463 Statement* clear_first_or_next = factory()->NewIfStatement(
3464 compare, clear_first, next, RelocInfo::kNoPosition);
3465 ignore_completion_block->AddStatement(clear_first_or_next, zone());
3468 Variable* flag = scope_->NewTemporary(temp_name);
3469 // Make statement: flag = 1.
3471 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3472 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3473 Assignment* assignment = factory()->NewAssignment(
3474 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
3475 Statement* assignment_statement =
3476 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3477 ignore_completion_block->AddStatement(assignment_statement, zone());
3479 inner_block->AddStatement(ignore_completion_block, zone());
3480 // Make cond expression for main loop: flag == 1.
3481 Expression* flag_cond = NULL;
3483 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3484 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3485 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
3486 RelocInfo::kNoPosition);
3489 // Create chain of expressions "flag = 0, temp_x = x, ..."
3490 Statement* compound_next_statement = NULL;
3492 Expression* compound_next = NULL;
3493 // Make expression: flag = 0.
3495 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3496 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3497 compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
3498 const0, RelocInfo::kNoPosition);
3501 // Make the comma-separated list of temp_x = x assignments.
3502 int inner_var_proxy_pos = scanner()->location().beg_pos;
3503 for (int i = 0; i < names->length(); i++) {
3504 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3505 VariableProxy* proxy =
3506 factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos);
3507 Assignment* assignment = factory()->NewAssignment(
3508 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3509 compound_next = factory()->NewBinaryOperation(
3510 Token::COMMA, compound_next, assignment, RelocInfo::kNoPosition);
3513 compound_next_statement = factory()->NewExpressionStatement(
3514 compound_next, RelocInfo::kNoPosition);
3517 // Make statement: if (cond) { body; } else { break outer; }
3518 Statement* body_or_stop = body;
3521 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3523 factory()->NewIfStatement(cond, body, stop, cond->position());
3526 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
3527 // Note that we re-use the original loop node, which retains its labels
3528 // and ensures that any break or continue statements in body point to
3530 loop->Initialize(NULL, flag_cond, compound_next_statement, body_or_stop);
3531 inner_block->AddStatement(loop, zone());
3533 // Make statement: if (flag == 1) { break; }
3535 Expression* compare = NULL;
3536 // Make compare expresion: flag == 1.
3538 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3539 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3540 compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
3541 RelocInfo::kNoPosition);
3544 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3545 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
3546 Statement* if_flag_break =
3547 factory()->NewIfStatement(compare, stop, empty, RelocInfo::kNoPosition);
3548 inner_block->AddStatement(if_flag_break, zone());
3551 inner_scope->set_end_position(scanner()->location().end_pos);
3552 inner_block->set_scope(inner_scope);
3555 outer_loop->Initialize(NULL, NULL, NULL, inner_block);
3560 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
3563 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
3565 int stmt_pos = peek_position();
3566 bool is_const = false;
3567 Statement* init = NULL;
3568 ZoneList<const AstRawString*> lexical_bindings(1, zone());
3570 // Create an in-between scope for let-bound iteration variables.
3571 Scope* saved_scope = scope_;
3572 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
3574 Expect(Token::FOR, CHECK_OK);
3575 Expect(Token::LPAREN, CHECK_OK);
3576 for_scope->set_start_position(scanner()->location().beg_pos);
3577 bool is_let_identifier_expression = false;
3578 DeclarationParsingResult parsing_result;
3579 if (peek() != Token::SEMICOLON) {
3580 if (peek() == Token::VAR || (peek() == Token::CONST && allow_const()) ||
3581 (peek() == Token::LET && IsNextLetKeyword())) {
3582 ParseVariableDeclarations(kForStatement, &parsing_result, CHECK_OK);
3583 is_const = parsing_result.descriptor.mode == CONST;
3585 int num_decl = parsing_result.declarations.length();
3586 bool accept_IN = num_decl >= 1;
3587 bool accept_OF = true;
3588 ForEachStatement::VisitMode mode;
3589 int each_beg_pos = scanner()->location().beg_pos;
3590 int each_end_pos = scanner()->location().end_pos;
3592 if (accept_IN && CheckInOrOf(accept_OF, &mode, ok)) {
3593 if (!*ok) return nullptr;
3594 if (num_decl != 1) {
3595 const char* loop_type =
3596 mode == ForEachStatement::ITERATE ? "for-of" : "for-in";
3597 ParserTraits::ReportMessageAt(
3598 parsing_result.bindings_loc,
3599 MessageTemplate::kForInOfLoopMultiBindings, loop_type);
3603 if (parsing_result.first_initializer_loc.IsValid() &&
3604 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE ||
3605 IsLexicalVariableMode(parsing_result.descriptor.mode))) {
3606 if (mode == ForEachStatement::ITERATE) {
3607 ReportMessageAt(parsing_result.first_initializer_loc,
3608 MessageTemplate::kForOfLoopInitializer);
3610 // TODO(caitp): This should be an error in sloppy mode too.
3611 ReportMessageAt(parsing_result.first_initializer_loc,
3612 MessageTemplate::kForInLoopInitializer);
3618 DCHECK(parsing_result.declarations.length() == 1);
3619 Block* init_block = nullptr;
3621 // special case for legacy for (var/const x =.... in)
3622 if (!IsLexicalVariableMode(parsing_result.descriptor.mode) &&
3623 parsing_result.declarations[0].initializer != nullptr) {
3624 VariableProxy* single_var = scope_->NewUnresolved(
3625 factory(), parsing_result.SingleName(), Variable::NORMAL,
3626 each_beg_pos, each_end_pos);
3627 init_block = factory()->NewBlock(
3628 nullptr, 2, true, parsing_result.descriptor.declaration_pos);
3629 init_block->AddStatement(
3630 factory()->NewExpressionStatement(
3631 factory()->NewAssignment(
3632 Token::ASSIGN, single_var,
3633 parsing_result.declarations[0].initializer,
3634 RelocInfo::kNoPosition),
3635 RelocInfo::kNoPosition),
3639 // Rewrite a for-in/of statement of the form
3641 // for (let/const/var x in/of e) b
3646 // <let x' be a temporary variable>
3647 // for (x' in/of e) {
3652 // let x; // for TDZ
3655 Variable* temp = scope_->NewTemporary(
3656 ast_value_factory()->dot_for_string());
3657 ForEachStatement* loop =
3658 factory()->NewForEachStatement(mode, labels, stmt_pos);
3659 Target target(&this->target_stack_, loop);
3661 Expression* enumerable = ParseExpression(true, CHECK_OK);
3663 Expect(Token::RPAREN, CHECK_OK);
3665 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE);
3666 body_scope->set_start_position(scanner()->location().beg_pos);
3667 scope_ = body_scope;
3669 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3672 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3674 auto each_initialization_block =
3675 factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition);
3677 DCHECK(parsing_result.declarations.length() == 1);
3678 DeclarationParsingResult::Declaration decl =
3679 parsing_result.declarations[0];
3680 auto descriptor = parsing_result.descriptor;
3681 descriptor.declaration_pos = RelocInfo::kNoPosition;
3682 descriptor.initialization_pos = RelocInfo::kNoPosition;
3683 decl.initializer = factory()->NewVariableProxy(temp);
3685 PatternRewriter::DeclareAndInitializeVariables(
3686 each_initialization_block, &descriptor, &decl,
3687 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings
3692 body_block->AddStatement(each_initialization_block, zone());
3693 body_block->AddStatement(body, zone());
3694 VariableProxy* temp_proxy =
3695 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
3696 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block);
3698 body_scope->set_end_position(scanner()->location().end_pos);
3699 body_scope = body_scope->FinalizeBlockScope();
3700 if (body_scope != nullptr) {
3701 body_block->set_scope(body_scope);
3704 // Create a TDZ for any lexically-bound names.
3705 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) {
3706 DCHECK_NULL(init_block);
3709 factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition);
3711 for (int i = 0; i < lexical_bindings.length(); ++i) {
3712 // TODO(adamk): This needs to be some sort of special
3713 // INTERNAL variable that's invisible to the debugger
3714 // but visible to everything else.
3715 VariableProxy* tdz_proxy = NewUnresolved(lexical_bindings[i], LET);
3716 Declaration* tdz_decl = factory()->NewVariableDeclaration(
3717 tdz_proxy, LET, scope_, RelocInfo::kNoPosition);
3718 Variable* tdz_var = Declare(tdz_decl, DeclarationDescriptor::NORMAL,
3720 tdz_var->set_initializer_position(position());
3724 scope_ = saved_scope;
3725 for_scope->set_end_position(scanner()->location().end_pos);
3726 for_scope = for_scope->FinalizeBlockScope();
3727 // Parsed for-in loop w/ variable declarations.
3728 if (init_block != nullptr) {
3729 init_block->AddStatement(loop, zone());
3730 if (for_scope != nullptr) {
3731 init_block->set_scope(for_scope);
3735 DCHECK_NULL(for_scope);
3739 init = parsing_result.BuildInitializationBlock(
3740 IsLexicalVariableMode(parsing_result.descriptor.mode)
3746 int lhs_beg_pos = peek_position();
3747 Expression* expression = ParseExpression(false, CHECK_OK);
3748 int lhs_end_pos = scanner()->location().end_pos;
3749 ForEachStatement::VisitMode mode;
3750 bool accept_OF = expression->IsVariableProxy();
3751 is_let_identifier_expression =
3752 expression->IsVariableProxy() &&
3753 expression->AsVariableProxy()->raw_name() ==
3754 ast_value_factory()->let_string();
3756 if (CheckInOrOf(accept_OF, &mode, ok)) {
3757 if (!*ok) return nullptr;
3758 expression = this->CheckAndRewriteReferenceExpression(
3759 expression, lhs_beg_pos, lhs_end_pos,
3760 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK);
3762 ForEachStatement* loop =
3763 factory()->NewForEachStatement(mode, labels, stmt_pos);
3764 Target target(&this->target_stack_, loop);
3766 Expression* enumerable = ParseExpression(true, CHECK_OK);
3767 Expect(Token::RPAREN, CHECK_OK);
3769 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3770 InitializeForEachStatement(loop, expression, enumerable, body);
3771 scope_ = saved_scope;
3772 for_scope->set_end_position(scanner()->location().end_pos);
3773 for_scope = for_scope->FinalizeBlockScope();
3774 DCHECK(for_scope == NULL);
3775 // Parsed for-in loop.
3779 init = factory()->NewExpressionStatement(expression, lhs_beg_pos);
3784 // Standard 'for' loop
3785 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos);
3786 Target target(&this->target_stack_, loop);
3788 // Parsed initializer at this point.
3789 // Detect attempts at 'let' declarations in sloppy mode.
3790 if (peek() == Token::IDENTIFIER && is_sloppy(language_mode()) &&
3791 is_let_identifier_expression) {
3792 ReportMessage(MessageTemplate::kSloppyLexical, NULL);
3796 Expect(Token::SEMICOLON, CHECK_OK);
3798 // If there are let bindings, then condition and the next statement of the
3799 // for loop must be parsed in a new scope.
3800 Scope* inner_scope = NULL;
3801 if (lexical_bindings.length() > 0) {
3802 inner_scope = NewScope(for_scope, BLOCK_SCOPE);
3803 inner_scope->set_start_position(scanner()->location().beg_pos);
3804 scope_ = inner_scope;
3807 Expression* cond = NULL;
3808 if (peek() != Token::SEMICOLON) {
3809 cond = ParseExpression(true, CHECK_OK);
3811 Expect(Token::SEMICOLON, CHECK_OK);
3813 Statement* next = NULL;
3814 if (peek() != Token::RPAREN) {
3815 Expression* exp = ParseExpression(true, CHECK_OK);
3816 next = factory()->NewExpressionStatement(exp, exp->position());
3818 Expect(Token::RPAREN, CHECK_OK);
3820 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3822 Statement* result = NULL;
3823 if (lexical_bindings.length() > 0) {
3825 result = DesugarLexicalBindingsInForStatement(
3826 inner_scope, is_const, &lexical_bindings, loop, init, cond,
3827 next, body, CHECK_OK);
3828 scope_ = saved_scope;
3829 for_scope->set_end_position(scanner()->location().end_pos);
3831 scope_ = saved_scope;
3832 for_scope->set_end_position(scanner()->location().end_pos);
3833 for_scope = for_scope->FinalizeBlockScope();
3835 // Rewrite a for statement of the form
3836 // for (const x = i; c; n) b
3844 DCHECK(init != NULL);
3846 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3847 block->AddStatement(init, zone());
3848 block->AddStatement(loop, zone());
3849 block->set_scope(for_scope);
3850 loop->Initialize(NULL, cond, next, body);
3853 loop->Initialize(init, cond, next, body);
3861 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
3862 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
3863 // contexts this is used as a statement which invokes the debugger as i a
3864 // break point is present.
3865 // DebuggerStatement ::
3868 int pos = peek_position();
3869 Expect(Token::DEBUGGER, CHECK_OK);
3870 ExpectSemicolon(CHECK_OK);
3871 return factory()->NewDebuggerStatement(pos);
3875 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
3876 if (expression->IsLiteral()) return true;
3877 MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3878 return lit != NULL && lit->is_simple();
3882 Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate,
3883 Expression* expression) {
3884 Factory* factory = isolate->factory();
3885 DCHECK(IsCompileTimeValue(expression));
3886 Handle<FixedArray> result = factory->NewFixedArray(2, TENURED);
3887 ObjectLiteral* object_literal = expression->AsObjectLiteral();
3888 if (object_literal != NULL) {
3889 DCHECK(object_literal->is_simple());
3890 if (object_literal->fast_elements()) {
3891 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
3893 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
3895 result->set(kElementsSlot, *object_literal->constant_properties());
3897 ArrayLiteral* array_literal = expression->AsArrayLiteral();
3898 DCHECK(array_literal != NULL && array_literal->is_simple());
3899 result->set(kLiteralTypeSlot, Smi::FromInt(ARRAY_LITERAL));
3900 result->set(kElementsSlot, *array_literal->constant_elements());
3906 CompileTimeValue::LiteralType CompileTimeValue::GetLiteralType(
3907 Handle<FixedArray> value) {
3908 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot));
3909 return static_cast<LiteralType>(literal_type->value());
3913 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
3914 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
3918 void ParserTraits::ParseArrowFunctionFormalParameters(
3919 ParserFormalParameters* parameters, Expression* expr,
3920 const Scanner::Location& params_loc, bool* ok) {
3921 if (parameters->Arity() >= Code::kMaxArguments) {
3922 ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
3927 // ArrowFunctionFormals ::
3928 // Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail)
3930 // NonTailArrowFunctionFormals ::
3931 // Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy)
3935 // Spread(VariableProxy)
3937 // As we need to visit the parameters in left-to-right order, we recurse on
3938 // the left-hand side of comma expressions.
3940 if (expr->IsBinaryOperation()) {
3941 BinaryOperation* binop = expr->AsBinaryOperation();
3942 // The classifier has already run, so we know that the expression is a valid
3943 // arrow function formals production.
3944 DCHECK_EQ(binop->op(), Token::COMMA);
3945 Expression* left = binop->left();
3946 Expression* right = binop->right();
3947 ParseArrowFunctionFormalParameters(parameters, left, params_loc, ok);
3949 // LHS of comma expression should be unparenthesized.
3953 // Only the right-most expression may be a rest parameter.
3954 DCHECK(!parameters->has_rest);
3956 bool is_rest = expr->IsSpread();
3958 expr = expr->AsSpread()->expression();
3959 parameters->has_rest = true;
3960 parameters->rest_array_literal_index =
3961 parser_->function_state_->NextMaterializedLiteralIndex();
3962 ++parameters->materialized_literals_count;
3964 if (parameters->is_simple) {
3965 parameters->is_simple = !is_rest && expr->IsVariableProxy();
3968 Expression* initializer = nullptr;
3969 if (expr->IsVariableProxy()) {
3970 // When the formal parameter was originally seen, it was parsed as a
3971 // VariableProxy and recorded as unresolved in the scope. Here we undo that
3972 // parse-time side-effect for parameters that are single-names (not
3973 // patterns; for patterns that happens uniformly in
3974 // PatternRewriter::VisitVariableProxy).
3975 parser_->scope_->RemoveUnresolved(expr->AsVariableProxy());
3976 } else if (expr->IsAssignment()) {
3977 Assignment* assignment = expr->AsAssignment();
3978 DCHECK(parser_->allow_harmony_default_parameters());
3979 DCHECK(!assignment->is_compound());
3980 initializer = assignment->value();
3981 expr = assignment->target();
3984 AddFormalParameter(parameters, expr, initializer, is_rest);
3988 void ParserTraits::ParseArrowFunctionFormalParameterList(
3989 ParserFormalParameters* parameters, Expression* expr,
3990 const Scanner::Location& params_loc,
3991 Scanner::Location* duplicate_loc, bool* ok) {
3992 if (expr->IsEmptyParentheses()) return;
3994 ParseArrowFunctionFormalParameters(parameters, expr, params_loc, ok);
3997 ExpressionClassifier classifier;
3998 if (!parameters->is_simple) {
3999 classifier.RecordNonSimpleParameter();
4001 for (int i = 0; i < parameters->Arity(); ++i) {
4002 auto parameter = parameters->at(i);
4003 DeclareFormalParameter(parameters->scope, parameter, &classifier);
4004 if (!duplicate_loc->IsValid()) {
4005 *duplicate_loc = classifier.duplicate_formal_parameter_error().location;
4008 DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters());
4012 void ParserTraits::ReindexLiterals(const ParserFormalParameters& parameters) {
4013 if (parser_->function_state_->materialized_literal_count() > 0) {
4014 AstLiteralReindexer reindexer;
4016 for (const auto p : parameters.params) {
4017 if (p.pattern != nullptr) reindexer.Reindex(p.pattern);
4020 if (parameters.has_rest) {
4021 parameters.rest_array_literal_index = reindexer.NextIndex();
4024 DCHECK(reindexer.count() <=
4025 parser_->function_state_->materialized_literal_count());
4030 FunctionLiteral* Parser::ParseFunctionLiteral(
4031 const AstRawString* function_name, Scanner::Location function_name_location,
4032 FunctionNameValidity function_name_validity, FunctionKind kind,
4033 int function_token_pos, FunctionLiteral::FunctionType function_type,
4034 FunctionLiteral::ArityRestriction arity_restriction,
4035 LanguageMode language_mode, bool* ok) {
4037 // '(' FormalParameterList? ')' '{' FunctionBody '}'
4040 // '(' ')' '{' FunctionBody '}'
4043 // '(' PropertySetParameterList ')' '{' FunctionBody '}'
4045 int pos = function_token_pos == RelocInfo::kNoPosition
4046 ? peek_position() : function_token_pos;
4048 bool is_generator = IsGeneratorFunction(kind);
4050 // Anonymous functions were passed either the empty symbol or a null
4051 // handle as the function name. Remember if we were passed a non-empty
4052 // handle to decide whether to invoke function name inference.
4053 bool should_infer_name = function_name == NULL;
4055 // We want a non-null handle as the function name.
4056 if (should_infer_name) {
4057 function_name = ast_value_factory()->empty_string();
4060 // Function declarations are function scoped in normal mode, so they are
4061 // hoisted. In harmony block scoping mode they are block scoped, so they
4064 // One tricky case are function declarations in a local sloppy-mode eval:
4065 // their declaration is hoisted, but they still see the local scope. E.g.,
4069 // try { throw 1 } catch (x) { eval("function g() { return x }") }
4073 // needs to return 1. To distinguish such cases, we need to detect
4074 // (1) whether a function stems from a sloppy eval, and
4075 // (2) whether it actually hoists across the eval.
4076 // Unfortunately, we do not represent sloppy eval scopes, so we do not have
4077 // either information available directly, especially not when lazily compiling
4078 // a function like 'g'. We hence rely on the following invariants:
4079 // - (1) is the case iff the innermost scope of the deserialized scope chain
4080 // under which we compile is _not_ a declaration scope. This holds because
4081 // in all normal cases, function declarations are fully hoisted to a
4082 // declaration scope and compiled relative to that.
4083 // - (2) is the case iff the current declaration scope is still the original
4084 // one relative to the deserialized scope chain. Otherwise we must be
4085 // compiling a function in an inner declaration scope in the eval, e.g. a
4086 // nested function, and hoisting works normally relative to that.
4087 Scope* declaration_scope = scope_->DeclarationScope();
4088 Scope* original_declaration_scope = original_scope_->DeclarationScope();
4089 Scope* scope = function_type == FunctionLiteral::DECLARATION &&
4090 is_sloppy(language_mode) &&
4091 !allow_harmony_sloppy_function() &&
4092 (original_scope_ == original_declaration_scope ||
4093 declaration_scope != original_declaration_scope)
4094 ? NewScope(declaration_scope, FUNCTION_SCOPE, kind)
4095 : NewScope(scope_, FUNCTION_SCOPE, kind);
4096 scope->SetLanguageMode(language_mode);
4097 ZoneList<Statement*>* body = NULL;
4099 int materialized_literal_count = -1;
4100 int expected_property_count = -1;
4101 DuplicateFinder duplicate_finder(scanner()->unicode_cache());
4102 ExpressionClassifier formals_classifier(&duplicate_finder);
4103 FunctionLiteral::EagerCompileHint eager_compile_hint =
4104 parenthesized_function_ ? FunctionLiteral::kShouldEagerCompile
4105 : FunctionLiteral::kShouldLazyCompile;
4106 bool should_be_used_once_hint = false;
4109 AstNodeFactory function_factory(ast_value_factory());
4110 FunctionState function_state(&function_state_, &scope_, scope, kind,
4112 scope_->SetScopeName(function_name);
4115 // For generators, allocating variables in contexts is currently a win
4116 // because it minimizes the work needed to suspend and resume an
4118 scope_->ForceContextAllocation();
4120 // Calling a generator returns a generator object. That object is stored
4121 // in a temporary variable, a definition that is used by "yield"
4122 // expressions. This also marks the FunctionState as a generator.
4123 Variable* temp = scope_->NewTemporary(
4124 ast_value_factory()->dot_generator_object_string());
4125 function_state.set_generator_object_variable(temp);
4128 Expect(Token::LPAREN, CHECK_OK);
4129 int start_position = scanner()->location().beg_pos;
4130 scope_->set_start_position(start_position);
4131 ParserFormalParameters formals(scope);
4132 ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
4133 arity = formals.Arity();
4134 Expect(Token::RPAREN, CHECK_OK);
4135 int formals_end_position = scanner()->location().end_pos;
4137 CheckArityRestrictions(arity, arity_restriction,
4138 formals.has_rest, start_position,
4139 formals_end_position, CHECK_OK);
4140 Expect(Token::LBRACE, CHECK_OK);
4142 // Determine if the function can be parsed lazily. Lazy parsing is different
4143 // from lazy compilation; we need to parse more eagerly than we compile.
4145 // We can only parse lazily if we also compile lazily. The heuristics for
4146 // lazy compilation are:
4147 // - It must not have been prohibited by the caller to Parse (some callers
4148 // need a full AST).
4149 // - The outer scope must allow lazy compilation of inner functions.
4150 // - The function mustn't be a function expression with an open parenthesis
4151 // before; we consider that a hint that the function will be called
4152 // immediately, and it would be a waste of time to make it lazily
4154 // These are all things we can know at this point, without looking at the
4157 // In addition, we need to distinguish between these cases:
4158 // (function foo() {
4159 // bar = function() { return 1; }
4162 // (function foo() {
4164 // bar = function() { return a; }
4167 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
4168 // parenthesis before the function means that it will be called
4169 // immediately). The inner function *must* be parsed eagerly to resolve the
4170 // possible reference to the variable in foo's scope. However, it's possible
4171 // that it will be compiled lazily.
4173 // To make this additional case work, both Parser and PreParser implement a
4174 // logic where only top-level functions will be parsed lazily.
4175 bool is_lazily_parsed = mode() == PARSE_LAZILY &&
4176 scope_->AllowsLazyParsing() &&
4177 !parenthesized_function_;
4178 parenthesized_function_ = false; // The bit was set for this function only.
4180 // Eager or lazy parse?
4181 // If is_lazily_parsed, we'll parse lazy. If we can set a bookmark, we'll
4182 // pass it to SkipLazyFunctionBody, which may use it to abort lazy
4183 // parsing if it suspect that wasn't a good idea. If so, or if we didn't
4184 // try to lazy parse in the first place, we'll have to parse eagerly.
4185 Scanner::BookmarkScope bookmark(scanner());
4186 if (is_lazily_parsed) {
4187 Scanner::BookmarkScope* maybe_bookmark =
4188 bookmark.Set() ? &bookmark : nullptr;
4189 SkipLazyFunctionBody(&materialized_literal_count,
4190 &expected_property_count, /*CHECK_OK*/ ok,
4193 if (formals.materialized_literals_count > 0) {
4194 materialized_literal_count += formals.materialized_literals_count;
4197 if (bookmark.HasBeenReset()) {
4198 // Trigger eager (re-)parsing, just below this block.
4199 is_lazily_parsed = false;
4201 // This is probably an initialization function. Inform the compiler it
4202 // should also eager-compile this function, and that we expect it to be
4204 eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
4205 should_be_used_once_hint = true;
4208 if (!is_lazily_parsed) {
4209 body = ParseEagerFunctionBody(function_name, pos, formals, kind,
4210 function_type, CHECK_OK);
4211 materialized_literal_count = function_state.materialized_literal_count();
4212 expected_property_count = function_state.expected_property_count();
4215 // Parsing the body may change the language mode in our scope.
4216 language_mode = scope->language_mode();
4218 if (is_strong(language_mode) && IsSubclassConstructor(kind)) {
4219 if (!function_state.super_location().IsValid()) {
4220 ReportMessageAt(function_name_location,
4221 MessageTemplate::kStrongSuperCallMissing,
4228 // Validate name and parameter names. We can do this only after parsing the
4229 // function, since the function can declare itself strict.
4230 CheckFunctionName(language_mode, function_name, function_name_validity,
4231 function_name_location, CHECK_OK);
4232 const bool allow_duplicate_parameters =
4233 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind);
4234 ValidateFormalParameters(&formals_classifier, language_mode,
4235 allow_duplicate_parameters, CHECK_OK);
4237 if (is_strict(language_mode)) {
4238 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
4241 if (is_strict(language_mode) || allow_harmony_sloppy()) {
4242 CheckConflictingVarDeclarations(scope, CHECK_OK);
4246 bool has_duplicate_parameters =
4247 !formals_classifier.is_valid_formal_parameter_list_without_duplicates();
4248 FunctionLiteral::ParameterFlag duplicate_parameters =
4249 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
4250 : FunctionLiteral::kNoDuplicateParameters;
4252 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
4253 function_name, ast_value_factory(), scope, body,
4254 materialized_literal_count, expected_property_count, arity,
4255 duplicate_parameters, function_type, FunctionLiteral::kIsFunction,
4256 eager_compile_hint, kind, pos);
4257 function_literal->set_function_token_position(function_token_pos);
4258 if (should_be_used_once_hint)
4259 function_literal->set_should_be_used_once_hint();
4261 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
4262 return function_literal;
4266 void Parser::SkipLazyFunctionBody(int* materialized_literal_count,
4267 int* expected_property_count, bool* ok,
4268 Scanner::BookmarkScope* bookmark) {
4269 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet());
4270 if (produce_cached_parse_data()) CHECK(log_);
4272 int function_block_pos = position();
4273 if (consume_cached_parse_data() && !cached_parse_data_->rejected()) {
4274 // If we have cached data, we use it to skip parsing the function body. The
4275 // data contains the information we need to construct the lazy function.
4276 FunctionEntry entry =
4277 cached_parse_data_->GetFunctionEntry(function_block_pos);
4278 // Check that cached data is valid. If not, mark it as invalid (the embedder
4279 // handles it). Note that end position greater than end of stream is safe,
4280 // and hard to check.
4281 if (entry.is_valid() && entry.end_pos() > function_block_pos) {
4282 scanner()->SeekForward(entry.end_pos() - 1);
4284 scope_->set_end_position(entry.end_pos());
4285 Expect(Token::RBRACE, ok);
4289 total_preparse_skipped_ += scope_->end_position() - function_block_pos;
4290 *materialized_literal_count = entry.literal_count();
4291 *expected_property_count = entry.property_count();
4292 scope_->SetLanguageMode(entry.language_mode());
4293 if (entry.uses_super_property()) scope_->RecordSuperPropertyUsage();
4294 if (entry.calls_eval()) scope_->RecordEvalCall();
4297 cached_parse_data_->Reject();
4299 // With no cached data, we partially parse the function, without building an
4300 // AST. This gathers the data needed to build a lazy function.
4301 SingletonLogger logger;
4302 PreParser::PreParseResult result =
4303 ParseLazyFunctionBodyWithPreParser(&logger, bookmark);
4304 if (bookmark && bookmark->HasBeenReset()) {
4305 return; // Return immediately if pre-parser devided to abort parsing.
4307 if (result == PreParser::kPreParseStackOverflow) {
4308 // Propagate stack overflow.
4309 set_stack_overflow();
4313 if (logger.has_error()) {
4314 ParserTraits::ReportMessageAt(
4315 Scanner::Location(logger.start(), logger.end()), logger.message(),
4316 logger.argument_opt(), logger.error_type());
4320 scope_->set_end_position(logger.end());
4321 Expect(Token::RBRACE, ok);
4325 total_preparse_skipped_ += scope_->end_position() - function_block_pos;
4326 *materialized_literal_count = logger.literals();
4327 *expected_property_count = logger.properties();
4328 scope_->SetLanguageMode(logger.language_mode());
4329 if (logger.uses_super_property()) {
4330 scope_->RecordSuperPropertyUsage();
4332 if (logger.calls_eval()) {
4333 scope_->RecordEvalCall();
4335 if (produce_cached_parse_data()) {
4337 // Position right after terminal '}'.
4338 int body_end = scanner()->location().end_pos;
4339 log_->LogFunction(function_block_pos, body_end, *materialized_literal_count,
4340 *expected_property_count, scope_->language_mode(),
4341 scope_->uses_super_property(), scope_->calls_eval());
4346 void Parser::AddAssertIsConstruct(ZoneList<Statement*>* body, int pos) {
4347 ZoneList<Expression*>* arguments =
4348 new (zone()) ZoneList<Expression*>(0, zone());
4349 CallRuntime* construct_check = factory()->NewCallRuntime(
4350 Runtime::kInlineIsConstructCall, arguments, pos);
4351 CallRuntime* non_callable_error = factory()->NewCallRuntime(
4352 Runtime::kThrowConstructorNonCallableError, arguments, pos);
4353 IfStatement* if_statement = factory()->NewIfStatement(
4354 factory()->NewUnaryOperation(Token::NOT, construct_check, pos),
4355 factory()->NewReturnStatement(non_callable_error, pos),
4356 factory()->NewEmptyStatement(pos), pos);
4357 body->Add(if_statement, zone());
4361 Statement* Parser::BuildAssertIsCoercible(Variable* var) {
4362 // if (var === null || var === undefined)
4363 // throw /* type error kNonCoercible) */;
4365 Expression* condition = factory()->NewBinaryOperation(
4366 Token::OR, factory()->NewCompareOperation(
4367 Token::EQ_STRICT, factory()->NewVariableProxy(var),
4368 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
4369 RelocInfo::kNoPosition),
4370 factory()->NewCompareOperation(
4371 Token::EQ_STRICT, factory()->NewVariableProxy(var),
4372 factory()->NewNullLiteral(RelocInfo::kNoPosition),
4373 RelocInfo::kNoPosition),
4374 RelocInfo::kNoPosition);
4375 Expression* throw_type_error = this->NewThrowTypeError(
4376 MessageTemplate::kNonCoercible, ast_value_factory()->empty_string(),
4377 RelocInfo::kNoPosition);
4378 IfStatement* if_statement = factory()->NewIfStatement(
4379 condition, factory()->NewExpressionStatement(throw_type_error,
4380 RelocInfo::kNoPosition),
4381 factory()->NewEmptyStatement(RelocInfo::kNoPosition),
4382 RelocInfo::kNoPosition);
4383 return if_statement;
4387 Block* Parser::BuildParameterInitializationBlock(
4388 const ParserFormalParameters& parameters, bool* ok) {
4389 DCHECK(!parameters.is_simple);
4390 DCHECK(scope_->is_function_scope());
4392 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
4393 for (int i = 0; i < parameters.params.length(); ++i) {
4394 auto parameter = parameters.params[i];
4395 DeclarationDescriptor descriptor;
4396 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
4397 descriptor.parser = this;
4398 descriptor.declaration_scope = scope_;
4399 descriptor.scope = scope_;
4400 descriptor.hoist_scope = nullptr;
4401 descriptor.mode = LET;
4402 descriptor.is_const = false;
4403 descriptor.needs_init = true;
4404 descriptor.declaration_pos = parameter.pattern->position();
4405 descriptor.initialization_pos = parameter.pattern->position();
4406 descriptor.init_op = Token::INIT_LET;
4407 Expression* initial_value =
4408 factory()->NewVariableProxy(parameters.scope->parameter(i));
4409 if (parameter.initializer != nullptr) {
4410 // IS_UNDEFINED($param) ? initializer : $param
4411 DCHECK(!parameter.is_rest);
4412 auto condition = factory()->NewCompareOperation(
4414 factory()->NewVariableProxy(parameters.scope->parameter(i)),
4415 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
4416 RelocInfo::kNoPosition);
4417 initial_value = factory()->NewConditional(
4418 condition, parameter.initializer, initial_value,
4419 RelocInfo::kNoPosition);
4420 descriptor.initialization_pos = parameter.initializer->position();
4421 } else if (parameter.is_rest) {
4423 // for (var $argument_index = $rest_index;
4424 // $argument_index < %_ArgumentsLength();
4425 // ++$argument_index) {
4426 // %AppendElement($rest, %_Arguments($argument_index));
4428 // let <param> = $rest;
4429 DCHECK(parameter.pattern->IsVariableProxy());
4430 DCHECK_EQ(i, parameters.params.length() - 1);
4432 int pos = parameter.pattern->position();
4433 Variable* temp_var = parameters.scope->parameter(i);
4434 auto empty_values = new (zone()) ZoneList<Expression*>(0, zone());
4435 auto empty_array = factory()->NewArrayLiteral(
4436 empty_values, parameters.rest_array_literal_index,
4437 is_strong(language_mode()), RelocInfo::kNoPosition);
4439 auto init_array = factory()->NewAssignment(
4440 Token::INIT_VAR, factory()->NewVariableProxy(temp_var), empty_array,
4441 RelocInfo::kNoPosition);
4443 auto loop = factory()->NewForStatement(NULL, RelocInfo::kNoPosition);
4445 auto argument_index =
4446 parameters.scope->NewTemporary(ast_value_factory()->empty_string());
4447 auto init = factory()->NewExpressionStatement(
4448 factory()->NewAssignment(
4449 Token::INIT_VAR, factory()->NewVariableProxy(argument_index),
4450 factory()->NewSmiLiteral(i, RelocInfo::kNoPosition),
4451 RelocInfo::kNoPosition),
4452 RelocInfo::kNoPosition);
4454 auto empty_arguments = new (zone()) ZoneList<Expression*>(0, zone());
4456 // $arguments_index < arguments.length
4457 auto cond = factory()->NewCompareOperation(
4458 Token::LT, factory()->NewVariableProxy(argument_index),
4459 factory()->NewCallRuntime(Runtime::kInlineArgumentsLength,
4460 empty_arguments, RelocInfo::kNoPosition),
4461 RelocInfo::kNoPosition);
4464 auto next = factory()->NewExpressionStatement(
4465 factory()->NewCountOperation(
4466 Token::INC, true, factory()->NewVariableProxy(argument_index),
4467 RelocInfo::kNoPosition),
4468 RelocInfo::kNoPosition);
4470 // %_Arguments($arguments_index)
4471 auto arguments_args = new (zone()) ZoneList<Expression*>(1, zone());
4472 arguments_args->Add(factory()->NewVariableProxy(argument_index), zone());
4474 // %AppendElement($rest, %_Arguments($arguments_index))
4475 auto append_element_args = new (zone()) ZoneList<Expression*>(2, zone());
4477 append_element_args->Add(factory()->NewVariableProxy(temp_var), zone());
4478 append_element_args->Add(
4479 factory()->NewCallRuntime(Runtime::kInlineArguments, arguments_args,
4480 RelocInfo::kNoPosition),
4483 auto body = factory()->NewExpressionStatement(
4484 factory()->NewCallRuntime(Runtime::kAppendElement,
4485 append_element_args,
4486 RelocInfo::kNoPosition),
4487 RelocInfo::kNoPosition);
4489 loop->Initialize(init, cond, next, body);
4491 init_block->AddStatement(
4492 factory()->NewExpressionStatement(init_array, RelocInfo::kNoPosition),
4495 init_block->AddStatement(loop, zone());
4497 descriptor.initialization_pos = pos;
4500 Scope* param_scope = scope_;
4501 Block* param_block = init_block;
4502 if (!parameter.is_simple() && scope_->calls_sloppy_eval()) {
4503 param_scope = NewScope(scope_, BLOCK_SCOPE);
4504 param_scope->set_is_declaration_scope();
4505 param_scope->set_start_position(parameter.pattern->position());
4506 param_scope->set_end_position(RelocInfo::kNoPosition);
4507 param_scope->RecordEvalCall();
4508 param_block = factory()->NewBlock(NULL, 8, true, RelocInfo::kNoPosition);
4509 param_block->set_scope(param_scope);
4510 descriptor.hoist_scope = scope_;
4514 BlockState block_state(&scope_, param_scope);
4515 DeclarationParsingResult::Declaration decl(
4516 parameter.pattern, parameter.pattern->position(), initial_value);
4517 PatternRewriter::DeclareAndInitializeVariables(param_block, &descriptor,
4518 &decl, nullptr, CHECK_OK);
4521 if (!parameter.is_simple() && scope_->calls_sloppy_eval()) {
4522 param_scope = param_scope->FinalizeBlockScope();
4523 if (param_scope != nullptr) {
4524 CheckConflictingVarDeclarations(param_scope, CHECK_OK);
4526 init_block->AddStatement(param_block, zone());
4533 ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
4534 const AstRawString* function_name, int pos,
4535 const ParserFormalParameters& parameters, FunctionKind kind,
4536 FunctionLiteral::FunctionType function_type, bool* ok) {
4537 // Everything inside an eagerly parsed function will be parsed eagerly
4538 // (see comment above).
4539 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
4540 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone());
4542 static const int kFunctionNameAssignmentIndex = 0;
4543 if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
4544 DCHECK(function_name != NULL);
4545 // If we have a named function expression, we add a local variable
4546 // declaration to the body of the function with the name of the
4547 // function and let it refer to the function itself (closure).
4548 // Not having parsed the function body, the language mode may still change,
4549 // so we reserve a spot and create the actual const assignment later.
4550 DCHECK_EQ(kFunctionNameAssignmentIndex, result->length());
4551 result->Add(NULL, zone());
4554 // For concise constructors, check that they are constructed,
4556 if (i::IsConstructor(kind)) {
4557 AddAssertIsConstruct(result, pos);
4560 ZoneList<Statement*>* body = result;
4561 Scope* inner_scope = scope_;
4562 Block* inner_block = nullptr;
4563 if (!parameters.is_simple) {
4564 inner_scope = NewScope(scope_, BLOCK_SCOPE);
4565 inner_scope->set_is_declaration_scope();
4566 inner_scope->set_start_position(scanner()->location().beg_pos);
4567 inner_block = factory()->NewBlock(NULL, 8, true, RelocInfo::kNoPosition);
4568 inner_block->set_scope(inner_scope);
4569 body = inner_block->statements();
4573 BlockState block_state(&scope_, inner_scope);
4575 // For generators, allocate and yield an iterator on function entry.
4576 if (IsGeneratorFunction(kind)) {
4577 ZoneList<Expression*>* arguments =
4578 new(zone()) ZoneList<Expression*>(0, zone());
4579 CallRuntime* allocation = factory()->NewCallRuntime(
4580 Runtime::kCreateJSGeneratorObject, arguments, pos);
4581 VariableProxy* init_proxy = factory()->NewVariableProxy(
4582 function_state_->generator_object_variable());
4583 Assignment* assignment = factory()->NewAssignment(
4584 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
4585 VariableProxy* get_proxy = factory()->NewVariableProxy(
4586 function_state_->generator_object_variable());
4587 Yield* yield = factory()->NewYield(
4588 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition);
4589 body->Add(factory()->NewExpressionStatement(
4590 yield, RelocInfo::kNoPosition), zone());
4593 ParseStatementList(body, Token::RBRACE, CHECK_OK);
4595 if (IsGeneratorFunction(kind)) {
4596 VariableProxy* get_proxy = factory()->NewVariableProxy(
4597 function_state_->generator_object_variable());
4598 Expression* undefined =
4599 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition);
4600 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal,
4601 RelocInfo::kNoPosition);
4602 body->Add(factory()->NewExpressionStatement(
4603 yield, RelocInfo::kNoPosition), zone());
4606 if (IsSubclassConstructor(kind)) {
4608 factory()->NewReturnStatement(
4609 this->ThisExpression(scope_, factory(), RelocInfo::kNoPosition),
4610 RelocInfo::kNoPosition),
4615 Expect(Token::RBRACE, CHECK_OK);
4616 scope_->set_end_position(scanner()->location().end_pos);
4618 if (!parameters.is_simple) {
4619 DCHECK_NOT_NULL(inner_scope);
4620 DCHECK_EQ(body, inner_block->statements());
4621 scope_->SetLanguageMode(inner_scope->language_mode());
4622 Block* init_block = BuildParameterInitializationBlock(parameters, CHECK_OK);
4623 DCHECK_NOT_NULL(init_block);
4625 inner_scope->set_end_position(scanner()->location().end_pos);
4626 inner_scope = inner_scope->FinalizeBlockScope();
4627 if (inner_scope != nullptr) {
4628 CheckConflictingVarDeclarations(inner_scope, CHECK_OK);
4631 result->Add(init_block, zone());
4632 result->Add(inner_block, zone());
4635 if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
4636 // Now that we know the language mode, we can create the const assignment
4637 // in the previously reserved spot.
4638 // NOTE: We create a proxy and resolve it here so that in the
4639 // future we can change the AST to only refer to VariableProxies
4640 // instead of Variables and Proxies as is the case now.
4641 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY;
4642 bool use_strict_const = is_strict(scope_->language_mode()) ||
4643 (!allow_legacy_const() && allow_harmony_sloppy());
4644 if (use_strict_const) {
4645 fvar_init_op = Token::INIT_CONST;
4647 VariableMode fvar_mode = use_strict_const ? CONST : CONST_LEGACY;
4648 Variable* fvar = new (zone())
4649 Variable(scope_, function_name, fvar_mode, Variable::NORMAL,
4650 kCreatedInitialized, kNotAssigned);
4651 VariableProxy* proxy = factory()->NewVariableProxy(fvar);
4652 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration(
4653 proxy, fvar_mode, scope_, RelocInfo::kNoPosition);
4654 scope_->DeclareFunctionVar(fvar_declaration);
4656 VariableProxy* fproxy = scope_->NewUnresolved(factory(), function_name);
4657 fproxy->BindTo(fvar);
4658 result->Set(kFunctionNameAssignmentIndex,
4659 factory()->NewExpressionStatement(
4660 factory()->NewAssignment(fvar_init_op, fproxy,
4661 factory()->NewThisFunction(pos),
4662 RelocInfo::kNoPosition),
4663 RelocInfo::kNoPosition));
4670 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
4671 SingletonLogger* logger, Scanner::BookmarkScope* bookmark) {
4672 // This function may be called on a background thread too; record only the
4673 // main thread preparse times.
4674 if (pre_parse_timer_ != NULL) {
4675 pre_parse_timer_->Start();
4677 DCHECK_EQ(Token::LBRACE, scanner()->current_token());
4679 if (reusable_preparser_ == NULL) {
4680 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(),
4681 NULL, stack_limit_);
4682 reusable_preparser_->set_allow_lazy(true);
4683 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
4685 SET_ALLOW(harmony_arrow_functions);
4686 SET_ALLOW(harmony_sloppy);
4687 SET_ALLOW(harmony_sloppy_let);
4688 SET_ALLOW(harmony_rest_parameters);
4689 SET_ALLOW(harmony_default_parameters);
4690 SET_ALLOW(harmony_spreadcalls);
4691 SET_ALLOW(harmony_destructuring);
4692 SET_ALLOW(harmony_spread_arrays);
4693 SET_ALLOW(harmony_new_target);
4694 SET_ALLOW(strong_mode);
4697 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
4698 language_mode(), function_state_->kind(), scope_->has_simple_parameters(),
4700 if (pre_parse_timer_ != NULL) {
4701 pre_parse_timer_->Stop();
4707 ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name,
4708 Scanner::Location class_name_location,
4709 bool name_is_strict_reserved, int pos,
4711 // All parts of a ClassDeclaration and ClassExpression are strict code.
4712 if (name_is_strict_reserved) {
4713 ReportMessageAt(class_name_location,
4714 MessageTemplate::kUnexpectedStrictReserved);
4718 if (IsEvalOrArguments(name)) {
4719 ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments);
4723 if (is_strong(language_mode()) && IsUndefined(name)) {
4724 ReportMessageAt(class_name_location, MessageTemplate::kStrongUndefined);
4729 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
4730 BlockState block_state(&scope_, block_scope);
4731 scope_->SetLanguageMode(
4732 static_cast<LanguageMode>(scope_->language_mode() | STRICT));
4733 scope_->SetScopeName(name);
4735 VariableProxy* proxy = NULL;
4737 proxy = NewUnresolved(name, CONST);
4738 const bool is_class_declaration = true;
4739 Declaration* declaration = factory()->NewVariableDeclaration(
4740 proxy, CONST, block_scope, pos, is_class_declaration,
4741 scope_->class_declaration_group_start());
4742 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
4745 Expression* extends = NULL;
4746 if (Check(Token::EXTENDS)) {
4747 block_scope->set_start_position(scanner()->location().end_pos);
4748 ExpressionClassifier classifier;
4749 extends = ParseLeftHandSideExpression(&classifier, CHECK_OK);
4750 ValidateExpression(&classifier, CHECK_OK);
4752 block_scope->set_start_position(scanner()->location().end_pos);
4756 ClassLiteralChecker checker(this);
4757 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone());
4758 FunctionLiteral* constructor = NULL;
4759 bool has_seen_constructor = false;
4761 Expect(Token::LBRACE, CHECK_OK);
4763 const bool has_extends = extends != nullptr;
4764 while (peek() != Token::RBRACE) {
4765 if (Check(Token::SEMICOLON)) continue;
4766 if (fni_ != NULL) fni_->Enter();
4767 const bool in_class = true;
4768 const bool is_static = false;
4769 bool is_computed_name = false; // Classes do not care about computed
4770 // property names here.
4771 ExpressionClassifier classifier;
4772 ObjectLiteral::Property* property = ParsePropertyDefinition(
4773 &checker, in_class, has_extends, is_static, &is_computed_name,
4774 &has_seen_constructor, &classifier, CHECK_OK);
4775 ValidateExpression(&classifier, CHECK_OK);
4777 if (has_seen_constructor && constructor == NULL) {
4778 constructor = GetPropertyValue(property)->AsFunctionLiteral();
4779 DCHECK_NOT_NULL(constructor);
4781 properties->Add(property, zone());
4790 Expect(Token::RBRACE, CHECK_OK);
4791 int end_pos = scanner()->location().end_pos;
4793 if (constructor == NULL) {
4794 constructor = DefaultConstructor(extends != NULL, block_scope, pos, end_pos,
4795 block_scope->language_mode());
4798 block_scope->set_end_position(end_pos);
4801 DCHECK_NOT_NULL(proxy);
4802 proxy->var()->set_initializer_position(end_pos);
4804 // Unnamed classes should not have scopes (the scope will be empty).
4805 DCHECK_EQ(block_scope->num_var_or_const(), 0);
4806 block_scope = nullptr;
4809 return factory()->NewClassLiteral(name, block_scope, proxy, extends,
4810 constructor, properties, pos, end_pos);
4814 Expression* Parser::ParseV8Intrinsic(bool* ok) {
4816 // '%' Identifier Arguments
4818 int pos = peek_position();
4819 Expect(Token::MOD, CHECK_OK);
4820 // Allow "eval" or "arguments" for backward compatibility.
4821 const AstRawString* name = ParseIdentifier(kAllowRestrictedIdentifiers,
4823 Scanner::Location spread_pos;
4824 ExpressionClassifier classifier;
4825 ZoneList<Expression*>* args =
4826 ParseArguments(&spread_pos, &classifier, CHECK_OK);
4827 ValidateExpression(&classifier, CHECK_OK);
4829 DCHECK(!spread_pos.IsValid());
4831 if (extension_ != NULL) {
4832 // The extension structures are only accessible while parsing the
4833 // very first time not when reparsing because of lazy compilation.
4834 scope_->DeclarationScope()->ForceEagerCompilation();
4837 const Runtime::Function* function = Runtime::FunctionForName(name->string());
4839 if (function != NULL) {
4840 // Check for possible name clash.
4841 DCHECK_EQ(Context::kNotFound,
4842 Context::IntrinsicIndexForName(name->string()));
4843 // Check for built-in IS_VAR macro.
4844 if (function->function_id == Runtime::kIS_VAR) {
4845 DCHECK_EQ(Runtime::RUNTIME, function->intrinsic_type);
4846 // %IS_VAR(x) evaluates to x if x is a variable,
4847 // leads to a parse error otherwise. Could be implemented as an
4848 // inline function %_IS_VAR(x) to eliminate this special case.
4849 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
4852 ReportMessage(MessageTemplate::kNotIsvar);
4858 // Check that the expected number of arguments are being passed.
4859 if (function->nargs != -1 && function->nargs != args->length()) {
4860 ReportMessage(MessageTemplate::kIllegalAccess);
4865 return factory()->NewCallRuntime(function, args, pos);
4868 int context_index = Context::IntrinsicIndexForName(name->string());
4870 // Check that the function is defined.
4871 if (context_index == Context::kNotFound) {
4872 ParserTraits::ReportMessage(MessageTemplate::kNotDefined, name);
4877 return factory()->NewCallRuntime(context_index, args, pos);
4881 Literal* Parser::GetLiteralUndefined(int position) {
4882 return factory()->NewUndefinedLiteral(position);
4886 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
4887 Declaration* decl = scope->CheckConflictingVarDeclarations();
4889 // In harmony mode we treat conflicting variable bindinds as early
4890 // errors. See ES5 16 for a definition of early errors.
4891 const AstRawString* name = decl->proxy()->raw_name();
4892 int position = decl->proxy()->position();
4893 Scanner::Location location = position == RelocInfo::kNoPosition
4894 ? Scanner::Location::invalid()
4895 : Scanner::Location(position, position + 1);
4896 ParserTraits::ReportMessageAt(location, MessageTemplate::kVarRedeclaration,
4903 // ----------------------------------------------------------------------------
4906 bool Parser::TargetStackContainsLabel(const AstRawString* label) {
4907 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4908 if (ContainsLabel(t->statement()->labels(), label)) return true;
4914 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
4916 bool anonymous = label == NULL;
4917 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4918 BreakableStatement* stat = t->statement();
4919 if ((anonymous && stat->is_target_for_anonymous()) ||
4920 (!anonymous && ContainsLabel(stat->labels(), label))) {
4928 IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
4930 bool anonymous = label == NULL;
4931 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4932 IterationStatement* stat = t->statement()->AsIterationStatement();
4933 if (stat == NULL) continue;
4935 DCHECK(stat->is_target_for_anonymous());
4936 if (anonymous || ContainsLabel(stat->labels(), label)) {
4944 void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
4945 if (scanner_.source_url()->length() > 0) {
4946 Handle<String> source_url = scanner_.source_url()->Internalize(isolate);
4947 script->set_source_url(*source_url);
4949 if (scanner_.source_mapping_url()->length() > 0) {
4950 Handle<String> source_mapping_url =
4951 scanner_.source_mapping_url()->Internalize(isolate);
4952 script->set_source_mapping_url(*source_mapping_url);
4957 void Parser::Internalize(Isolate* isolate, Handle<Script> script, bool error) {
4958 // Internalize strings.
4959 ast_value_factory()->Internalize(isolate);
4961 // Error processing.
4963 if (stack_overflow()) {
4964 isolate->StackOverflow();
4966 DCHECK(pending_error_handler_.has_pending_error());
4967 pending_error_handler_.ThrowPendingError(isolate, script);
4971 // Move statistics to Isolate.
4972 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
4974 for (int i = 0; i < use_counts_[feature]; ++i) {
4975 isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
4978 isolate->counters()->total_preparse_skipped()->Increment(
4979 total_preparse_skipped_);
4983 // ----------------------------------------------------------------------------
4984 // Regular expressions
4987 RegExpParser::RegExpParser(FlatStringReader* in, Handle<String>* error,
4988 bool multiline, bool unicode, Isolate* isolate,
4990 : isolate_(isolate),
4995 current_(kEndMarker),
4999 multiline_(multiline),
5002 contains_anchor_(false),
5003 is_scanned_for_captures_(false),
5009 uc32 RegExpParser::Next() {
5011 return in()->Get(next_pos_);
5018 void RegExpParser::Advance() {
5019 if (next_pos_ < in()->length()) {
5020 StackLimitCheck check(isolate());
5021 if (check.HasOverflowed()) {
5022 ReportError(CStrVector(Isolate::kStackOverflowMessage));
5023 } else if (zone()->excess_allocation()) {
5024 ReportError(CStrVector("Regular expression too large"));
5026 current_ = in()->Get(next_pos_);
5030 current_ = kEndMarker;
5031 // Advance so that position() points to 1-after-the-last-character. This is
5032 // important so that Reset() to this position works correctly.
5033 next_pos_ = in()->length() + 1;
5039 void RegExpParser::Reset(int pos) {
5041 has_more_ = (pos < in()->length());
5046 void RegExpParser::Advance(int dist) {
5047 next_pos_ += dist - 1;
5052 bool RegExpParser::simple() {
5057 bool RegExpParser::IsSyntaxCharacter(uc32 c) {
5058 return c == '^' || c == '$' || c == '\\' || c == '.' || c == '*' ||
5059 c == '+' || c == '?' || c == '(' || c == ')' || c == '[' || c == ']' ||
5060 c == '{' || c == '}' || c == '|';
5064 RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
5066 *error_ = isolate()->factory()->NewStringFromAscii(message).ToHandleChecked();
5067 // Zip to the end to make sure the no more input is read.
5068 current_ = kEndMarker;
5069 next_pos_ = in()->length();
5076 RegExpTree* RegExpParser::ParsePattern() {
5077 RegExpTree* result = ParseDisjunction(CHECK_FAILED);
5078 DCHECK(!has_more());
5079 // If the result of parsing is a literal string atom, and it has the
5080 // same length as the input, then the atom is identical to the input.
5081 if (result->IsAtom() && result->AsAtom()->length() == in()->length()) {
5090 // Alternative | Disjunction
5098 RegExpTree* RegExpParser::ParseDisjunction() {
5099 // Used to store current state while parsing subexpressions.
5100 RegExpParserState initial_state(NULL, INITIAL, 0, zone());
5101 RegExpParserState* stored_state = &initial_state;
5102 // Cache the builder in a local variable for quick access.
5103 RegExpBuilder* builder = initial_state.builder();
5105 switch (current()) {
5107 if (stored_state->IsSubexpression()) {
5108 // Inside a parenthesized group when hitting end of input.
5109 ReportError(CStrVector("Unterminated group") CHECK_FAILED);
5111 DCHECK_EQ(INITIAL, stored_state->group_type());
5112 // Parsing completed successfully.
5113 return builder->ToRegExp();
5115 if (!stored_state->IsSubexpression()) {
5116 ReportError(CStrVector("Unmatched ')'") CHECK_FAILED);
5118 DCHECK_NE(INITIAL, stored_state->group_type());
5121 // End disjunction parsing and convert builder content to new single
5123 RegExpTree* body = builder->ToRegExp();
5125 int end_capture_index = captures_started();
5127 int capture_index = stored_state->capture_index();
5128 SubexpressionType group_type = stored_state->group_type();
5130 // Restore previous state.
5131 stored_state = stored_state->previous_state();
5132 builder = stored_state->builder();
5134 // Build result of subexpression.
5135 if (group_type == CAPTURE) {
5136 RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index);
5137 captures_->at(capture_index - 1) = capture;
5139 } else if (group_type != GROUPING) {
5140 DCHECK(group_type == POSITIVE_LOOKAHEAD ||
5141 group_type == NEGATIVE_LOOKAHEAD);
5142 bool is_positive = (group_type == POSITIVE_LOOKAHEAD);
5143 body = new(zone()) RegExpLookahead(body,
5145 end_capture_index - capture_index,
5148 builder->AddAtom(body);
5149 // For compatability with JSC and ES3, we allow quantifiers after
5150 // lookaheads, and break in all cases.
5155 builder->NewAlternative();
5161 return ReportError(CStrVector("Nothing to repeat"));
5165 builder->AddAssertion(
5166 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE));
5168 builder->AddAssertion(
5169 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
5170 set_contains_anchor();
5176 RegExpAssertion::AssertionType assertion_type =
5177 multiline_ ? RegExpAssertion::END_OF_LINE :
5178 RegExpAssertion::END_OF_INPUT;
5179 builder->AddAssertion(new(zone()) RegExpAssertion(assertion_type));
5184 // everything except \x0a, \x0d, \u2028 and \u2029
5185 ZoneList<CharacterRange>* ranges =
5186 new(zone()) ZoneList<CharacterRange>(2, zone());
5187 CharacterRange::AddClassEscape('.', ranges, zone());
5188 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
5189 builder->AddAtom(atom);
5193 SubexpressionType subexpr_type = CAPTURE;
5195 if (current() == '?') {
5198 subexpr_type = GROUPING;
5201 subexpr_type = POSITIVE_LOOKAHEAD;
5204 subexpr_type = NEGATIVE_LOOKAHEAD;
5207 ReportError(CStrVector("Invalid group") CHECK_FAILED);
5212 if (captures_ == NULL) {
5213 captures_ = new(zone()) ZoneList<RegExpCapture*>(2, zone());
5215 if (captures_started() >= kMaxCaptures) {
5216 ReportError(CStrVector("Too many captures") CHECK_FAILED);
5218 captures_->Add(NULL, zone());
5220 // Store current state and begin new disjunction parsing.
5221 stored_state = new(zone()) RegExpParserState(stored_state, subexpr_type,
5222 captures_started(), zone());
5223 builder = stored_state->builder();
5227 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED);
5228 builder->AddAtom(atom);
5236 return ReportError(CStrVector("\\ at end of pattern"));
5239 builder->AddAssertion(
5240 new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
5244 builder->AddAssertion(
5245 new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
5248 // CharacterClassEscape
5250 // CharacterClassEscape :: one of
5252 case 'd': case 'D': case 's': case 'S': case 'w': case 'W': {
5255 ZoneList<CharacterRange>* ranges =
5256 new(zone()) ZoneList<CharacterRange>(2, zone());
5257 CharacterRange::AddClassEscape(c, ranges, zone());
5258 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
5259 builder->AddAtom(atom);
5262 case '1': case '2': case '3': case '4': case '5': case '6':
5263 case '7': case '8': case '9': {
5265 if (ParseBackReferenceIndex(&index)) {
5266 RegExpCapture* capture = NULL;
5267 if (captures_ != NULL && index <= captures_->length()) {
5268 capture = captures_->at(index - 1);
5270 if (capture == NULL) {
5271 builder->AddEmpty();
5274 RegExpTree* atom = new(zone()) RegExpBackReference(capture);
5275 builder->AddAtom(atom);
5278 uc32 first_digit = Next();
5279 if (first_digit == '8' || first_digit == '9') {
5280 // If the 'u' flag is present, only syntax characters can be escaped,
5281 // no other identity escapes are allowed. If the 'u' flag is not
5282 // present, all identity escapes are allowed.
5283 if (!FLAG_harmony_unicode_regexps || !unicode_) {
5284 builder->AddCharacter(first_digit);
5287 return ReportError(CStrVector("Invalid escape"));
5295 uc32 octal = ParseOctalLiteral();
5296 builder->AddCharacter(octal);
5299 // ControlEscape :: one of
5303 builder->AddCharacter('\f');
5307 builder->AddCharacter('\n');
5311 builder->AddCharacter('\r');
5315 builder->AddCharacter('\t');
5319 builder->AddCharacter('\v');
5323 uc32 controlLetter = Next();
5324 // Special case if it is an ASCII letter.
5325 // Convert lower case letters to uppercase.
5326 uc32 letter = controlLetter & ~('a' ^ 'A');
5327 if (letter < 'A' || 'Z' < letter) {
5328 // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
5329 // This is outside the specification. We match JSC in
5330 // reading the backslash as a literal character instead
5331 // of as starting an escape.
5332 builder->AddCharacter('\\');
5335 builder->AddCharacter(controlLetter & 0x1f);
5342 if (ParseHexEscape(2, &value)) {
5343 builder->AddCharacter(value);
5344 } else if (!FLAG_harmony_unicode_regexps || !unicode_) {
5345 builder->AddCharacter('x');
5347 // If the 'u' flag is present, invalid escapes are not treated as
5348 // identity escapes.
5349 return ReportError(CStrVector("Invalid escape"));
5356 if (ParseUnicodeEscape(&value)) {
5357 builder->AddCharacter(value);
5358 } else if (!FLAG_harmony_unicode_regexps || !unicode_) {
5359 builder->AddCharacter('u');
5361 // If the 'u' flag is present, invalid escapes are not treated as
5362 // identity escapes.
5363 return ReportError(CStrVector("Invalid unicode escape"));
5369 // If the 'u' flag is present, only syntax characters can be escaped, no
5370 // other identity escapes are allowed. If the 'u' flag is not present,
5371 // all identity escapes are allowed.
5372 if (!FLAG_harmony_unicode_regexps || !unicode_ ||
5373 IsSyntaxCharacter(current())) {
5374 builder->AddCharacter(current());
5377 return ReportError(CStrVector("Invalid escape"));
5384 if (ParseIntervalQuantifier(&dummy, &dummy)) {
5385 ReportError(CStrVector("Nothing to repeat") CHECK_FAILED);
5390 builder->AddCharacter(current());
5393 } // end switch(current())
5397 switch (current()) {
5398 // QuantifierPrefix ::
5405 max = RegExpTree::kInfinity;
5410 max = RegExpTree::kInfinity;
5419 if (ParseIntervalQuantifier(&min, &max)) {
5421 ReportError(CStrVector("numbers out of order in {} quantifier.")
5431 RegExpQuantifier::QuantifierType quantifier_type = RegExpQuantifier::GREEDY;
5432 if (current() == '?') {
5433 quantifier_type = RegExpQuantifier::NON_GREEDY;
5435 } else if (FLAG_regexp_possessive_quantifier && current() == '+') {
5436 // FLAG_regexp_possessive_quantifier is a debug-only flag.
5437 quantifier_type = RegExpQuantifier::POSSESSIVE;
5440 builder->AddQuantifierToAtom(min, max, quantifier_type);
5446 // Currently only used in an DCHECK.
5447 static bool IsSpecialClassEscape(uc32 c) {
5460 // In order to know whether an escape is a backreference or not we have to scan
5461 // the entire regexp and find the number of capturing parentheses. However we
5462 // don't want to scan the regexp twice unless it is necessary. This mini-parser
5463 // is called when needed. It can see the difference between capturing and
5464 // noncapturing parentheses and can skip character classes and backslash-escaped
5466 void RegExpParser::ScanForCaptures() {
5467 // Start with captures started previous to current position
5468 int capture_count = captures_started();
5469 // Add count of captures after this position.
5471 while ((n = current()) != kEndMarker) {
5479 while ((c = current()) != kEndMarker) {
5484 if (c == ']') break;
5490 if (current() != '?') capture_count++;
5494 capture_count_ = capture_count;
5495 is_scanned_for_captures_ = true;
5499 bool RegExpParser::ParseBackReferenceIndex(int* index_out) {
5500 DCHECK_EQ('\\', current());
5501 DCHECK('1' <= Next() && Next() <= '9');
5502 // Try to parse a decimal literal that is no greater than the total number
5503 // of left capturing parentheses in the input.
5504 int start = position();
5505 int value = Next() - '0';
5509 if (IsDecimalDigit(c)) {
5510 value = 10 * value + (c - '0');
5511 if (value > kMaxCaptures) {
5520 if (value > captures_started()) {
5521 if (!is_scanned_for_captures_) {
5522 int saved_position = position();
5524 Reset(saved_position);
5526 if (value > capture_count_) {
5536 // QuantifierPrefix ::
5537 // { DecimalDigits }
5538 // { DecimalDigits , }
5539 // { DecimalDigits , DecimalDigits }
5541 // Returns true if parsing succeeds, and set the min_out and max_out
5542 // values. Values are truncated to RegExpTree::kInfinity if they overflow.
5543 bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
5544 DCHECK_EQ(current(), '{');
5545 int start = position();
5548 if (!IsDecimalDigit(current())) {
5552 while (IsDecimalDigit(current())) {
5553 int next = current() - '0';
5554 if (min > (RegExpTree::kInfinity - next) / 10) {
5555 // Overflow. Skip past remaining decimal digits and return -1.
5558 } while (IsDecimalDigit(current()));
5559 min = RegExpTree::kInfinity;
5562 min = 10 * min + next;
5566 if (current() == '}') {
5569 } else if (current() == ',') {
5571 if (current() == '}') {
5572 max = RegExpTree::kInfinity;
5575 while (IsDecimalDigit(current())) {
5576 int next = current() - '0';
5577 if (max > (RegExpTree::kInfinity - next) / 10) {
5580 } while (IsDecimalDigit(current()));
5581 max = RegExpTree::kInfinity;
5584 max = 10 * max + next;
5587 if (current() != '}') {
5603 uc32 RegExpParser::ParseOctalLiteral() {
5604 DCHECK(('0' <= current() && current() <= '7') || current() == kEndMarker);
5605 // For compatibility with some other browsers (not all), we parse
5606 // up to three octal digits with a value below 256.
5607 uc32 value = current() - '0';
5609 if ('0' <= current() && current() <= '7') {
5610 value = value * 8 + current() - '0';
5612 if (value < 32 && '0' <= current() && current() <= '7') {
5613 value = value * 8 + current() - '0';
5621 bool RegExpParser::ParseHexEscape(int length, uc32* value) {
5622 int start = position();
5624 for (int i = 0; i < length; ++i) {
5626 int d = HexValue(c);
5639 bool RegExpParser::ParseUnicodeEscape(uc32* value) {
5640 // Accept both \uxxxx and \u{xxxxxx} (if harmony unicode escapes are
5641 // allowed). In the latter case, the number of hex digits between { } is
5642 // arbitrary. \ and u have already been read.
5643 if (current() == '{' && FLAG_harmony_unicode_regexps && unicode_) {
5644 int start = position();
5646 if (ParseUnlimitedLengthHexNumber(0x10ffff, value)) {
5647 if (current() == '}') {
5655 // \u but no {, or \u{...} escapes not allowed.
5656 return ParseHexEscape(4, value);
5660 bool RegExpParser::ParseUnlimitedLengthHexNumber(int max_value, uc32* value) {
5662 int d = HexValue(current());
5668 if (x > max_value) {
5672 d = HexValue(current());
5679 uc32 RegExpParser::ParseClassCharacterEscape() {
5680 DCHECK(current() == '\\');
5681 DCHECK(has_next() && !IsSpecialClassEscape(Next()));
5683 switch (current()) {
5687 // ControlEscape :: one of
5705 uc32 controlLetter = Next();
5706 uc32 letter = controlLetter & ~('A' ^ 'a');
5707 // For compatibility with JSC, inside a character class
5708 // we also accept digits and underscore as control characters.
5709 if ((controlLetter >= '0' && controlLetter <= '9') ||
5710 controlLetter == '_' ||
5711 (letter >= 'A' && letter <= 'Z')) {
5713 // Control letters mapped to ASCII control characters in the range
5715 return controlLetter & 0x1f;
5717 // We match JSC in reading the backslash as a literal
5718 // character instead of as starting an escape.
5721 case '0': case '1': case '2': case '3': case '4': case '5':
5723 // For compatibility, we interpret a decimal escape that isn't
5724 // a back reference (and therefore either \0 or not valid according
5725 // to the specification) as a 1..3 digit octal character code.
5726 return ParseOctalLiteral();
5730 if (ParseHexEscape(2, &value)) {
5733 if (!FLAG_harmony_unicode_regexps || !unicode_) {
5734 // If \x is not followed by a two-digit hexadecimal, treat it
5735 // as an identity escape.
5738 // If the 'u' flag is present, invalid escapes are not treated as
5739 // identity escapes.
5740 ReportError(CStrVector("Invalid escape"));
5746 if (ParseUnicodeEscape(&value)) {
5749 if (!FLAG_harmony_unicode_regexps || !unicode_) {
5752 // If the 'u' flag is present, invalid escapes are not treated as
5753 // identity escapes.
5754 ReportError(CStrVector("Invalid unicode escape"));
5758 uc32 result = current();
5759 // If the 'u' flag is present, only syntax characters can be escaped, no
5760 // other identity escapes are allowed. If the 'u' flag is not present, all
5761 // identity escapes are allowed.
5762 if (!FLAG_harmony_unicode_regexps || !unicode_ ||
5763 IsSyntaxCharacter(result)) {
5767 ReportError(CStrVector("Invalid escape"));
5775 CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) {
5776 DCHECK_EQ(0, *char_class);
5777 uc32 first = current();
5778 if (first == '\\') {
5780 case 'w': case 'W': case 'd': case 'D': case 's': case 'S': {
5781 *char_class = Next();
5783 return CharacterRange::Singleton(0); // Return dummy value.
5786 return ReportError(CStrVector("\\ at end of pattern"));
5788 uc32 c = ParseClassCharacterEscape(CHECK_FAILED);
5789 return CharacterRange::Singleton(c);
5793 return CharacterRange::Singleton(first);
5798 static const uc16 kNoCharClass = 0;
5800 // Adds range or pre-defined character class to character ranges.
5801 // If char_class is not kInvalidClass, it's interpreted as a class
5802 // escape (i.e., 's' means whitespace, from '\s').
5803 static inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges,
5805 CharacterRange range,
5807 if (char_class != kNoCharClass) {
5808 CharacterRange::AddClassEscape(char_class, ranges, zone);
5810 ranges->Add(range, zone);
5815 RegExpTree* RegExpParser::ParseCharacterClass() {
5816 static const char* kUnterminated = "Unterminated character class";
5817 static const char* kRangeOutOfOrder = "Range out of order in character class";
5819 DCHECK_EQ(current(), '[');
5821 bool is_negated = false;
5822 if (current() == '^') {
5826 ZoneList<CharacterRange>* ranges =
5827 new(zone()) ZoneList<CharacterRange>(2, zone());
5828 while (has_more() && current() != ']') {
5829 uc16 char_class = kNoCharClass;
5830 CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED);
5831 if (current() == '-') {
5833 if (current() == kEndMarker) {
5834 // If we reach the end we break out of the loop and let the
5835 // following code report an error.
5837 } else if (current() == ']') {
5838 AddRangeOrEscape(ranges, char_class, first, zone());
5839 ranges->Add(CharacterRange::Singleton('-'), zone());
5842 uc16 char_class_2 = kNoCharClass;
5843 CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED);
5844 if (char_class != kNoCharClass || char_class_2 != kNoCharClass) {
5845 // Either end is an escaped character class. Treat the '-' verbatim.
5846 AddRangeOrEscape(ranges, char_class, first, zone());
5847 ranges->Add(CharacterRange::Singleton('-'), zone());
5848 AddRangeOrEscape(ranges, char_class_2, next, zone());
5851 if (first.from() > next.to()) {
5852 return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED);
5854 ranges->Add(CharacterRange::Range(first.from(), next.to()), zone());
5856 AddRangeOrEscape(ranges, char_class, first, zone());
5860 return ReportError(CStrVector(kUnterminated) CHECK_FAILED);
5863 if (ranges->length() == 0) {
5864 ranges->Add(CharacterRange::Everything(), zone());
5865 is_negated = !is_negated;
5867 return new(zone()) RegExpCharacterClass(ranges, is_negated);
5871 // ----------------------------------------------------------------------------
5872 // The Parser interface.
5874 bool RegExpParser::ParseRegExp(Isolate* isolate, Zone* zone,
5875 FlatStringReader* input, bool multiline,
5876 bool unicode, RegExpCompileData* result) {
5877 DCHECK(result != NULL);
5878 RegExpParser parser(input, &result->error, multiline, unicode, isolate, zone);
5879 RegExpTree* tree = parser.ParsePattern();
5880 if (parser.failed()) {
5881 DCHECK(tree == NULL);
5882 DCHECK(!result->error.is_null());
5884 DCHECK(tree != NULL);
5885 DCHECK(result->error.is_null());
5886 result->tree = tree;
5887 int capture_count = parser.captures_started();
5888 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
5889 result->contains_anchor = parser.contains_anchor();
5890 result->capture_count = capture_count;
5892 return !parser.failed();
5896 bool Parser::ParseStatic(ParseInfo* info) {
5897 Parser parser(info);
5898 if (parser.Parse(info)) {
5899 info->set_language_mode(info->literal()->language_mode());
5906 bool Parser::Parse(ParseInfo* info) {
5907 DCHECK(info->literal() == NULL);
5908 FunctionLiteral* result = NULL;
5909 // Ok to use Isolate here; this function is only called in the main thread.
5910 DCHECK(parsing_on_main_thread_);
5911 Isolate* isolate = info->isolate();
5912 pre_parse_timer_ = isolate->counters()->pre_parse();
5913 if (FLAG_trace_parse || allow_natives() || extension_ != NULL) {
5914 // If intrinsics are allowed, the Parser cannot operate independent of the
5915 // V8 heap because of Runtime. Tell the string table to internalize strings
5916 // and values right after they're created.
5917 ast_value_factory()->Internalize(isolate);
5920 if (info->is_lazy()) {
5921 DCHECK(!info->is_eval());
5922 if (info->shared_info()->is_function()) {
5923 result = ParseLazy(isolate, info);
5925 result = ParseProgram(isolate, info);
5928 SetCachedData(info);
5929 result = ParseProgram(isolate, info);
5931 info->set_literal(result);
5933 Internalize(isolate, info->script(), result == NULL);
5934 DCHECK(ast_value_factory()->IsInternalized());
5935 return (result != NULL);
5939 void Parser::ParseOnBackground(ParseInfo* info) {
5940 parsing_on_main_thread_ = false;
5942 DCHECK(info->literal() == NULL);
5943 FunctionLiteral* result = NULL;
5944 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
5946 CompleteParserRecorder recorder;
5947 if (produce_cached_parse_data()) log_ = &recorder;
5949 DCHECK(info->source_stream() != NULL);
5950 ExternalStreamingStream stream(info->source_stream(),
5951 info->source_stream_encoding());
5952 scanner_.Initialize(&stream);
5953 DCHECK(info->context().is_null() || info->context()->IsNativeContext());
5955 // When streaming, we don't know the length of the source until we have parsed
5956 // it. The raw data can be UTF-8, so we wouldn't know the source length until
5957 // we have decoded it anyway even if we knew the raw data length (which we
5958 // don't). We work around this by storing all the scopes which need their end
5959 // position set at the end of the script (the top scope and possible eval
5960 // scopes) and set their end position after we know the script length.
5961 result = DoParseProgram(info);
5963 info->set_literal(result);
5965 // We cannot internalize on a background thread; a foreground task will take
5966 // care of calling Parser::Internalize just before compilation.
5968 if (produce_cached_parse_data()) {
5969 if (result != NULL) *info->cached_data() = recorder.GetScriptData();
5975 ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
5976 return new (zone()) ParserTraits::TemplateLiteral(zone(), pos);
5980 void Parser::AddTemplateSpan(TemplateLiteralState* state, bool tail) {
5981 int pos = scanner()->location().beg_pos;
5982 int end = scanner()->location().end_pos - (tail ? 1 : 2);
5983 const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory());
5984 const AstRawString* trv = scanner()->CurrentRawSymbol(ast_value_factory());
5985 Literal* cooked = factory()->NewStringLiteral(tv, pos);
5986 Literal* raw = factory()->NewStringLiteral(trv, pos);
5987 (*state)->AddTemplateSpan(cooked, raw, end, zone());
5991 void Parser::AddTemplateExpression(TemplateLiteralState* state,
5992 Expression* expression) {
5993 (*state)->AddExpression(expression, zone());
5997 Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
5999 TemplateLiteral* lit = *state;
6000 int pos = lit->position();
6001 const ZoneList<Expression*>* cooked_strings = lit->cooked();
6002 const ZoneList<Expression*>* raw_strings = lit->raw();
6003 const ZoneList<Expression*>* expressions = lit->expressions();
6004 DCHECK_EQ(cooked_strings->length(), raw_strings->length());
6005 DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
6008 // Build tree of BinaryOps to simplify code-generation
6009 Expression* expr = cooked_strings->at(0);
6011 while (i < expressions->length()) {
6012 Expression* sub = expressions->at(i++);
6013 Expression* cooked_str = cooked_strings->at(i);
6015 // Let middle be ToString(sub).
6016 ZoneList<Expression*>* args =
6017 new (zone()) ZoneList<Expression*>(1, zone());
6018 args->Add(sub, zone());
6019 Expression* middle = factory()->NewCallRuntime(
6020 Context::TO_STRING_FUN_INDEX, args, sub->position());
6022 expr = factory()->NewBinaryOperation(
6023 Token::ADD, factory()->NewBinaryOperation(
6024 Token::ADD, expr, middle, expr->position()),
6025 cooked_str, sub->position());
6029 uint32_t hash = ComputeTemplateLiteralHash(lit);
6031 int cooked_idx = function_state_->NextMaterializedLiteralIndex();
6032 int raw_idx = function_state_->NextMaterializedLiteralIndex();
6034 // $getTemplateCallSite
6035 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone());
6036 args->Add(factory()->NewArrayLiteral(
6037 const_cast<ZoneList<Expression*>*>(cooked_strings),
6038 cooked_idx, is_strong(language_mode()), pos),
6041 factory()->NewArrayLiteral(
6042 const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx,
6043 is_strong(language_mode()), pos),
6046 // Ensure hash is suitable as a Smi value
6047 Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash)));
6048 args->Add(factory()->NewSmiLiteral(hash_obj->value(), pos), zone());
6050 this->CheckPossibleEvalCall(tag, scope_);
6051 Expression* call_site = factory()->NewCallRuntime(
6052 Context::GET_TEMPLATE_CALL_SITE_INDEX, args, start);
6055 ZoneList<Expression*>* call_args =
6056 new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone());
6057 call_args->Add(call_site, zone());
6058 call_args->AddAll(*expressions, zone());
6059 return factory()->NewCall(tag, call_args, pos);
6064 uint32_t Parser::ComputeTemplateLiteralHash(const TemplateLiteral* lit) {
6065 const ZoneList<Expression*>* raw_strings = lit->raw();
6066 int total = raw_strings->length();
6069 uint32_t running_hash = 0;
6071 for (int index = 0; index < total; ++index) {
6073 running_hash = StringHasher::ComputeRunningHashOneByte(
6074 running_hash, "${}", 3);
6077 const AstRawString* raw_string =
6078 raw_strings->at(index)->AsLiteral()->raw_value()->AsString();
6079 if (raw_string->is_one_byte()) {
6080 const char* data = reinterpret_cast<const char*>(raw_string->raw_data());
6081 running_hash = StringHasher::ComputeRunningHashOneByte(
6082 running_hash, data, raw_string->length());
6084 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
6085 running_hash = StringHasher::ComputeRunningHash(running_hash, data,
6086 raw_string->length());
6090 return running_hash;
6094 ZoneList<v8::internal::Expression*>* Parser::PrepareSpreadArguments(
6095 ZoneList<v8::internal::Expression*>* list) {
6096 ZoneList<v8::internal::Expression*>* args =
6097 new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
6098 if (list->length() == 1) {
6099 // Spread-call with single spread argument produces an InternalArray
6100 // containing the values from the array.
6102 // Function is called or constructed with the produced array of arguments
6104 // EG: Apply(Func, Spread(spread0))
6105 ZoneList<Expression*>* spread_list =
6106 new (zone()) ZoneList<Expression*>(0, zone());
6107 spread_list->Add(list->at(0)->AsSpread()->expression(), zone());
6108 args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX,
6109 spread_list, RelocInfo::kNoPosition),
6113 // Spread-call with multiple arguments produces array literals for each
6114 // sequences of unspread arguments, and converts each spread iterable to
6115 // an Internal array. Finally, all of these produced arrays are flattened
6116 // into a single InternalArray, containing the arguments for the call.
6118 // EG: Apply(Func, Flatten([unspread0, unspread1], Spread(spread0),
6119 // Spread(spread1), [unspread2, unspread3]))
6121 int n = list->length();
6123 if (!list->at(i)->IsSpread()) {
6124 ZoneList<v8::internal::Expression*>* unspread =
6125 new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
6127 // Push array of unspread parameters
6128 while (i < n && !list->at(i)->IsSpread()) {
6129 unspread->Add(list->at(i++), zone());
6131 int literal_index = function_state_->NextMaterializedLiteralIndex();
6132 args->Add(factory()->NewArrayLiteral(unspread, literal_index,
6133 is_strong(language_mode()),
6134 RelocInfo::kNoPosition),
6140 // Push eagerly spread argument
6141 ZoneList<v8::internal::Expression*>* spread_list =
6142 new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
6143 spread_list->Add(list->at(i++)->AsSpread()->expression(), zone());
6144 args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX,
6145 spread_list, RelocInfo::kNoPosition),
6149 list = new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
6150 list->Add(factory()->NewCallRuntime(Context::SPREAD_ARGUMENTS_INDEX, args,
6151 RelocInfo::kNoPosition),
6159 Expression* Parser::SpreadCall(Expression* function,
6160 ZoneList<v8::internal::Expression*>* args,
6162 if (function->IsSuperCallReference()) {
6164 // %reflect_construct(%GetPrototype(<this-function>), args, new.target))
6165 ZoneList<Expression*>* tmp = new (zone()) ZoneList<Expression*>(1, zone());
6166 tmp->Add(function->AsSuperCallReference()->this_function_var(), zone());
6167 Expression* get_prototype =
6168 factory()->NewCallRuntime(Runtime::kGetPrototype, tmp, pos);
6169 args->InsertAt(0, get_prototype, zone());
6170 args->Add(function->AsSuperCallReference()->new_target_var(), zone());
6171 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args,
6174 if (function->IsProperty()) {
6176 if (function->AsProperty()->IsSuperAccess()) {
6178 ThisExpression(scope_, factory(), RelocInfo::kNoPosition);
6179 args->InsertAt(0, function, zone());
6180 args->InsertAt(1, home, zone());
6183 scope_->NewTemporary(ast_value_factory()->empty_string());
6184 VariableProxy* obj = factory()->NewVariableProxy(temp);
6185 Assignment* assign_obj = factory()->NewAssignment(
6186 Token::ASSIGN, obj, function->AsProperty()->obj(),
6187 RelocInfo::kNoPosition);
6188 function = factory()->NewProperty(
6189 assign_obj, function->AsProperty()->key(), RelocInfo::kNoPosition);
6190 args->InsertAt(0, function, zone());
6191 obj = factory()->NewVariableProxy(temp);
6192 args->InsertAt(1, obj, zone());
6196 args->InsertAt(0, function, zone());
6197 args->InsertAt(1, factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
6200 return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos);
6205 Expression* Parser::SpreadCallNew(Expression* function,
6206 ZoneList<v8::internal::Expression*>* args,
6208 args->InsertAt(0, function, zone());
6210 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
6212 } // namespace internal