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.
9 #include "src/bailout-reason.h"
10 #include "src/base/platform/platform.h"
11 #include "src/bootstrapper.h"
12 #include "src/char-predicates-inl.h"
13 #include "src/codegen.h"
14 #include "src/compiler.h"
15 #include "src/messages.h"
16 #include "src/parser.h"
17 #include "src/preparser.h"
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 RegExpBuilder::RegExpBuilder(Zone* zone)
28 pending_empty_(false),
33 , last_added_(ADD_NONE)
38 void RegExpBuilder::FlushCharacters() {
39 pending_empty_ = false;
40 if (characters_ != NULL) {
41 RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector());
43 text_.Add(atom, zone());
49 void RegExpBuilder::FlushText() {
51 int num_text = text_.length();
54 } else if (num_text == 1) {
55 terms_.Add(text_.last(), zone());
57 RegExpText* text = new(zone()) RegExpText(zone());
58 for (int i = 0; i < num_text; i++)
59 text_.Get(i)->AppendToText(text, zone());
60 terms_.Add(text, zone());
66 void RegExpBuilder::AddCharacter(uc16 c) {
67 pending_empty_ = false;
68 if (characters_ == NULL) {
69 characters_ = new(zone()) ZoneList<uc16>(4, zone());
71 characters_->Add(c, zone());
76 void RegExpBuilder::AddEmpty() {
77 pending_empty_ = true;
81 void RegExpBuilder::AddAtom(RegExpTree* term) {
82 if (term->IsEmpty()) {
86 if (term->IsTextElement()) {
88 text_.Add(term, zone());
91 terms_.Add(term, zone());
97 void RegExpBuilder::AddAssertion(RegExpTree* assert) {
99 terms_.Add(assert, zone());
104 void RegExpBuilder::NewAlternative() {
109 void RegExpBuilder::FlushTerms() {
111 int num_terms = terms_.length();
112 RegExpTree* alternative;
113 if (num_terms == 0) {
114 alternative = new (zone()) RegExpEmpty();
115 } else if (num_terms == 1) {
116 alternative = terms_.last();
118 alternative = new(zone()) RegExpAlternative(terms_.GetList(zone()));
120 alternatives_.Add(alternative, zone());
126 RegExpTree* RegExpBuilder::ToRegExp() {
128 int num_alternatives = alternatives_.length();
129 if (num_alternatives == 0) return new (zone()) RegExpEmpty();
130 if (num_alternatives == 1) return alternatives_.last();
131 return new(zone()) RegExpDisjunction(alternatives_.GetList(zone()));
135 void RegExpBuilder::AddQuantifierToAtom(
136 int min, int max, RegExpQuantifier::QuantifierType quantifier_type) {
137 if (pending_empty_) {
138 pending_empty_ = false;
142 if (characters_ != NULL) {
143 DCHECK(last_added_ == ADD_CHAR);
144 // Last atom was character.
145 Vector<const uc16> char_vector = characters_->ToConstVector();
146 int num_chars = char_vector.length();
148 Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1);
149 text_.Add(new(zone()) RegExpAtom(prefix), zone());
150 char_vector = char_vector.SubVector(num_chars - 1, num_chars);
153 atom = new(zone()) RegExpAtom(char_vector);
155 } else if (text_.length() > 0) {
156 DCHECK(last_added_ == ADD_ATOM);
157 atom = text_.RemoveLast();
159 } else if (terms_.length() > 0) {
160 DCHECK(last_added_ == ADD_ATOM);
161 atom = terms_.RemoveLast();
162 if (atom->max_match() == 0) {
163 // Guaranteed to only match an empty string.
168 terms_.Add(atom, zone());
172 // Only call immediately after adding an atom or character!
177 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone());
182 FunctionEntry ParseData::GetFunctionEntry(int start) {
183 // The current pre-data entry must be a FunctionEntry with the given
185 if ((function_index_ + FunctionEntry::kSize <= Length()) &&
186 (static_cast<int>(Data()[function_index_]) == start)) {
187 int index = function_index_;
188 function_index_ += FunctionEntry::kSize;
189 Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize);
190 return FunctionEntry(subvector);
192 return FunctionEntry();
196 int ParseData::FunctionCount() {
197 int functions_size = FunctionsSize();
198 if (functions_size < 0) return 0;
199 if (functions_size % FunctionEntry::kSize != 0) return 0;
200 return functions_size / FunctionEntry::kSize;
204 bool ParseData::IsSane() {
205 if (!IsAligned(script_data_->length(), sizeof(unsigned))) return false;
206 // Check that the header data is valid and doesn't specify
207 // point to positions outside the store.
208 int data_length = Length();
209 if (data_length < PreparseDataConstants::kHeaderSize) return false;
210 if (Magic() != PreparseDataConstants::kMagicNumber) return false;
211 if (Version() != PreparseDataConstants::kCurrentVersion) return false;
212 if (HasError()) return false;
213 // Check that the space allocated for function entries is sane.
214 int functions_size = FunctionsSize();
215 if (functions_size < 0) return false;
216 if (functions_size % FunctionEntry::kSize != 0) return false;
217 // Check that the total size has room for header and function entries.
219 PreparseDataConstants::kHeaderSize + functions_size;
220 if (data_length < minimum_size) return false;
225 void ParseData::Initialize() {
226 // Prepares state for use.
227 int data_length = Length();
228 if (data_length >= PreparseDataConstants::kHeaderSize) {
229 function_index_ = PreparseDataConstants::kHeaderSize;
234 bool ParseData::HasError() {
235 return Data()[PreparseDataConstants::kHasErrorOffset];
239 unsigned ParseData::Magic() {
240 return Data()[PreparseDataConstants::kMagicOffset];
244 unsigned ParseData::Version() {
245 return Data()[PreparseDataConstants::kVersionOffset];
249 int ParseData::FunctionsSize() {
250 return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]);
254 void Parser::SetCachedData(CompilationInfo* info) {
255 if (compile_options_ == ScriptCompiler::kNoCompileOptions) {
256 cached_parse_data_ = NULL;
258 DCHECK(info->cached_data() != NULL);
259 if (compile_options_ == ScriptCompiler::kConsumeParserCache) {
260 cached_parse_data_ = ParseData::FromCachedData(*info->cached_data());
266 FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope,
267 int pos, int end_pos) {
268 int materialized_literal_count = -1;
269 int expected_property_count = -1;
270 int handler_count = 0;
271 int parameter_count = 0;
272 const AstRawString* name = ast_value_factory()->empty_string();
275 FunctionKind kind = call_super ? FunctionKind::kDefaultSubclassConstructor
276 : FunctionKind::kDefaultBaseConstructor;
277 Scope* function_scope = NewScope(scope, FUNCTION_SCOPE, kind);
278 function_scope->SetLanguageMode(
279 static_cast<LanguageMode>(scope->language_mode() | STRICT_BIT));
280 // Set start and end position to the same value
281 function_scope->set_start_position(pos);
282 function_scope->set_end_position(pos);
283 ZoneList<Statement*>* body = NULL;
286 AstNodeFactory function_factory(ast_value_factory());
287 FunctionState function_state(&function_state_, &scope_, function_scope,
288 kind, &function_factory);
290 body = new (zone()) ZoneList<Statement*>(call_super ? 2 : 1, zone());
291 AddAssertIsConstruct(body, pos);
293 ZoneList<Expression*>* args =
294 new (zone()) ZoneList<Expression*>(0, zone());
295 CallRuntime* call = factory()->NewCallRuntime(
296 ast_value_factory()->empty_string(),
297 Runtime::FunctionForId(Runtime::kInlineDefaultConstructorCallSuper),
299 body->Add(factory()->NewReturnStatement(call, pos), zone());
302 materialized_literal_count = function_state.materialized_literal_count();
303 expected_property_count = function_state.expected_property_count();
304 handler_count = function_state.handler_count();
307 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
308 name, ast_value_factory(), function_scope, body,
309 materialized_literal_count, expected_property_count, handler_count,
310 parameter_count, FunctionLiteral::kNoDuplicateParameters,
311 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
312 FunctionLiteral::kNotParenthesized, kind, pos);
314 return function_literal;
318 // ----------------------------------------------------------------------------
319 // Target is a support class to facilitate manipulation of the
320 // Parser's target_stack_ (the stack of potential 'break' and
321 // 'continue' statement targets). Upon construction, a new target is
322 // added; it is removed upon destruction.
324 class Target BASE_EMBEDDED {
326 Target(Target** variable, BreakableStatement* statement)
327 : variable_(variable), statement_(statement), previous_(*variable) {
332 *variable_ = previous_;
335 Target* previous() { return previous_; }
336 BreakableStatement* statement() { return statement_; }
340 BreakableStatement* statement_;
345 class TargetScope BASE_EMBEDDED {
347 explicit TargetScope(Target** variable)
348 : variable_(variable), previous_(*variable) {
353 *variable_ = previous_;
362 // ----------------------------------------------------------------------------
363 // The CHECK_OK macro is a convenient macro to enforce error
364 // handling for functions that may fail (by returning !*ok).
366 // CAUTION: This macro appends extra statements after a call,
367 // thus it must never be used where only a single statement
368 // is correct (e.g. an if statement branch w/o braces)!
370 #define CHECK_OK ok); \
371 if (!*ok) return NULL; \
373 #define DUMMY ) // to make indentation work
376 #define CHECK_FAILED /**/); \
377 if (failed_) return NULL; \
379 #define DUMMY ) // to make indentation work
382 // ----------------------------------------------------------------------------
383 // Implementation of Parser
385 bool ParserTraits::IsEval(const AstRawString* identifier) const {
386 return identifier == parser_->ast_value_factory()->eval_string();
390 bool ParserTraits::IsArguments(const AstRawString* identifier) const {
391 return identifier == parser_->ast_value_factory()->arguments_string();
395 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const {
396 return IsEval(identifier) || IsArguments(identifier);
400 bool ParserTraits::IsPrototype(const AstRawString* identifier) const {
401 return identifier == parser_->ast_value_factory()->prototype_string();
405 bool ParserTraits::IsConstructor(const AstRawString* identifier) const {
406 return identifier == parser_->ast_value_factory()->constructor_string();
410 bool ParserTraits::IsThisProperty(Expression* expression) {
411 DCHECK(expression != NULL);
412 Property* property = expression->AsProperty();
413 return property != NULL && property->obj()->IsVariableProxy() &&
414 property->obj()->AsVariableProxy()->is_this();
418 bool ParserTraits::IsIdentifier(Expression* expression) {
419 VariableProxy* operand = expression->AsVariableProxy();
420 return operand != NULL && !operand->is_this();
424 void ParserTraits::PushPropertyName(FuncNameInferrer* fni,
425 Expression* expression) {
426 if (expression->IsPropertyName()) {
427 fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
429 fni->PushLiteralName(
430 parser_->ast_value_factory()->anonymous_function_string());
435 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
437 DCHECK(left != NULL);
438 if (left->IsProperty() && right->IsFunctionLiteral()) {
439 right->AsFunctionLiteral()->set_pretenure();
444 void ParserTraits::CheckPossibleEvalCall(Expression* expression,
446 VariableProxy* callee = expression->AsVariableProxy();
447 if (callee != NULL &&
448 callee->raw_name() == parser_->ast_value_factory()->eval_string()) {
449 scope->DeclarationScope()->RecordEvalCall();
454 Expression* ParserTraits::MarkExpressionAsAssigned(Expression* expression) {
455 VariableProxy* proxy =
456 expression != NULL ? expression->AsVariableProxy() : NULL;
457 if (proxy != NULL) proxy->set_is_assigned();
462 bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
463 Expression** x, Expression* y, Token::Value op, int pos,
464 AstNodeFactory* factory) {
465 if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
466 y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) {
467 double x_val = (*x)->AsLiteral()->raw_value()->AsNumber();
468 double y_val = y->AsLiteral()->raw_value()->AsNumber();
471 *x = factory->NewNumberLiteral(x_val + y_val, pos);
474 *x = factory->NewNumberLiteral(x_val - y_val, pos);
477 *x = factory->NewNumberLiteral(x_val * y_val, pos);
480 *x = factory->NewNumberLiteral(x_val / y_val, pos);
482 case Token::BIT_OR: {
483 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
484 *x = factory->NewNumberLiteral(value, pos);
487 case Token::BIT_AND: {
488 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
489 *x = factory->NewNumberLiteral(value, pos);
492 case Token::BIT_XOR: {
493 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
494 *x = factory->NewNumberLiteral(value, pos);
498 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
499 *x = factory->NewNumberLiteral(value, pos);
503 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
504 uint32_t value = DoubleToUint32(x_val) >> shift;
505 *x = factory->NewNumberLiteral(value, pos);
509 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
510 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
511 *x = factory->NewNumberLiteral(value, pos);
522 Expression* ParserTraits::BuildUnaryExpression(Expression* expression,
523 Token::Value op, int pos,
524 AstNodeFactory* factory) {
525 DCHECK(expression != NULL);
526 if (expression->IsLiteral()) {
527 const AstValue* literal = expression->AsLiteral()->raw_value();
528 if (op == Token::NOT) {
529 // Convert the literal to a boolean condition and negate it.
530 bool condition = literal->BooleanValue();
531 return factory->NewBooleanLiteral(!condition, pos);
532 } else if (literal->IsNumber()) {
533 // Compute some expressions involving only number literals.
534 double value = literal->AsNumber();
539 return factory->NewNumberLiteral(-value, pos);
541 return factory->NewNumberLiteral(~DoubleToInt32(value), pos);
547 // Desugar '+foo' => 'foo*1'
548 if (op == Token::ADD) {
549 return factory->NewBinaryOperation(
550 Token::MUL, expression, factory->NewNumberLiteral(1, pos), pos);
552 // The same idea for '-foo' => 'foo*(-1)'.
553 if (op == Token::SUB) {
554 return factory->NewBinaryOperation(
555 Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos);
557 // ...and one more time for '~foo' => 'foo^(~0)'.
558 if (op == Token::BIT_NOT) {
559 return factory->NewBinaryOperation(
560 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos);
562 return factory->NewUnaryOperation(op, expression, pos);
566 Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) {
567 return NewThrowError(
568 parser_->ast_value_factory()->make_reference_error_string(), message,
569 parser_->ast_value_factory()->empty_string(), pos);
573 Expression* ParserTraits::NewThrowSyntaxError(
574 const char* message, const AstRawString* arg, int pos) {
575 return NewThrowError(parser_->ast_value_factory()->make_syntax_error_string(),
580 Expression* ParserTraits::NewThrowTypeError(
581 const char* message, const AstRawString* arg, int pos) {
582 return NewThrowError(parser_->ast_value_factory()->make_type_error_string(),
587 Expression* ParserTraits::NewThrowError(
588 const AstRawString* constructor, const char* message,
589 const AstRawString* arg, int pos) {
590 Zone* zone = parser_->zone();
591 const AstRawString* type =
592 parser_->ast_value_factory()->GetOneByteString(message);
593 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone);
594 args->Add(parser_->factory()->NewStringLiteral(type, pos), zone);
595 args->Add(parser_->factory()->NewStringLiteral(arg, pos), zone);
596 CallRuntime* call_constructor =
597 parser_->factory()->NewCallRuntime(constructor, NULL, args, pos);
598 return parser_->factory()->NewThrow(call_constructor, pos);
602 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
605 bool is_reference_error) {
606 if (parser_->stack_overflow()) {
607 // Suppress the error message (syntax error or such) in the presence of a
608 // stack overflow. The isolate allows only one pending exception at at time
609 // and we want to report the stack overflow later.
612 parser_->has_pending_error_ = true;
613 parser_->pending_error_location_ = source_location;
614 parser_->pending_error_message_ = message;
615 parser_->pending_error_char_arg_ = arg;
616 parser_->pending_error_arg_ = NULL;
617 parser_->pending_error_is_reference_error_ = is_reference_error;
621 void ParserTraits::ReportMessage(const char* message,
623 bool is_reference_error) {
624 Scanner::Location source_location = parser_->scanner()->location();
625 ReportMessageAt(source_location, message, arg, is_reference_error);
629 void ParserTraits::ReportMessage(const char* message,
630 const AstRawString* arg,
631 bool is_reference_error) {
632 Scanner::Location source_location = parser_->scanner()->location();
633 ReportMessageAt(source_location, message, arg, is_reference_error);
637 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
639 const AstRawString* arg,
640 bool is_reference_error) {
641 if (parser_->stack_overflow()) {
642 // Suppress the error message (syntax error or such) in the presence of a
643 // stack overflow. The isolate allows only one pending exception at at time
644 // and we want to report the stack overflow later.
647 parser_->has_pending_error_ = true;
648 parser_->pending_error_location_ = source_location;
649 parser_->pending_error_message_ = message;
650 parser_->pending_error_char_arg_ = NULL;
651 parser_->pending_error_arg_ = arg;
652 parser_->pending_error_is_reference_error_ = is_reference_error;
656 const AstRawString* ParserTraits::GetSymbol(Scanner* scanner) {
657 const AstRawString* result =
658 parser_->scanner()->CurrentSymbol(parser_->ast_value_factory());
659 DCHECK(result != NULL);
664 const AstRawString* ParserTraits::GetNumberAsSymbol(Scanner* scanner) {
665 double double_value = parser_->scanner()->DoubleValue();
668 DoubleToCString(double_value, Vector<char>(array, arraysize(array)));
669 return parser_->ast_value_factory()->GetOneByteString(string);
673 const AstRawString* ParserTraits::GetNextSymbol(Scanner* scanner) {
674 return parser_->scanner()->NextSymbol(parser_->ast_value_factory());
678 Expression* ParserTraits::ThisExpression(Scope* scope, AstNodeFactory* factory,
680 return factory->NewVariableProxy(scope->receiver(), pos);
683 Expression* ParserTraits::SuperReference(Scope* scope, AstNodeFactory* factory,
685 return factory->NewSuperReference(
686 ThisExpression(scope, factory, pos)->AsVariableProxy(),
691 Expression* ParserTraits::DefaultConstructor(bool call_super, Scope* scope,
692 int pos, int end_pos) {
693 return parser_->DefaultConstructor(call_super, scope, pos, end_pos);
697 Literal* ParserTraits::ExpressionFromLiteral(Token::Value token, int pos,
699 AstNodeFactory* factory) {
701 case Token::NULL_LITERAL:
702 return factory->NewNullLiteral(pos);
703 case Token::TRUE_LITERAL:
704 return factory->NewBooleanLiteral(true, pos);
705 case Token::FALSE_LITERAL:
706 return factory->NewBooleanLiteral(false, pos);
707 case Token::NUMBER: {
708 double value = scanner->DoubleValue();
709 return factory->NewNumberLiteral(value, pos);
718 Expression* ParserTraits::ExpressionFromIdentifier(const AstRawString* name,
719 int pos, Scope* scope,
720 AstNodeFactory* factory) {
721 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name);
723 // Arrow function parameters are parsed as an expression. When
724 // parsing lazily, it is enough to create a VariableProxy in order
725 // for Traits::DeclareArrowParametersFromExpression() to be able to
726 // pick the names of the parameters.
727 return parser_->parsing_lazy_arrow_parameters_
728 ? factory->NewVariableProxy(name, false, pos)
729 : scope->NewUnresolved(factory, name, pos);
733 Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner,
734 AstNodeFactory* factory) {
735 const AstRawString* symbol = GetSymbol(scanner);
736 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol);
737 return factory->NewStringLiteral(symbol, pos);
741 Expression* ParserTraits::GetIterator(Expression* iterable,
742 AstNodeFactory* factory) {
743 Expression* iterator_symbol_literal =
744 factory->NewSymbolLiteral("iterator_symbol", RelocInfo::kNoPosition);
745 int pos = iterable->position();
747 factory->NewProperty(iterable, iterator_symbol_literal, pos);
748 Zone* zone = parser_->zone();
749 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(0, zone);
750 return factory->NewCall(prop, args, pos);
754 Literal* ParserTraits::GetLiteralTheHole(int position,
755 AstNodeFactory* factory) {
756 return factory->NewTheHoleLiteral(RelocInfo::kNoPosition);
760 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) {
761 return parser_->ParseV8Intrinsic(ok);
765 FunctionLiteral* ParserTraits::ParseFunctionLiteral(
766 const AstRawString* name, Scanner::Location function_name_location,
767 bool name_is_strict_reserved, FunctionKind kind,
768 int function_token_position, FunctionLiteral::FunctionType type,
769 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
770 return parser_->ParseFunctionLiteral(
771 name, function_name_location, name_is_strict_reserved, kind,
772 function_token_position, type, arity_restriction, ok);
776 ClassLiteral* ParserTraits::ParseClassLiteral(
777 const AstRawString* name, Scanner::Location class_name_location,
778 bool name_is_strict_reserved, int pos, bool* ok) {
779 return parser_->ParseClassLiteral(name, class_name_location,
780 name_is_strict_reserved, pos, ok);
784 Parser::Parser(CompilationInfo* info, uintptr_t stack_limit, uint32_t hash_seed,
785 UnicodeCache* unicode_cache)
786 : ParserBase<ParserTraits>(info->zone(), &scanner_, stack_limit,
787 info->extension(), info->ast_value_factory(),
789 scanner_(unicode_cache),
790 reusable_preparser_(NULL),
791 original_scope_(NULL),
793 compile_options_(info->compile_options()),
794 cached_parse_data_(NULL),
795 parsing_lazy_arrow_parameters_(false),
796 has_pending_error_(false),
797 pending_error_message_(NULL),
798 pending_error_arg_(NULL),
799 pending_error_char_arg_(NULL),
800 total_preparse_skipped_(0),
801 pre_parse_timer_(NULL),
802 parsing_on_main_thread_(true) {
803 // Even though we were passed CompilationInfo, we should not store it in
804 // Parser - this makes sure that Isolate is not accidentally accessed via
805 // CompilationInfo during background parsing.
806 DCHECK(!info->script().is_null() || info->source_stream() != NULL);
807 set_allow_lazy(false); // Must be explicitly enabled.
808 set_allow_natives(FLAG_allow_natives_syntax || info->is_native());
809 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping);
810 set_allow_harmony_modules(!info->is_native() && FLAG_harmony_modules);
811 set_allow_harmony_arrow_functions(FLAG_harmony_arrow_functions);
812 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
813 set_allow_harmony_classes(FLAG_harmony_classes);
814 set_allow_harmony_object_literals(FLAG_harmony_object_literals);
815 set_allow_harmony_templates(FLAG_harmony_templates);
816 set_allow_harmony_sloppy(FLAG_harmony_sloppy);
817 set_allow_harmony_unicode(FLAG_harmony_unicode);
818 set_allow_harmony_computed_property_names(
819 FLAG_harmony_computed_property_names);
820 set_allow_harmony_rest_params(FLAG_harmony_rest_parameters);
821 set_allow_strong_mode(FLAG_strong_mode);
822 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
824 use_counts_[feature] = 0;
826 if (info->ast_value_factory() == NULL) {
827 // info takes ownership of AstValueFactory.
828 info->SetAstValueFactory(new AstValueFactory(zone(), hash_seed));
829 ast_value_factory_ = info->ast_value_factory();
834 FunctionLiteral* Parser::ParseProgram(CompilationInfo* info) {
835 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
836 // see comment for HistogramTimerScope class.
838 // It's OK to use the Isolate & counters here, since this function is only
839 // called in the main thread.
840 DCHECK(parsing_on_main_thread_);
842 Isolate* isolate = info->isolate();
843 HistogramTimerScope timer_scope(isolate->counters()->parse(), true);
844 Handle<String> source(String::cast(info->script()->source()));
845 isolate->counters()->total_parse_size()->Increment(source->length());
846 base::ElapsedTimer timer;
847 if (FLAG_trace_parse) {
850 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
852 // Initialize parser state.
853 CompleteParserRecorder recorder;
855 if (produce_cached_parse_data()) {
857 } else if (consume_cached_parse_data()) {
858 cached_parse_data_->Initialize();
861 source = String::Flatten(source);
862 FunctionLiteral* result;
864 Scope* top_scope = NULL;
865 Scope* eval_scope = NULL;
866 if (source->IsExternalTwoByteString()) {
867 // Notice that the stream is destroyed at the end of the branch block.
868 // The last line of the blocks can't be moved outside, even though they're
870 ExternalTwoByteStringUtf16CharacterStream stream(
871 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
872 scanner_.Initialize(&stream);
873 result = DoParseProgram(info, &top_scope, &eval_scope);
875 GenericStringUtf16CharacterStream stream(source, 0, source->length());
876 scanner_.Initialize(&stream);
877 result = DoParseProgram(info, &top_scope, &eval_scope);
879 top_scope->set_end_position(source->length());
880 if (eval_scope != NULL) {
881 eval_scope->set_end_position(source->length());
883 HandleSourceURLComments(info);
885 if (FLAG_trace_parse && result != NULL) {
886 double ms = timer.Elapsed().InMillisecondsF();
887 if (info->is_eval()) {
888 PrintF("[parsing eval");
889 } else if (info->script()->name()->IsString()) {
890 String* name = String::cast(info->script()->name());
891 SmartArrayPointer<char> name_chars = name->ToCString();
892 PrintF("[parsing script: %s", name_chars.get());
894 PrintF("[parsing script");
896 PrintF(" - took %0.3f ms]\n", ms);
898 if (produce_cached_parse_data()) {
899 if (result != NULL) *info->cached_data() = recorder.GetScriptData();
906 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope,
907 Scope** eval_scope) {
908 // Note that this function can be called from the main thread or from a
909 // background thread. We should not access anything Isolate / heap dependent
910 // via CompilationInfo, and also not pass it forward.
911 DCHECK(scope_ == NULL);
912 DCHECK(target_stack_ == NULL);
914 FunctionLiteral* result = NULL;
916 *scope = NewScope(scope_, SCRIPT_SCOPE);
917 info->SetScriptScope(*scope);
918 if (!info->context().is_null() && !info->context()->IsNativeContext()) {
919 *scope = Scope::DeserializeScopeChain(info->isolate(), zone(),
920 *info->context(), *scope);
921 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this
922 // means the Parser cannot operate independent of the V8 heap. Tell the
923 // string table to internalize strings and values right after they're
924 // created. This kind of parsing can only be done in the main thread.
925 DCHECK(parsing_on_main_thread_);
926 ast_value_factory()->Internalize(info->isolate());
928 original_scope_ = *scope;
929 if (info->is_eval()) {
930 if (!(*scope)->is_script_scope() || is_strict(info->language_mode())) {
931 *scope = NewScope(*scope, EVAL_SCOPE);
933 } else if (info->is_global()) {
934 *scope = NewScope(*scope, SCRIPT_SCOPE);
936 (*scope)->set_start_position(0);
937 // End position will be set by the caller.
939 // Compute the parsing mode.
940 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY;
941 if (allow_natives() || extension_ != NULL ||
942 (*scope)->is_eval_scope()) {
943 mode = PARSE_EAGERLY;
945 ParsingModeScope parsing_mode(this, mode);
948 AstNodeFactory function_factory(ast_value_factory());
949 FunctionState function_state(&function_state_, &scope_, *scope,
950 kNormalFunction, &function_factory);
952 scope_->SetLanguageMode(info->language_mode());
953 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
955 int beg_pos = scanner()->location().beg_pos;
956 if (info->is_module()) {
957 DCHECK(allow_harmony_modules());
958 Statement* stmt = ParseModule(&ok);
960 body->Add(stmt, zone());
963 ParseStatementList(body, Token::EOS, info->is_eval(), eval_scope, &ok);
966 if (ok && is_strict(language_mode())) {
967 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
970 if (ok && allow_harmony_scoping() && is_strict(language_mode())) {
971 CheckConflictingVarDeclarations(scope_, &ok);
974 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
975 if (body->length() != 1 ||
976 !body->at(0)->IsExpressionStatement() ||
977 !body->at(0)->AsExpressionStatement()->
978 expression()->IsFunctionLiteral()) {
979 ReportMessage("single_function_literal");
985 result = factory()->NewFunctionLiteral(
986 ast_value_factory()->empty_string(), ast_value_factory(), scope_,
987 body, function_state.materialized_literal_count(),
988 function_state.expected_property_count(),
989 function_state.handler_count(), 0,
990 FunctionLiteral::kNoDuplicateParameters,
991 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval,
992 FunctionLiteral::kNotParenthesized, FunctionKind::kNormalFunction, 0);
996 // Make sure the target stack is empty.
997 DCHECK(target_stack_ == NULL);
1003 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) {
1004 // It's OK to use the Isolate & counters here, since this function is only
1005 // called in the main thread.
1006 DCHECK(parsing_on_main_thread_);
1007 HistogramTimerScope timer_scope(info->isolate()->counters()->parse_lazy());
1008 Handle<String> source(String::cast(info->script()->source()));
1009 info->isolate()->counters()->total_parse_size()->Increment(source->length());
1010 base::ElapsedTimer timer;
1011 if (FLAG_trace_parse) {
1014 Handle<SharedFunctionInfo> shared_info = info->shared_info();
1016 // Initialize parser state.
1017 source = String::Flatten(source);
1018 FunctionLiteral* result;
1019 if (source->IsExternalTwoByteString()) {
1020 ExternalTwoByteStringUtf16CharacterStream stream(
1021 Handle<ExternalTwoByteString>::cast(source),
1022 shared_info->start_position(),
1023 shared_info->end_position());
1024 result = ParseLazy(info, &stream);
1026 GenericStringUtf16CharacterStream stream(source,
1027 shared_info->start_position(),
1028 shared_info->end_position());
1029 result = ParseLazy(info, &stream);
1032 if (FLAG_trace_parse && result != NULL) {
1033 double ms = timer.Elapsed().InMillisecondsF();
1034 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString();
1035 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
1041 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
1042 Utf16CharacterStream* source) {
1043 Handle<SharedFunctionInfo> shared_info = info->shared_info();
1044 scanner_.Initialize(source);
1045 DCHECK(scope_ == NULL);
1046 DCHECK(target_stack_ == NULL);
1048 Handle<String> name(String::cast(shared_info->name()));
1049 DCHECK(ast_value_factory());
1050 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
1051 const AstRawString* raw_name = ast_value_factory()->GetString(name);
1052 fni_->PushEnclosingName(raw_name);
1054 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1056 // Place holder for the result.
1057 FunctionLiteral* result = NULL;
1060 // Parse the function literal.
1061 Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
1062 info->SetScriptScope(scope);
1063 if (!info->closure().is_null()) {
1064 // Ok to use Isolate here, since lazy function parsing is only done in the
1066 DCHECK(parsing_on_main_thread_);
1067 scope = Scope::DeserializeScopeChain(info->isolate(), zone(),
1068 info->closure()->context(), scope);
1070 original_scope_ = scope;
1071 AstNodeFactory function_factory(ast_value_factory());
1072 FunctionState function_state(&function_state_, &scope_, scope,
1073 shared_info->kind(), &function_factory);
1074 DCHECK(is_sloppy(scope->language_mode()) ||
1075 is_strict(info->language_mode()));
1076 DCHECK(info->language_mode() == shared_info->language_mode());
1077 scope->SetLanguageMode(shared_info->language_mode());
1078 FunctionLiteral::FunctionType function_type = shared_info->is_expression()
1079 ? (shared_info->is_anonymous()
1080 ? FunctionLiteral::ANONYMOUS_EXPRESSION
1081 : FunctionLiteral::NAMED_EXPRESSION)
1082 : FunctionLiteral::DECLARATION;
1085 if (shared_info->is_arrow()) {
1086 // The first expression being parsed is the parameter list of the arrow
1087 // function. Setting this avoids prevents ExpressionFromIdentifier()
1088 // from creating unresolved variables in already-resolved scopes.
1089 parsing_lazy_arrow_parameters_ = true;
1090 Expression* expression = ParseExpression(false, &ok);
1091 DCHECK(expression->IsFunctionLiteral());
1092 result = expression->AsFunctionLiteral();
1093 } else if (shared_info->is_default_constructor()) {
1094 result = DefaultConstructor(IsSubclassConstructor(shared_info->kind()),
1095 scope, shared_info->start_position(),
1096 shared_info->end_position());
1098 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(),
1099 false, // Strict mode name already checked.
1100 shared_info->kind(), RelocInfo::kNoPosition,
1102 FunctionLiteral::NORMAL_ARITY, &ok);
1104 // Make sure the results agree.
1105 DCHECK(ok == (result != NULL));
1108 // Make sure the target stack is empty.
1109 DCHECK(target_stack_ == NULL);
1111 if (result != NULL) {
1112 Handle<String> inferred_name(shared_info->inferred_name());
1113 result->set_inferred_name(inferred_name);
1119 void* Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token,
1120 bool is_eval, Scope** eval_scope, bool* ok) {
1122 // (StatementListItem)* <end_token>
1124 // Allocate a target stack to use for this set of source
1125 // elements. This way, all scripts and functions get their own
1126 // target stack thus avoiding illegal breaks and continues across
1128 TargetScope scope(&this->target_stack_);
1130 DCHECK(body != NULL);
1131 bool directive_prologue = true; // Parsing directive prologue.
1133 while (peek() != end_token) {
1134 if (directive_prologue && peek() != Token::STRING) {
1135 directive_prologue = false;
1138 Scanner::Location token_loc = scanner()->peek_location();
1139 Statement* stat = ParseStatementListItem(CHECK_OK);
1140 if (stat == NULL || stat->IsEmpty()) {
1141 directive_prologue = false; // End of directive prologue.
1145 if (directive_prologue) {
1146 // A shot at a directive.
1147 ExpressionStatement* e_stat;
1149 // Still processing directive prologue?
1150 if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1151 (literal = e_stat->expression()->AsLiteral()) != NULL &&
1152 literal->raw_value()->IsString()) {
1153 // Check "use strict" directive (ES5 14.1), "use asm" directive, and
1154 // "use strong" directive (experimental).
1155 bool use_strict_found =
1156 literal->raw_value()->AsString() ==
1157 ast_value_factory()->use_strict_string() &&
1158 token_loc.end_pos - token_loc.beg_pos ==
1159 ast_value_factory()->use_strict_string()->length() + 2;
1160 bool use_strong_found =
1161 allow_strong_mode() &&
1162 literal->raw_value()->AsString() ==
1163 ast_value_factory()->use_strong_string() &&
1164 token_loc.end_pos - token_loc.beg_pos ==
1165 ast_value_factory()->use_strong_string()->length() + 2;
1166 if (use_strict_found || use_strong_found) {
1167 // Strong mode implies strict mode. If there are several "use strict"
1168 // / "use strong" directives, do the strict mode changes only once.
1169 if (is_sloppy(scope_->language_mode())) {
1170 // TODO(mstarzinger): Global strict eval calls, need their own scope
1171 // as specified in ES5 10.4.2(3). The correct fix would be to always
1172 // add this scope in DoParseProgram(), but that requires adaptations
1173 // all over the code base, so we go with a quick-fix for now.
1174 // In the same manner, we have to patch the parsing mode.
1175 if (is_eval && !scope_->is_eval_scope()) {
1176 DCHECK(scope_->is_script_scope());
1177 Scope* scope = NewScope(scope_, EVAL_SCOPE);
1178 scope->set_start_position(scope_->start_position());
1179 scope->set_end_position(scope_->end_position());
1181 if (eval_scope != NULL) {
1182 // Caller will correct the positions of the ad hoc eval scope.
1183 *eval_scope = scope;
1185 mode_ = PARSE_EAGERLY;
1187 scope_->SetLanguageMode(static_cast<LanguageMode>(
1188 scope_->language_mode() | STRICT_BIT));
1191 if (use_strong_found) {
1192 scope_->SetLanguageMode(static_cast<LanguageMode>(
1193 scope_->language_mode() | STRONG_BIT));
1195 } else if (literal->raw_value()->AsString() ==
1196 ast_value_factory()->use_asm_string() &&
1197 token_loc.end_pos - token_loc.beg_pos ==
1198 ast_value_factory()->use_asm_string()->length() + 2) {
1199 // Store the usage count; The actual use counter on the isolate is
1200 // incremented after parsing is done.
1201 ++use_counts_[v8::Isolate::kUseAsm];
1202 scope_->SetAsmModule();
1205 // End of the directive prologue.
1206 directive_prologue = false;
1210 body->Add(stat, zone());
1217 Statement* Parser::ParseStatementListItem(bool* ok) {
1218 // (Ecma 262 6th Edition, 13.1):
1219 // StatementListItem:
1224 case Token::FUNCTION:
1225 return ParseFunctionDeclaration(NULL, ok);
1227 return ParseClassDeclaration(NULL, ok);
1230 return ParseVariableStatement(kStatementListItem, NULL, ok);
1232 DCHECK(allow_harmony_scoping());
1233 if (is_strict(language_mode())) {
1234 return ParseVariableStatement(kStatementListItem, NULL, ok);
1238 return ParseStatement(NULL, ok);
1243 Statement* Parser::ParseModuleItem(bool* ok) {
1244 // (Ecma 262 6th Edition, 15.2):
1246 // ImportDeclaration
1247 // ExportDeclaration
1248 // StatementListItem
1252 return ParseImportDeclaration(ok);
1254 return ParseExportDeclaration(ok);
1256 return ParseStatementListItem(ok);
1261 Statement* Parser::ParseModule(bool* ok) {
1262 // (Ecma 262 6th Edition, 15.2):
1269 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition);
1270 Scope* scope = NewScope(scope_, MODULE_SCOPE);
1271 scope->set_start_position(scanner()->location().beg_pos);
1272 scope->SetLanguageMode(
1273 static_cast<LanguageMode>(scope->language_mode() | STRICT_BIT));
1276 BlockState block_state(&scope_, scope);
1278 while (peek() != Token::EOS) {
1279 Statement* stat = ParseModuleItem(CHECK_OK);
1280 if (stat && !stat->IsEmpty()) {
1281 body->AddStatement(stat, zone());
1286 scope->set_end_position(scanner()->location().end_pos);
1287 body->set_scope(scope);
1289 // Check that all exports are bound.
1290 ModuleDescriptor* descriptor = scope->module();
1291 for (ModuleDescriptor::Iterator it = descriptor->iterator(); !it.done();
1293 if (scope->LookupLocal(it.name()) == NULL) {
1294 ParserTraits::ReportMessage("module_export_undefined", it.name());
1300 scope->module()->Freeze();
1305 Literal* Parser::ParseModuleSpecifier(bool* ok) {
1306 // ModuleSpecifier :
1309 int pos = peek_position();
1310 Expect(Token::STRING, CHECK_OK);
1311 return factory()->NewStringLiteral(GetSymbol(scanner()), pos);
1315 void* Parser::ParseExportClause(ZoneList<const AstRawString*>* names,
1316 Scanner::Location* reserved_loc, bool* ok) {
1319 // '{' ExportsList '}'
1320 // '{' ExportsList ',' '}'
1324 // ExportsList ',' ExportSpecifier
1326 // ExportSpecifier :
1328 // IdentifierName 'as' IdentifierName
1330 Expect(Token::LBRACE, CHECK_OK);
1332 Token::Value name_tok;
1333 while ((name_tok = peek()) != Token::RBRACE) {
1334 // Keep track of the first reserved word encountered in case our
1335 // caller needs to report an error.
1336 if (!reserved_loc->IsValid() &&
1337 !Token::IsIdentifier(name_tok, STRICT, false)) {
1338 *reserved_loc = scanner()->location();
1340 const AstRawString* name = ParseIdentifierName(CHECK_OK);
1341 names->Add(name, zone());
1342 const AstRawString* export_name = NULL;
1343 if (CheckContextualKeyword(CStrVector("as"))) {
1344 export_name = ParseIdentifierName(CHECK_OK);
1346 // TODO(ES6): Return the export_name as well as the name.
1348 if (peek() == Token::RBRACE) break;
1349 Expect(Token::COMMA, CHECK_OK);
1352 Expect(Token::RBRACE, CHECK_OK);
1358 void* Parser::ParseNamedImports(ZoneList<const AstRawString*>* names,
1362 // '{' ImportsList '}'
1363 // '{' ImportsList ',' '}'
1367 // ImportsList ',' ImportSpecifier
1369 // ImportSpecifier :
1370 // BindingIdentifier
1371 // IdentifierName 'as' BindingIdentifier
1373 Expect(Token::LBRACE, CHECK_OK);
1375 Token::Value name_tok;
1376 while ((name_tok = peek()) != Token::RBRACE) {
1377 const AstRawString* name = ParseIdentifierName(CHECK_OK);
1378 const AstRawString* import_name = NULL;
1379 // In the presence of 'as', the left-side of the 'as' can
1380 // be any IdentifierName. But without 'as', it must be a valid
1381 // BindingIdentiifer.
1382 if (CheckContextualKeyword(CStrVector("as"))) {
1383 import_name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1384 } else if (!Token::IsIdentifier(name_tok, STRICT, false)) {
1386 ReportMessageAt(scanner()->location(), "unexpected_reserved");
1388 } else if (IsEvalOrArguments(name)) {
1390 ReportMessageAt(scanner()->location(), "strict_eval_arguments");
1393 // TODO(ES6): Return the import_name as well as the name.
1394 names->Add(name, zone());
1396 if (peek() == Token::RBRACE) break;
1397 Expect(Token::COMMA, CHECK_OK);
1400 Expect(Token::RBRACE, CHECK_OK);
1406 Statement* Parser::ParseImportDeclaration(bool* ok) {
1407 // ImportDeclaration :
1408 // 'import' ImportClause 'from' ModuleSpecifier ';'
1409 // 'import' ModuleSpecifier ';'
1414 // ImportedDefaultBinding
1415 // ImportedDefaultBinding ',' NameSpaceImport
1416 // ImportedDefaultBinding ',' NamedImports
1418 // NameSpaceImport :
1419 // '*' 'as' ImportedBinding
1421 int pos = peek_position();
1422 Expect(Token::IMPORT, CHECK_OK);
1424 Token::Value tok = peek();
1426 // 'import' ModuleSpecifier ';'
1427 if (tok == Token::STRING) {
1428 ParseModuleSpecifier(CHECK_OK);
1429 ExpectSemicolon(CHECK_OK);
1430 return factory()->NewEmptyStatement(pos);
1433 // Parse ImportedDefaultBinding if present.
1434 const AstRawString* imported_default_binding = NULL;
1435 if (tok != Token::MUL && tok != Token::LBRACE) {
1436 imported_default_binding =
1437 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1440 const AstRawString* module_instance_binding = NULL;
1441 ZoneList<const AstRawString*> names(1, zone());
1442 if (imported_default_binding == NULL || Check(Token::COMMA)) {
1445 Consume(Token::MUL);
1446 ExpectContextualKeyword(CStrVector("as"), CHECK_OK);
1447 module_instance_binding =
1448 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1453 ParseNamedImports(&names, CHECK_OK);
1458 ReportUnexpectedToken(scanner()->current_token());
1463 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1464 Literal* module = ParseModuleSpecifier(CHECK_OK);
1467 ExpectSemicolon(CHECK_OK);
1469 if (module_instance_binding != NULL) {
1470 // TODO(ES6): Bind name to the Module Instance Object of module.
1473 if (imported_default_binding != NULL) {
1474 // TODO(ES6): Add an appropriate declaration.
1477 for (int i = 0; i < names.length(); ++i) {
1478 // TODO(ES6): Add an appropriate declaration for each name
1481 return factory()->NewEmptyStatement(pos);
1485 Statement* Parser::ParseExportDefault(bool* ok) {
1486 // Supports the following productions, starting after the 'default' token:
1487 // 'export' 'default' FunctionDeclaration
1488 // 'export' 'default' ClassDeclaration
1489 // 'export' 'default' AssignmentExpression[In] ';'
1491 Statement* result = NULL;
1493 case Token::FUNCTION:
1494 // TODO(ES6): Support parsing anonymous function declarations here.
1495 result = ParseFunctionDeclaration(NULL, CHECK_OK);
1499 // TODO(ES6): Support parsing anonymous class declarations here.
1500 result = ParseClassDeclaration(NULL, CHECK_OK);
1504 int pos = peek_position();
1505 Expression* expr = ParseAssignmentExpression(true, CHECK_OK);
1506 ExpectSemicolon(CHECK_OK);
1507 result = factory()->NewExpressionStatement(expr, pos);
1512 // TODO(ES6): Add default export to scope_->module()
1518 Statement* Parser::ParseExportDeclaration(bool* ok) {
1519 // ExportDeclaration:
1520 // 'export' '*' 'from' ModuleSpecifier ';'
1521 // 'export' ExportClause ('from' ModuleSpecifier)? ';'
1522 // 'export' VariableStatement
1523 // 'export' Declaration
1524 // 'export' 'default' ... (handled in ParseExportDefault)
1526 int pos = peek_position();
1527 Expect(Token::EXPORT, CHECK_OK);
1529 Statement* result = NULL;
1530 ZoneList<const AstRawString*> names(1, zone());
1531 bool is_export_from = false;
1533 case Token::DEFAULT:
1534 Consume(Token::DEFAULT);
1535 return ParseExportDefault(ok);
1538 Consume(Token::MUL);
1539 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1540 Literal* module = ParseModuleSpecifier(CHECK_OK);
1541 ExpectSemicolon(CHECK_OK);
1542 // TODO(ES6): Do something with the return value
1543 // of ParseModuleSpecifier.
1545 is_export_from = true;
1546 result = factory()->NewEmptyStatement(pos);
1550 case Token::LBRACE: {
1551 // There are two cases here:
1553 // 'export' ExportClause ';'
1555 // 'export' ExportClause FromClause ';'
1557 // In the first case, the exported identifiers in ExportClause must
1558 // not be reserved words, while in the latter they may be. We
1559 // pass in a location that gets filled with the first reserved word
1560 // encountered, and then throw a SyntaxError if we are in the
1561 // non-FromClause case.
1562 Scanner::Location reserved_loc = Scanner::Location::invalid();
1563 ParseExportClause(&names, &reserved_loc, CHECK_OK);
1564 if (CheckContextualKeyword(CStrVector("from"))) {
1565 Literal* module = ParseModuleSpecifier(CHECK_OK);
1566 // TODO(ES6): Do something with the return value
1567 // of ParseModuleSpecifier.
1569 is_export_from = true;
1570 } else if (reserved_loc.IsValid()) {
1571 // No FromClause, so reserved words are invalid in ExportClause.
1573 ReportMessageAt(reserved_loc, "unexpected_reserved");
1576 ExpectSemicolon(CHECK_OK);
1577 result = factory()->NewEmptyStatement(pos);
1581 case Token::FUNCTION:
1582 result = ParseFunctionDeclaration(&names, CHECK_OK);
1586 result = ParseClassDeclaration(&names, CHECK_OK);
1592 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK);
1597 ReportUnexpectedToken(scanner()->current_token());
1601 // Every export of a module may be assigned.
1602 for (int i = 0; i < names.length(); ++i) {
1603 Variable* var = scope_->Lookup(names[i]);
1605 // TODO(sigurds) This is an export that has no definition yet,
1606 // not clear what to do in this case.
1609 if (!IsImmutableVariableMode(var->mode())) {
1610 var->set_maybe_assigned();
1614 // TODO(ES6): Handle 'export from' once imports are properly implemented.
1615 // For now we just drop such exports on the floor.
1616 if (!is_export_from) {
1617 // Extract declared names into export declarations and module descriptor.
1618 ModuleDescriptor* descriptor = scope_->module();
1619 for (int i = 0; i < names.length(); ++i) {
1620 // TODO(adamk): Make early errors here provide the right error message
1621 // (duplicate exported names).
1622 descriptor->Add(names[i], zone(), CHECK_OK);
1623 // TODO(rossberg): Rethink whether we actually need to store export
1624 // declarations (for compilation?).
1625 // ExportDeclaration* declaration =
1626 // factory()->NewExportDeclaration(proxy, scope_, position);
1627 // scope_->AddDeclaration(declaration);
1631 DCHECK(result != NULL);
1636 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels,
1642 if (peek() == Token::SEMICOLON) {
1644 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1646 return ParseSubStatement(labels, ok);
1650 Statement* Parser::ParseSubStatement(ZoneList<const AstRawString*>* labels,
1654 // VariableStatement
1656 // ExpressionStatement
1658 // IterationStatement
1659 // ContinueStatement
1663 // LabelledStatement
1667 // DebuggerStatement
1669 // Note: Since labels can only be used by 'break' and 'continue'
1670 // statements, which themselves are only valid within blocks,
1671 // iterations or 'switch' statements (i.e., BreakableStatements),
1672 // labels can be simply ignored in all other cases; except for
1673 // trivial labeled break statements 'label: break label' which is
1674 // parsed into an empty statement.
1677 return ParseBlock(labels, ok);
1679 case Token::SEMICOLON:
1680 if (is_strong(language_mode())) {
1681 ReportMessageAt(scanner()->peek_location(), "strong_empty");
1686 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1689 return ParseIfStatement(labels, ok);
1692 return ParseDoWhileStatement(labels, ok);
1695 return ParseWhileStatement(labels, ok);
1698 return ParseForStatement(labels, ok);
1700 case Token::CONTINUE:
1701 return ParseContinueStatement(ok);
1704 return ParseBreakStatement(labels, ok);
1707 return ParseReturnStatement(ok);
1710 return ParseWithStatement(labels, ok);
1713 return ParseSwitchStatement(labels, ok);
1716 return ParseThrowStatement(ok);
1719 // NOTE: It is somewhat complicated to have labels on
1720 // try-statements. When breaking out of a try-finally statement,
1721 // one must take great care not to treat it as a
1722 // fall-through. It is much easier just to wrap the entire
1723 // try-statement in a statement block and put the labels there
1725 factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition);
1726 Target target(&this->target_stack_, result);
1727 TryStatement* statement = ParseTryStatement(CHECK_OK);
1728 if (result) result->AddStatement(statement, zone());
1732 case Token::FUNCTION: {
1733 // FunctionDeclaration is only allowed in the context of SourceElements
1734 // (Ecma 262 5th Edition, clause 14):
1737 // FunctionDeclaration
1738 // Common language extension is to allow function declaration in place
1739 // of any statement. This language extension is disabled in strict mode.
1741 // In Harmony mode, this case also handles the extension:
1743 // GeneratorDeclaration
1744 if (is_strict(language_mode())) {
1745 ReportMessageAt(scanner()->peek_location(), "strict_function");
1749 return ParseFunctionDeclaration(NULL, ok);
1752 case Token::DEBUGGER:
1753 return ParseDebuggerStatement(ok);
1756 return ParseVariableStatement(kStatement, NULL, ok);
1759 // In ES6 CONST is not allowed as a Statement, only as a
1760 // LexicalDeclaration, however we continue to allow it in sloppy mode for
1761 // backwards compatibility.
1762 if (is_sloppy(language_mode())) {
1763 return ParseVariableStatement(kStatement, NULL, ok);
1768 return ParseExpressionOrLabelledStatement(labels, ok);
1773 VariableProxy* Parser::NewUnresolved(const AstRawString* name,
1774 VariableMode mode) {
1775 // If we are inside a function, a declaration of a var/const variable is a
1776 // truly local variable, and the scope of the variable is always the function
1778 // Let/const variables in harmony mode are always added to the immediately
1780 return DeclarationScope(mode)->NewUnresolved(factory(), name, position());
1784 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
1785 VariableProxy* proxy = declaration->proxy();
1786 DCHECK(proxy->raw_name() != NULL);
1787 const AstRawString* name = proxy->raw_name();
1788 VariableMode mode = declaration->mode();
1789 Scope* declaration_scope = DeclarationScope(mode);
1790 Variable* var = NULL;
1792 // If a suitable scope exists, then we can statically declare this
1793 // variable and also set its mode. In any case, a Declaration node
1794 // will be added to the scope so that the declaration can be added
1795 // to the corresponding activation frame at runtime if necessary.
1796 // For instance declarations inside an eval scope need to be added
1797 // to the calling function context.
1798 // Similarly, strict mode eval scope does not leak variable declarations to
1799 // the caller's scope so we declare all locals, too.
1800 if (declaration_scope->is_function_scope() ||
1801 declaration_scope->is_strict_eval_scope() ||
1802 declaration_scope->is_block_scope() ||
1803 declaration_scope->is_module_scope() ||
1804 declaration_scope->is_script_scope()) {
1805 // Declare the variable in the declaration scope.
1806 var = declaration_scope->LookupLocal(name);
1808 // Declare the name.
1809 var = declaration_scope->DeclareLocal(
1810 name, mode, declaration->initialization(), kNotAssigned);
1811 } else if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode())
1812 || ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) &&
1813 !declaration_scope->is_script_scope())) {
1814 // The name was declared in this scope before; check for conflicting
1815 // re-declarations. We have a conflict if either of the declarations is
1816 // not a var (in script scope, we also have to ignore legacy const for
1817 // compatibility). There is similar code in runtime.cc in the Declare
1818 // functions. The function CheckConflictingVarDeclarations checks for
1819 // var and let bindings from different scopes whereas this is a check for
1820 // conflicting declarations within the same scope. This check also covers
1823 // function () { let x; { var x; } }
1825 // because the var declaration is hoisted to the function scope where 'x'
1826 // is already bound.
1827 DCHECK(IsDeclaredVariableMode(var->mode()));
1828 if (allow_harmony_scoping() && is_strict(language_mode())) {
1829 // In harmony we treat re-declarations as early errors. See
1830 // ES5 16 for a definition of early errors.
1831 ParserTraits::ReportMessage("var_redeclaration", name);
1835 Expression* expression = NewThrowTypeError(
1836 "var_redeclaration", name, declaration->position());
1837 declaration_scope->SetIllegalRedeclaration(expression);
1838 } else if (mode == VAR) {
1839 var->set_maybe_assigned();
1843 // We add a declaration node for every declaration. The compiler
1844 // will only generate code if necessary. In particular, declarations
1845 // for inner local variables that do not represent functions won't
1846 // result in any generated code.
1848 // Note that we always add an unresolved proxy even if it's not
1849 // used, simply because we don't know in this method (w/o extra
1850 // parameters) if the proxy is needed or not. The proxy will be
1851 // bound during variable resolution time unless it was pre-bound
1854 // WARNING: This will lead to multiple declaration nodes for the
1855 // same variable if it is declared several times. This is not a
1856 // semantic issue as long as we keep the source order, but it may be
1857 // a performance issue since it may lead to repeated
1858 // RuntimeHidden_DeclareLookupSlot calls.
1859 declaration_scope->AddDeclaration(declaration);
1861 if (mode == CONST_LEGACY && declaration_scope->is_script_scope()) {
1862 // For global const variables we bind the proxy to a variable.
1863 DCHECK(resolve); // should be set by all callers
1864 Variable::Kind kind = Variable::NORMAL;
1865 var = new (zone()) Variable(declaration_scope, name, mode, true, kind,
1866 kNeedsInitialization, kNotAssigned);
1867 } else if (declaration_scope->is_eval_scope() &&
1868 is_sloppy(declaration_scope->language_mode())) {
1869 // For variable declarations in a sloppy eval scope the proxy is bound
1870 // to a lookup variable to force a dynamic declaration using the
1871 // DeclareLookupSlot runtime function.
1872 Variable::Kind kind = Variable::NORMAL;
1873 // TODO(sigurds) figure out if kNotAssigned is OK here
1874 var = new (zone()) Variable(declaration_scope, name, mode, true, kind,
1875 declaration->initialization(), kNotAssigned);
1876 var->AllocateTo(Variable::LOOKUP, -1);
1880 // If requested and we have a local variable, bind the proxy to the variable
1881 // at parse-time. This is used for functions (and consts) declared inside
1882 // statements: the corresponding function (or const) variable must be in the
1883 // function scope and not a statement-local scope, e.g. as provided with a
1884 // 'with' statement:
1890 // which is translated into:
1893 // // in this case this is not: 'var f; f = function () {};'
1894 // var f = function () {};
1897 // Note that if 'f' is accessed from inside the 'with' statement, it
1898 // will be allocated in the context (because we must be able to look
1899 // it up dynamically) but it will also be accessed statically, i.e.,
1900 // with a context slot index and a context chain length for this
1901 // initialization code. Thus, inside the 'with' statement, we need
1902 // both access to the static and the dynamic context chain; the
1903 // runtime needs to provide both.
1904 if (resolve && var != NULL) {
1910 // Language extension which is only enabled for source files loaded
1911 // through the API's extension mechanism. A native function
1912 // declaration is resolved by looking up the function through a
1913 // callback provided by the extension.
1914 Statement* Parser::ParseNativeDeclaration(bool* ok) {
1915 int pos = peek_position();
1916 Expect(Token::FUNCTION, CHECK_OK);
1917 // Allow "eval" or "arguments" for backward compatibility.
1918 const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1919 Expect(Token::LPAREN, CHECK_OK);
1920 bool done = (peek() == Token::RPAREN);
1922 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1923 done = (peek() == Token::RPAREN);
1925 Expect(Token::COMMA, CHECK_OK);
1928 Expect(Token::RPAREN, CHECK_OK);
1929 Expect(Token::SEMICOLON, CHECK_OK);
1931 // Make sure that the function containing the native declaration
1932 // isn't lazily compiled. The extension structures are only
1933 // accessible while parsing the first time not when reparsing
1934 // because of lazy compilation.
1935 DeclarationScope(VAR)->ForceEagerCompilation();
1937 // TODO(1240846): It's weird that native function declarations are
1938 // introduced dynamically when we meet their declarations, whereas
1939 // other functions are set up when entering the surrounding scope.
1940 VariableProxy* proxy = NewUnresolved(name, VAR);
1941 Declaration* declaration =
1942 factory()->NewVariableDeclaration(proxy, VAR, scope_, pos);
1943 Declare(declaration, true, CHECK_OK);
1944 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral(
1945 name, extension_, RelocInfo::kNoPosition);
1946 return factory()->NewExpressionStatement(
1947 factory()->NewAssignment(
1948 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition),
1953 Statement* Parser::ParseFunctionDeclaration(
1954 ZoneList<const AstRawString*>* names, bool* ok) {
1955 // FunctionDeclaration ::
1956 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
1957 // GeneratorDeclaration ::
1958 // 'function' '*' Identifier '(' FormalParameterListopt ')'
1959 // '{' FunctionBody '}'
1960 Expect(Token::FUNCTION, CHECK_OK);
1961 int pos = position();
1962 bool is_generator = Check(Token::MUL);
1963 bool is_strict_reserved = false;
1964 const AstRawString* name = ParseIdentifierOrStrictReservedWord(
1965 &is_strict_reserved, CHECK_OK);
1966 FunctionLiteral* fun =
1967 ParseFunctionLiteral(name, scanner()->location(), is_strict_reserved,
1968 is_generator ? FunctionKind::kGeneratorFunction
1969 : FunctionKind::kNormalFunction,
1970 pos, FunctionLiteral::DECLARATION,
1971 FunctionLiteral::NORMAL_ARITY, CHECK_OK);
1972 // Even if we're not at the top-level of the global or a function
1973 // scope, we treat it as such and introduce the function with its
1974 // initial value upon entering the corresponding scope.
1975 // In ES6, a function behaves as a lexical binding, except in
1976 // a script scope, or the initial scope of eval or another function.
1978 is_strong(language_mode()) ? CONST :
1979 allow_harmony_scoping() && is_strict(language_mode()) &&
1980 !(scope_->is_script_scope() || scope_->is_eval_scope() ||
1981 scope_->is_function_scope())
1984 VariableProxy* proxy = NewUnresolved(name, mode);
1985 Declaration* declaration =
1986 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
1987 Declare(declaration, true, CHECK_OK);
1988 if (names) names->Add(name, zone());
1989 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1993 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
1995 // ClassDeclaration ::
1996 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
1998 // A ClassDeclaration
2002 // has the same semantics as:
2004 // let C = class C { ... };
2006 // so rewrite it as such.
2008 Expect(Token::CLASS, CHECK_OK);
2009 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
2010 ReportMessage("sloppy_lexical");
2015 int pos = position();
2016 bool is_strict_reserved = false;
2017 const AstRawString* name =
2018 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
2019 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(),
2020 is_strict_reserved, pos, CHECK_OK);
2022 VariableMode mode = is_strong(language_mode()) ? CONST : LET;
2023 VariableProxy* proxy = NewUnresolved(name, mode);
2024 Declaration* declaration =
2025 factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
2026 Declare(declaration, true, CHECK_OK);
2027 proxy->var()->set_initializer_position(pos);
2029 Token::Value init_op =
2030 is_strong(language_mode()) ? Token::INIT_CONST : Token::INIT_LET;
2031 Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos);
2032 Statement* assignment_statement =
2033 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
2034 if (names) names->Add(name, zone());
2035 return assignment_statement;
2039 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) {
2040 if (allow_harmony_scoping() && is_strict(language_mode())) {
2041 return ParseScopedBlock(labels, ok);
2045 // '{' Statement* '}'
2047 // Note that a Block does not introduce a new execution scope!
2048 // (ECMA-262, 3rd, 12.2)
2050 // Construct block expecting 16 statements.
2052 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2053 Target target(&this->target_stack_, result);
2054 Expect(Token::LBRACE, CHECK_OK);
2055 while (peek() != Token::RBRACE) {
2056 Statement* stat = ParseStatement(NULL, CHECK_OK);
2057 if (stat && !stat->IsEmpty()) {
2058 result->AddStatement(stat, zone());
2061 Expect(Token::RBRACE, CHECK_OK);
2066 Block* Parser::ParseScopedBlock(ZoneList<const AstRawString*>* labels,
2068 // The harmony mode uses block elements instead of statements.
2071 // '{' StatementList '}'
2073 // Construct block expecting 16 statements.
2075 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2076 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
2078 // Parse the statements and collect escaping labels.
2079 Expect(Token::LBRACE, CHECK_OK);
2080 block_scope->set_start_position(scanner()->location().beg_pos);
2081 { BlockState block_state(&scope_, block_scope);
2082 Target target(&this->target_stack_, body);
2084 while (peek() != Token::RBRACE) {
2085 Statement* stat = ParseStatementListItem(CHECK_OK);
2086 if (stat && !stat->IsEmpty()) {
2087 body->AddStatement(stat, zone());
2091 Expect(Token::RBRACE, CHECK_OK);
2092 block_scope->set_end_position(scanner()->location().end_pos);
2093 block_scope = block_scope->FinalizeBlockScope();
2094 body->set_scope(block_scope);
2099 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
2100 ZoneList<const AstRawString*>* names,
2102 // VariableStatement ::
2103 // VariableDeclarations ';'
2105 const AstRawString* ignore;
2107 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK);
2108 ExpectSemicolon(CHECK_OK);
2113 // If the variable declaration declares exactly one non-const
2114 // variable, then *out is set to that variable. In all other cases,
2115 // *out is untouched; in particular, it is the caller's responsibility
2116 // to initialize it properly. This mechanism is used for the parsing
2117 // of 'for-in' loops.
2118 Block* Parser::ParseVariableDeclarations(
2119 VariableDeclarationContext var_context,
2120 VariableDeclarationProperties* decl_props,
2121 ZoneList<const AstRawString*>* names,
2122 const AstRawString** out,
2124 // VariableDeclarations ::
2125 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
2127 // The ES6 Draft Rev3 specifies the following grammar for const declarations
2129 // ConstDeclaration ::
2130 // const ConstBinding (',' ConstBinding)* ';'
2132 // Identifier '=' AssignmentExpression
2136 // BindingPattern '=' AssignmentExpression
2138 int pos = peek_position();
2139 VariableMode mode = VAR;
2140 // True if the binding needs initialization. 'let' and 'const' declared
2141 // bindings are created uninitialized by their declaration nodes and
2142 // need initialization. 'var' declared bindings are always initialized
2143 // immediately by their declaration nodes.
2144 bool needs_init = false;
2145 bool is_const = false;
2146 Token::Value init_op = Token::INIT_VAR;
2147 if (peek() == Token::VAR) {
2148 if (is_strong(language_mode())) {
2149 Scanner::Location location = scanner()->peek_location();
2150 ReportMessageAt(location, "strong_var");
2154 Consume(Token::VAR);
2155 } else if (peek() == Token::CONST) {
2156 Consume(Token::CONST);
2157 if (is_sloppy(language_mode())) {
2158 mode = CONST_LEGACY;
2159 init_op = Token::INIT_CONST_LEGACY;
2161 DCHECK(var_context != kStatement);
2162 // In ES5 const is not allowed in strict mode.
2163 if (!allow_harmony_scoping()) {
2164 ReportMessage("strict_const");
2169 init_op = Token::INIT_CONST;
2173 } else if (peek() == Token::LET && is_strict(language_mode())) {
2174 DCHECK(allow_harmony_scoping());
2175 Consume(Token::LET);
2176 DCHECK(var_context != kStatement);
2179 init_op = Token::INIT_LET;
2181 UNREACHABLE(); // by current callers
2184 Scope* declaration_scope = DeclarationScope(mode);
2186 // The scope of a var/const declared variable anywhere inside a function
2187 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
2188 // transform a source-level var/const declaration into a (Function)
2189 // Scope declaration, and rewrite the source-level initialization into an
2190 // assignment statement. We use a block to collect multiple assignments.
2192 // We mark the block as initializer block because we don't want the
2193 // rewriter to add a '.result' assignment to such a block (to get compliant
2194 // behavior for code such as print(eval('var x = 7')), and for cosmetic
2195 // reasons when pretty-printing. Also, unless an assignment (initialization)
2196 // is inside an initializer block, it is ignored.
2198 // Create new block with one expected declaration.
2199 Block* block = factory()->NewBlock(NULL, 1, true, pos);
2200 int nvars = 0; // the number of variables declared
2201 const AstRawString* name = NULL;
2202 bool is_for_iteration_variable;
2204 if (fni_ != NULL) fni_->Enter();
2206 // Parse variable name.
2207 if (nvars > 0) Consume(Token::COMMA);
2208 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
2209 if (fni_ != NULL) fni_->PushVariableName(name);
2211 // Declare variable.
2212 // Note that we *always* must treat the initial value via a separate init
2213 // assignment for variables and constants because the value must be assigned
2214 // when the variable is encountered in the source. But the variable/constant
2215 // is declared (and set to 'undefined') upon entering the function within
2216 // which the variable or constant is declared. Only function variables have
2217 // an initial value in the declaration (because they are initialized upon
2218 // entering the function).
2220 // If we have a const declaration, in an inner scope, the proxy is always
2221 // bound to the declared variable (independent of possibly surrounding with
2223 // For let/const declarations in harmony mode, we can also immediately
2224 // pre-resolve the proxy because it resides in the same scope as the
2226 is_for_iteration_variable =
2227 var_context == kForStatement &&
2228 (peek() == Token::IN || PeekContextualKeyword(CStrVector("of")));
2229 if (is_for_iteration_variable && mode == CONST) {
2233 VariableProxy* proxy = NewUnresolved(name, mode);
2234 Declaration* declaration =
2235 factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
2236 Declare(declaration, mode != VAR, CHECK_OK);
2238 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
2239 ReportMessage("too_many_variables");
2243 if (names) names->Add(name, zone());
2245 // Parse initialization expression if present and/or needed. A
2246 // declaration of the form:
2250 // is syntactic sugar for:
2254 // In particular, we need to re-lookup 'v' (in scope_, not
2255 // declaration_scope) as it may be a different 'v' than the 'v' in the
2256 // declaration (e.g., if we are inside a 'with' statement or 'catch'
2259 // However, note that const declarations are different! A const
2260 // declaration of the form:
2264 // is *not* syntactic sugar for:
2268 // The "variable" c initialized to x is the same as the declared
2269 // one - there is no re-lookup (see the last parameter of the
2270 // Declare() call above).
2272 Scope* initialization_scope = is_const ? declaration_scope : scope_;
2273 Expression* value = NULL;
2275 // Harmony consts have non-optional initializers.
2276 if (peek() == Token::ASSIGN ||
2277 (mode == CONST && !is_for_iteration_variable)) {
2278 Expect(Token::ASSIGN, CHECK_OK);
2280 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
2281 // Don't infer if it is "a = function(){...}();"-like expression.
2283 value->AsCall() == NULL &&
2284 value->AsCallNew() == NULL) {
2287 fni_->RemoveLastFunction();
2289 if (decl_props != NULL) *decl_props = kHasInitializers;
2292 // Record the end position of the initializer.
2293 if (proxy->is_resolved()) {
2294 proxy->var()->set_initializer_position(position());
2297 // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
2298 if (value == NULL && needs_init) {
2299 value = GetLiteralUndefined(position());
2302 // Global variable declarations must be compiled in a specific
2303 // way. When the script containing the global variable declaration
2304 // is entered, the global variable must be declared, so that if it
2305 // doesn't exist (on the global object itself, see ES5 errata) it
2306 // gets created with an initial undefined value. This is handled
2307 // by the declarations part of the function representing the
2308 // top-level global code; see Runtime::DeclareGlobalVariable. If
2309 // it already exists (in the object or in a prototype), it is
2310 // *not* touched until the variable declaration statement is
2313 // Executing the variable declaration statement will always
2314 // guarantee to give the global object an own property.
2315 // This way, global variable declarations can shadow
2316 // properties in the prototype chain, but only after the variable
2317 // declaration statement has been executed. This is important in
2318 // browsers where the global object (window) has lots of
2319 // properties defined in prototype objects.
2320 if (initialization_scope->is_script_scope() &&
2321 !IsLexicalVariableMode(mode)) {
2322 // Compute the arguments for the runtime call.
2323 ZoneList<Expression*>* arguments =
2324 new(zone()) ZoneList<Expression*>(3, zone());
2325 // We have at least 1 parameter.
2326 arguments->Add(factory()->NewStringLiteral(name, pos), zone());
2327 CallRuntime* initialize;
2330 arguments->Add(value, zone());
2331 value = NULL; // zap the value to avoid the unnecessary assignment
2333 // Construct the call to Runtime_InitializeConstGlobal
2334 // and add it to the initialization statement block.
2335 // Note that the function does different things depending on
2336 // the number of arguments (1 or 2).
2337 initialize = factory()->NewCallRuntime(
2338 ast_value_factory()->initialize_const_global_string(),
2339 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), arguments,
2342 // Add language mode.
2343 // We may want to pass singleton to avoid Literal allocations.
2344 LanguageMode language_mode = initialization_scope->language_mode();
2345 arguments->Add(factory()->NewNumberLiteral(language_mode, pos), zone());
2347 // Be careful not to assign a value to the global variable if
2348 // we're in a with. The initialization value should not
2349 // necessarily be stored in the global object in that case,
2350 // which is why we need to generate a separate assignment node.
2351 if (value != NULL && !inside_with()) {
2352 arguments->Add(value, zone());
2353 value = NULL; // zap the value to avoid the unnecessary assignment
2354 // Construct the call to Runtime_InitializeVarGlobal
2355 // and add it to the initialization statement block.
2356 initialize = factory()->NewCallRuntime(
2357 ast_value_factory()->initialize_var_global_string(),
2358 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), arguments,
2365 if (initialize != NULL) {
2366 block->AddStatement(factory()->NewExpressionStatement(
2367 initialize, RelocInfo::kNoPosition),
2370 } else if (needs_init) {
2371 // Constant initializations always assign to the declared constant which
2372 // is always at the function scope level. This is only relevant for
2373 // dynamically looked-up variables and constants (the start context for
2374 // constant lookups is always the function context, while it is the top
2375 // context for var declared variables). Sigh...
2376 // For 'let' and 'const' declared variables in harmony mode the
2377 // initialization also always assigns to the declared variable.
2378 DCHECK(proxy != NULL);
2379 DCHECK(proxy->var() != NULL);
2380 DCHECK(value != NULL);
2381 Assignment* assignment =
2382 factory()->NewAssignment(init_op, proxy, value, pos);
2383 block->AddStatement(
2384 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
2389 // Add an assignment node to the initialization statement block if we still
2390 // have a pending initialization value.
2391 if (value != NULL) {
2392 DCHECK(mode == VAR);
2393 // 'var' initializations are simply assignments (with all the consequences
2394 // if they are inside a 'with' statement - they may change a 'with' object
2396 VariableProxy* proxy =
2397 initialization_scope->NewUnresolved(factory(), name);
2398 Assignment* assignment =
2399 factory()->NewAssignment(init_op, proxy, value, pos);
2400 block->AddStatement(
2401 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
2405 if (fni_ != NULL) fni_->Leave();
2406 } while (peek() == Token::COMMA);
2408 // If there was a single non-const declaration, return it in the output
2409 // parameter for possible use by for/in.
2410 if (nvars == 1 && (!is_const || is_for_iteration_variable)) {
2418 static bool ContainsLabel(ZoneList<const AstRawString*>* labels,
2419 const AstRawString* label) {
2420 DCHECK(label != NULL);
2421 if (labels != NULL) {
2422 for (int i = labels->length(); i-- > 0; ) {
2423 if (labels->at(i) == label) {
2432 Statement* Parser::ParseExpressionOrLabelledStatement(
2433 ZoneList<const AstRawString*>* labels, bool* ok) {
2434 // ExpressionStatement | LabelledStatement ::
2436 // Identifier ':' Statement
2438 // ExpressionStatement[Yield] :
2439 // [lookahead ∉ {{, function, class, let [}] Expression[In, ?Yield] ;
2442 case Token::FUNCTION:
2444 UNREACHABLE(); // Always handled by the callers.
2446 ReportUnexpectedToken(Next());
2450 // TODO(arv): Handle `let [`
2451 // https://code.google.com/p/v8/issues/detail?id=3847
2457 int pos = peek_position();
2458 bool starts_with_idenfifier = peek_any_identifier();
2459 Expression* expr = ParseExpression(true, CHECK_OK);
2460 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
2461 expr->AsVariableProxy() != NULL &&
2462 !expr->AsVariableProxy()->is_this()) {
2463 // Expression is a single identifier, and not, e.g., a parenthesized
2465 VariableProxy* var = expr->AsVariableProxy();
2466 const AstRawString* label = var->raw_name();
2467 // TODO(1240780): We don't check for redeclaration of labels
2468 // during preparsing since keeping track of the set of active
2469 // labels requires nontrivial changes to the way scopes are
2470 // structured. However, these are probably changes we want to
2471 // make later anyway so we should go back and fix this then.
2472 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
2473 ParserTraits::ReportMessage("label_redeclaration", label);
2477 if (labels == NULL) {
2478 labels = new(zone()) ZoneList<const AstRawString*>(4, zone());
2480 labels->Add(label, zone());
2481 // Remove the "ghost" variable that turned out to be a label
2482 // from the top scope. This way, we don't try to resolve it
2483 // during the scope processing.
2484 scope_->RemoveUnresolved(var);
2485 Expect(Token::COLON, CHECK_OK);
2486 return ParseStatement(labels, ok);
2489 // If we have an extension, we allow a native function declaration.
2490 // A native function declaration starts with "native function" with
2491 // no line-terminator between the two words.
2492 if (extension_ != NULL && peek() == Token::FUNCTION &&
2493 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL &&
2494 expr->AsVariableProxy() != NULL &&
2495 expr->AsVariableProxy()->raw_name() ==
2496 ast_value_factory()->native_string() &&
2497 !scanner()->literal_contains_escapes()) {
2498 return ParseNativeDeclaration(ok);
2501 // Parsed expression statement, followed by semicolon.
2502 // Detect attempts at 'let' declarations in sloppy mode.
2503 if (peek() == Token::IDENTIFIER && expr->AsVariableProxy() != NULL &&
2504 expr->AsVariableProxy()->raw_name() ==
2505 ast_value_factory()->let_string()) {
2506 ReportMessage("sloppy_lexical", NULL);
2510 ExpectSemicolon(CHECK_OK);
2511 return factory()->NewExpressionStatement(expr, pos);
2515 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels,
2518 // 'if' '(' Expression ')' Statement ('else' Statement)?
2520 int pos = peek_position();
2521 Expect(Token::IF, CHECK_OK);
2522 Expect(Token::LPAREN, CHECK_OK);
2523 Expression* condition = ParseExpression(true, CHECK_OK);
2524 Expect(Token::RPAREN, CHECK_OK);
2525 Statement* then_statement = ParseSubStatement(labels, CHECK_OK);
2526 Statement* else_statement = NULL;
2527 if (peek() == Token::ELSE) {
2529 else_statement = ParseSubStatement(labels, CHECK_OK);
2531 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2533 return factory()->NewIfStatement(
2534 condition, then_statement, else_statement, pos);
2538 Statement* Parser::ParseContinueStatement(bool* ok) {
2539 // ContinueStatement ::
2540 // 'continue' Identifier? ';'
2542 int pos = peek_position();
2543 Expect(Token::CONTINUE, CHECK_OK);
2544 const AstRawString* label = NULL;
2545 Token::Value tok = peek();
2546 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2547 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2548 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2549 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
2551 IterationStatement* target = LookupContinueTarget(label, CHECK_OK);
2552 if (target == NULL) {
2553 // Illegal continue statement.
2554 const char* message = "illegal_continue";
2555 if (label != NULL) {
2556 message = "unknown_label";
2558 ParserTraits::ReportMessage(message, label);
2562 ExpectSemicolon(CHECK_OK);
2563 return factory()->NewContinueStatement(target, pos);
2567 Statement* Parser::ParseBreakStatement(ZoneList<const AstRawString*>* labels,
2569 // BreakStatement ::
2570 // 'break' Identifier? ';'
2572 int pos = peek_position();
2573 Expect(Token::BREAK, CHECK_OK);
2574 const AstRawString* label = NULL;
2575 Token::Value tok = peek();
2576 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2577 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2578 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2579 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
2581 // Parse labeled break statements that target themselves into
2582 // empty statements, e.g. 'l1: l2: l3: break l2;'
2583 if (label != NULL && ContainsLabel(labels, label)) {
2584 ExpectSemicolon(CHECK_OK);
2585 return factory()->NewEmptyStatement(pos);
2587 BreakableStatement* target = NULL;
2588 target = LookupBreakTarget(label, CHECK_OK);
2589 if (target == NULL) {
2590 // Illegal break statement.
2591 const char* message = "illegal_break";
2592 if (label != NULL) {
2593 message = "unknown_label";
2595 ParserTraits::ReportMessage(message, label);
2599 ExpectSemicolon(CHECK_OK);
2600 return factory()->NewBreakStatement(target, pos);
2604 Statement* Parser::ParseReturnStatement(bool* ok) {
2605 // ReturnStatement ::
2606 // 'return' Expression? ';'
2608 // Consume the return token. It is necessary to do that before
2609 // reporting any errors on it, because of the way errors are
2610 // reported (underlining).
2611 Expect(Token::RETURN, CHECK_OK);
2612 Scanner::Location loc = scanner()->location();
2614 Token::Value tok = peek();
2616 Expression* return_value;
2617 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
2618 tok == Token::SEMICOLON ||
2619 tok == Token::RBRACE ||
2620 tok == Token::EOS) {
2621 if (IsSubclassConstructor(function_state_->kind())) {
2622 return_value = ThisExpression(scope_, factory(), loc.beg_pos);
2624 return_value = GetLiteralUndefined(position());
2627 return_value = ParseExpression(true, CHECK_OK);
2629 ExpectSemicolon(CHECK_OK);
2631 if (is_generator()) {
2632 Expression* generator = factory()->NewVariableProxy(
2633 function_state_->generator_object_variable());
2634 Expression* yield = factory()->NewYield(
2635 generator, return_value, Yield::kFinal, loc.beg_pos);
2636 result = factory()->NewExpressionStatement(yield, loc.beg_pos);
2638 result = factory()->NewReturnStatement(return_value, loc.beg_pos);
2641 Scope* decl_scope = scope_->DeclarationScope();
2642 if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) {
2643 ReportMessageAt(loc, "illegal_return");
2651 Statement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels,
2654 // 'with' '(' Expression ')' Statement
2656 Expect(Token::WITH, CHECK_OK);
2657 int pos = position();
2659 if (is_strict(language_mode())) {
2660 ReportMessage("strict_mode_with");
2665 Expect(Token::LPAREN, CHECK_OK);
2666 Expression* expr = ParseExpression(true, CHECK_OK);
2667 Expect(Token::RPAREN, CHECK_OK);
2669 scope_->DeclarationScope()->RecordWithStatement();
2670 Scope* with_scope = NewScope(scope_, WITH_SCOPE);
2672 { BlockState block_state(&scope_, with_scope);
2673 with_scope->set_start_position(scanner()->peek_location().beg_pos);
2674 stmt = ParseSubStatement(labels, CHECK_OK);
2675 with_scope->set_end_position(scanner()->location().end_pos);
2677 return factory()->NewWithStatement(with_scope, expr, stmt, pos);
2681 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
2683 // 'case' Expression ':' Statement*
2684 // 'default' ':' Statement*
2686 Expression* label = NULL; // NULL expression indicates default case
2687 if (peek() == Token::CASE) {
2688 Expect(Token::CASE, CHECK_OK);
2689 label = ParseExpression(true, CHECK_OK);
2691 Expect(Token::DEFAULT, CHECK_OK);
2692 if (*default_seen_ptr) {
2693 ReportMessage("multiple_defaults_in_switch");
2697 *default_seen_ptr = true;
2699 Expect(Token::COLON, CHECK_OK);
2700 int pos = position();
2701 ZoneList<Statement*>* statements =
2702 new(zone()) ZoneList<Statement*>(5, zone());
2703 while (peek() != Token::CASE &&
2704 peek() != Token::DEFAULT &&
2705 peek() != Token::RBRACE) {
2706 Statement* stat = ParseStatement(NULL, CHECK_OK);
2707 statements->Add(stat, zone());
2710 return factory()->NewCaseClause(label, statements, pos);
2714 SwitchStatement* Parser::ParseSwitchStatement(
2715 ZoneList<const AstRawString*>* labels, bool* ok) {
2716 // SwitchStatement ::
2717 // 'switch' '(' Expression ')' '{' CaseClause* '}'
2719 SwitchStatement* statement =
2720 factory()->NewSwitchStatement(labels, peek_position());
2721 Target target(&this->target_stack_, statement);
2723 Expect(Token::SWITCH, CHECK_OK);
2724 Expect(Token::LPAREN, CHECK_OK);
2725 Expression* tag = ParseExpression(true, CHECK_OK);
2726 Expect(Token::RPAREN, CHECK_OK);
2728 bool default_seen = false;
2729 ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4, zone());
2730 Expect(Token::LBRACE, CHECK_OK);
2731 while (peek() != Token::RBRACE) {
2732 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
2733 cases->Add(clause, zone());
2735 Expect(Token::RBRACE, CHECK_OK);
2737 if (statement) statement->Initialize(tag, cases);
2742 Statement* Parser::ParseThrowStatement(bool* ok) {
2743 // ThrowStatement ::
2744 // 'throw' Expression ';'
2746 Expect(Token::THROW, CHECK_OK);
2747 int pos = position();
2748 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
2749 ReportMessage("newline_after_throw");
2753 Expression* exception = ParseExpression(true, CHECK_OK);
2754 ExpectSemicolon(CHECK_OK);
2756 return factory()->NewExpressionStatement(
2757 factory()->NewThrow(exception, pos), pos);
2761 TryStatement* Parser::ParseTryStatement(bool* ok) {
2763 // 'try' Block Catch
2764 // 'try' Block Finally
2765 // 'try' Block Catch Finally
2768 // 'catch' '(' Identifier ')' Block
2773 Expect(Token::TRY, CHECK_OK);
2774 int pos = position();
2776 Block* try_block = ParseBlock(NULL, CHECK_OK);
2778 Token::Value tok = peek();
2779 if (tok != Token::CATCH && tok != Token::FINALLY) {
2780 ReportMessage("no_catch_or_finally");
2785 Scope* catch_scope = NULL;
2786 Variable* catch_variable = NULL;
2787 Block* catch_block = NULL;
2788 const AstRawString* name = NULL;
2789 if (tok == Token::CATCH) {
2790 Consume(Token::CATCH);
2792 Expect(Token::LPAREN, CHECK_OK);
2793 catch_scope = NewScope(scope_, CATCH_SCOPE);
2794 catch_scope->set_start_position(scanner()->location().beg_pos);
2795 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
2797 Expect(Token::RPAREN, CHECK_OK);
2799 catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized);
2800 BlockState block_state(&scope_, catch_scope);
2801 catch_block = ParseBlock(NULL, CHECK_OK);
2803 catch_scope->set_end_position(scanner()->location().end_pos);
2807 Block* finally_block = NULL;
2808 DCHECK(tok == Token::FINALLY || catch_block != NULL);
2809 if (tok == Token::FINALLY) {
2810 Consume(Token::FINALLY);
2811 finally_block = ParseBlock(NULL, CHECK_OK);
2814 // Simplify the AST nodes by converting:
2815 // 'try B0 catch B1 finally B2'
2817 // 'try { try B0 catch B1 } finally B2'
2819 if (catch_block != NULL && finally_block != NULL) {
2820 // If we have both, create an inner try/catch.
2821 DCHECK(catch_scope != NULL && catch_variable != NULL);
2822 int index = function_state_->NextHandlerIndex();
2823 TryCatchStatement* statement = factory()->NewTryCatchStatement(
2824 index, try_block, catch_scope, catch_variable, catch_block,
2825 RelocInfo::kNoPosition);
2826 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
2827 try_block->AddStatement(statement, zone());
2828 catch_block = NULL; // Clear to indicate it's been handled.
2831 TryStatement* result = NULL;
2832 if (catch_block != NULL) {
2833 DCHECK(finally_block == NULL);
2834 DCHECK(catch_scope != NULL && catch_variable != NULL);
2835 int index = function_state_->NextHandlerIndex();
2836 result = factory()->NewTryCatchStatement(
2837 index, try_block, catch_scope, catch_variable, catch_block, pos);
2839 DCHECK(finally_block != NULL);
2840 int index = function_state_->NextHandlerIndex();
2841 result = factory()->NewTryFinallyStatement(
2842 index, try_block, finally_block, pos);
2849 DoWhileStatement* Parser::ParseDoWhileStatement(
2850 ZoneList<const AstRawString*>* labels, bool* ok) {
2852 // 'do' Statement 'while' '(' Expression ')' ';'
2854 DoWhileStatement* loop =
2855 factory()->NewDoWhileStatement(labels, peek_position());
2856 Target target(&this->target_stack_, loop);
2858 Expect(Token::DO, CHECK_OK);
2859 Statement* body = ParseSubStatement(NULL, CHECK_OK);
2860 Expect(Token::WHILE, CHECK_OK);
2861 Expect(Token::LPAREN, CHECK_OK);
2863 Expression* cond = ParseExpression(true, CHECK_OK);
2864 Expect(Token::RPAREN, CHECK_OK);
2866 // Allow do-statements to be terminated with and without
2867 // semi-colons. This allows code such as 'do;while(0)return' to
2868 // parse, which would not be the case if we had used the
2869 // ExpectSemicolon() functionality here.
2870 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
2872 if (loop != NULL) loop->Initialize(cond, body);
2877 WhileStatement* Parser::ParseWhileStatement(
2878 ZoneList<const AstRawString*>* labels, bool* ok) {
2879 // WhileStatement ::
2880 // 'while' '(' Expression ')' Statement
2882 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position());
2883 Target target(&this->target_stack_, loop);
2885 Expect(Token::WHILE, CHECK_OK);
2886 Expect(Token::LPAREN, CHECK_OK);
2887 Expression* cond = ParseExpression(true, CHECK_OK);
2888 Expect(Token::RPAREN, CHECK_OK);
2889 Statement* body = ParseSubStatement(NULL, CHECK_OK);
2891 if (loop != NULL) loop->Initialize(cond, body);
2896 void Parser::InitializeForEachStatement(ForEachStatement* stmt,
2898 Expression* subject,
2900 ForOfStatement* for_of = stmt->AsForOfStatement();
2902 if (for_of != NULL) {
2903 Variable* iterator = scope_->DeclarationScope()->NewTemporary(
2904 ast_value_factory()->dot_iterator_string());
2905 Variable* result = scope_->DeclarationScope()->NewTemporary(
2906 ast_value_factory()->dot_result_string());
2908 Expression* assign_iterator;
2909 Expression* next_result;
2910 Expression* result_done;
2911 Expression* assign_each;
2913 // var iterator = subject[Symbol.iterator]();
2914 assign_iterator = factory()->NewAssignment(
2915 Token::ASSIGN, factory()->NewVariableProxy(iterator),
2916 GetIterator(subject, factory()), subject->position());
2918 // var result = iterator.next();
2920 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
2921 Expression* next_literal = factory()->NewStringLiteral(
2922 ast_value_factory()->next_string(), RelocInfo::kNoPosition);
2923 Expression* next_property = factory()->NewProperty(
2924 iterator_proxy, next_literal, RelocInfo::kNoPosition);
2925 ZoneList<Expression*>* next_arguments =
2926 new(zone()) ZoneList<Expression*>(0, zone());
2927 Expression* next_call = factory()->NewCall(next_property, next_arguments,
2928 subject->position());
2929 Expression* result_proxy = factory()->NewVariableProxy(result);
2930 next_result = factory()->NewAssignment(Token::ASSIGN, result_proxy,
2931 next_call, subject->position());
2936 Expression* done_literal = factory()->NewStringLiteral(
2937 ast_value_factory()->done_string(), RelocInfo::kNoPosition);
2938 Expression* result_proxy = factory()->NewVariableProxy(result);
2939 result_done = factory()->NewProperty(
2940 result_proxy, done_literal, RelocInfo::kNoPosition);
2943 // each = result.value
2945 Expression* value_literal = factory()->NewStringLiteral(
2946 ast_value_factory()->value_string(), RelocInfo::kNoPosition);
2947 Expression* result_proxy = factory()->NewVariableProxy(result);
2948 Expression* result_value = factory()->NewProperty(
2949 result_proxy, value_literal, RelocInfo::kNoPosition);
2950 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value,
2954 for_of->Initialize(each, subject, body,
2960 stmt->Initialize(each, subject, body);
2965 Statement* Parser::DesugarLetBindingsInForStatement(
2966 Scope* inner_scope, ZoneList<const AstRawString*>* names,
2967 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
2968 Statement* body, bool* ok) {
2969 // ES6 13.6.3.4 specifies that on each loop iteration the let variables are
2970 // copied into a new environment. After copying, the "next" statement of the
2971 // loop is executed to update the loop variables. The loop condition is
2972 // checked and the loop body is executed.
2974 // We rewrite a for statement of the form
2976 // labels: for (let x = i; cond; next) body
2984 // outer: for (;;) {
2986 // if (first == 1) {
2992 // labels: for (; flag == 1; flag = 0, temp_x = x) {
3005 DCHECK(names->length() > 0);
3006 Scope* for_scope = scope_;
3007 ZoneList<Variable*> temps(names->length(), zone());
3009 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false,
3010 RelocInfo::kNoPosition);
3012 // Add statement: let x = i.
3013 outer_block->AddStatement(init, zone());
3015 const AstRawString* temp_name = ast_value_factory()->dot_for_string();
3017 // For each let variable x:
3018 // make statement: temp_x = x.
3019 for (int i = 0; i < names->length(); i++) {
3020 VariableProxy* proxy = NewUnresolved(names->at(i), LET);
3021 Variable* temp = scope_->DeclarationScope()->NewTemporary(temp_name);
3022 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
3023 Assignment* assignment = factory()->NewAssignment(
3024 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3025 Statement* assignment_statement = factory()->NewExpressionStatement(
3026 assignment, RelocInfo::kNoPosition);
3027 outer_block->AddStatement(assignment_statement, zone());
3028 temps.Add(temp, zone());
3031 Variable* first = NULL;
3032 // Make statement: first = 1.
3034 first = scope_->DeclarationScope()->NewTemporary(temp_name);
3035 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3036 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3037 Assignment* assignment = factory()->NewAssignment(
3038 Token::ASSIGN, first_proxy, const1, RelocInfo::kNoPosition);
3039 Statement* assignment_statement =
3040 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3041 outer_block->AddStatement(assignment_statement, zone());
3044 // Make statement: outer: for (;;)
3045 // Note that we don't actually create the label, or set this loop up as an
3046 // explicit break target, instead handing it directly to those nodes that
3047 // need to know about it. This should be safe because we don't run any code
3048 // in this function that looks up break targets.
3049 ForStatement* outer_loop =
3050 factory()->NewForStatement(NULL, RelocInfo::kNoPosition);
3051 outer_block->AddStatement(outer_loop, zone());
3053 outer_block->set_scope(for_scope);
3054 scope_ = inner_scope;
3056 Block* inner_block = factory()->NewBlock(NULL, names->length() + 4, false,
3057 RelocInfo::kNoPosition);
3058 int pos = scanner()->location().beg_pos;
3059 ZoneList<Variable*> inner_vars(names->length(), zone());
3061 // For each let variable x:
3062 // make statement: let x = temp_x.
3063 for (int i = 0; i < names->length(); i++) {
3064 VariableProxy* proxy = NewUnresolved(names->at(i), LET);
3065 Declaration* declaration =
3066 factory()->NewVariableDeclaration(proxy, LET, scope_, pos);
3067 Declare(declaration, true, CHECK_OK);
3068 inner_vars.Add(declaration->proxy()->var(), zone());
3069 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3070 Assignment* assignment = factory()->NewAssignment(
3071 Token::INIT_LET, proxy, temp_proxy, pos);
3072 Statement* assignment_statement = factory()->NewExpressionStatement(
3074 proxy->var()->set_initializer_position(pos);
3075 inner_block->AddStatement(assignment_statement, zone());
3078 // Make statement: if (first == 1) { first = 0; } else { next; }
3081 Expression* compare = NULL;
3082 // Make compare expression: first == 1.
3084 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3085 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3087 factory()->NewCompareOperation(Token::EQ, first_proxy, const1, pos);
3089 Statement* clear_first = NULL;
3090 // Make statement: first = 0.
3092 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3093 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3094 Assignment* assignment = factory()->NewAssignment(
3095 Token::ASSIGN, first_proxy, const0, RelocInfo::kNoPosition);
3097 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3099 Statement* clear_first_or_next = factory()->NewIfStatement(
3100 compare, clear_first, next, RelocInfo::kNoPosition);
3101 inner_block->AddStatement(clear_first_or_next, zone());
3104 Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name);
3105 // Make statement: flag = 1.
3107 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3108 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3109 Assignment* assignment = factory()->NewAssignment(
3110 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
3111 Statement* assignment_statement =
3112 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3113 inner_block->AddStatement(assignment_statement, zone());
3116 // Make cond expression for main loop: flag == 1.
3117 Expression* flag_cond = NULL;
3119 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3120 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3122 factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, pos);
3125 // Create chain of expressions "flag = 0, temp_x = x, ..."
3126 Statement* compound_next_statement = NULL;
3128 Expression* compound_next = NULL;
3129 // Make expression: flag = 0.
3131 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3132 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3133 compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
3134 const0, RelocInfo::kNoPosition);
3137 // Make the comma-separated list of temp_x = x assignments.
3138 for (int i = 0; i < names->length(); i++) {
3139 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3140 VariableProxy* proxy = factory()->NewVariableProxy(inner_vars.at(i), pos);
3141 Assignment* assignment = factory()->NewAssignment(
3142 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3143 compound_next = factory()->NewBinaryOperation(
3144 Token::COMMA, compound_next, assignment, RelocInfo::kNoPosition);
3147 compound_next_statement = factory()->NewExpressionStatement(
3148 compound_next, RelocInfo::kNoPosition);
3151 // Make statement: if (cond) { body; } else { break outer; }
3152 Statement* body_or_stop = body;
3155 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3157 factory()->NewIfStatement(cond, body, stop, cond->position());
3160 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
3161 // Note that we re-use the original loop node, which retains it labels
3162 // and ensures that any break or continue statements in body point to
3164 loop->Initialize(NULL, flag_cond, compound_next_statement, body_or_stop);
3165 inner_block->AddStatement(loop, zone());
3167 // Make statement: if (flag == 1) { break; }
3169 Expression* compare = NULL;
3170 // Make compare expresion: flag == 1.
3172 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3173 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3175 factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, pos);
3178 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3179 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
3180 Statement* if_flag_break =
3181 factory()->NewIfStatement(compare, stop, empty, RelocInfo::kNoPosition);
3182 inner_block->AddStatement(if_flag_break, zone());
3185 inner_scope->set_end_position(scanner()->location().end_pos);
3186 inner_block->set_scope(inner_scope);
3189 outer_loop->Initialize(NULL, NULL, NULL, inner_block);
3194 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
3197 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
3199 int stmt_pos = peek_position();
3200 Statement* init = NULL;
3201 ZoneList<const AstRawString*> let_bindings(1, zone());
3203 // Create an in-between scope for let-bound iteration variables.
3204 Scope* saved_scope = scope_;
3205 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
3208 Expect(Token::FOR, CHECK_OK);
3209 Expect(Token::LPAREN, CHECK_OK);
3210 for_scope->set_start_position(scanner()->location().beg_pos);
3211 bool is_let_identifier_expression = false;
3212 if (peek() != Token::SEMICOLON) {
3213 if (peek() == Token::VAR ||
3214 (peek() == Token::CONST && is_sloppy(language_mode()))) {
3215 const AstRawString* name = NULL;
3216 VariableDeclarationProperties decl_props = kHasNoInitializers;
3217 Block* variable_statement =
3218 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
3220 bool accept_OF = decl_props == kHasNoInitializers;
3221 ForEachStatement::VisitMode mode;
3222 int each_pos = position();
3224 if (name != NULL && CheckInOrOf(accept_OF, &mode, ok)) {
3225 if (!*ok) return nullptr;
3226 ForEachStatement* loop =
3227 factory()->NewForEachStatement(mode, labels, stmt_pos);
3228 Target target(&this->target_stack_, loop);
3230 Expression* enumerable = ParseExpression(true, CHECK_OK);
3231 Expect(Token::RPAREN, CHECK_OK);
3233 VariableProxy* each = scope_->NewUnresolved(factory(), name, each_pos);
3234 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3235 InitializeForEachStatement(loop, each, enumerable, body);
3237 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3238 result->AddStatement(variable_statement, zone());
3239 result->AddStatement(loop, zone());
3240 scope_ = saved_scope;
3241 for_scope->set_end_position(scanner()->location().end_pos);
3242 for_scope = for_scope->FinalizeBlockScope();
3243 DCHECK(for_scope == NULL);
3244 // Parsed for-in loop w/ variable/const declaration.
3247 init = variable_statement;
3249 } else if ((peek() == Token::LET || peek() == Token::CONST) &&
3250 is_strict(language_mode())) {
3251 bool is_const = peek() == Token::CONST;
3252 const AstRawString* name = NULL;
3253 VariableDeclarationProperties decl_props = kHasNoInitializers;
3254 Block* variable_statement =
3255 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings,
3257 bool accept_IN = name != NULL && decl_props != kHasInitializers;
3258 bool accept_OF = decl_props == kHasNoInitializers;
3259 ForEachStatement::VisitMode mode;
3260 int each_pos = position();
3262 if (accept_IN && CheckInOrOf(accept_OF, &mode, ok)) {
3263 if (!*ok) return nullptr;
3265 // Rewrite a for-in statement of the form
3267 // for (let/const x in e) b
3271 // <let x' be a temporary variable>
3278 // TODO(keuchel): Move the temporary variable to the block scope, after
3279 // implementing stack allocated block scoped variables.
3280 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3281 ast_value_factory()->dot_for_string());
3282 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp, each_pos);
3283 ForEachStatement* loop =
3284 factory()->NewForEachStatement(mode, labels, stmt_pos);
3285 Target target(&this->target_stack_, loop);
3287 // The expression does not see the loop variable.
3288 scope_ = saved_scope;
3289 Expression* enumerable = ParseExpression(true, CHECK_OK);
3291 Expect(Token::RPAREN, CHECK_OK);
3293 VariableProxy* each = scope_->NewUnresolved(factory(), name, each_pos);
3294 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3296 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3297 Token::Value init_op = is_const ? Token::INIT_CONST : Token::ASSIGN;
3298 Assignment* assignment = factory()->NewAssignment(
3299 init_op, each, temp_proxy, RelocInfo::kNoPosition);
3300 Statement* assignment_statement = factory()->NewExpressionStatement(
3301 assignment, RelocInfo::kNoPosition);
3302 body_block->AddStatement(variable_statement, zone());
3303 body_block->AddStatement(assignment_statement, zone());
3304 body_block->AddStatement(body, zone());
3305 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block);
3306 scope_ = saved_scope;
3307 for_scope->set_end_position(scanner()->location().end_pos);
3308 for_scope = for_scope->FinalizeBlockScope();
3309 body_block->set_scope(for_scope);
3310 // Parsed for-in loop w/ let declaration.
3314 init = variable_statement;
3317 Scanner::Location lhs_location = scanner()->peek_location();
3318 Expression* expression = ParseExpression(false, CHECK_OK);
3319 ForEachStatement::VisitMode mode;
3320 bool accept_OF = expression->IsVariableProxy();
3321 is_let_identifier_expression =
3322 expression->IsVariableProxy() &&
3323 expression->AsVariableProxy()->raw_name() ==
3324 ast_value_factory()->let_string();
3326 if (CheckInOrOf(accept_OF, &mode, ok)) {
3327 if (!*ok) return nullptr;
3328 expression = this->CheckAndRewriteReferenceExpression(
3329 expression, lhs_location, "invalid_lhs_in_for", CHECK_OK);
3331 ForEachStatement* loop =
3332 factory()->NewForEachStatement(mode, labels, stmt_pos);
3333 Target target(&this->target_stack_, loop);
3335 Expression* enumerable = ParseExpression(true, CHECK_OK);
3336 Expect(Token::RPAREN, CHECK_OK);
3338 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3339 InitializeForEachStatement(loop, expression, enumerable, body);
3340 scope_ = saved_scope;
3341 for_scope->set_end_position(scanner()->location().end_pos);
3342 for_scope = for_scope->FinalizeBlockScope();
3343 DCHECK(for_scope == NULL);
3344 // Parsed for-in loop.
3348 init = factory()->NewExpressionStatement(expression, position());
3353 // Standard 'for' loop
3354 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos);
3355 Target target(&this->target_stack_, loop);
3357 // Parsed initializer at this point.
3358 // Detect attempts at 'let' declarations in sloppy mode.
3359 if (peek() == Token::IDENTIFIER && is_sloppy(language_mode()) &&
3360 is_let_identifier_expression) {
3361 ReportMessage("sloppy_lexical", NULL);
3365 Expect(Token::SEMICOLON, CHECK_OK);
3367 // If there are let bindings, then condition and the next statement of the
3368 // for loop must be parsed in a new scope.
3369 Scope* inner_scope = NULL;
3370 if (let_bindings.length() > 0) {
3371 inner_scope = NewScope(for_scope, BLOCK_SCOPE);
3372 inner_scope->set_start_position(scanner()->location().beg_pos);
3373 scope_ = inner_scope;
3376 Expression* cond = NULL;
3377 if (peek() != Token::SEMICOLON) {
3378 cond = ParseExpression(true, CHECK_OK);
3380 Expect(Token::SEMICOLON, CHECK_OK);
3382 Statement* next = NULL;
3383 if (peek() != Token::RPAREN) {
3384 int next_pos = position();
3385 Expression* exp = ParseExpression(true, CHECK_OK);
3386 next = factory()->NewExpressionStatement(exp, next_pos);
3388 Expect(Token::RPAREN, CHECK_OK);
3390 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3392 Statement* result = NULL;
3393 if (let_bindings.length() > 0) {
3395 result = DesugarLetBindingsInForStatement(inner_scope, &let_bindings, loop,
3396 init, cond, next, body, CHECK_OK);
3397 scope_ = saved_scope;
3398 for_scope->set_end_position(scanner()->location().end_pos);
3400 scope_ = saved_scope;
3401 for_scope->set_end_position(scanner()->location().end_pos);
3402 for_scope = for_scope->FinalizeBlockScope();
3404 // Rewrite a for statement of the form
3405 // for (const x = i; c; n) b
3413 DCHECK(init != NULL);
3415 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3416 block->AddStatement(init, zone());
3417 block->AddStatement(loop, zone());
3418 block->set_scope(for_scope);
3419 loop->Initialize(NULL, cond, next, body);
3422 loop->Initialize(init, cond, next, body);
3430 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
3431 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
3432 // contexts this is used as a statement which invokes the debugger as i a
3433 // break point is present.
3434 // DebuggerStatement ::
3437 int pos = peek_position();
3438 Expect(Token::DEBUGGER, CHECK_OK);
3439 ExpectSemicolon(CHECK_OK);
3440 return factory()->NewDebuggerStatement(pos);
3444 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
3445 if (expression->IsLiteral()) return true;
3446 MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3447 return lit != NULL && lit->is_simple();
3451 Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate,
3452 Expression* expression) {
3453 Factory* factory = isolate->factory();
3454 DCHECK(IsCompileTimeValue(expression));
3455 Handle<FixedArray> result = factory->NewFixedArray(2, TENURED);
3456 ObjectLiteral* object_literal = expression->AsObjectLiteral();
3457 if (object_literal != NULL) {
3458 DCHECK(object_literal->is_simple());
3459 if (object_literal->fast_elements()) {
3460 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
3462 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
3464 result->set(kElementsSlot, *object_literal->constant_properties());
3466 ArrayLiteral* array_literal = expression->AsArrayLiteral();
3467 DCHECK(array_literal != NULL && array_literal->is_simple());
3468 result->set(kLiteralTypeSlot, Smi::FromInt(ARRAY_LITERAL));
3469 result->set(kElementsSlot, *array_literal->constant_elements());
3475 CompileTimeValue::LiteralType CompileTimeValue::GetLiteralType(
3476 Handle<FixedArray> value) {
3477 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot));
3478 return static_cast<LiteralType>(literal_type->value());
3482 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
3483 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
3487 bool CheckAndDeclareArrowParameter(ParserTraits* traits, Expression* expression,
3488 Scope* scope, int* num_params,
3489 Scanner::Location* dupe_loc) {
3490 // Case for empty parameter lists:
3492 if (expression == NULL) return true;
3494 // Too many parentheses around expression:
3496 if (expression->is_multi_parenthesized()) return false;
3498 // Case for a single parameter:
3501 if (expression->IsVariableProxy()) {
3502 if (expression->AsVariableProxy()->is_this()) return false;
3504 const AstRawString* raw_name = expression->AsVariableProxy()->raw_name();
3505 if (traits->IsEvalOrArguments(raw_name) ||
3506 traits->IsFutureStrictReserved(raw_name))
3509 if (scope->IsDeclared(raw_name)) {
3510 *dupe_loc = Scanner::Location(
3511 expression->position(), expression->position() + raw_name->length());
3515 scope->DeclareParameter(raw_name, VAR);
3520 // Case for more than one parameter:
3521 // (foo, bar [, ...]) => ...
3522 if (expression->IsBinaryOperation()) {
3523 BinaryOperation* binop = expression->AsBinaryOperation();
3524 if (binop->op() != Token::COMMA || binop->left()->is_parenthesized() ||
3525 binop->right()->is_parenthesized())
3528 return CheckAndDeclareArrowParameter(traits, binop->left(), scope,
3529 num_params, dupe_loc) &&
3530 CheckAndDeclareArrowParameter(traits, binop->right(), scope,
3531 num_params, dupe_loc);
3534 // Any other kind of expression is not a valid parameter list.
3539 int ParserTraits::DeclareArrowParametersFromExpression(
3540 Expression* expression, Scope* scope, Scanner::Location* dupe_loc,
3543 // Always reset the flag: It only needs to be set for the first expression
3544 // parsed as arrow function parameter list, becauseonly top-level functions
3545 // are parsed lazily.
3546 parser_->parsing_lazy_arrow_parameters_ = false;
3547 *ok = CheckAndDeclareArrowParameter(this, expression, scope, &num_params,
3553 FunctionLiteral* Parser::ParseFunctionLiteral(
3554 const AstRawString* function_name, Scanner::Location function_name_location,
3555 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos,
3556 FunctionLiteral::FunctionType function_type,
3557 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
3559 // '(' FormalParameterList? ')' '{' FunctionBody '}'
3562 // '(' ')' '{' FunctionBody '}'
3565 // '(' PropertySetParameterList ')' '{' FunctionBody '}'
3567 int pos = function_token_pos == RelocInfo::kNoPosition
3568 ? peek_position() : function_token_pos;
3570 bool is_generator = IsGeneratorFunction(kind);
3572 // Anonymous functions were passed either the empty symbol or a null
3573 // handle as the function name. Remember if we were passed a non-empty
3574 // handle to decide whether to invoke function name inference.
3575 bool should_infer_name = function_name == NULL;
3577 // We want a non-null handle as the function name.
3578 if (should_infer_name) {
3579 function_name = ast_value_factory()->empty_string();
3582 int num_parameters = 0;
3583 // Function declarations are function scoped in normal mode, so they are
3584 // hoisted. In harmony block scoping mode they are block scoped, so they
3587 // One tricky case are function declarations in a local sloppy-mode eval:
3588 // their declaration is hoisted, but they still see the local scope. E.g.,
3592 // try { throw 1 } catch (x) { eval("function g() { return x }") }
3596 // needs to return 1. To distinguish such cases, we need to detect
3597 // (1) whether a function stems from a sloppy eval, and
3598 // (2) whether it actually hoists across the eval.
3599 // Unfortunately, we do not represent sloppy eval scopes, so we do not have
3600 // either information available directly, especially not when lazily compiling
3601 // a function like 'g'. We hence rely on the following invariants:
3602 // - (1) is the case iff the innermost scope of the deserialized scope chain
3603 // under which we compile is _not_ a declaration scope. This holds because
3604 // in all normal cases, function declarations are fully hoisted to a
3605 // declaration scope and compiled relative to that.
3606 // - (2) is the case iff the current declaration scope is still the original
3607 // one relative to the deserialized scope chain. Otherwise we must be
3608 // compiling a function in an inner declaration scope in the eval, e.g. a
3609 // nested function, and hoisting works normally relative to that.
3610 Scope* declaration_scope = scope_->DeclarationScope();
3611 Scope* original_declaration_scope = original_scope_->DeclarationScope();
3613 function_type == FunctionLiteral::DECLARATION &&
3614 (!allow_harmony_scoping() || is_sloppy(language_mode())) &&
3615 (original_scope_ == original_declaration_scope ||
3616 declaration_scope != original_declaration_scope)
3617 ? NewScope(declaration_scope, FUNCTION_SCOPE, kind)
3618 : NewScope(scope_, FUNCTION_SCOPE, kind);
3619 ZoneList<Statement*>* body = NULL;
3620 int materialized_literal_count = -1;
3621 int expected_property_count = -1;
3622 int handler_count = 0;
3623 FunctionLiteral::ParameterFlag duplicate_parameters =
3624 FunctionLiteral::kNoDuplicateParameters;
3625 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
3626 ? FunctionLiteral::kIsParenthesized
3627 : FunctionLiteral::kNotParenthesized;
3628 // Parse function body.
3630 AstNodeFactory function_factory(ast_value_factory());
3631 FunctionState function_state(&function_state_, &scope_, scope, kind,
3633 scope_->SetScopeName(function_name);
3636 // For generators, allocating variables in contexts is currently a win
3637 // because it minimizes the work needed to suspend and resume an
3639 scope_->ForceContextAllocation();
3641 // Calling a generator returns a generator object. That object is stored
3642 // in a temporary variable, a definition that is used by "yield"
3643 // expressions. This also marks the FunctionState as a generator.
3644 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3645 ast_value_factory()->dot_generator_object_string());
3646 function_state.set_generator_object_variable(temp);
3649 // FormalParameterList ::
3650 // '(' (Identifier)*[','] ')'
3651 Expect(Token::LPAREN, CHECK_OK);
3652 scope->set_start_position(scanner()->location().beg_pos);
3654 // We don't yet know if the function will be strict, so we cannot yet
3655 // produce errors for parameter names or duplicates. However, we remember
3656 // the locations of these errors if they occur and produce the errors later.
3657 Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
3658 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
3659 Scanner::Location reserved_error_loc = Scanner::Location::invalid();
3661 bool is_rest = false;
3662 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY ||
3663 (peek() == Token::RPAREN &&
3664 arity_restriction != FunctionLiteral::SETTER_ARITY);
3666 bool is_strict_reserved = false;
3667 is_rest = peek() == Token::ELLIPSIS && allow_harmony_rest_params();
3669 Consume(Token::ELLIPSIS);
3672 const AstRawString* param_name =
3673 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
3675 // Store locations for possible future error reports.
3676 if (!eval_args_error_loc.IsValid() && IsEvalOrArguments(param_name)) {
3677 eval_args_error_loc = scanner()->location();
3679 if (!reserved_error_loc.IsValid() && is_strict_reserved) {
3680 reserved_error_loc = scanner()->location();
3682 if (!dupe_error_loc.IsValid() &&
3683 scope_->IsDeclaredParameter(param_name)) {
3684 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters;
3685 dupe_error_loc = scanner()->location();
3688 Variable* var = scope_->DeclareParameter(param_name, VAR, is_rest);
3689 if (is_sloppy(scope->language_mode())) {
3690 // TODO(sigurds) Mark every parameter as maybe assigned. This is a
3691 // conservative approximation necessary to account for parameters
3692 // that are assigned via the arguments array.
3693 var->set_maybe_assigned();
3697 if (num_parameters > Code::kMaxArguments) {
3698 ReportMessage("too_many_parameters");
3702 if (arity_restriction == FunctionLiteral::SETTER_ARITY) break;
3703 done = (peek() == Token::RPAREN);
3706 ReportMessageAt(scanner()->peek_location(), "param_after_rest");
3710 Expect(Token::COMMA, CHECK_OK);
3713 Expect(Token::RPAREN, CHECK_OK);
3715 Expect(Token::LBRACE, CHECK_OK);
3717 // If we have a named function expression, we add a local variable
3718 // declaration to the body of the function with the name of the
3719 // function and let it refer to the function itself (closure).
3720 // NOTE: We create a proxy and resolve it here so that in the
3721 // future we can change the AST to only refer to VariableProxies
3722 // instead of Variables and Proxis as is the case now.
3723 Variable* fvar = NULL;
3724 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY;
3725 if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
3726 if (allow_harmony_scoping() && is_strict(language_mode())) {
3727 fvar_init_op = Token::INIT_CONST;
3729 VariableMode fvar_mode =
3730 allow_harmony_scoping() && is_strict(language_mode()) ? CONST
3732 DCHECK(function_name != NULL);
3734 Variable(scope_, function_name, fvar_mode, true /* is valid LHS */,
3735 Variable::NORMAL, kCreatedInitialized, kNotAssigned);
3736 VariableProxy* proxy = factory()->NewVariableProxy(fvar);
3737 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration(
3738 proxy, fvar_mode, scope_, RelocInfo::kNoPosition);
3739 scope_->DeclareFunctionVar(fvar_declaration);
3742 // Determine if the function can be parsed lazily. Lazy parsing is different
3743 // from lazy compilation; we need to parse more eagerly than we compile.
3745 // We can only parse lazily if we also compile lazily. The heuristics for
3746 // lazy compilation are:
3747 // - It must not have been prohibited by the caller to Parse (some callers
3748 // need a full AST).
3749 // - The outer scope must allow lazy compilation of inner functions.
3750 // - The function mustn't be a function expression with an open parenthesis
3751 // before; we consider that a hint that the function will be called
3752 // immediately, and it would be a waste of time to make it lazily
3754 // These are all things we can know at this point, without looking at the
3757 // In addition, we need to distinguish between these cases:
3758 // (function foo() {
3759 // bar = function() { return 1; }
3762 // (function foo() {
3764 // bar = function() { return a; }
3767 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
3768 // parenthesis before the function means that it will be called
3769 // immediately). The inner function *must* be parsed eagerly to resolve the
3770 // possible reference to the variable in foo's scope. However, it's possible
3771 // that it will be compiled lazily.
3773 // To make this additional case work, both Parser and PreParser implement a
3774 // logic where only top-level functions will be parsed lazily.
3775 bool is_lazily_parsed = (mode() == PARSE_LAZILY &&
3776 scope_->AllowsLazyCompilation() &&
3777 !parenthesized_function_);
3778 parenthesized_function_ = false; // The bit was set for this function only.
3780 if (is_lazily_parsed) {
3781 SkipLazyFunctionBody(function_name, &materialized_literal_count,
3782 &expected_property_count, CHECK_OK);
3784 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
3786 materialized_literal_count = function_state.materialized_literal_count();
3787 expected_property_count = function_state.expected_property_count();
3788 handler_count = function_state.handler_count();
3791 // Validate name and parameter names. We can do this only after parsing the
3792 // function, since the function can declare itself strict.
3793 CheckFunctionName(language_mode(), kind, function_name,
3794 name_is_strict_reserved, function_name_location,
3796 const bool use_strict_params = is_rest || IsConciseMethod(kind);
3797 CheckFunctionParameterNames(language_mode(), use_strict_params,
3798 eval_args_error_loc, dupe_error_loc,
3799 reserved_error_loc, CHECK_OK);
3801 if (is_strict(language_mode())) {
3802 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
3805 if (allow_harmony_scoping() && is_strict(language_mode())) {
3806 CheckConflictingVarDeclarations(scope, CHECK_OK);
3810 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
3811 function_name, ast_value_factory(), scope, body,
3812 materialized_literal_count, expected_property_count, handler_count,
3813 num_parameters, duplicate_parameters, function_type,
3814 FunctionLiteral::kIsFunction, parenthesized, kind, pos);
3815 function_literal->set_function_token_position(function_token_pos);
3817 if (scope->has_rest_parameter()) {
3818 // TODO(caitp): enable optimization of functions with rest params
3819 function_literal->set_dont_optimize_reason(kRestParameter);
3822 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
3823 return function_literal;
3827 void Parser::SkipLazyFunctionBody(const AstRawString* function_name,
3828 int* materialized_literal_count,
3829 int* expected_property_count,
3831 if (produce_cached_parse_data()) CHECK(log_);
3833 int function_block_pos = position();
3834 if (consume_cached_parse_data() && !cached_parse_data_->rejected()) {
3835 // If we have cached data, we use it to skip parsing the function body. The
3836 // data contains the information we need to construct the lazy function.
3837 FunctionEntry entry =
3838 cached_parse_data_->GetFunctionEntry(function_block_pos);
3839 // Check that cached data is valid. If not, mark it as invalid (the embedder
3840 // handles it). Note that end position greater than end of stream is safe,
3841 // and hard to check.
3842 if (entry.is_valid() && entry.end_pos() > function_block_pos) {
3843 scanner()->SeekForward(entry.end_pos() - 1);
3845 scope_->set_end_position(entry.end_pos());
3846 Expect(Token::RBRACE, ok);
3850 total_preparse_skipped_ += scope_->end_position() - function_block_pos;
3851 *materialized_literal_count = entry.literal_count();
3852 *expected_property_count = entry.property_count();
3853 scope_->SetLanguageMode(entry.language_mode());
3854 if (entry.uses_super_property()) scope_->RecordSuperPropertyUsage();
3857 cached_parse_data_->Reject();
3859 // With no cached data, we partially parse the function, without building an
3860 // AST. This gathers the data needed to build a lazy function.
3861 SingletonLogger logger;
3862 PreParser::PreParseResult result =
3863 ParseLazyFunctionBodyWithPreParser(&logger);
3864 if (result == PreParser::kPreParseStackOverflow) {
3865 // Propagate stack overflow.
3866 set_stack_overflow();
3870 if (logger.has_error()) {
3871 ParserTraits::ReportMessageAt(
3872 Scanner::Location(logger.start(), logger.end()), logger.message(),
3873 logger.argument_opt(), logger.is_reference_error());
3877 scope_->set_end_position(logger.end());
3878 Expect(Token::RBRACE, ok);
3882 total_preparse_skipped_ += scope_->end_position() - function_block_pos;
3883 *materialized_literal_count = logger.literals();
3884 *expected_property_count = logger.properties();
3885 scope_->SetLanguageMode(logger.language_mode());
3886 if (logger.scope_uses_super_property()) {
3887 scope_->RecordSuperPropertyUsage();
3889 if (produce_cached_parse_data()) {
3891 // Position right after terminal '}'.
3892 int body_end = scanner()->location().end_pos;
3893 log_->LogFunction(function_block_pos, body_end, *materialized_literal_count,
3894 *expected_property_count, scope_->language_mode(),
3895 scope_->uses_super_property());
3900 void Parser::AddAssertIsConstruct(ZoneList<Statement*>* body, int pos) {
3901 ZoneList<Expression*>* arguments =
3902 new (zone()) ZoneList<Expression*>(0, zone());
3903 CallRuntime* construct_check = factory()->NewCallRuntime(
3904 ast_value_factory()->is_construct_call_string(),
3905 Runtime::FunctionForId(Runtime::kInlineIsConstructCall), arguments, pos);
3906 CallRuntime* non_callable_error = factory()->NewCallRuntime(
3907 ast_value_factory()->empty_string(),
3908 Runtime::FunctionForId(Runtime::kThrowConstructorNonCallableError),
3910 IfStatement* if_statement = factory()->NewIfStatement(
3911 factory()->NewUnaryOperation(Token::NOT, construct_check, pos),
3912 factory()->NewReturnStatement(non_callable_error, pos),
3913 factory()->NewEmptyStatement(pos), pos);
3914 body->Add(if_statement, zone());
3918 ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
3919 const AstRawString* function_name, int pos, Variable* fvar,
3920 Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
3921 // Everything inside an eagerly parsed function will be parsed eagerly
3922 // (see comment above).
3923 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
3924 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone());
3926 VariableProxy* fproxy = scope_->NewUnresolved(factory(), function_name);
3927 fproxy->BindTo(fvar);
3928 body->Add(factory()->NewExpressionStatement(
3929 factory()->NewAssignment(fvar_init_op,
3931 factory()->NewThisFunction(pos),
3932 RelocInfo::kNoPosition),
3933 RelocInfo::kNoPosition), zone());
3937 // For concise constructors, check that they are constructed,
3939 if (i::IsConstructor(kind)) {
3940 AddAssertIsConstruct(body, pos);
3943 // For generators, allocate and yield an iterator on function entry.
3944 if (IsGeneratorFunction(kind)) {
3945 ZoneList<Expression*>* arguments =
3946 new(zone()) ZoneList<Expression*>(0, zone());
3947 CallRuntime* allocation = factory()->NewCallRuntime(
3948 ast_value_factory()->empty_string(),
3949 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), arguments,
3951 VariableProxy* init_proxy = factory()->NewVariableProxy(
3952 function_state_->generator_object_variable());
3953 Assignment* assignment = factory()->NewAssignment(
3954 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
3955 VariableProxy* get_proxy = factory()->NewVariableProxy(
3956 function_state_->generator_object_variable());
3957 Yield* yield = factory()->NewYield(
3958 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition);
3959 body->Add(factory()->NewExpressionStatement(
3960 yield, RelocInfo::kNoPosition), zone());
3963 ParseStatementList(body, Token::RBRACE, false, NULL, CHECK_OK);
3965 if (IsGeneratorFunction(kind)) {
3966 VariableProxy* get_proxy = factory()->NewVariableProxy(
3967 function_state_->generator_object_variable());
3968 Expression* undefined =
3969 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition);
3970 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal,
3971 RelocInfo::kNoPosition);
3972 body->Add(factory()->NewExpressionStatement(
3973 yield, RelocInfo::kNoPosition), zone());
3976 if (IsSubclassConstructor(kind)) {
3978 factory()->NewReturnStatement(
3979 this->ThisExpression(scope_, factory(), RelocInfo::kNoPosition),
3980 RelocInfo::kNoPosition),
3984 Expect(Token::RBRACE, CHECK_OK);
3985 scope_->set_end_position(scanner()->location().end_pos);
3991 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
3992 SingletonLogger* logger) {
3993 // This function may be called on a background thread too; record only the
3994 // main thread preparse times.
3995 if (pre_parse_timer_ != NULL) {
3996 pre_parse_timer_->Start();
3998 DCHECK_EQ(Token::LBRACE, scanner()->current_token());
4000 if (reusable_preparser_ == NULL) {
4001 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(),
4002 NULL, stack_limit_);
4003 reusable_preparser_->set_allow_lazy(true);
4004 reusable_preparser_->set_allow_natives(allow_natives());
4005 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping());
4006 reusable_preparser_->set_allow_harmony_modules(allow_harmony_modules());
4007 reusable_preparser_->set_allow_harmony_arrow_functions(
4008 allow_harmony_arrow_functions());
4009 reusable_preparser_->set_allow_harmony_numeric_literals(
4010 allow_harmony_numeric_literals());
4011 reusable_preparser_->set_allow_harmony_classes(allow_harmony_classes());
4012 reusable_preparser_->set_allow_harmony_object_literals(
4013 allow_harmony_object_literals());
4014 reusable_preparser_->set_allow_harmony_templates(allow_harmony_templates());
4015 reusable_preparser_->set_allow_harmony_sloppy(allow_harmony_sloppy());
4016 reusable_preparser_->set_allow_harmony_unicode(allow_harmony_unicode());
4017 reusable_preparser_->set_allow_harmony_computed_property_names(
4018 allow_harmony_computed_property_names());
4019 reusable_preparser_->set_allow_harmony_rest_params(
4020 allow_harmony_rest_params());
4021 reusable_preparser_->set_allow_strong_mode(allow_strong_mode());
4023 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
4024 language_mode(), function_state_->kind(), logger);
4025 if (pre_parse_timer_ != NULL) {
4026 pre_parse_timer_->Stop();
4032 ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name,
4033 Scanner::Location class_name_location,
4034 bool name_is_strict_reserved, int pos,
4036 // All parts of a ClassDeclaration and ClassExpression are strict code.
4037 if (name_is_strict_reserved) {
4038 ReportMessageAt(class_name_location, "unexpected_strict_reserved");
4042 if (IsEvalOrArguments(name)) {
4043 ReportMessageAt(class_name_location, "strict_eval_arguments");
4048 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
4049 BlockState block_state(&scope_, block_scope);
4050 scope_->SetLanguageMode(
4051 static_cast<LanguageMode>(scope_->language_mode() | STRICT_BIT));
4052 scope_->SetScopeName(name);
4054 VariableProxy* proxy = NULL;
4056 proxy = NewUnresolved(name, CONST);
4057 Declaration* declaration =
4058 factory()->NewVariableDeclaration(proxy, CONST, block_scope, pos);
4059 Declare(declaration, true, CHECK_OK);
4062 Expression* extends = NULL;
4063 if (Check(Token::EXTENDS)) {
4064 block_scope->set_start_position(scanner()->location().end_pos);
4065 extends = ParseLeftHandSideExpression(CHECK_OK);
4067 block_scope->set_start_position(scanner()->location().end_pos);
4071 ClassLiteralChecker checker(this);
4072 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone());
4073 FunctionLiteral* constructor = NULL;
4074 bool has_seen_constructor = false;
4076 Expect(Token::LBRACE, CHECK_OK);
4077 const bool has_extends = extends != nullptr;
4078 while (peek() != Token::RBRACE) {
4079 if (Check(Token::SEMICOLON)) continue;
4080 if (fni_ != NULL) fni_->Enter();
4081 const bool in_class = true;
4082 const bool is_static = false;
4083 bool is_computed_name = false; // Classes do not care about computed
4084 // property names here.
4085 ObjectLiteral::Property* property = ParsePropertyDefinition(
4086 &checker, in_class, has_extends, is_static, &is_computed_name,
4087 &has_seen_constructor, CHECK_OK);
4089 if (has_seen_constructor && constructor == NULL) {
4090 constructor = GetPropertyValue(property)->AsFunctionLiteral();
4091 DCHECK_NOT_NULL(constructor);
4093 properties->Add(property, zone());
4102 Expect(Token::RBRACE, CHECK_OK);
4103 int end_pos = scanner()->location().end_pos;
4105 if (constructor == NULL) {
4107 DefaultConstructor(extends != NULL, block_scope, pos, end_pos);
4110 block_scope->set_end_position(end_pos);
4111 block_scope = block_scope->FinalizeBlockScope();
4114 DCHECK_NOT_NULL(proxy);
4115 DCHECK_NOT_NULL(block_scope);
4116 proxy->var()->set_initializer_position(end_pos);
4119 return factory()->NewClassLiteral(name, block_scope, proxy, extends,
4120 constructor, properties, pos, end_pos);
4124 Expression* Parser::ParseV8Intrinsic(bool* ok) {
4126 // '%' Identifier Arguments
4128 int pos = peek_position();
4129 Expect(Token::MOD, CHECK_OK);
4130 // Allow "eval" or "arguments" for backward compatibility.
4131 const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
4132 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
4134 if (extension_ != NULL) {
4135 // The extension structures are only accessible while parsing the
4136 // very first time not when reparsing because of lazy compilation.
4137 scope_->DeclarationScope()->ForceEagerCompilation();
4140 const Runtime::Function* function = Runtime::FunctionForName(name->string());
4142 // Check for built-in IS_VAR macro.
4143 if (function != NULL &&
4144 function->intrinsic_type == Runtime::RUNTIME &&
4145 function->function_id == Runtime::kIS_VAR) {
4146 // %IS_VAR(x) evaluates to x if x is a variable,
4147 // leads to a parse error otherwise. Could be implemented as an
4148 // inline function %_IS_VAR(x) to eliminate this special case.
4149 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
4152 ReportMessage("not_isvar");
4158 // Check that the expected number of arguments are being passed.
4159 if (function != NULL &&
4160 function->nargs != -1 &&
4161 function->nargs != args->length()) {
4162 ReportMessage("illegal_access");
4167 // Check that the function is defined if it's an inline runtime call.
4168 if (function == NULL && name->FirstCharacter() == '_') {
4169 ParserTraits::ReportMessage("not_defined", name);
4174 // We have a valid intrinsics call or a call to a builtin.
4175 return factory()->NewCallRuntime(name, function, args, pos);
4179 Literal* Parser::GetLiteralUndefined(int position) {
4180 return factory()->NewUndefinedLiteral(position);
4184 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
4185 Declaration* decl = scope->CheckConflictingVarDeclarations();
4187 // In harmony mode we treat conflicting variable bindinds as early
4188 // errors. See ES5 16 for a definition of early errors.
4189 const AstRawString* name = decl->proxy()->raw_name();
4190 int position = decl->proxy()->position();
4191 Scanner::Location location = position == RelocInfo::kNoPosition
4192 ? Scanner::Location::invalid()
4193 : Scanner::Location(position, position + 1);
4194 ParserTraits::ReportMessageAt(location, "var_redeclaration", name);
4200 // ----------------------------------------------------------------------------
4204 bool Parser::TargetStackContainsLabel(const AstRawString* label) {
4205 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4206 if (ContainsLabel(t->statement()->labels(), label)) return true;
4212 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
4214 bool anonymous = label == NULL;
4215 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4216 BreakableStatement* stat = t->statement();
4217 if ((anonymous && stat->is_target_for_anonymous()) ||
4218 (!anonymous && ContainsLabel(stat->labels(), label))) {
4226 IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
4228 bool anonymous = label == NULL;
4229 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4230 IterationStatement* stat = t->statement()->AsIterationStatement();
4231 if (stat == NULL) continue;
4233 DCHECK(stat->is_target_for_anonymous());
4234 if (anonymous || ContainsLabel(stat->labels(), label)) {
4242 void Parser::HandleSourceURLComments(CompilationInfo* info) {
4243 if (scanner_.source_url()->length() > 0) {
4244 Handle<String> source_url =
4245 scanner_.source_url()->Internalize(info->isolate());
4246 info->script()->set_source_url(*source_url);
4248 if (scanner_.source_mapping_url()->length() > 0) {
4249 Handle<String> source_mapping_url =
4250 scanner_.source_mapping_url()->Internalize(info->isolate());
4251 info->script()->set_source_mapping_url(*source_mapping_url);
4256 void Parser::ThrowPendingError(Isolate* isolate, Handle<Script> script) {
4257 DCHECK(ast_value_factory()->IsInternalized());
4258 if (has_pending_error_) {
4259 MessageLocation location(script, pending_error_location_.beg_pos,
4260 pending_error_location_.end_pos);
4261 Factory* factory = isolate->factory();
4263 pending_error_arg_ != NULL || pending_error_char_arg_ != NULL;
4264 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0);
4265 if (pending_error_arg_ != NULL) {
4266 Handle<String> arg_string = pending_error_arg_->string();
4267 elements->set(0, *arg_string);
4268 } else if (pending_error_char_arg_ != NULL) {
4269 Handle<String> arg_string =
4270 factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_))
4272 elements->set(0, *arg_string);
4274 isolate->debug()->OnCompileError(script);
4276 Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
4277 Handle<Object> error;
4278 MaybeHandle<Object> maybe_error =
4279 pending_error_is_reference_error_
4280 ? factory->NewReferenceError(pending_error_message_, array)
4281 : factory->NewSyntaxError(pending_error_message_, array);
4283 if (maybe_error.ToHandle(&error)) {
4284 Handle<JSObject> jserror = Handle<JSObject>::cast(error);
4286 Handle<Name> key_start_pos = factory->error_start_pos_symbol();
4287 JSObject::SetProperty(jserror, key_start_pos,
4288 handle(Smi::FromInt(location.start_pos()), isolate),
4291 Handle<Name> key_end_pos = factory->error_end_pos_symbol();
4292 JSObject::SetProperty(jserror, key_end_pos,
4293 handle(Smi::FromInt(location.end_pos()), isolate),
4296 Handle<Name> key_script = factory->error_script_symbol();
4297 JSObject::SetProperty(jserror, key_script, script, SLOPPY).Check();
4299 isolate->Throw(*error, &location);
4305 void Parser::Internalize(CompilationInfo* info) {
4306 // Internalize strings.
4307 ast_value_factory()->Internalize(info->isolate());
4309 // Error processing.
4310 if (info->function() == NULL) {
4311 if (stack_overflow()) {
4312 info->isolate()->StackOverflow();
4314 ThrowPendingError(info->isolate(), info->script());
4318 // Move statistics to Isolate.
4319 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
4321 for (int i = 0; i < use_counts_[feature]; ++i) {
4322 info->isolate()->CountUsage(v8::Isolate::UseCounterFeature(feature));
4325 info->isolate()->counters()->total_preparse_skipped()->Increment(
4326 total_preparse_skipped_);
4330 // ----------------------------------------------------------------------------
4331 // Regular expressions
4334 RegExpParser::RegExpParser(FlatStringReader* in, Handle<String>* error,
4335 bool multiline, bool unicode, Isolate* isolate,
4337 : isolate_(isolate),
4342 current_(kEndMarker),
4346 multiline_(multiline),
4349 contains_anchor_(false),
4350 is_scanned_for_captures_(false),
4356 uc32 RegExpParser::Next() {
4358 return in()->Get(next_pos_);
4365 void RegExpParser::Advance() {
4366 if (next_pos_ < in()->length()) {
4367 StackLimitCheck check(isolate());
4368 if (check.HasOverflowed()) {
4369 ReportError(CStrVector(Isolate::kStackOverflowMessage));
4370 } else if (zone()->excess_allocation()) {
4371 ReportError(CStrVector("Regular expression too large"));
4373 current_ = in()->Get(next_pos_);
4377 current_ = kEndMarker;
4378 // Advance so that position() points to 1-after-the-last-character. This is
4379 // important so that Reset() to this position works correctly.
4380 next_pos_ = in()->length() + 1;
4386 void RegExpParser::Reset(int pos) {
4388 has_more_ = (pos < in()->length());
4393 void RegExpParser::Advance(int dist) {
4394 next_pos_ += dist - 1;
4399 bool RegExpParser::simple() {
4404 bool RegExpParser::IsSyntaxCharacter(uc32 c) {
4405 return c == '^' || c == '$' || c == '\\' || c == '.' || c == '*' ||
4406 c == '+' || c == '?' || c == '(' || c == ')' || c == '[' || c == ']' ||
4407 c == '{' || c == '}' || c == '|';
4411 RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
4413 *error_ = isolate()->factory()->NewStringFromAscii(message).ToHandleChecked();
4414 // Zip to the end to make sure the no more input is read.
4415 current_ = kEndMarker;
4416 next_pos_ = in()->length();
4423 RegExpTree* RegExpParser::ParsePattern() {
4424 RegExpTree* result = ParseDisjunction(CHECK_FAILED);
4425 DCHECK(!has_more());
4426 // If the result of parsing is a literal string atom, and it has the
4427 // same length as the input, then the atom is identical to the input.
4428 if (result->IsAtom() && result->AsAtom()->length() == in()->length()) {
4437 // Alternative | Disjunction
4445 RegExpTree* RegExpParser::ParseDisjunction() {
4446 // Used to store current state while parsing subexpressions.
4447 RegExpParserState initial_state(NULL, INITIAL, 0, zone());
4448 RegExpParserState* stored_state = &initial_state;
4449 // Cache the builder in a local variable for quick access.
4450 RegExpBuilder* builder = initial_state.builder();
4452 switch (current()) {
4454 if (stored_state->IsSubexpression()) {
4455 // Inside a parenthesized group when hitting end of input.
4456 ReportError(CStrVector("Unterminated group") CHECK_FAILED);
4458 DCHECK_EQ(INITIAL, stored_state->group_type());
4459 // Parsing completed successfully.
4460 return builder->ToRegExp();
4462 if (!stored_state->IsSubexpression()) {
4463 ReportError(CStrVector("Unmatched ')'") CHECK_FAILED);
4465 DCHECK_NE(INITIAL, stored_state->group_type());
4468 // End disjunction parsing and convert builder content to new single
4470 RegExpTree* body = builder->ToRegExp();
4472 int end_capture_index = captures_started();
4474 int capture_index = stored_state->capture_index();
4475 SubexpressionType group_type = stored_state->group_type();
4477 // Restore previous state.
4478 stored_state = stored_state->previous_state();
4479 builder = stored_state->builder();
4481 // Build result of subexpression.
4482 if (group_type == CAPTURE) {
4483 RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index);
4484 captures_->at(capture_index - 1) = capture;
4486 } else if (group_type != GROUPING) {
4487 DCHECK(group_type == POSITIVE_LOOKAHEAD ||
4488 group_type == NEGATIVE_LOOKAHEAD);
4489 bool is_positive = (group_type == POSITIVE_LOOKAHEAD);
4490 body = new(zone()) RegExpLookahead(body,
4492 end_capture_index - capture_index,
4495 builder->AddAtom(body);
4496 // For compatability with JSC and ES3, we allow quantifiers after
4497 // lookaheads, and break in all cases.
4502 builder->NewAlternative();
4508 return ReportError(CStrVector("Nothing to repeat"));
4512 builder->AddAssertion(
4513 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE));
4515 builder->AddAssertion(
4516 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
4517 set_contains_anchor();
4523 RegExpAssertion::AssertionType assertion_type =
4524 multiline_ ? RegExpAssertion::END_OF_LINE :
4525 RegExpAssertion::END_OF_INPUT;
4526 builder->AddAssertion(new(zone()) RegExpAssertion(assertion_type));
4531 // everything except \x0a, \x0d, \u2028 and \u2029
4532 ZoneList<CharacterRange>* ranges =
4533 new(zone()) ZoneList<CharacterRange>(2, zone());
4534 CharacterRange::AddClassEscape('.', ranges, zone());
4535 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
4536 builder->AddAtom(atom);
4540 SubexpressionType subexpr_type = CAPTURE;
4542 if (current() == '?') {
4545 subexpr_type = GROUPING;
4548 subexpr_type = POSITIVE_LOOKAHEAD;
4551 subexpr_type = NEGATIVE_LOOKAHEAD;
4554 ReportError(CStrVector("Invalid group") CHECK_FAILED);
4559 if (captures_ == NULL) {
4560 captures_ = new(zone()) ZoneList<RegExpCapture*>(2, zone());
4562 if (captures_started() >= kMaxCaptures) {
4563 ReportError(CStrVector("Too many captures") CHECK_FAILED);
4565 captures_->Add(NULL, zone());
4567 // Store current state and begin new disjunction parsing.
4568 stored_state = new(zone()) RegExpParserState(stored_state, subexpr_type,
4569 captures_started(), zone());
4570 builder = stored_state->builder();
4574 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED);
4575 builder->AddAtom(atom);
4583 return ReportError(CStrVector("\\ at end of pattern"));
4586 builder->AddAssertion(
4587 new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
4591 builder->AddAssertion(
4592 new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
4595 // CharacterClassEscape
4597 // CharacterClassEscape :: one of
4599 case 'd': case 'D': case 's': case 'S': case 'w': case 'W': {
4602 ZoneList<CharacterRange>* ranges =
4603 new(zone()) ZoneList<CharacterRange>(2, zone());
4604 CharacterRange::AddClassEscape(c, ranges, zone());
4605 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
4606 builder->AddAtom(atom);
4609 case '1': case '2': case '3': case '4': case '5': case '6':
4610 case '7': case '8': case '9': {
4612 if (ParseBackReferenceIndex(&index)) {
4613 RegExpCapture* capture = NULL;
4614 if (captures_ != NULL && index <= captures_->length()) {
4615 capture = captures_->at(index - 1);
4617 if (capture == NULL) {
4618 builder->AddEmpty();
4621 RegExpTree* atom = new(zone()) RegExpBackReference(capture);
4622 builder->AddAtom(atom);
4625 uc32 first_digit = Next();
4626 if (first_digit == '8' || first_digit == '9') {
4627 // If the 'u' flag is present, only syntax characters can be escaped,
4628 // no other identity escapes are allowed. If the 'u' flag is not
4629 // present, all identity escapes are allowed.
4630 if (!FLAG_harmony_unicode_regexps || !unicode_) {
4631 builder->AddCharacter(first_digit);
4634 return ReportError(CStrVector("Invalid escape"));
4642 uc32 octal = ParseOctalLiteral();
4643 builder->AddCharacter(octal);
4646 // ControlEscape :: one of
4650 builder->AddCharacter('\f');
4654 builder->AddCharacter('\n');
4658 builder->AddCharacter('\r');
4662 builder->AddCharacter('\t');
4666 builder->AddCharacter('\v');
4670 uc32 controlLetter = Next();
4671 // Special case if it is an ASCII letter.
4672 // Convert lower case letters to uppercase.
4673 uc32 letter = controlLetter & ~('a' ^ 'A');
4674 if (letter < 'A' || 'Z' < letter) {
4675 // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
4676 // This is outside the specification. We match JSC in
4677 // reading the backslash as a literal character instead
4678 // of as starting an escape.
4679 builder->AddCharacter('\\');
4682 builder->AddCharacter(controlLetter & 0x1f);
4689 if (ParseHexEscape(2, &value)) {
4690 builder->AddCharacter(value);
4691 } else if (!FLAG_harmony_unicode_regexps || !unicode_) {
4692 builder->AddCharacter('x');
4694 // If the 'u' flag is present, invalid escapes are not treated as
4695 // identity escapes.
4696 return ReportError(CStrVector("Invalid escape"));
4703 if (ParseUnicodeEscape(&value)) {
4704 builder->AddCharacter(value);
4705 } else if (!FLAG_harmony_unicode_regexps || !unicode_) {
4706 builder->AddCharacter('u');
4708 // If the 'u' flag is present, invalid escapes are not treated as
4709 // identity escapes.
4710 return ReportError(CStrVector("Invalid unicode escape"));
4716 // If the 'u' flag is present, only syntax characters can be escaped, no
4717 // other identity escapes are allowed. If the 'u' flag is not present,
4718 // all identity escapes are allowed.
4719 if (!FLAG_harmony_unicode_regexps || !unicode_ ||
4720 IsSyntaxCharacter(current())) {
4721 builder->AddCharacter(current());
4724 return ReportError(CStrVector("Invalid escape"));
4731 if (ParseIntervalQuantifier(&dummy, &dummy)) {
4732 ReportError(CStrVector("Nothing to repeat") CHECK_FAILED);
4737 builder->AddCharacter(current());
4740 } // end switch(current())
4744 switch (current()) {
4745 // QuantifierPrefix ::
4752 max = RegExpTree::kInfinity;
4757 max = RegExpTree::kInfinity;
4766 if (ParseIntervalQuantifier(&min, &max)) {
4768 ReportError(CStrVector("numbers out of order in {} quantifier.")
4778 RegExpQuantifier::QuantifierType quantifier_type = RegExpQuantifier::GREEDY;
4779 if (current() == '?') {
4780 quantifier_type = RegExpQuantifier::NON_GREEDY;
4782 } else if (FLAG_regexp_possessive_quantifier && current() == '+') {
4783 // FLAG_regexp_possessive_quantifier is a debug-only flag.
4784 quantifier_type = RegExpQuantifier::POSSESSIVE;
4787 builder->AddQuantifierToAtom(min, max, quantifier_type);
4793 // Currently only used in an DCHECK.
4794 static bool IsSpecialClassEscape(uc32 c) {
4807 // In order to know whether an escape is a backreference or not we have to scan
4808 // the entire regexp and find the number of capturing parentheses. However we
4809 // don't want to scan the regexp twice unless it is necessary. This mini-parser
4810 // is called when needed. It can see the difference between capturing and
4811 // noncapturing parentheses and can skip character classes and backslash-escaped
4813 void RegExpParser::ScanForCaptures() {
4814 // Start with captures started previous to current position
4815 int capture_count = captures_started();
4816 // Add count of captures after this position.
4818 while ((n = current()) != kEndMarker) {
4826 while ((c = current()) != kEndMarker) {
4831 if (c == ']') break;
4837 if (current() != '?') capture_count++;
4841 capture_count_ = capture_count;
4842 is_scanned_for_captures_ = true;
4846 bool RegExpParser::ParseBackReferenceIndex(int* index_out) {
4847 DCHECK_EQ('\\', current());
4848 DCHECK('1' <= Next() && Next() <= '9');
4849 // Try to parse a decimal literal that is no greater than the total number
4850 // of left capturing parentheses in the input.
4851 int start = position();
4852 int value = Next() - '0';
4856 if (IsDecimalDigit(c)) {
4857 value = 10 * value + (c - '0');
4858 if (value > kMaxCaptures) {
4867 if (value > captures_started()) {
4868 if (!is_scanned_for_captures_) {
4869 int saved_position = position();
4871 Reset(saved_position);
4873 if (value > capture_count_) {
4883 // QuantifierPrefix ::
4884 // { DecimalDigits }
4885 // { DecimalDigits , }
4886 // { DecimalDigits , DecimalDigits }
4888 // Returns true if parsing succeeds, and set the min_out and max_out
4889 // values. Values are truncated to RegExpTree::kInfinity if they overflow.
4890 bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
4891 DCHECK_EQ(current(), '{');
4892 int start = position();
4895 if (!IsDecimalDigit(current())) {
4899 while (IsDecimalDigit(current())) {
4900 int next = current() - '0';
4901 if (min > (RegExpTree::kInfinity - next) / 10) {
4902 // Overflow. Skip past remaining decimal digits and return -1.
4905 } while (IsDecimalDigit(current()));
4906 min = RegExpTree::kInfinity;
4909 min = 10 * min + next;
4913 if (current() == '}') {
4916 } else if (current() == ',') {
4918 if (current() == '}') {
4919 max = RegExpTree::kInfinity;
4922 while (IsDecimalDigit(current())) {
4923 int next = current() - '0';
4924 if (max > (RegExpTree::kInfinity - next) / 10) {
4927 } while (IsDecimalDigit(current()));
4928 max = RegExpTree::kInfinity;
4931 max = 10 * max + next;
4934 if (current() != '}') {
4950 uc32 RegExpParser::ParseOctalLiteral() {
4951 DCHECK(('0' <= current() && current() <= '7') || current() == kEndMarker);
4952 // For compatibility with some other browsers (not all), we parse
4953 // up to three octal digits with a value below 256.
4954 uc32 value = current() - '0';
4956 if ('0' <= current() && current() <= '7') {
4957 value = value * 8 + current() - '0';
4959 if (value < 32 && '0' <= current() && current() <= '7') {
4960 value = value * 8 + current() - '0';
4968 bool RegExpParser::ParseHexEscape(int length, uc32* value) {
4969 int start = position();
4971 for (int i = 0; i < length; ++i) {
4973 int d = HexValue(c);
4986 bool RegExpParser::ParseUnicodeEscape(uc32* value) {
4987 // Accept both \uxxxx and \u{xxxxxx} (if harmony unicode escapes are
4988 // allowed). In the latter case, the number of hex digits between { } is
4989 // arbitrary. \ and u have already been read.
4990 if (current() == '{' && FLAG_harmony_unicode_regexps && unicode_) {
4991 int start = position();
4993 if (ParseUnlimitedLengthHexNumber(0x10ffff, value)) {
4994 if (current() == '}') {
5002 // \u but no {, or \u{...} escapes not allowed.
5003 return ParseHexEscape(4, value);
5007 bool RegExpParser::ParseUnlimitedLengthHexNumber(int max_value, uc32* value) {
5009 int d = HexValue(current());
5015 if (x > max_value) {
5019 d = HexValue(current());
5026 uc32 RegExpParser::ParseClassCharacterEscape() {
5027 DCHECK(current() == '\\');
5028 DCHECK(has_next() && !IsSpecialClassEscape(Next()));
5030 switch (current()) {
5034 // ControlEscape :: one of
5052 uc32 controlLetter = Next();
5053 uc32 letter = controlLetter & ~('A' ^ 'a');
5054 // For compatibility with JSC, inside a character class
5055 // we also accept digits and underscore as control characters.
5056 if ((controlLetter >= '0' && controlLetter <= '9') ||
5057 controlLetter == '_' ||
5058 (letter >= 'A' && letter <= 'Z')) {
5060 // Control letters mapped to ASCII control characters in the range
5062 return controlLetter & 0x1f;
5064 // We match JSC in reading the backslash as a literal
5065 // character instead of as starting an escape.
5068 case '0': case '1': case '2': case '3': case '4': case '5':
5070 // For compatibility, we interpret a decimal escape that isn't
5071 // a back reference (and therefore either \0 or not valid according
5072 // to the specification) as a 1..3 digit octal character code.
5073 return ParseOctalLiteral();
5077 if (ParseHexEscape(2, &value)) {
5080 if (!FLAG_harmony_unicode_regexps || !unicode_) {
5081 // If \x is not followed by a two-digit hexadecimal, treat it
5082 // as an identity escape.
5085 // If the 'u' flag is present, invalid escapes are not treated as
5086 // identity escapes.
5087 ReportError(CStrVector("Invalid escape"));
5093 if (ParseUnicodeEscape(&value)) {
5096 if (!FLAG_harmony_unicode_regexps || !unicode_) {
5099 // If the 'u' flag is present, invalid escapes are not treated as
5100 // identity escapes.
5101 ReportError(CStrVector("Invalid unicode escape"));
5105 uc32 result = current();
5106 // If the 'u' flag is present, only syntax characters can be escaped, no
5107 // other identity escapes are allowed. If the 'u' flag is not present, all
5108 // identity escapes are allowed.
5109 if (!FLAG_harmony_unicode_regexps || !unicode_ ||
5110 IsSyntaxCharacter(result)) {
5114 ReportError(CStrVector("Invalid escape"));
5122 CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) {
5123 DCHECK_EQ(0, *char_class);
5124 uc32 first = current();
5125 if (first == '\\') {
5127 case 'w': case 'W': case 'd': case 'D': case 's': case 'S': {
5128 *char_class = Next();
5130 return CharacterRange::Singleton(0); // Return dummy value.
5133 return ReportError(CStrVector("\\ at end of pattern"));
5135 uc32 c = ParseClassCharacterEscape(CHECK_FAILED);
5136 return CharacterRange::Singleton(c);
5140 return CharacterRange::Singleton(first);
5145 static const uc16 kNoCharClass = 0;
5147 // Adds range or pre-defined character class to character ranges.
5148 // If char_class is not kInvalidClass, it's interpreted as a class
5149 // escape (i.e., 's' means whitespace, from '\s').
5150 static inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges,
5152 CharacterRange range,
5154 if (char_class != kNoCharClass) {
5155 CharacterRange::AddClassEscape(char_class, ranges, zone);
5157 ranges->Add(range, zone);
5162 RegExpTree* RegExpParser::ParseCharacterClass() {
5163 static const char* kUnterminated = "Unterminated character class";
5164 static const char* kRangeOutOfOrder = "Range out of order in character class";
5166 DCHECK_EQ(current(), '[');
5168 bool is_negated = false;
5169 if (current() == '^') {
5173 ZoneList<CharacterRange>* ranges =
5174 new(zone()) ZoneList<CharacterRange>(2, zone());
5175 while (has_more() && current() != ']') {
5176 uc16 char_class = kNoCharClass;
5177 CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED);
5178 if (current() == '-') {
5180 if (current() == kEndMarker) {
5181 // If we reach the end we break out of the loop and let the
5182 // following code report an error.
5184 } else if (current() == ']') {
5185 AddRangeOrEscape(ranges, char_class, first, zone());
5186 ranges->Add(CharacterRange::Singleton('-'), zone());
5189 uc16 char_class_2 = kNoCharClass;
5190 CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED);
5191 if (char_class != kNoCharClass || char_class_2 != kNoCharClass) {
5192 // Either end is an escaped character class. Treat the '-' verbatim.
5193 AddRangeOrEscape(ranges, char_class, first, zone());
5194 ranges->Add(CharacterRange::Singleton('-'), zone());
5195 AddRangeOrEscape(ranges, char_class_2, next, zone());
5198 if (first.from() > next.to()) {
5199 return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED);
5201 ranges->Add(CharacterRange::Range(first.from(), next.to()), zone());
5203 AddRangeOrEscape(ranges, char_class, first, zone());
5207 return ReportError(CStrVector(kUnterminated) CHECK_FAILED);
5210 if (ranges->length() == 0) {
5211 ranges->Add(CharacterRange::Everything(), zone());
5212 is_negated = !is_negated;
5214 return new(zone()) RegExpCharacterClass(ranges, is_negated);
5218 // ----------------------------------------------------------------------------
5219 // The Parser interface.
5221 bool RegExpParser::ParseRegExp(Isolate* isolate, Zone* zone,
5222 FlatStringReader* input, bool multiline,
5223 bool unicode, RegExpCompileData* result) {
5224 DCHECK(result != NULL);
5225 RegExpParser parser(input, &result->error, multiline, unicode, isolate, zone);
5226 RegExpTree* tree = parser.ParsePattern();
5227 if (parser.failed()) {
5228 DCHECK(tree == NULL);
5229 DCHECK(!result->error.is_null());
5231 DCHECK(tree != NULL);
5232 DCHECK(result->error.is_null());
5233 result->tree = tree;
5234 int capture_count = parser.captures_started();
5235 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
5236 result->contains_anchor = parser.contains_anchor();
5237 result->capture_count = capture_count;
5239 return !parser.failed();
5243 bool Parser::ParseStatic(CompilationInfo* info, bool allow_lazy) {
5244 Parser parser(info, info->isolate()->stack_guard()->real_climit(),
5245 info->isolate()->heap()->HashSeed(),
5246 info->isolate()->unicode_cache());
5247 parser.set_allow_lazy(allow_lazy);
5248 if (parser.Parse(info)) {
5249 info->SetLanguageMode(info->function()->language_mode());
5256 bool Parser::Parse(CompilationInfo* info) {
5257 DCHECK(info->function() == NULL);
5258 FunctionLiteral* result = NULL;
5259 // Ok to use Isolate here; this function is only called in the main thread.
5260 DCHECK(parsing_on_main_thread_);
5261 Isolate* isolate = info->isolate();
5262 pre_parse_timer_ = isolate->counters()->pre_parse();
5263 if (FLAG_trace_parse || allow_natives() || extension_ != NULL) {
5264 // If intrinsics are allowed, the Parser cannot operate independent of the
5265 // V8 heap because of Runtime. Tell the string table to internalize strings
5266 // and values right after they're created.
5267 ast_value_factory()->Internalize(isolate);
5270 if (info->is_lazy()) {
5271 DCHECK(!info->is_eval());
5272 if (info->shared_info()->is_function()) {
5273 result = ParseLazy(info);
5275 result = ParseProgram(info);
5278 SetCachedData(info);
5279 result = ParseProgram(info);
5281 info->SetFunction(result);
5284 DCHECK(ast_value_factory()->IsInternalized());
5285 return (result != NULL);
5289 void Parser::ParseOnBackground(CompilationInfo* info) {
5290 parsing_on_main_thread_ = false;
5292 DCHECK(info->function() == NULL);
5293 FunctionLiteral* result = NULL;
5294 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
5296 CompleteParserRecorder recorder;
5297 if (produce_cached_parse_data()) log_ = &recorder;
5299 DCHECK(info->source_stream() != NULL);
5300 ExternalStreamingStream stream(info->source_stream(),
5301 info->source_stream_encoding());
5302 scanner_.Initialize(&stream);
5303 DCHECK(info->context().is_null() || info->context()->IsNativeContext());
5305 // When streaming, we don't know the length of the source until we have parsed
5306 // it. The raw data can be UTF-8, so we wouldn't know the source length until
5307 // we have decoded it anyway even if we knew the raw data length (which we
5308 // don't). We work around this by storing all the scopes which need their end
5309 // position set at the end of the script (the top scope and possible eval
5310 // scopes) and set their end position after we know the script length.
5311 Scope* top_scope = NULL;
5312 Scope* eval_scope = NULL;
5313 result = DoParseProgram(info, &top_scope, &eval_scope);
5315 top_scope->set_end_position(scanner()->location().end_pos);
5316 if (eval_scope != NULL) {
5317 eval_scope->set_end_position(scanner()->location().end_pos);
5320 info->SetFunction(result);
5322 // We cannot internalize on a background thread; a foreground task will take
5323 // care of calling Parser::Internalize just before compilation.
5325 if (produce_cached_parse_data()) {
5326 if (result != NULL) *info->cached_data() = recorder.GetScriptData();
5332 ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
5333 return new (zone()) ParserTraits::TemplateLiteral(zone(), pos);
5337 void Parser::AddTemplateSpan(TemplateLiteralState* state, bool tail) {
5338 int pos = scanner()->location().beg_pos;
5339 int end = scanner()->location().end_pos - (tail ? 1 : 2);
5340 const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory());
5341 const AstRawString* trv = scanner()->CurrentRawSymbol(ast_value_factory());
5342 Literal* cooked = factory()->NewStringLiteral(tv, pos);
5343 Literal* raw = factory()->NewStringLiteral(trv, pos);
5344 (*state)->AddTemplateSpan(cooked, raw, end, zone());
5348 void Parser::AddTemplateExpression(TemplateLiteralState* state,
5349 Expression* expression) {
5350 (*state)->AddExpression(expression, zone());
5354 Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
5356 TemplateLiteral* lit = *state;
5357 int pos = lit->position();
5358 const ZoneList<Expression*>* cooked_strings = lit->cooked();
5359 const ZoneList<Expression*>* raw_strings = lit->raw();
5360 const ZoneList<Expression*>* expressions = lit->expressions();
5361 DCHECK_EQ(cooked_strings->length(), raw_strings->length());
5362 DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
5365 // Build tree of BinaryOps to simplify code-generation
5366 Expression* expr = NULL;
5368 if (expressions->length() == 0) {
5369 // Simple case: treat as string literal
5370 expr = cooked_strings->at(0);
5373 Expression* cooked_str = cooked_strings->at(0);
5374 expr = factory()->NewBinaryOperation(
5375 Token::ADD, cooked_str, expressions->at(0), cooked_str->position());
5376 for (i = 1; i < expressions->length(); ++i) {
5377 cooked_str = cooked_strings->at(i);
5378 expr = factory()->NewBinaryOperation(
5379 Token::ADD, expr, factory()->NewBinaryOperation(
5380 Token::ADD, cooked_str, expressions->at(i),
5381 cooked_str->position()),
5382 cooked_str->position());
5384 cooked_str = cooked_strings->at(i);
5385 expr = factory()->NewBinaryOperation(Token::ADD, expr, cooked_str,
5386 cooked_str->position());
5390 uint32_t hash = ComputeTemplateLiteralHash(lit);
5392 int cooked_idx = function_state_->NextMaterializedLiteralIndex();
5393 int raw_idx = function_state_->NextMaterializedLiteralIndex();
5395 // GetTemplateCallSite
5396 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone());
5397 args->Add(factory()->NewArrayLiteral(
5398 const_cast<ZoneList<Expression*>*>(cooked_strings),
5402 factory()->NewArrayLiteral(
5403 const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx, pos),
5406 // Ensure hash is suitable as a Smi value
5407 Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash)));
5408 args->Add(factory()->NewSmiLiteral(hash_obj->value(), pos), zone());
5410 this->CheckPossibleEvalCall(tag, scope_);
5411 Expression* call_site = factory()->NewCallRuntime(
5412 ast_value_factory()->get_template_callsite_string(), NULL, args, start);
5415 ZoneList<Expression*>* call_args =
5416 new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone());
5417 call_args->Add(call_site, zone());
5418 call_args->AddAll(*expressions, zone());
5419 return factory()->NewCall(tag, call_args, pos);
5424 uint32_t Parser::ComputeTemplateLiteralHash(const TemplateLiteral* lit) {
5425 const ZoneList<Expression*>* raw_strings = lit->raw();
5426 int total = raw_strings->length();
5429 uint32_t running_hash = 0;
5431 for (int index = 0; index < total; ++index) {
5433 running_hash = StringHasher::ComputeRunningHashOneByte(
5434 running_hash, "${}", 3);
5437 const AstRawString* raw_string =
5438 raw_strings->at(index)->AsLiteral()->raw_value()->AsString();
5439 if (raw_string->is_one_byte()) {
5440 const char* data = reinterpret_cast<const char*>(raw_string->raw_data());
5441 running_hash = StringHasher::ComputeRunningHashOneByte(
5442 running_hash, data, raw_string->length());
5444 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
5445 running_hash = StringHasher::ComputeRunningHash(running_hash, data,
5446 raw_string->length());
5450 return running_hash;
5452 } } // namespace v8::internal