1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
9 #include "src/bailout-reason.h"
10 #include "src/base/platform/platform.h"
11 #include "src/bootstrapper.h"
12 #include "src/char-predicates-inl.h"
13 #include "src/codegen.h"
14 #include "src/compiler.h"
15 #include "src/messages.h"
16 #include "src/parser.h"
17 #include "src/preparser.h"
18 #include "src/runtime/runtime.h"
19 #include "src/scanner-character-streams.h"
20 #include "src/scopeinfo.h"
21 #include "src/string-stream.h"
26 ScriptData::ScriptData(const byte* data, int length)
27 : owns_data_(false), rejected_(false), data_(data), length_(length) {
28 if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) {
29 byte* copy = NewArray<byte>(length);
30 DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment));
31 CopyBytes(copy, data, length);
33 AcquireDataOwnership();
38 ParseInfo::ParseInfo(Zone* zone)
41 source_stream_(nullptr),
42 source_stream_encoding_(ScriptCompiler::StreamedSource::ONE_BYTE),
44 compile_options_(ScriptCompiler::kNoCompileOptions),
45 script_scope_(nullptr),
46 unicode_cache_(nullptr),
49 cached_data_(nullptr),
50 ast_value_factory_(nullptr),
55 ParseInfo::ParseInfo(Zone* zone, Handle<JSFunction> function)
56 : ParseInfo(zone, Handle<SharedFunctionInfo>(function->shared())) {
57 set_closure(function);
58 set_context(Handle<Context>(function->context()));
62 ParseInfo::ParseInfo(Zone* zone, Handle<SharedFunctionInfo> shared)
64 isolate_ = shared->GetIsolate();
67 set_hash_seed(isolate_->heap()->HashSeed());
68 set_stack_limit(isolate_->stack_guard()->real_climit());
69 set_unicode_cache(isolate_->unicode_cache());
70 set_language_mode(shared->language_mode());
71 set_shared_info(shared);
73 Handle<Script> script(Script::cast(shared->script()));
75 if (!script.is_null() && script->type()->value() == Script::TYPE_NATIVE) {
81 ParseInfo::ParseInfo(Zone* zone, Handle<Script> script) : ParseInfo(zone) {
82 isolate_ = script->GetIsolate();
84 set_hash_seed(isolate_->heap()->HashSeed());
85 set_stack_limit(isolate_->stack_guard()->real_climit());
86 set_unicode_cache(isolate_->unicode_cache());
89 if (script->type()->value() == Script::TYPE_NATIVE) {
95 RegExpBuilder::RegExpBuilder(Zone* zone)
97 pending_empty_(false),
102 , last_added_(ADD_NONE)
107 void RegExpBuilder::FlushCharacters() {
108 pending_empty_ = false;
109 if (characters_ != NULL) {
110 RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector());
112 text_.Add(atom, zone());
118 void RegExpBuilder::FlushText() {
120 int num_text = text_.length();
123 } else if (num_text == 1) {
124 terms_.Add(text_.last(), zone());
126 RegExpText* text = new(zone()) RegExpText(zone());
127 for (int i = 0; i < num_text; i++)
128 text_.Get(i)->AppendToText(text, zone());
129 terms_.Add(text, zone());
135 void RegExpBuilder::AddCharacter(uc16 c) {
136 pending_empty_ = false;
137 if (characters_ == NULL) {
138 characters_ = new(zone()) ZoneList<uc16>(4, zone());
140 characters_->Add(c, zone());
145 void RegExpBuilder::AddEmpty() {
146 pending_empty_ = true;
150 void RegExpBuilder::AddAtom(RegExpTree* term) {
151 if (term->IsEmpty()) {
155 if (term->IsTextElement()) {
157 text_.Add(term, zone());
160 terms_.Add(term, zone());
166 void RegExpBuilder::AddAssertion(RegExpTree* assert) {
168 terms_.Add(assert, zone());
173 void RegExpBuilder::NewAlternative() {
178 void RegExpBuilder::FlushTerms() {
180 int num_terms = terms_.length();
181 RegExpTree* alternative;
182 if (num_terms == 0) {
183 alternative = new (zone()) RegExpEmpty();
184 } else if (num_terms == 1) {
185 alternative = terms_.last();
187 alternative = new(zone()) RegExpAlternative(terms_.GetList(zone()));
189 alternatives_.Add(alternative, zone());
195 RegExpTree* RegExpBuilder::ToRegExp() {
197 int num_alternatives = alternatives_.length();
198 if (num_alternatives == 0) return new (zone()) RegExpEmpty();
199 if (num_alternatives == 1) return alternatives_.last();
200 return new(zone()) RegExpDisjunction(alternatives_.GetList(zone()));
204 void RegExpBuilder::AddQuantifierToAtom(
205 int min, int max, RegExpQuantifier::QuantifierType quantifier_type) {
206 if (pending_empty_) {
207 pending_empty_ = false;
211 if (characters_ != NULL) {
212 DCHECK(last_added_ == ADD_CHAR);
213 // Last atom was character.
214 Vector<const uc16> char_vector = characters_->ToConstVector();
215 int num_chars = char_vector.length();
217 Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1);
218 text_.Add(new(zone()) RegExpAtom(prefix), zone());
219 char_vector = char_vector.SubVector(num_chars - 1, num_chars);
222 atom = new(zone()) RegExpAtom(char_vector);
224 } else if (text_.length() > 0) {
225 DCHECK(last_added_ == ADD_ATOM);
226 atom = text_.RemoveLast();
228 } else if (terms_.length() > 0) {
229 DCHECK(last_added_ == ADD_ATOM);
230 atom = terms_.RemoveLast();
231 if (atom->max_match() == 0) {
232 // Guaranteed to only match an empty string.
237 terms_.Add(atom, zone());
241 // Only call immediately after adding an atom or character!
246 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone());
251 FunctionEntry ParseData::GetFunctionEntry(int start) {
252 // The current pre-data entry must be a FunctionEntry with the given
254 if ((function_index_ + FunctionEntry::kSize <= Length()) &&
255 (static_cast<int>(Data()[function_index_]) == start)) {
256 int index = function_index_;
257 function_index_ += FunctionEntry::kSize;
258 Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize);
259 return FunctionEntry(subvector);
261 return FunctionEntry();
265 int ParseData::FunctionCount() {
266 int functions_size = FunctionsSize();
267 if (functions_size < 0) return 0;
268 if (functions_size % FunctionEntry::kSize != 0) return 0;
269 return functions_size / FunctionEntry::kSize;
273 bool ParseData::IsSane() {
274 if (!IsAligned(script_data_->length(), sizeof(unsigned))) return false;
275 // Check that the header data is valid and doesn't specify
276 // point to positions outside the store.
277 int data_length = Length();
278 if (data_length < PreparseDataConstants::kHeaderSize) return false;
279 if (Magic() != PreparseDataConstants::kMagicNumber) return false;
280 if (Version() != PreparseDataConstants::kCurrentVersion) return false;
281 if (HasError()) return false;
282 // Check that the space allocated for function entries is sane.
283 int functions_size = FunctionsSize();
284 if (functions_size < 0) return false;
285 if (functions_size % FunctionEntry::kSize != 0) return false;
286 // Check that the total size has room for header and function entries.
288 PreparseDataConstants::kHeaderSize + functions_size;
289 if (data_length < minimum_size) return false;
294 void ParseData::Initialize() {
295 // Prepares state for use.
296 int data_length = Length();
297 if (data_length >= PreparseDataConstants::kHeaderSize) {
298 function_index_ = PreparseDataConstants::kHeaderSize;
303 bool ParseData::HasError() {
304 return Data()[PreparseDataConstants::kHasErrorOffset];
308 unsigned ParseData::Magic() {
309 return Data()[PreparseDataConstants::kMagicOffset];
313 unsigned ParseData::Version() {
314 return Data()[PreparseDataConstants::kVersionOffset];
318 int ParseData::FunctionsSize() {
319 return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]);
323 void Parser::SetCachedData(ParseInfo* info) {
324 if (compile_options_ == ScriptCompiler::kNoCompileOptions) {
325 cached_parse_data_ = NULL;
327 DCHECK(info->cached_data() != NULL);
328 if (compile_options_ == ScriptCompiler::kConsumeParserCache) {
329 cached_parse_data_ = ParseData::FromCachedData(*info->cached_data());
335 FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope,
336 int pos, int end_pos) {
337 int materialized_literal_count = -1;
338 int expected_property_count = -1;
339 int handler_count = 0;
340 int parameter_count = 0;
341 const AstRawString* name = ast_value_factory()->empty_string();
344 FunctionKind kind = call_super ? FunctionKind::kDefaultSubclassConstructor
345 : FunctionKind::kDefaultBaseConstructor;
346 Scope* function_scope = NewScope(scope, FUNCTION_SCOPE, kind);
347 function_scope->SetLanguageMode(
348 static_cast<LanguageMode>(scope->language_mode() | STRICT_BIT));
349 // Set start and end position to the same value
350 function_scope->set_start_position(pos);
351 function_scope->set_end_position(pos);
352 ZoneList<Statement*>* body = NULL;
355 AstNodeFactory function_factory(ast_value_factory());
356 FunctionState function_state(&function_state_, &scope_, function_scope,
357 kind, &function_factory);
359 body = new (zone()) ZoneList<Statement*>(call_super ? 2 : 1, zone());
360 AddAssertIsConstruct(body, pos);
362 ZoneList<Expression*>* args =
363 new (zone()) ZoneList<Expression*>(0, zone());
364 CallRuntime* call = factory()->NewCallRuntime(
365 ast_value_factory()->empty_string(),
366 Runtime::FunctionForId(Runtime::kInlineDefaultConstructorCallSuper),
368 body->Add(factory()->NewReturnStatement(call, pos), zone());
371 materialized_literal_count = function_state.materialized_literal_count();
372 expected_property_count = function_state.expected_property_count();
373 handler_count = function_state.handler_count();
376 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
377 name, ast_value_factory(), function_scope, body,
378 materialized_literal_count, expected_property_count, handler_count,
379 parameter_count, FunctionLiteral::kNoDuplicateParameters,
380 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
381 FunctionLiteral::kNotParenthesized, kind, pos);
383 return function_literal;
387 // ----------------------------------------------------------------------------
388 // Target is a support class to facilitate manipulation of the
389 // Parser's target_stack_ (the stack of potential 'break' and
390 // 'continue' statement targets). Upon construction, a new target is
391 // added; it is removed upon destruction.
393 class Target BASE_EMBEDDED {
395 Target(Target** variable, BreakableStatement* statement)
396 : variable_(variable), statement_(statement), previous_(*variable) {
401 *variable_ = previous_;
404 Target* previous() { return previous_; }
405 BreakableStatement* statement() { return statement_; }
409 BreakableStatement* statement_;
414 class TargetScope BASE_EMBEDDED {
416 explicit TargetScope(Target** variable)
417 : variable_(variable), previous_(*variable) {
422 *variable_ = previous_;
431 // ----------------------------------------------------------------------------
432 // The CHECK_OK macro is a convenient macro to enforce error
433 // handling for functions that may fail (by returning !*ok).
435 // CAUTION: This macro appends extra statements after a call,
436 // thus it must never be used where only a single statement
437 // is correct (e.g. an if statement branch w/o braces)!
439 #define CHECK_OK ok); \
440 if (!*ok) return NULL; \
442 #define DUMMY ) // to make indentation work
445 #define CHECK_FAILED /**/); \
446 if (failed_) return NULL; \
448 #define DUMMY ) // to make indentation work
451 // ----------------------------------------------------------------------------
452 // Implementation of Parser
454 bool ParserTraits::IsEval(const AstRawString* identifier) const {
455 return identifier == parser_->ast_value_factory()->eval_string();
459 bool ParserTraits::IsArguments(const AstRawString* identifier) const {
460 return identifier == parser_->ast_value_factory()->arguments_string();
464 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const {
465 return IsEval(identifier) || IsArguments(identifier);
469 bool ParserTraits::IsPrototype(const AstRawString* identifier) const {
470 return identifier == parser_->ast_value_factory()->prototype_string();
474 bool ParserTraits::IsConstructor(const AstRawString* identifier) const {
475 return identifier == parser_->ast_value_factory()->constructor_string();
479 bool ParserTraits::IsThisProperty(Expression* expression) {
480 DCHECK(expression != NULL);
481 Property* property = expression->AsProperty();
482 return property != NULL && property->obj()->IsVariableProxy() &&
483 property->obj()->AsVariableProxy()->is_this();
487 bool ParserTraits::IsIdentifier(Expression* expression) {
488 VariableProxy* operand = expression->AsVariableProxy();
489 return operand != NULL && !operand->is_this();
493 void ParserTraits::PushPropertyName(FuncNameInferrer* fni,
494 Expression* expression) {
495 if (expression->IsPropertyName()) {
496 fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
498 fni->PushLiteralName(
499 parser_->ast_value_factory()->anonymous_function_string());
504 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
506 DCHECK(left != NULL);
507 if (left->IsProperty() && right->IsFunctionLiteral()) {
508 right->AsFunctionLiteral()->set_pretenure();
513 void ParserTraits::CheckPossibleEvalCall(Expression* expression,
515 VariableProxy* callee = expression->AsVariableProxy();
516 if (callee != NULL &&
517 callee->raw_name() == parser_->ast_value_factory()->eval_string()) {
518 scope->DeclarationScope()->RecordEvalCall();
523 Expression* ParserTraits::MarkExpressionAsAssigned(Expression* expression) {
524 VariableProxy* proxy =
525 expression != NULL ? expression->AsVariableProxy() : NULL;
526 if (proxy != NULL) proxy->set_is_assigned();
531 bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
532 Expression** x, Expression* y, Token::Value op, int pos,
533 AstNodeFactory* factory) {
534 if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
535 y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) {
536 double x_val = (*x)->AsLiteral()->raw_value()->AsNumber();
537 double y_val = y->AsLiteral()->raw_value()->AsNumber();
540 *x = factory->NewNumberLiteral(x_val + y_val, pos);
543 *x = factory->NewNumberLiteral(x_val - y_val, pos);
546 *x = factory->NewNumberLiteral(x_val * y_val, pos);
549 *x = factory->NewNumberLiteral(x_val / y_val, pos);
551 case Token::BIT_OR: {
552 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
553 *x = factory->NewNumberLiteral(value, pos);
556 case Token::BIT_AND: {
557 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
558 *x = factory->NewNumberLiteral(value, pos);
561 case Token::BIT_XOR: {
562 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
563 *x = factory->NewNumberLiteral(value, pos);
567 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
568 *x = factory->NewNumberLiteral(value, pos);
572 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
573 uint32_t value = DoubleToUint32(x_val) >> shift;
574 *x = factory->NewNumberLiteral(value, pos);
578 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
579 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
580 *x = factory->NewNumberLiteral(value, pos);
591 Expression* ParserTraits::BuildUnaryExpression(Expression* expression,
592 Token::Value op, int pos,
593 AstNodeFactory* factory) {
594 DCHECK(expression != NULL);
595 if (expression->IsLiteral()) {
596 const AstValue* literal = expression->AsLiteral()->raw_value();
597 if (op == Token::NOT) {
598 // Convert the literal to a boolean condition and negate it.
599 bool condition = literal->BooleanValue();
600 return factory->NewBooleanLiteral(!condition, pos);
601 } else if (literal->IsNumber()) {
602 // Compute some expressions involving only number literals.
603 double value = literal->AsNumber();
608 return factory->NewNumberLiteral(-value, pos);
610 return factory->NewNumberLiteral(~DoubleToInt32(value), pos);
616 // Desugar '+foo' => 'foo*1'
617 if (op == Token::ADD) {
618 return factory->NewBinaryOperation(
619 Token::MUL, expression, factory->NewNumberLiteral(1, pos), pos);
621 // The same idea for '-foo' => 'foo*(-1)'.
622 if (op == Token::SUB) {
623 return factory->NewBinaryOperation(
624 Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos);
626 // ...and one more time for '~foo' => 'foo^(~0)'.
627 if (op == Token::BIT_NOT) {
628 return factory->NewBinaryOperation(
629 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos);
631 return factory->NewUnaryOperation(op, expression, pos);
635 Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) {
636 return NewThrowError(
637 parser_->ast_value_factory()->make_reference_error_string(), message,
638 parser_->ast_value_factory()->empty_string(), pos);
642 Expression* ParserTraits::NewThrowSyntaxError(
643 const char* message, const AstRawString* arg, int pos) {
644 return NewThrowError(parser_->ast_value_factory()->make_syntax_error_string(),
649 Expression* ParserTraits::NewThrowTypeError(
650 const char* message, const AstRawString* arg, int pos) {
651 return NewThrowError(parser_->ast_value_factory()->make_type_error_string(),
656 Expression* ParserTraits::NewThrowError(
657 const AstRawString* constructor, const char* message,
658 const AstRawString* arg, int pos) {
659 Zone* zone = parser_->zone();
660 const AstRawString* type =
661 parser_->ast_value_factory()->GetOneByteString(message);
662 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone);
663 args->Add(parser_->factory()->NewStringLiteral(type, pos), zone);
664 args->Add(parser_->factory()->NewStringLiteral(arg, pos), zone);
665 CallRuntime* call_constructor =
666 parser_->factory()->NewCallRuntime(constructor, NULL, args, pos);
667 return parser_->factory()->NewThrow(call_constructor, pos);
671 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
672 const char* message, const char* arg,
673 ParseErrorType error_type) {
674 if (parser_->stack_overflow()) {
675 // Suppress the error message (syntax error or such) in the presence of a
676 // stack overflow. The isolate allows only one pending exception at at time
677 // and we want to report the stack overflow later.
680 parser_->pending_error_handler_.ReportMessageAt(source_location.beg_pos,
681 source_location.end_pos,
682 message, arg, error_type);
686 void ParserTraits::ReportMessage(const char* message, const char* arg,
687 ParseErrorType error_type) {
688 Scanner::Location source_location = parser_->scanner()->location();
689 ReportMessageAt(source_location, message, arg, error_type);
693 void ParserTraits::ReportMessage(const char* message, const AstRawString* arg,
694 ParseErrorType error_type) {
695 Scanner::Location source_location = parser_->scanner()->location();
696 ReportMessageAt(source_location, message, arg, error_type);
700 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
701 const char* message, const AstRawString* arg,
702 ParseErrorType error_type) {
703 if (parser_->stack_overflow()) {
704 // Suppress the error message (syntax error or such) in the presence of a
705 // stack overflow. The isolate allows only one pending exception at at time
706 // and we want to report the stack overflow later.
709 parser_->pending_error_handler_.ReportMessageAt(source_location.beg_pos,
710 source_location.end_pos,
711 message, arg, error_type);
715 const AstRawString* ParserTraits::GetSymbol(Scanner* scanner) {
716 const AstRawString* result =
717 parser_->scanner()->CurrentSymbol(parser_->ast_value_factory());
718 DCHECK(result != NULL);
723 const AstRawString* ParserTraits::GetNumberAsSymbol(Scanner* scanner) {
724 double double_value = parser_->scanner()->DoubleValue();
727 DoubleToCString(double_value, Vector<char>(array, arraysize(array)));
728 return parser_->ast_value_factory()->GetOneByteString(string);
732 const AstRawString* ParserTraits::GetNextSymbol(Scanner* scanner) {
733 return parser_->scanner()->NextSymbol(parser_->ast_value_factory());
737 Expression* ParserTraits::ThisExpression(Scope* scope, AstNodeFactory* factory,
739 return factory->NewVariableProxy(scope->receiver(), pos);
742 Expression* ParserTraits::SuperReference(Scope* scope, AstNodeFactory* factory,
744 return factory->NewSuperReference(
745 ThisExpression(scope, factory, pos)->AsVariableProxy(),
750 Expression* ParserTraits::DefaultConstructor(bool call_super, Scope* scope,
751 int pos, int end_pos) {
752 return parser_->DefaultConstructor(call_super, scope, pos, end_pos);
756 Literal* ParserTraits::ExpressionFromLiteral(Token::Value token, int pos,
758 AstNodeFactory* factory) {
760 case Token::NULL_LITERAL:
761 return factory->NewNullLiteral(pos);
762 case Token::TRUE_LITERAL:
763 return factory->NewBooleanLiteral(true, pos);
764 case Token::FALSE_LITERAL:
765 return factory->NewBooleanLiteral(false, pos);
767 int value = scanner->smi_value();
768 return factory->NewSmiLiteral(value, pos);
770 case Token::NUMBER: {
771 double value = scanner->DoubleValue();
772 return factory->NewNumberLiteral(value, pos);
781 Expression* ParserTraits::ExpressionFromIdentifier(const AstRawString* name,
785 AstNodeFactory* factory) {
786 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name);
788 // Arrow function parameters are parsed as an expression. When
789 // parsing lazily, it is enough to create a VariableProxy in order
790 // for Traits::DeclareArrowParametersFromExpression() to be able to
791 // pick the names of the parameters.
792 return parser_->parsing_lazy_arrow_parameters_
793 ? factory->NewVariableProxy(name, Variable::NORMAL, start_position,
795 : scope->NewUnresolved(factory, name, start_position,
800 Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner,
801 AstNodeFactory* factory) {
802 const AstRawString* symbol = GetSymbol(scanner);
803 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol);
804 return factory->NewStringLiteral(symbol, pos);
808 Expression* ParserTraits::GetIterator(Expression* iterable,
809 AstNodeFactory* factory) {
810 Expression* iterator_symbol_literal =
811 factory->NewSymbolLiteral("iterator_symbol", RelocInfo::kNoPosition);
812 int pos = iterable->position();
814 factory->NewProperty(iterable, iterator_symbol_literal, pos);
815 Zone* zone = parser_->zone();
816 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(0, zone);
817 return factory->NewCall(prop, args, pos);
821 Literal* ParserTraits::GetLiteralTheHole(int position,
822 AstNodeFactory* factory) {
823 return factory->NewTheHoleLiteral(RelocInfo::kNoPosition);
827 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) {
828 return parser_->ParseV8Intrinsic(ok);
832 FunctionLiteral* ParserTraits::ParseFunctionLiteral(
833 const AstRawString* name, Scanner::Location function_name_location,
834 bool name_is_strict_reserved, FunctionKind kind,
835 int function_token_position, FunctionLiteral::FunctionType type,
836 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
837 return parser_->ParseFunctionLiteral(
838 name, function_name_location, name_is_strict_reserved, kind,
839 function_token_position, type, arity_restriction, ok);
843 ClassLiteral* ParserTraits::ParseClassLiteral(
844 const AstRawString* name, Scanner::Location class_name_location,
845 bool name_is_strict_reserved, int pos, bool* ok) {
846 return parser_->ParseClassLiteral(name, class_name_location,
847 name_is_strict_reserved, pos, ok);
851 Parser::Parser(ParseInfo* info)
852 : ParserBase<ParserTraits>(info->zone(), &scanner_, info->stack_limit(),
853 info->extension(), info->ast_value_factory(),
855 scanner_(info->unicode_cache()),
856 reusable_preparser_(NULL),
857 original_scope_(NULL),
859 compile_options_(info->compile_options()),
860 cached_parse_data_(NULL),
861 parsing_lazy_arrow_parameters_(false),
862 total_preparse_skipped_(0),
863 pre_parse_timer_(NULL),
864 parsing_on_main_thread_(true) {
865 // Even though we were passed ParseInfo, we should not store it in
866 // Parser - this makes sure that Isolate is not accidentally accessed via
867 // ParseInfo during background parsing.
868 DCHECK(!info->script().is_null() || info->source_stream() != NULL);
869 set_allow_lazy(info->allow_lazy_parsing());
870 set_allow_natives(FLAG_allow_natives_syntax || info->is_native());
871 set_allow_harmony_modules(!info->is_native() && FLAG_harmony_modules);
872 set_allow_harmony_arrow_functions(FLAG_harmony_arrow_functions);
873 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
874 set_allow_harmony_classes(FLAG_harmony_classes);
875 set_allow_harmony_object_literals(FLAG_harmony_object_literals);
876 set_allow_harmony_sloppy(FLAG_harmony_sloppy);
877 set_allow_harmony_unicode(FLAG_harmony_unicode);
878 set_allow_harmony_computed_property_names(
879 FLAG_harmony_computed_property_names);
880 set_allow_harmony_rest_params(FLAG_harmony_rest_parameters);
881 set_allow_strong_mode(FLAG_strong_mode);
882 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
884 use_counts_[feature] = 0;
886 if (info->ast_value_factory() == NULL) {
887 // info takes ownership of AstValueFactory.
888 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed()));
889 info->set_ast_value_factory_owned();
890 ast_value_factory_ = info->ast_value_factory();
895 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
896 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
897 // see comment for HistogramTimerScope class.
899 // It's OK to use the Isolate & counters here, since this function is only
900 // called in the main thread.
901 DCHECK(parsing_on_main_thread_);
903 HistogramTimerScope timer_scope(isolate->counters()->parse(), true);
904 Handle<String> source(String::cast(info->script()->source()));
905 isolate->counters()->total_parse_size()->Increment(source->length());
906 base::ElapsedTimer timer;
907 if (FLAG_trace_parse) {
910 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
912 // Initialize parser state.
913 CompleteParserRecorder recorder;
915 if (produce_cached_parse_data()) {
917 } else if (consume_cached_parse_data()) {
918 cached_parse_data_->Initialize();
921 source = String::Flatten(source);
922 FunctionLiteral* result;
924 Scope* top_scope = NULL;
925 Scope* eval_scope = NULL;
926 if (source->IsExternalTwoByteString()) {
927 // Notice that the stream is destroyed at the end of the branch block.
928 // The last line of the blocks can't be moved outside, even though they're
930 ExternalTwoByteStringUtf16CharacterStream stream(
931 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
932 scanner_.Initialize(&stream);
933 result = DoParseProgram(info, &top_scope, &eval_scope);
935 GenericStringUtf16CharacterStream stream(source, 0, source->length());
936 scanner_.Initialize(&stream);
937 result = DoParseProgram(info, &top_scope, &eval_scope);
939 top_scope->set_end_position(source->length());
940 if (eval_scope != NULL) {
941 eval_scope->set_end_position(source->length());
943 HandleSourceURLComments(isolate, info->script());
945 if (FLAG_trace_parse && result != NULL) {
946 double ms = timer.Elapsed().InMillisecondsF();
947 if (info->is_eval()) {
948 PrintF("[parsing eval");
949 } else if (info->script()->name()->IsString()) {
950 String* name = String::cast(info->script()->name());
951 SmartArrayPointer<char> name_chars = name->ToCString();
952 PrintF("[parsing script: %s", name_chars.get());
954 PrintF("[parsing script");
956 PrintF(" - took %0.3f ms]\n", ms);
958 if (produce_cached_parse_data()) {
959 if (result != NULL) *info->cached_data() = recorder.GetScriptData();
966 FunctionLiteral* Parser::DoParseProgram(ParseInfo* info, Scope** scope,
967 Scope** eval_scope) {
968 // Note that this function can be called from the main thread or from a
969 // background thread. We should not access anything Isolate / heap dependent
970 // via ParseInfo, and also not pass it forward.
971 DCHECK(scope_ == NULL);
972 DCHECK(target_stack_ == NULL);
974 FunctionLiteral* result = NULL;
976 *scope = NewScope(scope_, SCRIPT_SCOPE);
977 info->set_script_scope(*scope);
978 if (!info->context().is_null() && !info->context()->IsNativeContext()) {
979 *scope = Scope::DeserializeScopeChain(info->isolate(), zone(),
980 *info->context(), *scope);
981 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this
982 // means the Parser cannot operate independent of the V8 heap. Tell the
983 // string table to internalize strings and values right after they're
984 // created. This kind of parsing can only be done in the main thread.
985 DCHECK(parsing_on_main_thread_);
986 ast_value_factory()->Internalize(info->isolate());
988 original_scope_ = *scope;
989 if (info->is_eval()) {
990 if (!(*scope)->is_script_scope() || is_strict(info->language_mode())) {
991 *scope = NewScope(*scope, EVAL_SCOPE);
993 } else if (info->is_module()) {
994 *scope = NewScope(*scope, MODULE_SCOPE);
996 (*scope)->set_start_position(0);
997 // End position will be set by the caller.
999 // Compute the parsing mode.
1000 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY;
1001 if (allow_natives() || extension_ != NULL ||
1002 (*scope)->is_eval_scope()) {
1003 mode = PARSE_EAGERLY;
1005 ParsingModeScope parsing_mode(this, mode);
1008 AstNodeFactory function_factory(ast_value_factory());
1009 FunctionState function_state(&function_state_, &scope_, *scope,
1010 kNormalFunction, &function_factory);
1012 scope_->SetLanguageMode(info->language_mode());
1013 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
1015 int beg_pos = scanner()->location().beg_pos;
1016 if (info->is_module()) {
1017 DCHECK(allow_harmony_modules());
1018 ParseModuleItemList(body, &ok);
1020 ParseStatementList(body, Token::EOS, info->is_eval(), eval_scope, &ok);
1023 if (ok && is_strict(language_mode())) {
1024 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
1025 CheckConflictingVarDeclarations(scope_, &ok);
1028 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
1029 if (body->length() != 1 ||
1030 !body->at(0)->IsExpressionStatement() ||
1031 !body->at(0)->AsExpressionStatement()->
1032 expression()->IsFunctionLiteral()) {
1033 ReportMessage("single_function_literal");
1039 result = factory()->NewFunctionLiteral(
1040 ast_value_factory()->empty_string(), ast_value_factory(), scope_,
1041 body, function_state.materialized_literal_count(),
1042 function_state.expected_property_count(),
1043 function_state.handler_count(), 0,
1044 FunctionLiteral::kNoDuplicateParameters,
1045 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval,
1046 FunctionLiteral::kNotParenthesized, FunctionKind::kNormalFunction, 0);
1050 // Make sure the target stack is empty.
1051 DCHECK(target_stack_ == NULL);
1057 FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info) {
1058 // It's OK to use the Isolate & counters here, since this function is only
1059 // called in the main thread.
1060 DCHECK(parsing_on_main_thread_);
1061 HistogramTimerScope timer_scope(isolate->counters()->parse_lazy());
1062 Handle<String> source(String::cast(info->script()->source()));
1063 isolate->counters()->total_parse_size()->Increment(source->length());
1064 base::ElapsedTimer timer;
1065 if (FLAG_trace_parse) {
1068 Handle<SharedFunctionInfo> shared_info = info->shared_info();
1070 // Initialize parser state.
1071 source = String::Flatten(source);
1072 FunctionLiteral* result;
1073 if (source->IsExternalTwoByteString()) {
1074 ExternalTwoByteStringUtf16CharacterStream stream(
1075 Handle<ExternalTwoByteString>::cast(source),
1076 shared_info->start_position(),
1077 shared_info->end_position());
1078 result = ParseLazy(isolate, info, &stream);
1080 GenericStringUtf16CharacterStream stream(source,
1081 shared_info->start_position(),
1082 shared_info->end_position());
1083 result = ParseLazy(isolate, info, &stream);
1086 if (FLAG_trace_parse && result != NULL) {
1087 double ms = timer.Elapsed().InMillisecondsF();
1088 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString();
1089 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
1095 FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info,
1096 Utf16CharacterStream* source) {
1097 Handle<SharedFunctionInfo> shared_info = info->shared_info();
1098 scanner_.Initialize(source);
1099 DCHECK(scope_ == NULL);
1100 DCHECK(target_stack_ == NULL);
1102 Handle<String> name(String::cast(shared_info->name()));
1103 DCHECK(ast_value_factory());
1104 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
1105 const AstRawString* raw_name = ast_value_factory()->GetString(name);
1106 fni_->PushEnclosingName(raw_name);
1108 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1110 // Place holder for the result.
1111 FunctionLiteral* result = NULL;
1114 // Parse the function literal.
1115 Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
1116 info->set_script_scope(scope);
1117 if (!info->closure().is_null()) {
1118 // Ok to use Isolate here, since lazy function parsing is only done in the
1120 DCHECK(parsing_on_main_thread_);
1121 scope = Scope::DeserializeScopeChain(isolate, zone(),
1122 info->closure()->context(), scope);
1124 original_scope_ = scope;
1125 AstNodeFactory function_factory(ast_value_factory());
1126 FunctionState function_state(&function_state_, &scope_, scope,
1127 shared_info->kind(), &function_factory);
1128 DCHECK(is_sloppy(scope->language_mode()) ||
1129 is_strict(info->language_mode()));
1130 DCHECK(info->language_mode() == shared_info->language_mode());
1131 scope->SetLanguageMode(shared_info->language_mode());
1132 FunctionLiteral::FunctionType function_type = shared_info->is_expression()
1133 ? (shared_info->is_anonymous()
1134 ? FunctionLiteral::ANONYMOUS_EXPRESSION
1135 : FunctionLiteral::NAMED_EXPRESSION)
1136 : FunctionLiteral::DECLARATION;
1139 if (shared_info->is_arrow()) {
1140 // The first expression being parsed is the parameter list of the arrow
1141 // function. Setting this avoids prevents ExpressionFromIdentifier()
1142 // from creating unresolved variables in already-resolved scopes.
1143 parsing_lazy_arrow_parameters_ = true;
1144 Expression* expression = ParseExpression(false, &ok);
1146 // Scanning must end at the same position that was recorded
1147 // previously. If not, parsing has been interrupted due to a
1148 // stack overflow, at which point the partially parsed arrow
1149 // function concise body happens to be a valid expression. This
1150 // is a problem only for arrow functions with single statement
1151 // bodies, since there is no end token such as "}" for normal
1153 if (scanner()->location().end_pos == shared_info->end_position()) {
1154 // The pre-parser saw an arrow function here, so the full parser
1155 // must produce a FunctionLiteral.
1156 DCHECK(expression->IsFunctionLiteral());
1157 result = expression->AsFunctionLiteral();
1163 } else if (shared_info->is_default_constructor()) {
1164 result = DefaultConstructor(IsSubclassConstructor(shared_info->kind()),
1165 scope, shared_info->start_position(),
1166 shared_info->end_position());
1168 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(),
1169 false, // Strict mode name already checked.
1170 shared_info->kind(), RelocInfo::kNoPosition,
1172 FunctionLiteral::NORMAL_ARITY, &ok);
1174 // Make sure the results agree.
1175 DCHECK(ok == (result != NULL));
1178 // Make sure the target stack is empty.
1179 DCHECK(target_stack_ == NULL);
1181 if (result != NULL) {
1182 Handle<String> inferred_name(shared_info->inferred_name());
1183 result->set_inferred_name(inferred_name);
1189 void* Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token,
1190 bool is_eval, Scope** eval_scope, bool* ok) {
1192 // (StatementListItem)* <end_token>
1194 // Allocate a target stack to use for this set of source
1195 // elements. This way, all scripts and functions get their own
1196 // target stack thus avoiding illegal breaks and continues across
1198 TargetScope scope(&this->target_stack_);
1200 DCHECK(body != NULL);
1201 bool directive_prologue = true; // Parsing directive prologue.
1203 while (peek() != end_token) {
1204 if (directive_prologue && peek() != Token::STRING) {
1205 directive_prologue = false;
1208 Token::Value token = peek();
1209 Scanner::Location token_loc = scanner()->peek_location();
1210 Scanner::Location old_super_loc = function_state_->super_call_location();
1211 Statement* stat = ParseStatementListItem(CHECK_OK);
1212 Scanner::Location super_loc = function_state_->super_call_location();
1214 if (is_strong(language_mode()) &&
1215 i::IsConstructor(function_state_->kind()) &&
1216 !old_super_loc.IsValid() && super_loc.IsValid() &&
1217 token != Token::SUPER) {
1218 // TODO(rossberg): This is more permissive than spec'ed, it allows e.g.
1222 // That should still be safe, though, thanks to left-to-right evaluation.
1223 // The proper check would be difficult to implement in the preparser.
1224 ReportMessageAt(super_loc, "strong_super_call_nested");
1229 if (stat == NULL || stat->IsEmpty()) {
1230 directive_prologue = false; // End of directive prologue.
1234 if (directive_prologue) {
1235 // A shot at a directive.
1236 ExpressionStatement* e_stat;
1238 // Still processing directive prologue?
1239 if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1240 (literal = e_stat->expression()->AsLiteral()) != NULL &&
1241 literal->raw_value()->IsString()) {
1242 // Check "use strict" directive (ES5 14.1), "use asm" directive, and
1243 // "use strong" directive (experimental).
1244 bool use_strict_found =
1245 literal->raw_value()->AsString() ==
1246 ast_value_factory()->use_strict_string() &&
1247 token_loc.end_pos - token_loc.beg_pos ==
1248 ast_value_factory()->use_strict_string()->length() + 2;
1249 bool use_strong_found =
1250 allow_strong_mode() &&
1251 literal->raw_value()->AsString() ==
1252 ast_value_factory()->use_strong_string() &&
1253 token_loc.end_pos - token_loc.beg_pos ==
1254 ast_value_factory()->use_strong_string()->length() + 2;
1255 if (use_strict_found || use_strong_found) {
1256 // Strong mode implies strict mode. If there are several "use strict"
1257 // / "use strong" directives, do the strict mode changes only once.
1258 if (is_sloppy(scope_->language_mode())) {
1259 // TODO(mstarzinger): Global strict eval calls, need their own scope
1260 // as specified in ES5 10.4.2(3). The correct fix would be to always
1261 // add this scope in DoParseProgram(), but that requires adaptations
1262 // all over the code base, so we go with a quick-fix for now.
1263 // In the same manner, we have to patch the parsing mode.
1264 if (is_eval && !scope_->is_eval_scope()) {
1265 DCHECK(scope_->is_script_scope());
1266 Scope* scope = NewScope(scope_, EVAL_SCOPE);
1267 scope->set_start_position(scope_->start_position());
1268 scope->set_end_position(scope_->end_position());
1270 if (eval_scope != NULL) {
1271 // Caller will correct the positions of the ad hoc eval scope.
1272 *eval_scope = scope;
1274 mode_ = PARSE_EAGERLY;
1276 scope_->SetLanguageMode(static_cast<LanguageMode>(
1277 scope_->language_mode() | STRICT_BIT));
1280 if (use_strong_found) {
1281 scope_->SetLanguageMode(static_cast<LanguageMode>(
1282 scope_->language_mode() | STRONG_BIT));
1284 } else if (literal->raw_value()->AsString() ==
1285 ast_value_factory()->use_asm_string() &&
1286 token_loc.end_pos - token_loc.beg_pos ==
1287 ast_value_factory()->use_asm_string()->length() + 2) {
1288 // Store the usage count; The actual use counter on the isolate is
1289 // incremented after parsing is done.
1290 ++use_counts_[v8::Isolate::kUseAsm];
1291 scope_->SetAsmModule();
1294 // End of the directive prologue.
1295 directive_prologue = false;
1299 body->Add(stat, zone());
1306 Statement* Parser::ParseStatementListItem(bool* ok) {
1307 // (Ecma 262 6th Edition, 13.1):
1308 // StatementListItem:
1313 case Token::FUNCTION:
1314 return ParseFunctionDeclaration(NULL, ok);
1316 return ParseClassDeclaration(NULL, ok);
1319 return ParseVariableStatement(kStatementListItem, NULL, ok);
1321 if (is_strict(language_mode())) {
1322 return ParseVariableStatement(kStatementListItem, NULL, ok);
1326 return ParseStatement(NULL, ok);
1331 Statement* Parser::ParseModuleItem(bool* ok) {
1332 // (Ecma 262 6th Edition, 15.2):
1334 // ImportDeclaration
1335 // ExportDeclaration
1336 // StatementListItem
1340 return ParseImportDeclaration(ok);
1342 return ParseExportDeclaration(ok);
1344 return ParseStatementListItem(ok);
1349 void* Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) {
1350 // (Ecma 262 6th Edition, 15.2):
1357 DCHECK(scope_->is_module_scope());
1358 scope_->SetLanguageMode(
1359 static_cast<LanguageMode>(scope_->language_mode() | STRICT_BIT));
1361 while (peek() != Token::EOS) {
1362 Statement* stat = ParseModuleItem(CHECK_OK);
1363 if (stat && !stat->IsEmpty()) {
1364 body->Add(stat, zone());
1368 // Check that all exports are bound.
1369 ModuleDescriptor* descriptor = scope_->module();
1370 for (ModuleDescriptor::Iterator it = descriptor->iterator(); !it.done();
1372 if (scope_->LookupLocal(it.local_name()) == NULL) {
1373 // TODO(adamk): Pass both local_name and export_name once ParserTraits
1374 // supports multiple arg error messages.
1375 // Also try to report this at a better location.
1376 ParserTraits::ReportMessage("module_export_undefined", it.local_name());
1382 scope_->module()->Freeze();
1387 const AstRawString* Parser::ParseModuleSpecifier(bool* ok) {
1388 // ModuleSpecifier :
1391 Expect(Token::STRING, CHECK_OK);
1392 return GetSymbol(scanner());
1396 void* Parser::ParseExportClause(ZoneList<const AstRawString*>* export_names,
1397 ZoneList<Scanner::Location>* export_locations,
1398 ZoneList<const AstRawString*>* local_names,
1399 Scanner::Location* reserved_loc, bool* ok) {
1402 // '{' ExportsList '}'
1403 // '{' ExportsList ',' '}'
1407 // ExportsList ',' ExportSpecifier
1409 // ExportSpecifier :
1411 // IdentifierName 'as' IdentifierName
1413 Expect(Token::LBRACE, CHECK_OK);
1415 Token::Value name_tok;
1416 while ((name_tok = peek()) != Token::RBRACE) {
1417 // Keep track of the first reserved word encountered in case our
1418 // caller needs to report an error.
1419 if (!reserved_loc->IsValid() &&
1420 !Token::IsIdentifier(name_tok, STRICT, false)) {
1421 *reserved_loc = scanner()->location();
1423 const AstRawString* local_name = ParseIdentifierName(CHECK_OK);
1424 const AstRawString* export_name = NULL;
1425 if (CheckContextualKeyword(CStrVector("as"))) {
1426 export_name = ParseIdentifierName(CHECK_OK);
1428 if (export_name == NULL) {
1429 export_name = local_name;
1431 export_names->Add(export_name, zone());
1432 local_names->Add(local_name, zone());
1433 export_locations->Add(scanner()->location(), zone());
1434 if (peek() == Token::RBRACE) break;
1435 Expect(Token::COMMA, CHECK_OK);
1438 Expect(Token::RBRACE, CHECK_OK);
1444 ZoneList<ImportDeclaration*>* Parser::ParseNamedImports(int pos, bool* ok) {
1447 // '{' ImportsList '}'
1448 // '{' ImportsList ',' '}'
1452 // ImportsList ',' ImportSpecifier
1454 // ImportSpecifier :
1455 // BindingIdentifier
1456 // IdentifierName 'as' BindingIdentifier
1458 Expect(Token::LBRACE, CHECK_OK);
1460 ZoneList<ImportDeclaration*>* result =
1461 new (zone()) ZoneList<ImportDeclaration*>(1, zone());
1462 while (peek() != Token::RBRACE) {
1463 const AstRawString* import_name = ParseIdentifierName(CHECK_OK);
1464 const AstRawString* local_name = import_name;
1465 // In the presence of 'as', the left-side of the 'as' can
1466 // be any IdentifierName. But without 'as', it must be a valid
1467 // BindingIdentifier.
1468 if (CheckContextualKeyword(CStrVector("as"))) {
1469 local_name = ParseIdentifierName(CHECK_OK);
1471 if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false)) {
1473 ReportMessage("unexpected_reserved");
1475 } else if (IsEvalOrArguments(local_name)) {
1477 ReportMessage("strict_eval_arguments");
1480 VariableProxy* proxy = NewUnresolved(local_name, IMPORT);
1481 ImportDeclaration* declaration =
1482 factory()->NewImportDeclaration(proxy, import_name, NULL, scope_, pos);
1483 Declare(declaration, true, CHECK_OK);
1484 result->Add(declaration, zone());
1485 if (peek() == Token::RBRACE) break;
1486 Expect(Token::COMMA, CHECK_OK);
1489 Expect(Token::RBRACE, CHECK_OK);
1495 Statement* Parser::ParseImportDeclaration(bool* ok) {
1496 // ImportDeclaration :
1497 // 'import' ImportClause 'from' ModuleSpecifier ';'
1498 // 'import' ModuleSpecifier ';'
1503 // ImportedDefaultBinding
1504 // ImportedDefaultBinding ',' NameSpaceImport
1505 // ImportedDefaultBinding ',' NamedImports
1507 // NameSpaceImport :
1508 // '*' 'as' ImportedBinding
1510 int pos = peek_position();
1511 Expect(Token::IMPORT, CHECK_OK);
1513 Token::Value tok = peek();
1515 // 'import' ModuleSpecifier ';'
1516 if (tok == Token::STRING) {
1517 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1518 ExpectSemicolon(CHECK_OK);
1519 // TODO(ES6): Add module to the requested modules of scope_->module().
1520 USE(module_specifier);
1521 return factory()->NewEmptyStatement(pos);
1524 // Parse ImportedDefaultBinding if present.
1525 ImportDeclaration* import_default_declaration = NULL;
1526 if (tok != Token::MUL && tok != Token::LBRACE) {
1527 const AstRawString* local_name =
1528 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1529 VariableProxy* proxy = NewUnresolved(local_name, IMPORT);
1530 import_default_declaration = factory()->NewImportDeclaration(
1531 proxy, ast_value_factory()->default_string(), NULL, scope_, pos);
1532 Declare(import_default_declaration, true, CHECK_OK);
1535 const AstRawString* module_instance_binding = NULL;
1536 ZoneList<ImportDeclaration*>* named_declarations = NULL;
1537 if (import_default_declaration == NULL || Check(Token::COMMA)) {
1540 Consume(Token::MUL);
1541 ExpectContextualKeyword(CStrVector("as"), CHECK_OK);
1542 module_instance_binding =
1543 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1544 // TODO(ES6): Add an appropriate declaration.
1549 named_declarations = ParseNamedImports(pos, CHECK_OK);
1554 ReportUnexpectedToken(scanner()->current_token());
1559 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1560 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1561 ExpectSemicolon(CHECK_OK);
1563 if (module_instance_binding != NULL) {
1564 // TODO(ES6): Set the module specifier for the module namespace binding.
1567 if (import_default_declaration != NULL) {
1568 import_default_declaration->set_module_specifier(module_specifier);
1571 if (named_declarations != NULL) {
1572 for (int i = 0; i < named_declarations->length(); ++i) {
1573 named_declarations->at(i)->set_module_specifier(module_specifier);
1577 return factory()->NewEmptyStatement(pos);
1581 Statement* Parser::ParseExportDefault(bool* ok) {
1582 // Supports the following productions, starting after the 'default' token:
1583 // 'export' 'default' FunctionDeclaration
1584 // 'export' 'default' ClassDeclaration
1585 // 'export' 'default' AssignmentExpression[In] ';'
1587 Expect(Token::DEFAULT, CHECK_OK);
1588 Scanner::Location default_loc = scanner()->location();
1590 ZoneList<const AstRawString*> names(1, zone());
1591 Statement* result = NULL;
1593 case Token::FUNCTION:
1594 // TODO(ES6): Support parsing anonymous function declarations here.
1595 result = ParseFunctionDeclaration(&names, CHECK_OK);
1599 // TODO(ES6): Support parsing anonymous class declarations here.
1600 result = ParseClassDeclaration(&names, CHECK_OK);
1604 int pos = peek_position();
1605 Expression* expr = ParseAssignmentExpression(true, CHECK_OK);
1606 ExpectSemicolon(CHECK_OK);
1607 result = factory()->NewExpressionStatement(expr, pos);
1612 const AstRawString* default_string = ast_value_factory()->default_string();
1614 DCHECK_LE(names.length(), 1);
1615 if (names.length() == 1) {
1616 scope_->module()->AddLocalExport(default_string, names.first(), zone(), ok);
1618 ParserTraits::ReportMessageAt(default_loc, "duplicate_export",
1623 // TODO(ES6): Assign result to a const binding with the name "*default*"
1624 // and add an export entry with "*default*" as the local name.
1631 Statement* Parser::ParseExportDeclaration(bool* ok) {
1632 // ExportDeclaration:
1633 // 'export' '*' 'from' ModuleSpecifier ';'
1634 // 'export' ExportClause ('from' ModuleSpecifier)? ';'
1635 // 'export' VariableStatement
1636 // 'export' Declaration
1637 // 'export' 'default' ... (handled in ParseExportDefault)
1639 int pos = peek_position();
1640 Expect(Token::EXPORT, CHECK_OK);
1642 Statement* result = NULL;
1643 ZoneList<const AstRawString*> names(1, zone());
1645 case Token::DEFAULT:
1646 return ParseExportDefault(ok);
1649 Consume(Token::MUL);
1650 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1651 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1652 ExpectSemicolon(CHECK_OK);
1653 // TODO(ES6): scope_->module()->AddStarExport(...)
1654 USE(module_specifier);
1655 return factory()->NewEmptyStatement(pos);
1658 case Token::LBRACE: {
1659 // There are two cases here:
1661 // 'export' ExportClause ';'
1663 // 'export' ExportClause FromClause ';'
1665 // In the first case, the exported identifiers in ExportClause must
1666 // not be reserved words, while in the latter they may be. We
1667 // pass in a location that gets filled with the first reserved word
1668 // encountered, and then throw a SyntaxError if we are in the
1669 // non-FromClause case.
1670 Scanner::Location reserved_loc = Scanner::Location::invalid();
1671 ZoneList<const AstRawString*> export_names(1, zone());
1672 ZoneList<Scanner::Location> export_locations(1, zone());
1673 ZoneList<const AstRawString*> local_names(1, zone());
1674 ParseExportClause(&export_names, &export_locations, &local_names,
1675 &reserved_loc, CHECK_OK);
1676 const AstRawString* indirect_export_module_specifier = NULL;
1677 if (CheckContextualKeyword(CStrVector("from"))) {
1678 indirect_export_module_specifier = ParseModuleSpecifier(CHECK_OK);
1679 } else if (reserved_loc.IsValid()) {
1680 // No FromClause, so reserved words are invalid in ExportClause.
1682 ReportMessageAt(reserved_loc, "unexpected_reserved");
1685 ExpectSemicolon(CHECK_OK);
1686 const int length = export_names.length();
1687 DCHECK_EQ(length, local_names.length());
1688 DCHECK_EQ(length, export_locations.length());
1689 if (indirect_export_module_specifier == NULL) {
1690 for (int i = 0; i < length; ++i) {
1691 scope_->module()->AddLocalExport(export_names[i], local_names[i],
1694 ParserTraits::ReportMessageAt(export_locations[i],
1695 "duplicate_export", export_names[i]);
1700 for (int i = 0; i < length; ++i) {
1701 // TODO(ES6): scope_->module()->AddIndirectExport(...);(
1704 return factory()->NewEmptyStatement(pos);
1707 case Token::FUNCTION:
1708 result = ParseFunctionDeclaration(&names, CHECK_OK);
1712 result = ParseClassDeclaration(&names, CHECK_OK);
1718 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK);
1723 ReportUnexpectedToken(scanner()->current_token());
1727 // Extract declared names into export declarations.
1728 ModuleDescriptor* descriptor = scope_->module();
1729 for (int i = 0; i < names.length(); ++i) {
1730 descriptor->AddLocalExport(names[i], names[i], zone(), ok);
1732 // TODO(adamk): Possibly report this error at the right place.
1733 ParserTraits::ReportMessage("duplicate_export", names[i]);
1738 DCHECK_NOT_NULL(result);
1743 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels,
1749 if (peek() == Token::SEMICOLON) {
1751 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1753 return ParseSubStatement(labels, ok);
1757 Statement* Parser::ParseSubStatement(ZoneList<const AstRawString*>* labels,
1761 // VariableStatement
1763 // ExpressionStatement
1765 // IterationStatement
1766 // ContinueStatement
1770 // LabelledStatement
1774 // DebuggerStatement
1776 // Note: Since labels can only be used by 'break' and 'continue'
1777 // statements, which themselves are only valid within blocks,
1778 // iterations or 'switch' statements (i.e., BreakableStatements),
1779 // labels can be simply ignored in all other cases; except for
1780 // trivial labeled break statements 'label: break label' which is
1781 // parsed into an empty statement.
1784 return ParseBlock(labels, ok);
1786 case Token::SEMICOLON:
1787 if (is_strong(language_mode())) {
1788 ReportMessageAt(scanner()->peek_location(), "strong_empty");
1793 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1796 return ParseIfStatement(labels, ok);
1799 return ParseDoWhileStatement(labels, ok);
1802 return ParseWhileStatement(labels, ok);
1805 return ParseForStatement(labels, ok);
1807 case Token::CONTINUE:
1808 return ParseContinueStatement(ok);
1811 return ParseBreakStatement(labels, ok);
1814 return ParseReturnStatement(ok);
1817 return ParseWithStatement(labels, ok);
1820 return ParseSwitchStatement(labels, ok);
1823 return ParseThrowStatement(ok);
1826 // NOTE: It is somewhat complicated to have labels on
1827 // try-statements. When breaking out of a try-finally statement,
1828 // one must take great care not to treat it as a
1829 // fall-through. It is much easier just to wrap the entire
1830 // try-statement in a statement block and put the labels there
1832 factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition);
1833 Target target(&this->target_stack_, result);
1834 TryStatement* statement = ParseTryStatement(CHECK_OK);
1835 if (result) result->AddStatement(statement, zone());
1839 case Token::FUNCTION: {
1840 // FunctionDeclaration is only allowed in the context of SourceElements
1841 // (Ecma 262 5th Edition, clause 14):
1844 // FunctionDeclaration
1845 // Common language extension is to allow function declaration in place
1846 // of any statement. This language extension is disabled in strict mode.
1848 // In Harmony mode, this case also handles the extension:
1850 // GeneratorDeclaration
1851 if (is_strict(language_mode())) {
1852 ReportMessageAt(scanner()->peek_location(), "strict_function");
1856 return ParseFunctionDeclaration(NULL, ok);
1859 case Token::DEBUGGER:
1860 return ParseDebuggerStatement(ok);
1863 return ParseVariableStatement(kStatement, NULL, ok);
1866 // In ES6 CONST is not allowed as a Statement, only as a
1867 // LexicalDeclaration, however we continue to allow it in sloppy mode for
1868 // backwards compatibility.
1869 if (is_sloppy(language_mode())) {
1870 return ParseVariableStatement(kStatement, NULL, ok);
1875 return ParseExpressionOrLabelledStatement(labels, ok);
1880 VariableProxy* Parser::NewUnresolved(const AstRawString* name,
1881 VariableMode mode) {
1882 // If we are inside a function, a declaration of a var/const variable is a
1883 // truly local variable, and the scope of the variable is always the function
1885 // Let/const variables in harmony mode are always added to the immediately
1887 return DeclarationScope(mode)->NewUnresolved(factory(), name,
1888 scanner()->location().beg_pos,
1889 scanner()->location().end_pos);
1893 Variable* Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
1894 VariableProxy* proxy = declaration->proxy();
1895 DCHECK(proxy->raw_name() != NULL);
1896 const AstRawString* name = proxy->raw_name();
1897 VariableMode mode = declaration->mode();
1898 Scope* declaration_scope = DeclarationScope(mode);
1899 Variable* var = NULL;
1901 // If a suitable scope exists, then we can statically declare this
1902 // variable and also set its mode. In any case, a Declaration node
1903 // will be added to the scope so that the declaration can be added
1904 // to the corresponding activation frame at runtime if necessary.
1905 // For instance declarations inside an eval scope need to be added
1906 // to the calling function context.
1907 // Similarly, strict mode eval scope does not leak variable declarations to
1908 // the caller's scope so we declare all locals, too.
1909 if (declaration_scope->is_function_scope() ||
1910 declaration_scope->is_strict_eval_scope() ||
1911 declaration_scope->is_block_scope() ||
1912 declaration_scope->is_module_scope() ||
1913 declaration_scope->is_script_scope()) {
1914 // Declare the variable in the declaration scope.
1915 var = declaration_scope->LookupLocal(name);
1917 // Declare the name.
1918 var = declaration_scope->DeclareLocal(
1919 name, mode, declaration->initialization(),
1920 declaration->IsFunctionDeclaration() ? Variable::FUNCTION
1923 } else if (IsLexicalVariableMode(mode) ||
1924 IsLexicalVariableMode(var->mode()) ||
1925 ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) &&
1926 !declaration_scope->is_script_scope())) {
1927 // The name was declared in this scope before; check for conflicting
1928 // re-declarations. We have a conflict if either of the declarations is
1929 // not a var (in script scope, we also have to ignore legacy const for
1930 // compatibility). There is similar code in runtime.cc in the Declare
1931 // functions. The function CheckConflictingVarDeclarations checks for
1932 // var and let bindings from different scopes whereas this is a check for
1933 // conflicting declarations within the same scope. This check also covers
1936 // function () { let x; { var x; } }
1938 // because the var declaration is hoisted to the function scope where 'x'
1939 // is already bound.
1940 DCHECK(IsDeclaredVariableMode(var->mode()));
1941 if (is_strict(language_mode())) {
1942 // In harmony we treat re-declarations as early errors. See
1943 // ES5 16 for a definition of early errors.
1944 ParserTraits::ReportMessage("var_redeclaration", name);
1948 Expression* expression = NewThrowTypeError(
1949 "var_redeclaration", name, declaration->position());
1950 declaration_scope->SetIllegalRedeclaration(expression);
1951 } else if (mode == VAR) {
1952 var->set_maybe_assigned();
1956 // We add a declaration node for every declaration. The compiler
1957 // will only generate code if necessary. In particular, declarations
1958 // for inner local variables that do not represent functions won't
1959 // result in any generated code.
1961 // Note that we always add an unresolved proxy even if it's not
1962 // used, simply because we don't know in this method (w/o extra
1963 // parameters) if the proxy is needed or not. The proxy will be
1964 // bound during variable resolution time unless it was pre-bound
1967 // WARNING: This will lead to multiple declaration nodes for the
1968 // same variable if it is declared several times. This is not a
1969 // semantic issue as long as we keep the source order, but it may be
1970 // a performance issue since it may lead to repeated
1971 // RuntimeHidden_DeclareLookupSlot calls.
1972 declaration_scope->AddDeclaration(declaration);
1974 if (mode == CONST_LEGACY && declaration_scope->is_script_scope()) {
1975 // For global const variables we bind the proxy to a variable.
1976 DCHECK(resolve); // should be set by all callers
1977 Variable::Kind kind = Variable::NORMAL;
1978 var = new (zone()) Variable(declaration_scope, name, mode, kind,
1979 kNeedsInitialization, kNotAssigned);
1980 } else if (declaration_scope->is_eval_scope() &&
1981 is_sloppy(declaration_scope->language_mode())) {
1982 // For variable declarations in a sloppy eval scope the proxy is bound
1983 // to a lookup variable to force a dynamic declaration using the
1984 // DeclareLookupSlot runtime function.
1985 Variable::Kind kind = Variable::NORMAL;
1986 // TODO(sigurds) figure out if kNotAssigned is OK here
1987 var = new (zone()) Variable(declaration_scope, name, mode, kind,
1988 declaration->initialization(), kNotAssigned);
1989 var->AllocateTo(Variable::LOOKUP, -1);
1993 // If requested and we have a local variable, bind the proxy to the variable
1994 // at parse-time. This is used for functions (and consts) declared inside
1995 // statements: the corresponding function (or const) variable must be in the
1996 // function scope and not a statement-local scope, e.g. as provided with a
1997 // 'with' statement:
2003 // which is translated into:
2006 // // in this case this is not: 'var f; f = function () {};'
2007 // var f = function () {};
2010 // Note that if 'f' is accessed from inside the 'with' statement, it
2011 // will be allocated in the context (because we must be able to look
2012 // it up dynamically) but it will also be accessed statically, i.e.,
2013 // with a context slot index and a context chain length for this
2014 // initialization code. Thus, inside the 'with' statement, we need
2015 // both access to the static and the dynamic context chain; the
2016 // runtime needs to provide both.
2017 if (resolve && var != NULL) {
2024 // Language extension which is only enabled for source files loaded
2025 // through the API's extension mechanism. A native function
2026 // declaration is resolved by looking up the function through a
2027 // callback provided by the extension.
2028 Statement* Parser::ParseNativeDeclaration(bool* ok) {
2029 int pos = peek_position();
2030 Expect(Token::FUNCTION, CHECK_OK);
2031 // Allow "eval" or "arguments" for backward compatibility.
2032 const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
2033 Expect(Token::LPAREN, CHECK_OK);
2034 bool done = (peek() == Token::RPAREN);
2036 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
2037 done = (peek() == Token::RPAREN);
2039 Expect(Token::COMMA, CHECK_OK);
2042 Expect(Token::RPAREN, CHECK_OK);
2043 Expect(Token::SEMICOLON, CHECK_OK);
2045 // Make sure that the function containing the native declaration
2046 // isn't lazily compiled. The extension structures are only
2047 // accessible while parsing the first time not when reparsing
2048 // because of lazy compilation.
2049 DeclarationScope(VAR)->ForceEagerCompilation();
2051 // TODO(1240846): It's weird that native function declarations are
2052 // introduced dynamically when we meet their declarations, whereas
2053 // other functions are set up when entering the surrounding scope.
2054 VariableProxy* proxy = NewUnresolved(name, VAR);
2055 Declaration* declaration =
2056 factory()->NewVariableDeclaration(proxy, VAR, scope_, pos);
2057 Declare(declaration, true, CHECK_OK);
2058 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral(
2059 name, extension_, RelocInfo::kNoPosition);
2060 return factory()->NewExpressionStatement(
2061 factory()->NewAssignment(
2062 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition),
2067 Statement* Parser::ParseFunctionDeclaration(
2068 ZoneList<const AstRawString*>* names, bool* ok) {
2069 // FunctionDeclaration ::
2070 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
2071 // GeneratorDeclaration ::
2072 // 'function' '*' Identifier '(' FormalParameterListopt ')'
2073 // '{' FunctionBody '}'
2074 Expect(Token::FUNCTION, CHECK_OK);
2075 int pos = position();
2076 bool is_generator = Check(Token::MUL);
2077 bool is_strict_reserved = false;
2078 const AstRawString* name = ParseIdentifierOrStrictReservedWord(
2079 &is_strict_reserved, CHECK_OK);
2080 FunctionLiteral* fun =
2081 ParseFunctionLiteral(name, scanner()->location(), is_strict_reserved,
2082 is_generator ? FunctionKind::kGeneratorFunction
2083 : FunctionKind::kNormalFunction,
2084 pos, FunctionLiteral::DECLARATION,
2085 FunctionLiteral::NORMAL_ARITY, CHECK_OK);
2086 // Even if we're not at the top-level of the global or a function
2087 // scope, we treat it as such and introduce the function with its
2088 // initial value upon entering the corresponding scope.
2089 // In ES6, a function behaves as a lexical binding, except in
2090 // a script scope, or the initial scope of eval or another function.
2092 is_strong(language_mode())
2094 : is_strict(language_mode()) &&
2095 !(scope_->is_script_scope() || scope_->is_eval_scope() ||
2096 scope_->is_function_scope())
2099 VariableProxy* proxy = NewUnresolved(name, mode);
2100 Declaration* declaration =
2101 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
2102 Declare(declaration, true, CHECK_OK);
2103 if (names) names->Add(name, zone());
2104 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2108 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
2110 // ClassDeclaration ::
2111 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
2113 // A ClassDeclaration
2117 // has the same semantics as:
2119 // let C = class C { ... };
2121 // so rewrite it as such.
2123 Expect(Token::CLASS, CHECK_OK);
2124 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
2125 ReportMessage("sloppy_lexical");
2130 int pos = position();
2131 bool is_strict_reserved = false;
2132 const AstRawString* name =
2133 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
2134 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(),
2135 is_strict_reserved, pos, CHECK_OK);
2137 VariableMode mode = is_strong(language_mode()) ? CONST : LET;
2138 VariableProxy* proxy = NewUnresolved(name, mode);
2139 Declaration* declaration =
2140 factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
2141 Declare(declaration, true, CHECK_OK);
2142 proxy->var()->set_initializer_position(position());
2144 Token::Value init_op =
2145 is_strong(language_mode()) ? Token::INIT_CONST : Token::INIT_LET;
2146 Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos);
2147 Statement* assignment_statement =
2148 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
2149 if (names) names->Add(name, zone());
2150 return assignment_statement;
2154 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) {
2155 if (is_strict(language_mode())) {
2156 return ParseScopedBlock(labels, ok);
2160 // '{' Statement* '}'
2162 // Note that a Block does not introduce a new execution scope!
2163 // (ECMA-262, 3rd, 12.2)
2165 // Construct block expecting 16 statements.
2167 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2168 Target target(&this->target_stack_, result);
2169 Expect(Token::LBRACE, CHECK_OK);
2170 while (peek() != Token::RBRACE) {
2171 Statement* stat = ParseStatement(NULL, CHECK_OK);
2172 if (stat && !stat->IsEmpty()) {
2173 result->AddStatement(stat, zone());
2176 Expect(Token::RBRACE, CHECK_OK);
2181 Block* Parser::ParseScopedBlock(ZoneList<const AstRawString*>* labels,
2183 // The harmony mode uses block elements instead of statements.
2186 // '{' StatementList '}'
2188 // Construct block expecting 16 statements.
2190 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2191 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
2193 // Parse the statements and collect escaping labels.
2194 Expect(Token::LBRACE, CHECK_OK);
2195 block_scope->set_start_position(scanner()->location().beg_pos);
2196 { BlockState block_state(&scope_, block_scope);
2197 Target target(&this->target_stack_, body);
2199 while (peek() != Token::RBRACE) {
2200 Statement* stat = ParseStatementListItem(CHECK_OK);
2201 if (stat && !stat->IsEmpty()) {
2202 body->AddStatement(stat, zone());
2206 Expect(Token::RBRACE, CHECK_OK);
2207 block_scope->set_end_position(scanner()->location().end_pos);
2208 block_scope = block_scope->FinalizeBlockScope();
2209 body->set_scope(block_scope);
2214 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
2215 ZoneList<const AstRawString*>* names,
2217 // VariableStatement ::
2218 // VariableDeclarations ';'
2220 const AstRawString* ignore;
2222 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK);
2223 ExpectSemicolon(CHECK_OK);
2228 // If the variable declaration declares exactly one non-const
2229 // variable, then *out is set to that variable. In all other cases,
2230 // *out is untouched; in particular, it is the caller's responsibility
2231 // to initialize it properly. This mechanism is used for the parsing
2232 // of 'for-in' loops.
2233 Block* Parser::ParseVariableDeclarations(
2234 VariableDeclarationContext var_context,
2235 VariableDeclarationProperties* decl_props,
2236 ZoneList<const AstRawString*>* names,
2237 const AstRawString** out,
2239 // VariableDeclarations ::
2240 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
2242 // The ES6 Draft Rev3 specifies the following grammar for const declarations
2244 // ConstDeclaration ::
2245 // const ConstBinding (',' ConstBinding)* ';'
2247 // Identifier '=' AssignmentExpression
2251 // BindingPattern '=' AssignmentExpression
2253 int pos = peek_position();
2254 VariableMode mode = VAR;
2255 // True if the binding needs initialization. 'let' and 'const' declared
2256 // bindings are created uninitialized by their declaration nodes and
2257 // need initialization. 'var' declared bindings are always initialized
2258 // immediately by their declaration nodes.
2259 bool needs_init = false;
2260 bool is_const = false;
2261 Token::Value init_op = Token::INIT_VAR;
2262 if (peek() == Token::VAR) {
2263 if (is_strong(language_mode())) {
2264 Scanner::Location location = scanner()->peek_location();
2265 ReportMessageAt(location, "strong_var");
2269 Consume(Token::VAR);
2270 } else if (peek() == Token::CONST) {
2271 Consume(Token::CONST);
2272 if (is_sloppy(language_mode())) {
2273 mode = CONST_LEGACY;
2274 init_op = Token::INIT_CONST_LEGACY;
2276 DCHECK(var_context != kStatement);
2278 init_op = Token::INIT_CONST;
2282 } else if (peek() == Token::LET && is_strict(language_mode())) {
2283 Consume(Token::LET);
2284 DCHECK(var_context != kStatement);
2287 init_op = Token::INIT_LET;
2289 UNREACHABLE(); // by current callers
2292 Scope* declaration_scope = DeclarationScope(mode);
2294 // The scope of a var/const declared variable anywhere inside a function
2295 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
2296 // transform a source-level var/const declaration into a (Function)
2297 // Scope declaration, and rewrite the source-level initialization into an
2298 // assignment statement. We use a block to collect multiple assignments.
2300 // We mark the block as initializer block because we don't want the
2301 // rewriter to add a '.result' assignment to such a block (to get compliant
2302 // behavior for code such as print(eval('var x = 7')), and for cosmetic
2303 // reasons when pretty-printing. Also, unless an assignment (initialization)
2304 // is inside an initializer block, it is ignored.
2306 // Create new block with one expected declaration.
2307 Block* block = factory()->NewBlock(NULL, 1, true, pos);
2308 int nvars = 0; // the number of variables declared
2309 const AstRawString* name = NULL;
2310 bool is_for_iteration_variable;
2312 if (fni_ != NULL) fni_->Enter();
2314 // Parse variable name.
2315 if (nvars > 0) Consume(Token::COMMA);
2316 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
2317 if (fni_ != NULL) fni_->PushVariableName(name);
2319 // Declare variable.
2320 // Note that we *always* must treat the initial value via a separate init
2321 // assignment for variables and constants because the value must be assigned
2322 // when the variable is encountered in the source. But the variable/constant
2323 // is declared (and set to 'undefined') upon entering the function within
2324 // which the variable or constant is declared. Only function variables have
2325 // an initial value in the declaration (because they are initialized upon
2326 // entering the function).
2328 // If we have a const declaration, in an inner scope, the proxy is always
2329 // bound to the declared variable (independent of possibly surrounding with
2331 // For let/const declarations in harmony mode, we can also immediately
2332 // pre-resolve the proxy because it resides in the same scope as the
2334 is_for_iteration_variable =
2335 var_context == kForStatement &&
2336 (peek() == Token::IN || PeekContextualKeyword(CStrVector("of")));
2337 if (is_for_iteration_variable && mode == CONST) {
2341 VariableProxy* proxy = NewUnresolved(name, mode);
2342 Declaration* declaration =
2343 factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
2344 Variable* var = Declare(declaration, mode != VAR, CHECK_OK);
2345 DCHECK_NOT_NULL(var);
2346 DCHECK(!proxy->is_resolved() || proxy->var() == var);
2348 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
2349 ReportMessage("too_many_variables");
2353 if (names) names->Add(name, zone());
2355 // Parse initialization expression if present and/or needed. A
2356 // declaration of the form:
2360 // is syntactic sugar for:
2364 // In particular, we need to re-lookup 'v' (in scope_, not
2365 // declaration_scope) as it may be a different 'v' than the 'v' in the
2366 // declaration (e.g., if we are inside a 'with' statement or 'catch'
2369 // However, note that const declarations are different! A const
2370 // declaration of the form:
2374 // is *not* syntactic sugar for:
2378 // The "variable" c initialized to x is the same as the declared
2379 // one - there is no re-lookup (see the last parameter of the
2380 // Declare() call above).
2382 Scope* initialization_scope = is_const ? declaration_scope : scope_;
2383 Expression* value = NULL;
2385 // Harmony consts have non-optional initializers.
2386 if (peek() == Token::ASSIGN ||
2387 (mode == CONST && !is_for_iteration_variable)) {
2388 Expect(Token::ASSIGN, CHECK_OK);
2390 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
2391 // Don't infer if it is "a = function(){...}();"-like expression.
2393 value->AsCall() == NULL &&
2394 value->AsCallNew() == NULL) {
2397 fni_->RemoveLastFunction();
2399 if (decl_props != NULL) *decl_props = kHasInitializers;
2400 // End position of the initializer is after the assignment expression.
2401 var->set_initializer_position(scanner()->location().end_pos);
2403 // End position of the initializer is after the variable.
2404 var->set_initializer_position(position());
2407 // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
2408 if (value == NULL && needs_init) {
2409 value = GetLiteralUndefined(position());
2412 // Global variable declarations must be compiled in a specific
2413 // way. When the script containing the global variable declaration
2414 // is entered, the global variable must be declared, so that if it
2415 // doesn't exist (on the global object itself, see ES5 errata) it
2416 // gets created with an initial undefined value. This is handled
2417 // by the declarations part of the function representing the
2418 // top-level global code; see Runtime::DeclareGlobalVariable. If
2419 // it already exists (in the object or in a prototype), it is
2420 // *not* touched until the variable declaration statement is
2423 // Executing the variable declaration statement will always
2424 // guarantee to give the global object an own property.
2425 // This way, global variable declarations can shadow
2426 // properties in the prototype chain, but only after the variable
2427 // declaration statement has been executed. This is important in
2428 // browsers where the global object (window) has lots of
2429 // properties defined in prototype objects.
2430 if (initialization_scope->is_script_scope() &&
2431 !IsLexicalVariableMode(mode)) {
2432 // Compute the arguments for the runtime call.
2433 ZoneList<Expression*>* arguments =
2434 new(zone()) ZoneList<Expression*>(3, zone());
2435 // We have at least 1 parameter.
2436 arguments->Add(factory()->NewStringLiteral(name, pos), zone());
2437 CallRuntime* initialize;
2440 arguments->Add(value, zone());
2441 value = NULL; // zap the value to avoid the unnecessary assignment
2443 // Construct the call to Runtime_InitializeConstGlobal
2444 // and add it to the initialization statement block.
2445 // Note that the function does different things depending on
2446 // the number of arguments (1 or 2).
2447 initialize = factory()->NewCallRuntime(
2448 ast_value_factory()->initialize_const_global_string(),
2449 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), arguments,
2452 // Add language mode.
2453 // We may want to pass singleton to avoid Literal allocations.
2454 LanguageMode language_mode = initialization_scope->language_mode();
2455 arguments->Add(factory()->NewNumberLiteral(language_mode, pos), zone());
2457 // Be careful not to assign a value to the global variable if
2458 // we're in a with. The initialization value should not
2459 // necessarily be stored in the global object in that case,
2460 // which is why we need to generate a separate assignment node.
2461 if (value != NULL && !inside_with()) {
2462 arguments->Add(value, zone());
2463 value = NULL; // zap the value to avoid the unnecessary assignment
2464 // Construct the call to Runtime_InitializeVarGlobal
2465 // and add it to the initialization statement block.
2466 initialize = factory()->NewCallRuntime(
2467 ast_value_factory()->initialize_var_global_string(),
2468 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), arguments,
2475 if (initialize != NULL) {
2476 block->AddStatement(factory()->NewExpressionStatement(
2477 initialize, RelocInfo::kNoPosition),
2480 } else if (needs_init) {
2481 // Constant initializations always assign to the declared constant which
2482 // is always at the function scope level. This is only relevant for
2483 // dynamically looked-up variables and constants (the start context for
2484 // constant lookups is always the function context, while it is the top
2485 // context for var declared variables). Sigh...
2486 // For 'let' and 'const' declared variables in harmony mode the
2487 // initialization also always assigns to the declared variable.
2488 DCHECK(proxy != NULL);
2489 DCHECK(proxy->var() != NULL);
2490 DCHECK(value != NULL);
2491 Assignment* assignment =
2492 factory()->NewAssignment(init_op, proxy, value, pos);
2493 block->AddStatement(
2494 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
2499 // Add an assignment node to the initialization statement block if we still
2500 // have a pending initialization value.
2501 if (value != NULL) {
2502 DCHECK(mode == VAR);
2503 // 'var' initializations are simply assignments (with all the consequences
2504 // if they are inside a 'with' statement - they may change a 'with' object
2506 VariableProxy* proxy =
2507 initialization_scope->NewUnresolved(factory(), name);
2508 Assignment* assignment =
2509 factory()->NewAssignment(init_op, proxy, value, pos);
2510 block->AddStatement(
2511 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
2515 if (fni_ != NULL) fni_->Leave();
2516 } while (peek() == Token::COMMA);
2518 // If there was a single non-const declaration, return it in the output
2519 // parameter for possible use by for/in.
2520 if (nvars == 1 && (!is_const || is_for_iteration_variable)) {
2528 static bool ContainsLabel(ZoneList<const AstRawString*>* labels,
2529 const AstRawString* label) {
2530 DCHECK(label != NULL);
2531 if (labels != NULL) {
2532 for (int i = labels->length(); i-- > 0; ) {
2533 if (labels->at(i) == label) {
2542 Statement* Parser::ParseExpressionOrLabelledStatement(
2543 ZoneList<const AstRawString*>* labels, bool* ok) {
2544 // ExpressionStatement | LabelledStatement ::
2546 // Identifier ':' Statement
2548 // ExpressionStatement[Yield] :
2549 // [lookahead ∉ {{, function, class, let [}] Expression[In, ?Yield] ;
2552 case Token::FUNCTION:
2554 UNREACHABLE(); // Always handled by the callers.
2556 ReportUnexpectedToken(Next());
2560 // TODO(arv): Handle `let [`
2561 // https://code.google.com/p/v8/issues/detail?id=3847
2567 int pos = peek_position();
2568 bool starts_with_idenfifier = peek_any_identifier();
2569 Expression* expr = ParseExpression(true, CHECK_OK);
2570 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
2571 expr->AsVariableProxy() != NULL &&
2572 !expr->AsVariableProxy()->is_this()) {
2573 // Expression is a single identifier, and not, e.g., a parenthesized
2575 VariableProxy* var = expr->AsVariableProxy();
2576 const AstRawString* label = var->raw_name();
2577 // TODO(1240780): We don't check for redeclaration of labels
2578 // during preparsing since keeping track of the set of active
2579 // labels requires nontrivial changes to the way scopes are
2580 // structured. However, these are probably changes we want to
2581 // make later anyway so we should go back and fix this then.
2582 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
2583 ParserTraits::ReportMessage("label_redeclaration", label);
2587 if (labels == NULL) {
2588 labels = new(zone()) ZoneList<const AstRawString*>(4, zone());
2590 labels->Add(label, zone());
2591 // Remove the "ghost" variable that turned out to be a label
2592 // from the top scope. This way, we don't try to resolve it
2593 // during the scope processing.
2594 scope_->RemoveUnresolved(var);
2595 Expect(Token::COLON, CHECK_OK);
2596 return ParseStatement(labels, ok);
2599 // If we have an extension, we allow a native function declaration.
2600 // A native function declaration starts with "native function" with
2601 // no line-terminator between the two words.
2602 if (extension_ != NULL && peek() == Token::FUNCTION &&
2603 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL &&
2604 expr->AsVariableProxy() != NULL &&
2605 expr->AsVariableProxy()->raw_name() ==
2606 ast_value_factory()->native_string() &&
2607 !scanner()->literal_contains_escapes()) {
2608 return ParseNativeDeclaration(ok);
2611 // Parsed expression statement, followed by semicolon.
2612 // Detect attempts at 'let' declarations in sloppy mode.
2613 if (peek() == Token::IDENTIFIER && expr->AsVariableProxy() != NULL &&
2614 expr->AsVariableProxy()->raw_name() ==
2615 ast_value_factory()->let_string()) {
2616 ReportMessage("sloppy_lexical", NULL);
2620 ExpectSemicolon(CHECK_OK);
2621 return factory()->NewExpressionStatement(expr, pos);
2625 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels,
2628 // 'if' '(' Expression ')' Statement ('else' Statement)?
2630 int pos = peek_position();
2631 Expect(Token::IF, CHECK_OK);
2632 Expect(Token::LPAREN, CHECK_OK);
2633 Expression* condition = ParseExpression(true, CHECK_OK);
2634 Expect(Token::RPAREN, CHECK_OK);
2635 Statement* then_statement = ParseSubStatement(labels, CHECK_OK);
2636 Statement* else_statement = NULL;
2637 if (peek() == Token::ELSE) {
2639 else_statement = ParseSubStatement(labels, CHECK_OK);
2641 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2643 return factory()->NewIfStatement(
2644 condition, then_statement, else_statement, pos);
2648 Statement* Parser::ParseContinueStatement(bool* ok) {
2649 // ContinueStatement ::
2650 // 'continue' Identifier? ';'
2652 int pos = peek_position();
2653 Expect(Token::CONTINUE, CHECK_OK);
2654 const AstRawString* label = NULL;
2655 Token::Value tok = peek();
2656 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2657 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2658 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2659 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
2661 IterationStatement* target = LookupContinueTarget(label, CHECK_OK);
2662 if (target == NULL) {
2663 // Illegal continue statement.
2664 const char* message = "illegal_continue";
2665 if (label != NULL) {
2666 message = "unknown_label";
2668 ParserTraits::ReportMessage(message, label);
2672 ExpectSemicolon(CHECK_OK);
2673 return factory()->NewContinueStatement(target, pos);
2677 Statement* Parser::ParseBreakStatement(ZoneList<const AstRawString*>* labels,
2679 // BreakStatement ::
2680 // 'break' Identifier? ';'
2682 int pos = peek_position();
2683 Expect(Token::BREAK, CHECK_OK);
2684 const AstRawString* label = NULL;
2685 Token::Value tok = peek();
2686 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2687 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2688 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2689 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
2691 // Parse labeled break statements that target themselves into
2692 // empty statements, e.g. 'l1: l2: l3: break l2;'
2693 if (label != NULL && ContainsLabel(labels, label)) {
2694 ExpectSemicolon(CHECK_OK);
2695 return factory()->NewEmptyStatement(pos);
2697 BreakableStatement* target = NULL;
2698 target = LookupBreakTarget(label, CHECK_OK);
2699 if (target == NULL) {
2700 // Illegal break statement.
2701 const char* message = "illegal_break";
2702 if (label != NULL) {
2703 message = "unknown_label";
2705 ParserTraits::ReportMessage(message, label);
2709 ExpectSemicolon(CHECK_OK);
2710 return factory()->NewBreakStatement(target, pos);
2714 Statement* Parser::ParseReturnStatement(bool* ok) {
2715 // ReturnStatement ::
2716 // 'return' Expression? ';'
2718 // Consume the return token. It is necessary to do that before
2719 // reporting any errors on it, because of the way errors are
2720 // reported (underlining).
2721 Expect(Token::RETURN, CHECK_OK);
2722 Scanner::Location loc = scanner()->location();
2723 function_state_->set_return_location(loc);
2725 Token::Value tok = peek();
2727 Expression* return_value;
2728 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
2729 tok == Token::SEMICOLON ||
2730 tok == Token::RBRACE ||
2731 tok == Token::EOS) {
2732 if (IsSubclassConstructor(function_state_->kind())) {
2733 return_value = ThisExpression(scope_, factory(), loc.beg_pos);
2735 return_value = GetLiteralUndefined(position());
2738 if (is_strong(language_mode()) &&
2739 i::IsConstructor(function_state_->kind())) {
2740 int pos = peek_position();
2741 ReportMessageAt(Scanner::Location(pos, pos + 1),
2742 "strong_constructor_return_value");
2746 return_value = ParseExpression(true, CHECK_OK);
2748 ExpectSemicolon(CHECK_OK);
2750 if (is_generator()) {
2751 Expression* generator = factory()->NewVariableProxy(
2752 function_state_->generator_object_variable());
2753 Expression* yield = factory()->NewYield(
2754 generator, return_value, Yield::kFinal, loc.beg_pos);
2755 result = factory()->NewExpressionStatement(yield, loc.beg_pos);
2757 result = factory()->NewReturnStatement(return_value, loc.beg_pos);
2760 Scope* decl_scope = scope_->DeclarationScope();
2761 if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) {
2762 ReportMessageAt(loc, "illegal_return");
2770 Statement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels,
2773 // 'with' '(' Expression ')' Statement
2775 Expect(Token::WITH, CHECK_OK);
2776 int pos = position();
2778 if (is_strict(language_mode())) {
2779 ReportMessage("strict_mode_with");
2784 Expect(Token::LPAREN, CHECK_OK);
2785 Expression* expr = ParseExpression(true, CHECK_OK);
2786 Expect(Token::RPAREN, CHECK_OK);
2788 scope_->DeclarationScope()->RecordWithStatement();
2789 Scope* with_scope = NewScope(scope_, WITH_SCOPE);
2791 { BlockState block_state(&scope_, with_scope);
2792 with_scope->set_start_position(scanner()->peek_location().beg_pos);
2793 stmt = ParseSubStatement(labels, CHECK_OK);
2794 with_scope->set_end_position(scanner()->location().end_pos);
2796 return factory()->NewWithStatement(with_scope, expr, stmt, pos);
2800 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
2802 // 'case' Expression ':' StatementList
2803 // 'default' ':' StatementList
2805 Expression* label = NULL; // NULL expression indicates default case
2806 if (peek() == Token::CASE) {
2807 Expect(Token::CASE, CHECK_OK);
2808 label = ParseExpression(true, CHECK_OK);
2810 Expect(Token::DEFAULT, CHECK_OK);
2811 if (*default_seen_ptr) {
2812 ReportMessage("multiple_defaults_in_switch");
2816 *default_seen_ptr = true;
2818 Expect(Token::COLON, CHECK_OK);
2819 int pos = position();
2820 ZoneList<Statement*>* statements =
2821 new(zone()) ZoneList<Statement*>(5, zone());
2822 while (peek() != Token::CASE &&
2823 peek() != Token::DEFAULT &&
2824 peek() != Token::RBRACE) {
2825 Statement* stat = ParseStatementListItem(CHECK_OK);
2826 statements->Add(stat, zone());
2829 return factory()->NewCaseClause(label, statements, pos);
2833 SwitchStatement* Parser::ParseSwitchStatement(
2834 ZoneList<const AstRawString*>* labels, bool* ok) {
2835 // SwitchStatement ::
2836 // 'switch' '(' Expression ')' '{' CaseClause* '}'
2838 SwitchStatement* statement =
2839 factory()->NewSwitchStatement(labels, peek_position());
2840 Target target(&this->target_stack_, statement);
2842 Expect(Token::SWITCH, CHECK_OK);
2843 Expect(Token::LPAREN, CHECK_OK);
2844 Expression* tag = ParseExpression(true, CHECK_OK);
2845 Expect(Token::RPAREN, CHECK_OK);
2847 bool default_seen = false;
2848 ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4, zone());
2849 Expect(Token::LBRACE, CHECK_OK);
2850 while (peek() != Token::RBRACE) {
2851 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
2852 cases->Add(clause, zone());
2854 Expect(Token::RBRACE, CHECK_OK);
2856 if (statement) statement->Initialize(tag, cases);
2861 Statement* Parser::ParseThrowStatement(bool* ok) {
2862 // ThrowStatement ::
2863 // 'throw' Expression ';'
2865 Expect(Token::THROW, CHECK_OK);
2866 int pos = position();
2867 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
2868 ReportMessage("newline_after_throw");
2872 Expression* exception = ParseExpression(true, CHECK_OK);
2873 ExpectSemicolon(CHECK_OK);
2875 return factory()->NewExpressionStatement(
2876 factory()->NewThrow(exception, pos), pos);
2880 TryStatement* Parser::ParseTryStatement(bool* ok) {
2882 // 'try' Block Catch
2883 // 'try' Block Finally
2884 // 'try' Block Catch Finally
2887 // 'catch' '(' Identifier ')' Block
2892 Expect(Token::TRY, CHECK_OK);
2893 int pos = position();
2895 Block* try_block = ParseBlock(NULL, CHECK_OK);
2897 Token::Value tok = peek();
2898 if (tok != Token::CATCH && tok != Token::FINALLY) {
2899 ReportMessage("no_catch_or_finally");
2904 Scope* catch_scope = NULL;
2905 Variable* catch_variable = NULL;
2906 Block* catch_block = NULL;
2907 const AstRawString* name = NULL;
2908 if (tok == Token::CATCH) {
2909 Consume(Token::CATCH);
2911 Expect(Token::LPAREN, CHECK_OK);
2912 catch_scope = NewScope(scope_, CATCH_SCOPE);
2913 catch_scope->set_start_position(scanner()->location().beg_pos);
2914 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
2916 Expect(Token::RPAREN, CHECK_OK);
2918 catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized,
2920 BlockState block_state(&scope_, catch_scope);
2921 catch_block = ParseBlock(NULL, CHECK_OK);
2923 catch_scope->set_end_position(scanner()->location().end_pos);
2927 Block* finally_block = NULL;
2928 DCHECK(tok == Token::FINALLY || catch_block != NULL);
2929 if (tok == Token::FINALLY) {
2930 Consume(Token::FINALLY);
2931 finally_block = ParseBlock(NULL, CHECK_OK);
2934 // Simplify the AST nodes by converting:
2935 // 'try B0 catch B1 finally B2'
2937 // 'try { try B0 catch B1 } finally B2'
2939 if (catch_block != NULL && finally_block != NULL) {
2940 // If we have both, create an inner try/catch.
2941 DCHECK(catch_scope != NULL && catch_variable != NULL);
2942 int index = function_state_->NextHandlerIndex();
2943 TryCatchStatement* statement = factory()->NewTryCatchStatement(
2944 index, try_block, catch_scope, catch_variable, catch_block,
2945 RelocInfo::kNoPosition);
2946 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
2947 try_block->AddStatement(statement, zone());
2948 catch_block = NULL; // Clear to indicate it's been handled.
2951 TryStatement* result = NULL;
2952 if (catch_block != NULL) {
2953 DCHECK(finally_block == NULL);
2954 DCHECK(catch_scope != NULL && catch_variable != NULL);
2955 int index = function_state_->NextHandlerIndex();
2956 result = factory()->NewTryCatchStatement(
2957 index, try_block, catch_scope, catch_variable, catch_block, pos);
2959 DCHECK(finally_block != NULL);
2960 int index = function_state_->NextHandlerIndex();
2961 result = factory()->NewTryFinallyStatement(
2962 index, try_block, finally_block, pos);
2969 DoWhileStatement* Parser::ParseDoWhileStatement(
2970 ZoneList<const AstRawString*>* labels, bool* ok) {
2972 // 'do' Statement 'while' '(' Expression ')' ';'
2974 DoWhileStatement* loop =
2975 factory()->NewDoWhileStatement(labels, peek_position());
2976 Target target(&this->target_stack_, loop);
2978 Expect(Token::DO, CHECK_OK);
2979 Statement* body = ParseSubStatement(NULL, CHECK_OK);
2980 Expect(Token::WHILE, CHECK_OK);
2981 Expect(Token::LPAREN, CHECK_OK);
2983 Expression* cond = ParseExpression(true, CHECK_OK);
2984 Expect(Token::RPAREN, CHECK_OK);
2986 // Allow do-statements to be terminated with and without
2987 // semi-colons. This allows code such as 'do;while(0)return' to
2988 // parse, which would not be the case if we had used the
2989 // ExpectSemicolon() functionality here.
2990 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
2992 if (loop != NULL) loop->Initialize(cond, body);
2997 WhileStatement* Parser::ParseWhileStatement(
2998 ZoneList<const AstRawString*>* labels, bool* ok) {
2999 // WhileStatement ::
3000 // 'while' '(' Expression ')' Statement
3002 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position());
3003 Target target(&this->target_stack_, loop);
3005 Expect(Token::WHILE, CHECK_OK);
3006 Expect(Token::LPAREN, CHECK_OK);
3007 Expression* cond = ParseExpression(true, CHECK_OK);
3008 Expect(Token::RPAREN, CHECK_OK);
3009 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3011 if (loop != NULL) loop->Initialize(cond, body);
3016 void Parser::InitializeForEachStatement(ForEachStatement* stmt,
3018 Expression* subject,
3020 ForOfStatement* for_of = stmt->AsForOfStatement();
3022 if (for_of != NULL) {
3023 Variable* iterator = scope_->DeclarationScope()->NewTemporary(
3024 ast_value_factory()->dot_iterator_string());
3025 Variable* result = scope_->DeclarationScope()->NewTemporary(
3026 ast_value_factory()->dot_result_string());
3028 Expression* assign_iterator;
3029 Expression* next_result;
3030 Expression* result_done;
3031 Expression* assign_each;
3033 // iterator = subject[Symbol.iterator]()
3034 assign_iterator = factory()->NewAssignment(
3035 Token::ASSIGN, factory()->NewVariableProxy(iterator),
3036 GetIterator(subject, factory()), subject->position());
3038 // !%_IsSpecObject(result = iterator.next()) &&
3039 // %ThrowIteratorResultNotAnObject(result)
3041 // result = iterator.next()
3042 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
3043 Expression* next_literal = factory()->NewStringLiteral(
3044 ast_value_factory()->next_string(), RelocInfo::kNoPosition);
3045 Expression* next_property = factory()->NewProperty(
3046 iterator_proxy, next_literal, RelocInfo::kNoPosition);
3047 ZoneList<Expression*>* next_arguments =
3048 new (zone()) ZoneList<Expression*>(0, zone());
3049 Expression* next_call = factory()->NewCall(next_property, next_arguments,
3050 subject->position());
3051 Expression* result_proxy = factory()->NewVariableProxy(result);
3052 next_result = factory()->NewAssignment(Token::ASSIGN, result_proxy,
3053 next_call, subject->position());
3055 // %_IsSpecObject(...)
3056 ZoneList<Expression*>* is_spec_object_args =
3057 new (zone()) ZoneList<Expression*>(1, zone());
3058 is_spec_object_args->Add(next_result, zone());
3059 Expression* is_spec_object_call = factory()->NewCallRuntime(
3060 ast_value_factory()->is_spec_object_string(),
3061 Runtime::FunctionForId(Runtime::kInlineIsSpecObject),
3062 is_spec_object_args, subject->position());
3064 // %ThrowIteratorResultNotAnObject(result)
3065 Expression* result_proxy_again = factory()->NewVariableProxy(result);
3066 ZoneList<Expression*>* throw_arguments =
3067 new (zone()) ZoneList<Expression*>(1, zone());
3068 throw_arguments->Add(result_proxy_again, zone());
3069 Expression* throw_call = factory()->NewCallRuntime(
3070 ast_value_factory()->throw_iterator_result_not_an_object_string(),
3071 Runtime::FunctionForId(Runtime::kThrowIteratorResultNotAnObject),
3072 throw_arguments, subject->position());
3074 next_result = factory()->NewBinaryOperation(
3075 Token::AND, factory()->NewUnaryOperation(
3076 Token::NOT, is_spec_object_call, subject->position()),
3077 throw_call, subject->position());
3082 Expression* done_literal = factory()->NewStringLiteral(
3083 ast_value_factory()->done_string(), RelocInfo::kNoPosition);
3084 Expression* result_proxy = factory()->NewVariableProxy(result);
3085 result_done = factory()->NewProperty(
3086 result_proxy, done_literal, RelocInfo::kNoPosition);
3089 // each = result.value
3091 Expression* value_literal = factory()->NewStringLiteral(
3092 ast_value_factory()->value_string(), RelocInfo::kNoPosition);
3093 Expression* result_proxy = factory()->NewVariableProxy(result);
3094 Expression* result_value = factory()->NewProperty(
3095 result_proxy, value_literal, RelocInfo::kNoPosition);
3096 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value,
3100 for_of->Initialize(each, subject, body,
3106 stmt->Initialize(each, subject, body);
3111 Statement* Parser::DesugarLexicalBindingsInForStatement(
3112 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names,
3113 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
3114 Statement* body, bool* ok) {
3115 // ES6 13.6.3.4 specifies that on each loop iteration the let variables are
3116 // copied into a new environment. After copying, the "next" statement of the
3117 // loop is executed to update the loop variables. The loop condition is
3118 // checked and the loop body is executed.
3120 // We rewrite a for statement of the form
3122 // labels: for (let/const x = i; cond; next) body
3130 // outer: for (;;) {
3131 // let/const x = temp_x;
3132 // if (first == 1) {
3138 // labels: for (; flag == 1; flag = 0, temp_x = x) {
3151 DCHECK(names->length() > 0);
3152 Scope* for_scope = scope_;
3153 ZoneList<Variable*> temps(names->length(), zone());
3155 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false,
3156 RelocInfo::kNoPosition);
3158 // Add statement: let/const x = i.
3159 outer_block->AddStatement(init, zone());
3161 const AstRawString* temp_name = ast_value_factory()->dot_for_string();
3163 // For each lexical variable x:
3164 // make statement: temp_x = x.
3165 for (int i = 0; i < names->length(); i++) {
3166 VariableProxy* proxy = NewUnresolved(names->at(i), LET);
3167 Variable* temp = scope_->DeclarationScope()->NewTemporary(temp_name);
3168 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
3169 Assignment* assignment = factory()->NewAssignment(
3170 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3171 Statement* assignment_statement = factory()->NewExpressionStatement(
3172 assignment, RelocInfo::kNoPosition);
3173 outer_block->AddStatement(assignment_statement, zone());
3174 temps.Add(temp, zone());
3177 Variable* first = NULL;
3178 // Make statement: first = 1.
3180 first = scope_->DeclarationScope()->NewTemporary(temp_name);
3181 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3182 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3183 Assignment* assignment = factory()->NewAssignment(
3184 Token::ASSIGN, first_proxy, const1, RelocInfo::kNoPosition);
3185 Statement* assignment_statement =
3186 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3187 outer_block->AddStatement(assignment_statement, zone());
3190 // Make statement: outer: for (;;)
3191 // Note that we don't actually create the label, or set this loop up as an
3192 // explicit break target, instead handing it directly to those nodes that
3193 // need to know about it. This should be safe because we don't run any code
3194 // in this function that looks up break targets.
3195 ForStatement* outer_loop =
3196 factory()->NewForStatement(NULL, RelocInfo::kNoPosition);
3197 outer_block->AddStatement(outer_loop, zone());
3199 outer_block->set_scope(for_scope);
3200 scope_ = inner_scope;
3202 Block* inner_block = factory()->NewBlock(NULL, names->length() + 4, false,
3203 RelocInfo::kNoPosition);
3204 ZoneList<Variable*> inner_vars(names->length(), zone());
3206 // For each let variable x:
3207 // make statement: let/const x = temp_x.
3208 VariableMode mode = is_const ? CONST : LET;
3209 for (int i = 0; i < names->length(); i++) {
3210 VariableProxy* proxy = NewUnresolved(names->at(i), mode);
3211 Declaration* declaration = factory()->NewVariableDeclaration(
3212 proxy, mode, scope_, RelocInfo::kNoPosition);
3213 Declare(declaration, true, CHECK_OK);
3214 inner_vars.Add(declaration->proxy()->var(), zone());
3215 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3216 Assignment* assignment =
3217 factory()->NewAssignment(is_const ? Token::INIT_CONST : Token::INIT_LET,
3218 proxy, temp_proxy, RelocInfo::kNoPosition);
3219 Statement* assignment_statement =
3220 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3221 proxy->var()->set_initializer_position(init->position());
3222 inner_block->AddStatement(assignment_statement, zone());
3225 // Make statement: if (first == 1) { first = 0; } else { next; }
3228 Expression* compare = NULL;
3229 // Make compare expression: first == 1.
3231 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3232 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3233 compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
3234 RelocInfo::kNoPosition);
3236 Statement* clear_first = NULL;
3237 // Make statement: first = 0.
3239 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3240 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3241 Assignment* assignment = factory()->NewAssignment(
3242 Token::ASSIGN, first_proxy, const0, RelocInfo::kNoPosition);
3244 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3246 Statement* clear_first_or_next =
3247 factory()->NewIfStatement(compare, clear_first, next, next->position());
3248 inner_block->AddStatement(clear_first_or_next, zone());
3251 Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name);
3252 // Make statement: flag = 1.
3254 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3255 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3256 Assignment* assignment = factory()->NewAssignment(
3257 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
3258 Statement* assignment_statement =
3259 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3260 inner_block->AddStatement(assignment_statement, zone());
3263 // Make cond expression for main loop: flag == 1.
3264 Expression* flag_cond = NULL;
3266 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3267 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3268 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
3269 RelocInfo::kNoPosition);
3272 // Create chain of expressions "flag = 0, temp_x = x, ..."
3273 Statement* compound_next_statement = NULL;
3275 Expression* compound_next = NULL;
3276 // Make expression: flag = 0.
3278 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3279 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3280 compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
3281 const0, RelocInfo::kNoPosition);
3284 // Make the comma-separated list of temp_x = x assignments.
3285 int inner_var_proxy_pos = scanner()->location().beg_pos;
3286 for (int i = 0; i < names->length(); i++) {
3287 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3288 VariableProxy* proxy =
3289 factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos);
3290 Assignment* assignment = factory()->NewAssignment(
3291 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3292 compound_next = factory()->NewBinaryOperation(
3293 Token::COMMA, compound_next, assignment, RelocInfo::kNoPosition);
3296 compound_next_statement = factory()->NewExpressionStatement(
3297 compound_next, RelocInfo::kNoPosition);
3300 // Make statement: if (cond) { body; } else { break outer; }
3301 Statement* body_or_stop = body;
3304 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3306 factory()->NewIfStatement(cond, body, stop, cond->position());
3309 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
3310 // Note that we re-use the original loop node, which retains it labels
3311 // and ensures that any break or continue statements in body point to
3313 loop->Initialize(NULL, flag_cond, compound_next_statement, body_or_stop);
3314 inner_block->AddStatement(loop, zone());
3316 // Make statement: if (flag == 1) { break; }
3318 Expression* compare = NULL;
3319 // Make compare expresion: flag == 1.
3321 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3322 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3323 compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
3324 RelocInfo::kNoPosition);
3327 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3328 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
3329 Statement* if_flag_break =
3330 factory()->NewIfStatement(compare, stop, empty, RelocInfo::kNoPosition);
3331 inner_block->AddStatement(if_flag_break, zone());
3334 inner_scope->set_end_position(scanner()->location().end_pos);
3335 inner_block->set_scope(inner_scope);
3338 outer_loop->Initialize(NULL, NULL, NULL, inner_block);
3343 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
3346 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
3348 int stmt_pos = peek_position();
3349 bool is_const = false;
3350 Statement* init = NULL;
3351 ZoneList<const AstRawString*> lexical_bindings(1, zone());
3353 // Create an in-between scope for let-bound iteration variables.
3354 Scope* saved_scope = scope_;
3355 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
3358 Expect(Token::FOR, CHECK_OK);
3359 Expect(Token::LPAREN, CHECK_OK);
3360 for_scope->set_start_position(scanner()->location().beg_pos);
3361 bool is_let_identifier_expression = false;
3362 if (peek() != Token::SEMICOLON) {
3363 if (peek() == Token::VAR ||
3364 (peek() == Token::CONST && is_sloppy(language_mode()))) {
3365 const AstRawString* name = NULL;
3366 VariableDeclarationProperties decl_props = kHasNoInitializers;
3367 Block* variable_statement =
3368 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
3370 bool accept_OF = decl_props == kHasNoInitializers;
3371 ForEachStatement::VisitMode mode;
3372 int each_beg_pos = scanner()->location().beg_pos;
3373 int each_end_pos = scanner()->location().end_pos;
3375 if (name != NULL && CheckInOrOf(accept_OF, &mode, ok)) {
3376 if (!*ok) return nullptr;
3377 ForEachStatement* loop =
3378 factory()->NewForEachStatement(mode, labels, stmt_pos);
3379 Target target(&this->target_stack_, loop);
3381 Expression* enumerable = ParseExpression(true, CHECK_OK);
3382 Expect(Token::RPAREN, CHECK_OK);
3384 VariableProxy* each =
3385 scope_->NewUnresolved(factory(), name, each_beg_pos, each_end_pos);
3386 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3387 InitializeForEachStatement(loop, each, enumerable, body);
3389 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3390 result->AddStatement(variable_statement, zone());
3391 result->AddStatement(loop, zone());
3392 scope_ = saved_scope;
3393 for_scope->set_end_position(scanner()->location().end_pos);
3394 for_scope = for_scope->FinalizeBlockScope();
3395 DCHECK(for_scope == NULL);
3396 // Parsed for-in loop w/ variable/const declaration.
3399 init = variable_statement;
3401 } else if ((peek() == Token::LET || peek() == Token::CONST) &&
3402 is_strict(language_mode())) {
3403 is_const = peek() == Token::CONST;
3404 const AstRawString* name = NULL;
3405 VariableDeclarationProperties decl_props = kHasNoInitializers;
3406 Block* variable_statement =
3407 ParseVariableDeclarations(kForStatement, &decl_props,
3408 &lexical_bindings, &name, CHECK_OK);
3409 bool accept_IN = name != NULL && decl_props != kHasInitializers;
3410 bool accept_OF = decl_props == kHasNoInitializers;
3411 ForEachStatement::VisitMode mode;
3412 int each_beg_pos = scanner()->location().beg_pos;
3413 int each_end_pos = scanner()->location().end_pos;
3415 if (accept_IN && CheckInOrOf(accept_OF, &mode, ok)) {
3416 if (!*ok) return nullptr;
3418 // Rewrite a for-in statement of the form
3420 // for (let/const x in e) b
3424 // <let x' be a temporary variable>
3431 // TODO(keuchel): Move the temporary variable to the block scope, after
3432 // implementing stack allocated block scoped variables.
3433 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3434 ast_value_factory()->dot_for_string());
3435 VariableProxy* temp_proxy =
3436 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
3437 ForEachStatement* loop =
3438 factory()->NewForEachStatement(mode, labels, stmt_pos);
3439 Target target(&this->target_stack_, loop);
3441 // The expression does not see the loop variable.
3442 scope_ = saved_scope;
3443 Expression* enumerable = ParseExpression(true, CHECK_OK);
3445 Expect(Token::RPAREN, CHECK_OK);
3447 VariableProxy* each =
3448 scope_->NewUnresolved(factory(), name, each_beg_pos, each_end_pos);
3449 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3451 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3452 Token::Value init_op = is_const ? Token::INIT_CONST : Token::ASSIGN;
3453 Assignment* assignment = factory()->NewAssignment(
3454 init_op, each, temp_proxy, RelocInfo::kNoPosition);
3455 Statement* assignment_statement = factory()->NewExpressionStatement(
3456 assignment, RelocInfo::kNoPosition);
3457 body_block->AddStatement(variable_statement, zone());
3458 body_block->AddStatement(assignment_statement, zone());
3459 body_block->AddStatement(body, zone());
3460 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block);
3461 scope_ = saved_scope;
3462 for_scope->set_end_position(scanner()->location().end_pos);
3463 for_scope = for_scope->FinalizeBlockScope();
3464 body_block->set_scope(for_scope);
3465 // Parsed for-in loop w/ let declaration.
3469 init = variable_statement;
3472 Scanner::Location lhs_location = scanner()->peek_location();
3473 Expression* expression = ParseExpression(false, CHECK_OK);
3474 ForEachStatement::VisitMode mode;
3475 bool accept_OF = expression->IsVariableProxy();
3476 is_let_identifier_expression =
3477 expression->IsVariableProxy() &&
3478 expression->AsVariableProxy()->raw_name() ==
3479 ast_value_factory()->let_string();
3481 if (CheckInOrOf(accept_OF, &mode, ok)) {
3482 if (!*ok) return nullptr;
3483 expression = this->CheckAndRewriteReferenceExpression(
3484 expression, lhs_location, "invalid_lhs_in_for", CHECK_OK);
3486 ForEachStatement* loop =
3487 factory()->NewForEachStatement(mode, labels, stmt_pos);
3488 Target target(&this->target_stack_, loop);
3490 Expression* enumerable = ParseExpression(true, CHECK_OK);
3491 Expect(Token::RPAREN, CHECK_OK);
3493 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3494 InitializeForEachStatement(loop, expression, enumerable, body);
3495 scope_ = saved_scope;
3496 for_scope->set_end_position(scanner()->location().end_pos);
3497 for_scope = for_scope->FinalizeBlockScope();
3498 DCHECK(for_scope == NULL);
3499 // Parsed for-in loop.
3503 init = factory()->NewExpressionStatement(expression, position());
3508 // Standard 'for' loop
3509 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos);
3510 Target target(&this->target_stack_, loop);
3512 // Parsed initializer at this point.
3513 // Detect attempts at 'let' declarations in sloppy mode.
3514 if (peek() == Token::IDENTIFIER && is_sloppy(language_mode()) &&
3515 is_let_identifier_expression) {
3516 ReportMessage("sloppy_lexical", NULL);
3520 Expect(Token::SEMICOLON, CHECK_OK);
3522 // If there are let bindings, then condition and the next statement of the
3523 // for loop must be parsed in a new scope.
3524 Scope* inner_scope = NULL;
3525 if (lexical_bindings.length() > 0) {
3526 inner_scope = NewScope(for_scope, BLOCK_SCOPE);
3527 inner_scope->set_start_position(scanner()->location().beg_pos);
3528 scope_ = inner_scope;
3531 Expression* cond = NULL;
3532 if (peek() != Token::SEMICOLON) {
3533 cond = ParseExpression(true, CHECK_OK);
3535 Expect(Token::SEMICOLON, CHECK_OK);
3537 Statement* next = NULL;
3538 if (peek() != Token::RPAREN) {
3539 int next_pos = position();
3540 Expression* exp = ParseExpression(true, CHECK_OK);
3541 next = factory()->NewExpressionStatement(exp, next_pos);
3543 Expect(Token::RPAREN, CHECK_OK);
3545 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3547 Statement* result = NULL;
3548 if (lexical_bindings.length() > 0) {
3550 result = DesugarLexicalBindingsInForStatement(
3551 inner_scope, is_const, &lexical_bindings, loop, init, cond,
3552 next, body, CHECK_OK);
3553 scope_ = saved_scope;
3554 for_scope->set_end_position(scanner()->location().end_pos);
3556 scope_ = saved_scope;
3557 for_scope->set_end_position(scanner()->location().end_pos);
3558 for_scope = for_scope->FinalizeBlockScope();
3560 // Rewrite a for statement of the form
3561 // for (const x = i; c; n) b
3569 DCHECK(init != NULL);
3571 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3572 block->AddStatement(init, zone());
3573 block->AddStatement(loop, zone());
3574 block->set_scope(for_scope);
3575 loop->Initialize(NULL, cond, next, body);
3578 loop->Initialize(init, cond, next, body);
3586 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
3587 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
3588 // contexts this is used as a statement which invokes the debugger as i a
3589 // break point is present.
3590 // DebuggerStatement ::
3593 int pos = peek_position();
3594 Expect(Token::DEBUGGER, CHECK_OK);
3595 ExpectSemicolon(CHECK_OK);
3596 return factory()->NewDebuggerStatement(pos);
3600 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
3601 if (expression->IsLiteral()) return true;
3602 MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3603 return lit != NULL && lit->is_simple();
3607 Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate,
3608 Expression* expression) {
3609 Factory* factory = isolate->factory();
3610 DCHECK(IsCompileTimeValue(expression));
3611 Handle<FixedArray> result = factory->NewFixedArray(2, TENURED);
3612 ObjectLiteral* object_literal = expression->AsObjectLiteral();
3613 if (object_literal != NULL) {
3614 DCHECK(object_literal->is_simple());
3615 if (object_literal->fast_elements()) {
3616 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
3618 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
3620 result->set(kElementsSlot, *object_literal->constant_properties());
3622 ArrayLiteral* array_literal = expression->AsArrayLiteral();
3623 DCHECK(array_literal != NULL && array_literal->is_simple());
3624 result->set(kLiteralTypeSlot, Smi::FromInt(ARRAY_LITERAL));
3625 result->set(kElementsSlot, *array_literal->constant_elements());
3631 CompileTimeValue::LiteralType CompileTimeValue::GetLiteralType(
3632 Handle<FixedArray> value) {
3633 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot));
3634 return static_cast<LiteralType>(literal_type->value());
3638 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
3639 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
3643 bool CheckAndDeclareArrowParameter(ParserTraits* traits, Expression* expression,
3644 Scope* scope, int* num_params,
3645 Scanner::Location* dupe_loc) {
3646 // Case for empty parameter lists:
3648 if (expression == NULL) return true;
3650 // Too many parentheses around expression:
3652 if (expression->is_multi_parenthesized()) return false;
3654 // Case for a single parameter:
3657 if (expression->IsVariableProxy()) {
3658 if (expression->AsVariableProxy()->is_this()) return false;
3660 const AstRawString* raw_name = expression->AsVariableProxy()->raw_name();
3661 if (traits->IsEvalOrArguments(raw_name) ||
3662 traits->IsFutureStrictReserved(raw_name))
3665 if (scope->IsDeclared(raw_name)) {
3666 *dupe_loc = Scanner::Location(
3667 expression->position(), expression->position() + raw_name->length());
3671 // When the variable was seen, it was recorded as unresolved in the outer
3672 // scope. But it's really not unresolved.
3673 scope->outer_scope()->RemoveUnresolved(expression->AsVariableProxy());
3675 scope->DeclareParameter(raw_name, VAR);
3680 // Case for more than one parameter:
3681 // (foo, bar [, ...]) => ...
3682 if (expression->IsBinaryOperation()) {
3683 BinaryOperation* binop = expression->AsBinaryOperation();
3684 if (binop->op() != Token::COMMA || binop->left()->is_parenthesized() ||
3685 binop->right()->is_parenthesized())
3688 return CheckAndDeclareArrowParameter(traits, binop->left(), scope,
3689 num_params, dupe_loc) &&
3690 CheckAndDeclareArrowParameter(traits, binop->right(), scope,
3691 num_params, dupe_loc);
3694 // Any other kind of expression is not a valid parameter list.
3699 int ParserTraits::DeclareArrowParametersFromExpression(
3700 Expression* expression, Scope* scope, Scanner::Location* dupe_loc,
3703 // Always reset the flag: It only needs to be set for the first expression
3704 // parsed as arrow function parameter list, becauseonly top-level functions
3705 // are parsed lazily.
3706 parser_->parsing_lazy_arrow_parameters_ = false;
3707 *ok = CheckAndDeclareArrowParameter(this, expression, scope, &num_params,
3713 FunctionLiteral* Parser::ParseFunctionLiteral(
3714 const AstRawString* function_name, Scanner::Location function_name_location,
3715 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos,
3716 FunctionLiteral::FunctionType function_type,
3717 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
3719 // '(' FormalParameterList? ')' '{' FunctionBody '}'
3722 // '(' ')' '{' FunctionBody '}'
3725 // '(' PropertySetParameterList ')' '{' FunctionBody '}'
3727 int pos = function_token_pos == RelocInfo::kNoPosition
3728 ? peek_position() : function_token_pos;
3730 bool is_generator = IsGeneratorFunction(kind);
3732 // Anonymous functions were passed either the empty symbol or a null
3733 // handle as the function name. Remember if we were passed a non-empty
3734 // handle to decide whether to invoke function name inference.
3735 bool should_infer_name = function_name == NULL;
3737 // We want a non-null handle as the function name.
3738 if (should_infer_name) {
3739 function_name = ast_value_factory()->empty_string();
3742 int num_parameters = 0;
3743 // Function declarations are function scoped in normal mode, so they are
3744 // hoisted. In harmony block scoping mode they are block scoped, so they
3747 // One tricky case are function declarations in a local sloppy-mode eval:
3748 // their declaration is hoisted, but they still see the local scope. E.g.,
3752 // try { throw 1 } catch (x) { eval("function g() { return x }") }
3756 // needs to return 1. To distinguish such cases, we need to detect
3757 // (1) whether a function stems from a sloppy eval, and
3758 // (2) whether it actually hoists across the eval.
3759 // Unfortunately, we do not represent sloppy eval scopes, so we do not have
3760 // either information available directly, especially not when lazily compiling
3761 // a function like 'g'. We hence rely on the following invariants:
3762 // - (1) is the case iff the innermost scope of the deserialized scope chain
3763 // under which we compile is _not_ a declaration scope. This holds because
3764 // in all normal cases, function declarations are fully hoisted to a
3765 // declaration scope and compiled relative to that.
3766 // - (2) is the case iff the current declaration scope is still the original
3767 // one relative to the deserialized scope chain. Otherwise we must be
3768 // compiling a function in an inner declaration scope in the eval, e.g. a
3769 // nested function, and hoisting works normally relative to that.
3770 Scope* declaration_scope = scope_->DeclarationScope();
3771 Scope* original_declaration_scope = original_scope_->DeclarationScope();
3772 Scope* scope = function_type == FunctionLiteral::DECLARATION &&
3773 is_sloppy(language_mode()) &&
3774 (original_scope_ == original_declaration_scope ||
3775 declaration_scope != original_declaration_scope)
3776 ? NewScope(declaration_scope, FUNCTION_SCOPE, kind)
3777 : NewScope(scope_, FUNCTION_SCOPE, kind);
3778 ZoneList<Statement*>* body = NULL;
3779 int materialized_literal_count = -1;
3780 int expected_property_count = -1;
3781 int handler_count = 0;
3782 FunctionLiteral::ParameterFlag duplicate_parameters =
3783 FunctionLiteral::kNoDuplicateParameters;
3784 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
3785 ? FunctionLiteral::kIsParenthesized
3786 : FunctionLiteral::kNotParenthesized;
3787 // Parse function body.
3789 AstNodeFactory function_factory(ast_value_factory());
3790 FunctionState function_state(&function_state_, &scope_, scope, kind,
3792 scope_->SetScopeName(function_name);
3795 // For generators, allocating variables in contexts is currently a win
3796 // because it minimizes the work needed to suspend and resume an
3798 scope_->ForceContextAllocation();
3800 // Calling a generator returns a generator object. That object is stored
3801 // in a temporary variable, a definition that is used by "yield"
3802 // expressions. This also marks the FunctionState as a generator.
3803 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3804 ast_value_factory()->dot_generator_object_string());
3805 function_state.set_generator_object_variable(temp);
3808 // FormalParameterList ::
3809 // '(' (Identifier)*[','] ')'
3810 Expect(Token::LPAREN, CHECK_OK);
3811 scope->set_start_position(scanner()->location().beg_pos);
3813 // We don't yet know if the function will be strict, so we cannot yet
3814 // produce errors for parameter names or duplicates. However, we remember
3815 // the locations of these errors if they occur and produce the errors later.
3816 Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
3817 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
3818 Scanner::Location reserved_error_loc = Scanner::Location::invalid();
3820 bool is_rest = false;
3821 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY ||
3822 (peek() == Token::RPAREN &&
3823 arity_restriction != FunctionLiteral::SETTER_ARITY);
3825 bool is_strict_reserved = false;
3826 is_rest = peek() == Token::ELLIPSIS && allow_harmony_rest_params();
3828 Consume(Token::ELLIPSIS);
3831 const AstRawString* param_name =
3832 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
3834 // Store locations for possible future error reports.
3835 if (!eval_args_error_loc.IsValid() && IsEvalOrArguments(param_name)) {
3836 eval_args_error_loc = scanner()->location();
3838 if (!reserved_error_loc.IsValid() && is_strict_reserved) {
3839 reserved_error_loc = scanner()->location();
3841 if (!dupe_error_loc.IsValid() &&
3842 scope_->IsDeclaredParameter(param_name)) {
3843 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters;
3844 dupe_error_loc = scanner()->location();
3847 Variable* var = scope_->DeclareParameter(param_name, VAR, is_rest);
3848 if (is_sloppy(scope->language_mode())) {
3849 // TODO(sigurds) Mark every parameter as maybe assigned. This is a
3850 // conservative approximation necessary to account for parameters
3851 // that are assigned via the arguments array.
3852 var->set_maybe_assigned();
3856 if (num_parameters > Code::kMaxArguments) {
3857 ReportMessage("too_many_parameters");
3861 if (arity_restriction == FunctionLiteral::SETTER_ARITY) break;
3862 done = (peek() == Token::RPAREN);
3865 ReportMessageAt(scanner()->peek_location(), "param_after_rest");
3869 Expect(Token::COMMA, CHECK_OK);
3872 Expect(Token::RPAREN, CHECK_OK);
3874 Expect(Token::LBRACE, CHECK_OK);
3876 // If we have a named function expression, we add a local variable
3877 // declaration to the body of the function with the name of the
3878 // function and let it refer to the function itself (closure).
3879 // NOTE: We create a proxy and resolve it here so that in the
3880 // future we can change the AST to only refer to VariableProxies
3881 // instead of Variables and Proxis as is the case now.
3882 Variable* fvar = NULL;
3883 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY;
3884 if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
3885 if (is_strict(language_mode())) {
3886 fvar_init_op = Token::INIT_CONST;
3888 VariableMode fvar_mode =
3889 is_strict(language_mode()) ? CONST : CONST_LEGACY;
3890 DCHECK(function_name != NULL);
3892 Variable(scope_, function_name, fvar_mode, Variable::NORMAL,
3893 kCreatedInitialized, kNotAssigned);
3894 VariableProxy* proxy = factory()->NewVariableProxy(fvar);
3895 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration(
3896 proxy, fvar_mode, scope_, RelocInfo::kNoPosition);
3897 scope_->DeclareFunctionVar(fvar_declaration);
3900 // Determine if the function can be parsed lazily. Lazy parsing is different
3901 // from lazy compilation; we need to parse more eagerly than we compile.
3903 // We can only parse lazily if we also compile lazily. The heuristics for
3904 // lazy compilation are:
3905 // - It must not have been prohibited by the caller to Parse (some callers
3906 // need a full AST).
3907 // - The outer scope must allow lazy compilation of inner functions.
3908 // - The function mustn't be a function expression with an open parenthesis
3909 // before; we consider that a hint that the function will be called
3910 // immediately, and it would be a waste of time to make it lazily
3912 // These are all things we can know at this point, without looking at the
3915 // In addition, we need to distinguish between these cases:
3916 // (function foo() {
3917 // bar = function() { return 1; }
3920 // (function foo() {
3922 // bar = function() { return a; }
3925 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
3926 // parenthesis before the function means that it will be called
3927 // immediately). The inner function *must* be parsed eagerly to resolve the
3928 // possible reference to the variable in foo's scope. However, it's possible
3929 // that it will be compiled lazily.
3931 // To make this additional case work, both Parser and PreParser implement a
3932 // logic where only top-level functions will be parsed lazily.
3933 bool is_lazily_parsed = (mode() == PARSE_LAZILY &&
3934 scope_->AllowsLazyCompilation() &&
3935 !parenthesized_function_);
3936 parenthesized_function_ = false; // The bit was set for this function only.
3938 if (is_lazily_parsed) {
3939 SkipLazyFunctionBody(function_name, &materialized_literal_count,
3940 &expected_property_count, CHECK_OK);
3942 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
3944 materialized_literal_count = function_state.materialized_literal_count();
3945 expected_property_count = function_state.expected_property_count();
3946 handler_count = function_state.handler_count();
3949 // Validate name and parameter names. We can do this only after parsing the
3950 // function, since the function can declare itself strict.
3951 CheckFunctionName(language_mode(), kind, function_name,
3952 name_is_strict_reserved, function_name_location,
3954 const bool use_strict_params = is_rest || IsConciseMethod(kind);
3955 CheckFunctionParameterNames(language_mode(), use_strict_params,
3956 eval_args_error_loc, dupe_error_loc,
3957 reserved_error_loc, CHECK_OK);
3959 if (is_strict(language_mode())) {
3960 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
3963 if (is_strict(language_mode())) {
3964 CheckConflictingVarDeclarations(scope, CHECK_OK);
3966 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) {
3967 if (!function_state.super_call_location().IsValid()) {
3968 ReportMessageAt(function_name_location, "strong_super_call_missing",
3976 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
3977 function_name, ast_value_factory(), scope, body,
3978 materialized_literal_count, expected_property_count, handler_count,
3979 num_parameters, duplicate_parameters, function_type,
3980 FunctionLiteral::kIsFunction, parenthesized, kind, pos);
3981 function_literal->set_function_token_position(function_token_pos);
3983 if (scope->has_rest_parameter()) {
3984 // TODO(caitp): enable optimization of functions with rest params
3985 function_literal->set_dont_optimize_reason(kRestParameter);
3988 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
3989 return function_literal;
3993 void Parser::SkipLazyFunctionBody(const AstRawString* function_name,
3994 int* materialized_literal_count,
3995 int* expected_property_count,
3997 if (produce_cached_parse_data()) CHECK(log_);
3999 int function_block_pos = position();
4000 if (consume_cached_parse_data() && !cached_parse_data_->rejected()) {
4001 // If we have cached data, we use it to skip parsing the function body. The
4002 // data contains the information we need to construct the lazy function.
4003 FunctionEntry entry =
4004 cached_parse_data_->GetFunctionEntry(function_block_pos);
4005 // Check that cached data is valid. If not, mark it as invalid (the embedder
4006 // handles it). Note that end position greater than end of stream is safe,
4007 // and hard to check.
4008 if (entry.is_valid() && entry.end_pos() > function_block_pos) {
4009 scanner()->SeekForward(entry.end_pos() - 1);
4011 scope_->set_end_position(entry.end_pos());
4012 Expect(Token::RBRACE, ok);
4016 total_preparse_skipped_ += scope_->end_position() - function_block_pos;
4017 *materialized_literal_count = entry.literal_count();
4018 *expected_property_count = entry.property_count();
4019 scope_->SetLanguageMode(entry.language_mode());
4020 if (entry.uses_super_property()) scope_->RecordSuperPropertyUsage();
4023 cached_parse_data_->Reject();
4025 // With no cached data, we partially parse the function, without building an
4026 // AST. This gathers the data needed to build a lazy function.
4027 SingletonLogger logger;
4028 PreParser::PreParseResult result =
4029 ParseLazyFunctionBodyWithPreParser(&logger);
4030 if (result == PreParser::kPreParseStackOverflow) {
4031 // Propagate stack overflow.
4032 set_stack_overflow();
4036 if (logger.has_error()) {
4037 ParserTraits::ReportMessageAt(
4038 Scanner::Location(logger.start(), logger.end()), logger.message(),
4039 logger.argument_opt(), logger.error_type());
4043 scope_->set_end_position(logger.end());
4044 Expect(Token::RBRACE, ok);
4048 total_preparse_skipped_ += scope_->end_position() - function_block_pos;
4049 *materialized_literal_count = logger.literals();
4050 *expected_property_count = logger.properties();
4051 scope_->SetLanguageMode(logger.language_mode());
4052 if (logger.scope_uses_super_property()) {
4053 scope_->RecordSuperPropertyUsage();
4055 if (produce_cached_parse_data()) {
4057 // Position right after terminal '}'.
4058 int body_end = scanner()->location().end_pos;
4059 log_->LogFunction(function_block_pos, body_end, *materialized_literal_count,
4060 *expected_property_count, scope_->language_mode(),
4061 scope_->uses_super_property());
4066 void Parser::AddAssertIsConstruct(ZoneList<Statement*>* body, int pos) {
4067 ZoneList<Expression*>* arguments =
4068 new (zone()) ZoneList<Expression*>(0, zone());
4069 CallRuntime* construct_check = factory()->NewCallRuntime(
4070 ast_value_factory()->is_construct_call_string(),
4071 Runtime::FunctionForId(Runtime::kInlineIsConstructCall), arguments, pos);
4072 CallRuntime* non_callable_error = factory()->NewCallRuntime(
4073 ast_value_factory()->empty_string(),
4074 Runtime::FunctionForId(Runtime::kThrowConstructorNonCallableError),
4076 IfStatement* if_statement = factory()->NewIfStatement(
4077 factory()->NewUnaryOperation(Token::NOT, construct_check, pos),
4078 factory()->NewReturnStatement(non_callable_error, pos),
4079 factory()->NewEmptyStatement(pos), pos);
4080 body->Add(if_statement, zone());
4084 ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
4085 const AstRawString* function_name, int pos, Variable* fvar,
4086 Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
4087 // Everything inside an eagerly parsed function will be parsed eagerly
4088 // (see comment above).
4089 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
4090 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone());
4092 VariableProxy* fproxy = scope_->NewUnresolved(factory(), function_name);
4093 fproxy->BindTo(fvar);
4094 body->Add(factory()->NewExpressionStatement(
4095 factory()->NewAssignment(fvar_init_op,
4097 factory()->NewThisFunction(pos),
4098 RelocInfo::kNoPosition),
4099 RelocInfo::kNoPosition), zone());
4103 // For concise constructors, check that they are constructed,
4105 if (i::IsConstructor(kind)) {
4106 AddAssertIsConstruct(body, pos);
4109 // For generators, allocate and yield an iterator on function entry.
4110 if (IsGeneratorFunction(kind)) {
4111 ZoneList<Expression*>* arguments =
4112 new(zone()) ZoneList<Expression*>(0, zone());
4113 CallRuntime* allocation = factory()->NewCallRuntime(
4114 ast_value_factory()->empty_string(),
4115 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), arguments,
4117 VariableProxy* init_proxy = factory()->NewVariableProxy(
4118 function_state_->generator_object_variable());
4119 Assignment* assignment = factory()->NewAssignment(
4120 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
4121 VariableProxy* get_proxy = factory()->NewVariableProxy(
4122 function_state_->generator_object_variable());
4123 Yield* yield = factory()->NewYield(
4124 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition);
4125 body->Add(factory()->NewExpressionStatement(
4126 yield, RelocInfo::kNoPosition), zone());
4129 ParseStatementList(body, Token::RBRACE, false, NULL, CHECK_OK);
4131 if (IsGeneratorFunction(kind)) {
4132 VariableProxy* get_proxy = factory()->NewVariableProxy(
4133 function_state_->generator_object_variable());
4134 Expression* undefined =
4135 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition);
4136 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal,
4137 RelocInfo::kNoPosition);
4138 body->Add(factory()->NewExpressionStatement(
4139 yield, RelocInfo::kNoPosition), zone());
4142 if (IsSubclassConstructor(kind)) {
4144 factory()->NewReturnStatement(
4145 this->ThisExpression(scope_, factory(), RelocInfo::kNoPosition),
4146 RelocInfo::kNoPosition),
4150 Expect(Token::RBRACE, CHECK_OK);
4151 scope_->set_end_position(scanner()->location().end_pos);
4157 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
4158 SingletonLogger* logger) {
4159 // This function may be called on a background thread too; record only the
4160 // main thread preparse times.
4161 if (pre_parse_timer_ != NULL) {
4162 pre_parse_timer_->Start();
4164 DCHECK_EQ(Token::LBRACE, scanner()->current_token());
4166 if (reusable_preparser_ == NULL) {
4167 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(),
4168 NULL, stack_limit_);
4169 reusable_preparser_->set_allow_lazy(true);
4170 reusable_preparser_->set_allow_natives(allow_natives());
4171 reusable_preparser_->set_allow_harmony_modules(allow_harmony_modules());
4172 reusable_preparser_->set_allow_harmony_arrow_functions(
4173 allow_harmony_arrow_functions());
4174 reusable_preparser_->set_allow_harmony_numeric_literals(
4175 allow_harmony_numeric_literals());
4176 reusable_preparser_->set_allow_harmony_classes(allow_harmony_classes());
4177 reusable_preparser_->set_allow_harmony_object_literals(
4178 allow_harmony_object_literals());
4179 reusable_preparser_->set_allow_harmony_sloppy(allow_harmony_sloppy());
4180 reusable_preparser_->set_allow_harmony_unicode(allow_harmony_unicode());
4181 reusable_preparser_->set_allow_harmony_computed_property_names(
4182 allow_harmony_computed_property_names());
4183 reusable_preparser_->set_allow_harmony_rest_params(
4184 allow_harmony_rest_params());
4185 reusable_preparser_->set_allow_strong_mode(allow_strong_mode());
4187 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
4188 language_mode(), function_state_->kind(), logger);
4189 if (pre_parse_timer_ != NULL) {
4190 pre_parse_timer_->Stop();
4196 ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name,
4197 Scanner::Location class_name_location,
4198 bool name_is_strict_reserved, int pos,
4200 // All parts of a ClassDeclaration and ClassExpression are strict code.
4201 if (name_is_strict_reserved) {
4202 ReportMessageAt(class_name_location, "unexpected_strict_reserved");
4206 if (IsEvalOrArguments(name)) {
4207 ReportMessageAt(class_name_location, "strict_eval_arguments");
4212 // Create a block scope which is additionally tagged as class scope; this is
4213 // important for resolving variable references to the class name in the strong
4215 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
4216 block_scope->tag_as_class_scope();
4217 BlockState block_state(&scope_, block_scope);
4218 scope_->SetLanguageMode(
4219 static_cast<LanguageMode>(scope_->language_mode() | STRICT_BIT));
4220 scope_->SetScopeName(name);
4222 VariableProxy* proxy = NULL;
4224 proxy = NewUnresolved(name, CONST);
4225 Declaration* declaration =
4226 factory()->NewVariableDeclaration(proxy, CONST, block_scope, pos);
4227 Declare(declaration, true, CHECK_OK);
4230 Expression* extends = NULL;
4231 if (Check(Token::EXTENDS)) {
4232 block_scope->set_start_position(scanner()->location().end_pos);
4233 extends = ParseLeftHandSideExpression(CHECK_OK);
4235 block_scope->set_start_position(scanner()->location().end_pos);
4239 ClassLiteralChecker checker(this);
4240 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone());
4241 FunctionLiteral* constructor = NULL;
4242 bool has_seen_constructor = false;
4244 Expect(Token::LBRACE, CHECK_OK);
4246 const bool has_extends = extends != nullptr;
4247 while (peek() != Token::RBRACE) {
4248 if (Check(Token::SEMICOLON)) continue;
4249 if (fni_ != NULL) fni_->Enter();
4250 const bool in_class = true;
4251 const bool is_static = false;
4252 bool is_computed_name = false; // Classes do not care about computed
4253 // property names here.
4254 ObjectLiteral::Property* property = ParsePropertyDefinition(
4255 &checker, in_class, has_extends, is_static, &is_computed_name,
4256 &has_seen_constructor, CHECK_OK);
4258 if (has_seen_constructor && constructor == NULL) {
4259 constructor = GetPropertyValue(property)->AsFunctionLiteral();
4260 DCHECK_NOT_NULL(constructor);
4262 properties->Add(property, zone());
4271 Expect(Token::RBRACE, CHECK_OK);
4272 int end_pos = scanner()->location().end_pos;
4274 if (constructor == NULL) {
4276 DefaultConstructor(extends != NULL, block_scope, pos, end_pos);
4279 block_scope->set_end_position(end_pos);
4282 DCHECK_NOT_NULL(proxy);
4283 proxy->var()->set_initializer_position(end_pos);
4285 // Unnamed classes should not have scopes (the scope will be empty).
4286 DCHECK_EQ(block_scope->num_var_or_const(), 0);
4287 block_scope = nullptr;
4290 return factory()->NewClassLiteral(name, block_scope, proxy, extends,
4291 constructor, properties, pos, end_pos);
4295 Expression* Parser::ParseV8Intrinsic(bool* ok) {
4297 // '%' Identifier Arguments
4299 int pos = peek_position();
4300 Expect(Token::MOD, CHECK_OK);
4301 // Allow "eval" or "arguments" for backward compatibility.
4302 const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
4303 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
4305 if (extension_ != NULL) {
4306 // The extension structures are only accessible while parsing the
4307 // very first time not when reparsing because of lazy compilation.
4308 scope_->DeclarationScope()->ForceEagerCompilation();
4311 const Runtime::Function* function = Runtime::FunctionForName(name->string());
4313 // Check for built-in IS_VAR macro.
4314 if (function != NULL &&
4315 function->intrinsic_type == Runtime::RUNTIME &&
4316 function->function_id == Runtime::kIS_VAR) {
4317 // %IS_VAR(x) evaluates to x if x is a variable,
4318 // leads to a parse error otherwise. Could be implemented as an
4319 // inline function %_IS_VAR(x) to eliminate this special case.
4320 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
4323 ReportMessage("not_isvar");
4329 // Check that the expected number of arguments are being passed.
4330 if (function != NULL &&
4331 function->nargs != -1 &&
4332 function->nargs != args->length()) {
4333 ReportMessage("illegal_access");
4338 // Check that the function is defined if it's an inline runtime call.
4339 if (function == NULL && name->FirstCharacter() == '_') {
4340 ParserTraits::ReportMessage("not_defined", name);
4345 // We have a valid intrinsics call or a call to a builtin.
4346 return factory()->NewCallRuntime(name, function, args, pos);
4350 Literal* Parser::GetLiteralUndefined(int position) {
4351 return factory()->NewUndefinedLiteral(position);
4355 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
4356 Declaration* decl = scope->CheckConflictingVarDeclarations();
4358 // In harmony mode we treat conflicting variable bindinds as early
4359 // errors. See ES5 16 for a definition of early errors.
4360 const AstRawString* name = decl->proxy()->raw_name();
4361 int position = decl->proxy()->position();
4362 Scanner::Location location = position == RelocInfo::kNoPosition
4363 ? Scanner::Location::invalid()
4364 : Scanner::Location(position, position + 1);
4365 ParserTraits::ReportMessageAt(location, "var_redeclaration", name);
4371 // ----------------------------------------------------------------------------
4375 bool Parser::TargetStackContainsLabel(const AstRawString* label) {
4376 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4377 if (ContainsLabel(t->statement()->labels(), label)) return true;
4383 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
4385 bool anonymous = label == NULL;
4386 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4387 BreakableStatement* stat = t->statement();
4388 if ((anonymous && stat->is_target_for_anonymous()) ||
4389 (!anonymous && ContainsLabel(stat->labels(), label))) {
4397 IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
4399 bool anonymous = label == NULL;
4400 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4401 IterationStatement* stat = t->statement()->AsIterationStatement();
4402 if (stat == NULL) continue;
4404 DCHECK(stat->is_target_for_anonymous());
4405 if (anonymous || ContainsLabel(stat->labels(), label)) {
4413 void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
4414 if (scanner_.source_url()->length() > 0) {
4415 Handle<String> source_url = scanner_.source_url()->Internalize(isolate);
4416 script->set_source_url(*source_url);
4418 if (scanner_.source_mapping_url()->length() > 0) {
4419 Handle<String> source_mapping_url =
4420 scanner_.source_mapping_url()->Internalize(isolate);
4421 script->set_source_mapping_url(*source_mapping_url);
4426 void Parser::Internalize(Isolate* isolate, Handle<Script> script, bool error) {
4427 // Internalize strings.
4428 ast_value_factory()->Internalize(isolate);
4430 // Error processing.
4432 if (stack_overflow()) {
4433 isolate->StackOverflow();
4435 DCHECK(pending_error_handler_.has_pending_error());
4436 pending_error_handler_.ThrowPendingError(isolate, script);
4440 // Move statistics to Isolate.
4441 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
4443 for (int i = 0; i < use_counts_[feature]; ++i) {
4444 isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
4447 isolate->counters()->total_preparse_skipped()->Increment(
4448 total_preparse_skipped_);
4452 // ----------------------------------------------------------------------------
4453 // Regular expressions
4456 RegExpParser::RegExpParser(FlatStringReader* in, Handle<String>* error,
4457 bool multiline, bool unicode, Isolate* isolate,
4459 : isolate_(isolate),
4464 current_(kEndMarker),
4468 multiline_(multiline),
4471 contains_anchor_(false),
4472 is_scanned_for_captures_(false),
4478 uc32 RegExpParser::Next() {
4480 return in()->Get(next_pos_);
4487 void RegExpParser::Advance() {
4488 if (next_pos_ < in()->length()) {
4489 StackLimitCheck check(isolate());
4490 if (check.HasOverflowed()) {
4491 ReportError(CStrVector(Isolate::kStackOverflowMessage));
4492 } else if (zone()->excess_allocation()) {
4493 ReportError(CStrVector("Regular expression too large"));
4495 current_ = in()->Get(next_pos_);
4499 current_ = kEndMarker;
4500 // Advance so that position() points to 1-after-the-last-character. This is
4501 // important so that Reset() to this position works correctly.
4502 next_pos_ = in()->length() + 1;
4508 void RegExpParser::Reset(int pos) {
4510 has_more_ = (pos < in()->length());
4515 void RegExpParser::Advance(int dist) {
4516 next_pos_ += dist - 1;
4521 bool RegExpParser::simple() {
4526 bool RegExpParser::IsSyntaxCharacter(uc32 c) {
4527 return c == '^' || c == '$' || c == '\\' || c == '.' || c == '*' ||
4528 c == '+' || c == '?' || c == '(' || c == ')' || c == '[' || c == ']' ||
4529 c == '{' || c == '}' || c == '|';
4533 RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
4535 *error_ = isolate()->factory()->NewStringFromAscii(message).ToHandleChecked();
4536 // Zip to the end to make sure the no more input is read.
4537 current_ = kEndMarker;
4538 next_pos_ = in()->length();
4545 RegExpTree* RegExpParser::ParsePattern() {
4546 RegExpTree* result = ParseDisjunction(CHECK_FAILED);
4547 DCHECK(!has_more());
4548 // If the result of parsing is a literal string atom, and it has the
4549 // same length as the input, then the atom is identical to the input.
4550 if (result->IsAtom() && result->AsAtom()->length() == in()->length()) {
4559 // Alternative | Disjunction
4567 RegExpTree* RegExpParser::ParseDisjunction() {
4568 // Used to store current state while parsing subexpressions.
4569 RegExpParserState initial_state(NULL, INITIAL, 0, zone());
4570 RegExpParserState* stored_state = &initial_state;
4571 // Cache the builder in a local variable for quick access.
4572 RegExpBuilder* builder = initial_state.builder();
4574 switch (current()) {
4576 if (stored_state->IsSubexpression()) {
4577 // Inside a parenthesized group when hitting end of input.
4578 ReportError(CStrVector("Unterminated group") CHECK_FAILED);
4580 DCHECK_EQ(INITIAL, stored_state->group_type());
4581 // Parsing completed successfully.
4582 return builder->ToRegExp();
4584 if (!stored_state->IsSubexpression()) {
4585 ReportError(CStrVector("Unmatched ')'") CHECK_FAILED);
4587 DCHECK_NE(INITIAL, stored_state->group_type());
4590 // End disjunction parsing and convert builder content to new single
4592 RegExpTree* body = builder->ToRegExp();
4594 int end_capture_index = captures_started();
4596 int capture_index = stored_state->capture_index();
4597 SubexpressionType group_type = stored_state->group_type();
4599 // Restore previous state.
4600 stored_state = stored_state->previous_state();
4601 builder = stored_state->builder();
4603 // Build result of subexpression.
4604 if (group_type == CAPTURE) {
4605 RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index);
4606 captures_->at(capture_index - 1) = capture;
4608 } else if (group_type != GROUPING) {
4609 DCHECK(group_type == POSITIVE_LOOKAHEAD ||
4610 group_type == NEGATIVE_LOOKAHEAD);
4611 bool is_positive = (group_type == POSITIVE_LOOKAHEAD);
4612 body = new(zone()) RegExpLookahead(body,
4614 end_capture_index - capture_index,
4617 builder->AddAtom(body);
4618 // For compatability with JSC and ES3, we allow quantifiers after
4619 // lookaheads, and break in all cases.
4624 builder->NewAlternative();
4630 return ReportError(CStrVector("Nothing to repeat"));
4634 builder->AddAssertion(
4635 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE));
4637 builder->AddAssertion(
4638 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
4639 set_contains_anchor();
4645 RegExpAssertion::AssertionType assertion_type =
4646 multiline_ ? RegExpAssertion::END_OF_LINE :
4647 RegExpAssertion::END_OF_INPUT;
4648 builder->AddAssertion(new(zone()) RegExpAssertion(assertion_type));
4653 // everything except \x0a, \x0d, \u2028 and \u2029
4654 ZoneList<CharacterRange>* ranges =
4655 new(zone()) ZoneList<CharacterRange>(2, zone());
4656 CharacterRange::AddClassEscape('.', ranges, zone());
4657 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
4658 builder->AddAtom(atom);
4662 SubexpressionType subexpr_type = CAPTURE;
4664 if (current() == '?') {
4667 subexpr_type = GROUPING;
4670 subexpr_type = POSITIVE_LOOKAHEAD;
4673 subexpr_type = NEGATIVE_LOOKAHEAD;
4676 ReportError(CStrVector("Invalid group") CHECK_FAILED);
4681 if (captures_ == NULL) {
4682 captures_ = new(zone()) ZoneList<RegExpCapture*>(2, zone());
4684 if (captures_started() >= kMaxCaptures) {
4685 ReportError(CStrVector("Too many captures") CHECK_FAILED);
4687 captures_->Add(NULL, zone());
4689 // Store current state and begin new disjunction parsing.
4690 stored_state = new(zone()) RegExpParserState(stored_state, subexpr_type,
4691 captures_started(), zone());
4692 builder = stored_state->builder();
4696 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED);
4697 builder->AddAtom(atom);
4705 return ReportError(CStrVector("\\ at end of pattern"));
4708 builder->AddAssertion(
4709 new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
4713 builder->AddAssertion(
4714 new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
4717 // CharacterClassEscape
4719 // CharacterClassEscape :: one of
4721 case 'd': case 'D': case 's': case 'S': case 'w': case 'W': {
4724 ZoneList<CharacterRange>* ranges =
4725 new(zone()) ZoneList<CharacterRange>(2, zone());
4726 CharacterRange::AddClassEscape(c, ranges, zone());
4727 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
4728 builder->AddAtom(atom);
4731 case '1': case '2': case '3': case '4': case '5': case '6':
4732 case '7': case '8': case '9': {
4734 if (ParseBackReferenceIndex(&index)) {
4735 RegExpCapture* capture = NULL;
4736 if (captures_ != NULL && index <= captures_->length()) {
4737 capture = captures_->at(index - 1);
4739 if (capture == NULL) {
4740 builder->AddEmpty();
4743 RegExpTree* atom = new(zone()) RegExpBackReference(capture);
4744 builder->AddAtom(atom);
4747 uc32 first_digit = Next();
4748 if (first_digit == '8' || first_digit == '9') {
4749 // If the 'u' flag is present, only syntax characters can be escaped,
4750 // no other identity escapes are allowed. If the 'u' flag is not
4751 // present, all identity escapes are allowed.
4752 if (!FLAG_harmony_unicode_regexps || !unicode_) {
4753 builder->AddCharacter(first_digit);
4756 return ReportError(CStrVector("Invalid escape"));
4764 uc32 octal = ParseOctalLiteral();
4765 builder->AddCharacter(octal);
4768 // ControlEscape :: one of
4772 builder->AddCharacter('\f');
4776 builder->AddCharacter('\n');
4780 builder->AddCharacter('\r');
4784 builder->AddCharacter('\t');
4788 builder->AddCharacter('\v');
4792 uc32 controlLetter = Next();
4793 // Special case if it is an ASCII letter.
4794 // Convert lower case letters to uppercase.
4795 uc32 letter = controlLetter & ~('a' ^ 'A');
4796 if (letter < 'A' || 'Z' < letter) {
4797 // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
4798 // This is outside the specification. We match JSC in
4799 // reading the backslash as a literal character instead
4800 // of as starting an escape.
4801 builder->AddCharacter('\\');
4804 builder->AddCharacter(controlLetter & 0x1f);
4811 if (ParseHexEscape(2, &value)) {
4812 builder->AddCharacter(value);
4813 } else if (!FLAG_harmony_unicode_regexps || !unicode_) {
4814 builder->AddCharacter('x');
4816 // If the 'u' flag is present, invalid escapes are not treated as
4817 // identity escapes.
4818 return ReportError(CStrVector("Invalid escape"));
4825 if (ParseUnicodeEscape(&value)) {
4826 builder->AddCharacter(value);
4827 } else if (!FLAG_harmony_unicode_regexps || !unicode_) {
4828 builder->AddCharacter('u');
4830 // If the 'u' flag is present, invalid escapes are not treated as
4831 // identity escapes.
4832 return ReportError(CStrVector("Invalid unicode escape"));
4838 // If the 'u' flag is present, only syntax characters can be escaped, no
4839 // other identity escapes are allowed. If the 'u' flag is not present,
4840 // all identity escapes are allowed.
4841 if (!FLAG_harmony_unicode_regexps || !unicode_ ||
4842 IsSyntaxCharacter(current())) {
4843 builder->AddCharacter(current());
4846 return ReportError(CStrVector("Invalid escape"));
4853 if (ParseIntervalQuantifier(&dummy, &dummy)) {
4854 ReportError(CStrVector("Nothing to repeat") CHECK_FAILED);
4859 builder->AddCharacter(current());
4862 } // end switch(current())
4866 switch (current()) {
4867 // QuantifierPrefix ::
4874 max = RegExpTree::kInfinity;
4879 max = RegExpTree::kInfinity;
4888 if (ParseIntervalQuantifier(&min, &max)) {
4890 ReportError(CStrVector("numbers out of order in {} quantifier.")
4900 RegExpQuantifier::QuantifierType quantifier_type = RegExpQuantifier::GREEDY;
4901 if (current() == '?') {
4902 quantifier_type = RegExpQuantifier::NON_GREEDY;
4904 } else if (FLAG_regexp_possessive_quantifier && current() == '+') {
4905 // FLAG_regexp_possessive_quantifier is a debug-only flag.
4906 quantifier_type = RegExpQuantifier::POSSESSIVE;
4909 builder->AddQuantifierToAtom(min, max, quantifier_type);
4915 // Currently only used in an DCHECK.
4916 static bool IsSpecialClassEscape(uc32 c) {
4929 // In order to know whether an escape is a backreference or not we have to scan
4930 // the entire regexp and find the number of capturing parentheses. However we
4931 // don't want to scan the regexp twice unless it is necessary. This mini-parser
4932 // is called when needed. It can see the difference between capturing and
4933 // noncapturing parentheses and can skip character classes and backslash-escaped
4935 void RegExpParser::ScanForCaptures() {
4936 // Start with captures started previous to current position
4937 int capture_count = captures_started();
4938 // Add count of captures after this position.
4940 while ((n = current()) != kEndMarker) {
4948 while ((c = current()) != kEndMarker) {
4953 if (c == ']') break;
4959 if (current() != '?') capture_count++;
4963 capture_count_ = capture_count;
4964 is_scanned_for_captures_ = true;
4968 bool RegExpParser::ParseBackReferenceIndex(int* index_out) {
4969 DCHECK_EQ('\\', current());
4970 DCHECK('1' <= Next() && Next() <= '9');
4971 // Try to parse a decimal literal that is no greater than the total number
4972 // of left capturing parentheses in the input.
4973 int start = position();
4974 int value = Next() - '0';
4978 if (IsDecimalDigit(c)) {
4979 value = 10 * value + (c - '0');
4980 if (value > kMaxCaptures) {
4989 if (value > captures_started()) {
4990 if (!is_scanned_for_captures_) {
4991 int saved_position = position();
4993 Reset(saved_position);
4995 if (value > capture_count_) {
5005 // QuantifierPrefix ::
5006 // { DecimalDigits }
5007 // { DecimalDigits , }
5008 // { DecimalDigits , DecimalDigits }
5010 // Returns true if parsing succeeds, and set the min_out and max_out
5011 // values. Values are truncated to RegExpTree::kInfinity if they overflow.
5012 bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
5013 DCHECK_EQ(current(), '{');
5014 int start = position();
5017 if (!IsDecimalDigit(current())) {
5021 while (IsDecimalDigit(current())) {
5022 int next = current() - '0';
5023 if (min > (RegExpTree::kInfinity - next) / 10) {
5024 // Overflow. Skip past remaining decimal digits and return -1.
5027 } while (IsDecimalDigit(current()));
5028 min = RegExpTree::kInfinity;
5031 min = 10 * min + next;
5035 if (current() == '}') {
5038 } else if (current() == ',') {
5040 if (current() == '}') {
5041 max = RegExpTree::kInfinity;
5044 while (IsDecimalDigit(current())) {
5045 int next = current() - '0';
5046 if (max > (RegExpTree::kInfinity - next) / 10) {
5049 } while (IsDecimalDigit(current()));
5050 max = RegExpTree::kInfinity;
5053 max = 10 * max + next;
5056 if (current() != '}') {
5072 uc32 RegExpParser::ParseOctalLiteral() {
5073 DCHECK(('0' <= current() && current() <= '7') || current() == kEndMarker);
5074 // For compatibility with some other browsers (not all), we parse
5075 // up to three octal digits with a value below 256.
5076 uc32 value = current() - '0';
5078 if ('0' <= current() && current() <= '7') {
5079 value = value * 8 + current() - '0';
5081 if (value < 32 && '0' <= current() && current() <= '7') {
5082 value = value * 8 + current() - '0';
5090 bool RegExpParser::ParseHexEscape(int length, uc32* value) {
5091 int start = position();
5093 for (int i = 0; i < length; ++i) {
5095 int d = HexValue(c);
5108 bool RegExpParser::ParseUnicodeEscape(uc32* value) {
5109 // Accept both \uxxxx and \u{xxxxxx} (if harmony unicode escapes are
5110 // allowed). In the latter case, the number of hex digits between { } is
5111 // arbitrary. \ and u have already been read.
5112 if (current() == '{' && FLAG_harmony_unicode_regexps && unicode_) {
5113 int start = position();
5115 if (ParseUnlimitedLengthHexNumber(0x10ffff, value)) {
5116 if (current() == '}') {
5124 // \u but no {, or \u{...} escapes not allowed.
5125 return ParseHexEscape(4, value);
5129 bool RegExpParser::ParseUnlimitedLengthHexNumber(int max_value, uc32* value) {
5131 int d = HexValue(current());
5137 if (x > max_value) {
5141 d = HexValue(current());
5148 uc32 RegExpParser::ParseClassCharacterEscape() {
5149 DCHECK(current() == '\\');
5150 DCHECK(has_next() && !IsSpecialClassEscape(Next()));
5152 switch (current()) {
5156 // ControlEscape :: one of
5174 uc32 controlLetter = Next();
5175 uc32 letter = controlLetter & ~('A' ^ 'a');
5176 // For compatibility with JSC, inside a character class
5177 // we also accept digits and underscore as control characters.
5178 if ((controlLetter >= '0' && controlLetter <= '9') ||
5179 controlLetter == '_' ||
5180 (letter >= 'A' && letter <= 'Z')) {
5182 // Control letters mapped to ASCII control characters in the range
5184 return controlLetter & 0x1f;
5186 // We match JSC in reading the backslash as a literal
5187 // character instead of as starting an escape.
5190 case '0': case '1': case '2': case '3': case '4': case '5':
5192 // For compatibility, we interpret a decimal escape that isn't
5193 // a back reference (and therefore either \0 or not valid according
5194 // to the specification) as a 1..3 digit octal character code.
5195 return ParseOctalLiteral();
5199 if (ParseHexEscape(2, &value)) {
5202 if (!FLAG_harmony_unicode_regexps || !unicode_) {
5203 // If \x is not followed by a two-digit hexadecimal, treat it
5204 // as an identity escape.
5207 // If the 'u' flag is present, invalid escapes are not treated as
5208 // identity escapes.
5209 ReportError(CStrVector("Invalid escape"));
5215 if (ParseUnicodeEscape(&value)) {
5218 if (!FLAG_harmony_unicode_regexps || !unicode_) {
5221 // If the 'u' flag is present, invalid escapes are not treated as
5222 // identity escapes.
5223 ReportError(CStrVector("Invalid unicode escape"));
5227 uc32 result = current();
5228 // If the 'u' flag is present, only syntax characters can be escaped, no
5229 // other identity escapes are allowed. If the 'u' flag is not present, all
5230 // identity escapes are allowed.
5231 if (!FLAG_harmony_unicode_regexps || !unicode_ ||
5232 IsSyntaxCharacter(result)) {
5236 ReportError(CStrVector("Invalid escape"));
5244 CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) {
5245 DCHECK_EQ(0, *char_class);
5246 uc32 first = current();
5247 if (first == '\\') {
5249 case 'w': case 'W': case 'd': case 'D': case 's': case 'S': {
5250 *char_class = Next();
5252 return CharacterRange::Singleton(0); // Return dummy value.
5255 return ReportError(CStrVector("\\ at end of pattern"));
5257 uc32 c = ParseClassCharacterEscape(CHECK_FAILED);
5258 return CharacterRange::Singleton(c);
5262 return CharacterRange::Singleton(first);
5267 static const uc16 kNoCharClass = 0;
5269 // Adds range or pre-defined character class to character ranges.
5270 // If char_class is not kInvalidClass, it's interpreted as a class
5271 // escape (i.e., 's' means whitespace, from '\s').
5272 static inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges,
5274 CharacterRange range,
5276 if (char_class != kNoCharClass) {
5277 CharacterRange::AddClassEscape(char_class, ranges, zone);
5279 ranges->Add(range, zone);
5284 RegExpTree* RegExpParser::ParseCharacterClass() {
5285 static const char* kUnterminated = "Unterminated character class";
5286 static const char* kRangeOutOfOrder = "Range out of order in character class";
5288 DCHECK_EQ(current(), '[');
5290 bool is_negated = false;
5291 if (current() == '^') {
5295 ZoneList<CharacterRange>* ranges =
5296 new(zone()) ZoneList<CharacterRange>(2, zone());
5297 while (has_more() && current() != ']') {
5298 uc16 char_class = kNoCharClass;
5299 CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED);
5300 if (current() == '-') {
5302 if (current() == kEndMarker) {
5303 // If we reach the end we break out of the loop and let the
5304 // following code report an error.
5306 } else if (current() == ']') {
5307 AddRangeOrEscape(ranges, char_class, first, zone());
5308 ranges->Add(CharacterRange::Singleton('-'), zone());
5311 uc16 char_class_2 = kNoCharClass;
5312 CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED);
5313 if (char_class != kNoCharClass || char_class_2 != kNoCharClass) {
5314 // Either end is an escaped character class. Treat the '-' verbatim.
5315 AddRangeOrEscape(ranges, char_class, first, zone());
5316 ranges->Add(CharacterRange::Singleton('-'), zone());
5317 AddRangeOrEscape(ranges, char_class_2, next, zone());
5320 if (first.from() > next.to()) {
5321 return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED);
5323 ranges->Add(CharacterRange::Range(first.from(), next.to()), zone());
5325 AddRangeOrEscape(ranges, char_class, first, zone());
5329 return ReportError(CStrVector(kUnterminated) CHECK_FAILED);
5332 if (ranges->length() == 0) {
5333 ranges->Add(CharacterRange::Everything(), zone());
5334 is_negated = !is_negated;
5336 return new(zone()) RegExpCharacterClass(ranges, is_negated);
5340 // ----------------------------------------------------------------------------
5341 // The Parser interface.
5343 bool RegExpParser::ParseRegExp(Isolate* isolate, Zone* zone,
5344 FlatStringReader* input, bool multiline,
5345 bool unicode, RegExpCompileData* result) {
5346 DCHECK(result != NULL);
5347 RegExpParser parser(input, &result->error, multiline, unicode, isolate, zone);
5348 RegExpTree* tree = parser.ParsePattern();
5349 if (parser.failed()) {
5350 DCHECK(tree == NULL);
5351 DCHECK(!result->error.is_null());
5353 DCHECK(tree != NULL);
5354 DCHECK(result->error.is_null());
5355 result->tree = tree;
5356 int capture_count = parser.captures_started();
5357 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
5358 result->contains_anchor = parser.contains_anchor();
5359 result->capture_count = capture_count;
5361 return !parser.failed();
5365 bool Parser::ParseStatic(ParseInfo* info) {
5366 Parser parser(info);
5367 if (parser.Parse(info)) {
5368 info->set_language_mode(info->function()->language_mode());
5375 bool Parser::Parse(ParseInfo* info) {
5376 DCHECK(info->function() == NULL);
5377 FunctionLiteral* result = NULL;
5378 // Ok to use Isolate here; this function is only called in the main thread.
5379 DCHECK(parsing_on_main_thread_);
5380 Isolate* isolate = info->isolate();
5381 pre_parse_timer_ = isolate->counters()->pre_parse();
5382 if (FLAG_trace_parse || allow_natives() || extension_ != NULL) {
5383 // If intrinsics are allowed, the Parser cannot operate independent of the
5384 // V8 heap because of Runtime. Tell the string table to internalize strings
5385 // and values right after they're created.
5386 ast_value_factory()->Internalize(isolate);
5389 if (info->is_lazy()) {
5390 DCHECK(!info->is_eval());
5391 if (info->shared_info()->is_function()) {
5392 result = ParseLazy(isolate, info);
5394 result = ParseProgram(isolate, info);
5397 SetCachedData(info);
5398 result = ParseProgram(isolate, info);
5400 info->set_literal(result);
5402 Internalize(isolate, info->script(), result == NULL);
5403 DCHECK(ast_value_factory()->IsInternalized());
5404 return (result != NULL);
5408 void Parser::ParseOnBackground(ParseInfo* info) {
5409 parsing_on_main_thread_ = false;
5411 DCHECK(info->function() == NULL);
5412 FunctionLiteral* result = NULL;
5413 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
5415 CompleteParserRecorder recorder;
5416 if (produce_cached_parse_data()) log_ = &recorder;
5418 DCHECK(info->source_stream() != NULL);
5419 ExternalStreamingStream stream(info->source_stream(),
5420 info->source_stream_encoding());
5421 scanner_.Initialize(&stream);
5422 DCHECK(info->context().is_null() || info->context()->IsNativeContext());
5424 // When streaming, we don't know the length of the source until we have parsed
5425 // it. The raw data can be UTF-8, so we wouldn't know the source length until
5426 // we have decoded it anyway even if we knew the raw data length (which we
5427 // don't). We work around this by storing all the scopes which need their end
5428 // position set at the end of the script (the top scope and possible eval
5429 // scopes) and set their end position after we know the script length.
5430 Scope* top_scope = NULL;
5431 Scope* eval_scope = NULL;
5432 result = DoParseProgram(info, &top_scope, &eval_scope);
5434 top_scope->set_end_position(scanner()->location().end_pos);
5435 if (eval_scope != NULL) {
5436 eval_scope->set_end_position(scanner()->location().end_pos);
5439 info->set_literal(result);
5441 // We cannot internalize on a background thread; a foreground task will take
5442 // care of calling Parser::Internalize just before compilation.
5444 if (produce_cached_parse_data()) {
5445 if (result != NULL) *info->cached_data() = recorder.GetScriptData();
5451 ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
5452 return new (zone()) ParserTraits::TemplateLiteral(zone(), pos);
5456 void Parser::AddTemplateSpan(TemplateLiteralState* state, bool tail) {
5457 int pos = scanner()->location().beg_pos;
5458 int end = scanner()->location().end_pos - (tail ? 1 : 2);
5459 const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory());
5460 const AstRawString* trv = scanner()->CurrentRawSymbol(ast_value_factory());
5461 Literal* cooked = factory()->NewStringLiteral(tv, pos);
5462 Literal* raw = factory()->NewStringLiteral(trv, pos);
5463 (*state)->AddTemplateSpan(cooked, raw, end, zone());
5467 void Parser::AddTemplateExpression(TemplateLiteralState* state,
5468 Expression* expression) {
5469 (*state)->AddExpression(expression, zone());
5473 Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
5475 TemplateLiteral* lit = *state;
5476 int pos = lit->position();
5477 const ZoneList<Expression*>* cooked_strings = lit->cooked();
5478 const ZoneList<Expression*>* raw_strings = lit->raw();
5479 const ZoneList<Expression*>* expressions = lit->expressions();
5480 DCHECK_EQ(cooked_strings->length(), raw_strings->length());
5481 DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
5484 // Build tree of BinaryOps to simplify code-generation
5485 Expression* expr = cooked_strings->at(0);
5487 while (i < expressions->length()) {
5488 Expression* sub = expressions->at(i++);
5489 Expression* cooked_str = cooked_strings->at(i);
5491 // Let middle be ToString(sub).
5492 ZoneList<Expression*>* args =
5493 new (zone()) ZoneList<Expression*>(1, zone());
5494 args->Add(sub, zone());
5495 Expression* middle = factory()->NewCallRuntime(
5496 ast_value_factory()->to_string_string(), NULL, args,
5499 expr = factory()->NewBinaryOperation(
5500 Token::ADD, factory()->NewBinaryOperation(
5501 Token::ADD, expr, middle, expr->position()),
5502 cooked_str, sub->position());
5506 uint32_t hash = ComputeTemplateLiteralHash(lit);
5508 int cooked_idx = function_state_->NextMaterializedLiteralIndex();
5509 int raw_idx = function_state_->NextMaterializedLiteralIndex();
5511 // GetTemplateCallSite
5512 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone());
5513 args->Add(factory()->NewArrayLiteral(
5514 const_cast<ZoneList<Expression*>*>(cooked_strings),
5518 factory()->NewArrayLiteral(
5519 const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx, pos),
5522 // Ensure hash is suitable as a Smi value
5523 Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash)));
5524 args->Add(factory()->NewSmiLiteral(hash_obj->value(), pos), zone());
5526 this->CheckPossibleEvalCall(tag, scope_);
5527 Expression* call_site = factory()->NewCallRuntime(
5528 ast_value_factory()->get_template_callsite_string(), NULL, args, start);
5531 ZoneList<Expression*>* call_args =
5532 new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone());
5533 call_args->Add(call_site, zone());
5534 call_args->AddAll(*expressions, zone());
5535 return factory()->NewCall(tag, call_args, pos);
5540 uint32_t Parser::ComputeTemplateLiteralHash(const TemplateLiteral* lit) {
5541 const ZoneList<Expression*>* raw_strings = lit->raw();
5542 int total = raw_strings->length();
5545 uint32_t running_hash = 0;
5547 for (int index = 0; index < total; ++index) {
5549 running_hash = StringHasher::ComputeRunningHashOneByte(
5550 running_hash, "${}", 3);
5553 const AstRawString* raw_string =
5554 raw_strings->at(index)->AsLiteral()->raw_value()->AsString();
5555 if (raw_string->is_one_byte()) {
5556 const char* data = reinterpret_cast<const char*>(raw_string->raw_data());
5557 running_hash = StringHasher::ComputeRunningHashOneByte(
5558 running_hash, data, raw_string->length());
5560 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
5561 running_hash = StringHasher::ComputeRunningHash(running_hash, data,
5562 raw_string->length());
5566 return running_hash;
5568 } } // namespace v8::internal