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/base/platform/platform.h"
10 #include "src/bootstrapper.h"
11 #include "src/char-predicates-inl.h"
12 #include "src/codegen.h"
13 #include "src/compiler.h"
14 #include "src/messages.h"
15 #include "src/parser.h"
16 #include "src/preparser.h"
17 #include "src/runtime.h"
18 #include "src/scanner-character-streams.h"
19 #include "src/scopeinfo.h"
20 #include "src/string-stream.h"
25 RegExpBuilder::RegExpBuilder(Zone* zone)
27 pending_empty_(false),
32 , last_added_(ADD_NONE)
37 void RegExpBuilder::FlushCharacters() {
38 pending_empty_ = false;
39 if (characters_ != NULL) {
40 RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector());
42 text_.Add(atom, zone());
48 void RegExpBuilder::FlushText() {
50 int num_text = text_.length();
53 } else if (num_text == 1) {
54 terms_.Add(text_.last(), zone());
56 RegExpText* text = new(zone()) RegExpText(zone());
57 for (int i = 0; i < num_text; i++)
58 text_.Get(i)->AppendToText(text, zone());
59 terms_.Add(text, zone());
65 void RegExpBuilder::AddCharacter(uc16 c) {
66 pending_empty_ = false;
67 if (characters_ == NULL) {
68 characters_ = new(zone()) ZoneList<uc16>(4, zone());
70 characters_->Add(c, zone());
75 void RegExpBuilder::AddEmpty() {
76 pending_empty_ = true;
80 void RegExpBuilder::AddAtom(RegExpTree* term) {
81 if (term->IsEmpty()) {
85 if (term->IsTextElement()) {
87 text_.Add(term, zone());
90 terms_.Add(term, zone());
96 void RegExpBuilder::AddAssertion(RegExpTree* assert) {
98 terms_.Add(assert, zone());
103 void RegExpBuilder::NewAlternative() {
108 void RegExpBuilder::FlushTerms() {
110 int num_terms = terms_.length();
111 RegExpTree* alternative;
112 if (num_terms == 0) {
113 alternative = RegExpEmpty::GetInstance();
114 } else if (num_terms == 1) {
115 alternative = terms_.last();
117 alternative = new(zone()) RegExpAlternative(terms_.GetList(zone()));
119 alternatives_.Add(alternative, zone());
125 RegExpTree* RegExpBuilder::ToRegExp() {
127 int num_alternatives = alternatives_.length();
128 if (num_alternatives == 0) {
129 return RegExpEmpty::GetInstance();
131 if (num_alternatives == 1) {
132 return alternatives_.last();
134 return new(zone()) RegExpDisjunction(alternatives_.GetList(zone()));
138 void RegExpBuilder::AddQuantifierToAtom(
139 int min, int max, RegExpQuantifier::QuantifierType quantifier_type) {
140 if (pending_empty_) {
141 pending_empty_ = false;
145 if (characters_ != NULL) {
146 DCHECK(last_added_ == ADD_CHAR);
147 // Last atom was character.
148 Vector<const uc16> char_vector = characters_->ToConstVector();
149 int num_chars = char_vector.length();
151 Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1);
152 text_.Add(new(zone()) RegExpAtom(prefix), zone());
153 char_vector = char_vector.SubVector(num_chars - 1, num_chars);
156 atom = new(zone()) RegExpAtom(char_vector);
158 } else if (text_.length() > 0) {
159 DCHECK(last_added_ == ADD_ATOM);
160 atom = text_.RemoveLast();
162 } else if (terms_.length() > 0) {
163 DCHECK(last_added_ == ADD_ATOM);
164 atom = terms_.RemoveLast();
165 if (atom->max_match() == 0) {
166 // Guaranteed to only match an empty string.
171 terms_.Add(atom, zone());
175 // Only call immediately after adding an atom or character!
180 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone());
185 FunctionEntry ParseData::GetFunctionEntry(int start) {
186 // The current pre-data entry must be a FunctionEntry with the given
188 if ((function_index_ + FunctionEntry::kSize <= Length()) &&
189 (static_cast<int>(Data()[function_index_]) == start)) {
190 int index = function_index_;
191 function_index_ += FunctionEntry::kSize;
192 Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize);
193 return FunctionEntry(subvector);
195 return FunctionEntry();
199 int ParseData::FunctionCount() {
200 int functions_size = FunctionsSize();
201 if (functions_size < 0) return 0;
202 if (functions_size % FunctionEntry::kSize != 0) return 0;
203 return functions_size / FunctionEntry::kSize;
207 bool ParseData::IsSane() {
208 // Check that the header data is valid and doesn't specify
209 // point to positions outside the store.
210 int data_length = Length();
211 if (data_length < PreparseDataConstants::kHeaderSize) return false;
212 if (Magic() != PreparseDataConstants::kMagicNumber) return false;
213 if (Version() != PreparseDataConstants::kCurrentVersion) return false;
214 if (HasError()) return false;
215 // Check that the space allocated for function entries is sane.
216 int functions_size = FunctionsSize();
217 if (functions_size < 0) return false;
218 if (functions_size % FunctionEntry::kSize != 0) return false;
219 // Check that the total size has room for header and function entries.
221 PreparseDataConstants::kHeaderSize + functions_size;
222 if (data_length < minimum_size) return false;
227 void ParseData::Initialize() {
228 // Prepares state for use.
229 int data_length = Length();
230 if (data_length >= PreparseDataConstants::kHeaderSize) {
231 function_index_ = PreparseDataConstants::kHeaderSize;
236 bool ParseData::HasError() {
237 return Data()[PreparseDataConstants::kHasErrorOffset];
241 unsigned ParseData::Magic() {
242 return Data()[PreparseDataConstants::kMagicOffset];
246 unsigned ParseData::Version() {
247 return Data()[PreparseDataConstants::kVersionOffset];
251 int ParseData::FunctionsSize() {
252 return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]);
256 void Parser::SetCachedData() {
257 if (compile_options() == ScriptCompiler::kNoCompileOptions) {
258 cached_parse_data_ = NULL;
260 DCHECK(info_->cached_data() != NULL);
261 if (compile_options() == ScriptCompiler::kConsumeParserCache) {
262 cached_parse_data_ = new ParseData(*info_->cached_data());
268 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) {
269 DCHECK(ast_value_factory_);
271 new (zone()) Scope(parent, scope_type, ast_value_factory_, zone());
272 result->Initialize();
277 // ----------------------------------------------------------------------------
278 // Target is a support class to facilitate manipulation of the
279 // Parser's target_stack_ (the stack of potential 'break' and
280 // 'continue' statement targets). Upon construction, a new target is
281 // added; it is removed upon destruction.
283 class Target BASE_EMBEDDED {
285 Target(Target** variable, AstNode* node)
286 : variable_(variable), node_(node), previous_(*variable) {
291 *variable_ = previous_;
294 Target* previous() { return previous_; }
295 AstNode* node() { return node_; }
304 class TargetScope BASE_EMBEDDED {
306 explicit TargetScope(Target** variable)
307 : variable_(variable), previous_(*variable) {
312 *variable_ = previous_;
321 // ----------------------------------------------------------------------------
322 // The CHECK_OK macro is a convenient macro to enforce error
323 // handling for functions that may fail (by returning !*ok).
325 // CAUTION: This macro appends extra statements after a call,
326 // thus it must never be used where only a single statement
327 // is correct (e.g. an if statement branch w/o braces)!
329 #define CHECK_OK ok); \
330 if (!*ok) return NULL; \
332 #define DUMMY ) // to make indentation work
335 #define CHECK_FAILED /**/); \
336 if (failed_) return NULL; \
338 #define DUMMY ) // to make indentation work
341 // ----------------------------------------------------------------------------
342 // Implementation of Parser
344 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const {
345 return identifier == parser_->ast_value_factory_->eval_string() ||
346 identifier == parser_->ast_value_factory_->arguments_string();
350 bool ParserTraits::IsThisProperty(Expression* expression) {
351 DCHECK(expression != NULL);
352 Property* property = expression->AsProperty();
353 return property != NULL &&
354 property->obj()->AsVariableProxy() != NULL &&
355 property->obj()->AsVariableProxy()->is_this();
359 bool ParserTraits::IsIdentifier(Expression* expression) {
360 VariableProxy* operand = expression->AsVariableProxy();
361 return operand != NULL && !operand->is_this();
365 void ParserTraits::PushPropertyName(FuncNameInferrer* fni,
366 Expression* expression) {
367 if (expression->IsPropertyName()) {
368 fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
370 fni->PushLiteralName(
371 parser_->ast_value_factory_->anonymous_function_string());
376 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
378 DCHECK(left != NULL);
379 if (left->AsProperty() != NULL &&
380 right->AsFunctionLiteral() != NULL) {
381 right->AsFunctionLiteral()->set_pretenure();
386 void ParserTraits::CheckPossibleEvalCall(Expression* expression,
388 VariableProxy* callee = expression->AsVariableProxy();
389 if (callee != NULL &&
390 callee->raw_name() == parser_->ast_value_factory_->eval_string()) {
391 scope->DeclarationScope()->RecordEvalCall();
396 Expression* ParserTraits::MarkExpressionAsAssigned(Expression* expression) {
397 VariableProxy* proxy =
398 expression != NULL ? expression->AsVariableProxy() : NULL;
399 if (proxy != NULL) proxy->set_is_assigned();
404 bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
405 Expression** x, Expression* y, Token::Value op, int pos,
406 AstNodeFactory<AstConstructionVisitor>* factory) {
407 if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
408 y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) {
409 double x_val = (*x)->AsLiteral()->raw_value()->AsNumber();
410 double y_val = y->AsLiteral()->raw_value()->AsNumber();
413 *x = factory->NewNumberLiteral(x_val + y_val, pos);
416 *x = factory->NewNumberLiteral(x_val - y_val, pos);
419 *x = factory->NewNumberLiteral(x_val * y_val, pos);
422 *x = factory->NewNumberLiteral(x_val / y_val, pos);
424 case Token::BIT_OR: {
425 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
426 *x = factory->NewNumberLiteral(value, pos);
429 case Token::BIT_AND: {
430 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
431 *x = factory->NewNumberLiteral(value, pos);
434 case Token::BIT_XOR: {
435 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
436 *x = factory->NewNumberLiteral(value, pos);
440 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
441 *x = factory->NewNumberLiteral(value, pos);
445 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
446 uint32_t value = DoubleToUint32(x_val) >> shift;
447 *x = factory->NewNumberLiteral(value, pos);
451 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
452 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
453 *x = factory->NewNumberLiteral(value, pos);
464 Expression* ParserTraits::BuildUnaryExpression(
465 Expression* expression, Token::Value op, int pos,
466 AstNodeFactory<AstConstructionVisitor>* factory) {
467 DCHECK(expression != NULL);
468 if (expression->IsLiteral()) {
469 const AstValue* literal = expression->AsLiteral()->raw_value();
470 if (op == Token::NOT) {
471 // Convert the literal to a boolean condition and negate it.
472 bool condition = literal->BooleanValue();
473 return factory->NewBooleanLiteral(!condition, pos);
474 } else if (literal->IsNumber()) {
475 // Compute some expressions involving only number literals.
476 double value = literal->AsNumber();
481 return factory->NewNumberLiteral(-value, pos);
483 return factory->NewNumberLiteral(~DoubleToInt32(value), pos);
489 // Desugar '+foo' => 'foo*1'
490 if (op == Token::ADD) {
491 return factory->NewBinaryOperation(
492 Token::MUL, expression, factory->NewNumberLiteral(1, pos), pos);
494 // The same idea for '-foo' => 'foo*(-1)'.
495 if (op == Token::SUB) {
496 return factory->NewBinaryOperation(
497 Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos);
499 // ...and one more time for '~foo' => 'foo^(~0)'.
500 if (op == Token::BIT_NOT) {
501 return factory->NewBinaryOperation(
502 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos);
504 return factory->NewUnaryOperation(op, expression, pos);
508 Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) {
509 return NewThrowError(
510 parser_->ast_value_factory_->make_reference_error_string(), message, NULL,
515 Expression* ParserTraits::NewThrowSyntaxError(
516 const char* message, const AstRawString* arg, int pos) {
517 return NewThrowError(parser_->ast_value_factory_->make_syntax_error_string(),
522 Expression* ParserTraits::NewThrowTypeError(
523 const char* message, const AstRawString* arg, int pos) {
524 return NewThrowError(parser_->ast_value_factory_->make_type_error_string(),
529 Expression* ParserTraits::NewThrowError(
530 const AstRawString* constructor, const char* message,
531 const AstRawString* arg, int pos) {
532 Zone* zone = parser_->zone();
533 int argc = arg != NULL ? 1 : 0;
534 const AstRawString* type =
535 parser_->ast_value_factory_->GetOneByteString(message);
536 ZoneList<const AstRawString*>* array =
537 new (zone) ZoneList<const AstRawString*>(argc, zone);
539 array->Add(arg, zone);
541 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone);
542 args->Add(parser_->factory()->NewStringLiteral(type, pos), zone);
543 args->Add(parser_->factory()->NewStringListLiteral(array, pos), zone);
544 CallRuntime* call_constructor =
545 parser_->factory()->NewCallRuntime(constructor, NULL, args, pos);
546 return parser_->factory()->NewThrow(call_constructor, pos);
550 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
553 bool is_reference_error) {
554 if (parser_->stack_overflow()) {
555 // Suppress the error message (syntax error or such) in the presence of a
556 // stack overflow. The isolate allows only one pending exception at at time
557 // and we want to report the stack overflow later.
560 parser_->has_pending_error_ = true;
561 parser_->pending_error_location_ = source_location;
562 parser_->pending_error_message_ = message;
563 parser_->pending_error_char_arg_ = arg;
564 parser_->pending_error_arg_ = NULL;
565 parser_->pending_error_is_reference_error_ = is_reference_error;
569 void ParserTraits::ReportMessage(const char* message,
571 bool is_reference_error) {
572 Scanner::Location source_location = parser_->scanner()->location();
573 ReportMessageAt(source_location, message, arg, is_reference_error);
577 void ParserTraits::ReportMessage(const char* message,
578 const AstRawString* arg,
579 bool is_reference_error) {
580 Scanner::Location source_location = parser_->scanner()->location();
581 ReportMessageAt(source_location, message, arg, is_reference_error);
585 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
587 const AstRawString* arg,
588 bool is_reference_error) {
589 if (parser_->stack_overflow()) {
590 // Suppress the error message (syntax error or such) in the presence of a
591 // stack overflow. The isolate allows only one pending exception at at time
592 // and we want to report the stack overflow later.
595 parser_->has_pending_error_ = true;
596 parser_->pending_error_location_ = source_location;
597 parser_->pending_error_message_ = message;
598 parser_->pending_error_char_arg_ = NULL;
599 parser_->pending_error_arg_ = arg;
600 parser_->pending_error_is_reference_error_ = is_reference_error;
604 const AstRawString* ParserTraits::GetSymbol(Scanner* scanner) {
605 const AstRawString* result =
606 parser_->scanner()->CurrentSymbol(parser_->ast_value_factory_);
607 DCHECK(result != NULL);
612 const AstRawString* ParserTraits::GetNextSymbol(Scanner* scanner) {
613 return parser_->scanner()->NextSymbol(parser_->ast_value_factory_);
617 Expression* ParserTraits::ThisExpression(
618 Scope* scope, AstNodeFactory<AstConstructionVisitor>* factory, int pos) {
619 return factory->NewVariableProxy(scope->receiver(), pos);
623 Literal* ParserTraits::ExpressionFromLiteral(
624 Token::Value token, int pos,
626 AstNodeFactory<AstConstructionVisitor>* factory) {
628 case Token::NULL_LITERAL:
629 return factory->NewNullLiteral(pos);
630 case Token::TRUE_LITERAL:
631 return factory->NewBooleanLiteral(true, pos);
632 case Token::FALSE_LITERAL:
633 return factory->NewBooleanLiteral(false, pos);
634 case Token::NUMBER: {
635 double value = scanner->DoubleValue();
636 return factory->NewNumberLiteral(value, pos);
645 Expression* ParserTraits::ExpressionFromIdentifier(
646 const AstRawString* name, int pos, Scope* scope,
647 AstNodeFactory<AstConstructionVisitor>* factory) {
648 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name);
649 // The name may refer to a module instance object, so its type is unknown.
651 if (FLAG_print_interface_details)
652 PrintF("# Variable %.*s ", name->length(), name->raw_data());
654 Interface* interface = Interface::NewUnknown(parser_->zone());
655 return scope->NewUnresolved(factory, name, interface, pos);
659 Expression* ParserTraits::ExpressionFromString(
660 int pos, Scanner* scanner,
661 AstNodeFactory<AstConstructionVisitor>* factory) {
662 const AstRawString* symbol = GetSymbol(scanner);
663 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol);
664 return factory->NewStringLiteral(symbol, pos);
668 Expression* ParserTraits::GetIterator(
669 Expression* iterable, AstNodeFactory<AstConstructionVisitor>* factory) {
670 Expression* iterator_symbol_literal =
671 factory->NewSymbolLiteral("symbolIterator", RelocInfo::kNoPosition);
672 int pos = iterable->position();
674 factory->NewProperty(iterable, iterator_symbol_literal, pos);
675 Zone* zone = parser_->zone();
676 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(0, zone);
677 return factory->NewCall(prop, args, pos);
681 Literal* ParserTraits::GetLiteralTheHole(
682 int position, AstNodeFactory<AstConstructionVisitor>* factory) {
683 return factory->NewTheHoleLiteral(RelocInfo::kNoPosition);
687 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) {
688 return parser_->ParseV8Intrinsic(ok);
692 FunctionLiteral* ParserTraits::ParseFunctionLiteral(
693 const AstRawString* name,
694 Scanner::Location function_name_location,
695 bool name_is_strict_reserved,
697 int function_token_position,
698 FunctionLiteral::FunctionType type,
699 FunctionLiteral::ArityRestriction arity_restriction,
701 return parser_->ParseFunctionLiteral(name, function_name_location,
702 name_is_strict_reserved, is_generator,
703 function_token_position, type,
704 arity_restriction, ok);
708 Parser::Parser(CompilationInfo* info)
709 : ParserBase<ParserTraits>(&scanner_,
710 info->isolate()->stack_guard()->real_climit(),
711 info->extension(), NULL, info->zone(), this),
712 isolate_(info->isolate()),
713 script_(info->script()),
714 scanner_(isolate_->unicode_cache()),
715 reusable_preparser_(NULL),
716 original_scope_(NULL),
718 cached_parse_data_(NULL),
719 ast_value_factory_(NULL),
721 has_pending_error_(false),
722 pending_error_message_(NULL),
723 pending_error_arg_(NULL),
724 pending_error_char_arg_(NULL) {
725 DCHECK(!script_.is_null());
726 isolate_->set_ast_node_id(0);
727 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping);
728 set_allow_modules(!info->is_native() && FLAG_harmony_modules);
729 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native());
730 set_allow_lazy(false); // Must be explicitly enabled.
731 set_allow_generators(FLAG_harmony_generators);
732 set_allow_arrow_functions(FLAG_harmony_arrow_functions);
733 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
734 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
736 use_counts_[feature] = 0;
741 FunctionLiteral* Parser::ParseProgram() {
742 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
743 // see comment for HistogramTimerScope class.
744 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true);
745 Handle<String> source(String::cast(script_->source()));
746 isolate()->counters()->total_parse_size()->Increment(source->length());
747 base::ElapsedTimer timer;
748 if (FLAG_trace_parse) {
751 fni_ = new(zone()) FuncNameInferrer(ast_value_factory_, zone());
753 // Initialize parser state.
754 CompleteParserRecorder recorder;
756 if (compile_options() == ScriptCompiler::kProduceParserCache) {
758 } else if (compile_options() == ScriptCompiler::kConsumeParserCache) {
759 cached_parse_data_->Initialize();
762 source = String::Flatten(source);
763 FunctionLiteral* result;
764 if (source->IsExternalTwoByteString()) {
765 // Notice that the stream is destroyed at the end of the branch block.
766 // The last line of the blocks can't be moved outside, even though they're
768 ExternalTwoByteStringUtf16CharacterStream stream(
769 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
770 scanner_.Initialize(&stream);
771 result = DoParseProgram(info(), source);
773 GenericStringUtf16CharacterStream stream(source, 0, source->length());
774 scanner_.Initialize(&stream);
775 result = DoParseProgram(info(), source);
778 if (FLAG_trace_parse && result != NULL) {
779 double ms = timer.Elapsed().InMillisecondsF();
780 if (info()->is_eval()) {
781 PrintF("[parsing eval");
782 } else if (info()->script()->name()->IsString()) {
783 String* name = String::cast(info()->script()->name());
784 SmartArrayPointer<char> name_chars = name->ToCString();
785 PrintF("[parsing script: %s", name_chars.get());
787 PrintF("[parsing script");
789 PrintF(" - took %0.3f ms]\n", ms);
791 if (compile_options() == ScriptCompiler::kProduceParserCache) {
792 if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
799 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
800 Handle<String> source) {
801 DCHECK(scope_ == NULL);
802 DCHECK(target_stack_ == NULL);
804 FunctionLiteral* result = NULL;
805 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE);
806 info->SetGlobalScope(scope);
807 if (!info->context().is_null() && !info->context()->IsNativeContext()) {
808 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone());
809 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this
810 // means the Parser cannot operate independent of the V8 heap. Tell the
811 // string table to internalize strings and values right after they're
813 ast_value_factory_->Internalize(isolate());
815 original_scope_ = scope;
816 if (info->is_eval()) {
817 if (!scope->is_global_scope() || info->strict_mode() == STRICT) {
818 scope = NewScope(scope, EVAL_SCOPE);
820 } else if (info->is_global()) {
821 scope = NewScope(scope, GLOBAL_SCOPE);
823 scope->set_start_position(0);
824 scope->set_end_position(source->length());
826 // Compute the parsing mode.
827 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY;
828 if (allow_natives_syntax() ||
829 extension_ != NULL ||
830 scope->is_eval_scope()) {
831 mode = PARSE_EAGERLY;
833 ParsingModeScope parsing_mode(this, mode);
836 FunctionState function_state(&function_state_, &scope_, scope, zone(),
839 scope_->SetStrictMode(info->strict_mode());
840 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
842 int beg_pos = scanner()->location().beg_pos;
843 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok);
845 HandleSourceURLComments();
847 if (ok && strict_mode() == STRICT) {
848 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
851 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) {
852 CheckConflictingVarDeclarations(scope_, &ok);
855 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
856 if (body->length() != 1 ||
857 !body->at(0)->IsExpressionStatement() ||
858 !body->at(0)->AsExpressionStatement()->
859 expression()->IsFunctionLiteral()) {
860 ReportMessage("single_function_literal");
865 ast_value_factory_->Internalize(isolate());
867 result = factory()->NewFunctionLiteral(
868 ast_value_factory_->empty_string(), ast_value_factory_, scope_, body,
869 function_state.materialized_literal_count(),
870 function_state.expected_property_count(),
871 function_state.handler_count(), 0,
872 FunctionLiteral::kNoDuplicateParameters,
873 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval,
874 FunctionLiteral::kNotParenthesized, FunctionLiteral::kNormalFunction,
876 result->set_ast_properties(factory()->visitor()->ast_properties());
877 result->set_dont_optimize_reason(
878 factory()->visitor()->dont_optimize_reason());
879 } else if (stack_overflow()) {
880 isolate()->StackOverflow();
886 // Make sure the target stack is empty.
887 DCHECK(target_stack_ == NULL);
893 FunctionLiteral* Parser::ParseLazy() {
894 HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy());
895 Handle<String> source(String::cast(script_->source()));
896 isolate()->counters()->total_parse_size()->Increment(source->length());
897 base::ElapsedTimer timer;
898 if (FLAG_trace_parse) {
901 Handle<SharedFunctionInfo> shared_info = info()->shared_info();
903 // Initialize parser state.
904 source = String::Flatten(source);
905 FunctionLiteral* result;
906 if (source->IsExternalTwoByteString()) {
907 ExternalTwoByteStringUtf16CharacterStream stream(
908 Handle<ExternalTwoByteString>::cast(source),
909 shared_info->start_position(),
910 shared_info->end_position());
911 result = ParseLazy(&stream);
913 GenericStringUtf16CharacterStream stream(source,
914 shared_info->start_position(),
915 shared_info->end_position());
916 result = ParseLazy(&stream);
919 if (FLAG_trace_parse && result != NULL) {
920 double ms = timer.Elapsed().InMillisecondsF();
921 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString();
922 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
928 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) {
929 Handle<SharedFunctionInfo> shared_info = info()->shared_info();
930 scanner_.Initialize(source);
931 DCHECK(scope_ == NULL);
932 DCHECK(target_stack_ == NULL);
934 Handle<String> name(String::cast(shared_info->name()));
935 DCHECK(ast_value_factory_);
936 fni_ = new(zone()) FuncNameInferrer(ast_value_factory_, zone());
937 const AstRawString* raw_name = ast_value_factory_->GetString(name);
938 fni_->PushEnclosingName(raw_name);
940 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
942 // Place holder for the result.
943 FunctionLiteral* result = NULL;
946 // Parse the function literal.
947 Scope* scope = NewScope(scope_, GLOBAL_SCOPE);
948 info()->SetGlobalScope(scope);
949 if (!info()->closure().is_null()) {
950 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope,
953 original_scope_ = scope;
954 FunctionState function_state(&function_state_, &scope_, scope, zone(),
956 DCHECK(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT);
957 DCHECK(info()->strict_mode() == shared_info->strict_mode());
958 scope->SetStrictMode(shared_info->strict_mode());
959 FunctionLiteral::FunctionType function_type = shared_info->is_expression()
960 ? (shared_info->is_anonymous()
961 ? FunctionLiteral::ANONYMOUS_EXPRESSION
962 : FunctionLiteral::NAMED_EXPRESSION)
963 : FunctionLiteral::DECLARATION;
964 bool is_generator = shared_info->is_generator();
967 if (shared_info->is_arrow()) {
968 DCHECK(!is_generator);
969 Expression* expression = ParseExpression(false, &ok);
970 DCHECK(expression->IsFunctionLiteral());
971 result = expression->AsFunctionLiteral();
973 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(),
974 false, // Strict mode name already checked.
975 is_generator, RelocInfo::kNoPosition,
977 FunctionLiteral::NORMAL_ARITY, &ok);
979 // Make sure the results agree.
980 DCHECK(ok == (result != NULL));
983 // Make sure the target stack is empty.
984 DCHECK(target_stack_ == NULL);
986 ast_value_factory_->Internalize(isolate());
987 if (result == NULL) {
988 if (stack_overflow()) {
989 isolate()->StackOverflow();
994 Handle<String> inferred_name(shared_info->inferred_name());
995 result->set_inferred_name(inferred_name);
1001 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
1006 // SourceElements ::
1007 // (ModuleElement)* <end_token>
1009 // Allocate a target stack to use for this set of source
1010 // elements. This way, all scripts and functions get their own
1011 // target stack thus avoiding illegal breaks and continues across
1013 TargetScope scope(&this->target_stack_);
1015 DCHECK(processor != NULL);
1016 bool directive_prologue = true; // Parsing directive prologue.
1018 while (peek() != end_token) {
1019 if (directive_prologue && peek() != Token::STRING) {
1020 directive_prologue = false;
1023 Scanner::Location token_loc = scanner()->peek_location();
1025 if (is_global && !is_eval) {
1026 stat = ParseModuleElement(NULL, CHECK_OK);
1028 stat = ParseBlockElement(NULL, CHECK_OK);
1030 if (stat == NULL || stat->IsEmpty()) {
1031 directive_prologue = false; // End of directive prologue.
1035 if (directive_prologue) {
1036 // A shot at a directive.
1037 ExpressionStatement* e_stat;
1039 // Still processing directive prologue?
1040 if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1041 (literal = e_stat->expression()->AsLiteral()) != NULL &&
1042 literal->raw_value()->IsString()) {
1043 // Check "use strict" directive (ES5 14.1) and "use asm" directive. Only
1044 // one can be present.
1045 if (strict_mode() == SLOPPY &&
1046 literal->raw_value()->AsString() ==
1047 ast_value_factory_->use_strict_string() &&
1048 token_loc.end_pos - token_loc.beg_pos ==
1049 ast_value_factory_->use_strict_string()->length() + 2) {
1050 // TODO(mstarzinger): Global strict eval calls, need their own scope
1051 // as specified in ES5 10.4.2(3). The correct fix would be to always
1052 // add this scope in DoParseProgram(), but that requires adaptations
1053 // all over the code base, so we go with a quick-fix for now.
1054 // In the same manner, we have to patch the parsing mode.
1055 if (is_eval && !scope_->is_eval_scope()) {
1056 DCHECK(scope_->is_global_scope());
1057 Scope* scope = NewScope(scope_, EVAL_SCOPE);
1058 scope->set_start_position(scope_->start_position());
1059 scope->set_end_position(scope_->end_position());
1061 mode_ = PARSE_EAGERLY;
1063 scope_->SetStrictMode(STRICT);
1064 // "use strict" is the only directive for now.
1065 directive_prologue = false;
1066 } else if (literal->raw_value()->AsString() ==
1067 ast_value_factory_->use_asm_string() &&
1068 token_loc.end_pos - token_loc.beg_pos ==
1069 ast_value_factory_->use_asm_string()->length() + 2) {
1070 // Store the usage count; The actual use counter on the isolate is
1071 // incremented after parsing is done.
1072 ++use_counts_[v8::Isolate::kUseAsm];
1075 // End of the directive prologue.
1076 directive_prologue = false;
1080 processor->Add(stat, zone());
1087 Statement* Parser::ParseModuleElement(ZoneList<const AstRawString*>* labels,
1089 // (Ecma 262 5th Edition, clause 14):
1092 // FunctionDeclaration
1094 // In harmony mode we allow additionally the following productions
1098 // ModuleDeclaration
1099 // ImportDeclaration
1100 // ExportDeclaration
1101 // GeneratorDeclaration
1104 case Token::FUNCTION:
1105 return ParseFunctionDeclaration(NULL, ok);
1107 return ParseImportDeclaration(ok);
1109 return ParseExportDeclaration(ok);
1111 return ParseVariableStatement(kModuleElement, NULL, ok);
1113 DCHECK(allow_harmony_scoping());
1114 if (strict_mode() == STRICT) {
1115 return ParseVariableStatement(kModuleElement, NULL, ok);
1119 Statement* stmt = ParseStatement(labels, CHECK_OK);
1120 // Handle 'module' as a context-sensitive keyword.
1121 if (FLAG_harmony_modules &&
1122 peek() == Token::IDENTIFIER &&
1123 !scanner()->HasAnyLineTerminatorBeforeNext() &&
1125 ExpressionStatement* estmt = stmt->AsExpressionStatement();
1126 if (estmt != NULL && estmt->expression()->AsVariableProxy() != NULL &&
1127 estmt->expression()->AsVariableProxy()->raw_name() ==
1128 ast_value_factory_->module_string() &&
1129 !scanner()->literal_contains_escapes()) {
1130 return ParseModuleDeclaration(NULL, ok);
1139 Statement* Parser::ParseModuleDeclaration(ZoneList<const AstRawString*>* names,
1141 // ModuleDeclaration:
1142 // 'module' Identifier Module
1144 int pos = peek_position();
1145 const AstRawString* name =
1146 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1149 if (FLAG_print_interface_details)
1150 PrintF("# Module %.*s ", name->length(), name->raw_data());
1153 Module* module = ParseModule(CHECK_OK);
1154 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface());
1155 Declaration* declaration =
1156 factory()->NewModuleDeclaration(proxy, module, scope_, pos);
1157 Declare(declaration, true, CHECK_OK);
1160 if (FLAG_print_interface_details)
1161 PrintF("# Module %.*s ", name->length(), name->raw_data());
1162 if (FLAG_print_interfaces) {
1163 PrintF("module %.*s: ", name->length(), name->raw_data());
1164 module->interface()->Print();
1168 if (names) names->Add(name, zone());
1169 if (module->body() == NULL)
1170 return factory()->NewEmptyStatement(pos);
1172 return factory()->NewModuleStatement(proxy, module->body(), pos);
1176 Module* Parser::ParseModule(bool* ok) {
1178 // '{' ModuleElement '}'
1179 // '=' ModulePath ';'
1184 return ParseModuleLiteral(ok);
1186 case Token::ASSIGN: {
1187 Expect(Token::ASSIGN, CHECK_OK);
1188 Module* result = ParseModulePath(CHECK_OK);
1189 ExpectSemicolon(CHECK_OK);
1194 ExpectContextualKeyword(CStrVector("at"), CHECK_OK);
1195 Module* result = ParseModuleUrl(CHECK_OK);
1196 ExpectSemicolon(CHECK_OK);
1203 Module* Parser::ParseModuleLiteral(bool* ok) {
1205 // '{' ModuleElement '}'
1207 int pos = peek_position();
1208 // Construct block expecting 16 statements.
1209 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition);
1211 if (FLAG_print_interface_details) PrintF("# Literal ");
1213 Scope* scope = NewScope(scope_, MODULE_SCOPE);
1215 Expect(Token::LBRACE, CHECK_OK);
1216 scope->set_start_position(scanner()->location().beg_pos);
1217 scope->SetStrictMode(STRICT);
1220 BlockState block_state(&scope_, scope);
1221 TargetCollector collector(zone());
1222 Target target(&this->target_stack_, &collector);
1223 Target target_body(&this->target_stack_, body);
1225 while (peek() != Token::RBRACE) {
1226 Statement* stat = ParseModuleElement(NULL, CHECK_OK);
1227 if (stat && !stat->IsEmpty()) {
1228 body->AddStatement(stat, zone());
1233 Expect(Token::RBRACE, CHECK_OK);
1234 scope->set_end_position(scanner()->location().end_pos);
1235 body->set_scope(scope);
1237 // Check that all exports are bound.
1238 Interface* interface = scope->interface();
1239 for (Interface::Iterator it = interface->iterator();
1240 !it.done(); it.Advance()) {
1241 if (scope->LookupLocal(it.name()) == NULL) {
1242 ParserTraits::ReportMessage("module_export_undefined", it.name());
1248 interface->MakeModule(ok);
1250 interface->Freeze(ok);
1252 return factory()->NewModuleLiteral(body, interface, pos);
1256 Module* Parser::ParseModulePath(bool* ok) {
1259 // ModulePath '.' Identifier
1261 int pos = peek_position();
1262 Module* result = ParseModuleVariable(CHECK_OK);
1263 while (Check(Token::PERIOD)) {
1264 const AstRawString* name = ParseIdentifierName(CHECK_OK);
1266 if (FLAG_print_interface_details)
1267 PrintF("# Path .%.*s ", name->length(), name->raw_data());
1269 Module* member = factory()->NewModulePath(result, name, pos);
1270 result->interface()->Add(name, member->interface(), zone(), ok);
1273 if (FLAG_print_interfaces) {
1274 PrintF("PATH TYPE ERROR at '%.*s'\n", name->length(), name->raw_data());
1276 result->interface()->Print();
1278 member->interface()->Print();
1281 ParserTraits::ReportMessage("invalid_module_path", name);
1291 Module* Parser::ParseModuleVariable(bool* ok) {
1295 int pos = peek_position();
1296 const AstRawString* name =
1297 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1299 if (FLAG_print_interface_details)
1300 PrintF("# Module variable %.*s ", name->length(), name->raw_data());
1302 VariableProxy* proxy = scope_->NewUnresolved(
1303 factory(), name, Interface::NewModule(zone()),
1304 scanner()->location().beg_pos);
1306 return factory()->NewModuleVariable(proxy, pos);
1310 Module* Parser::ParseModuleUrl(bool* ok) {
1314 int pos = peek_position();
1315 Expect(Token::STRING, CHECK_OK);
1316 const AstRawString* symbol = GetSymbol(scanner());
1318 // TODO(ES6): Request JS resource from environment...
1321 if (FLAG_print_interface_details) PrintF("# Url ");
1324 // Create an empty literal as long as the feature isn't finished.
1326 Scope* scope = NewScope(scope_, MODULE_SCOPE);
1327 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
1328 body->set_scope(scope);
1329 Interface* interface = scope->interface();
1330 Module* result = factory()->NewModuleLiteral(body, interface, pos);
1331 interface->Freeze(ok);
1333 interface->Unify(scope->interface(), zone(), ok);
1339 Module* Parser::ParseModuleSpecifier(bool* ok) {
1344 if (peek() == Token::STRING) {
1345 return ParseModuleUrl(ok);
1347 return ParseModulePath(ok);
1352 Block* Parser::ParseImportDeclaration(bool* ok) {
1353 // ImportDeclaration:
1354 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';'
1356 // TODO(ES6): implement destructuring ImportSpecifiers
1358 int pos = peek_position();
1359 Expect(Token::IMPORT, CHECK_OK);
1360 ZoneList<const AstRawString*> names(1, zone());
1362 const AstRawString* name = ParseIdentifierName(CHECK_OK);
1363 names.Add(name, zone());
1364 while (peek() == Token::COMMA) {
1365 Consume(Token::COMMA);
1366 name = ParseIdentifierName(CHECK_OK);
1367 names.Add(name, zone());
1370 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1371 Module* module = ParseModuleSpecifier(CHECK_OK);
1372 ExpectSemicolon(CHECK_OK);
1374 // Generate a separate declaration for each identifier.
1375 // TODO(ES6): once we implement destructuring, make that one declaration.
1376 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
1377 for (int i = 0; i < names.length(); ++i) {
1379 if (FLAG_print_interface_details)
1380 PrintF("# Import %.*s ", name->length(), name->raw_data());
1382 Interface* interface = Interface::NewUnknown(zone());
1383 module->interface()->Add(names[i], interface, zone(), ok);
1386 if (FLAG_print_interfaces) {
1387 PrintF("IMPORT TYPE ERROR at '%.*s'\n", name->length(),
1390 module->interface()->Print();
1393 ParserTraits::ReportMessage("invalid_module_path", name);
1396 VariableProxy* proxy = NewUnresolved(names[i], LET, interface);
1397 Declaration* declaration =
1398 factory()->NewImportDeclaration(proxy, module, scope_, pos);
1399 Declare(declaration, true, CHECK_OK);
1406 Statement* Parser::ParseExportDeclaration(bool* ok) {
1407 // ExportDeclaration:
1408 // 'export' Identifier (',' Identifier)* ';'
1409 // 'export' VariableDeclaration
1410 // 'export' FunctionDeclaration
1411 // 'export' GeneratorDeclaration
1412 // 'export' ModuleDeclaration
1414 // TODO(ES6): implement structuring ExportSpecifiers
1416 Expect(Token::EXPORT, CHECK_OK);
1418 Statement* result = NULL;
1419 ZoneList<const AstRawString*> names(1, zone());
1421 case Token::IDENTIFIER: {
1422 int pos = position();
1423 const AstRawString* name =
1424 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1425 // Handle 'module' as a context-sensitive keyword.
1426 if (name != ast_value_factory_->module_string()) {
1427 names.Add(name, zone());
1428 while (peek() == Token::COMMA) {
1429 Consume(Token::COMMA);
1430 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1431 names.Add(name, zone());
1433 ExpectSemicolon(CHECK_OK);
1434 result = factory()->NewEmptyStatement(pos);
1436 result = ParseModuleDeclaration(&names, CHECK_OK);
1441 case Token::FUNCTION:
1442 result = ParseFunctionDeclaration(&names, CHECK_OK);
1448 result = ParseVariableStatement(kModuleElement, &names, CHECK_OK);
1453 ReportUnexpectedToken(scanner()->current_token());
1457 // Every export of a module may be assigned.
1458 for (int i = 0; i < names.length(); ++i) {
1459 Variable* var = scope_->Lookup(names[i]);
1461 // TODO(sigurds) This is an export that has no definition yet,
1462 // not clear what to do in this case.
1465 if (!IsImmutableVariableMode(var->mode())) {
1466 var->set_maybe_assigned();
1470 // Extract declared names into export declarations and interface.
1471 Interface* interface = scope_->interface();
1472 for (int i = 0; i < names.length(); ++i) {
1474 if (FLAG_print_interface_details)
1475 PrintF("# Export %.*s ", names[i]->length(), names[i]->raw_data());
1477 Interface* inner = Interface::NewUnknown(zone());
1478 interface->Add(names[i], inner, zone(), CHECK_OK);
1481 VariableProxy* proxy = NewUnresolved(names[i], LET, inner);
1483 // TODO(rossberg): Rethink whether we actually need to store export
1484 // declarations (for compilation?).
1485 // ExportDeclaration* declaration =
1486 // factory()->NewExportDeclaration(proxy, scope_, position);
1487 // scope_->AddDeclaration(declaration);
1490 DCHECK(result != NULL);
1495 Statement* Parser::ParseBlockElement(ZoneList<const AstRawString*>* labels,
1497 // (Ecma 262 5th Edition, clause 14):
1500 // FunctionDeclaration
1502 // In harmony mode we allow additionally the following productions
1503 // BlockElement (aka SourceElement):
1506 // GeneratorDeclaration
1509 case Token::FUNCTION:
1510 return ParseFunctionDeclaration(NULL, ok);
1512 return ParseVariableStatement(kModuleElement, NULL, ok);
1514 DCHECK(allow_harmony_scoping());
1515 if (strict_mode() == STRICT) {
1516 return ParseVariableStatement(kModuleElement, NULL, ok);
1520 return ParseStatement(labels, ok);
1525 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels,
1529 // VariableStatement
1531 // ExpressionStatement
1533 // IterationStatement
1534 // ContinueStatement
1538 // LabelledStatement
1542 // DebuggerStatement
1544 // Note: Since labels can only be used by 'break' and 'continue'
1545 // statements, which themselves are only valid within blocks,
1546 // iterations or 'switch' statements (i.e., BreakableStatements),
1547 // labels can be simply ignored in all other cases; except for
1548 // trivial labeled break statements 'label: break label' which is
1549 // parsed into an empty statement.
1552 return ParseBlock(labels, ok);
1554 case Token::SEMICOLON:
1556 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1559 return ParseIfStatement(labels, ok);
1562 return ParseDoWhileStatement(labels, ok);
1565 return ParseWhileStatement(labels, ok);
1568 return ParseForStatement(labels, ok);
1570 case Token::CONTINUE:
1571 return ParseContinueStatement(ok);
1574 return ParseBreakStatement(labels, ok);
1577 return ParseReturnStatement(ok);
1580 return ParseWithStatement(labels, ok);
1583 return ParseSwitchStatement(labels, ok);
1586 return ParseThrowStatement(ok);
1589 // NOTE: It is somewhat complicated to have labels on
1590 // try-statements. When breaking out of a try-finally statement,
1591 // one must take great care not to treat it as a
1592 // fall-through. It is much easier just to wrap the entire
1593 // try-statement in a statement block and put the labels there
1595 factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition);
1596 Target target(&this->target_stack_, result);
1597 TryStatement* statement = ParseTryStatement(CHECK_OK);
1598 if (result) result->AddStatement(statement, zone());
1602 case Token::FUNCTION: {
1603 // FunctionDeclaration is only allowed in the context of SourceElements
1604 // (Ecma 262 5th Edition, clause 14):
1607 // FunctionDeclaration
1608 // Common language extension is to allow function declaration in place
1609 // of any statement. This language extension is disabled in strict mode.
1611 // In Harmony mode, this case also handles the extension:
1613 // GeneratorDeclaration
1614 if (strict_mode() == STRICT) {
1615 ReportMessageAt(scanner()->peek_location(), "strict_function");
1619 return ParseFunctionDeclaration(NULL, ok);
1622 case Token::DEBUGGER:
1623 return ParseDebuggerStatement(ok);
1627 return ParseVariableStatement(kStatement, NULL, ok);
1630 DCHECK(allow_harmony_scoping());
1631 if (strict_mode() == STRICT) {
1632 return ParseVariableStatement(kStatement, NULL, ok);
1636 return ParseExpressionOrLabelledStatement(labels, ok);
1641 VariableProxy* Parser::NewUnresolved(const AstRawString* name,
1642 VariableMode mode, Interface* interface) {
1643 // If we are inside a function, a declaration of a var/const variable is a
1644 // truly local variable, and the scope of the variable is always the function
1646 // Let/const variables in harmony mode are always added to the immediately
1648 return DeclarationScope(mode)->NewUnresolved(
1649 factory(), name, interface, position());
1653 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
1654 VariableProxy* proxy = declaration->proxy();
1655 DCHECK(proxy->raw_name() != NULL);
1656 const AstRawString* name = proxy->raw_name();
1657 VariableMode mode = declaration->mode();
1658 Scope* declaration_scope = DeclarationScope(mode);
1659 Variable* var = NULL;
1661 // If a suitable scope exists, then we can statically declare this
1662 // variable and also set its mode. In any case, a Declaration node
1663 // will be added to the scope so that the declaration can be added
1664 // to the corresponding activation frame at runtime if necessary.
1665 // For instance declarations inside an eval scope need to be added
1666 // to the calling function context.
1667 // Similarly, strict mode eval scope does not leak variable declarations to
1668 // the caller's scope so we declare all locals, too.
1669 if (declaration_scope->is_function_scope() ||
1670 declaration_scope->is_strict_eval_scope() ||
1671 declaration_scope->is_block_scope() ||
1672 declaration_scope->is_module_scope() ||
1673 declaration_scope->is_global_scope()) {
1674 // Declare the variable in the declaration scope.
1675 // For the global scope, we have to check for collisions with earlier
1676 // (i.e., enclosing) global scopes, to maintain the illusion of a single
1678 var = declaration_scope->is_global_scope()
1679 ? declaration_scope->Lookup(name)
1680 : declaration_scope->LookupLocal(name);
1682 // Declare the name.
1683 var = declaration_scope->DeclareLocal(name, mode,
1684 declaration->initialization(),
1685 kNotAssigned, proxy->interface());
1686 } else if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode())
1687 || ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) &&
1688 !declaration_scope->is_global_scope())) {
1689 // The name was declared in this scope before; check for conflicting
1690 // re-declarations. We have a conflict if either of the declarations is
1691 // not a var (in the global scope, we also have to ignore legacy const for
1692 // compatibility). There is similar code in runtime.cc in the Declare
1693 // functions. The function CheckConflictingVarDeclarations checks for
1694 // var and let bindings from different scopes whereas this is a check for
1695 // conflicting declarations within the same scope. This check also covers
1698 // function () { let x; { var x; } }
1700 // because the var declaration is hoisted to the function scope where 'x'
1701 // is already bound.
1702 DCHECK(IsDeclaredVariableMode(var->mode()));
1703 if (allow_harmony_scoping() && strict_mode() == STRICT) {
1704 // In harmony we treat re-declarations as early errors. See
1705 // ES5 16 for a definition of early errors.
1706 ParserTraits::ReportMessage("var_redeclaration", name);
1710 Expression* expression = NewThrowTypeError(
1711 "var_redeclaration", name, declaration->position());
1712 declaration_scope->SetIllegalRedeclaration(expression);
1713 } else if (mode == VAR) {
1714 var->set_maybe_assigned();
1718 // We add a declaration node for every declaration. The compiler
1719 // will only generate code if necessary. In particular, declarations
1720 // for inner local variables that do not represent functions won't
1721 // result in any generated code.
1723 // Note that we always add an unresolved proxy even if it's not
1724 // used, simply because we don't know in this method (w/o extra
1725 // parameters) if the proxy is needed or not. The proxy will be
1726 // bound during variable resolution time unless it was pre-bound
1729 // WARNING: This will lead to multiple declaration nodes for the
1730 // same variable if it is declared several times. This is not a
1731 // semantic issue as long as we keep the source order, but it may be
1732 // a performance issue since it may lead to repeated
1733 // RuntimeHidden_DeclareLookupSlot calls.
1734 declaration_scope->AddDeclaration(declaration);
1736 if (mode == CONST_LEGACY && declaration_scope->is_global_scope()) {
1737 // For global const variables we bind the proxy to a variable.
1738 DCHECK(resolve); // should be set by all callers
1739 Variable::Kind kind = Variable::NORMAL;
1741 Variable(declaration_scope, name, mode, true, kind,
1742 kNeedsInitialization, kNotAssigned, proxy->interface());
1743 } else if (declaration_scope->is_eval_scope() &&
1744 declaration_scope->strict_mode() == SLOPPY) {
1745 // For variable declarations in a sloppy eval scope the proxy is bound
1746 // to a lookup variable to force a dynamic declaration using the
1747 // DeclareLookupSlot runtime function.
1748 Variable::Kind kind = Variable::NORMAL;
1749 // TODO(sigurds) figure out if kNotAssigned is OK here
1750 var = new (zone()) Variable(declaration_scope, name, mode, true, kind,
1751 declaration->initialization(), kNotAssigned,
1752 proxy->interface());
1753 var->AllocateTo(Variable::LOOKUP, -1);
1757 // If requested and we have a local variable, bind the proxy to the variable
1758 // at parse-time. This is used for functions (and consts) declared inside
1759 // statements: the corresponding function (or const) variable must be in the
1760 // function scope and not a statement-local scope, e.g. as provided with a
1761 // 'with' statement:
1767 // which is translated into:
1770 // // in this case this is not: 'var f; f = function () {};'
1771 // var f = function () {};
1774 // Note that if 'f' is accessed from inside the 'with' statement, it
1775 // will be allocated in the context (because we must be able to look
1776 // it up dynamically) but it will also be accessed statically, i.e.,
1777 // with a context slot index and a context chain length for this
1778 // initialization code. Thus, inside the 'with' statement, we need
1779 // both access to the static and the dynamic context chain; the
1780 // runtime needs to provide both.
1781 if (resolve && var != NULL) {
1784 if (FLAG_harmony_modules) {
1787 if (FLAG_print_interface_details) {
1788 PrintF("# Declare %.*s ", var->raw_name()->length(),
1789 var->raw_name()->raw_data());
1792 proxy->interface()->Unify(var->interface(), zone(), &ok);
1795 if (FLAG_print_interfaces) {
1796 PrintF("DECLARE TYPE ERROR\n");
1798 proxy->interface()->Print();
1800 var->interface()->Print();
1803 ParserTraits::ReportMessage("module_type_error", name);
1810 // Language extension which is only enabled for source files loaded
1811 // through the API's extension mechanism. A native function
1812 // declaration is resolved by looking up the function through a
1813 // callback provided by the extension.
1814 Statement* Parser::ParseNativeDeclaration(bool* ok) {
1815 int pos = peek_position();
1816 Expect(Token::FUNCTION, CHECK_OK);
1817 // Allow "eval" or "arguments" for backward compatibility.
1818 const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1819 Expect(Token::LPAREN, CHECK_OK);
1820 bool done = (peek() == Token::RPAREN);
1822 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1823 done = (peek() == Token::RPAREN);
1825 Expect(Token::COMMA, CHECK_OK);
1828 Expect(Token::RPAREN, CHECK_OK);
1829 Expect(Token::SEMICOLON, CHECK_OK);
1831 // Make sure that the function containing the native declaration
1832 // isn't lazily compiled. The extension structures are only
1833 // accessible while parsing the first time not when reparsing
1834 // because of lazy compilation.
1835 DeclarationScope(VAR)->ForceEagerCompilation();
1837 // TODO(1240846): It's weird that native function declarations are
1838 // introduced dynamically when we meet their declarations, whereas
1839 // other functions are set up when entering the surrounding scope.
1840 VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue());
1841 Declaration* declaration =
1842 factory()->NewVariableDeclaration(proxy, VAR, scope_, pos);
1843 Declare(declaration, true, CHECK_OK);
1844 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral(
1845 name, extension_, RelocInfo::kNoPosition);
1846 return factory()->NewExpressionStatement(
1847 factory()->NewAssignment(
1848 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition),
1853 Statement* Parser::ParseFunctionDeclaration(
1854 ZoneList<const AstRawString*>* names, bool* ok) {
1855 // FunctionDeclaration ::
1856 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
1857 // GeneratorDeclaration ::
1858 // 'function' '*' Identifier '(' FormalParameterListopt ')'
1859 // '{' FunctionBody '}'
1860 Expect(Token::FUNCTION, CHECK_OK);
1861 int pos = position();
1862 bool is_generator = allow_generators() && Check(Token::MUL);
1863 bool is_strict_reserved = false;
1864 const AstRawString* name = ParseIdentifierOrStrictReservedWord(
1865 &is_strict_reserved, CHECK_OK);
1866 FunctionLiteral* fun = ParseFunctionLiteral(name,
1867 scanner()->location(),
1871 FunctionLiteral::DECLARATION,
1872 FunctionLiteral::NORMAL_ARITY,
1874 // Even if we're not at the top-level of the global or a function
1875 // scope, we treat it as such and introduce the function with its
1876 // initial value upon entering the corresponding scope.
1877 // In ES6, a function behaves as a lexical binding, except in the
1878 // global scope, or the initial scope of eval or another function.
1880 allow_harmony_scoping() && strict_mode() == STRICT &&
1881 !(scope_->is_global_scope() || scope_->is_eval_scope() ||
1882 scope_->is_function_scope()) ? LET : VAR;
1883 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
1884 Declaration* declaration =
1885 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
1886 Declare(declaration, true, CHECK_OK);
1887 if (names) names->Add(name, zone());
1888 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1892 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) {
1893 if (allow_harmony_scoping() && strict_mode() == STRICT) {
1894 return ParseScopedBlock(labels, ok);
1898 // '{' Statement* '}'
1900 // Note that a Block does not introduce a new execution scope!
1901 // (ECMA-262, 3rd, 12.2)
1903 // Construct block expecting 16 statements.
1905 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
1906 Target target(&this->target_stack_, result);
1907 Expect(Token::LBRACE, CHECK_OK);
1908 while (peek() != Token::RBRACE) {
1909 Statement* stat = ParseStatement(NULL, CHECK_OK);
1910 if (stat && !stat->IsEmpty()) {
1911 result->AddStatement(stat, zone());
1914 Expect(Token::RBRACE, CHECK_OK);
1919 Block* Parser::ParseScopedBlock(ZoneList<const AstRawString*>* labels,
1921 // The harmony mode uses block elements instead of statements.
1924 // '{' BlockElement* '}'
1926 // Construct block expecting 16 statements.
1928 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
1929 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
1931 // Parse the statements and collect escaping labels.
1932 Expect(Token::LBRACE, CHECK_OK);
1933 block_scope->set_start_position(scanner()->location().beg_pos);
1934 { BlockState block_state(&scope_, block_scope);
1935 TargetCollector collector(zone());
1936 Target target(&this->target_stack_, &collector);
1937 Target target_body(&this->target_stack_, body);
1939 while (peek() != Token::RBRACE) {
1940 Statement* stat = ParseBlockElement(NULL, CHECK_OK);
1941 if (stat && !stat->IsEmpty()) {
1942 body->AddStatement(stat, zone());
1946 Expect(Token::RBRACE, CHECK_OK);
1947 block_scope->set_end_position(scanner()->location().end_pos);
1948 block_scope = block_scope->FinalizeBlockScope();
1949 body->set_scope(block_scope);
1954 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
1955 ZoneList<const AstRawString*>* names,
1957 // VariableStatement ::
1958 // VariableDeclarations ';'
1960 const AstRawString* ignore;
1962 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK);
1963 ExpectSemicolon(CHECK_OK);
1968 // If the variable declaration declares exactly one non-const
1969 // variable, then *out is set to that variable. In all other cases,
1970 // *out is untouched; in particular, it is the caller's responsibility
1971 // to initialize it properly. This mechanism is used for the parsing
1972 // of 'for-in' loops.
1973 Block* Parser::ParseVariableDeclarations(
1974 VariableDeclarationContext var_context,
1975 VariableDeclarationProperties* decl_props,
1976 ZoneList<const AstRawString*>* names,
1977 const AstRawString** out,
1979 // VariableDeclarations ::
1980 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
1982 // The ES6 Draft Rev3 specifies the following grammar for const declarations
1984 // ConstDeclaration ::
1985 // const ConstBinding (',' ConstBinding)* ';'
1987 // Identifier '=' AssignmentExpression
1991 // BindingPattern '=' AssignmentExpression
1993 int pos = peek_position();
1994 VariableMode mode = VAR;
1995 // True if the binding needs initialization. 'let' and 'const' declared
1996 // bindings are created uninitialized by their declaration nodes and
1997 // need initialization. 'var' declared bindings are always initialized
1998 // immediately by their declaration nodes.
1999 bool needs_init = false;
2000 bool is_const = false;
2001 Token::Value init_op = Token::INIT_VAR;
2002 if (peek() == Token::VAR) {
2003 Consume(Token::VAR);
2004 } else if (peek() == Token::CONST) {
2005 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
2007 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
2009 // * It is a Syntax Error if the code that matches this production is not
2010 // contained in extended code.
2012 // However disallowing const in sloppy mode will break compatibility with
2013 // existing pages. Therefore we keep allowing const with the old
2014 // non-harmony semantics in sloppy mode.
2015 Consume(Token::CONST);
2016 switch (strict_mode()) {
2018 mode = CONST_LEGACY;
2019 init_op = Token::INIT_CONST_LEGACY;
2022 if (allow_harmony_scoping()) {
2023 if (var_context == kStatement) {
2024 // In strict mode 'const' declarations are only allowed in source
2025 // element positions.
2026 ReportMessage("unprotected_const");
2031 init_op = Token::INIT_CONST;
2033 ReportMessage("strict_const");
2040 } else if (peek() == Token::LET && strict_mode() == STRICT) {
2041 DCHECK(allow_harmony_scoping());
2042 Consume(Token::LET);
2043 if (var_context == kStatement) {
2044 // Let declarations are only allowed in source element positions.
2045 ReportMessage("unprotected_let");
2051 init_op = Token::INIT_LET;
2053 UNREACHABLE(); // by current callers
2056 Scope* declaration_scope = DeclarationScope(mode);
2058 // The scope of a var/const declared variable anywhere inside a function
2059 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
2060 // transform a source-level var/const declaration into a (Function)
2061 // Scope declaration, and rewrite the source-level initialization into an
2062 // assignment statement. We use a block to collect multiple assignments.
2064 // We mark the block as initializer block because we don't want the
2065 // rewriter to add a '.result' assignment to such a block (to get compliant
2066 // behavior for code such as print(eval('var x = 7')), and for cosmetic
2067 // reasons when pretty-printing. Also, unless an assignment (initialization)
2068 // is inside an initializer block, it is ignored.
2070 // Create new block with one expected declaration.
2071 Block* block = factory()->NewBlock(NULL, 1, true, pos);
2072 int nvars = 0; // the number of variables declared
2073 const AstRawString* name = NULL;
2075 if (fni_ != NULL) fni_->Enter();
2077 // Parse variable name.
2078 if (nvars > 0) Consume(Token::COMMA);
2079 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
2080 if (fni_ != NULL) fni_->PushVariableName(name);
2082 // Declare variable.
2083 // Note that we *always* must treat the initial value via a separate init
2084 // assignment for variables and constants because the value must be assigned
2085 // when the variable is encountered in the source. But the variable/constant
2086 // is declared (and set to 'undefined') upon entering the function within
2087 // which the variable or constant is declared. Only function variables have
2088 // an initial value in the declaration (because they are initialized upon
2089 // entering the function).
2091 // If we have a const declaration, in an inner scope, the proxy is always
2092 // bound to the declared variable (independent of possibly surrounding with
2094 // For let/const declarations in harmony mode, we can also immediately
2095 // pre-resolve the proxy because it resides in the same scope as the
2097 Interface* interface =
2098 is_const ? Interface::NewConst() : Interface::NewValue();
2099 VariableProxy* proxy = NewUnresolved(name, mode, interface);
2100 Declaration* declaration =
2101 factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
2102 Declare(declaration, mode != VAR, CHECK_OK);
2104 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
2105 ReportMessage("too_many_variables");
2109 if (names) names->Add(name, zone());
2111 // Parse initialization expression if present and/or needed. A
2112 // declaration of the form:
2116 // is syntactic sugar for:
2120 // In particular, we need to re-lookup 'v' (in scope_, not
2121 // declaration_scope) as it may be a different 'v' than the 'v' in the
2122 // declaration (e.g., if we are inside a 'with' statement or 'catch'
2125 // However, note that const declarations are different! A const
2126 // declaration of the form:
2130 // is *not* syntactic sugar for:
2134 // The "variable" c initialized to x is the same as the declared
2135 // one - there is no re-lookup (see the last parameter of the
2136 // Declare() call above).
2138 Scope* initialization_scope = is_const ? declaration_scope : scope_;
2139 Expression* value = NULL;
2141 // Harmony consts have non-optional initializers.
2142 if (peek() == Token::ASSIGN || mode == CONST) {
2143 Expect(Token::ASSIGN, CHECK_OK);
2145 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
2146 // Don't infer if it is "a = function(){...}();"-like expression.
2148 value->AsCall() == NULL &&
2149 value->AsCallNew() == NULL) {
2152 fni_->RemoveLastFunction();
2154 if (decl_props != NULL) *decl_props = kHasInitializers;
2157 // Record the end position of the initializer.
2158 if (proxy->var() != NULL) {
2159 proxy->var()->set_initializer_position(position());
2162 // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
2163 if (value == NULL && needs_init) {
2164 value = GetLiteralUndefined(position());
2167 // Global variable declarations must be compiled in a specific
2168 // way. When the script containing the global variable declaration
2169 // is entered, the global variable must be declared, so that if it
2170 // doesn't exist (on the global object itself, see ES5 errata) it
2171 // gets created with an initial undefined value. This is handled
2172 // by the declarations part of the function representing the
2173 // top-level global code; see Runtime::DeclareGlobalVariable. If
2174 // it already exists (in the object or in a prototype), it is
2175 // *not* touched until the variable declaration statement is
2178 // Executing the variable declaration statement will always
2179 // guarantee to give the global object an own property.
2180 // This way, global variable declarations can shadow
2181 // properties in the prototype chain, but only after the variable
2182 // declaration statement has been executed. This is important in
2183 // browsers where the global object (window) has lots of
2184 // properties defined in prototype objects.
2185 if (initialization_scope->is_global_scope() &&
2186 !IsLexicalVariableMode(mode)) {
2187 // Compute the arguments for the runtime call.
2188 ZoneList<Expression*>* arguments =
2189 new(zone()) ZoneList<Expression*>(3, zone());
2190 // We have at least 1 parameter.
2191 arguments->Add(factory()->NewStringLiteral(name, pos), zone());
2192 CallRuntime* initialize;
2195 arguments->Add(value, zone());
2196 value = NULL; // zap the value to avoid the unnecessary assignment
2198 // Construct the call to Runtime_InitializeConstGlobal
2199 // and add it to the initialization statement block.
2200 // Note that the function does different things depending on
2201 // the number of arguments (1 or 2).
2202 initialize = factory()->NewCallRuntime(
2203 ast_value_factory_->initialize_const_global_string(),
2204 Runtime::FunctionForId(Runtime::kInitializeConstGlobal),
2208 // We may want to pass singleton to avoid Literal allocations.
2209 StrictMode strict_mode = initialization_scope->strict_mode();
2210 arguments->Add(factory()->NewNumberLiteral(strict_mode, pos), zone());
2212 // Be careful not to assign a value to the global variable if
2213 // we're in a with. The initialization value should not
2214 // necessarily be stored in the global object in that case,
2215 // which is why we need to generate a separate assignment node.
2216 if (value != NULL && !inside_with()) {
2217 arguments->Add(value, zone());
2218 value = NULL; // zap the value to avoid the unnecessary assignment
2219 // Construct the call to Runtime_InitializeVarGlobal
2220 // and add it to the initialization statement block.
2221 initialize = factory()->NewCallRuntime(
2222 ast_value_factory_->initialize_var_global_string(),
2223 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), arguments,
2230 if (initialize != NULL) {
2231 block->AddStatement(factory()->NewExpressionStatement(
2232 initialize, RelocInfo::kNoPosition),
2235 } else if (needs_init) {
2236 // Constant initializations always assign to the declared constant which
2237 // is always at the function scope level. This is only relevant for
2238 // dynamically looked-up variables and constants (the start context for
2239 // constant lookups is always the function context, while it is the top
2240 // context for var declared variables). Sigh...
2241 // For 'let' and 'const' declared variables in harmony mode the
2242 // initialization also always assigns to the declared variable.
2243 DCHECK(proxy != NULL);
2244 DCHECK(proxy->var() != NULL);
2245 DCHECK(value != NULL);
2246 Assignment* assignment =
2247 factory()->NewAssignment(init_op, proxy, value, pos);
2248 block->AddStatement(
2249 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
2254 // Add an assignment node to the initialization statement block if we still
2255 // have a pending initialization value.
2256 if (value != NULL) {
2257 DCHECK(mode == VAR);
2258 // 'var' initializations are simply assignments (with all the consequences
2259 // if they are inside a 'with' statement - they may change a 'with' object
2261 VariableProxy* proxy =
2262 initialization_scope->NewUnresolved(factory(), name, interface);
2263 Assignment* assignment =
2264 factory()->NewAssignment(init_op, proxy, value, pos);
2265 block->AddStatement(
2266 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
2270 if (fni_ != NULL) fni_->Leave();
2271 } while (peek() == Token::COMMA);
2273 // If there was a single non-const declaration, return it in the output
2274 // parameter for possible use by for/in.
2275 if (nvars == 1 && !is_const) {
2283 static bool ContainsLabel(ZoneList<const AstRawString*>* labels,
2284 const AstRawString* label) {
2285 DCHECK(label != NULL);
2286 if (labels != NULL) {
2287 for (int i = labels->length(); i-- > 0; ) {
2288 if (labels->at(i) == label) {
2297 Statement* Parser::ParseExpressionOrLabelledStatement(
2298 ZoneList<const AstRawString*>* labels, bool* ok) {
2299 // ExpressionStatement | LabelledStatement ::
2301 // Identifier ':' Statement
2302 int pos = peek_position();
2303 bool starts_with_idenfifier = peek_any_identifier();
2304 Expression* expr = ParseExpression(true, CHECK_OK);
2305 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
2306 expr->AsVariableProxy() != NULL &&
2307 !expr->AsVariableProxy()->is_this()) {
2308 // Expression is a single identifier, and not, e.g., a parenthesized
2310 VariableProxy* var = expr->AsVariableProxy();
2311 const AstRawString* label = var->raw_name();
2312 // TODO(1240780): We don't check for redeclaration of labels
2313 // during preparsing since keeping track of the set of active
2314 // labels requires nontrivial changes to the way scopes are
2315 // structured. However, these are probably changes we want to
2316 // make later anyway so we should go back and fix this then.
2317 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
2318 ParserTraits::ReportMessage("label_redeclaration", label);
2322 if (labels == NULL) {
2323 labels = new(zone()) ZoneList<const AstRawString*>(4, zone());
2325 labels->Add(label, zone());
2326 // Remove the "ghost" variable that turned out to be a label
2327 // from the top scope. This way, we don't try to resolve it
2328 // during the scope processing.
2329 scope_->RemoveUnresolved(var);
2330 Expect(Token::COLON, CHECK_OK);
2331 return ParseStatement(labels, ok);
2334 // If we have an extension, we allow a native function declaration.
2335 // A native function declaration starts with "native function" with
2336 // no line-terminator between the two words.
2337 if (extension_ != NULL &&
2338 peek() == Token::FUNCTION &&
2339 !scanner()->HasAnyLineTerminatorBeforeNext() &&
2341 expr->AsVariableProxy() != NULL &&
2342 expr->AsVariableProxy()->raw_name() ==
2343 ast_value_factory_->native_string() &&
2344 !scanner()->literal_contains_escapes()) {
2345 return ParseNativeDeclaration(ok);
2348 // Parsed expression statement, or the context-sensitive 'module' keyword.
2349 // Only expect semicolon in the former case.
2350 if (!FLAG_harmony_modules ||
2351 peek() != Token::IDENTIFIER ||
2352 scanner()->HasAnyLineTerminatorBeforeNext() ||
2353 expr->AsVariableProxy() == NULL ||
2354 expr->AsVariableProxy()->raw_name() !=
2355 ast_value_factory_->module_string() ||
2356 scanner()->literal_contains_escapes()) {
2357 ExpectSemicolon(CHECK_OK);
2359 return factory()->NewExpressionStatement(expr, pos);
2363 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels,
2366 // 'if' '(' Expression ')' Statement ('else' Statement)?
2368 int pos = peek_position();
2369 Expect(Token::IF, CHECK_OK);
2370 Expect(Token::LPAREN, CHECK_OK);
2371 Expression* condition = ParseExpression(true, CHECK_OK);
2372 Expect(Token::RPAREN, CHECK_OK);
2373 Statement* then_statement = ParseStatement(labels, CHECK_OK);
2374 Statement* else_statement = NULL;
2375 if (peek() == Token::ELSE) {
2377 else_statement = ParseStatement(labels, CHECK_OK);
2379 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2381 return factory()->NewIfStatement(
2382 condition, then_statement, else_statement, pos);
2386 Statement* Parser::ParseContinueStatement(bool* ok) {
2387 // ContinueStatement ::
2388 // 'continue' Identifier? ';'
2390 int pos = peek_position();
2391 Expect(Token::CONTINUE, CHECK_OK);
2392 const AstRawString* label = NULL;
2393 Token::Value tok = peek();
2394 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2395 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2396 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2397 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
2399 IterationStatement* target = LookupContinueTarget(label, CHECK_OK);
2400 if (target == NULL) {
2401 // Illegal continue statement.
2402 const char* message = "illegal_continue";
2403 if (label != NULL) {
2404 message = "unknown_label";
2406 ParserTraits::ReportMessage(message, label);
2410 ExpectSemicolon(CHECK_OK);
2411 return factory()->NewContinueStatement(target, pos);
2415 Statement* Parser::ParseBreakStatement(ZoneList<const AstRawString*>* labels,
2417 // BreakStatement ::
2418 // 'break' Identifier? ';'
2420 int pos = peek_position();
2421 Expect(Token::BREAK, CHECK_OK);
2422 const AstRawString* label = NULL;
2423 Token::Value tok = peek();
2424 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2425 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2426 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2427 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
2429 // Parse labeled break statements that target themselves into
2430 // empty statements, e.g. 'l1: l2: l3: break l2;'
2431 if (label != NULL && ContainsLabel(labels, label)) {
2432 ExpectSemicolon(CHECK_OK);
2433 return factory()->NewEmptyStatement(pos);
2435 BreakableStatement* target = NULL;
2436 target = LookupBreakTarget(label, CHECK_OK);
2437 if (target == NULL) {
2438 // Illegal break statement.
2439 const char* message = "illegal_break";
2440 if (label != NULL) {
2441 message = "unknown_label";
2443 ParserTraits::ReportMessage(message, label);
2447 ExpectSemicolon(CHECK_OK);
2448 return factory()->NewBreakStatement(target, pos);
2452 Statement* Parser::ParseReturnStatement(bool* ok) {
2453 // ReturnStatement ::
2454 // 'return' Expression? ';'
2456 // Consume the return token. It is necessary to do that before
2457 // reporting any errors on it, because of the way errors are
2458 // reported (underlining).
2459 Expect(Token::RETURN, CHECK_OK);
2460 Scanner::Location loc = scanner()->location();
2462 Token::Value tok = peek();
2464 Expression* return_value;
2465 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
2466 tok == Token::SEMICOLON ||
2467 tok == Token::RBRACE ||
2468 tok == Token::EOS) {
2469 return_value = GetLiteralUndefined(position());
2471 return_value = ParseExpression(true, CHECK_OK);
2473 ExpectSemicolon(CHECK_OK);
2474 if (is_generator()) {
2475 Expression* generator = factory()->NewVariableProxy(
2476 function_state_->generator_object_variable());
2477 Expression* yield = factory()->NewYield(
2478 generator, return_value, Yield::FINAL, loc.beg_pos);
2479 result = factory()->NewExpressionStatement(yield, loc.beg_pos);
2481 result = factory()->NewReturnStatement(return_value, loc.beg_pos);
2484 Scope* decl_scope = scope_->DeclarationScope();
2485 if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) {
2486 ReportMessageAt(loc, "illegal_return");
2494 Statement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels,
2497 // 'with' '(' Expression ')' Statement
2499 Expect(Token::WITH, CHECK_OK);
2500 int pos = position();
2502 if (strict_mode() == STRICT) {
2503 ReportMessage("strict_mode_with");
2508 Expect(Token::LPAREN, CHECK_OK);
2509 Expression* expr = ParseExpression(true, CHECK_OK);
2510 Expect(Token::RPAREN, CHECK_OK);
2512 scope_->DeclarationScope()->RecordWithStatement();
2513 Scope* with_scope = NewScope(scope_, WITH_SCOPE);
2515 { BlockState block_state(&scope_, with_scope);
2516 with_scope->set_start_position(scanner()->peek_location().beg_pos);
2517 stmt = ParseStatement(labels, CHECK_OK);
2518 with_scope->set_end_position(scanner()->location().end_pos);
2520 return factory()->NewWithStatement(with_scope, expr, stmt, pos);
2524 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
2526 // 'case' Expression ':' Statement*
2527 // 'default' ':' Statement*
2529 Expression* label = NULL; // NULL expression indicates default case
2530 if (peek() == Token::CASE) {
2531 Expect(Token::CASE, CHECK_OK);
2532 label = ParseExpression(true, CHECK_OK);
2534 Expect(Token::DEFAULT, CHECK_OK);
2535 if (*default_seen_ptr) {
2536 ReportMessage("multiple_defaults_in_switch");
2540 *default_seen_ptr = true;
2542 Expect(Token::COLON, CHECK_OK);
2543 int pos = position();
2544 ZoneList<Statement*>* statements =
2545 new(zone()) ZoneList<Statement*>(5, zone());
2546 while (peek() != Token::CASE &&
2547 peek() != Token::DEFAULT &&
2548 peek() != Token::RBRACE) {
2549 Statement* stat = ParseStatement(NULL, CHECK_OK);
2550 statements->Add(stat, zone());
2553 return factory()->NewCaseClause(label, statements, pos);
2557 SwitchStatement* Parser::ParseSwitchStatement(
2558 ZoneList<const AstRawString*>* labels, bool* ok) {
2559 // SwitchStatement ::
2560 // 'switch' '(' Expression ')' '{' CaseClause* '}'
2562 SwitchStatement* statement =
2563 factory()->NewSwitchStatement(labels, peek_position());
2564 Target target(&this->target_stack_, statement);
2566 Expect(Token::SWITCH, CHECK_OK);
2567 Expect(Token::LPAREN, CHECK_OK);
2568 Expression* tag = ParseExpression(true, CHECK_OK);
2569 Expect(Token::RPAREN, CHECK_OK);
2571 bool default_seen = false;
2572 ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4, zone());
2573 Expect(Token::LBRACE, CHECK_OK);
2574 while (peek() != Token::RBRACE) {
2575 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
2576 cases->Add(clause, zone());
2578 Expect(Token::RBRACE, CHECK_OK);
2580 if (statement) statement->Initialize(tag, cases);
2585 Statement* Parser::ParseThrowStatement(bool* ok) {
2586 // ThrowStatement ::
2587 // 'throw' Expression ';'
2589 Expect(Token::THROW, CHECK_OK);
2590 int pos = position();
2591 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
2592 ReportMessage("newline_after_throw");
2596 Expression* exception = ParseExpression(true, CHECK_OK);
2597 ExpectSemicolon(CHECK_OK);
2599 return factory()->NewExpressionStatement(
2600 factory()->NewThrow(exception, pos), pos);
2604 TryStatement* Parser::ParseTryStatement(bool* ok) {
2606 // 'try' Block Catch
2607 // 'try' Block Finally
2608 // 'try' Block Catch Finally
2611 // 'catch' '(' Identifier ')' Block
2616 Expect(Token::TRY, CHECK_OK);
2617 int pos = position();
2619 TargetCollector try_collector(zone());
2622 { Target target(&this->target_stack_, &try_collector);
2623 try_block = ParseBlock(NULL, CHECK_OK);
2626 Token::Value tok = peek();
2627 if (tok != Token::CATCH && tok != Token::FINALLY) {
2628 ReportMessage("no_catch_or_finally");
2633 // If we can break out from the catch block and there is a finally block,
2634 // then we will need to collect escaping targets from the catch
2635 // block. Since we don't know yet if there will be a finally block, we
2636 // always collect the targets.
2637 TargetCollector catch_collector(zone());
2638 Scope* catch_scope = NULL;
2639 Variable* catch_variable = NULL;
2640 Block* catch_block = NULL;
2641 const AstRawString* name = NULL;
2642 if (tok == Token::CATCH) {
2643 Consume(Token::CATCH);
2645 Expect(Token::LPAREN, CHECK_OK);
2646 catch_scope = NewScope(scope_, CATCH_SCOPE);
2647 catch_scope->set_start_position(scanner()->location().beg_pos);
2648 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
2650 Expect(Token::RPAREN, CHECK_OK);
2652 Target target(&this->target_stack_, &catch_collector);
2654 allow_harmony_scoping() && strict_mode() == STRICT ? LET : VAR;
2655 catch_variable = catch_scope->DeclareLocal(name, mode, kCreatedInitialized);
2656 BlockState block_state(&scope_, catch_scope);
2657 catch_block = ParseBlock(NULL, CHECK_OK);
2659 catch_scope->set_end_position(scanner()->location().end_pos);
2663 Block* finally_block = NULL;
2664 DCHECK(tok == Token::FINALLY || catch_block != NULL);
2665 if (tok == Token::FINALLY) {
2666 Consume(Token::FINALLY);
2667 finally_block = ParseBlock(NULL, CHECK_OK);
2670 // Simplify the AST nodes by converting:
2671 // 'try B0 catch B1 finally B2'
2673 // 'try { try B0 catch B1 } finally B2'
2675 if (catch_block != NULL && finally_block != NULL) {
2676 // If we have both, create an inner try/catch.
2677 DCHECK(catch_scope != NULL && catch_variable != NULL);
2678 int index = function_state_->NextHandlerIndex();
2679 TryCatchStatement* statement = factory()->NewTryCatchStatement(
2680 index, try_block, catch_scope, catch_variable, catch_block,
2681 RelocInfo::kNoPosition);
2682 statement->set_escaping_targets(try_collector.targets());
2683 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
2684 try_block->AddStatement(statement, zone());
2685 catch_block = NULL; // Clear to indicate it's been handled.
2688 TryStatement* result = NULL;
2689 if (catch_block != NULL) {
2690 DCHECK(finally_block == NULL);
2691 DCHECK(catch_scope != NULL && catch_variable != NULL);
2692 int index = function_state_->NextHandlerIndex();
2693 result = factory()->NewTryCatchStatement(
2694 index, try_block, catch_scope, catch_variable, catch_block, pos);
2696 DCHECK(finally_block != NULL);
2697 int index = function_state_->NextHandlerIndex();
2698 result = factory()->NewTryFinallyStatement(
2699 index, try_block, finally_block, pos);
2700 // Combine the jump targets of the try block and the possible catch block.
2701 try_collector.targets()->AddAll(*catch_collector.targets(), zone());
2704 result->set_escaping_targets(try_collector.targets());
2709 DoWhileStatement* Parser::ParseDoWhileStatement(
2710 ZoneList<const AstRawString*>* labels, bool* ok) {
2712 // 'do' Statement 'while' '(' Expression ')' ';'
2714 DoWhileStatement* loop =
2715 factory()->NewDoWhileStatement(labels, peek_position());
2716 Target target(&this->target_stack_, loop);
2718 Expect(Token::DO, CHECK_OK);
2719 Statement* body = ParseStatement(NULL, CHECK_OK);
2720 Expect(Token::WHILE, CHECK_OK);
2721 Expect(Token::LPAREN, CHECK_OK);
2723 Expression* cond = ParseExpression(true, CHECK_OK);
2724 Expect(Token::RPAREN, CHECK_OK);
2726 // Allow do-statements to be terminated with and without
2727 // semi-colons. This allows code such as 'do;while(0)return' to
2728 // parse, which would not be the case if we had used the
2729 // ExpectSemicolon() functionality here.
2730 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
2732 if (loop != NULL) loop->Initialize(cond, body);
2737 WhileStatement* Parser::ParseWhileStatement(
2738 ZoneList<const AstRawString*>* labels, bool* ok) {
2739 // WhileStatement ::
2740 // 'while' '(' Expression ')' Statement
2742 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position());
2743 Target target(&this->target_stack_, loop);
2745 Expect(Token::WHILE, CHECK_OK);
2746 Expect(Token::LPAREN, CHECK_OK);
2747 Expression* cond = ParseExpression(true, CHECK_OK);
2748 Expect(Token::RPAREN, CHECK_OK);
2749 Statement* body = ParseStatement(NULL, CHECK_OK);
2751 if (loop != NULL) loop->Initialize(cond, body);
2756 bool Parser::CheckInOrOf(bool accept_OF,
2757 ForEachStatement::VisitMode* visit_mode) {
2758 if (Check(Token::IN)) {
2759 *visit_mode = ForEachStatement::ENUMERATE;
2761 } else if (accept_OF && CheckContextualKeyword(CStrVector("of"))) {
2762 *visit_mode = ForEachStatement::ITERATE;
2769 void Parser::InitializeForEachStatement(ForEachStatement* stmt,
2771 Expression* subject,
2773 ForOfStatement* for_of = stmt->AsForOfStatement();
2775 if (for_of != NULL) {
2776 Variable* iterator = scope_->DeclarationScope()->NewTemporary(
2777 ast_value_factory_->dot_iterator_string());
2778 Variable* result = scope_->DeclarationScope()->NewTemporary(
2779 ast_value_factory_->dot_result_string());
2781 Expression* assign_iterator;
2782 Expression* next_result;
2783 Expression* result_done;
2784 Expression* assign_each;
2786 // var iterator = subject[Symbol.iterator]();
2787 assign_iterator = factory()->NewAssignment(
2788 Token::ASSIGN, factory()->NewVariableProxy(iterator),
2789 GetIterator(subject, factory()), RelocInfo::kNoPosition);
2791 // var result = iterator.next();
2793 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
2794 Expression* next_literal = factory()->NewStringLiteral(
2795 ast_value_factory_->next_string(), RelocInfo::kNoPosition);
2796 Expression* next_property = factory()->NewProperty(
2797 iterator_proxy, next_literal, RelocInfo::kNoPosition);
2798 ZoneList<Expression*>* next_arguments =
2799 new(zone()) ZoneList<Expression*>(0, zone());
2800 Expression* next_call = factory()->NewCall(
2801 next_property, next_arguments, RelocInfo::kNoPosition);
2802 Expression* result_proxy = factory()->NewVariableProxy(result);
2803 next_result = factory()->NewAssignment(
2804 Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition);
2809 Expression* done_literal = factory()->NewStringLiteral(
2810 ast_value_factory_->done_string(), RelocInfo::kNoPosition);
2811 Expression* result_proxy = factory()->NewVariableProxy(result);
2812 result_done = factory()->NewProperty(
2813 result_proxy, done_literal, RelocInfo::kNoPosition);
2816 // each = result.value
2818 Expression* value_literal = factory()->NewStringLiteral(
2819 ast_value_factory_->value_string(), RelocInfo::kNoPosition);
2820 Expression* result_proxy = factory()->NewVariableProxy(result);
2821 Expression* result_value = factory()->NewProperty(
2822 result_proxy, value_literal, RelocInfo::kNoPosition);
2823 assign_each = factory()->NewAssignment(
2824 Token::ASSIGN, each, result_value, RelocInfo::kNoPosition);
2827 for_of->Initialize(each, subject, body,
2833 stmt->Initialize(each, subject, body);
2838 Statement* Parser::DesugarLetBindingsInForStatement(
2839 Scope* inner_scope, ZoneList<const AstRawString*>* names,
2840 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
2841 Statement* body, bool* ok) {
2842 // ES6 13.6.3.4 specifies that on each loop iteration the let variables are
2843 // copied into a new environment. After copying, the "next" statement of the
2844 // loop is executed to update the loop variables. The loop condition is
2845 // checked and the loop body is executed.
2847 // We rewrite a for statement of the form
2849 // for (let x = i; cond; next) body
2874 DCHECK(names->length() > 0);
2875 Scope* for_scope = scope_;
2876 ZoneList<Variable*> temps(names->length(), zone());
2878 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false,
2879 RelocInfo::kNoPosition);
2880 outer_block->AddStatement(init, zone());
2882 const AstRawString* temp_name = ast_value_factory_->dot_for_string();
2884 // For each let variable x:
2885 // make statement: temp_x = x.
2886 for (int i = 0; i < names->length(); i++) {
2887 VariableProxy* proxy =
2888 NewUnresolved(names->at(i), LET, Interface::NewValue());
2889 Variable* temp = scope_->DeclarationScope()->NewTemporary(temp_name);
2890 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
2891 Assignment* assignment = factory()->NewAssignment(
2892 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
2893 Statement* assignment_statement = factory()->NewExpressionStatement(
2894 assignment, RelocInfo::kNoPosition);
2895 outer_block->AddStatement(assignment_statement, zone());
2896 temps.Add(temp, zone());
2899 Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name);
2900 // Make statement: flag = 1.
2902 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2903 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
2904 Assignment* assignment = factory()->NewAssignment(
2905 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
2906 Statement* assignment_statement = factory()->NewExpressionStatement(
2907 assignment, RelocInfo::kNoPosition);
2908 outer_block->AddStatement(assignment_statement, zone());
2911 outer_block->AddStatement(loop, zone());
2912 outer_block->set_scope(for_scope);
2913 scope_ = inner_scope;
2915 Block* inner_block = factory()->NewBlock(NULL, 2 * names->length() + 3,
2916 false, RelocInfo::kNoPosition);
2917 int pos = scanner()->location().beg_pos;
2918 ZoneList<Variable*> inner_vars(names->length(), zone());
2920 // For each let variable x:
2921 // make statement: let x = temp_x.
2922 for (int i = 0; i < names->length(); i++) {
2923 VariableProxy* proxy =
2924 NewUnresolved(names->at(i), LET, Interface::NewValue());
2925 Declaration* declaration =
2926 factory()->NewVariableDeclaration(proxy, LET, scope_, pos);
2927 Declare(declaration, true, CHECK_OK);
2928 inner_vars.Add(declaration->proxy()->var(), zone());
2929 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2930 Assignment* assignment = factory()->NewAssignment(
2931 Token::INIT_LET, proxy, temp_proxy, pos);
2932 Statement* assignment_statement = factory()->NewExpressionStatement(
2934 proxy->var()->set_initializer_position(pos);
2935 inner_block->AddStatement(assignment_statement, zone());
2938 // Make statement: if (flag == 1) { flag = 0; } else { next; }.
2940 Expression* compare = NULL;
2941 // Make compare expresion: flag == 1.
2943 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
2944 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2945 compare = factory()->NewCompareOperation(
2946 Token::EQ, flag_proxy, const1, pos);
2948 Statement* clear_flag = NULL;
2949 // Make statement: flag = 0.
2951 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2952 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
2953 Assignment* assignment = factory()->NewAssignment(
2954 Token::ASSIGN, flag_proxy, const0, RelocInfo::kNoPosition);
2955 clear_flag = factory()->NewExpressionStatement(assignment, pos);
2957 Statement* clear_flag_or_next = factory()->NewIfStatement(
2958 compare, clear_flag, next, RelocInfo::kNoPosition);
2959 inner_block->AddStatement(clear_flag_or_next, zone());
2963 // Make statement: if (cond) { } else { break; }.
2965 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2966 BreakableStatement* t = LookupBreakTarget(NULL, CHECK_OK);
2967 Statement* stop = factory()->NewBreakStatement(t, RelocInfo::kNoPosition);
2968 Statement* if_not_cond_break = factory()->NewIfStatement(
2969 cond, empty, stop, cond->position());
2970 inner_block->AddStatement(if_not_cond_break, zone());
2973 inner_block->AddStatement(body, zone());
2975 // For each let variable x:
2976 // make statement: temp_x = x;
2977 for (int i = 0; i < names->length(); i++) {
2978 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2979 int pos = scanner()->location().end_pos;
2980 VariableProxy* proxy = factory()->NewVariableProxy(inner_vars.at(i), pos);
2981 Assignment* assignment = factory()->NewAssignment(
2982 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
2983 Statement* assignment_statement = factory()->NewExpressionStatement(
2984 assignment, RelocInfo::kNoPosition);
2985 inner_block->AddStatement(assignment_statement, zone());
2988 inner_scope->set_end_position(scanner()->location().end_pos);
2989 inner_block->set_scope(inner_scope);
2992 loop->Initialize(NULL, NULL, NULL, inner_block);
2997 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
3000 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
3002 int pos = peek_position();
3003 Statement* init = NULL;
3004 ZoneList<const AstRawString*> let_bindings(1, zone());
3006 // Create an in-between scope for let-bound iteration variables.
3007 Scope* saved_scope = scope_;
3008 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
3011 Expect(Token::FOR, CHECK_OK);
3012 Expect(Token::LPAREN, CHECK_OK);
3013 for_scope->set_start_position(scanner()->location().beg_pos);
3014 if (peek() != Token::SEMICOLON) {
3015 if (peek() == Token::VAR || peek() == Token::CONST) {
3016 bool is_const = peek() == Token::CONST;
3017 const AstRawString* name = NULL;
3018 VariableDeclarationProperties decl_props = kHasNoInitializers;
3019 Block* variable_statement =
3020 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
3022 bool accept_OF = decl_props == kHasNoInitializers;
3023 ForEachStatement::VisitMode mode;
3025 if (name != NULL && CheckInOrOf(accept_OF, &mode)) {
3026 Interface* interface =
3027 is_const ? Interface::NewConst() : Interface::NewValue();
3028 ForEachStatement* loop =
3029 factory()->NewForEachStatement(mode, labels, pos);
3030 Target target(&this->target_stack_, loop);
3032 Expression* enumerable = ParseExpression(true, CHECK_OK);
3033 Expect(Token::RPAREN, CHECK_OK);
3035 VariableProxy* each =
3036 scope_->NewUnresolved(factory(), name, interface);
3037 Statement* body = ParseStatement(NULL, CHECK_OK);
3038 InitializeForEachStatement(loop, each, enumerable, body);
3040 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3041 result->AddStatement(variable_statement, zone());
3042 result->AddStatement(loop, zone());
3043 scope_ = saved_scope;
3044 for_scope->set_end_position(scanner()->location().end_pos);
3045 for_scope = for_scope->FinalizeBlockScope();
3046 DCHECK(for_scope == NULL);
3047 // Parsed for-in loop w/ variable/const declaration.
3050 init = variable_statement;
3052 } else if (peek() == Token::LET && strict_mode() == STRICT) {
3053 DCHECK(allow_harmony_scoping());
3054 const AstRawString* name = NULL;
3055 VariableDeclarationProperties decl_props = kHasNoInitializers;
3056 Block* variable_statement =
3057 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings,
3059 bool accept_IN = name != NULL && decl_props != kHasInitializers;
3060 bool accept_OF = decl_props == kHasNoInitializers;
3061 ForEachStatement::VisitMode mode;
3063 if (accept_IN && CheckInOrOf(accept_OF, &mode)) {
3064 // Rewrite a for-in statement of the form
3066 // for (let x in e) b
3070 // <let x' be a temporary variable>
3077 // TODO(keuchel): Move the temporary variable to the block scope, after
3078 // implementing stack allocated block scoped variables.
3079 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3080 ast_value_factory_->dot_for_string());
3081 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
3082 ForEachStatement* loop =
3083 factory()->NewForEachStatement(mode, labels, pos);
3084 Target target(&this->target_stack_, loop);
3086 // The expression does not see the loop variable.
3087 scope_ = saved_scope;
3088 Expression* enumerable = ParseExpression(true, CHECK_OK);
3090 Expect(Token::RPAREN, CHECK_OK);
3092 VariableProxy* each =
3093 scope_->NewUnresolved(factory(), name, Interface::NewValue());
3094 Statement* body = ParseStatement(NULL, CHECK_OK);
3096 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3097 Assignment* assignment = factory()->NewAssignment(
3098 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition);
3099 Statement* assignment_statement = factory()->NewExpressionStatement(
3100 assignment, RelocInfo::kNoPosition);
3101 body_block->AddStatement(variable_statement, zone());
3102 body_block->AddStatement(assignment_statement, zone());
3103 body_block->AddStatement(body, zone());
3104 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block);
3105 scope_ = saved_scope;
3106 for_scope->set_end_position(scanner()->location().end_pos);
3107 for_scope = for_scope->FinalizeBlockScope();
3108 body_block->set_scope(for_scope);
3109 // Parsed for-in loop w/ let declaration.
3113 init = variable_statement;
3116 Scanner::Location lhs_location = scanner()->peek_location();
3117 Expression* expression = ParseExpression(false, CHECK_OK);
3118 ForEachStatement::VisitMode mode;
3119 bool accept_OF = expression->AsVariableProxy();
3121 if (CheckInOrOf(accept_OF, &mode)) {
3122 expression = this->CheckAndRewriteReferenceExpression(
3123 expression, lhs_location, "invalid_lhs_in_for", CHECK_OK);
3125 ForEachStatement* loop =
3126 factory()->NewForEachStatement(mode, labels, pos);
3127 Target target(&this->target_stack_, loop);
3129 Expression* enumerable = ParseExpression(true, CHECK_OK);
3130 Expect(Token::RPAREN, CHECK_OK);
3132 Statement* body = ParseStatement(NULL, CHECK_OK);
3133 InitializeForEachStatement(loop, expression, enumerable, body);
3134 scope_ = saved_scope;
3135 for_scope->set_end_position(scanner()->location().end_pos);
3136 for_scope = for_scope->FinalizeBlockScope();
3137 DCHECK(for_scope == NULL);
3138 // Parsed for-in loop.
3142 init = factory()->NewExpressionStatement(
3143 expression, RelocInfo::kNoPosition);
3148 // Standard 'for' loop
3149 ForStatement* loop = factory()->NewForStatement(labels, pos);
3150 Target target(&this->target_stack_, loop);
3152 // Parsed initializer at this point.
3153 Expect(Token::SEMICOLON, CHECK_OK);
3155 // If there are let bindings, then condition and the next statement of the
3156 // for loop must be parsed in a new scope.
3157 Scope* inner_scope = NULL;
3158 if (let_bindings.length() > 0) {
3159 inner_scope = NewScope(for_scope, BLOCK_SCOPE);
3160 inner_scope->set_start_position(scanner()->location().beg_pos);
3161 scope_ = inner_scope;
3164 Expression* cond = NULL;
3165 if (peek() != Token::SEMICOLON) {
3166 cond = ParseExpression(true, CHECK_OK);
3168 Expect(Token::SEMICOLON, CHECK_OK);
3170 Statement* next = NULL;
3171 if (peek() != Token::RPAREN) {
3172 Expression* exp = ParseExpression(true, CHECK_OK);
3173 next = factory()->NewExpressionStatement(exp, RelocInfo::kNoPosition);
3175 Expect(Token::RPAREN, CHECK_OK);
3177 Statement* body = ParseStatement(NULL, CHECK_OK);
3179 Statement* result = NULL;
3180 if (let_bindings.length() > 0) {
3182 result = DesugarLetBindingsInForStatement(inner_scope, &let_bindings, loop,
3183 init, cond, next, body, CHECK_OK);
3184 scope_ = saved_scope;
3185 for_scope->set_end_position(scanner()->location().end_pos);
3187 scope_ = saved_scope;
3188 for_scope->set_end_position(scanner()->location().end_pos);
3189 for_scope = for_scope->FinalizeBlockScope();
3191 // Rewrite a for statement of the form
3192 // for (const x = i; c; n) b
3200 DCHECK(init != NULL);
3202 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3203 block->AddStatement(init, zone());
3204 block->AddStatement(loop, zone());
3205 block->set_scope(for_scope);
3206 loop->Initialize(NULL, cond, next, body);
3209 loop->Initialize(init, cond, next, body);
3217 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
3218 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
3219 // contexts this is used as a statement which invokes the debugger as i a
3220 // break point is present.
3221 // DebuggerStatement ::
3224 int pos = peek_position();
3225 Expect(Token::DEBUGGER, CHECK_OK);
3226 ExpectSemicolon(CHECK_OK);
3227 return factory()->NewDebuggerStatement(pos);
3231 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
3232 if (expression->IsLiteral()) return true;
3233 MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3234 return lit != NULL && lit->is_simple();
3238 Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate,
3239 Expression* expression) {
3240 Factory* factory = isolate->factory();
3241 DCHECK(IsCompileTimeValue(expression));
3242 Handle<FixedArray> result = factory->NewFixedArray(2, TENURED);
3243 ObjectLiteral* object_literal = expression->AsObjectLiteral();
3244 if (object_literal != NULL) {
3245 DCHECK(object_literal->is_simple());
3246 if (object_literal->fast_elements()) {
3247 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
3249 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
3251 result->set(kElementsSlot, *object_literal->constant_properties());
3253 ArrayLiteral* array_literal = expression->AsArrayLiteral();
3254 DCHECK(array_literal != NULL && array_literal->is_simple());
3255 result->set(kLiteralTypeSlot, Smi::FromInt(ARRAY_LITERAL));
3256 result->set(kElementsSlot, *array_literal->constant_elements());
3262 CompileTimeValue::LiteralType CompileTimeValue::GetLiteralType(
3263 Handle<FixedArray> value) {
3264 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot));
3265 return static_cast<LiteralType>(literal_type->value());
3269 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
3270 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
3274 bool CheckAndDeclareArrowParameter(ParserTraits* traits, Expression* expression,
3275 Scope* scope, int* num_params,
3276 Scanner::Location* dupe_loc) {
3277 // Case for empty parameter lists:
3279 if (expression == NULL) return true;
3281 // Too many parentheses around expression:
3283 if (expression->parenthesization_level() > 1) return false;
3285 // Case for a single parameter:
3288 if (expression->IsVariableProxy()) {
3289 if (expression->AsVariableProxy()->is_this()) return false;
3291 const AstRawString* raw_name = expression->AsVariableProxy()->raw_name();
3292 if (traits->IsEvalOrArguments(raw_name) ||
3293 traits->IsFutureStrictReserved(raw_name))
3296 if (scope->IsDeclared(raw_name)) {
3297 *dupe_loc = Scanner::Location(
3298 expression->position(), expression->position() + raw_name->length());
3302 scope->DeclareParameter(raw_name, VAR);
3307 // Case for more than one parameter:
3308 // (foo, bar [, ...]) => ...
3309 if (expression->IsBinaryOperation()) {
3310 BinaryOperation* binop = expression->AsBinaryOperation();
3311 if (binop->op() != Token::COMMA || binop->left()->is_parenthesized() ||
3312 binop->right()->is_parenthesized())
3315 return CheckAndDeclareArrowParameter(traits, binop->left(), scope,
3316 num_params, dupe_loc) &&
3317 CheckAndDeclareArrowParameter(traits, binop->right(), scope,
3318 num_params, dupe_loc);
3321 // Any other kind of expression is not a valid parameter list.
3326 int ParserTraits::DeclareArrowParametersFromExpression(
3327 Expression* expression, Scope* scope, Scanner::Location* dupe_loc,
3330 *ok = CheckAndDeclareArrowParameter(this, expression, scope, &num_params,
3336 FunctionLiteral* Parser::ParseFunctionLiteral(
3337 const AstRawString* function_name,
3338 Scanner::Location function_name_location,
3339 bool name_is_strict_reserved,
3341 int function_token_pos,
3342 FunctionLiteral::FunctionType function_type,
3343 FunctionLiteral::ArityRestriction arity_restriction,
3346 // '(' FormalParameterList? ')' '{' FunctionBody '}'
3349 // '(' ')' '{' FunctionBody '}'
3352 // '(' PropertySetParameterList ')' '{' FunctionBody '}'
3354 int pos = function_token_pos == RelocInfo::kNoPosition
3355 ? peek_position() : function_token_pos;
3357 // Anonymous functions were passed either the empty symbol or a null
3358 // handle as the function name. Remember if we were passed a non-empty
3359 // handle to decide whether to invoke function name inference.
3360 bool should_infer_name = function_name == NULL;
3362 // We want a non-null handle as the function name.
3363 if (should_infer_name) {
3364 function_name = ast_value_factory_->empty_string();
3367 int num_parameters = 0;
3368 // Function declarations are function scoped in normal mode, so they are
3369 // hoisted. In harmony block scoping mode they are block scoped, so they
3372 // One tricky case are function declarations in a local sloppy-mode eval:
3373 // their declaration is hoisted, but they still see the local scope. E.g.,
3377 // try { throw 1 } catch (x) { eval("function g() { return x }") }
3381 // needs to return 1. To distinguish such cases, we need to detect
3382 // (1) whether a function stems from a sloppy eval, and
3383 // (2) whether it actually hoists across the eval.
3384 // Unfortunately, we do not represent sloppy eval scopes, so we do not have
3385 // either information available directly, especially not when lazily compiling
3386 // a function like 'g'. We hence rely on the following invariants:
3387 // - (1) is the case iff the innermost scope of the deserialized scope chain
3388 // under which we compile is _not_ a declaration scope. This holds because
3389 // in all normal cases, function declarations are fully hoisted to a
3390 // declaration scope and compiled relative to that.
3391 // - (2) is the case iff the current declaration scope is still the original
3392 // one relative to the deserialized scope chain. Otherwise we must be
3393 // compiling a function in an inner declaration scope in the eval, e.g. a
3394 // nested function, and hoisting works normally relative to that.
3395 Scope* declaration_scope = scope_->DeclarationScope();
3396 Scope* original_declaration_scope = original_scope_->DeclarationScope();
3398 function_type == FunctionLiteral::DECLARATION &&
3399 (!allow_harmony_scoping() || strict_mode() == SLOPPY) &&
3400 (original_scope_ == original_declaration_scope ||
3401 declaration_scope != original_declaration_scope)
3402 ? NewScope(declaration_scope, FUNCTION_SCOPE)
3403 : NewScope(scope_, FUNCTION_SCOPE);
3404 ZoneList<Statement*>* body = NULL;
3405 int materialized_literal_count = -1;
3406 int expected_property_count = -1;
3407 int handler_count = 0;
3408 FunctionLiteral::ParameterFlag duplicate_parameters =
3409 FunctionLiteral::kNoDuplicateParameters;
3410 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
3411 ? FunctionLiteral::kIsParenthesized
3412 : FunctionLiteral::kNotParenthesized;
3413 AstProperties ast_properties;
3414 BailoutReason dont_optimize_reason = kNoReason;
3415 // Parse function body.
3417 FunctionState function_state(&function_state_, &scope_, scope, zone(),
3418 ast_value_factory_);
3419 scope_->SetScopeName(function_name);
3422 // For generators, allocating variables in contexts is currently a win
3423 // because it minimizes the work needed to suspend and resume an
3425 scope_->ForceContextAllocation();
3427 // Calling a generator returns a generator object. That object is stored
3428 // in a temporary variable, a definition that is used by "yield"
3429 // expressions. This also marks the FunctionState as a generator.
3430 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3431 ast_value_factory_->dot_generator_object_string());
3432 function_state.set_generator_object_variable(temp);
3435 // FormalParameterList ::
3436 // '(' (Identifier)*[','] ')'
3437 Expect(Token::LPAREN, CHECK_OK);
3438 scope->set_start_position(scanner()->location().beg_pos);
3440 // We don't yet know if the function will be strict, so we cannot yet
3441 // produce errors for parameter names or duplicates. However, we remember
3442 // the locations of these errors if they occur and produce the errors later.
3443 Scanner::Location eval_args_error_log = Scanner::Location::invalid();
3444 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
3445 Scanner::Location reserved_loc = Scanner::Location::invalid();
3447 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY ||
3448 (peek() == Token::RPAREN &&
3449 arity_restriction != FunctionLiteral::SETTER_ARITY);
3451 bool is_strict_reserved = false;
3452 const AstRawString* param_name =
3453 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
3455 // Store locations for possible future error reports.
3456 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) {
3457 eval_args_error_log = scanner()->location();
3459 if (!reserved_loc.IsValid() && is_strict_reserved) {
3460 reserved_loc = scanner()->location();
3462 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) {
3463 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters;
3464 dupe_error_loc = scanner()->location();
3467 Variable* var = scope_->DeclareParameter(param_name, VAR);
3468 if (scope->strict_mode() == SLOPPY) {
3469 // TODO(sigurds) Mark every parameter as maybe assigned. This is a
3470 // conservative approximation necessary to account for parameters
3471 // that are assigned via the arguments array.
3472 var->set_maybe_assigned();
3476 if (num_parameters > Code::kMaxArguments) {
3477 ReportMessage("too_many_parameters");
3481 if (arity_restriction == FunctionLiteral::SETTER_ARITY) break;
3482 done = (peek() == Token::RPAREN);
3483 if (!done) Expect(Token::COMMA, CHECK_OK);
3485 Expect(Token::RPAREN, CHECK_OK);
3487 Expect(Token::LBRACE, CHECK_OK);
3489 // If we have a named function expression, we add a local variable
3490 // declaration to the body of the function with the name of the
3491 // function and let it refer to the function itself (closure).
3492 // NOTE: We create a proxy and resolve it here so that in the
3493 // future we can change the AST to only refer to VariableProxies
3494 // instead of Variables and Proxis as is the case now.
3495 Variable* fvar = NULL;
3496 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY;
3497 if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
3498 if (allow_harmony_scoping() && strict_mode() == STRICT) {
3499 fvar_init_op = Token::INIT_CONST;
3501 VariableMode fvar_mode =
3502 allow_harmony_scoping() && strict_mode() == STRICT
3503 ? CONST : CONST_LEGACY;
3504 DCHECK(function_name != NULL);
3506 Variable(scope_, function_name, fvar_mode, true /* is valid LHS */,
3507 Variable::NORMAL, kCreatedInitialized, kNotAssigned,
3508 Interface::NewConst());
3509 VariableProxy* proxy = factory()->NewVariableProxy(fvar);
3510 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration(
3511 proxy, fvar_mode, scope_, RelocInfo::kNoPosition);
3512 scope_->DeclareFunctionVar(fvar_declaration);
3515 // Determine if the function can be parsed lazily. Lazy parsing is different
3516 // from lazy compilation; we need to parse more eagerly than we compile.
3518 // We can only parse lazily if we also compile lazily. The heuristics for
3519 // lazy compilation are:
3520 // - It must not have been prohibited by the caller to Parse (some callers
3521 // need a full AST).
3522 // - The outer scope must allow lazy compilation of inner functions.
3523 // - The function mustn't be a function expression with an open parenthesis
3524 // before; we consider that a hint that the function will be called
3525 // immediately, and it would be a waste of time to make it lazily
3527 // These are all things we can know at this point, without looking at the
3530 // In addition, we need to distinguish between these cases:
3531 // (function foo() {
3532 // bar = function() { return 1; }
3535 // (function foo() {
3537 // bar = function() { return a; }
3540 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
3541 // parenthesis before the function means that it will be called
3542 // immediately). The inner function *must* be parsed eagerly to resolve the
3543 // possible reference to the variable in foo's scope. However, it's possible
3544 // that it will be compiled lazily.
3546 // To make this additional case work, both Parser and PreParser implement a
3547 // logic where only top-level functions will be parsed lazily.
3548 bool is_lazily_parsed = (mode() == PARSE_LAZILY &&
3549 scope_->AllowsLazyCompilation() &&
3550 !parenthesized_function_);
3551 parenthesized_function_ = false; // The bit was set for this function only.
3553 if (is_lazily_parsed) {
3554 SkipLazyFunctionBody(function_name, &materialized_literal_count,
3555 &expected_property_count, CHECK_OK);
3557 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
3558 is_generator, CHECK_OK);
3559 materialized_literal_count = function_state.materialized_literal_count();
3560 expected_property_count = function_state.expected_property_count();
3561 handler_count = function_state.handler_count();
3564 // Validate strict mode.
3565 if (strict_mode() == STRICT) {
3566 CheckStrictFunctionNameAndParameters(function_name,
3567 name_is_strict_reserved,
3568 function_name_location,
3569 eval_args_error_log,
3573 CheckOctalLiteral(scope->start_position(),
3574 scope->end_position(),
3577 ast_properties = *factory()->visitor()->ast_properties();
3578 dont_optimize_reason = factory()->visitor()->dont_optimize_reason();
3580 if (allow_harmony_scoping() && strict_mode() == STRICT) {
3581 CheckConflictingVarDeclarations(scope, CHECK_OK);
3585 FunctionLiteral::KindFlag kind = is_generator
3586 ? FunctionLiteral::kGeneratorFunction
3587 : FunctionLiteral::kNormalFunction;
3588 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
3589 function_name, ast_value_factory_, scope, body,
3590 materialized_literal_count, expected_property_count, handler_count,
3591 num_parameters, duplicate_parameters, function_type,
3592 FunctionLiteral::kIsFunction, parenthesized, kind, pos);
3593 function_literal->set_function_token_position(function_token_pos);
3594 function_literal->set_ast_properties(&ast_properties);
3595 function_literal->set_dont_optimize_reason(dont_optimize_reason);
3597 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
3598 return function_literal;
3602 void Parser::SkipLazyFunctionBody(const AstRawString* function_name,
3603 int* materialized_literal_count,
3604 int* expected_property_count,
3606 int function_block_pos = position();
3607 if (compile_options() == ScriptCompiler::kConsumeParserCache) {
3608 // If we have cached data, we use it to skip parsing the function body. The
3609 // data contains the information we need to construct the lazy function.
3610 FunctionEntry entry =
3611 cached_parse_data_->GetFunctionEntry(function_block_pos);
3612 // Check that cached data is valid.
3613 CHECK(entry.is_valid());
3614 // End position greater than end of stream is safe, and hard to check.
3615 CHECK(entry.end_pos() > function_block_pos);
3616 scanner()->SeekForward(entry.end_pos() - 1);
3618 scope_->set_end_position(entry.end_pos());
3619 Expect(Token::RBRACE, ok);
3623 isolate()->counters()->total_preparse_skipped()->Increment(
3624 scope_->end_position() - function_block_pos);
3625 *materialized_literal_count = entry.literal_count();
3626 *expected_property_count = entry.property_count();
3627 scope_->SetStrictMode(entry.strict_mode());
3629 // With no cached data, we partially parse the function, without building an
3630 // AST. This gathers the data needed to build a lazy function.
3631 SingletonLogger logger;
3632 PreParser::PreParseResult result =
3633 ParseLazyFunctionBodyWithPreParser(&logger);
3634 if (result == PreParser::kPreParseStackOverflow) {
3635 // Propagate stack overflow.
3636 set_stack_overflow();
3640 if (logger.has_error()) {
3641 ParserTraits::ReportMessageAt(
3642 Scanner::Location(logger.start(), logger.end()),
3643 logger.message(), logger.argument_opt(), logger.is_reference_error());
3647 scope_->set_end_position(logger.end());
3648 Expect(Token::RBRACE, ok);
3652 isolate()->counters()->total_preparse_skipped()->Increment(
3653 scope_->end_position() - function_block_pos);
3654 *materialized_literal_count = logger.literals();
3655 *expected_property_count = logger.properties();
3656 scope_->SetStrictMode(logger.strict_mode());
3657 if (compile_options() == ScriptCompiler::kProduceParserCache) {
3659 // Position right after terminal '}'.
3660 int body_end = scanner()->location().end_pos;
3661 log_->LogFunction(function_block_pos, body_end,
3662 *materialized_literal_count,
3663 *expected_property_count,
3664 scope_->strict_mode());
3670 ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
3671 const AstRawString* function_name, int pos, Variable* fvar,
3672 Token::Value fvar_init_op, bool is_generator, bool* ok) {
3673 // Everything inside an eagerly parsed function will be parsed eagerly
3674 // (see comment above).
3675 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
3676 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone());
3678 VariableProxy* fproxy = scope_->NewUnresolved(
3679 factory(), function_name, Interface::NewConst());
3680 fproxy->BindTo(fvar);
3681 body->Add(factory()->NewExpressionStatement(
3682 factory()->NewAssignment(fvar_init_op,
3684 factory()->NewThisFunction(pos),
3685 RelocInfo::kNoPosition),
3686 RelocInfo::kNoPosition), zone());
3689 // For generators, allocate and yield an iterator on function entry.
3691 ZoneList<Expression*>* arguments =
3692 new(zone()) ZoneList<Expression*>(0, zone());
3693 CallRuntime* allocation = factory()->NewCallRuntime(
3694 ast_value_factory_->empty_string(),
3695 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject),
3697 VariableProxy* init_proxy = factory()->NewVariableProxy(
3698 function_state_->generator_object_variable());
3699 Assignment* assignment = factory()->NewAssignment(
3700 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
3701 VariableProxy* get_proxy = factory()->NewVariableProxy(
3702 function_state_->generator_object_variable());
3703 Yield* yield = factory()->NewYield(
3704 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition);
3705 body->Add(factory()->NewExpressionStatement(
3706 yield, RelocInfo::kNoPosition), zone());
3709 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK);
3712 VariableProxy* get_proxy = factory()->NewVariableProxy(
3713 function_state_->generator_object_variable());
3714 Expression* undefined =
3715 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition);
3716 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::FINAL,
3717 RelocInfo::kNoPosition);
3718 body->Add(factory()->NewExpressionStatement(
3719 yield, RelocInfo::kNoPosition), zone());
3722 Expect(Token::RBRACE, CHECK_OK);
3723 scope_->set_end_position(scanner()->location().end_pos);
3729 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
3730 SingletonLogger* logger) {
3731 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse());
3732 DCHECK_EQ(Token::LBRACE, scanner()->current_token());
3734 if (reusable_preparser_ == NULL) {
3735 intptr_t stack_limit = isolate()->stack_guard()->real_climit();
3736 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit);
3737 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping());
3738 reusable_preparser_->set_allow_modules(allow_modules());
3739 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax());
3740 reusable_preparser_->set_allow_lazy(true);
3741 reusable_preparser_->set_allow_generators(allow_generators());
3742 reusable_preparser_->set_allow_arrow_functions(allow_arrow_functions());
3743 reusable_preparser_->set_allow_harmony_numeric_literals(
3744 allow_harmony_numeric_literals());
3746 PreParser::PreParseResult result =
3747 reusable_preparser_->PreParseLazyFunction(strict_mode(),
3754 Expression* Parser::ParseV8Intrinsic(bool* ok) {
3756 // '%' Identifier Arguments
3758 int pos = peek_position();
3759 Expect(Token::MOD, CHECK_OK);
3760 // Allow "eval" or "arguments" for backward compatibility.
3761 const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
3762 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
3764 if (extension_ != NULL) {
3765 // The extension structures are only accessible while parsing the
3766 // very first time not when reparsing because of lazy compilation.
3767 scope_->DeclarationScope()->ForceEagerCompilation();
3770 const Runtime::Function* function = Runtime::FunctionForName(name->string());
3772 // Check for built-in IS_VAR macro.
3773 if (function != NULL &&
3774 function->intrinsic_type == Runtime::RUNTIME &&
3775 function->function_id == Runtime::kIS_VAR) {
3776 // %IS_VAR(x) evaluates to x if x is a variable,
3777 // leads to a parse error otherwise. Could be implemented as an
3778 // inline function %_IS_VAR(x) to eliminate this special case.
3779 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
3782 ReportMessage("not_isvar");
3788 // Check that the expected number of arguments are being passed.
3789 if (function != NULL &&
3790 function->nargs != -1 &&
3791 function->nargs != args->length()) {
3792 ReportMessage("illegal_access");
3797 // Check that the function is defined if it's an inline runtime call.
3798 if (function == NULL && name->FirstCharacter() == '_') {
3799 ParserTraits::ReportMessage("not_defined", name);
3804 // We have a valid intrinsics call or a call to a builtin.
3805 return factory()->NewCallRuntime(name, function, args, pos);
3809 Literal* Parser::GetLiteralUndefined(int position) {
3810 return factory()->NewUndefinedLiteral(position);
3814 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
3815 Declaration* decl = scope->CheckConflictingVarDeclarations();
3817 // In harmony mode we treat conflicting variable bindinds as early
3818 // errors. See ES5 16 for a definition of early errors.
3819 const AstRawString* name = decl->proxy()->raw_name();
3820 int position = decl->proxy()->position();
3821 Scanner::Location location = position == RelocInfo::kNoPosition
3822 ? Scanner::Location::invalid()
3823 : Scanner::Location(position, position + 1);
3824 ParserTraits::ReportMessageAt(location, "var_redeclaration", name);
3830 // ----------------------------------------------------------------------------
3834 bool Parser::TargetStackContainsLabel(const AstRawString* label) {
3835 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
3836 BreakableStatement* stat = t->node()->AsBreakableStatement();
3837 if (stat != NULL && ContainsLabel(stat->labels(), label))
3844 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
3846 bool anonymous = label == NULL;
3847 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
3848 BreakableStatement* stat = t->node()->AsBreakableStatement();
3849 if (stat == NULL) continue;
3850 if ((anonymous && stat->is_target_for_anonymous()) ||
3851 (!anonymous && ContainsLabel(stat->labels(), label))) {
3852 RegisterTargetUse(stat->break_target(), t->previous());
3860 IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
3862 bool anonymous = label == NULL;
3863 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
3864 IterationStatement* stat = t->node()->AsIterationStatement();
3865 if (stat == NULL) continue;
3867 DCHECK(stat->is_target_for_anonymous());
3868 if (anonymous || ContainsLabel(stat->labels(), label)) {
3869 RegisterTargetUse(stat->continue_target(), t->previous());
3877 void Parser::RegisterTargetUse(Label* target, Target* stop) {
3878 // Register that a break target found at the given stop in the
3879 // target stack has been used from the top of the target stack. Add
3880 // the break target to any TargetCollectors passed on the stack.
3881 for (Target* t = target_stack_; t != stop; t = t->previous()) {
3882 TargetCollector* collector = t->node()->AsTargetCollector();
3883 if (collector != NULL) collector->AddTarget(target, zone());
3888 void Parser::HandleSourceURLComments() {
3889 if (scanner_.source_url()->length() > 0) {
3890 Handle<String> source_url = scanner_.source_url()->Internalize(isolate());
3891 info_->script()->set_source_url(*source_url);
3893 if (scanner_.source_mapping_url()->length() > 0) {
3894 Handle<String> source_mapping_url =
3895 scanner_.source_mapping_url()->Internalize(isolate());
3896 info_->script()->set_source_mapping_url(*source_mapping_url);
3901 void Parser::ThrowPendingError() {
3902 DCHECK(ast_value_factory_->IsInternalized());
3903 if (has_pending_error_) {
3904 MessageLocation location(script_,
3905 pending_error_location_.beg_pos,
3906 pending_error_location_.end_pos);
3907 Factory* factory = isolate()->factory();
3909 pending_error_arg_ != NULL || pending_error_char_arg_ != NULL;
3910 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0);
3911 if (pending_error_arg_ != NULL) {
3912 Handle<String> arg_string = pending_error_arg_->string();
3913 elements->set(0, *arg_string);
3914 } else if (pending_error_char_arg_ != NULL) {
3915 Handle<String> arg_string =
3916 factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_))
3918 elements->set(0, *arg_string);
3920 isolate()->debug()->OnCompileError(script_);
3922 Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
3923 Handle<Object> result = pending_error_is_reference_error_
3924 ? factory->NewReferenceError(pending_error_message_, array)
3925 : factory->NewSyntaxError(pending_error_message_, array);
3926 isolate()->Throw(*result, &location);
3931 void Parser::InternalizeUseCounts() {
3932 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
3934 for (int i = 0; i < use_counts_[feature]; ++i) {
3935 isolate()->CountUsage(v8::Isolate::UseCounterFeature(feature));
3941 // ----------------------------------------------------------------------------
3942 // Regular expressions
3945 RegExpParser::RegExpParser(FlatStringReader* in,
3946 Handle<String>* error,
3949 : isolate_(zone->isolate()),
3954 current_(kEndMarker),
3958 multiline_(multiline),
3960 contains_anchor_(false),
3961 is_scanned_for_captures_(false),
3967 uc32 RegExpParser::Next() {
3969 return in()->Get(next_pos_);
3976 void RegExpParser::Advance() {
3977 if (next_pos_ < in()->length()) {
3978 StackLimitCheck check(isolate());
3979 if (check.HasOverflowed()) {
3980 ReportError(CStrVector(Isolate::kStackOverflowMessage));
3981 } else if (zone()->excess_allocation()) {
3982 ReportError(CStrVector("Regular expression too large"));
3984 current_ = in()->Get(next_pos_);
3988 current_ = kEndMarker;
3994 void RegExpParser::Reset(int pos) {
3996 has_more_ = (pos < in()->length());
4001 void RegExpParser::Advance(int dist) {
4002 next_pos_ += dist - 1;
4007 bool RegExpParser::simple() {
4012 RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
4014 *error_ = isolate()->factory()->NewStringFromAscii(message).ToHandleChecked();
4015 // Zip to the end to make sure the no more input is read.
4016 current_ = kEndMarker;
4017 next_pos_ = in()->length();
4024 RegExpTree* RegExpParser::ParsePattern() {
4025 RegExpTree* result = ParseDisjunction(CHECK_FAILED);
4026 DCHECK(!has_more());
4027 // If the result of parsing is a literal string atom, and it has the
4028 // same length as the input, then the atom is identical to the input.
4029 if (result->IsAtom() && result->AsAtom()->length() == in()->length()) {
4038 // Alternative | Disjunction
4046 RegExpTree* RegExpParser::ParseDisjunction() {
4047 // Used to store current state while parsing subexpressions.
4048 RegExpParserState initial_state(NULL, INITIAL, 0, zone());
4049 RegExpParserState* stored_state = &initial_state;
4050 // Cache the builder in a local variable for quick access.
4051 RegExpBuilder* builder = initial_state.builder();
4053 switch (current()) {
4055 if (stored_state->IsSubexpression()) {
4056 // Inside a parenthesized group when hitting end of input.
4057 ReportError(CStrVector("Unterminated group") CHECK_FAILED);
4059 DCHECK_EQ(INITIAL, stored_state->group_type());
4060 // Parsing completed successfully.
4061 return builder->ToRegExp();
4063 if (!stored_state->IsSubexpression()) {
4064 ReportError(CStrVector("Unmatched ')'") CHECK_FAILED);
4066 DCHECK_NE(INITIAL, stored_state->group_type());
4069 // End disjunction parsing and convert builder content to new single
4071 RegExpTree* body = builder->ToRegExp();
4073 int end_capture_index = captures_started();
4075 int capture_index = stored_state->capture_index();
4076 SubexpressionType group_type = stored_state->group_type();
4078 // Restore previous state.
4079 stored_state = stored_state->previous_state();
4080 builder = stored_state->builder();
4082 // Build result of subexpression.
4083 if (group_type == CAPTURE) {
4084 RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index);
4085 captures_->at(capture_index - 1) = capture;
4087 } else if (group_type != GROUPING) {
4088 DCHECK(group_type == POSITIVE_LOOKAHEAD ||
4089 group_type == NEGATIVE_LOOKAHEAD);
4090 bool is_positive = (group_type == POSITIVE_LOOKAHEAD);
4091 body = new(zone()) RegExpLookahead(body,
4093 end_capture_index - capture_index,
4096 builder->AddAtom(body);
4097 // For compatability with JSC and ES3, we allow quantifiers after
4098 // lookaheads, and break in all cases.
4103 builder->NewAlternative();
4109 return ReportError(CStrVector("Nothing to repeat"));
4113 builder->AddAssertion(
4114 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE));
4116 builder->AddAssertion(
4117 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
4118 set_contains_anchor();
4124 RegExpAssertion::AssertionType assertion_type =
4125 multiline_ ? RegExpAssertion::END_OF_LINE :
4126 RegExpAssertion::END_OF_INPUT;
4127 builder->AddAssertion(new(zone()) RegExpAssertion(assertion_type));
4132 // everything except \x0a, \x0d, \u2028 and \u2029
4133 ZoneList<CharacterRange>* ranges =
4134 new(zone()) ZoneList<CharacterRange>(2, zone());
4135 CharacterRange::AddClassEscape('.', ranges, zone());
4136 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
4137 builder->AddAtom(atom);
4141 SubexpressionType subexpr_type = CAPTURE;
4143 if (current() == '?') {
4146 subexpr_type = GROUPING;
4149 subexpr_type = POSITIVE_LOOKAHEAD;
4152 subexpr_type = NEGATIVE_LOOKAHEAD;
4155 ReportError(CStrVector("Invalid group") CHECK_FAILED);
4160 if (captures_ == NULL) {
4161 captures_ = new(zone()) ZoneList<RegExpCapture*>(2, zone());
4163 if (captures_started() >= kMaxCaptures) {
4164 ReportError(CStrVector("Too many captures") CHECK_FAILED);
4166 captures_->Add(NULL, zone());
4168 // Store current state and begin new disjunction parsing.
4169 stored_state = new(zone()) RegExpParserState(stored_state, subexpr_type,
4170 captures_started(), zone());
4171 builder = stored_state->builder();
4175 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED);
4176 builder->AddAtom(atom);
4184 return ReportError(CStrVector("\\ at end of pattern"));
4187 builder->AddAssertion(
4188 new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
4192 builder->AddAssertion(
4193 new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
4196 // CharacterClassEscape
4198 // CharacterClassEscape :: one of
4200 case 'd': case 'D': case 's': case 'S': case 'w': case 'W': {
4203 ZoneList<CharacterRange>* ranges =
4204 new(zone()) ZoneList<CharacterRange>(2, zone());
4205 CharacterRange::AddClassEscape(c, ranges, zone());
4206 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
4207 builder->AddAtom(atom);
4210 case '1': case '2': case '3': case '4': case '5': case '6':
4211 case '7': case '8': case '9': {
4213 if (ParseBackReferenceIndex(&index)) {
4214 RegExpCapture* capture = NULL;
4215 if (captures_ != NULL && index <= captures_->length()) {
4216 capture = captures_->at(index - 1);
4218 if (capture == NULL) {
4219 builder->AddEmpty();
4222 RegExpTree* atom = new(zone()) RegExpBackReference(capture);
4223 builder->AddAtom(atom);
4226 uc32 first_digit = Next();
4227 if (first_digit == '8' || first_digit == '9') {
4228 // Treat as identity escape
4229 builder->AddCharacter(first_digit);
4237 uc32 octal = ParseOctalLiteral();
4238 builder->AddCharacter(octal);
4241 // ControlEscape :: one of
4245 builder->AddCharacter('\f');
4249 builder->AddCharacter('\n');
4253 builder->AddCharacter('\r');
4257 builder->AddCharacter('\t');
4261 builder->AddCharacter('\v');
4265 uc32 controlLetter = Next();
4266 // Special case if it is an ASCII letter.
4267 // Convert lower case letters to uppercase.
4268 uc32 letter = controlLetter & ~('a' ^ 'A');
4269 if (letter < 'A' || 'Z' < letter) {
4270 // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
4271 // This is outside the specification. We match JSC in
4272 // reading the backslash as a literal character instead
4273 // of as starting an escape.
4274 builder->AddCharacter('\\');
4277 builder->AddCharacter(controlLetter & 0x1f);
4284 if (ParseHexEscape(2, &value)) {
4285 builder->AddCharacter(value);
4287 builder->AddCharacter('x');
4294 if (ParseHexEscape(4, &value)) {
4295 builder->AddCharacter(value);
4297 builder->AddCharacter('u');
4303 builder->AddCharacter(Next());
4310 if (ParseIntervalQuantifier(&dummy, &dummy)) {
4311 ReportError(CStrVector("Nothing to repeat") CHECK_FAILED);
4316 builder->AddCharacter(current());
4319 } // end switch(current())
4323 switch (current()) {
4324 // QuantifierPrefix ::
4331 max = RegExpTree::kInfinity;
4336 max = RegExpTree::kInfinity;
4345 if (ParseIntervalQuantifier(&min, &max)) {
4347 ReportError(CStrVector("numbers out of order in {} quantifier.")
4357 RegExpQuantifier::QuantifierType quantifier_type = RegExpQuantifier::GREEDY;
4358 if (current() == '?') {
4359 quantifier_type = RegExpQuantifier::NON_GREEDY;
4361 } else if (FLAG_regexp_possessive_quantifier && current() == '+') {
4362 // FLAG_regexp_possessive_quantifier is a debug-only flag.
4363 quantifier_type = RegExpQuantifier::POSSESSIVE;
4366 builder->AddQuantifierToAtom(min, max, quantifier_type);
4372 // Currently only used in an DCHECK.
4373 static bool IsSpecialClassEscape(uc32 c) {
4386 // In order to know whether an escape is a backreference or not we have to scan
4387 // the entire regexp and find the number of capturing parentheses. However we
4388 // don't want to scan the regexp twice unless it is necessary. This mini-parser
4389 // is called when needed. It can see the difference between capturing and
4390 // noncapturing parentheses and can skip character classes and backslash-escaped
4392 void RegExpParser::ScanForCaptures() {
4393 // Start with captures started previous to current position
4394 int capture_count = captures_started();
4395 // Add count of captures after this position.
4397 while ((n = current()) != kEndMarker) {
4405 while ((c = current()) != kEndMarker) {
4410 if (c == ']') break;
4416 if (current() != '?') capture_count++;
4420 capture_count_ = capture_count;
4421 is_scanned_for_captures_ = true;
4425 bool RegExpParser::ParseBackReferenceIndex(int* index_out) {
4426 DCHECK_EQ('\\', current());
4427 DCHECK('1' <= Next() && Next() <= '9');
4428 // Try to parse a decimal literal that is no greater than the total number
4429 // of left capturing parentheses in the input.
4430 int start = position();
4431 int value = Next() - '0';
4435 if (IsDecimalDigit(c)) {
4436 value = 10 * value + (c - '0');
4437 if (value > kMaxCaptures) {
4446 if (value > captures_started()) {
4447 if (!is_scanned_for_captures_) {
4448 int saved_position = position();
4450 Reset(saved_position);
4452 if (value > capture_count_) {
4462 // QuantifierPrefix ::
4463 // { DecimalDigits }
4464 // { DecimalDigits , }
4465 // { DecimalDigits , DecimalDigits }
4467 // Returns true if parsing succeeds, and set the min_out and max_out
4468 // values. Values are truncated to RegExpTree::kInfinity if they overflow.
4469 bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
4470 DCHECK_EQ(current(), '{');
4471 int start = position();
4474 if (!IsDecimalDigit(current())) {
4478 while (IsDecimalDigit(current())) {
4479 int next = current() - '0';
4480 if (min > (RegExpTree::kInfinity - next) / 10) {
4481 // Overflow. Skip past remaining decimal digits and return -1.
4484 } while (IsDecimalDigit(current()));
4485 min = RegExpTree::kInfinity;
4488 min = 10 * min + next;
4492 if (current() == '}') {
4495 } else if (current() == ',') {
4497 if (current() == '}') {
4498 max = RegExpTree::kInfinity;
4501 while (IsDecimalDigit(current())) {
4502 int next = current() - '0';
4503 if (max > (RegExpTree::kInfinity - next) / 10) {
4506 } while (IsDecimalDigit(current()));
4507 max = RegExpTree::kInfinity;
4510 max = 10 * max + next;
4513 if (current() != '}') {
4529 uc32 RegExpParser::ParseOctalLiteral() {
4530 DCHECK(('0' <= current() && current() <= '7') || current() == kEndMarker);
4531 // For compatibility with some other browsers (not all), we parse
4532 // up to three octal digits with a value below 256.
4533 uc32 value = current() - '0';
4535 if ('0' <= current() && current() <= '7') {
4536 value = value * 8 + current() - '0';
4538 if (value < 32 && '0' <= current() && current() <= '7') {
4539 value = value * 8 + current() - '0';
4547 bool RegExpParser::ParseHexEscape(int length, uc32 *value) {
4548 int start = position();
4551 for (int i = 0; !done; i++) {
4553 int d = HexValue(c);
4560 if (i == length - 1) {
4569 uc32 RegExpParser::ParseClassCharacterEscape() {
4570 DCHECK(current() == '\\');
4571 DCHECK(has_next() && !IsSpecialClassEscape(Next()));
4573 switch (current()) {
4577 // ControlEscape :: one of
4595 uc32 controlLetter = Next();
4596 uc32 letter = controlLetter & ~('A' ^ 'a');
4597 // For compatibility with JSC, inside a character class
4598 // we also accept digits and underscore as control characters.
4599 if ((controlLetter >= '0' && controlLetter <= '9') ||
4600 controlLetter == '_' ||
4601 (letter >= 'A' && letter <= 'Z')) {
4603 // Control letters mapped to ASCII control characters in the range
4605 return controlLetter & 0x1f;
4607 // We match JSC in reading the backslash as a literal
4608 // character instead of as starting an escape.
4611 case '0': case '1': case '2': case '3': case '4': case '5':
4613 // For compatibility, we interpret a decimal escape that isn't
4614 // a back reference (and therefore either \0 or not valid according
4615 // to the specification) as a 1..3 digit octal character code.
4616 return ParseOctalLiteral();
4620 if (ParseHexEscape(2, &value)) {
4623 // If \x is not followed by a two-digit hexadecimal, treat it
4624 // as an identity escape.
4630 if (ParseHexEscape(4, &value)) {
4633 // If \u is not followed by a four-digit hexadecimal, treat it
4634 // as an identity escape.
4638 // Extended identity escape. We accept any character that hasn't
4639 // been matched by a more specific case, not just the subset required
4640 // by the ECMAScript specification.
4641 uc32 result = current();
4650 CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) {
4651 DCHECK_EQ(0, *char_class);
4652 uc32 first = current();
4653 if (first == '\\') {
4655 case 'w': case 'W': case 'd': case 'D': case 's': case 'S': {
4656 *char_class = Next();
4658 return CharacterRange::Singleton(0); // Return dummy value.
4661 return ReportError(CStrVector("\\ at end of pattern"));
4663 uc32 c = ParseClassCharacterEscape(CHECK_FAILED);
4664 return CharacterRange::Singleton(c);
4668 return CharacterRange::Singleton(first);
4673 static const uc16 kNoCharClass = 0;
4675 // Adds range or pre-defined character class to character ranges.
4676 // If char_class is not kInvalidClass, it's interpreted as a class
4677 // escape (i.e., 's' means whitespace, from '\s').
4678 static inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges,
4680 CharacterRange range,
4682 if (char_class != kNoCharClass) {
4683 CharacterRange::AddClassEscape(char_class, ranges, zone);
4685 ranges->Add(range, zone);
4690 RegExpTree* RegExpParser::ParseCharacterClass() {
4691 static const char* kUnterminated = "Unterminated character class";
4692 static const char* kRangeOutOfOrder = "Range out of order in character class";
4694 DCHECK_EQ(current(), '[');
4696 bool is_negated = false;
4697 if (current() == '^') {
4701 ZoneList<CharacterRange>* ranges =
4702 new(zone()) ZoneList<CharacterRange>(2, zone());
4703 while (has_more() && current() != ']') {
4704 uc16 char_class = kNoCharClass;
4705 CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED);
4706 if (current() == '-') {
4708 if (current() == kEndMarker) {
4709 // If we reach the end we break out of the loop and let the
4710 // following code report an error.
4712 } else if (current() == ']') {
4713 AddRangeOrEscape(ranges, char_class, first, zone());
4714 ranges->Add(CharacterRange::Singleton('-'), zone());
4717 uc16 char_class_2 = kNoCharClass;
4718 CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED);
4719 if (char_class != kNoCharClass || char_class_2 != kNoCharClass) {
4720 // Either end is an escaped character class. Treat the '-' verbatim.
4721 AddRangeOrEscape(ranges, char_class, first, zone());
4722 ranges->Add(CharacterRange::Singleton('-'), zone());
4723 AddRangeOrEscape(ranges, char_class_2, next, zone());
4726 if (first.from() > next.to()) {
4727 return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED);
4729 ranges->Add(CharacterRange::Range(first.from(), next.to()), zone());
4731 AddRangeOrEscape(ranges, char_class, first, zone());
4735 return ReportError(CStrVector(kUnterminated) CHECK_FAILED);
4738 if (ranges->length() == 0) {
4739 ranges->Add(CharacterRange::Everything(), zone());
4740 is_negated = !is_negated;
4742 return new(zone()) RegExpCharacterClass(ranges, is_negated);
4746 // ----------------------------------------------------------------------------
4747 // The Parser interface.
4749 bool RegExpParser::ParseRegExp(FlatStringReader* input,
4751 RegExpCompileData* result,
4753 DCHECK(result != NULL);
4754 RegExpParser parser(input, &result->error, multiline, zone);
4755 RegExpTree* tree = parser.ParsePattern();
4756 if (parser.failed()) {
4757 DCHECK(tree == NULL);
4758 DCHECK(!result->error.is_null());
4760 DCHECK(tree != NULL);
4761 DCHECK(result->error.is_null());
4762 result->tree = tree;
4763 int capture_count = parser.captures_started();
4764 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
4765 result->contains_anchor = parser.contains_anchor();
4766 result->capture_count = capture_count;
4768 return !parser.failed();
4772 bool Parser::Parse() {
4773 DCHECK(info()->function() == NULL);
4774 FunctionLiteral* result = NULL;
4775 ast_value_factory_ = info()->ast_value_factory();
4776 if (ast_value_factory_ == NULL) {
4777 ast_value_factory_ =
4778 new AstValueFactory(zone(), isolate()->heap()->HashSeed());
4780 if (allow_natives_syntax() || extension_ != NULL) {
4781 // If intrinsics are allowed, the Parser cannot operate independent of the
4782 // V8 heap because of Rumtime. Tell the string table to internalize strings
4783 // and values right after they're created.
4784 ast_value_factory_->Internalize(isolate());
4787 if (info()->is_lazy()) {
4788 DCHECK(!info()->is_eval());
4789 if (info()->shared_info()->is_function()) {
4790 result = ParseLazy();
4792 result = ParseProgram();
4796 result = ParseProgram();
4798 info()->SetFunction(result);
4799 DCHECK(ast_value_factory_->IsInternalized());
4800 // info takes ownership of ast_value_factory_.
4801 if (info()->ast_value_factory() == NULL) {
4802 info()->SetAstValueFactory(ast_value_factory_);
4804 ast_value_factory_ = NULL;
4806 InternalizeUseCounts();
4808 return (result != NULL);
4811 } } // namespace v8::internal