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.h"
19 #include "src/scanner-character-streams.h"
20 #include "src/scopeinfo.h"
21 #include "src/string-stream.h"
26 RegExpBuilder::RegExpBuilder(Zone* zone)
28 pending_empty_(false),
33 , last_added_(ADD_NONE)
38 void RegExpBuilder::FlushCharacters() {
39 pending_empty_ = false;
40 if (characters_ != NULL) {
41 RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector());
43 text_.Add(atom, zone());
49 void RegExpBuilder::FlushText() {
51 int num_text = text_.length();
54 } else if (num_text == 1) {
55 terms_.Add(text_.last(), zone());
57 RegExpText* text = new(zone()) RegExpText(zone());
58 for (int i = 0; i < num_text; i++)
59 text_.Get(i)->AppendToText(text, zone());
60 terms_.Add(text, zone());
66 void RegExpBuilder::AddCharacter(uc16 c) {
67 pending_empty_ = false;
68 if (characters_ == NULL) {
69 characters_ = new(zone()) ZoneList<uc16>(4, zone());
71 characters_->Add(c, zone());
76 void RegExpBuilder::AddEmpty() {
77 pending_empty_ = true;
81 void RegExpBuilder::AddAtom(RegExpTree* term) {
82 if (term->IsEmpty()) {
86 if (term->IsTextElement()) {
88 text_.Add(term, zone());
91 terms_.Add(term, zone());
97 void RegExpBuilder::AddAssertion(RegExpTree* assert) {
99 terms_.Add(assert, zone());
104 void RegExpBuilder::NewAlternative() {
109 void RegExpBuilder::FlushTerms() {
111 int num_terms = terms_.length();
112 RegExpTree* alternative;
113 if (num_terms == 0) {
114 alternative = RegExpEmpty::GetInstance();
115 } else if (num_terms == 1) {
116 alternative = terms_.last();
118 alternative = new(zone()) RegExpAlternative(terms_.GetList(zone()));
120 alternatives_.Add(alternative, zone());
126 RegExpTree* RegExpBuilder::ToRegExp() {
128 int num_alternatives = alternatives_.length();
129 if (num_alternatives == 0) {
130 return RegExpEmpty::GetInstance();
132 if (num_alternatives == 1) {
133 return alternatives_.last();
135 return new(zone()) RegExpDisjunction(alternatives_.GetList(zone()));
139 void RegExpBuilder::AddQuantifierToAtom(
140 int min, int max, RegExpQuantifier::QuantifierType quantifier_type) {
141 if (pending_empty_) {
142 pending_empty_ = false;
146 if (characters_ != NULL) {
147 DCHECK(last_added_ == ADD_CHAR);
148 // Last atom was character.
149 Vector<const uc16> char_vector = characters_->ToConstVector();
150 int num_chars = char_vector.length();
152 Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1);
153 text_.Add(new(zone()) RegExpAtom(prefix), zone());
154 char_vector = char_vector.SubVector(num_chars - 1, num_chars);
157 atom = new(zone()) RegExpAtom(char_vector);
159 } else if (text_.length() > 0) {
160 DCHECK(last_added_ == ADD_ATOM);
161 atom = text_.RemoveLast();
163 } else if (terms_.length() > 0) {
164 DCHECK(last_added_ == ADD_ATOM);
165 atom = terms_.RemoveLast();
166 if (atom->max_match() == 0) {
167 // Guaranteed to only match an empty string.
172 terms_.Add(atom, zone());
176 // Only call immediately after adding an atom or character!
181 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone());
186 FunctionEntry ParseData::GetFunctionEntry(int start) {
187 // The current pre-data entry must be a FunctionEntry with the given
189 if ((function_index_ + FunctionEntry::kSize <= Length()) &&
190 (static_cast<int>(Data()[function_index_]) == start)) {
191 int index = function_index_;
192 function_index_ += FunctionEntry::kSize;
193 Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize);
194 return FunctionEntry(subvector);
196 return FunctionEntry();
200 int ParseData::FunctionCount() {
201 int functions_size = FunctionsSize();
202 if (functions_size < 0) return 0;
203 if (functions_size % FunctionEntry::kSize != 0) return 0;
204 return functions_size / FunctionEntry::kSize;
208 bool ParseData::IsSane() {
209 // Check that the header data is valid and doesn't specify
210 // point to positions outside the store.
211 int data_length = Length();
212 if (data_length < PreparseDataConstants::kHeaderSize) return false;
213 if (Magic() != PreparseDataConstants::kMagicNumber) return false;
214 if (Version() != PreparseDataConstants::kCurrentVersion) return false;
215 if (HasError()) return false;
216 // Check that the space allocated for function entries is sane.
217 int functions_size = FunctionsSize();
218 if (functions_size < 0) return false;
219 if (functions_size % FunctionEntry::kSize != 0) return false;
220 // Check that the total size has room for header and function entries.
222 PreparseDataConstants::kHeaderSize + functions_size;
223 if (data_length < minimum_size) return false;
228 void ParseData::Initialize() {
229 // Prepares state for use.
230 int data_length = Length();
231 if (data_length >= PreparseDataConstants::kHeaderSize) {
232 function_index_ = PreparseDataConstants::kHeaderSize;
237 bool ParseData::HasError() {
238 return Data()[PreparseDataConstants::kHasErrorOffset];
242 unsigned ParseData::Magic() {
243 return Data()[PreparseDataConstants::kMagicOffset];
247 unsigned ParseData::Version() {
248 return Data()[PreparseDataConstants::kVersionOffset];
252 int ParseData::FunctionsSize() {
253 return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]);
257 void Parser::SetCachedData() {
258 if (compile_options() == ScriptCompiler::kNoCompileOptions) {
259 cached_parse_data_ = NULL;
261 DCHECK(info_->cached_data() != NULL);
262 if (compile_options() == ScriptCompiler::kConsumeParserCache) {
263 cached_parse_data_ = new ParseData(*info_->cached_data());
269 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) {
270 DCHECK(ast_value_factory());
272 new (zone()) Scope(parent, scope_type, ast_value_factory(), zone());
273 result->Initialize();
278 // ----------------------------------------------------------------------------
279 // Target is a support class to facilitate manipulation of the
280 // Parser's target_stack_ (the stack of potential 'break' and
281 // 'continue' statement targets). Upon construction, a new target is
282 // added; it is removed upon destruction.
284 class Target BASE_EMBEDDED {
286 Target(Target** variable, AstNode* node)
287 : variable_(variable), node_(node), previous_(*variable) {
292 *variable_ = previous_;
295 Target* previous() { return previous_; }
296 AstNode* node() { return node_; }
305 class TargetScope BASE_EMBEDDED {
307 explicit TargetScope(Target** variable)
308 : variable_(variable), previous_(*variable) {
313 *variable_ = previous_;
322 // ----------------------------------------------------------------------------
323 // The CHECK_OK macro is a convenient macro to enforce error
324 // handling for functions that may fail (by returning !*ok).
326 // CAUTION: This macro appends extra statements after a call,
327 // thus it must never be used where only a single statement
328 // is correct (e.g. an if statement branch w/o braces)!
330 #define CHECK_OK ok); \
331 if (!*ok) return NULL; \
333 #define DUMMY ) // to make indentation work
336 #define CHECK_FAILED /**/); \
337 if (failed_) return NULL; \
339 #define DUMMY ) // to make indentation work
342 // ----------------------------------------------------------------------------
343 // Implementation of Parser
345 class ParserTraits::Checkpoint
346 : public ParserBase<ParserTraits>::CheckpointBase {
348 explicit Checkpoint(ParserBase<ParserTraits>* parser)
349 : CheckpointBase(parser), parser_(parser) {
350 saved_ast_node_id_gen_ = *parser_->ast_node_id_gen_;
354 CheckpointBase::Restore();
355 *parser_->ast_node_id_gen_ = saved_ast_node_id_gen_;
359 ParserBase<ParserTraits>* parser_;
360 AstNode::IdGen saved_ast_node_id_gen_;
364 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const {
365 return identifier == parser_->ast_value_factory()->eval_string() ||
366 identifier == parser_->ast_value_factory()->arguments_string();
370 bool ParserTraits::IsPrototype(const AstRawString* identifier) const {
371 return identifier == parser_->ast_value_factory()->prototype_string();
375 bool ParserTraits::IsConstructor(const AstRawString* identifier) const {
376 return identifier == parser_->ast_value_factory()->constructor_string();
380 bool ParserTraits::IsThisProperty(Expression* expression) {
381 DCHECK(expression != NULL);
382 Property* property = expression->AsProperty();
383 return property != NULL &&
384 property->obj()->AsVariableProxy() != NULL &&
385 property->obj()->AsVariableProxy()->is_this();
389 bool ParserTraits::IsIdentifier(Expression* expression) {
390 VariableProxy* operand = expression->AsVariableProxy();
391 return operand != NULL && !operand->is_this();
395 void ParserTraits::PushPropertyName(FuncNameInferrer* fni,
396 Expression* expression) {
397 if (expression->IsPropertyName()) {
398 fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
400 fni->PushLiteralName(
401 parser_->ast_value_factory()->anonymous_function_string());
406 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
408 DCHECK(left != NULL);
409 if (left->AsProperty() != NULL &&
410 right->AsFunctionLiteral() != NULL) {
411 right->AsFunctionLiteral()->set_pretenure();
416 void ParserTraits::CheckPossibleEvalCall(Expression* expression,
418 VariableProxy* callee = expression->AsVariableProxy();
419 if (callee != NULL &&
420 callee->raw_name() == parser_->ast_value_factory()->eval_string()) {
421 scope->DeclarationScope()->RecordEvalCall();
426 Expression* ParserTraits::MarkExpressionAsAssigned(Expression* expression) {
427 VariableProxy* proxy =
428 expression != NULL ? expression->AsVariableProxy() : NULL;
429 if (proxy != NULL) proxy->set_is_assigned();
434 bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
435 Expression** x, Expression* y, Token::Value op, int pos,
436 AstNodeFactory<AstConstructionVisitor>* factory) {
437 if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
438 y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) {
439 double x_val = (*x)->AsLiteral()->raw_value()->AsNumber();
440 double y_val = y->AsLiteral()->raw_value()->AsNumber();
443 *x = factory->NewNumberLiteral(x_val + y_val, pos);
446 *x = factory->NewNumberLiteral(x_val - y_val, pos);
449 *x = factory->NewNumberLiteral(x_val * y_val, pos);
452 *x = factory->NewNumberLiteral(x_val / y_val, pos);
454 case Token::BIT_OR: {
455 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
456 *x = factory->NewNumberLiteral(value, pos);
459 case Token::BIT_AND: {
460 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
461 *x = factory->NewNumberLiteral(value, pos);
464 case Token::BIT_XOR: {
465 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
466 *x = factory->NewNumberLiteral(value, pos);
470 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
471 *x = factory->NewNumberLiteral(value, pos);
475 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
476 uint32_t value = DoubleToUint32(x_val) >> shift;
477 *x = factory->NewNumberLiteral(value, pos);
481 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
482 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
483 *x = factory->NewNumberLiteral(value, pos);
494 bool ParserTraits::BuildSIMD128LoadStoreExpression(
495 Expression** expression, ZoneList<Expression*>* arguments, int pos,
496 AstNodeFactory<AstConstructionVisitor>* factory) {
497 Property* prop = (*expression)->AsProperty();
498 Expression* tarray_op_literal = NULL;
501 Property* simd_type_prop = prop->obj()->AsProperty();
502 if (simd_type_prop) {
503 VariableProxy* simd_var = simd_type_prop->obj()->AsVariableProxy();
504 if (simd_var && simd_var->raw_name() &&
505 simd_var->raw_name()->IsOneByteEqualTo("SIMD")) {
506 Literal* type_literal = simd_type_prop->key()->AsLiteral();
507 if (type_literal && type_literal->raw_value() &&
508 type_literal->raw_value()->AsString()) {
509 const AstRawString* type_literal_raw_string =
510 type_literal->raw_value()->AsString();
511 if (type_literal_raw_string->IsOneByteEqualTo("float32x4")) {
512 Literal* op_literal = prop->key()->AsLiteral();
513 if (op_literal && op_literal->raw_value() &&
514 op_literal->raw_value()->AsString()) {
515 const AstRawString* op_raw_string =
516 op_literal->raw_value()->AsString();
517 AstValueFactory* ast_factory = parser_->ast_value_factory();
518 if (op_raw_string->IsOneByteEqualTo("load")) {
519 const AstRawString* op_str =
520 ast_factory->GetOneByteString("_getFloat32x4XYZW");
522 factory->NewStringLiteral(op_str, RelocInfo::kNoPosition);
523 } else if (op_raw_string->IsOneByteEqualTo("loadX")) {
524 const AstRawString* op_str =
525 ast_factory->GetOneByteString("_getFloat32x4X");
527 factory->NewStringLiteral(op_str, RelocInfo::kNoPosition);
528 } else if (op_raw_string->IsOneByteEqualTo("loadXY")) {
529 const AstRawString* op_str =
530 ast_factory->GetOneByteString("_getFloat32x4XY");
532 factory->NewStringLiteral(op_str, RelocInfo::kNoPosition);
533 } else if (op_raw_string->IsOneByteEqualTo("loadXYZ")) {
534 const AstRawString* op_str =
535 ast_factory->GetOneByteString("_getFloat32x4XYZ");
537 factory->NewStringLiteral(op_str, RelocInfo::kNoPosition);
538 } else if (op_raw_string->IsOneByteEqualTo("store")) {
539 const AstRawString* op_str =
540 ast_factory->GetOneByteString("_setFloat32x4XYZW");
542 factory->NewStringLiteral(op_str, RelocInfo::kNoPosition);
543 } else if (op_raw_string->IsOneByteEqualTo("storeX")) {
544 const AstRawString* op_str =
545 ast_factory->GetOneByteString("_setFloat32x4X");
547 factory->NewStringLiteral(op_str, RelocInfo::kNoPosition);
548 } else if (op_raw_string->IsOneByteEqualTo("storeXY")) {
549 const AstRawString* op_str =
550 ast_factory->GetOneByteString("_setFloat32x4XY");
552 factory->NewStringLiteral(op_str, RelocInfo::kNoPosition);
553 } else if (op_raw_string->IsOneByteEqualTo("storeXYZ")) {
554 const AstRawString* op_str =
555 ast_factory->GetOneByteString("_setFloat32x4XYZ");
557 factory->NewStringLiteral(op_str, RelocInfo::kNoPosition);
560 } else if (type_literal_raw_string->IsOneByteEqualTo("int32x4")) {
561 Literal* op_literal = prop->key()->AsLiteral();
562 if (op_literal && op_literal->raw_value() &&
563 op_literal->raw_value()->AsString()) {
564 const AstRawString* op_raw_string =
565 op_literal->raw_value()->AsString();
566 AstValueFactory* ast_factory = parser_->ast_value_factory();
567 if (op_raw_string->IsOneByteEqualTo("load")) {
568 const AstRawString* op_str =
569 ast_factory->GetOneByteString("_getInt32x4XYZW");
571 factory->NewStringLiteral(op_str, RelocInfo::kNoPosition);
572 } else if (op_raw_string->IsOneByteEqualTo("loadX")) {
573 const AstRawString* op_str =
574 ast_factory->GetOneByteString("_getInt32x4X");
576 factory->NewStringLiteral(op_str, RelocInfo::kNoPosition);
577 } else if (op_raw_string->IsOneByteEqualTo("loadXY")) {
578 const AstRawString* op_str =
579 ast_factory->GetOneByteString("_getInt32x4XY");
581 factory->NewStringLiteral(op_str, RelocInfo::kNoPosition);
582 } else if (op_raw_string->IsOneByteEqualTo("loadXYZ")) {
583 const AstRawString* op_str =
584 ast_factory->GetOneByteString("_getInt32x4XYZ");
586 factory->NewStringLiteral(op_str, RelocInfo::kNoPosition);
587 } else if (op_raw_string->IsOneByteEqualTo("store")) {
588 const AstRawString* op_str =
589 ast_factory->GetOneByteString("_setInt32x4XYZW");
591 factory->NewStringLiteral(op_str, RelocInfo::kNoPosition);
592 } else if (op_raw_string->IsOneByteEqualTo("storeX")) {
593 const AstRawString* op_str =
594 ast_factory->GetOneByteString("_setInt32x4X");
596 factory->NewStringLiteral(op_str, RelocInfo::kNoPosition);
597 } else if (op_raw_string->IsOneByteEqualTo("storeXY")) {
598 const AstRawString* op_str =
599 ast_factory->GetOneByteString("_setInt32x4XY");
601 factory->NewStringLiteral(op_str, RelocInfo::kNoPosition);
602 } else if (op_raw_string->IsOneByteEqualTo("storeXYZ")) {
603 const AstRawString* op_str =
604 ast_factory->GetOneByteString("_setInt32x4XYZ");
606 factory->NewStringLiteral(op_str, RelocInfo::kNoPosition);
609 } else if (type_literal_raw_string->IsOneByteEqualTo("float64x2")) {
610 Literal* op_literal = prop->key()->AsLiteral();
611 if (op_literal && op_literal->raw_value() &&
612 op_literal->raw_value()->AsString()) {
613 const AstRawString* op_raw_string =
614 op_literal->raw_value()->AsString();
615 AstValueFactory* ast_factory = parser_->ast_value_factory();
616 if (op_raw_string->IsOneByteEqualTo("load")) {
617 const AstRawString* op_str =
618 ast_factory->GetOneByteString("_getFloat64x2XY");
620 factory->NewStringLiteral(op_str, RelocInfo::kNoPosition);
621 } else if (op_raw_string->IsOneByteEqualTo("loadX")) {
622 const AstRawString* op_str =
623 ast_factory->GetOneByteString("_getFloat64x2X");
625 factory->NewStringLiteral(op_str, RelocInfo::kNoPosition);
626 } else if (op_raw_string->IsOneByteEqualTo("store")) {
627 const AstRawString* op_str =
628 ast_factory->GetOneByteString("_setFloat64x2XY");
630 factory->NewStringLiteral(op_str, RelocInfo::kNoPosition);
631 } else if (op_raw_string->IsOneByteEqualTo("storeX")) {
632 const AstRawString* op_str =
633 ast_factory->GetOneByteString("_setFloat64x2X");
635 factory->NewStringLiteral(op_str, RelocInfo::kNoPosition);
644 if (tarray_op_literal) {
645 if (arguments && arguments->length() == 2) {
646 Expression* tarray = arguments->at(0);
647 Expression* index = arguments->at(1);
648 Expression* tarray_op =
649 factory->NewProperty(tarray, tarray_op_literal, pos);
650 Zone* zone = parser_->zone();
651 ZoneList<Expression*>* tarray_op_args =
652 new (zone) ZoneList<Expression*>(1, zone);
653 tarray_op_args->Add(index, zone);
654 *expression = factory->NewCall(tarray_op, tarray_op_args, pos);
656 } else if (arguments && arguments->length() == 3) {
657 Expression* tarray = arguments->at(0);
658 Expression* index = arguments->at(1);
659 Expression* value = arguments->at(2);
660 Expression* tarray_op =
661 factory->NewProperty(tarray, tarray_op_literal, pos);
662 Zone* zone = parser_->zone();
663 ZoneList<Expression*>* tarray_op_args =
664 new (zone) ZoneList<Expression*>(1, zone);
665 tarray_op_args->Add(index, zone);
666 tarray_op_args->Add(value, zone);
667 *expression = factory->NewCall(tarray_op, tarray_op_args, pos);
675 Expression* ParserTraits::BuildUnaryExpression(
676 Expression* expression, Token::Value op, int pos,
677 AstNodeFactory<AstConstructionVisitor>* factory) {
678 DCHECK(expression != NULL);
679 if (expression->IsLiteral()) {
680 const AstValue* literal = expression->AsLiteral()->raw_value();
681 if (op == Token::NOT) {
682 // Convert the literal to a boolean condition and negate it.
683 bool condition = literal->BooleanValue();
684 return factory->NewBooleanLiteral(!condition, pos);
685 } else if (literal->IsNumber()) {
686 // Compute some expressions involving only number literals.
687 double value = literal->AsNumber();
692 return factory->NewNumberLiteral(-value, pos);
694 return factory->NewNumberLiteral(~DoubleToInt32(value), pos);
700 // Desugar '+foo' => 'foo*1'
701 if (op == Token::ADD) {
702 return factory->NewBinaryOperation(
703 Token::MUL, expression, factory->NewNumberLiteral(1, pos), pos);
705 // The same idea for '-foo' => 'foo*(-1)'.
706 if (op == Token::SUB) {
707 return factory->NewBinaryOperation(
708 Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos);
710 // ...and one more time for '~foo' => 'foo^(~0)'.
711 if (op == Token::BIT_NOT) {
712 return factory->NewBinaryOperation(
713 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos);
715 return factory->NewUnaryOperation(op, expression, pos);
719 Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) {
720 return NewThrowError(
721 parser_->ast_value_factory()->make_reference_error_string(), message,
726 Expression* ParserTraits::NewThrowSyntaxError(
727 const char* message, const AstRawString* arg, int pos) {
728 return NewThrowError(parser_->ast_value_factory()->make_syntax_error_string(),
733 Expression* ParserTraits::NewThrowTypeError(
734 const char* message, const AstRawString* arg, int pos) {
735 return NewThrowError(parser_->ast_value_factory()->make_type_error_string(),
740 Expression* ParserTraits::NewThrowError(
741 const AstRawString* constructor, const char* message,
742 const AstRawString* arg, int pos) {
743 Zone* zone = parser_->zone();
744 int argc = arg != NULL ? 1 : 0;
745 const AstRawString* type =
746 parser_->ast_value_factory()->GetOneByteString(message);
747 ZoneList<const AstRawString*>* array =
748 new (zone) ZoneList<const AstRawString*>(argc, zone);
750 array->Add(arg, zone);
752 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone);
753 args->Add(parser_->factory()->NewStringLiteral(type, pos), zone);
754 args->Add(parser_->factory()->NewStringListLiteral(array, pos), zone);
755 CallRuntime* call_constructor =
756 parser_->factory()->NewCallRuntime(constructor, NULL, args, pos);
757 return parser_->factory()->NewThrow(call_constructor, pos);
761 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
764 bool is_reference_error) {
765 if (parser_->stack_overflow()) {
766 // Suppress the error message (syntax error or such) in the presence of a
767 // stack overflow. The isolate allows only one pending exception at at time
768 // and we want to report the stack overflow later.
771 parser_->has_pending_error_ = true;
772 parser_->pending_error_location_ = source_location;
773 parser_->pending_error_message_ = message;
774 parser_->pending_error_char_arg_ = arg;
775 parser_->pending_error_arg_ = NULL;
776 parser_->pending_error_is_reference_error_ = is_reference_error;
780 void ParserTraits::ReportMessage(const char* message,
782 bool is_reference_error) {
783 Scanner::Location source_location = parser_->scanner()->location();
784 ReportMessageAt(source_location, message, arg, is_reference_error);
788 void ParserTraits::ReportMessage(const char* message,
789 const AstRawString* arg,
790 bool is_reference_error) {
791 Scanner::Location source_location = parser_->scanner()->location();
792 ReportMessageAt(source_location, message, arg, is_reference_error);
796 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
798 const AstRawString* arg,
799 bool is_reference_error) {
800 if (parser_->stack_overflow()) {
801 // Suppress the error message (syntax error or such) in the presence of a
802 // stack overflow. The isolate allows only one pending exception at at time
803 // and we want to report the stack overflow later.
806 parser_->has_pending_error_ = true;
807 parser_->pending_error_location_ = source_location;
808 parser_->pending_error_message_ = message;
809 parser_->pending_error_char_arg_ = NULL;
810 parser_->pending_error_arg_ = arg;
811 parser_->pending_error_is_reference_error_ = is_reference_error;
815 const AstRawString* ParserTraits::GetSymbol(Scanner* scanner) {
816 const AstRawString* result =
817 parser_->scanner()->CurrentSymbol(parser_->ast_value_factory());
818 DCHECK(result != NULL);
823 const AstRawString* ParserTraits::GetNumberAsSymbol(Scanner* scanner) {
824 double double_value = parser_->scanner()->DoubleValue();
827 DoubleToCString(double_value, Vector<char>(array, arraysize(array)));
828 return ast_value_factory()->GetOneByteString(string);
832 const AstRawString* ParserTraits::GetNextSymbol(Scanner* scanner) {
833 return parser_->scanner()->NextSymbol(parser_->ast_value_factory());
837 Expression* ParserTraits::ThisExpression(
838 Scope* scope, AstNodeFactory<AstConstructionVisitor>* factory, int pos) {
839 return factory->NewVariableProxy(scope->receiver(), pos);
842 Expression* ParserTraits::SuperReference(
843 Scope* scope, AstNodeFactory<AstConstructionVisitor>* factory, int pos) {
844 return factory->NewSuperReference(
845 ThisExpression(scope, factory, pos)->AsVariableProxy(),
849 Expression* ParserTraits::ClassLiteral(
850 const AstRawString* name, Expression* extends, Expression* constructor,
851 ZoneList<ObjectLiteral::Property*>* properties, int pos,
852 AstNodeFactory<AstConstructionVisitor>* factory) {
853 return factory->NewClassLiteral(name, extends, constructor, properties, pos);
856 Literal* ParserTraits::ExpressionFromLiteral(
857 Token::Value token, int pos,
859 AstNodeFactory<AstConstructionVisitor>* factory) {
861 case Token::NULL_LITERAL:
862 return factory->NewNullLiteral(pos);
863 case Token::TRUE_LITERAL:
864 return factory->NewBooleanLiteral(true, pos);
865 case Token::FALSE_LITERAL:
866 return factory->NewBooleanLiteral(false, pos);
867 case Token::NUMBER: {
868 double value = scanner->DoubleValue();
869 return factory->NewNumberLiteral(value, pos);
878 Expression* ParserTraits::ExpressionFromIdentifier(
879 const AstRawString* name, int pos, Scope* scope,
880 AstNodeFactory<AstConstructionVisitor>* factory) {
881 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name);
882 // The name may refer to a module instance object, so its type is unknown.
884 if (FLAG_print_interface_details)
885 PrintF("# Variable %.*s ", name->length(), name->raw_data());
887 Interface* interface = Interface::NewUnknown(parser_->zone());
888 return scope->NewUnresolved(factory, name, interface, pos);
892 Expression* ParserTraits::ExpressionFromString(
893 int pos, Scanner* scanner,
894 AstNodeFactory<AstConstructionVisitor>* factory) {
895 const AstRawString* symbol = GetSymbol(scanner);
896 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol);
897 return factory->NewStringLiteral(symbol, pos);
901 Expression* ParserTraits::GetIterator(
902 Expression* iterable, AstNodeFactory<AstConstructionVisitor>* factory) {
903 Expression* iterator_symbol_literal =
904 factory->NewSymbolLiteral("symbolIterator", RelocInfo::kNoPosition);
905 int pos = iterable->position();
907 factory->NewProperty(iterable, iterator_symbol_literal, pos);
908 Zone* zone = parser_->zone();
909 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(0, zone);
910 return factory->NewCall(prop, args, pos);
914 Literal* ParserTraits::GetLiteralTheHole(
915 int position, AstNodeFactory<AstConstructionVisitor>* factory) {
916 return factory->NewTheHoleLiteral(RelocInfo::kNoPosition);
920 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) {
921 return parser_->ParseV8Intrinsic(ok);
925 FunctionLiteral* ParserTraits::ParseFunctionLiteral(
926 const AstRawString* name, Scanner::Location function_name_location,
927 bool name_is_strict_reserved, FunctionKind kind,
928 int function_token_position, FunctionLiteral::FunctionType type,
929 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
930 return parser_->ParseFunctionLiteral(
931 name, function_name_location, name_is_strict_reserved, kind,
932 function_token_position, type, arity_restriction, ok);
936 Parser::Parser(CompilationInfo* info, ParseInfo* parse_info)
937 : ParserBase<ParserTraits>(&scanner_, parse_info->stack_limit,
938 info->extension(), NULL, info->zone(),
939 info->ast_node_id_gen(), this),
940 scanner_(parse_info->unicode_cache),
941 reusable_preparser_(NULL),
942 original_scope_(NULL),
944 cached_parse_data_(NULL),
946 has_pending_error_(false),
947 pending_error_message_(NULL),
948 pending_error_arg_(NULL),
949 pending_error_char_arg_(NULL),
950 total_preparse_skipped_(0),
951 pre_parse_timer_(NULL) {
952 DCHECK(!script().is_null() || info->source_stream() != NULL);
953 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping);
954 set_allow_modules(!info->is_native() && FLAG_harmony_modules);
955 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native());
956 set_allow_lazy(false); // Must be explicitly enabled.
957 set_allow_arrow_functions(FLAG_harmony_arrow_functions);
958 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
959 set_allow_classes(FLAG_harmony_classes);
960 set_allow_harmony_object_literals(FLAG_harmony_object_literals);
961 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
963 use_counts_[feature] = 0;
965 if (info->ast_value_factory() == NULL) {
966 // info takes ownership of AstValueFactory.
967 info->SetAstValueFactory(
968 new AstValueFactory(zone(), parse_info->hash_seed));
973 FunctionLiteral* Parser::ParseProgram() {
974 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
975 // see comment for HistogramTimerScope class.
977 // It's OK to use the counters here, since this function is only called in
979 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true);
980 Handle<String> source(String::cast(script()->source()));
981 isolate()->counters()->total_parse_size()->Increment(source->length());
982 base::ElapsedTimer timer;
983 if (FLAG_trace_parse) {
986 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
988 // Initialize parser state.
989 CompleteParserRecorder recorder;
991 if (compile_options() == ScriptCompiler::kProduceParserCache) {
993 } else if (compile_options() == ScriptCompiler::kConsumeParserCache) {
994 cached_parse_data_->Initialize();
997 source = String::Flatten(source);
998 FunctionLiteral* result;
1000 Scope* top_scope = NULL;
1001 Scope* eval_scope = NULL;
1002 if (source->IsExternalTwoByteString()) {
1003 // Notice that the stream is destroyed at the end of the branch block.
1004 // The last line of the blocks can't be moved outside, even though they're
1006 ExternalTwoByteStringUtf16CharacterStream stream(
1007 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
1008 scanner_.Initialize(&stream);
1009 result = DoParseProgram(info(), &top_scope, &eval_scope);
1011 GenericStringUtf16CharacterStream stream(source, 0, source->length());
1012 scanner_.Initialize(&stream);
1013 result = DoParseProgram(info(), &top_scope, &eval_scope);
1015 top_scope->set_end_position(source->length());
1016 if (eval_scope != NULL) {
1017 eval_scope->set_end_position(source->length());
1019 HandleSourceURLComments();
1021 if (FLAG_trace_parse && result != NULL) {
1022 double ms = timer.Elapsed().InMillisecondsF();
1023 if (info()->is_eval()) {
1024 PrintF("[parsing eval");
1025 } else if (info()->script()->name()->IsString()) {
1026 String* name = String::cast(info()->script()->name());
1027 SmartArrayPointer<char> name_chars = name->ToCString();
1028 PrintF("[parsing script: %s", name_chars.get());
1030 PrintF("[parsing script");
1032 PrintF(" - took %0.3f ms]\n", ms);
1034 if (compile_options() == ScriptCompiler::kProduceParserCache) {
1035 if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
1042 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope,
1043 Scope** eval_scope) {
1044 DCHECK(scope_ == NULL);
1045 DCHECK(target_stack_ == NULL);
1047 FunctionLiteral* result = NULL;
1049 *scope = NewScope(scope_, GLOBAL_SCOPE);
1050 info->SetGlobalScope(*scope);
1051 if (!info->context().is_null() && !info->context()->IsNativeContext()) {
1052 *scope = Scope::DeserializeScopeChain(*info->context(), *scope, zone());
1053 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this
1054 // means the Parser cannot operate independent of the V8 heap. Tell the
1055 // string table to internalize strings and values right after they're
1057 ast_value_factory()->Internalize(isolate());
1059 original_scope_ = *scope;
1060 if (info->is_eval()) {
1061 if (!(*scope)->is_global_scope() || info->strict_mode() == STRICT) {
1062 *scope = NewScope(*scope, EVAL_SCOPE);
1064 } else if (info->is_global()) {
1065 *scope = NewScope(*scope, GLOBAL_SCOPE);
1067 (*scope)->set_start_position(0);
1068 // End position will be set by the caller.
1070 // Compute the parsing mode.
1071 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY;
1072 if (allow_natives_syntax() || extension_ != NULL ||
1073 (*scope)->is_eval_scope()) {
1074 mode = PARSE_EAGERLY;
1076 ParsingModeScope parsing_mode(this, mode);
1079 FunctionState function_state(&function_state_, &scope_, *scope, zone(),
1080 ast_value_factory(), info->ast_node_id_gen());
1082 scope_->SetStrictMode(info->strict_mode());
1083 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
1085 int beg_pos = scanner()->location().beg_pos;
1086 ParseSourceElements(body, Token::EOS, info->is_eval(), true, eval_scope,
1089 if (ok && strict_mode() == STRICT) {
1090 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
1093 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) {
1094 CheckConflictingVarDeclarations(scope_, &ok);
1097 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
1098 if (body->length() != 1 ||
1099 !body->at(0)->IsExpressionStatement() ||
1100 !body->at(0)->AsExpressionStatement()->
1101 expression()->IsFunctionLiteral()) {
1102 ReportMessage("single_function_literal");
1108 result = factory()->NewFunctionLiteral(
1109 ast_value_factory()->empty_string(), ast_value_factory(), scope_,
1110 body, function_state.materialized_literal_count(),
1111 function_state.expected_property_count(),
1112 function_state.handler_count(), 0,
1113 FunctionLiteral::kNoDuplicateParameters,
1114 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval,
1115 FunctionLiteral::kNotParenthesized, FunctionKind::kNormalFunction, 0);
1116 result->set_ast_properties(factory()->visitor()->ast_properties());
1117 result->set_dont_optimize_reason(
1118 factory()->visitor()->dont_optimize_reason());
1122 // Make sure the target stack is empty.
1123 DCHECK(target_stack_ == NULL);
1129 FunctionLiteral* Parser::ParseLazy() {
1130 // It's OK to use the counters here, since this function is only called in
1132 HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy());
1133 Handle<String> source(String::cast(script()->source()));
1134 isolate()->counters()->total_parse_size()->Increment(source->length());
1135 base::ElapsedTimer timer;
1136 if (FLAG_trace_parse) {
1139 Handle<SharedFunctionInfo> shared_info = info()->shared_info();
1141 // Initialize parser state.
1142 source = String::Flatten(source);
1143 FunctionLiteral* result;
1144 if (source->IsExternalTwoByteString()) {
1145 ExternalTwoByteStringUtf16CharacterStream stream(
1146 Handle<ExternalTwoByteString>::cast(source),
1147 shared_info->start_position(),
1148 shared_info->end_position());
1149 result = ParseLazy(&stream);
1151 GenericStringUtf16CharacterStream stream(source,
1152 shared_info->start_position(),
1153 shared_info->end_position());
1154 result = ParseLazy(&stream);
1157 if (FLAG_trace_parse && result != NULL) {
1158 double ms = timer.Elapsed().InMillisecondsF();
1159 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString();
1160 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
1166 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) {
1167 Handle<SharedFunctionInfo> shared_info = info()->shared_info();
1168 scanner_.Initialize(source);
1169 DCHECK(scope_ == NULL);
1170 DCHECK(target_stack_ == NULL);
1172 Handle<String> name(String::cast(shared_info->name()));
1173 DCHECK(ast_value_factory());
1174 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
1175 const AstRawString* raw_name = ast_value_factory()->GetString(name);
1176 fni_->PushEnclosingName(raw_name);
1178 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1180 // Place holder for the result.
1181 FunctionLiteral* result = NULL;
1184 // Parse the function literal.
1185 Scope* scope = NewScope(scope_, GLOBAL_SCOPE);
1186 info()->SetGlobalScope(scope);
1187 if (!info()->closure().is_null()) {
1188 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope,
1191 original_scope_ = scope;
1192 FunctionState function_state(&function_state_, &scope_, scope, zone(),
1193 ast_value_factory(),
1194 info()->ast_node_id_gen());
1195 DCHECK(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT);
1196 DCHECK(info()->strict_mode() == shared_info->strict_mode());
1197 scope->SetStrictMode(shared_info->strict_mode());
1198 FunctionLiteral::FunctionType function_type = shared_info->is_expression()
1199 ? (shared_info->is_anonymous()
1200 ? FunctionLiteral::ANONYMOUS_EXPRESSION
1201 : FunctionLiteral::NAMED_EXPRESSION)
1202 : FunctionLiteral::DECLARATION;
1205 if (shared_info->is_arrow()) {
1206 Expression* expression = ParseExpression(false, &ok);
1207 DCHECK(expression->IsFunctionLiteral());
1208 result = expression->AsFunctionLiteral();
1210 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(),
1211 false, // Strict mode name already checked.
1212 shared_info->kind(), RelocInfo::kNoPosition,
1214 FunctionLiteral::NORMAL_ARITY, &ok);
1216 // Make sure the results agree.
1217 DCHECK(ok == (result != NULL));
1220 // Make sure the target stack is empty.
1221 DCHECK(target_stack_ == NULL);
1223 if (result != NULL) {
1224 Handle<String> inferred_name(shared_info->inferred_name());
1225 result->set_inferred_name(inferred_name);
1231 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
1232 int end_token, bool is_eval, bool is_global,
1233 Scope** eval_scope, bool* ok) {
1234 // SourceElements ::
1235 // (ModuleElement)* <end_token>
1237 // Allocate a target stack to use for this set of source
1238 // elements. This way, all scripts and functions get their own
1239 // target stack thus avoiding illegal breaks and continues across
1241 TargetScope scope(&this->target_stack_);
1243 DCHECK(processor != NULL);
1244 bool directive_prologue = true; // Parsing directive prologue.
1246 while (peek() != end_token) {
1247 if (directive_prologue && peek() != Token::STRING) {
1248 directive_prologue = false;
1251 Scanner::Location token_loc = scanner()->peek_location();
1253 if (is_global && !is_eval) {
1254 stat = ParseModuleElement(NULL, CHECK_OK);
1256 stat = ParseBlockElement(NULL, CHECK_OK);
1258 if (stat == NULL || stat->IsEmpty()) {
1259 directive_prologue = false; // End of directive prologue.
1263 if (directive_prologue) {
1264 // A shot at a directive.
1265 ExpressionStatement* e_stat;
1267 // Still processing directive prologue?
1268 if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1269 (literal = e_stat->expression()->AsLiteral()) != NULL &&
1270 literal->raw_value()->IsString()) {
1271 // Check "use strict" directive (ES5 14.1) and "use asm" directive. Only
1272 // one can be present.
1273 if (strict_mode() == SLOPPY &&
1274 literal->raw_value()->AsString() ==
1275 ast_value_factory()->use_strict_string() &&
1276 token_loc.end_pos - token_loc.beg_pos ==
1277 ast_value_factory()->use_strict_string()->length() + 2) {
1278 // TODO(mstarzinger): Global strict eval calls, need their own scope
1279 // as specified in ES5 10.4.2(3). The correct fix would be to always
1280 // add this scope in DoParseProgram(), but that requires adaptations
1281 // all over the code base, so we go with a quick-fix for now.
1282 // In the same manner, we have to patch the parsing mode.
1283 if (is_eval && !scope_->is_eval_scope()) {
1284 DCHECK(scope_->is_global_scope());
1285 Scope* scope = NewScope(scope_, EVAL_SCOPE);
1286 scope->set_start_position(scope_->start_position());
1287 scope->set_end_position(scope_->end_position());
1289 if (eval_scope != NULL) {
1290 // Caller will correct the positions of the ad hoc eval scope.
1291 *eval_scope = scope;
1293 mode_ = PARSE_EAGERLY;
1295 scope_->SetStrictMode(STRICT);
1296 // "use strict" is the only directive for now.
1297 directive_prologue = false;
1298 } else if (literal->raw_value()->AsString() ==
1299 ast_value_factory()->use_asm_string() &&
1300 token_loc.end_pos - token_loc.beg_pos ==
1301 ast_value_factory()->use_asm_string()->length() + 2) {
1302 // Store the usage count; The actual use counter on the isolate is
1303 // incremented after parsing is done.
1304 ++use_counts_[v8::Isolate::kUseAsm];
1305 scope_->SetAsmModule();
1308 // End of the directive prologue.
1309 directive_prologue = false;
1313 processor->Add(stat, zone());
1320 Statement* Parser::ParseModuleElement(ZoneList<const AstRawString*>* labels,
1322 // (Ecma 262 5th Edition, clause 14):
1325 // FunctionDeclaration
1327 // In harmony mode we allow additionally the following productions
1331 // ModuleDeclaration
1332 // ImportDeclaration
1333 // ExportDeclaration
1334 // GeneratorDeclaration
1337 case Token::FUNCTION:
1338 return ParseFunctionDeclaration(NULL, ok);
1340 return ParseClassDeclaration(NULL, ok);
1342 return ParseImportDeclaration(ok);
1344 return ParseExportDeclaration(ok);
1346 return ParseVariableStatement(kModuleElement, NULL, ok);
1348 DCHECK(allow_harmony_scoping());
1349 if (strict_mode() == STRICT) {
1350 return ParseVariableStatement(kModuleElement, NULL, ok);
1354 Statement* stmt = ParseStatement(labels, CHECK_OK);
1355 // Handle 'module' as a context-sensitive keyword.
1356 if (FLAG_harmony_modules &&
1357 peek() == Token::IDENTIFIER &&
1358 !scanner()->HasAnyLineTerminatorBeforeNext() &&
1360 ExpressionStatement* estmt = stmt->AsExpressionStatement();
1361 if (estmt != NULL && estmt->expression()->AsVariableProxy() != NULL &&
1362 estmt->expression()->AsVariableProxy()->raw_name() ==
1363 ast_value_factory()->module_string() &&
1364 !scanner()->literal_contains_escapes()) {
1365 return ParseModuleDeclaration(NULL, ok);
1374 Statement* Parser::ParseModuleDeclaration(ZoneList<const AstRawString*>* names,
1376 // ModuleDeclaration:
1377 // 'module' Identifier Module
1379 int pos = peek_position();
1380 const AstRawString* name =
1381 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1384 if (FLAG_print_interface_details)
1385 PrintF("# Module %.*s ", name->length(), name->raw_data());
1388 Module* module = ParseModule(CHECK_OK);
1389 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface());
1390 Declaration* declaration =
1391 factory()->NewModuleDeclaration(proxy, module, scope_, pos);
1392 Declare(declaration, true, CHECK_OK);
1395 if (FLAG_print_interface_details)
1396 PrintF("# Module %.*s ", name->length(), name->raw_data());
1397 if (FLAG_print_interfaces) {
1398 PrintF("module %.*s: ", name->length(), name->raw_data());
1399 module->interface()->Print();
1403 if (names) names->Add(name, zone());
1404 if (module->body() == NULL)
1405 return factory()->NewEmptyStatement(pos);
1407 return factory()->NewModuleStatement(proxy, module->body(), pos);
1411 Module* Parser::ParseModule(bool* ok) {
1413 // '{' ModuleElement '}'
1414 // '=' ModulePath ';'
1419 return ParseModuleLiteral(ok);
1421 case Token::ASSIGN: {
1422 Expect(Token::ASSIGN, CHECK_OK);
1423 Module* result = ParseModulePath(CHECK_OK);
1424 ExpectSemicolon(CHECK_OK);
1429 ExpectContextualKeyword(CStrVector("at"), CHECK_OK);
1430 Module* result = ParseModuleUrl(CHECK_OK);
1431 ExpectSemicolon(CHECK_OK);
1438 Module* Parser::ParseModuleLiteral(bool* ok) {
1440 // '{' ModuleElement '}'
1442 int pos = peek_position();
1443 // Construct block expecting 16 statements.
1444 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition);
1446 if (FLAG_print_interface_details) PrintF("# Literal ");
1448 Scope* scope = NewScope(scope_, MODULE_SCOPE);
1450 Expect(Token::LBRACE, CHECK_OK);
1451 scope->set_start_position(scanner()->location().beg_pos);
1452 scope->SetStrictMode(STRICT);
1455 BlockState block_state(&scope_, scope);
1456 TargetCollector collector(zone());
1457 Target target(&this->target_stack_, &collector);
1458 Target target_body(&this->target_stack_, body);
1460 while (peek() != Token::RBRACE) {
1461 Statement* stat = ParseModuleElement(NULL, CHECK_OK);
1462 if (stat && !stat->IsEmpty()) {
1463 body->AddStatement(stat, zone());
1468 Expect(Token::RBRACE, CHECK_OK);
1469 scope->set_end_position(scanner()->location().end_pos);
1470 body->set_scope(scope);
1472 // Check that all exports are bound.
1473 Interface* interface = scope->interface();
1474 for (Interface::Iterator it = interface->iterator();
1475 !it.done(); it.Advance()) {
1476 if (scope->LookupLocal(it.name()) == NULL) {
1477 ParserTraits::ReportMessage("module_export_undefined", it.name());
1483 interface->MakeModule(ok);
1485 interface->Freeze(ok);
1487 return factory()->NewModuleLiteral(body, interface, pos);
1491 Module* Parser::ParseModulePath(bool* ok) {
1494 // ModulePath '.' Identifier
1496 int pos = peek_position();
1497 Module* result = ParseModuleVariable(CHECK_OK);
1498 while (Check(Token::PERIOD)) {
1499 const AstRawString* name = ParseIdentifierName(CHECK_OK);
1501 if (FLAG_print_interface_details)
1502 PrintF("# Path .%.*s ", name->length(), name->raw_data());
1504 Module* member = factory()->NewModulePath(result, name, pos);
1505 result->interface()->Add(name, member->interface(), zone(), ok);
1508 if (FLAG_print_interfaces) {
1509 PrintF("PATH TYPE ERROR at '%.*s'\n", name->length(), name->raw_data());
1511 result->interface()->Print();
1513 member->interface()->Print();
1516 ParserTraits::ReportMessage("invalid_module_path", name);
1526 Module* Parser::ParseModuleVariable(bool* ok) {
1530 int pos = peek_position();
1531 const AstRawString* name =
1532 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1534 if (FLAG_print_interface_details)
1535 PrintF("# Module variable %.*s ", name->length(), name->raw_data());
1537 VariableProxy* proxy = scope_->NewUnresolved(
1538 factory(), name, Interface::NewModule(zone()),
1539 scanner()->location().beg_pos);
1541 return factory()->NewModuleVariable(proxy, pos);
1545 Module* Parser::ParseModuleUrl(bool* ok) {
1549 int pos = peek_position();
1550 Expect(Token::STRING, CHECK_OK);
1551 const AstRawString* symbol = GetSymbol(scanner());
1553 // TODO(ES6): Request JS resource from environment...
1556 if (FLAG_print_interface_details) PrintF("# Url ");
1559 // Create an empty literal as long as the feature isn't finished.
1561 Scope* scope = NewScope(scope_, MODULE_SCOPE);
1562 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
1563 body->set_scope(scope);
1564 Interface* interface = scope->interface();
1565 Module* result = factory()->NewModuleLiteral(body, interface, pos);
1566 interface->Freeze(ok);
1568 interface->Unify(scope->interface(), zone(), ok);
1574 Module* Parser::ParseModuleSpecifier(bool* ok) {
1579 if (peek() == Token::STRING) {
1580 return ParseModuleUrl(ok);
1582 return ParseModulePath(ok);
1587 Block* Parser::ParseImportDeclaration(bool* ok) {
1588 // ImportDeclaration:
1589 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';'
1591 // TODO(ES6): implement destructuring ImportSpecifiers
1593 int pos = peek_position();
1594 Expect(Token::IMPORT, CHECK_OK);
1595 ZoneList<const AstRawString*> names(1, zone());
1597 const AstRawString* name = ParseIdentifierName(CHECK_OK);
1598 names.Add(name, zone());
1599 while (peek() == Token::COMMA) {
1600 Consume(Token::COMMA);
1601 name = ParseIdentifierName(CHECK_OK);
1602 names.Add(name, zone());
1605 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1606 Module* module = ParseModuleSpecifier(CHECK_OK);
1607 ExpectSemicolon(CHECK_OK);
1609 // Generate a separate declaration for each identifier.
1610 // TODO(ES6): once we implement destructuring, make that one declaration.
1611 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
1612 for (int i = 0; i < names.length(); ++i) {
1614 if (FLAG_print_interface_details)
1615 PrintF("# Import %.*s ", name->length(), name->raw_data());
1617 Interface* interface = Interface::NewUnknown(zone());
1618 module->interface()->Add(names[i], interface, zone(), ok);
1621 if (FLAG_print_interfaces) {
1622 PrintF("IMPORT TYPE ERROR at '%.*s'\n", name->length(),
1625 module->interface()->Print();
1628 ParserTraits::ReportMessage("invalid_module_path", name);
1631 VariableProxy* proxy = NewUnresolved(names[i], LET, interface);
1632 Declaration* declaration =
1633 factory()->NewImportDeclaration(proxy, module, scope_, pos);
1634 Declare(declaration, true, CHECK_OK);
1641 Statement* Parser::ParseExportDeclaration(bool* ok) {
1642 // ExportDeclaration:
1643 // 'export' Identifier (',' Identifier)* ';'
1644 // 'export' VariableDeclaration
1645 // 'export' FunctionDeclaration
1646 // 'export' GeneratorDeclaration
1647 // 'export' ModuleDeclaration
1649 // TODO(ES6): implement structuring ExportSpecifiers
1651 Expect(Token::EXPORT, CHECK_OK);
1653 Statement* result = NULL;
1654 ZoneList<const AstRawString*> names(1, zone());
1656 case Token::IDENTIFIER: {
1657 int pos = position();
1658 const AstRawString* name =
1659 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1660 // Handle 'module' as a context-sensitive keyword.
1661 if (name != ast_value_factory()->module_string()) {
1662 names.Add(name, zone());
1663 while (peek() == Token::COMMA) {
1664 Consume(Token::COMMA);
1665 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1666 names.Add(name, zone());
1668 ExpectSemicolon(CHECK_OK);
1669 result = factory()->NewEmptyStatement(pos);
1671 result = ParseModuleDeclaration(&names, CHECK_OK);
1676 case Token::FUNCTION:
1677 result = ParseFunctionDeclaration(&names, CHECK_OK);
1681 result = ParseClassDeclaration(&names, CHECK_OK);
1687 result = ParseVariableStatement(kModuleElement, &names, CHECK_OK);
1692 ReportUnexpectedToken(scanner()->current_token());
1696 // Every export of a module may be assigned.
1697 for (int i = 0; i < names.length(); ++i) {
1698 Variable* var = scope_->Lookup(names[i]);
1700 // TODO(sigurds) This is an export that has no definition yet,
1701 // not clear what to do in this case.
1704 if (!IsImmutableVariableMode(var->mode())) {
1705 var->set_maybe_assigned();
1709 // Extract declared names into export declarations and interface.
1710 Interface* interface = scope_->interface();
1711 for (int i = 0; i < names.length(); ++i) {
1713 if (FLAG_print_interface_details)
1714 PrintF("# Export %.*s ", names[i]->length(), names[i]->raw_data());
1716 Interface* inner = Interface::NewUnknown(zone());
1717 interface->Add(names[i], inner, zone(), CHECK_OK);
1720 VariableProxy* proxy = NewUnresolved(names[i], LET, inner);
1722 // TODO(rossberg): Rethink whether we actually need to store export
1723 // declarations (for compilation?).
1724 // ExportDeclaration* declaration =
1725 // factory()->NewExportDeclaration(proxy, scope_, position);
1726 // scope_->AddDeclaration(declaration);
1729 DCHECK(result != NULL);
1734 Statement* Parser::ParseBlockElement(ZoneList<const AstRawString*>* labels,
1736 // (Ecma 262 5th Edition, clause 14):
1739 // FunctionDeclaration
1741 // In harmony mode we allow additionally the following productions
1742 // BlockElement (aka SourceElement):
1745 // GeneratorDeclaration
1749 case Token::FUNCTION:
1750 return ParseFunctionDeclaration(NULL, ok);
1752 return ParseClassDeclaration(NULL, ok);
1754 return ParseVariableStatement(kModuleElement, NULL, ok);
1756 DCHECK(allow_harmony_scoping());
1757 if (strict_mode() == STRICT) {
1758 return ParseVariableStatement(kModuleElement, NULL, ok);
1762 return ParseStatement(labels, ok);
1767 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels,
1771 // VariableStatement
1773 // ExpressionStatement
1775 // IterationStatement
1776 // ContinueStatement
1780 // LabelledStatement
1784 // DebuggerStatement
1786 // Note: Since labels can only be used by 'break' and 'continue'
1787 // statements, which themselves are only valid within blocks,
1788 // iterations or 'switch' statements (i.e., BreakableStatements),
1789 // labels can be simply ignored in all other cases; except for
1790 // trivial labeled break statements 'label: break label' which is
1791 // parsed into an empty statement.
1794 return ParseBlock(labels, ok);
1796 case Token::SEMICOLON:
1798 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1801 return ParseIfStatement(labels, ok);
1804 return ParseDoWhileStatement(labels, ok);
1807 return ParseWhileStatement(labels, ok);
1810 return ParseForStatement(labels, ok);
1812 case Token::CONTINUE:
1813 return ParseContinueStatement(ok);
1816 return ParseBreakStatement(labels, ok);
1819 return ParseReturnStatement(ok);
1822 return ParseWithStatement(labels, ok);
1825 return ParseSwitchStatement(labels, ok);
1828 return ParseThrowStatement(ok);
1831 // NOTE: It is somewhat complicated to have labels on
1832 // try-statements. When breaking out of a try-finally statement,
1833 // one must take great care not to treat it as a
1834 // fall-through. It is much easier just to wrap the entire
1835 // try-statement in a statement block and put the labels there
1837 factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition);
1838 Target target(&this->target_stack_, result);
1839 TryStatement* statement = ParseTryStatement(CHECK_OK);
1840 if (result) result->AddStatement(statement, zone());
1844 case Token::FUNCTION: {
1845 // FunctionDeclaration is only allowed in the context of SourceElements
1846 // (Ecma 262 5th Edition, clause 14):
1849 // FunctionDeclaration
1850 // Common language extension is to allow function declaration in place
1851 // of any statement. This language extension is disabled in strict mode.
1853 // In Harmony mode, this case also handles the extension:
1855 // GeneratorDeclaration
1856 if (strict_mode() == STRICT) {
1857 ReportMessageAt(scanner()->peek_location(), "strict_function");
1861 return ParseFunctionDeclaration(NULL, ok);
1865 return ParseClassDeclaration(NULL, ok);
1867 case Token::DEBUGGER:
1868 return ParseDebuggerStatement(ok);
1872 return ParseVariableStatement(kStatement, NULL, ok);
1875 DCHECK(allow_harmony_scoping());
1876 if (strict_mode() == STRICT) {
1877 return ParseVariableStatement(kStatement, NULL, ok);
1881 return ParseExpressionOrLabelledStatement(labels, ok);
1886 VariableProxy* Parser::NewUnresolved(const AstRawString* name,
1887 VariableMode mode, Interface* interface) {
1888 // If we are inside a function, a declaration of a var/const variable is a
1889 // truly local variable, and the scope of the variable is always the function
1891 // Let/const variables in harmony mode are always added to the immediately
1893 return DeclarationScope(mode)->NewUnresolved(
1894 factory(), name, interface, position());
1898 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
1899 VariableProxy* proxy = declaration->proxy();
1900 DCHECK(proxy->raw_name() != NULL);
1901 const AstRawString* name = proxy->raw_name();
1902 VariableMode mode = declaration->mode();
1903 Scope* declaration_scope = DeclarationScope(mode);
1904 Variable* var = NULL;
1906 // If a suitable scope exists, then we can statically declare this
1907 // variable and also set its mode. In any case, a Declaration node
1908 // will be added to the scope so that the declaration can be added
1909 // to the corresponding activation frame at runtime if necessary.
1910 // For instance declarations inside an eval scope need to be added
1911 // to the calling function context.
1912 // Similarly, strict mode eval scope does not leak variable declarations to
1913 // the caller's scope so we declare all locals, too.
1914 if (declaration_scope->is_function_scope() ||
1915 declaration_scope->is_strict_eval_scope() ||
1916 declaration_scope->is_block_scope() ||
1917 declaration_scope->is_module_scope() ||
1918 declaration_scope->is_global_scope()) {
1919 // Declare the variable in the declaration scope.
1920 // For the global scope, we have to check for collisions with earlier
1921 // (i.e., enclosing) global scopes, to maintain the illusion of a single
1923 var = declaration_scope->is_global_scope()
1924 ? declaration_scope->Lookup(name)
1925 : declaration_scope->LookupLocal(name);
1927 // Declare the name.
1928 var = declaration_scope->DeclareLocal(name, mode,
1929 declaration->initialization(),
1930 kNotAssigned, proxy->interface());
1931 } else if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode())
1932 || ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) &&
1933 !declaration_scope->is_global_scope())) {
1934 // The name was declared in this scope before; check for conflicting
1935 // re-declarations. We have a conflict if either of the declarations is
1936 // not a var (in the global scope, we also have to ignore legacy const for
1937 // compatibility). There is similar code in runtime.cc in the Declare
1938 // functions. The function CheckConflictingVarDeclarations checks for
1939 // var and let bindings from different scopes whereas this is a check for
1940 // conflicting declarations within the same scope. This check also covers
1943 // function () { let x; { var x; } }
1945 // because the var declaration is hoisted to the function scope where 'x'
1946 // is already bound.
1947 DCHECK(IsDeclaredVariableMode(var->mode()));
1948 if (allow_harmony_scoping() && strict_mode() == STRICT) {
1949 // In harmony we treat re-declarations as early errors. See
1950 // ES5 16 for a definition of early errors.
1951 ParserTraits::ReportMessage("var_redeclaration", name);
1955 Expression* expression = NewThrowTypeError(
1956 "var_redeclaration", name, declaration->position());
1957 declaration_scope->SetIllegalRedeclaration(expression);
1958 } else if (mode == VAR) {
1959 var->set_maybe_assigned();
1963 // We add a declaration node for every declaration. The compiler
1964 // will only generate code if necessary. In particular, declarations
1965 // for inner local variables that do not represent functions won't
1966 // result in any generated code.
1968 // Note that we always add an unresolved proxy even if it's not
1969 // used, simply because we don't know in this method (w/o extra
1970 // parameters) if the proxy is needed or not. The proxy will be
1971 // bound during variable resolution time unless it was pre-bound
1974 // WARNING: This will lead to multiple declaration nodes for the
1975 // same variable if it is declared several times. This is not a
1976 // semantic issue as long as we keep the source order, but it may be
1977 // a performance issue since it may lead to repeated
1978 // RuntimeHidden_DeclareLookupSlot calls.
1979 declaration_scope->AddDeclaration(declaration);
1981 if (mode == CONST_LEGACY && declaration_scope->is_global_scope()) {
1982 // For global const variables we bind the proxy to a variable.
1983 DCHECK(resolve); // should be set by all callers
1984 Variable::Kind kind = Variable::NORMAL;
1986 Variable(declaration_scope, name, mode, true, kind,
1987 kNeedsInitialization, kNotAssigned, proxy->interface());
1988 } else if (declaration_scope->is_eval_scope() &&
1989 declaration_scope->strict_mode() == SLOPPY) {
1990 // For variable declarations in a sloppy eval scope the proxy is bound
1991 // to a lookup variable to force a dynamic declaration using the
1992 // DeclareLookupSlot runtime function.
1993 Variable::Kind kind = Variable::NORMAL;
1994 // TODO(sigurds) figure out if kNotAssigned is OK here
1995 var = new (zone()) Variable(declaration_scope, name, mode, true, kind,
1996 declaration->initialization(), kNotAssigned,
1997 proxy->interface());
1998 var->AllocateTo(Variable::LOOKUP, -1);
2002 // If requested and we have a local variable, bind the proxy to the variable
2003 // at parse-time. This is used for functions (and consts) declared inside
2004 // statements: the corresponding function (or const) variable must be in the
2005 // function scope and not a statement-local scope, e.g. as provided with a
2006 // 'with' statement:
2012 // which is translated into:
2015 // // in this case this is not: 'var f; f = function () {};'
2016 // var f = function () {};
2019 // Note that if 'f' is accessed from inside the 'with' statement, it
2020 // will be allocated in the context (because we must be able to look
2021 // it up dynamically) but it will also be accessed statically, i.e.,
2022 // with a context slot index and a context chain length for this
2023 // initialization code. Thus, inside the 'with' statement, we need
2024 // both access to the static and the dynamic context chain; the
2025 // runtime needs to provide both.
2026 if (resolve && var != NULL) {
2029 if (FLAG_harmony_modules) {
2032 if (FLAG_print_interface_details) {
2033 PrintF("# Declare %.*s ", var->raw_name()->length(),
2034 var->raw_name()->raw_data());
2037 proxy->interface()->Unify(var->interface(), zone(), &ok);
2040 if (FLAG_print_interfaces) {
2041 PrintF("DECLARE TYPE ERROR\n");
2043 proxy->interface()->Print();
2045 var->interface()->Print();
2048 ParserTraits::ReportMessage("module_type_error", name);
2055 // Language extension which is only enabled for source files loaded
2056 // through the API's extension mechanism. A native function
2057 // declaration is resolved by looking up the function through a
2058 // callback provided by the extension.
2059 Statement* Parser::ParseNativeDeclaration(bool* ok) {
2060 int pos = peek_position();
2061 Expect(Token::FUNCTION, CHECK_OK);
2062 // Allow "eval" or "arguments" for backward compatibility.
2063 const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
2064 Expect(Token::LPAREN, CHECK_OK);
2065 bool done = (peek() == Token::RPAREN);
2067 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
2068 done = (peek() == Token::RPAREN);
2070 Expect(Token::COMMA, CHECK_OK);
2073 Expect(Token::RPAREN, CHECK_OK);
2074 Expect(Token::SEMICOLON, CHECK_OK);
2076 // Make sure that the function containing the native declaration
2077 // isn't lazily compiled. The extension structures are only
2078 // accessible while parsing the first time not when reparsing
2079 // because of lazy compilation.
2080 DeclarationScope(VAR)->ForceEagerCompilation();
2082 // TODO(1240846): It's weird that native function declarations are
2083 // introduced dynamically when we meet their declarations, whereas
2084 // other functions are set up when entering the surrounding scope.
2085 VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue());
2086 Declaration* declaration =
2087 factory()->NewVariableDeclaration(proxy, VAR, scope_, pos);
2088 Declare(declaration, true, CHECK_OK);
2089 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral(
2090 name, extension_, RelocInfo::kNoPosition);
2091 return factory()->NewExpressionStatement(
2092 factory()->NewAssignment(
2093 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition),
2098 Statement* Parser::ParseFunctionDeclaration(
2099 ZoneList<const AstRawString*>* names, bool* ok) {
2100 // FunctionDeclaration ::
2101 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
2102 // GeneratorDeclaration ::
2103 // 'function' '*' Identifier '(' FormalParameterListopt ')'
2104 // '{' FunctionBody '}'
2105 Expect(Token::FUNCTION, CHECK_OK);
2106 int pos = position();
2107 bool is_generator = Check(Token::MUL);
2108 bool is_strict_reserved = false;
2109 const AstRawString* name = ParseIdentifierOrStrictReservedWord(
2110 &is_strict_reserved, CHECK_OK);
2111 FunctionLiteral* fun =
2112 ParseFunctionLiteral(name, scanner()->location(), is_strict_reserved,
2113 is_generator ? FunctionKind::kGeneratorFunction
2114 : FunctionKind::kNormalFunction,
2115 pos, FunctionLiteral::DECLARATION,
2116 FunctionLiteral::NORMAL_ARITY, CHECK_OK);
2117 // Even if we're not at the top-level of the global or a function
2118 // scope, we treat it as such and introduce the function with its
2119 // initial value upon entering the corresponding scope.
2120 // In ES6, a function behaves as a lexical binding, except in the
2121 // global scope, or the initial scope of eval or another function.
2123 allow_harmony_scoping() && strict_mode() == STRICT &&
2124 !(scope_->is_global_scope() || scope_->is_eval_scope() ||
2125 scope_->is_function_scope()) ? LET : VAR;
2126 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
2127 Declaration* declaration =
2128 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
2129 Declare(declaration, true, CHECK_OK);
2130 if (names) names->Add(name, zone());
2131 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2135 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
2137 // ClassDeclaration ::
2138 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
2140 // A ClassDeclaration
2144 // has the same semantics as:
2146 // let C = class C { ... };
2148 // so rewrite it as such.
2150 Expect(Token::CLASS, CHECK_OK);
2151 int pos = position();
2152 bool is_strict_reserved = false;
2153 const AstRawString* name =
2154 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
2155 Expression* value = ParseClassLiteral(name, scanner()->location(),
2156 is_strict_reserved, pos, CHECK_OK);
2158 Block* block = factory()->NewBlock(NULL, 1, true, pos);
2159 VariableMode mode = LET;
2160 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
2161 Declaration* declaration =
2162 factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
2163 Declare(declaration, true, CHECK_OK);
2165 Token::Value init_op = Token::INIT_LET;
2166 Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos);
2167 block->AddStatement(
2168 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
2171 if (names) names->Add(name, zone());
2176 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) {
2177 if (allow_harmony_scoping() && strict_mode() == STRICT) {
2178 return ParseScopedBlock(labels, ok);
2182 // '{' Statement* '}'
2184 // Note that a Block does not introduce a new execution scope!
2185 // (ECMA-262, 3rd, 12.2)
2187 // Construct block expecting 16 statements.
2189 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2190 Target target(&this->target_stack_, result);
2191 Expect(Token::LBRACE, CHECK_OK);
2192 while (peek() != Token::RBRACE) {
2193 Statement* stat = ParseStatement(NULL, CHECK_OK);
2194 if (stat && !stat->IsEmpty()) {
2195 result->AddStatement(stat, zone());
2198 Expect(Token::RBRACE, CHECK_OK);
2203 Block* Parser::ParseScopedBlock(ZoneList<const AstRawString*>* labels,
2205 // The harmony mode uses block elements instead of statements.
2208 // '{' BlockElement* '}'
2210 // Construct block expecting 16 statements.
2212 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2213 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
2215 // Parse the statements and collect escaping labels.
2216 Expect(Token::LBRACE, CHECK_OK);
2217 block_scope->set_start_position(scanner()->location().beg_pos);
2218 { BlockState block_state(&scope_, block_scope);
2219 TargetCollector collector(zone());
2220 Target target(&this->target_stack_, &collector);
2221 Target target_body(&this->target_stack_, body);
2223 while (peek() != Token::RBRACE) {
2224 Statement* stat = ParseBlockElement(NULL, CHECK_OK);
2225 if (stat && !stat->IsEmpty()) {
2226 body->AddStatement(stat, zone());
2230 Expect(Token::RBRACE, CHECK_OK);
2231 block_scope->set_end_position(scanner()->location().end_pos);
2232 block_scope = block_scope->FinalizeBlockScope();
2233 body->set_scope(block_scope);
2238 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
2239 ZoneList<const AstRawString*>* names,
2241 // VariableStatement ::
2242 // VariableDeclarations ';'
2244 const AstRawString* ignore;
2246 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK);
2247 ExpectSemicolon(CHECK_OK);
2252 // If the variable declaration declares exactly one non-const
2253 // variable, then *out is set to that variable. In all other cases,
2254 // *out is untouched; in particular, it is the caller's responsibility
2255 // to initialize it properly. This mechanism is used for the parsing
2256 // of 'for-in' loops.
2257 Block* Parser::ParseVariableDeclarations(
2258 VariableDeclarationContext var_context,
2259 VariableDeclarationProperties* decl_props,
2260 ZoneList<const AstRawString*>* names,
2261 const AstRawString** out,
2263 // VariableDeclarations ::
2264 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
2266 // The ES6 Draft Rev3 specifies the following grammar for const declarations
2268 // ConstDeclaration ::
2269 // const ConstBinding (',' ConstBinding)* ';'
2271 // Identifier '=' AssignmentExpression
2275 // BindingPattern '=' AssignmentExpression
2277 int pos = peek_position();
2278 VariableMode mode = VAR;
2279 // True if the binding needs initialization. 'let' and 'const' declared
2280 // bindings are created uninitialized by their declaration nodes and
2281 // need initialization. 'var' declared bindings are always initialized
2282 // immediately by their declaration nodes.
2283 bool needs_init = false;
2284 bool is_const = false;
2285 Token::Value init_op = Token::INIT_VAR;
2286 if (peek() == Token::VAR) {
2287 Consume(Token::VAR);
2288 } else if (peek() == Token::CONST) {
2289 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
2291 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
2293 // * It is a Syntax Error if the code that matches this production is not
2294 // contained in extended code.
2296 // However disallowing const in sloppy mode will break compatibility with
2297 // existing pages. Therefore we keep allowing const with the old
2298 // non-harmony semantics in sloppy mode.
2299 Consume(Token::CONST);
2300 switch (strict_mode()) {
2302 mode = CONST_LEGACY;
2303 init_op = Token::INIT_CONST_LEGACY;
2306 if (allow_harmony_scoping()) {
2307 if (var_context == kStatement) {
2308 // In strict mode 'const' declarations are only allowed in source
2309 // element positions.
2310 ReportMessage("unprotected_const");
2315 init_op = Token::INIT_CONST;
2317 ReportMessage("strict_const");
2324 } else if (peek() == Token::LET && strict_mode() == STRICT) {
2325 DCHECK(allow_harmony_scoping());
2326 Consume(Token::LET);
2327 if (var_context == kStatement) {
2328 // Let declarations are only allowed in source element positions.
2329 ReportMessage("unprotected_let");
2335 init_op = Token::INIT_LET;
2337 UNREACHABLE(); // by current callers
2340 Scope* declaration_scope = DeclarationScope(mode);
2342 // The scope of a var/const declared variable anywhere inside a function
2343 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
2344 // transform a source-level var/const declaration into a (Function)
2345 // Scope declaration, and rewrite the source-level initialization into an
2346 // assignment statement. We use a block to collect multiple assignments.
2348 // We mark the block as initializer block because we don't want the
2349 // rewriter to add a '.result' assignment to such a block (to get compliant
2350 // behavior for code such as print(eval('var x = 7')), and for cosmetic
2351 // reasons when pretty-printing. Also, unless an assignment (initialization)
2352 // is inside an initializer block, it is ignored.
2354 // Create new block with one expected declaration.
2355 Block* block = factory()->NewBlock(NULL, 1, true, pos);
2356 int nvars = 0; // the number of variables declared
2357 const AstRawString* name = NULL;
2359 if (fni_ != NULL) fni_->Enter();
2361 // Parse variable name.
2362 if (nvars > 0) Consume(Token::COMMA);
2363 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
2364 if (fni_ != NULL) fni_->PushVariableName(name);
2366 // Declare variable.
2367 // Note that we *always* must treat the initial value via a separate init
2368 // assignment for variables and constants because the value must be assigned
2369 // when the variable is encountered in the source. But the variable/constant
2370 // is declared (and set to 'undefined') upon entering the function within
2371 // which the variable or constant is declared. Only function variables have
2372 // an initial value in the declaration (because they are initialized upon
2373 // entering the function).
2375 // If we have a const declaration, in an inner scope, the proxy is always
2376 // bound to the declared variable (independent of possibly surrounding with
2378 // For let/const declarations in harmony mode, we can also immediately
2379 // pre-resolve the proxy because it resides in the same scope as the
2381 Interface* interface =
2382 is_const ? Interface::NewConst() : Interface::NewValue();
2383 VariableProxy* proxy = NewUnresolved(name, mode, interface);
2384 Declaration* declaration =
2385 factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
2386 Declare(declaration, mode != VAR, CHECK_OK);
2388 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
2389 ReportMessage("too_many_variables");
2393 if (names) names->Add(name, zone());
2395 // Parse initialization expression if present and/or needed. A
2396 // declaration of the form:
2400 // is syntactic sugar for:
2404 // In particular, we need to re-lookup 'v' (in scope_, not
2405 // declaration_scope) as it may be a different 'v' than the 'v' in the
2406 // declaration (e.g., if we are inside a 'with' statement or 'catch'
2409 // However, note that const declarations are different! A const
2410 // declaration of the form:
2414 // is *not* syntactic sugar for:
2418 // The "variable" c initialized to x is the same as the declared
2419 // one - there is no re-lookup (see the last parameter of the
2420 // Declare() call above).
2422 Scope* initialization_scope = is_const ? declaration_scope : scope_;
2423 Expression* value = NULL;
2425 // Harmony consts have non-optional initializers.
2426 if (peek() == Token::ASSIGN || mode == CONST) {
2427 Expect(Token::ASSIGN, CHECK_OK);
2429 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
2430 // Don't infer if it is "a = function(){...}();"-like expression.
2432 value->AsCall() == NULL &&
2433 value->AsCallNew() == NULL) {
2436 fni_->RemoveLastFunction();
2438 if (decl_props != NULL) *decl_props = kHasInitializers;
2441 // Record the end position of the initializer.
2442 if (proxy->var() != NULL) {
2443 proxy->var()->set_initializer_position(position());
2446 // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
2447 if (value == NULL && needs_init) {
2448 value = GetLiteralUndefined(position());
2451 // Global variable declarations must be compiled in a specific
2452 // way. When the script containing the global variable declaration
2453 // is entered, the global variable must be declared, so that if it
2454 // doesn't exist (on the global object itself, see ES5 errata) it
2455 // gets created with an initial undefined value. This is handled
2456 // by the declarations part of the function representing the
2457 // top-level global code; see Runtime::DeclareGlobalVariable. If
2458 // it already exists (in the object or in a prototype), it is
2459 // *not* touched until the variable declaration statement is
2462 // Executing the variable declaration statement will always
2463 // guarantee to give the global object an own property.
2464 // This way, global variable declarations can shadow
2465 // properties in the prototype chain, but only after the variable
2466 // declaration statement has been executed. This is important in
2467 // browsers where the global object (window) has lots of
2468 // properties defined in prototype objects.
2469 if (initialization_scope->is_global_scope() &&
2470 !IsLexicalVariableMode(mode)) {
2471 // Compute the arguments for the runtime call.
2472 ZoneList<Expression*>* arguments =
2473 new(zone()) ZoneList<Expression*>(3, zone());
2474 // We have at least 1 parameter.
2475 arguments->Add(factory()->NewStringLiteral(name, pos), zone());
2476 CallRuntime* initialize;
2479 arguments->Add(value, zone());
2480 value = NULL; // zap the value to avoid the unnecessary assignment
2482 // Construct the call to Runtime_InitializeConstGlobal
2483 // and add it to the initialization statement block.
2484 // Note that the function does different things depending on
2485 // the number of arguments (1 or 2).
2486 initialize = factory()->NewCallRuntime(
2487 ast_value_factory()->initialize_const_global_string(),
2488 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), arguments,
2492 // We may want to pass singleton to avoid Literal allocations.
2493 StrictMode strict_mode = initialization_scope->strict_mode();
2494 arguments->Add(factory()->NewNumberLiteral(strict_mode, pos), zone());
2496 // Be careful not to assign a value to the global variable if
2497 // we're in a with. The initialization value should not
2498 // necessarily be stored in the global object in that case,
2499 // which is why we need to generate a separate assignment node.
2500 if (value != NULL && !inside_with()) {
2501 arguments->Add(value, zone());
2502 value = NULL; // zap the value to avoid the unnecessary assignment
2503 // Construct the call to Runtime_InitializeVarGlobal
2504 // and add it to the initialization statement block.
2505 initialize = factory()->NewCallRuntime(
2506 ast_value_factory()->initialize_var_global_string(),
2507 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), arguments,
2514 if (initialize != NULL) {
2515 block->AddStatement(factory()->NewExpressionStatement(
2516 initialize, RelocInfo::kNoPosition),
2519 } else if (needs_init) {
2520 // Constant initializations always assign to the declared constant which
2521 // is always at the function scope level. This is only relevant for
2522 // dynamically looked-up variables and constants (the start context for
2523 // constant lookups is always the function context, while it is the top
2524 // context for var declared variables). Sigh...
2525 // For 'let' and 'const' declared variables in harmony mode the
2526 // initialization also always assigns to the declared variable.
2527 DCHECK(proxy != NULL);
2528 DCHECK(proxy->var() != NULL);
2529 DCHECK(value != NULL);
2530 Assignment* assignment =
2531 factory()->NewAssignment(init_op, proxy, value, pos);
2532 block->AddStatement(
2533 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
2538 // Add an assignment node to the initialization statement block if we still
2539 // have a pending initialization value.
2540 if (value != NULL) {
2541 DCHECK(mode == VAR);
2542 // 'var' initializations are simply assignments (with all the consequences
2543 // if they are inside a 'with' statement - they may change a 'with' object
2545 VariableProxy* proxy =
2546 initialization_scope->NewUnresolved(factory(), name, interface);
2547 Assignment* assignment =
2548 factory()->NewAssignment(init_op, proxy, value, pos);
2549 block->AddStatement(
2550 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
2554 if (fni_ != NULL) fni_->Leave();
2555 } while (peek() == Token::COMMA);
2557 // If there was a single non-const declaration, return it in the output
2558 // parameter for possible use by for/in.
2559 if (nvars == 1 && !is_const) {
2567 static bool ContainsLabel(ZoneList<const AstRawString*>* labels,
2568 const AstRawString* label) {
2569 DCHECK(label != NULL);
2570 if (labels != NULL) {
2571 for (int i = labels->length(); i-- > 0; ) {
2572 if (labels->at(i) == label) {
2581 Statement* Parser::ParseExpressionOrLabelledStatement(
2582 ZoneList<const AstRawString*>* labels, bool* ok) {
2583 // ExpressionStatement | LabelledStatement ::
2585 // Identifier ':' Statement
2586 int pos = peek_position();
2587 bool starts_with_idenfifier = peek_any_identifier();
2588 Expression* expr = ParseExpression(true, CHECK_OK);
2589 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
2590 expr->AsVariableProxy() != NULL &&
2591 !expr->AsVariableProxy()->is_this()) {
2592 // Expression is a single identifier, and not, e.g., a parenthesized
2594 VariableProxy* var = expr->AsVariableProxy();
2595 const AstRawString* label = var->raw_name();
2596 // TODO(1240780): We don't check for redeclaration of labels
2597 // during preparsing since keeping track of the set of active
2598 // labels requires nontrivial changes to the way scopes are
2599 // structured. However, these are probably changes we want to
2600 // make later anyway so we should go back and fix this then.
2601 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
2602 ParserTraits::ReportMessage("label_redeclaration", label);
2606 if (labels == NULL) {
2607 labels = new(zone()) ZoneList<const AstRawString*>(4, zone());
2609 labels->Add(label, zone());
2610 // Remove the "ghost" variable that turned out to be a label
2611 // from the top scope. This way, we don't try to resolve it
2612 // during the scope processing.
2613 scope_->RemoveUnresolved(var);
2614 Expect(Token::COLON, CHECK_OK);
2615 return ParseStatement(labels, ok);
2618 // If we have an extension, we allow a native function declaration.
2619 // A native function declaration starts with "native function" with
2620 // no line-terminator between the two words.
2621 if (extension_ != NULL && peek() == Token::FUNCTION &&
2622 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL &&
2623 expr->AsVariableProxy() != NULL &&
2624 expr->AsVariableProxy()->raw_name() ==
2625 ast_value_factory()->native_string() &&
2626 !scanner()->literal_contains_escapes()) {
2627 return ParseNativeDeclaration(ok);
2630 // Parsed expression statement, or the context-sensitive 'module' keyword.
2631 // Only expect semicolon in the former case.
2632 if (!FLAG_harmony_modules || peek() != Token::IDENTIFIER ||
2633 scanner()->HasAnyLineTerminatorBeforeNext() ||
2634 expr->AsVariableProxy() == NULL ||
2635 expr->AsVariableProxy()->raw_name() !=
2636 ast_value_factory()->module_string() ||
2637 scanner()->literal_contains_escapes()) {
2638 ExpectSemicolon(CHECK_OK);
2640 return factory()->NewExpressionStatement(expr, pos);
2644 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels,
2647 // 'if' '(' Expression ')' Statement ('else' Statement)?
2649 int pos = peek_position();
2650 Expect(Token::IF, CHECK_OK);
2651 Expect(Token::LPAREN, CHECK_OK);
2652 Expression* condition = ParseExpression(true, CHECK_OK);
2653 Expect(Token::RPAREN, CHECK_OK);
2654 Statement* then_statement = ParseStatement(labels, CHECK_OK);
2655 Statement* else_statement = NULL;
2656 if (peek() == Token::ELSE) {
2658 else_statement = ParseStatement(labels, CHECK_OK);
2660 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2662 return factory()->NewIfStatement(
2663 condition, then_statement, else_statement, pos);
2667 Statement* Parser::ParseContinueStatement(bool* ok) {
2668 // ContinueStatement ::
2669 // 'continue' Identifier? ';'
2671 int pos = peek_position();
2672 Expect(Token::CONTINUE, CHECK_OK);
2673 const AstRawString* label = NULL;
2674 Token::Value tok = peek();
2675 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2676 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2677 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2678 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
2680 IterationStatement* target = LookupContinueTarget(label, CHECK_OK);
2681 if (target == NULL) {
2682 // Illegal continue statement.
2683 const char* message = "illegal_continue";
2684 if (label != NULL) {
2685 message = "unknown_label";
2687 ParserTraits::ReportMessage(message, label);
2691 ExpectSemicolon(CHECK_OK);
2692 return factory()->NewContinueStatement(target, pos);
2696 Statement* Parser::ParseBreakStatement(ZoneList<const AstRawString*>* labels,
2698 // BreakStatement ::
2699 // 'break' Identifier? ';'
2701 int pos = peek_position();
2702 Expect(Token::BREAK, CHECK_OK);
2703 const AstRawString* label = NULL;
2704 Token::Value tok = peek();
2705 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2706 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2707 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2708 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
2710 // Parse labeled break statements that target themselves into
2711 // empty statements, e.g. 'l1: l2: l3: break l2;'
2712 if (label != NULL && ContainsLabel(labels, label)) {
2713 ExpectSemicolon(CHECK_OK);
2714 return factory()->NewEmptyStatement(pos);
2716 BreakableStatement* target = NULL;
2717 target = LookupBreakTarget(label, CHECK_OK);
2718 if (target == NULL) {
2719 // Illegal break statement.
2720 const char* message = "illegal_break";
2721 if (label != NULL) {
2722 message = "unknown_label";
2724 ParserTraits::ReportMessage(message, label);
2728 ExpectSemicolon(CHECK_OK);
2729 return factory()->NewBreakStatement(target, pos);
2733 Statement* Parser::ParseReturnStatement(bool* ok) {
2734 // ReturnStatement ::
2735 // 'return' Expression? ';'
2737 // Consume the return token. It is necessary to do that before
2738 // reporting any errors on it, because of the way errors are
2739 // reported (underlining).
2740 Expect(Token::RETURN, CHECK_OK);
2741 Scanner::Location loc = scanner()->location();
2743 Token::Value tok = peek();
2745 Expression* return_value;
2746 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
2747 tok == Token::SEMICOLON ||
2748 tok == Token::RBRACE ||
2749 tok == Token::EOS) {
2750 return_value = GetLiteralUndefined(position());
2752 return_value = ParseExpression(true, CHECK_OK);
2754 ExpectSemicolon(CHECK_OK);
2755 if (is_generator()) {
2756 Expression* generator = factory()->NewVariableProxy(
2757 function_state_->generator_object_variable());
2758 Expression* yield = factory()->NewYield(
2759 generator, return_value, Yield::kFinal, loc.beg_pos);
2760 result = factory()->NewExpressionStatement(yield, loc.beg_pos);
2762 result = factory()->NewReturnStatement(return_value, loc.beg_pos);
2765 Scope* decl_scope = scope_->DeclarationScope();
2766 if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) {
2767 ReportMessageAt(loc, "illegal_return");
2775 Statement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels,
2778 // 'with' '(' Expression ')' Statement
2780 Expect(Token::WITH, CHECK_OK);
2781 int pos = position();
2783 if (strict_mode() == STRICT) {
2784 ReportMessage("strict_mode_with");
2789 Expect(Token::LPAREN, CHECK_OK);
2790 Expression* expr = ParseExpression(true, CHECK_OK);
2791 Expect(Token::RPAREN, CHECK_OK);
2793 scope_->DeclarationScope()->RecordWithStatement();
2794 Scope* with_scope = NewScope(scope_, WITH_SCOPE);
2796 { BlockState block_state(&scope_, with_scope);
2797 with_scope->set_start_position(scanner()->peek_location().beg_pos);
2798 stmt = ParseStatement(labels, CHECK_OK);
2799 with_scope->set_end_position(scanner()->location().end_pos);
2801 return factory()->NewWithStatement(with_scope, expr, stmt, pos);
2805 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
2807 // 'case' Expression ':' Statement*
2808 // 'default' ':' Statement*
2810 Expression* label = NULL; // NULL expression indicates default case
2811 if (peek() == Token::CASE) {
2812 Expect(Token::CASE, CHECK_OK);
2813 label = ParseExpression(true, CHECK_OK);
2815 Expect(Token::DEFAULT, CHECK_OK);
2816 if (*default_seen_ptr) {
2817 ReportMessage("multiple_defaults_in_switch");
2821 *default_seen_ptr = true;
2823 Expect(Token::COLON, CHECK_OK);
2824 int pos = position();
2825 ZoneList<Statement*>* statements =
2826 new(zone()) ZoneList<Statement*>(5, zone());
2827 while (peek() != Token::CASE &&
2828 peek() != Token::DEFAULT &&
2829 peek() != Token::RBRACE) {
2830 Statement* stat = ParseStatement(NULL, CHECK_OK);
2831 statements->Add(stat, zone());
2834 return factory()->NewCaseClause(label, statements, pos);
2838 SwitchStatement* Parser::ParseSwitchStatement(
2839 ZoneList<const AstRawString*>* labels, bool* ok) {
2840 // SwitchStatement ::
2841 // 'switch' '(' Expression ')' '{' CaseClause* '}'
2843 SwitchStatement* statement =
2844 factory()->NewSwitchStatement(labels, peek_position());
2845 Target target(&this->target_stack_, statement);
2847 Expect(Token::SWITCH, CHECK_OK);
2848 Expect(Token::LPAREN, CHECK_OK);
2849 Expression* tag = ParseExpression(true, CHECK_OK);
2850 Expect(Token::RPAREN, CHECK_OK);
2852 bool default_seen = false;
2853 ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4, zone());
2854 Expect(Token::LBRACE, CHECK_OK);
2855 while (peek() != Token::RBRACE) {
2856 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
2857 cases->Add(clause, zone());
2859 Expect(Token::RBRACE, CHECK_OK);
2861 if (statement) statement->Initialize(tag, cases);
2866 Statement* Parser::ParseThrowStatement(bool* ok) {
2867 // ThrowStatement ::
2868 // 'throw' Expression ';'
2870 Expect(Token::THROW, CHECK_OK);
2871 int pos = position();
2872 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
2873 ReportMessage("newline_after_throw");
2877 Expression* exception = ParseExpression(true, CHECK_OK);
2878 ExpectSemicolon(CHECK_OK);
2880 return factory()->NewExpressionStatement(
2881 factory()->NewThrow(exception, pos), pos);
2885 TryStatement* Parser::ParseTryStatement(bool* ok) {
2887 // 'try' Block Catch
2888 // 'try' Block Finally
2889 // 'try' Block Catch Finally
2892 // 'catch' '(' Identifier ')' Block
2897 Expect(Token::TRY, CHECK_OK);
2898 int pos = position();
2900 TargetCollector try_collector(zone());
2903 { Target target(&this->target_stack_, &try_collector);
2904 try_block = ParseBlock(NULL, CHECK_OK);
2907 Token::Value tok = peek();
2908 if (tok != Token::CATCH && tok != Token::FINALLY) {
2909 ReportMessage("no_catch_or_finally");
2914 // If we can break out from the catch block and there is a finally block,
2915 // then we will need to collect escaping targets from the catch
2916 // block. Since we don't know yet if there will be a finally block, we
2917 // always collect the targets.
2918 TargetCollector catch_collector(zone());
2919 Scope* catch_scope = NULL;
2920 Variable* catch_variable = NULL;
2921 Block* catch_block = NULL;
2922 const AstRawString* name = NULL;
2923 if (tok == Token::CATCH) {
2924 Consume(Token::CATCH);
2926 Expect(Token::LPAREN, CHECK_OK);
2927 catch_scope = NewScope(scope_, CATCH_SCOPE);
2928 catch_scope->set_start_position(scanner()->location().beg_pos);
2929 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
2931 Expect(Token::RPAREN, CHECK_OK);
2933 Target target(&this->target_stack_, &catch_collector);
2935 allow_harmony_scoping() && strict_mode() == STRICT ? LET : VAR;
2936 catch_variable = catch_scope->DeclareLocal(name, mode, kCreatedInitialized);
2937 BlockState block_state(&scope_, catch_scope);
2938 catch_block = ParseBlock(NULL, CHECK_OK);
2940 catch_scope->set_end_position(scanner()->location().end_pos);
2944 Block* finally_block = NULL;
2945 DCHECK(tok == Token::FINALLY || catch_block != NULL);
2946 if (tok == Token::FINALLY) {
2947 Consume(Token::FINALLY);
2948 finally_block = ParseBlock(NULL, CHECK_OK);
2951 // Simplify the AST nodes by converting:
2952 // 'try B0 catch B1 finally B2'
2954 // 'try { try B0 catch B1 } finally B2'
2956 if (catch_block != NULL && finally_block != NULL) {
2957 // If we have both, create an inner try/catch.
2958 DCHECK(catch_scope != NULL && catch_variable != NULL);
2959 int index = function_state_->NextHandlerIndex();
2960 TryCatchStatement* statement = factory()->NewTryCatchStatement(
2961 index, try_block, catch_scope, catch_variable, catch_block,
2962 RelocInfo::kNoPosition);
2963 statement->set_escaping_targets(try_collector.targets());
2964 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
2965 try_block->AddStatement(statement, zone());
2966 catch_block = NULL; // Clear to indicate it's been handled.
2969 TryStatement* result = NULL;
2970 if (catch_block != NULL) {
2971 DCHECK(finally_block == NULL);
2972 DCHECK(catch_scope != NULL && catch_variable != NULL);
2973 int index = function_state_->NextHandlerIndex();
2974 result = factory()->NewTryCatchStatement(
2975 index, try_block, catch_scope, catch_variable, catch_block, pos);
2977 DCHECK(finally_block != NULL);
2978 int index = function_state_->NextHandlerIndex();
2979 result = factory()->NewTryFinallyStatement(
2980 index, try_block, finally_block, pos);
2981 // Combine the jump targets of the try block and the possible catch block.
2982 try_collector.targets()->AddAll(*catch_collector.targets(), zone());
2985 result->set_escaping_targets(try_collector.targets());
2990 DoWhileStatement* Parser::ParseDoWhileStatement(
2991 ZoneList<const AstRawString*>* labels, bool* ok) {
2993 // 'do' Statement 'while' '(' Expression ')' ';'
2995 DoWhileStatement* loop =
2996 factory()->NewDoWhileStatement(labels, peek_position());
2997 Target target(&this->target_stack_, loop);
2999 Expect(Token::DO, CHECK_OK);
3000 Statement* body = ParseStatement(NULL, CHECK_OK);
3001 Expect(Token::WHILE, CHECK_OK);
3002 Expect(Token::LPAREN, CHECK_OK);
3004 Expression* cond = ParseExpression(true, CHECK_OK);
3005 Expect(Token::RPAREN, CHECK_OK);
3007 // Allow do-statements to be terminated with and without
3008 // semi-colons. This allows code such as 'do;while(0)return' to
3009 // parse, which would not be the case if we had used the
3010 // ExpectSemicolon() functionality here.
3011 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
3013 if (loop != NULL) loop->Initialize(cond, body);
3018 WhileStatement* Parser::ParseWhileStatement(
3019 ZoneList<const AstRawString*>* labels, bool* ok) {
3020 // WhileStatement ::
3021 // 'while' '(' Expression ')' Statement
3023 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position());
3024 Target target(&this->target_stack_, loop);
3026 Expect(Token::WHILE, CHECK_OK);
3027 Expect(Token::LPAREN, CHECK_OK);
3028 Expression* cond = ParseExpression(true, CHECK_OK);
3029 Expect(Token::RPAREN, CHECK_OK);
3030 Statement* body = ParseStatement(NULL, CHECK_OK);
3032 if (loop != NULL) loop->Initialize(cond, body);
3037 bool Parser::CheckInOrOf(bool accept_OF,
3038 ForEachStatement::VisitMode* visit_mode) {
3039 if (Check(Token::IN)) {
3040 *visit_mode = ForEachStatement::ENUMERATE;
3042 } else if (accept_OF && CheckContextualKeyword(CStrVector("of"))) {
3043 *visit_mode = ForEachStatement::ITERATE;
3050 void Parser::InitializeForEachStatement(ForEachStatement* stmt,
3052 Expression* subject,
3054 ForOfStatement* for_of = stmt->AsForOfStatement();
3056 if (for_of != NULL) {
3057 Variable* iterator = scope_->DeclarationScope()->NewTemporary(
3058 ast_value_factory()->dot_iterator_string());
3059 Variable* result = scope_->DeclarationScope()->NewTemporary(
3060 ast_value_factory()->dot_result_string());
3062 Expression* assign_iterator;
3063 Expression* next_result;
3064 Expression* result_done;
3065 Expression* assign_each;
3067 // var iterator = subject[Symbol.iterator]();
3068 assign_iterator = factory()->NewAssignment(
3069 Token::ASSIGN, factory()->NewVariableProxy(iterator),
3070 GetIterator(subject, factory()), RelocInfo::kNoPosition);
3072 // var result = iterator.next();
3074 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
3075 Expression* next_literal = factory()->NewStringLiteral(
3076 ast_value_factory()->next_string(), RelocInfo::kNoPosition);
3077 Expression* next_property = factory()->NewProperty(
3078 iterator_proxy, next_literal, RelocInfo::kNoPosition);
3079 ZoneList<Expression*>* next_arguments =
3080 new(zone()) ZoneList<Expression*>(0, zone());
3081 Expression* next_call = factory()->NewCall(
3082 next_property, next_arguments, RelocInfo::kNoPosition);
3083 Expression* result_proxy = factory()->NewVariableProxy(result);
3084 next_result = factory()->NewAssignment(
3085 Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition);
3090 Expression* done_literal = factory()->NewStringLiteral(
3091 ast_value_factory()->done_string(), RelocInfo::kNoPosition);
3092 Expression* result_proxy = factory()->NewVariableProxy(result);
3093 result_done = factory()->NewProperty(
3094 result_proxy, done_literal, RelocInfo::kNoPosition);
3097 // each = result.value
3099 Expression* value_literal = factory()->NewStringLiteral(
3100 ast_value_factory()->value_string(), RelocInfo::kNoPosition);
3101 Expression* result_proxy = factory()->NewVariableProxy(result);
3102 Expression* result_value = factory()->NewProperty(
3103 result_proxy, value_literal, RelocInfo::kNoPosition);
3104 assign_each = factory()->NewAssignment(
3105 Token::ASSIGN, each, result_value, RelocInfo::kNoPosition);
3108 for_of->Initialize(each, subject, body,
3114 stmt->Initialize(each, subject, body);
3119 Statement* Parser::DesugarLetBindingsInForStatement(
3120 Scope* inner_scope, ZoneList<const AstRawString*>* names,
3121 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
3122 Statement* body, bool* ok) {
3123 // ES6 13.6.3.4 specifies that on each loop iteration the let variables are
3124 // copied into a new environment. After copying, the "next" statement of the
3125 // loop is executed to update the loop variables. The loop condition is
3126 // checked and the loop body is executed.
3128 // We rewrite a for statement of the form
3130 // for (let x = i; cond; next) body
3155 DCHECK(names->length() > 0);
3156 Scope* for_scope = scope_;
3157 ZoneList<Variable*> temps(names->length(), zone());
3159 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false,
3160 RelocInfo::kNoPosition);
3161 outer_block->AddStatement(init, zone());
3163 const AstRawString* temp_name = ast_value_factory()->dot_for_string();
3165 // For each let variable x:
3166 // make statement: temp_x = x.
3167 for (int i = 0; i < names->length(); i++) {
3168 VariableProxy* proxy =
3169 NewUnresolved(names->at(i), LET, Interface::NewValue());
3170 Variable* temp = scope_->DeclarationScope()->NewTemporary(temp_name);
3171 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
3172 Assignment* assignment = factory()->NewAssignment(
3173 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3174 Statement* assignment_statement = factory()->NewExpressionStatement(
3175 assignment, RelocInfo::kNoPosition);
3176 outer_block->AddStatement(assignment_statement, zone());
3177 temps.Add(temp, zone());
3180 Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name);
3181 // Make statement: flag = 1.
3183 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3184 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3185 Assignment* assignment = factory()->NewAssignment(
3186 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
3187 Statement* assignment_statement = factory()->NewExpressionStatement(
3188 assignment, RelocInfo::kNoPosition);
3189 outer_block->AddStatement(assignment_statement, zone());
3192 outer_block->AddStatement(loop, zone());
3193 outer_block->set_scope(for_scope);
3194 scope_ = inner_scope;
3196 Block* inner_block = factory()->NewBlock(NULL, 2 * names->length() + 3,
3197 false, RelocInfo::kNoPosition);
3198 int pos = scanner()->location().beg_pos;
3199 ZoneList<Variable*> inner_vars(names->length(), zone());
3201 // For each let variable x:
3202 // make statement: let x = temp_x.
3203 for (int i = 0; i < names->length(); i++) {
3204 VariableProxy* proxy =
3205 NewUnresolved(names->at(i), LET, Interface::NewValue());
3206 Declaration* declaration =
3207 factory()->NewVariableDeclaration(proxy, LET, scope_, pos);
3208 Declare(declaration, true, CHECK_OK);
3209 inner_vars.Add(declaration->proxy()->var(), zone());
3210 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3211 Assignment* assignment = factory()->NewAssignment(
3212 Token::INIT_LET, proxy, temp_proxy, pos);
3213 Statement* assignment_statement = factory()->NewExpressionStatement(
3215 proxy->var()->set_initializer_position(pos);
3216 inner_block->AddStatement(assignment_statement, zone());
3219 // Make statement: if (flag == 1) { flag = 0; } else { next; }.
3221 Expression* compare = NULL;
3222 // Make compare expresion: flag == 1.
3224 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3225 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3226 compare = factory()->NewCompareOperation(
3227 Token::EQ, flag_proxy, const1, pos);
3229 Statement* clear_flag = NULL;
3230 // Make statement: flag = 0.
3232 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3233 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3234 Assignment* assignment = factory()->NewAssignment(
3235 Token::ASSIGN, flag_proxy, const0, RelocInfo::kNoPosition);
3236 clear_flag = factory()->NewExpressionStatement(assignment, pos);
3238 Statement* clear_flag_or_next = factory()->NewIfStatement(
3239 compare, clear_flag, next, RelocInfo::kNoPosition);
3240 inner_block->AddStatement(clear_flag_or_next, zone());
3244 // Make statement: if (cond) { } else { break; }.
3246 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
3247 BreakableStatement* t = LookupBreakTarget(NULL, CHECK_OK);
3248 Statement* stop = factory()->NewBreakStatement(t, RelocInfo::kNoPosition);
3249 Statement* if_not_cond_break = factory()->NewIfStatement(
3250 cond, empty, stop, cond->position());
3251 inner_block->AddStatement(if_not_cond_break, zone());
3254 inner_block->AddStatement(body, zone());
3256 // For each let variable x:
3257 // make statement: temp_x = x;
3258 for (int i = 0; i < names->length(); i++) {
3259 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3260 int pos = scanner()->location().end_pos;
3261 VariableProxy* proxy = factory()->NewVariableProxy(inner_vars.at(i), pos);
3262 Assignment* assignment = factory()->NewAssignment(
3263 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3264 Statement* assignment_statement = factory()->NewExpressionStatement(
3265 assignment, RelocInfo::kNoPosition);
3266 inner_block->AddStatement(assignment_statement, zone());
3269 inner_scope->set_end_position(scanner()->location().end_pos);
3270 inner_block->set_scope(inner_scope);
3273 loop->Initialize(NULL, NULL, NULL, inner_block);
3278 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
3281 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
3283 int pos = peek_position();
3284 Statement* init = NULL;
3285 ZoneList<const AstRawString*> let_bindings(1, zone());
3287 // Create an in-between scope for let-bound iteration variables.
3288 Scope* saved_scope = scope_;
3289 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
3292 Expect(Token::FOR, CHECK_OK);
3293 Expect(Token::LPAREN, CHECK_OK);
3294 for_scope->set_start_position(scanner()->location().beg_pos);
3295 if (peek() != Token::SEMICOLON) {
3296 if (peek() == Token::VAR || peek() == Token::CONST) {
3297 bool is_const = peek() == Token::CONST;
3298 const AstRawString* name = NULL;
3299 VariableDeclarationProperties decl_props = kHasNoInitializers;
3300 Block* variable_statement =
3301 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
3303 bool accept_OF = decl_props == kHasNoInitializers;
3304 ForEachStatement::VisitMode mode;
3306 if (name != NULL && CheckInOrOf(accept_OF, &mode)) {
3307 Interface* interface =
3308 is_const ? Interface::NewConst() : Interface::NewValue();
3309 ForEachStatement* loop =
3310 factory()->NewForEachStatement(mode, labels, pos);
3311 Target target(&this->target_stack_, loop);
3313 Expression* enumerable = ParseExpression(true, CHECK_OK);
3314 Expect(Token::RPAREN, CHECK_OK);
3316 VariableProxy* each =
3317 scope_->NewUnresolved(factory(), name, interface);
3318 Statement* body = ParseStatement(NULL, CHECK_OK);
3319 InitializeForEachStatement(loop, each, enumerable, body);
3321 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3322 result->AddStatement(variable_statement, zone());
3323 result->AddStatement(loop, zone());
3324 scope_ = saved_scope;
3325 for_scope->set_end_position(scanner()->location().end_pos);
3326 for_scope = for_scope->FinalizeBlockScope();
3327 DCHECK(for_scope == NULL);
3328 // Parsed for-in loop w/ variable/const declaration.
3331 init = variable_statement;
3333 } else if (peek() == Token::LET && strict_mode() == STRICT) {
3334 DCHECK(allow_harmony_scoping());
3335 const AstRawString* name = NULL;
3336 VariableDeclarationProperties decl_props = kHasNoInitializers;
3337 Block* variable_statement =
3338 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings,
3340 bool accept_IN = name != NULL && decl_props != kHasInitializers;
3341 bool accept_OF = decl_props == kHasNoInitializers;
3342 ForEachStatement::VisitMode mode;
3344 if (accept_IN && CheckInOrOf(accept_OF, &mode)) {
3345 // Rewrite a for-in statement of the form
3347 // for (let x in e) b
3351 // <let x' be a temporary variable>
3358 // TODO(keuchel): Move the temporary variable to the block scope, after
3359 // implementing stack allocated block scoped variables.
3360 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3361 ast_value_factory()->dot_for_string());
3362 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
3363 ForEachStatement* loop =
3364 factory()->NewForEachStatement(mode, labels, pos);
3365 Target target(&this->target_stack_, loop);
3367 // The expression does not see the loop variable.
3368 scope_ = saved_scope;
3369 Expression* enumerable = ParseExpression(true, CHECK_OK);
3371 Expect(Token::RPAREN, CHECK_OK);
3373 VariableProxy* each =
3374 scope_->NewUnresolved(factory(), name, Interface::NewValue());
3375 Statement* body = ParseStatement(NULL, CHECK_OK);
3377 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3378 Assignment* assignment = factory()->NewAssignment(
3379 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition);
3380 Statement* assignment_statement = factory()->NewExpressionStatement(
3381 assignment, RelocInfo::kNoPosition);
3382 body_block->AddStatement(variable_statement, zone());
3383 body_block->AddStatement(assignment_statement, zone());
3384 body_block->AddStatement(body, zone());
3385 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block);
3386 scope_ = saved_scope;
3387 for_scope->set_end_position(scanner()->location().end_pos);
3388 for_scope = for_scope->FinalizeBlockScope();
3389 body_block->set_scope(for_scope);
3390 // Parsed for-in loop w/ let declaration.
3394 init = variable_statement;
3397 Scanner::Location lhs_location = scanner()->peek_location();
3398 Expression* expression = ParseExpression(false, CHECK_OK);
3399 ForEachStatement::VisitMode mode;
3400 bool accept_OF = expression->AsVariableProxy();
3402 if (CheckInOrOf(accept_OF, &mode)) {
3403 expression = this->CheckAndRewriteReferenceExpression(
3404 expression, lhs_location, "invalid_lhs_in_for", CHECK_OK);
3406 ForEachStatement* loop =
3407 factory()->NewForEachStatement(mode, labels, pos);
3408 Target target(&this->target_stack_, loop);
3410 Expression* enumerable = ParseExpression(true, CHECK_OK);
3411 Expect(Token::RPAREN, CHECK_OK);
3413 Statement* body = ParseStatement(NULL, CHECK_OK);
3414 InitializeForEachStatement(loop, expression, enumerable, body);
3415 scope_ = saved_scope;
3416 for_scope->set_end_position(scanner()->location().end_pos);
3417 for_scope = for_scope->FinalizeBlockScope();
3418 DCHECK(for_scope == NULL);
3419 // Parsed for-in loop.
3423 init = factory()->NewExpressionStatement(
3424 expression, RelocInfo::kNoPosition);
3429 // Standard 'for' loop
3430 ForStatement* loop = factory()->NewForStatement(labels, pos);
3431 Target target(&this->target_stack_, loop);
3433 // Parsed initializer at this point.
3434 Expect(Token::SEMICOLON, CHECK_OK);
3436 // If there are let bindings, then condition and the next statement of the
3437 // for loop must be parsed in a new scope.
3438 Scope* inner_scope = NULL;
3439 if (let_bindings.length() > 0) {
3440 inner_scope = NewScope(for_scope, BLOCK_SCOPE);
3441 inner_scope->set_start_position(scanner()->location().beg_pos);
3442 scope_ = inner_scope;
3445 Expression* cond = NULL;
3446 if (peek() != Token::SEMICOLON) {
3447 cond = ParseExpression(true, CHECK_OK);
3449 Expect(Token::SEMICOLON, CHECK_OK);
3451 Statement* next = NULL;
3452 if (peek() != Token::RPAREN) {
3453 Expression* exp = ParseExpression(true, CHECK_OK);
3454 next = factory()->NewExpressionStatement(exp, RelocInfo::kNoPosition);
3456 Expect(Token::RPAREN, CHECK_OK);
3458 Statement* body = ParseStatement(NULL, CHECK_OK);
3460 Statement* result = NULL;
3461 if (let_bindings.length() > 0) {
3463 result = DesugarLetBindingsInForStatement(inner_scope, &let_bindings, loop,
3464 init, cond, next, body, CHECK_OK);
3465 scope_ = saved_scope;
3466 for_scope->set_end_position(scanner()->location().end_pos);
3468 scope_ = saved_scope;
3469 for_scope->set_end_position(scanner()->location().end_pos);
3470 for_scope = for_scope->FinalizeBlockScope();
3472 // Rewrite a for statement of the form
3473 // for (const x = i; c; n) b
3481 DCHECK(init != NULL);
3483 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3484 block->AddStatement(init, zone());
3485 block->AddStatement(loop, zone());
3486 block->set_scope(for_scope);
3487 loop->Initialize(NULL, cond, next, body);
3490 loop->Initialize(init, cond, next, body);
3498 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
3499 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
3500 // contexts this is used as a statement which invokes the debugger as i a
3501 // break point is present.
3502 // DebuggerStatement ::
3505 int pos = peek_position();
3506 Expect(Token::DEBUGGER, CHECK_OK);
3507 ExpectSemicolon(CHECK_OK);
3508 return factory()->NewDebuggerStatement(pos);
3512 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
3513 if (expression->IsLiteral()) return true;
3514 MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3515 return lit != NULL && lit->is_simple();
3519 Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate,
3520 Expression* expression) {
3521 Factory* factory = isolate->factory();
3522 DCHECK(IsCompileTimeValue(expression));
3523 Handle<FixedArray> result = factory->NewFixedArray(2, TENURED);
3524 ObjectLiteral* object_literal = expression->AsObjectLiteral();
3525 if (object_literal != NULL) {
3526 DCHECK(object_literal->is_simple());
3527 if (object_literal->fast_elements()) {
3528 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
3530 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
3532 result->set(kElementsSlot, *object_literal->constant_properties());
3534 ArrayLiteral* array_literal = expression->AsArrayLiteral();
3535 DCHECK(array_literal != NULL && array_literal->is_simple());
3536 result->set(kLiteralTypeSlot, Smi::FromInt(ARRAY_LITERAL));
3537 result->set(kElementsSlot, *array_literal->constant_elements());
3543 CompileTimeValue::LiteralType CompileTimeValue::GetLiteralType(
3544 Handle<FixedArray> value) {
3545 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot));
3546 return static_cast<LiteralType>(literal_type->value());
3550 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
3551 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
3555 bool CheckAndDeclareArrowParameter(ParserTraits* traits, Expression* expression,
3556 Scope* scope, int* num_params,
3557 Scanner::Location* dupe_loc) {
3558 // Case for empty parameter lists:
3560 if (expression == NULL) return true;
3562 // Too many parentheses around expression:
3564 if (expression->parenthesization_level() > 1) return false;
3566 // Case for a single parameter:
3569 if (expression->IsVariableProxy()) {
3570 if (expression->AsVariableProxy()->is_this()) return false;
3572 const AstRawString* raw_name = expression->AsVariableProxy()->raw_name();
3573 if (traits->IsEvalOrArguments(raw_name) ||
3574 traits->IsFutureStrictReserved(raw_name))
3577 if (scope->IsDeclared(raw_name)) {
3578 *dupe_loc = Scanner::Location(
3579 expression->position(), expression->position() + raw_name->length());
3583 scope->DeclareParameter(raw_name, VAR);
3588 // Case for more than one parameter:
3589 // (foo, bar [, ...]) => ...
3590 if (expression->IsBinaryOperation()) {
3591 BinaryOperation* binop = expression->AsBinaryOperation();
3592 if (binop->op() != Token::COMMA || binop->left()->is_parenthesized() ||
3593 binop->right()->is_parenthesized())
3596 return CheckAndDeclareArrowParameter(traits, binop->left(), scope,
3597 num_params, dupe_loc) &&
3598 CheckAndDeclareArrowParameter(traits, binop->right(), scope,
3599 num_params, dupe_loc);
3602 // Any other kind of expression is not a valid parameter list.
3607 int ParserTraits::DeclareArrowParametersFromExpression(
3608 Expression* expression, Scope* scope, Scanner::Location* dupe_loc,
3611 *ok = CheckAndDeclareArrowParameter(this, expression, scope, &num_params,
3617 FunctionLiteral* Parser::ParseFunctionLiteral(
3618 const AstRawString* function_name, Scanner::Location function_name_location,
3619 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos,
3620 FunctionLiteral::FunctionType function_type,
3621 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
3623 // '(' FormalParameterList? ')' '{' FunctionBody '}'
3626 // '(' ')' '{' FunctionBody '}'
3629 // '(' PropertySetParameterList ')' '{' FunctionBody '}'
3631 int pos = function_token_pos == RelocInfo::kNoPosition
3632 ? peek_position() : function_token_pos;
3634 bool is_generator = IsGeneratorFunction(kind);
3636 // Anonymous functions were passed either the empty symbol or a null
3637 // handle as the function name. Remember if we were passed a non-empty
3638 // handle to decide whether to invoke function name inference.
3639 bool should_infer_name = function_name == NULL;
3641 // We want a non-null handle as the function name.
3642 if (should_infer_name) {
3643 function_name = ast_value_factory()->empty_string();
3646 int num_parameters = 0;
3647 // Function declarations are function scoped in normal mode, so they are
3648 // hoisted. In harmony block scoping mode they are block scoped, so they
3651 // One tricky case are function declarations in a local sloppy-mode eval:
3652 // their declaration is hoisted, but they still see the local scope. E.g.,
3656 // try { throw 1 } catch (x) { eval("function g() { return x }") }
3660 // needs to return 1. To distinguish such cases, we need to detect
3661 // (1) whether a function stems from a sloppy eval, and
3662 // (2) whether it actually hoists across the eval.
3663 // Unfortunately, we do not represent sloppy eval scopes, so we do not have
3664 // either information available directly, especially not when lazily compiling
3665 // a function like 'g'. We hence rely on the following invariants:
3666 // - (1) is the case iff the innermost scope of the deserialized scope chain
3667 // under which we compile is _not_ a declaration scope. This holds because
3668 // in all normal cases, function declarations are fully hoisted to a
3669 // declaration scope and compiled relative to that.
3670 // - (2) is the case iff the current declaration scope is still the original
3671 // one relative to the deserialized scope chain. Otherwise we must be
3672 // compiling a function in an inner declaration scope in the eval, e.g. a
3673 // nested function, and hoisting works normally relative to that.
3674 Scope* declaration_scope = scope_->DeclarationScope();
3675 Scope* original_declaration_scope = original_scope_->DeclarationScope();
3677 function_type == FunctionLiteral::DECLARATION &&
3678 (!allow_harmony_scoping() || strict_mode() == SLOPPY) &&
3679 (original_scope_ == original_declaration_scope ||
3680 declaration_scope != original_declaration_scope)
3681 ? NewScope(declaration_scope, FUNCTION_SCOPE)
3682 : NewScope(scope_, FUNCTION_SCOPE);
3683 ZoneList<Statement*>* body = NULL;
3684 int materialized_literal_count = -1;
3685 int expected_property_count = -1;
3686 int handler_count = 0;
3687 FunctionLiteral::ParameterFlag duplicate_parameters =
3688 FunctionLiteral::kNoDuplicateParameters;
3689 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
3690 ? FunctionLiteral::kIsParenthesized
3691 : FunctionLiteral::kNotParenthesized;
3692 AstProperties ast_properties;
3693 BailoutReason dont_optimize_reason = kNoReason;
3694 // Parse function body.
3696 FunctionState function_state(&function_state_, &scope_, scope, zone(),
3697 ast_value_factory(),
3698 info()->ast_node_id_gen());
3699 scope_->SetScopeName(function_name);
3702 // For generators, allocating variables in contexts is currently a win
3703 // because it minimizes the work needed to suspend and resume an
3705 scope_->ForceContextAllocation();
3707 // Calling a generator returns a generator object. That object is stored
3708 // in a temporary variable, a definition that is used by "yield"
3709 // expressions. This also marks the FunctionState as a generator.
3710 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3711 ast_value_factory()->dot_generator_object_string());
3712 function_state.set_generator_object_variable(temp);
3715 // FormalParameterList ::
3716 // '(' (Identifier)*[','] ')'
3717 Expect(Token::LPAREN, CHECK_OK);
3718 scope->set_start_position(scanner()->location().beg_pos);
3720 // We don't yet know if the function will be strict, so we cannot yet
3721 // produce errors for parameter names or duplicates. However, we remember
3722 // the locations of these errors if they occur and produce the errors later.
3723 Scanner::Location eval_args_error_log = Scanner::Location::invalid();
3724 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
3725 Scanner::Location reserved_loc = Scanner::Location::invalid();
3727 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY ||
3728 (peek() == Token::RPAREN &&
3729 arity_restriction != FunctionLiteral::SETTER_ARITY);
3731 bool is_strict_reserved = false;
3732 const AstRawString* param_name =
3733 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
3735 // Store locations for possible future error reports.
3736 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) {
3737 eval_args_error_log = scanner()->location();
3739 if (!reserved_loc.IsValid() && is_strict_reserved) {
3740 reserved_loc = scanner()->location();
3742 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) {
3743 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters;
3744 dupe_error_loc = scanner()->location();
3747 Variable* var = scope_->DeclareParameter(param_name, VAR);
3748 if (scope->strict_mode() == SLOPPY) {
3749 // TODO(sigurds) Mark every parameter as maybe assigned. This is a
3750 // conservative approximation necessary to account for parameters
3751 // that are assigned via the arguments array.
3752 var->set_maybe_assigned();
3756 if (num_parameters > Code::kMaxArguments) {
3757 ReportMessage("too_many_parameters");
3761 if (arity_restriction == FunctionLiteral::SETTER_ARITY) break;
3762 done = (peek() == Token::RPAREN);
3763 if (!done) Expect(Token::COMMA, CHECK_OK);
3765 Expect(Token::RPAREN, CHECK_OK);
3767 Expect(Token::LBRACE, CHECK_OK);
3769 // If we have a named function expression, we add a local variable
3770 // declaration to the body of the function with the name of the
3771 // function and let it refer to the function itself (closure).
3772 // NOTE: We create a proxy and resolve it here so that in the
3773 // future we can change the AST to only refer to VariableProxies
3774 // instead of Variables and Proxis as is the case now.
3775 Variable* fvar = NULL;
3776 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY;
3777 if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
3778 if (allow_harmony_scoping() && strict_mode() == STRICT) {
3779 fvar_init_op = Token::INIT_CONST;
3781 VariableMode fvar_mode =
3782 allow_harmony_scoping() && strict_mode() == STRICT
3783 ? CONST : CONST_LEGACY;
3784 DCHECK(function_name != NULL);
3786 Variable(scope_, function_name, fvar_mode, true /* is valid LHS */,
3787 Variable::NORMAL, kCreatedInitialized, kNotAssigned,
3788 Interface::NewConst());
3789 VariableProxy* proxy = factory()->NewVariableProxy(fvar);
3790 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration(
3791 proxy, fvar_mode, scope_, RelocInfo::kNoPosition);
3792 scope_->DeclareFunctionVar(fvar_declaration);
3795 // Determine if the function can be parsed lazily. Lazy parsing is different
3796 // from lazy compilation; we need to parse more eagerly than we compile.
3798 // We can only parse lazily if we also compile lazily. The heuristics for
3799 // lazy compilation are:
3800 // - It must not have been prohibited by the caller to Parse (some callers
3801 // need a full AST).
3802 // - The outer scope must allow lazy compilation of inner functions.
3803 // - The function mustn't be a function expression with an open parenthesis
3804 // before; we consider that a hint that the function will be called
3805 // immediately, and it would be a waste of time to make it lazily
3807 // These are all things we can know at this point, without looking at the
3810 // In addition, we need to distinguish between these cases:
3811 // (function foo() {
3812 // bar = function() { return 1; }
3815 // (function foo() {
3817 // bar = function() { return a; }
3820 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
3821 // parenthesis before the function means that it will be called
3822 // immediately). The inner function *must* be parsed eagerly to resolve the
3823 // possible reference to the variable in foo's scope. However, it's possible
3824 // that it will be compiled lazily.
3826 // To make this additional case work, both Parser and PreParser implement a
3827 // logic where only top-level functions will be parsed lazily.
3828 bool is_lazily_parsed = (mode() == PARSE_LAZILY &&
3829 scope_->AllowsLazyCompilation() &&
3830 !parenthesized_function_);
3831 parenthesized_function_ = false; // The bit was set for this function only.
3833 if (is_lazily_parsed) {
3834 SkipLazyFunctionBody(function_name, &materialized_literal_count,
3835 &expected_property_count, CHECK_OK);
3837 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
3838 is_generator, CHECK_OK);
3839 materialized_literal_count = function_state.materialized_literal_count();
3840 expected_property_count = function_state.expected_property_count();
3841 handler_count = function_state.handler_count();
3844 // Validate strict mode.
3845 // Concise methods use StrictFormalParameters.
3846 if (strict_mode() == STRICT || IsConciseMethod(kind)) {
3847 CheckStrictFunctionNameAndParameters(function_name,
3848 name_is_strict_reserved,
3849 function_name_location,
3850 eval_args_error_log,
3855 if (strict_mode() == STRICT) {
3856 CheckOctalLiteral(scope->start_position(),
3857 scope->end_position(),
3860 ast_properties = *factory()->visitor()->ast_properties();
3861 dont_optimize_reason = factory()->visitor()->dont_optimize_reason();
3863 if (allow_harmony_scoping() && strict_mode() == STRICT) {
3864 CheckConflictingVarDeclarations(scope, CHECK_OK);
3868 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
3869 function_name, ast_value_factory(), scope, body,
3870 materialized_literal_count, expected_property_count, handler_count,
3871 num_parameters, duplicate_parameters, function_type,
3872 FunctionLiteral::kIsFunction, parenthesized, kind, pos);
3873 function_literal->set_function_token_position(function_token_pos);
3874 function_literal->set_ast_properties(&ast_properties);
3875 function_literal->set_dont_optimize_reason(dont_optimize_reason);
3877 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
3878 return function_literal;
3882 void Parser::SkipLazyFunctionBody(const AstRawString* function_name,
3883 int* materialized_literal_count,
3884 int* expected_property_count,
3886 int function_block_pos = position();
3887 if (compile_options() == ScriptCompiler::kConsumeParserCache) {
3888 // If we have cached data, we use it to skip parsing the function body. The
3889 // data contains the information we need to construct the lazy function.
3890 FunctionEntry entry =
3891 cached_parse_data_->GetFunctionEntry(function_block_pos);
3892 // Check that cached data is valid.
3893 CHECK(entry.is_valid());
3894 // End position greater than end of stream is safe, and hard to check.
3895 CHECK(entry.end_pos() > function_block_pos);
3896 scanner()->SeekForward(entry.end_pos() - 1);
3898 scope_->set_end_position(entry.end_pos());
3899 Expect(Token::RBRACE, ok);
3903 total_preparse_skipped_ += scope_->end_position() - function_block_pos;
3904 *materialized_literal_count = entry.literal_count();
3905 *expected_property_count = entry.property_count();
3906 scope_->SetStrictMode(entry.strict_mode());
3908 // With no cached data, we partially parse the function, without building an
3909 // AST. This gathers the data needed to build a lazy function.
3910 SingletonLogger logger;
3911 PreParser::PreParseResult result =
3912 ParseLazyFunctionBodyWithPreParser(&logger);
3913 if (result == PreParser::kPreParseStackOverflow) {
3914 // Propagate stack overflow.
3915 set_stack_overflow();
3919 if (logger.has_error()) {
3920 ParserTraits::ReportMessageAt(
3921 Scanner::Location(logger.start(), logger.end()),
3922 logger.message(), logger.argument_opt(), logger.is_reference_error());
3926 scope_->set_end_position(logger.end());
3927 Expect(Token::RBRACE, ok);
3931 total_preparse_skipped_ += scope_->end_position() - function_block_pos;
3932 *materialized_literal_count = logger.literals();
3933 *expected_property_count = logger.properties();
3934 scope_->SetStrictMode(logger.strict_mode());
3935 if (compile_options() == ScriptCompiler::kProduceParserCache) {
3937 // Position right after terminal '}'.
3938 int body_end = scanner()->location().end_pos;
3939 log_->LogFunction(function_block_pos, body_end,
3940 *materialized_literal_count,
3941 *expected_property_count,
3942 scope_->strict_mode());
3948 ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
3949 const AstRawString* function_name, int pos, Variable* fvar,
3950 Token::Value fvar_init_op, bool is_generator, bool* ok) {
3951 // Everything inside an eagerly parsed function will be parsed eagerly
3952 // (see comment above).
3953 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
3954 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone());
3956 VariableProxy* fproxy = scope_->NewUnresolved(
3957 factory(), function_name, Interface::NewConst());
3958 fproxy->BindTo(fvar);
3959 body->Add(factory()->NewExpressionStatement(
3960 factory()->NewAssignment(fvar_init_op,
3962 factory()->NewThisFunction(pos),
3963 RelocInfo::kNoPosition),
3964 RelocInfo::kNoPosition), zone());
3967 // For generators, allocate and yield an iterator on function entry.
3969 ZoneList<Expression*>* arguments =
3970 new(zone()) ZoneList<Expression*>(0, zone());
3971 CallRuntime* allocation = factory()->NewCallRuntime(
3972 ast_value_factory()->empty_string(),
3973 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), arguments,
3975 VariableProxy* init_proxy = factory()->NewVariableProxy(
3976 function_state_->generator_object_variable());
3977 Assignment* assignment = factory()->NewAssignment(
3978 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
3979 VariableProxy* get_proxy = factory()->NewVariableProxy(
3980 function_state_->generator_object_variable());
3981 Yield* yield = factory()->NewYield(
3982 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition);
3983 body->Add(factory()->NewExpressionStatement(
3984 yield, RelocInfo::kNoPosition), zone());
3987 ParseSourceElements(body, Token::RBRACE, false, false, NULL, CHECK_OK);
3990 VariableProxy* get_proxy = factory()->NewVariableProxy(
3991 function_state_->generator_object_variable());
3992 Expression* undefined =
3993 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition);
3994 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal,
3995 RelocInfo::kNoPosition);
3996 body->Add(factory()->NewExpressionStatement(
3997 yield, RelocInfo::kNoPosition), zone());
4000 Expect(Token::RBRACE, CHECK_OK);
4001 scope_->set_end_position(scanner()->location().end_pos);
4007 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
4008 SingletonLogger* logger) {
4009 // This function may be called on a background thread too; record only the
4010 // main thread preparse times.
4011 if (pre_parse_timer_ != NULL) {
4012 pre_parse_timer_->Start();
4014 DCHECK_EQ(Token::LBRACE, scanner()->current_token());
4016 if (reusable_preparser_ == NULL) {
4017 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit_);
4018 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping());
4019 reusable_preparser_->set_allow_modules(allow_modules());
4020 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax());
4021 reusable_preparser_->set_allow_lazy(true);
4022 reusable_preparser_->set_allow_arrow_functions(allow_arrow_functions());
4023 reusable_preparser_->set_allow_harmony_numeric_literals(
4024 allow_harmony_numeric_literals());
4025 reusable_preparser_->set_allow_classes(allow_classes());
4026 reusable_preparser_->set_allow_harmony_object_literals(
4027 allow_harmony_object_literals());
4029 PreParser::PreParseResult result =
4030 reusable_preparser_->PreParseLazyFunction(strict_mode(),
4033 if (pre_parse_timer_ != NULL) {
4034 pre_parse_timer_->Stop();
4040 Expression* Parser::ParseV8Intrinsic(bool* ok) {
4042 // '%' Identifier Arguments
4044 int pos = peek_position();
4045 Expect(Token::MOD, CHECK_OK);
4046 // Allow "eval" or "arguments" for backward compatibility.
4047 const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
4048 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
4050 if (extension_ != NULL) {
4051 // The extension structures are only accessible while parsing the
4052 // very first time not when reparsing because of lazy compilation.
4053 scope_->DeclarationScope()->ForceEagerCompilation();
4056 const Runtime::Function* function = Runtime::FunctionForName(name->string());
4058 // Check for built-in IS_VAR macro.
4059 if (function != NULL &&
4060 function->intrinsic_type == Runtime::RUNTIME &&
4061 function->function_id == Runtime::kIS_VAR) {
4062 // %IS_VAR(x) evaluates to x if x is a variable,
4063 // leads to a parse error otherwise. Could be implemented as an
4064 // inline function %_IS_VAR(x) to eliminate this special case.
4065 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
4068 ReportMessage("not_isvar");
4074 // Check that the expected number of arguments are being passed.
4075 if (function != NULL &&
4076 function->nargs != -1 &&
4077 function->nargs != args->length()) {
4078 ReportMessage("illegal_access");
4083 // Check that the function is defined if it's an inline runtime call.
4084 if (function == NULL && name->FirstCharacter() == '_') {
4085 ParserTraits::ReportMessage("not_defined", name);
4090 // We have a valid intrinsics call or a call to a builtin.
4091 return factory()->NewCallRuntime(name, function, args, pos);
4095 Literal* Parser::GetLiteralUndefined(int position) {
4096 return factory()->NewUndefinedLiteral(position);
4100 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
4101 Declaration* decl = scope->CheckConflictingVarDeclarations();
4103 // In harmony mode we treat conflicting variable bindinds as early
4104 // errors. See ES5 16 for a definition of early errors.
4105 const AstRawString* name = decl->proxy()->raw_name();
4106 int position = decl->proxy()->position();
4107 Scanner::Location location = position == RelocInfo::kNoPosition
4108 ? Scanner::Location::invalid()
4109 : Scanner::Location(position, position + 1);
4110 ParserTraits::ReportMessageAt(location, "var_redeclaration", name);
4116 // ----------------------------------------------------------------------------
4120 bool Parser::TargetStackContainsLabel(const AstRawString* label) {
4121 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4122 BreakableStatement* stat = t->node()->AsBreakableStatement();
4123 if (stat != NULL && ContainsLabel(stat->labels(), label))
4130 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
4132 bool anonymous = label == NULL;
4133 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4134 BreakableStatement* stat = t->node()->AsBreakableStatement();
4135 if (stat == NULL) continue;
4136 if ((anonymous && stat->is_target_for_anonymous()) ||
4137 (!anonymous && ContainsLabel(stat->labels(), label))) {
4138 RegisterTargetUse(stat->break_target(), t->previous());
4146 IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
4148 bool anonymous = label == NULL;
4149 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4150 IterationStatement* stat = t->node()->AsIterationStatement();
4151 if (stat == NULL) continue;
4153 DCHECK(stat->is_target_for_anonymous());
4154 if (anonymous || ContainsLabel(stat->labels(), label)) {
4155 RegisterTargetUse(stat->continue_target(), t->previous());
4163 void Parser::RegisterTargetUse(Label* target, Target* stop) {
4164 // Register that a break target found at the given stop in the
4165 // target stack has been used from the top of the target stack. Add
4166 // the break target to any TargetCollectors passed on the stack.
4167 for (Target* t = target_stack_; t != stop; t = t->previous()) {
4168 TargetCollector* collector = t->node()->AsTargetCollector();
4169 if (collector != NULL) collector->AddTarget(target, zone());
4174 void Parser::HandleSourceURLComments() {
4175 if (scanner_.source_url()->length() > 0) {
4176 Handle<String> source_url = scanner_.source_url()->Internalize(isolate());
4177 info_->script()->set_source_url(*source_url);
4179 if (scanner_.source_mapping_url()->length() > 0) {
4180 Handle<String> source_mapping_url =
4181 scanner_.source_mapping_url()->Internalize(isolate());
4182 info_->script()->set_source_mapping_url(*source_mapping_url);
4187 void Parser::ThrowPendingError() {
4188 DCHECK(ast_value_factory()->IsInternalized());
4189 if (has_pending_error_) {
4190 MessageLocation location(script(), pending_error_location_.beg_pos,
4191 pending_error_location_.end_pos);
4192 Factory* factory = isolate()->factory();
4194 pending_error_arg_ != NULL || pending_error_char_arg_ != NULL;
4195 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0);
4196 if (pending_error_arg_ != NULL) {
4197 Handle<String> arg_string = pending_error_arg_->string();
4198 elements->set(0, *arg_string);
4199 } else if (pending_error_char_arg_ != NULL) {
4200 Handle<String> arg_string =
4201 factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_))
4203 elements->set(0, *arg_string);
4205 isolate()->debug()->OnCompileError(script());
4207 Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
4208 Handle<Object> error;
4209 MaybeHandle<Object> maybe_error =
4210 pending_error_is_reference_error_
4211 ? factory->NewReferenceError(pending_error_message_, array)
4212 : factory->NewSyntaxError(pending_error_message_, array);
4213 if (maybe_error.ToHandle(&error)) isolate()->Throw(*error, &location);
4218 void Parser::Internalize() {
4219 // Internalize strings.
4220 ast_value_factory()->Internalize(isolate());
4222 // Error processing.
4223 if (info()->function() == NULL) {
4224 if (stack_overflow()) {
4225 isolate()->StackOverflow();
4227 ThrowPendingError();
4231 // Move statistics to Isolate.
4232 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
4234 for (int i = 0; i < use_counts_[feature]; ++i) {
4235 isolate()->CountUsage(v8::Isolate::UseCounterFeature(feature));
4238 isolate()->counters()->total_preparse_skipped()->Increment(
4239 total_preparse_skipped_);
4243 // ----------------------------------------------------------------------------
4244 // Regular expressions
4247 RegExpParser::RegExpParser(FlatStringReader* in,
4248 Handle<String>* error,
4251 : isolate_(zone->isolate()),
4256 current_(kEndMarker),
4260 multiline_(multiline),
4262 contains_anchor_(false),
4263 is_scanned_for_captures_(false),
4269 uc32 RegExpParser::Next() {
4271 return in()->Get(next_pos_);
4278 void RegExpParser::Advance() {
4279 if (next_pos_ < in()->length()) {
4280 StackLimitCheck check(isolate());
4281 if (check.HasOverflowed()) {
4282 ReportError(CStrVector(Isolate::kStackOverflowMessage));
4283 } else if (zone()->excess_allocation()) {
4284 ReportError(CStrVector("Regular expression too large"));
4286 current_ = in()->Get(next_pos_);
4290 current_ = kEndMarker;
4296 void RegExpParser::Reset(int pos) {
4298 has_more_ = (pos < in()->length());
4303 void RegExpParser::Advance(int dist) {
4304 next_pos_ += dist - 1;
4309 bool RegExpParser::simple() {
4314 RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
4316 *error_ = isolate()->factory()->NewStringFromAscii(message).ToHandleChecked();
4317 // Zip to the end to make sure the no more input is read.
4318 current_ = kEndMarker;
4319 next_pos_ = in()->length();
4326 RegExpTree* RegExpParser::ParsePattern() {
4327 RegExpTree* result = ParseDisjunction(CHECK_FAILED);
4328 DCHECK(!has_more());
4329 // If the result of parsing is a literal string atom, and it has the
4330 // same length as the input, then the atom is identical to the input.
4331 if (result->IsAtom() && result->AsAtom()->length() == in()->length()) {
4340 // Alternative | Disjunction
4348 RegExpTree* RegExpParser::ParseDisjunction() {
4349 // Used to store current state while parsing subexpressions.
4350 RegExpParserState initial_state(NULL, INITIAL, 0, zone());
4351 RegExpParserState* stored_state = &initial_state;
4352 // Cache the builder in a local variable for quick access.
4353 RegExpBuilder* builder = initial_state.builder();
4355 switch (current()) {
4357 if (stored_state->IsSubexpression()) {
4358 // Inside a parenthesized group when hitting end of input.
4359 ReportError(CStrVector("Unterminated group") CHECK_FAILED);
4361 DCHECK_EQ(INITIAL, stored_state->group_type());
4362 // Parsing completed successfully.
4363 return builder->ToRegExp();
4365 if (!stored_state->IsSubexpression()) {
4366 ReportError(CStrVector("Unmatched ')'") CHECK_FAILED);
4368 DCHECK_NE(INITIAL, stored_state->group_type());
4371 // End disjunction parsing and convert builder content to new single
4373 RegExpTree* body = builder->ToRegExp();
4375 int end_capture_index = captures_started();
4377 int capture_index = stored_state->capture_index();
4378 SubexpressionType group_type = stored_state->group_type();
4380 // Restore previous state.
4381 stored_state = stored_state->previous_state();
4382 builder = stored_state->builder();
4384 // Build result of subexpression.
4385 if (group_type == CAPTURE) {
4386 RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index);
4387 captures_->at(capture_index - 1) = capture;
4389 } else if (group_type != GROUPING) {
4390 DCHECK(group_type == POSITIVE_LOOKAHEAD ||
4391 group_type == NEGATIVE_LOOKAHEAD);
4392 bool is_positive = (group_type == POSITIVE_LOOKAHEAD);
4393 body = new(zone()) RegExpLookahead(body,
4395 end_capture_index - capture_index,
4398 builder->AddAtom(body);
4399 // For compatability with JSC and ES3, we allow quantifiers after
4400 // lookaheads, and break in all cases.
4405 builder->NewAlternative();
4411 return ReportError(CStrVector("Nothing to repeat"));
4415 builder->AddAssertion(
4416 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE));
4418 builder->AddAssertion(
4419 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
4420 set_contains_anchor();
4426 RegExpAssertion::AssertionType assertion_type =
4427 multiline_ ? RegExpAssertion::END_OF_LINE :
4428 RegExpAssertion::END_OF_INPUT;
4429 builder->AddAssertion(new(zone()) RegExpAssertion(assertion_type));
4434 // everything except \x0a, \x0d, \u2028 and \u2029
4435 ZoneList<CharacterRange>* ranges =
4436 new(zone()) ZoneList<CharacterRange>(2, zone());
4437 CharacterRange::AddClassEscape('.', ranges, zone());
4438 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
4439 builder->AddAtom(atom);
4443 SubexpressionType subexpr_type = CAPTURE;
4445 if (current() == '?') {
4448 subexpr_type = GROUPING;
4451 subexpr_type = POSITIVE_LOOKAHEAD;
4454 subexpr_type = NEGATIVE_LOOKAHEAD;
4457 ReportError(CStrVector("Invalid group") CHECK_FAILED);
4462 if (captures_ == NULL) {
4463 captures_ = new(zone()) ZoneList<RegExpCapture*>(2, zone());
4465 if (captures_started() >= kMaxCaptures) {
4466 ReportError(CStrVector("Too many captures") CHECK_FAILED);
4468 captures_->Add(NULL, zone());
4470 // Store current state and begin new disjunction parsing.
4471 stored_state = new(zone()) RegExpParserState(stored_state, subexpr_type,
4472 captures_started(), zone());
4473 builder = stored_state->builder();
4477 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED);
4478 builder->AddAtom(atom);
4486 return ReportError(CStrVector("\\ at end of pattern"));
4489 builder->AddAssertion(
4490 new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
4494 builder->AddAssertion(
4495 new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
4498 // CharacterClassEscape
4500 // CharacterClassEscape :: one of
4502 case 'd': case 'D': case 's': case 'S': case 'w': case 'W': {
4505 ZoneList<CharacterRange>* ranges =
4506 new(zone()) ZoneList<CharacterRange>(2, zone());
4507 CharacterRange::AddClassEscape(c, ranges, zone());
4508 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
4509 builder->AddAtom(atom);
4512 case '1': case '2': case '3': case '4': case '5': case '6':
4513 case '7': case '8': case '9': {
4515 if (ParseBackReferenceIndex(&index)) {
4516 RegExpCapture* capture = NULL;
4517 if (captures_ != NULL && index <= captures_->length()) {
4518 capture = captures_->at(index - 1);
4520 if (capture == NULL) {
4521 builder->AddEmpty();
4524 RegExpTree* atom = new(zone()) RegExpBackReference(capture);
4525 builder->AddAtom(atom);
4528 uc32 first_digit = Next();
4529 if (first_digit == '8' || first_digit == '9') {
4530 // Treat as identity escape
4531 builder->AddCharacter(first_digit);
4539 uc32 octal = ParseOctalLiteral();
4540 builder->AddCharacter(octal);
4543 // ControlEscape :: one of
4547 builder->AddCharacter('\f');
4551 builder->AddCharacter('\n');
4555 builder->AddCharacter('\r');
4559 builder->AddCharacter('\t');
4563 builder->AddCharacter('\v');
4567 uc32 controlLetter = Next();
4568 // Special case if it is an ASCII letter.
4569 // Convert lower case letters to uppercase.
4570 uc32 letter = controlLetter & ~('a' ^ 'A');
4571 if (letter < 'A' || 'Z' < letter) {
4572 // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
4573 // This is outside the specification. We match JSC in
4574 // reading the backslash as a literal character instead
4575 // of as starting an escape.
4576 builder->AddCharacter('\\');
4579 builder->AddCharacter(controlLetter & 0x1f);
4586 if (ParseHexEscape(2, &value)) {
4587 builder->AddCharacter(value);
4589 builder->AddCharacter('x');
4596 if (ParseHexEscape(4, &value)) {
4597 builder->AddCharacter(value);
4599 builder->AddCharacter('u');
4605 builder->AddCharacter(Next());
4612 if (ParseIntervalQuantifier(&dummy, &dummy)) {
4613 ReportError(CStrVector("Nothing to repeat") CHECK_FAILED);
4618 builder->AddCharacter(current());
4621 } // end switch(current())
4625 switch (current()) {
4626 // QuantifierPrefix ::
4633 max = RegExpTree::kInfinity;
4638 max = RegExpTree::kInfinity;
4647 if (ParseIntervalQuantifier(&min, &max)) {
4649 ReportError(CStrVector("numbers out of order in {} quantifier.")
4659 RegExpQuantifier::QuantifierType quantifier_type = RegExpQuantifier::GREEDY;
4660 if (current() == '?') {
4661 quantifier_type = RegExpQuantifier::NON_GREEDY;
4663 } else if (FLAG_regexp_possessive_quantifier && current() == '+') {
4664 // FLAG_regexp_possessive_quantifier is a debug-only flag.
4665 quantifier_type = RegExpQuantifier::POSSESSIVE;
4668 builder->AddQuantifierToAtom(min, max, quantifier_type);
4674 // Currently only used in an DCHECK.
4675 static bool IsSpecialClassEscape(uc32 c) {
4688 // In order to know whether an escape is a backreference or not we have to scan
4689 // the entire regexp and find the number of capturing parentheses. However we
4690 // don't want to scan the regexp twice unless it is necessary. This mini-parser
4691 // is called when needed. It can see the difference between capturing and
4692 // noncapturing parentheses and can skip character classes and backslash-escaped
4694 void RegExpParser::ScanForCaptures() {
4695 // Start with captures started previous to current position
4696 int capture_count = captures_started();
4697 // Add count of captures after this position.
4699 while ((n = current()) != kEndMarker) {
4707 while ((c = current()) != kEndMarker) {
4712 if (c == ']') break;
4718 if (current() != '?') capture_count++;
4722 capture_count_ = capture_count;
4723 is_scanned_for_captures_ = true;
4727 bool RegExpParser::ParseBackReferenceIndex(int* index_out) {
4728 DCHECK_EQ('\\', current());
4729 DCHECK('1' <= Next() && Next() <= '9');
4730 // Try to parse a decimal literal that is no greater than the total number
4731 // of left capturing parentheses in the input.
4732 int start = position();
4733 int value = Next() - '0';
4737 if (IsDecimalDigit(c)) {
4738 value = 10 * value + (c - '0');
4739 if (value > kMaxCaptures) {
4748 if (value > captures_started()) {
4749 if (!is_scanned_for_captures_) {
4750 int saved_position = position();
4752 Reset(saved_position);
4754 if (value > capture_count_) {
4764 // QuantifierPrefix ::
4765 // { DecimalDigits }
4766 // { DecimalDigits , }
4767 // { DecimalDigits , DecimalDigits }
4769 // Returns true if parsing succeeds, and set the min_out and max_out
4770 // values. Values are truncated to RegExpTree::kInfinity if they overflow.
4771 bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
4772 DCHECK_EQ(current(), '{');
4773 int start = position();
4776 if (!IsDecimalDigit(current())) {
4780 while (IsDecimalDigit(current())) {
4781 int next = current() - '0';
4782 if (min > (RegExpTree::kInfinity - next) / 10) {
4783 // Overflow. Skip past remaining decimal digits and return -1.
4786 } while (IsDecimalDigit(current()));
4787 min = RegExpTree::kInfinity;
4790 min = 10 * min + next;
4794 if (current() == '}') {
4797 } else if (current() == ',') {
4799 if (current() == '}') {
4800 max = RegExpTree::kInfinity;
4803 while (IsDecimalDigit(current())) {
4804 int next = current() - '0';
4805 if (max > (RegExpTree::kInfinity - next) / 10) {
4808 } while (IsDecimalDigit(current()));
4809 max = RegExpTree::kInfinity;
4812 max = 10 * max + next;
4815 if (current() != '}') {
4831 uc32 RegExpParser::ParseOctalLiteral() {
4832 DCHECK(('0' <= current() && current() <= '7') || current() == kEndMarker);
4833 // For compatibility with some other browsers (not all), we parse
4834 // up to three octal digits with a value below 256.
4835 uc32 value = current() - '0';
4837 if ('0' <= current() && current() <= '7') {
4838 value = value * 8 + current() - '0';
4840 if (value < 32 && '0' <= current() && current() <= '7') {
4841 value = value * 8 + current() - '0';
4849 bool RegExpParser::ParseHexEscape(int length, uc32 *value) {
4850 int start = position();
4853 for (int i = 0; !done; i++) {
4855 int d = HexValue(c);
4862 if (i == length - 1) {
4871 uc32 RegExpParser::ParseClassCharacterEscape() {
4872 DCHECK(current() == '\\');
4873 DCHECK(has_next() && !IsSpecialClassEscape(Next()));
4875 switch (current()) {
4879 // ControlEscape :: one of
4897 uc32 controlLetter = Next();
4898 uc32 letter = controlLetter & ~('A' ^ 'a');
4899 // For compatibility with JSC, inside a character class
4900 // we also accept digits and underscore as control characters.
4901 if ((controlLetter >= '0' && controlLetter <= '9') ||
4902 controlLetter == '_' ||
4903 (letter >= 'A' && letter <= 'Z')) {
4905 // Control letters mapped to ASCII control characters in the range
4907 return controlLetter & 0x1f;
4909 // We match JSC in reading the backslash as a literal
4910 // character instead of as starting an escape.
4913 case '0': case '1': case '2': case '3': case '4': case '5':
4915 // For compatibility, we interpret a decimal escape that isn't
4916 // a back reference (and therefore either \0 or not valid according
4917 // to the specification) as a 1..3 digit octal character code.
4918 return ParseOctalLiteral();
4922 if (ParseHexEscape(2, &value)) {
4925 // If \x is not followed by a two-digit hexadecimal, treat it
4926 // as an identity escape.
4932 if (ParseHexEscape(4, &value)) {
4935 // If \u is not followed by a four-digit hexadecimal, treat it
4936 // as an identity escape.
4940 // Extended identity escape. We accept any character that hasn't
4941 // been matched by a more specific case, not just the subset required
4942 // by the ECMAScript specification.
4943 uc32 result = current();
4952 CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) {
4953 DCHECK_EQ(0, *char_class);
4954 uc32 first = current();
4955 if (first == '\\') {
4957 case 'w': case 'W': case 'd': case 'D': case 's': case 'S': {
4958 *char_class = Next();
4960 return CharacterRange::Singleton(0); // Return dummy value.
4963 return ReportError(CStrVector("\\ at end of pattern"));
4965 uc32 c = ParseClassCharacterEscape(CHECK_FAILED);
4966 return CharacterRange::Singleton(c);
4970 return CharacterRange::Singleton(first);
4975 static const uc16 kNoCharClass = 0;
4977 // Adds range or pre-defined character class to character ranges.
4978 // If char_class is not kInvalidClass, it's interpreted as a class
4979 // escape (i.e., 's' means whitespace, from '\s').
4980 static inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges,
4982 CharacterRange range,
4984 if (char_class != kNoCharClass) {
4985 CharacterRange::AddClassEscape(char_class, ranges, zone);
4987 ranges->Add(range, zone);
4992 RegExpTree* RegExpParser::ParseCharacterClass() {
4993 static const char* kUnterminated = "Unterminated character class";
4994 static const char* kRangeOutOfOrder = "Range out of order in character class";
4996 DCHECK_EQ(current(), '[');
4998 bool is_negated = false;
4999 if (current() == '^') {
5003 ZoneList<CharacterRange>* ranges =
5004 new(zone()) ZoneList<CharacterRange>(2, zone());
5005 while (has_more() && current() != ']') {
5006 uc16 char_class = kNoCharClass;
5007 CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED);
5008 if (current() == '-') {
5010 if (current() == kEndMarker) {
5011 // If we reach the end we break out of the loop and let the
5012 // following code report an error.
5014 } else if (current() == ']') {
5015 AddRangeOrEscape(ranges, char_class, first, zone());
5016 ranges->Add(CharacterRange::Singleton('-'), zone());
5019 uc16 char_class_2 = kNoCharClass;
5020 CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED);
5021 if (char_class != kNoCharClass || char_class_2 != kNoCharClass) {
5022 // Either end is an escaped character class. Treat the '-' verbatim.
5023 AddRangeOrEscape(ranges, char_class, first, zone());
5024 ranges->Add(CharacterRange::Singleton('-'), zone());
5025 AddRangeOrEscape(ranges, char_class_2, next, zone());
5028 if (first.from() > next.to()) {
5029 return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED);
5031 ranges->Add(CharacterRange::Range(first.from(), next.to()), zone());
5033 AddRangeOrEscape(ranges, char_class, first, zone());
5037 return ReportError(CStrVector(kUnterminated) CHECK_FAILED);
5040 if (ranges->length() == 0) {
5041 ranges->Add(CharacterRange::Everything(), zone());
5042 is_negated = !is_negated;
5044 return new(zone()) RegExpCharacterClass(ranges, is_negated);
5048 // ----------------------------------------------------------------------------
5049 // The Parser interface.
5051 bool RegExpParser::ParseRegExp(FlatStringReader* input,
5053 RegExpCompileData* result,
5055 DCHECK(result != NULL);
5056 RegExpParser parser(input, &result->error, multiline, zone);
5057 RegExpTree* tree = parser.ParsePattern();
5058 if (parser.failed()) {
5059 DCHECK(tree == NULL);
5060 DCHECK(!result->error.is_null());
5062 DCHECK(tree != NULL);
5063 DCHECK(result->error.is_null());
5064 result->tree = tree;
5065 int capture_count = parser.captures_started();
5066 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
5067 result->contains_anchor = parser.contains_anchor();
5068 result->capture_count = capture_count;
5070 return !parser.failed();
5074 bool Parser::Parse() {
5075 DCHECK(info()->function() == NULL);
5076 FunctionLiteral* result = NULL;
5077 pre_parse_timer_ = isolate()->counters()->pre_parse();
5078 if (FLAG_trace_parse || allow_natives_syntax() || extension_ != NULL) {
5079 // If intrinsics are allowed, the Parser cannot operate independent of the
5080 // V8 heap because of Runtime. Tell the string table to internalize strings
5081 // and values right after they're created.
5082 ast_value_factory()->Internalize(isolate());
5085 if (info()->is_lazy()) {
5086 DCHECK(!info()->is_eval());
5087 if (info()->shared_info()->is_function()) {
5088 result = ParseLazy();
5090 result = ParseProgram();
5094 result = ParseProgram();
5096 info()->SetFunction(result);
5099 DCHECK(ast_value_factory()->IsInternalized());
5100 return (result != NULL);
5104 void Parser::ParseOnBackground() {
5105 DCHECK(info()->function() == NULL);
5106 FunctionLiteral* result = NULL;
5107 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
5109 CompleteParserRecorder recorder;
5110 if (compile_options() == ScriptCompiler::kProduceParserCache) {
5114 DCHECK(info()->source_stream() != NULL);
5115 ExternalStreamingStream stream(info()->source_stream(),
5116 info()->source_stream_encoding());
5117 scanner_.Initialize(&stream);
5118 DCHECK(info()->context().is_null() || info()->context()->IsNativeContext());
5120 // When streaming, we don't know the length of the source until we have parsed
5121 // it. The raw data can be UTF-8, so we wouldn't know the source length until
5122 // we have decoded it anyway even if we knew the raw data length (which we
5123 // don't). We work around this by storing all the scopes which need their end
5124 // position set at the end of the script (the top scope and possible eval
5125 // scopes) and set their end position after we know the script length.
5126 Scope* top_scope = NULL;
5127 Scope* eval_scope = NULL;
5128 result = DoParseProgram(info(), &top_scope, &eval_scope);
5130 top_scope->set_end_position(scanner()->location().end_pos);
5131 if (eval_scope != NULL) {
5132 eval_scope->set_end_position(scanner()->location().end_pos);
5135 info()->SetFunction(result);
5137 // We cannot internalize on a background thread; a foreground task will take
5138 // care of calling Parser::Internalize just before compilation.
5140 if (compile_options() == ScriptCompiler::kProduceParserCache) {
5141 if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
5145 } } // namespace v8::internal