1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include "bootstrapper.h"
33 #include "char-predicates-inl.h"
36 #include "func-name-inferrer.h"
40 #include "preparser.h"
42 #include "scanner-character-streams.h"
43 #include "scopeinfo.h"
44 #include "string-stream.h"
49 // PositionStack is used for on-stack allocation of token positions for
50 // new expressions. Please look at ParseNewExpression.
54 explicit PositionStack(bool* ok) : top_(NULL), ok_(ok) {}
56 ASSERT(!*ok_ || is_empty());
62 Element(PositionStack* stack, int value) {
63 previous_ = stack->top();
69 Element* previous() { return previous_; }
70 int value() { return value_; }
71 friend class PositionStack;
76 bool is_empty() { return top_ == NULL; }
79 int result = top_->value();
80 top_ = top_->previous();
85 Element* top() { return top_; }
86 void set_top(Element* value) { top_ = value; }
92 RegExpBuilder::RegExpBuilder(Zone* zone)
94 pending_empty_(false),
99 , last_added_(ADD_NONE)
104 void RegExpBuilder::FlushCharacters() {
105 pending_empty_ = false;
106 if (characters_ != NULL) {
107 RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector());
109 text_.Add(atom, zone());
115 void RegExpBuilder::FlushText() {
117 int num_text = text_.length();
120 } else if (num_text == 1) {
121 terms_.Add(text_.last(), zone());
123 RegExpText* text = new(zone()) RegExpText(zone());
124 for (int i = 0; i < num_text; i++)
125 text_.Get(i)->AppendToText(text, zone());
126 terms_.Add(text, zone());
132 void RegExpBuilder::AddCharacter(uc16 c) {
133 pending_empty_ = false;
134 if (characters_ == NULL) {
135 characters_ = new(zone()) ZoneList<uc16>(4, zone());
137 characters_->Add(c, zone());
142 void RegExpBuilder::AddEmpty() {
143 pending_empty_ = true;
147 void RegExpBuilder::AddAtom(RegExpTree* term) {
148 if (term->IsEmpty()) {
152 if (term->IsTextElement()) {
154 text_.Add(term, zone());
157 terms_.Add(term, zone());
163 void RegExpBuilder::AddAssertion(RegExpTree* assert) {
165 terms_.Add(assert, zone());
170 void RegExpBuilder::NewAlternative() {
175 void RegExpBuilder::FlushTerms() {
177 int num_terms = terms_.length();
178 RegExpTree* alternative;
179 if (num_terms == 0) {
180 alternative = RegExpEmpty::GetInstance();
181 } else if (num_terms == 1) {
182 alternative = terms_.last();
184 alternative = new(zone()) RegExpAlternative(terms_.GetList(zone()));
186 alternatives_.Add(alternative, zone());
192 RegExpTree* RegExpBuilder::ToRegExp() {
194 int num_alternatives = alternatives_.length();
195 if (num_alternatives == 0) {
196 return RegExpEmpty::GetInstance();
198 if (num_alternatives == 1) {
199 return alternatives_.last();
201 return new(zone()) RegExpDisjunction(alternatives_.GetList(zone()));
205 void RegExpBuilder::AddQuantifierToAtom(
206 int min, int max, RegExpQuantifier::QuantifierType quantifier_type) {
207 if (pending_empty_) {
208 pending_empty_ = false;
212 if (characters_ != NULL) {
213 ASSERT(last_added_ == ADD_CHAR);
214 // Last atom was character.
215 Vector<const uc16> char_vector = characters_->ToConstVector();
216 int num_chars = char_vector.length();
218 Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1);
219 text_.Add(new(zone()) RegExpAtom(prefix), zone());
220 char_vector = char_vector.SubVector(num_chars - 1, num_chars);
223 atom = new(zone()) RegExpAtom(char_vector);
225 } else if (text_.length() > 0) {
226 ASSERT(last_added_ == ADD_ATOM);
227 atom = text_.RemoveLast();
229 } else if (terms_.length() > 0) {
230 ASSERT(last_added_ == ADD_ATOM);
231 atom = terms_.RemoveLast();
232 if (atom->max_match() == 0) {
233 // Guaranteed to only match an empty string.
238 terms_.Add(atom, zone());
242 // Only call immediately after adding an atom or character!
247 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone());
252 Handle<String> Parser::LookupSymbol(int symbol_id) {
253 // Length of symbol cache is the number of identified symbols.
254 // If we are larger than that, or negative, it's not a cached symbol.
255 // This might also happen if there is no preparser symbol data, even
256 // if there is some preparser data.
257 if (static_cast<unsigned>(symbol_id)
258 >= static_cast<unsigned>(symbol_cache_.length())) {
259 if (scanner().is_literal_ascii()) {
260 return isolate()->factory()->InternalizeOneByteString(
261 Vector<const uint8_t>::cast(scanner().literal_ascii_string()));
263 return isolate()->factory()->InternalizeTwoByteString(
264 scanner().literal_utf16_string());
267 return LookupCachedSymbol(symbol_id);
271 Handle<String> Parser::LookupCachedSymbol(int symbol_id) {
272 // Make sure the cache is large enough to hold the symbol identifier.
273 if (symbol_cache_.length() <= symbol_id) {
274 // Increase length to index + 1.
275 symbol_cache_.AddBlock(Handle<String>::null(),
276 symbol_id + 1 - symbol_cache_.length(), zone());
278 Handle<String> result = symbol_cache_.at(symbol_id);
279 if (result.is_null()) {
280 if (scanner().is_literal_ascii()) {
281 result = isolate()->factory()->InternalizeOneByteString(
282 Vector<const uint8_t>::cast(scanner().literal_ascii_string()));
284 result = isolate()->factory()->InternalizeTwoByteString(
285 scanner().literal_utf16_string());
287 symbol_cache_.at(symbol_id) = result;
290 isolate()->counters()->total_preparse_symbols_skipped()->Increment();
295 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) {
296 // The current pre-data entry must be a FunctionEntry with the given
298 if ((function_index_ + FunctionEntry::kSize <= store_.length())
299 && (static_cast<int>(store_[function_index_]) == start)) {
300 int index = function_index_;
301 function_index_ += FunctionEntry::kSize;
302 return FunctionEntry(store_.SubVector(index,
303 index + FunctionEntry::kSize));
305 return FunctionEntry();
309 int ScriptDataImpl::GetSymbolIdentifier() {
310 return ReadNumber(&symbol_data_);
314 bool ScriptDataImpl::SanityCheck() {
315 // Check that the header data is valid and doesn't specify
316 // point to positions outside the store.
317 if (store_.length() < PreparseDataConstants::kHeaderSize) return false;
318 if (magic() != PreparseDataConstants::kMagicNumber) return false;
319 if (version() != PreparseDataConstants::kCurrentVersion) return false;
321 // Extra sane sanity check for error message encoding.
322 if (store_.length() <= PreparseDataConstants::kHeaderSize
323 + PreparseDataConstants::kMessageTextPos) {
326 if (Read(PreparseDataConstants::kMessageStartPos) >
327 Read(PreparseDataConstants::kMessageEndPos)) {
330 unsigned arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
331 int pos = PreparseDataConstants::kMessageTextPos;
332 for (unsigned int i = 0; i <= arg_count; i++) {
333 if (store_.length() <= PreparseDataConstants::kHeaderSize + pos) {
336 int length = static_cast<int>(Read(pos));
337 if (length < 0) return false;
340 if (store_.length() < PreparseDataConstants::kHeaderSize + pos) {
345 // Check that the space allocated for function entries is sane.
347 static_cast<int>(store_[PreparseDataConstants::kFunctionsSizeOffset]);
348 if (functions_size < 0) return false;
349 if (functions_size % FunctionEntry::kSize != 0) return false;
350 // Check that the count of symbols is non-negative.
352 static_cast<int>(store_[PreparseDataConstants::kSymbolCountOffset]);
353 if (symbol_count < 0) return false;
354 // Check that the total size has room for header and function entries.
356 PreparseDataConstants::kHeaderSize + functions_size;
357 if (store_.length() < minimum_size) return false;
363 const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) {
364 int length = start[0];
365 char* result = NewArray<char>(length + 1);
366 for (int i = 0; i < length; i++) {
367 result[i] = start[i + 1];
369 result[length] = '\0';
370 if (chars != NULL) *chars = length;
375 Scanner::Location ScriptDataImpl::MessageLocation() {
376 int beg_pos = Read(PreparseDataConstants::kMessageStartPos);
377 int end_pos = Read(PreparseDataConstants::kMessageEndPos);
378 return Scanner::Location(beg_pos, end_pos);
382 const char* ScriptDataImpl::BuildMessage() {
383 unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos);
384 return ReadString(start, NULL);
388 Vector<const char*> ScriptDataImpl::BuildArgs() {
389 int arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
390 const char** array = NewArray<const char*>(arg_count);
391 // Position after text found by skipping past length field and
392 // length field content words.
393 int pos = PreparseDataConstants::kMessageTextPos + 1
394 + Read(PreparseDataConstants::kMessageTextPos);
395 for (int i = 0; i < arg_count; i++) {
397 array[i] = ReadString(ReadAddress(pos), &count);
400 return Vector<const char*>(array, arg_count);
404 unsigned ScriptDataImpl::Read(int position) {
405 return store_[PreparseDataConstants::kHeaderSize + position];
409 unsigned* ScriptDataImpl::ReadAddress(int position) {
410 return &store_[PreparseDataConstants::kHeaderSize + position];
414 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) {
415 Scope* result = new(zone()) Scope(parent, scope_type, zone());
416 result->Initialize();
421 // ----------------------------------------------------------------------------
422 // Target is a support class to facilitate manipulation of the
423 // Parser's target_stack_ (the stack of potential 'break' and
424 // 'continue' statement targets). Upon construction, a new target is
425 // added; it is removed upon destruction.
427 class Target BASE_EMBEDDED {
429 Target(Target** variable, AstNode* node)
430 : variable_(variable), node_(node), previous_(*variable) {
435 *variable_ = previous_;
438 Target* previous() { return previous_; }
439 AstNode* node() { return node_; }
448 class TargetScope BASE_EMBEDDED {
450 explicit TargetScope(Target** variable)
451 : variable_(variable), previous_(*variable) {
456 *variable_ = previous_;
465 // ----------------------------------------------------------------------------
466 // FunctionState and BlockState together implement the parser's scope stack.
467 // The parser's current scope is in top_scope_. The BlockState and
468 // FunctionState constructors push on the scope stack and the destructors
469 // pop. They are also used to hold the parser's per-function and per-block
472 class Parser::BlockState BASE_EMBEDDED {
474 BlockState(Parser* parser, Scope* scope)
476 outer_scope_(parser->top_scope_) {
477 parser->top_scope_ = scope;
480 ~BlockState() { parser_->top_scope_ = outer_scope_; }
488 Parser::FunctionState::FunctionState(Parser* parser, Scope* scope)
489 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
490 next_handler_index_(0),
491 expected_property_count_(0),
492 generator_object_variable_(NULL),
494 outer_function_state_(parser->current_function_state_),
495 outer_scope_(parser->top_scope_),
496 saved_ast_node_id_(parser->zone()->isolate()->ast_node_id()),
497 factory_(parser->zone()) {
498 parser->top_scope_ = scope;
499 parser->current_function_state_ = this;
500 parser->zone()->isolate()->set_ast_node_id(BailoutId::FirstUsable().ToInt());
504 Parser::FunctionState::~FunctionState() {
505 parser_->top_scope_ = outer_scope_;
506 parser_->current_function_state_ = outer_function_state_;
507 if (outer_function_state_ != NULL) {
508 parser_->isolate()->set_ast_node_id(saved_ast_node_id_);
513 // ----------------------------------------------------------------------------
514 // The CHECK_OK macro is a convenient macro to enforce error
515 // handling for functions that may fail (by returning !*ok).
517 // CAUTION: This macro appends extra statements after a call,
518 // thus it must never be used where only a single statement
519 // is correct (e.g. an if statement branch w/o braces)!
521 #define CHECK_OK ok); \
522 if (!*ok) return NULL; \
524 #define DUMMY ) // to make indentation work
527 #define CHECK_FAILED /**/); \
528 if (failed_) return NULL; \
530 #define DUMMY ) // to make indentation work
533 // ----------------------------------------------------------------------------
534 // Implementation of Parser
536 Parser::Parser(CompilationInfo* info)
537 : ParserBase(&scanner_, info->isolate()->stack_guard()->real_climit()),
538 isolate_(info->isolate()),
539 symbol_cache_(0, info->zone()),
540 script_(info->script()),
541 scanner_(isolate_->unicode_cache()),
542 reusable_preparser_(NULL),
544 original_scope_(NULL),
545 current_function_state_(NULL),
547 extension_(info->extension()),
548 pre_parse_data_(NULL),
550 parenthesized_function_(false),
553 ASSERT(!script_.is_null());
554 isolate_->set_ast_node_id(0);
555 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping);
556 set_allow_modules(!info->is_native() && FLAG_harmony_modules);
557 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native());
558 set_allow_lazy(false); // Must be explicitly enabled.
559 set_allow_generators(FLAG_harmony_generators);
560 set_allow_for_of(FLAG_harmony_iteration);
561 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
565 FunctionLiteral* Parser::ParseProgram() {
566 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
567 // see comment for HistogramTimerScope class.
568 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true);
569 Handle<String> source(String::cast(script_->source()));
570 isolate()->counters()->total_parse_size()->Increment(source->length());
572 if (FLAG_trace_parse) {
575 fni_ = new(zone()) FuncNameInferrer(isolate(), zone());
577 // Initialize parser state.
578 source->TryFlatten();
579 FunctionLiteral* result;
580 if (source->IsExternalTwoByteString()) {
581 // Notice that the stream is destroyed at the end of the branch block.
582 // The last line of the blocks can't be moved outside, even though they're
584 ExternalTwoByteStringUtf16CharacterStream stream(
585 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
586 scanner_.Initialize(&stream);
587 result = DoParseProgram(info(), source);
589 GenericStringUtf16CharacterStream stream(source, 0, source->length());
590 scanner_.Initialize(&stream);
591 result = DoParseProgram(info(), source);
594 if (FLAG_trace_parse && result != NULL) {
595 double ms = timer.Elapsed().InMillisecondsF();
596 if (info()->is_eval()) {
597 PrintF("[parsing eval");
598 } else if (info()->script()->name()->IsString()) {
599 String* name = String::cast(info()->script()->name());
600 SmartArrayPointer<char> name_chars = name->ToCString();
601 PrintF("[parsing script: %s", name_chars.get());
603 PrintF("[parsing script");
605 PrintF(" - took %0.3f ms]\n", ms);
611 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
612 Handle<String> source) {
613 ASSERT(top_scope_ == NULL);
614 ASSERT(target_stack_ == NULL);
615 if (pre_parse_data_ != NULL) pre_parse_data_->Initialize();
617 Handle<String> no_name = isolate()->factory()->empty_string();
619 FunctionLiteral* result = NULL;
620 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE);
621 info->SetGlobalScope(scope);
622 if (!info->context().is_null()) {
623 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone());
625 original_scope_ = scope;
626 if (info->is_eval()) {
627 if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) {
628 scope = NewScope(scope, EVAL_SCOPE);
630 } else if (info->is_global()) {
631 scope = NewScope(scope, GLOBAL_SCOPE);
633 scope->set_start_position(0);
634 scope->set_end_position(source->length());
636 // Compute the parsing mode.
637 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY;
638 if (allow_natives_syntax() ||
639 extension_ != NULL ||
640 scope->is_eval_scope()) {
641 mode = PARSE_EAGERLY;
643 ParsingModeScope parsing_mode(this, mode);
646 FunctionState function_state(this, scope);
648 top_scope_->SetLanguageMode(info->language_mode());
649 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
651 int beg_pos = scanner().location().beg_pos;
652 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok);
653 if (ok && !top_scope_->is_classic_mode()) {
654 CheckOctalLiteral(beg_pos, scanner().location().end_pos, &ok);
657 if (ok && is_extended_mode()) {
658 CheckConflictingVarDeclarations(top_scope_, &ok);
661 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
662 if (body->length() != 1 ||
663 !body->at(0)->IsExpressionStatement() ||
664 !body->at(0)->AsExpressionStatement()->
665 expression()->IsFunctionLiteral()) {
666 ReportMessage("single_function_literal", Vector<const char*>::empty());
672 result = factory()->NewFunctionLiteral(
676 function_state.materialized_literal_count(),
677 function_state.expected_property_count(),
678 function_state.handler_count(),
680 FunctionLiteral::kNoDuplicateParameters,
681 FunctionLiteral::ANONYMOUS_EXPRESSION,
682 FunctionLiteral::kGlobalOrEval,
683 FunctionLiteral::kNotParenthesized,
684 FunctionLiteral::kNotGenerator,
686 result->set_ast_properties(factory()->visitor()->ast_properties());
687 result->set_dont_optimize_reason(
688 factory()->visitor()->dont_optimize_reason());
689 } else if (stack_overflow()) {
690 isolate()->StackOverflow();
694 // Make sure the target stack is empty.
695 ASSERT(target_stack_ == NULL);
701 FunctionLiteral* Parser::ParseLazy() {
702 HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy());
703 Handle<String> source(String::cast(script_->source()));
704 isolate()->counters()->total_parse_size()->Increment(source->length());
706 if (FLAG_trace_parse) {
709 Handle<SharedFunctionInfo> shared_info = info()->shared_info();
711 // Initialize parser state.
712 source->TryFlatten();
713 FunctionLiteral* result;
714 if (source->IsExternalTwoByteString()) {
715 ExternalTwoByteStringUtf16CharacterStream stream(
716 Handle<ExternalTwoByteString>::cast(source),
717 shared_info->start_position(),
718 shared_info->end_position());
719 result = ParseLazy(&stream);
721 GenericStringUtf16CharacterStream stream(source,
722 shared_info->start_position(),
723 shared_info->end_position());
724 result = ParseLazy(&stream);
727 if (FLAG_trace_parse && result != NULL) {
728 double ms = timer.Elapsed().InMillisecondsF();
729 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString();
730 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
736 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) {
737 Handle<SharedFunctionInfo> shared_info = info()->shared_info();
738 scanner_.Initialize(source);
739 ASSERT(top_scope_ == NULL);
740 ASSERT(target_stack_ == NULL);
742 Handle<String> name(String::cast(shared_info->name()));
743 fni_ = new(zone()) FuncNameInferrer(isolate(), zone());
744 fni_->PushEnclosingName(name);
746 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
748 // Place holder for the result.
749 FunctionLiteral* result = NULL;
752 // Parse the function literal.
753 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE);
754 info()->SetGlobalScope(scope);
755 if (!info()->closure().is_null()) {
756 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope,
759 original_scope_ = scope;
760 FunctionState function_state(this, scope);
761 ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode());
762 ASSERT(scope->language_mode() != EXTENDED_MODE ||
763 info()->is_extended_mode());
764 ASSERT(info()->language_mode() == shared_info->language_mode());
765 scope->SetLanguageMode(shared_info->language_mode());
766 FunctionLiteral::FunctionType function_type = shared_info->is_expression()
767 ? (shared_info->is_anonymous()
768 ? FunctionLiteral::ANONYMOUS_EXPRESSION
769 : FunctionLiteral::NAMED_EXPRESSION)
770 : FunctionLiteral::DECLARATION;
772 result = ParseFunctionLiteral(name,
773 false, // Strict mode name already checked.
774 shared_info->is_generator(),
775 RelocInfo::kNoPosition,
778 // Make sure the results agree.
779 ASSERT(ok == (result != NULL));
782 // Make sure the target stack is empty.
783 ASSERT(target_stack_ == NULL);
785 if (result == NULL) {
786 if (stack_overflow()) isolate()->StackOverflow();
788 Handle<String> inferred_name(shared_info->inferred_name());
789 result->set_inferred_name(inferred_name);
795 Handle<String> Parser::GetSymbol() {
797 if (pre_parse_data() != NULL) {
798 symbol_id = pre_parse_data()->GetSymbolIdentifier();
800 return LookupSymbol(symbol_id);
804 void Parser::ReportMessage(const char* message, Vector<const char*> args) {
805 Scanner::Location source_location = scanner().location();
806 ReportMessageAt(source_location, message, args);
810 void Parser::ReportMessage(const char* message, Vector<Handle<String> > args) {
811 Scanner::Location source_location = scanner().location();
812 ReportMessageAt(source_location, message, args);
816 void Parser::ReportMessageAt(Scanner::Location source_location,
818 Vector<const char*> args) {
819 MessageLocation location(script_,
820 source_location.beg_pos,
821 source_location.end_pos);
822 Factory* factory = isolate()->factory();
823 Handle<FixedArray> elements = factory->NewFixedArray(args.length());
824 for (int i = 0; i < args.length(); i++) {
825 Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i]));
826 elements->set(i, *arg_string);
828 Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
829 Handle<Object> result = factory->NewSyntaxError(message, array);
830 isolate()->Throw(*result, &location);
834 void Parser::ReportMessageAt(Scanner::Location source_location,
836 Vector<Handle<String> > args) {
837 MessageLocation location(script_,
838 source_location.beg_pos,
839 source_location.end_pos);
840 Factory* factory = isolate()->factory();
841 Handle<FixedArray> elements = factory->NewFixedArray(args.length());
842 for (int i = 0; i < args.length(); i++) {
843 elements->set(i, *args[i]);
845 Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
846 Handle<Object> result = factory->NewSyntaxError(message, array);
847 isolate()->Throw(*result, &location);
851 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
857 // (ModuleElement)* <end_token>
859 // Allocate a target stack to use for this set of source
860 // elements. This way, all scripts and functions get their own
861 // target stack thus avoiding illegal breaks and continues across
863 TargetScope scope(&this->target_stack_);
865 ASSERT(processor != NULL);
866 bool directive_prologue = true; // Parsing directive prologue.
868 while (peek() != end_token) {
869 if (directive_prologue && peek() != Token::STRING) {
870 directive_prologue = false;
873 Scanner::Location token_loc = scanner().peek_location();
875 if (is_global && !is_eval) {
876 stat = ParseModuleElement(NULL, CHECK_OK);
878 stat = ParseBlockElement(NULL, CHECK_OK);
880 if (stat == NULL || stat->IsEmpty()) {
881 directive_prologue = false; // End of directive prologue.
885 if (directive_prologue) {
886 // A shot at a directive.
887 ExpressionStatement* e_stat;
889 // Still processing directive prologue?
890 if ((e_stat = stat->AsExpressionStatement()) != NULL &&
891 (literal = e_stat->expression()->AsLiteral()) != NULL &&
892 literal->value()->IsString()) {
893 Handle<String> directive = Handle<String>::cast(literal->value());
895 // Check "use strict" directive (ES5 14.1).
896 if (top_scope_->is_classic_mode() &&
897 directive->Equals(isolate()->heap()->use_strict_string()) &&
898 token_loc.end_pos - token_loc.beg_pos ==
899 isolate()->heap()->use_strict_string()->length() + 2) {
900 // TODO(mstarzinger): Global strict eval calls, need their own scope
901 // as specified in ES5 10.4.2(3). The correct fix would be to always
902 // add this scope in DoParseProgram(), but that requires adaptations
903 // all over the code base, so we go with a quick-fix for now.
904 // In the same manner, we have to patch the parsing mode.
905 if (is_eval && !top_scope_->is_eval_scope()) {
906 ASSERT(top_scope_->is_global_scope());
907 Scope* scope = NewScope(top_scope_, EVAL_SCOPE);
908 scope->set_start_position(top_scope_->start_position());
909 scope->set_end_position(top_scope_->end_position());
911 mode_ = PARSE_EAGERLY;
913 // TODO(ES6): Fix entering extended mode, once it is specified.
914 top_scope_->SetLanguageMode(allow_harmony_scoping()
915 ? EXTENDED_MODE : STRICT_MODE);
916 // "use strict" is the only directive for now.
917 directive_prologue = false;
920 // End of the directive prologue.
921 directive_prologue = false;
925 processor->Add(stat, zone());
932 Statement* Parser::ParseModuleElement(ZoneStringList* labels,
934 // (Ecma 262 5th Edition, clause 14):
937 // FunctionDeclaration
939 // In harmony mode we allow additionally the following productions
946 // GeneratorDeclaration
949 case Token::FUNCTION:
950 return ParseFunctionDeclaration(NULL, ok);
953 return ParseVariableStatement(kModuleElement, NULL, ok);
955 return ParseImportDeclaration(ok);
957 return ParseExportDeclaration(ok);
959 Statement* stmt = ParseStatement(labels, CHECK_OK);
960 // Handle 'module' as a context-sensitive keyword.
961 if (FLAG_harmony_modules &&
962 peek() == Token::IDENTIFIER &&
963 !scanner().HasAnyLineTerminatorBeforeNext() &&
965 ExpressionStatement* estmt = stmt->AsExpressionStatement();
967 estmt->expression()->AsVariableProxy() != NULL &&
968 estmt->expression()->AsVariableProxy()->name()->Equals(
969 isolate()->heap()->module_string()) &&
970 !scanner().literal_contains_escapes()) {
971 return ParseModuleDeclaration(NULL, ok);
980 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) {
981 // ModuleDeclaration:
982 // 'module' Identifier Module
984 int pos = peek_position();
985 Handle<String> name = ParseIdentifier(CHECK_OK);
988 if (FLAG_print_interface_details)
989 PrintF("# Module %s...\n", name->ToAsciiArray());
992 Module* module = ParseModule(CHECK_OK);
993 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface());
994 Declaration* declaration =
995 factory()->NewModuleDeclaration(proxy, module, top_scope_, pos);
996 Declare(declaration, true, CHECK_OK);
999 if (FLAG_print_interface_details)
1000 PrintF("# Module %s.\n", name->ToAsciiArray());
1002 if (FLAG_print_interfaces) {
1003 PrintF("module %s : ", name->ToAsciiArray());
1004 module->interface()->Print();
1008 if (names) names->Add(name, zone());
1009 if (module->body() == NULL)
1010 return factory()->NewEmptyStatement(pos);
1012 return factory()->NewModuleStatement(proxy, module->body(), pos);
1016 Module* Parser::ParseModule(bool* ok) {
1018 // '{' ModuleElement '}'
1019 // '=' ModulePath ';'
1024 return ParseModuleLiteral(ok);
1026 case Token::ASSIGN: {
1027 Expect(Token::ASSIGN, CHECK_OK);
1028 Module* result = ParseModulePath(CHECK_OK);
1029 ExpectSemicolon(CHECK_OK);
1034 ExpectContextualKeyword(CStrVector("at"), CHECK_OK);
1035 Module* result = ParseModuleUrl(CHECK_OK);
1036 ExpectSemicolon(CHECK_OK);
1043 Module* Parser::ParseModuleLiteral(bool* ok) {
1045 // '{' ModuleElement '}'
1047 int pos = peek_position();
1048 // Construct block expecting 16 statements.
1049 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition);
1051 if (FLAG_print_interface_details) PrintF("# Literal ");
1053 Scope* scope = NewScope(top_scope_, MODULE_SCOPE);
1055 Expect(Token::LBRACE, CHECK_OK);
1056 scope->set_start_position(scanner().location().beg_pos);
1057 scope->SetLanguageMode(EXTENDED_MODE);
1060 BlockState block_state(this, scope);
1061 TargetCollector collector(zone());
1062 Target target(&this->target_stack_, &collector);
1063 Target target_body(&this->target_stack_, body);
1065 while (peek() != Token::RBRACE) {
1066 Statement* stat = ParseModuleElement(NULL, CHECK_OK);
1067 if (stat && !stat->IsEmpty()) {
1068 body->AddStatement(stat, zone());
1073 Expect(Token::RBRACE, CHECK_OK);
1074 scope->set_end_position(scanner().location().end_pos);
1075 body->set_scope(scope);
1077 // Check that all exports are bound.
1078 Interface* interface = scope->interface();
1079 for (Interface::Iterator it = interface->iterator();
1080 !it.done(); it.Advance()) {
1081 if (scope->LocalLookup(it.name()) == NULL) {
1082 Handle<String> name(it.name());
1083 ReportMessage("module_export_undefined",
1084 Vector<Handle<String> >(&name, 1));
1090 interface->MakeModule(ok);
1092 interface->Freeze(ok);
1094 return factory()->NewModuleLiteral(body, interface, pos);
1098 Module* Parser::ParseModulePath(bool* ok) {
1101 // ModulePath '.' Identifier
1103 int pos = peek_position();
1104 Module* result = ParseModuleVariable(CHECK_OK);
1105 while (Check(Token::PERIOD)) {
1106 Handle<String> name = ParseIdentifierName(CHECK_OK);
1108 if (FLAG_print_interface_details)
1109 PrintF("# Path .%s ", name->ToAsciiArray());
1111 Module* member = factory()->NewModulePath(result, name, pos);
1112 result->interface()->Add(name, member->interface(), zone(), ok);
1115 if (FLAG_print_interfaces) {
1116 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray());
1118 result->interface()->Print();
1120 member->interface()->Print();
1123 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1));
1133 Module* Parser::ParseModuleVariable(bool* ok) {
1137 int pos = peek_position();
1138 Handle<String> name = ParseIdentifier(CHECK_OK);
1140 if (FLAG_print_interface_details)
1141 PrintF("# Module variable %s ", name->ToAsciiArray());
1143 VariableProxy* proxy = top_scope_->NewUnresolved(
1144 factory(), name, Interface::NewModule(zone()),
1145 scanner().location().beg_pos);
1147 return factory()->NewModuleVariable(proxy, pos);
1151 Module* Parser::ParseModuleUrl(bool* ok) {
1155 int pos = peek_position();
1156 Expect(Token::STRING, CHECK_OK);
1157 Handle<String> symbol = GetSymbol();
1159 // TODO(ES6): Request JS resource from environment...
1162 if (FLAG_print_interface_details) PrintF("# Url ");
1165 // Create an empty literal as long as the feature isn't finished.
1167 Scope* scope = NewScope(top_scope_, MODULE_SCOPE);
1168 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
1169 body->set_scope(scope);
1170 Interface* interface = scope->interface();
1171 Module* result = factory()->NewModuleLiteral(body, interface, pos);
1172 interface->Freeze(ok);
1174 interface->Unify(scope->interface(), zone(), ok);
1180 Module* Parser::ParseModuleSpecifier(bool* ok) {
1185 if (peek() == Token::STRING) {
1186 return ParseModuleUrl(ok);
1188 return ParseModulePath(ok);
1193 Block* Parser::ParseImportDeclaration(bool* ok) {
1194 // ImportDeclaration:
1195 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';'
1197 // TODO(ES6): implement destructuring ImportSpecifiers
1199 int pos = peek_position();
1200 Expect(Token::IMPORT, CHECK_OK);
1201 ZoneStringList names(1, zone());
1203 Handle<String> name = ParseIdentifierName(CHECK_OK);
1204 names.Add(name, zone());
1205 while (peek() == Token::COMMA) {
1206 Consume(Token::COMMA);
1207 name = ParseIdentifierName(CHECK_OK);
1208 names.Add(name, zone());
1211 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1212 Module* module = ParseModuleSpecifier(CHECK_OK);
1213 ExpectSemicolon(CHECK_OK);
1215 // Generate a separate declaration for each identifier.
1216 // TODO(ES6): once we implement destructuring, make that one declaration.
1217 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
1218 for (int i = 0; i < names.length(); ++i) {
1220 if (FLAG_print_interface_details)
1221 PrintF("# Import %s ", names[i]->ToAsciiArray());
1223 Interface* interface = Interface::NewUnknown(zone());
1224 module->interface()->Add(names[i], interface, zone(), ok);
1227 if (FLAG_print_interfaces) {
1228 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray());
1230 module->interface()->Print();
1233 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1));
1236 VariableProxy* proxy = NewUnresolved(names[i], LET, interface);
1237 Declaration* declaration =
1238 factory()->NewImportDeclaration(proxy, module, top_scope_, pos);
1239 Declare(declaration, true, CHECK_OK);
1246 Statement* Parser::ParseExportDeclaration(bool* ok) {
1247 // ExportDeclaration:
1248 // 'export' Identifier (',' Identifier)* ';'
1249 // 'export' VariableDeclaration
1250 // 'export' FunctionDeclaration
1251 // 'export' GeneratorDeclaration
1252 // 'export' ModuleDeclaration
1254 // TODO(ES6): implement structuring ExportSpecifiers
1256 Expect(Token::EXPORT, CHECK_OK);
1258 Statement* result = NULL;
1259 ZoneStringList names(1, zone());
1261 case Token::IDENTIFIER: {
1262 int pos = position();
1263 Handle<String> name = ParseIdentifier(CHECK_OK);
1264 // Handle 'module' as a context-sensitive keyword.
1265 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) {
1266 names.Add(name, zone());
1267 while (peek() == Token::COMMA) {
1268 Consume(Token::COMMA);
1269 name = ParseIdentifier(CHECK_OK);
1270 names.Add(name, zone());
1272 ExpectSemicolon(CHECK_OK);
1273 result = factory()->NewEmptyStatement(pos);
1275 result = ParseModuleDeclaration(&names, CHECK_OK);
1280 case Token::FUNCTION:
1281 result = ParseFunctionDeclaration(&names, CHECK_OK);
1287 result = ParseVariableStatement(kModuleElement, &names, CHECK_OK);
1292 ReportUnexpectedToken(scanner().current_token());
1296 // Extract declared names into export declarations and interface.
1297 Interface* interface = top_scope_->interface();
1298 for (int i = 0; i < names.length(); ++i) {
1300 if (FLAG_print_interface_details)
1301 PrintF("# Export %s ", names[i]->ToAsciiArray());
1303 Interface* inner = Interface::NewUnknown(zone());
1304 interface->Add(names[i], inner, zone(), CHECK_OK);
1307 VariableProxy* proxy = NewUnresolved(names[i], LET, inner);
1309 // TODO(rossberg): Rethink whether we actually need to store export
1310 // declarations (for compilation?).
1311 // ExportDeclaration* declaration =
1312 // factory()->NewExportDeclaration(proxy, top_scope_, position);
1313 // top_scope_->AddDeclaration(declaration);
1316 ASSERT(result != NULL);
1321 Statement* Parser::ParseBlockElement(ZoneStringList* labels,
1323 // (Ecma 262 5th Edition, clause 14):
1326 // FunctionDeclaration
1328 // In harmony mode we allow additionally the following productions
1329 // BlockElement (aka SourceElement):
1332 // GeneratorDeclaration
1335 case Token::FUNCTION:
1336 return ParseFunctionDeclaration(NULL, ok);
1339 return ParseVariableStatement(kModuleElement, NULL, ok);
1341 return ParseStatement(labels, ok);
1346 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
1349 // VariableStatement
1351 // ExpressionStatement
1353 // IterationStatement
1354 // ContinueStatement
1358 // LabelledStatement
1362 // DebuggerStatement
1364 // Note: Since labels can only be used by 'break' and 'continue'
1365 // statements, which themselves are only valid within blocks,
1366 // iterations or 'switch' statements (i.e., BreakableStatements),
1367 // labels can be simply ignored in all other cases; except for
1368 // trivial labeled break statements 'label: break label' which is
1369 // parsed into an empty statement.
1372 return ParseBlock(labels, ok);
1374 case Token::CONST: // fall through
1377 return ParseVariableStatement(kStatement, NULL, ok);
1379 case Token::SEMICOLON:
1381 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1384 return ParseIfStatement(labels, ok);
1387 return ParseDoWhileStatement(labels, ok);
1390 return ParseWhileStatement(labels, ok);
1393 return ParseForStatement(labels, ok);
1395 case Token::CONTINUE:
1396 return ParseContinueStatement(ok);
1399 return ParseBreakStatement(labels, ok);
1402 return ParseReturnStatement(ok);
1405 return ParseWithStatement(labels, ok);
1408 return ParseSwitchStatement(labels, ok);
1411 return ParseThrowStatement(ok);
1414 // NOTE: It is somewhat complicated to have labels on
1415 // try-statements. When breaking out of a try-finally statement,
1416 // one must take great care not to treat it as a
1417 // fall-through. It is much easier just to wrap the entire
1418 // try-statement in a statement block and put the labels there
1420 factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition);
1421 Target target(&this->target_stack_, result);
1422 TryStatement* statement = ParseTryStatement(CHECK_OK);
1423 if (result) result->AddStatement(statement, zone());
1427 case Token::FUNCTION: {
1428 // FunctionDeclaration is only allowed in the context of SourceElements
1429 // (Ecma 262 5th Edition, clause 14):
1432 // FunctionDeclaration
1433 // Common language extension is to allow function declaration in place
1434 // of any statement. This language extension is disabled in strict mode.
1436 // In Harmony mode, this case also handles the extension:
1438 // GeneratorDeclaration
1439 if (!top_scope_->is_classic_mode()) {
1440 ReportMessageAt(scanner().peek_location(), "strict_function",
1441 Vector<const char*>::empty());
1445 return ParseFunctionDeclaration(NULL, ok);
1448 case Token::DEBUGGER:
1449 return ParseDebuggerStatement(ok);
1452 return ParseExpressionOrLabelledStatement(labels, ok);
1457 VariableProxy* Parser::NewUnresolved(
1458 Handle<String> name, VariableMode mode, Interface* interface) {
1459 // If we are inside a function, a declaration of a var/const variable is a
1460 // truly local variable, and the scope of the variable is always the function
1462 // Let/const variables in harmony mode are always added to the immediately
1464 return DeclarationScope(mode)->NewUnresolved(
1465 factory(), name, interface, position());
1469 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
1470 VariableProxy* proxy = declaration->proxy();
1471 Handle<String> name = proxy->name();
1472 VariableMode mode = declaration->mode();
1473 Scope* declaration_scope = DeclarationScope(mode);
1474 Variable* var = NULL;
1476 // If a suitable scope exists, then we can statically declare this
1477 // variable and also set its mode. In any case, a Declaration node
1478 // will be added to the scope so that the declaration can be added
1479 // to the corresponding activation frame at runtime if necessary.
1480 // For instance declarations inside an eval scope need to be added
1481 // to the calling function context.
1482 // Similarly, strict mode eval scope does not leak variable declarations to
1483 // the caller's scope so we declare all locals, too.
1484 if (declaration_scope->is_function_scope() ||
1485 declaration_scope->is_strict_or_extended_eval_scope() ||
1486 declaration_scope->is_block_scope() ||
1487 declaration_scope->is_module_scope() ||
1488 declaration_scope->is_global_scope()) {
1489 // Declare the variable in the declaration scope.
1490 // For the global scope, we have to check for collisions with earlier
1491 // (i.e., enclosing) global scopes, to maintain the illusion of a single
1493 var = declaration_scope->is_global_scope()
1494 ? declaration_scope->Lookup(name)
1495 : declaration_scope->LocalLookup(name);
1497 // Declare the name.
1498 var = declaration_scope->DeclareLocal(
1499 name, mode, declaration->initialization(), proxy->interface());
1500 } else if ((mode != VAR || var->mode() != VAR) &&
1501 (!declaration_scope->is_global_scope() ||
1502 IsLexicalVariableMode(mode) ||
1503 IsLexicalVariableMode(var->mode()))) {
1504 // The name was declared in this scope before; check for conflicting
1505 // re-declarations. We have a conflict if either of the declarations is
1506 // not a var (in the global scope, we also have to ignore legacy const for
1507 // compatibility). There is similar code in runtime.cc in the Declare
1508 // functions. The function CheckNonConflictingScope checks for conflicting
1509 // var and let bindings from different scopes whereas this is a check for
1510 // conflicting declarations within the same scope. This check also covers
1513 // function () { let x; { var x; } }
1515 // because the var declaration is hoisted to the function scope where 'x'
1516 // is already bound.
1517 ASSERT(IsDeclaredVariableMode(var->mode()));
1518 if (is_extended_mode()) {
1519 // In harmony mode we treat re-declarations as early errors. See
1520 // ES5 16 for a definition of early errors.
1521 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
1522 const char* elms[2] = { "Variable", c_string.get() };
1523 Vector<const char*> args(elms, 2);
1524 ReportMessage("redeclaration", args);
1528 Handle<String> message_string =
1529 isolate()->factory()->NewStringFromUtf8(CStrVector("Variable"),
1531 Expression* expression =
1532 NewThrowTypeError(isolate()->factory()->redeclaration_string(),
1533 message_string, name);
1534 declaration_scope->SetIllegalRedeclaration(expression);
1538 // We add a declaration node for every declaration. The compiler
1539 // will only generate code if necessary. In particular, declarations
1540 // for inner local variables that do not represent functions won't
1541 // result in any generated code.
1543 // Note that we always add an unresolved proxy even if it's not
1544 // used, simply because we don't know in this method (w/o extra
1545 // parameters) if the proxy is needed or not. The proxy will be
1546 // bound during variable resolution time unless it was pre-bound
1549 // WARNING: This will lead to multiple declaration nodes for the
1550 // same variable if it is declared several times. This is not a
1551 // semantic issue as long as we keep the source order, but it may be
1552 // a performance issue since it may lead to repeated
1553 // Runtime::DeclareContextSlot() calls.
1554 declaration_scope->AddDeclaration(declaration);
1556 if (mode == CONST && declaration_scope->is_global_scope()) {
1557 // For global const variables we bind the proxy to a variable.
1558 ASSERT(resolve); // should be set by all callers
1559 Variable::Kind kind = Variable::NORMAL;
1560 var = new(zone()) Variable(
1561 declaration_scope, name, mode, true, kind,
1562 kNeedsInitialization, proxy->interface());
1563 } else if (declaration_scope->is_eval_scope() &&
1564 declaration_scope->is_classic_mode()) {
1565 // For variable declarations in a non-strict eval scope the proxy is bound
1566 // to a lookup variable to force a dynamic declaration using the
1567 // DeclareContextSlot runtime function.
1568 Variable::Kind kind = Variable::NORMAL;
1569 var = new(zone()) Variable(
1570 declaration_scope, name, mode, true, kind,
1571 declaration->initialization(), proxy->interface());
1572 var->AllocateTo(Variable::LOOKUP, -1);
1576 // If requested and we have a local variable, bind the proxy to the variable
1577 // at parse-time. This is used for functions (and consts) declared inside
1578 // statements: the corresponding function (or const) variable must be in the
1579 // function scope and not a statement-local scope, e.g. as provided with a
1580 // 'with' statement:
1586 // which is translated into:
1589 // // in this case this is not: 'var f; f = function () {};'
1590 // var f = function () {};
1593 // Note that if 'f' is accessed from inside the 'with' statement, it
1594 // will be allocated in the context (because we must be able to look
1595 // it up dynamically) but it will also be accessed statically, i.e.,
1596 // with a context slot index and a context chain length for this
1597 // initialization code. Thus, inside the 'with' statement, we need
1598 // both access to the static and the dynamic context chain; the
1599 // runtime needs to provide both.
1600 if (resolve && var != NULL) {
1603 if (FLAG_harmony_modules) {
1606 if (FLAG_print_interface_details)
1607 PrintF("# Declare %s\n", var->name()->ToAsciiArray());
1609 proxy->interface()->Unify(var->interface(), zone(), &ok);
1612 if (FLAG_print_interfaces) {
1613 PrintF("DECLARE TYPE ERROR\n");
1615 proxy->interface()->Print();
1617 var->interface()->Print();
1620 ReportMessage("module_type_error", Vector<Handle<String> >(&name, 1));
1627 // Language extension which is only enabled for source files loaded
1628 // through the API's extension mechanism. A native function
1629 // declaration is resolved by looking up the function through a
1630 // callback provided by the extension.
1631 Statement* Parser::ParseNativeDeclaration(bool* ok) {
1632 int pos = peek_position();
1633 Expect(Token::FUNCTION, CHECK_OK);
1634 Handle<String> name = ParseIdentifier(CHECK_OK);
1635 Expect(Token::LPAREN, CHECK_OK);
1636 bool done = (peek() == Token::RPAREN);
1638 ParseIdentifier(CHECK_OK);
1639 done = (peek() == Token::RPAREN);
1641 Expect(Token::COMMA, CHECK_OK);
1644 Expect(Token::RPAREN, CHECK_OK);
1645 Expect(Token::SEMICOLON, CHECK_OK);
1647 // Make sure that the function containing the native declaration
1648 // isn't lazily compiled. The extension structures are only
1649 // accessible while parsing the first time not when reparsing
1650 // because of lazy compilation.
1651 DeclarationScope(VAR)->ForceEagerCompilation();
1653 // TODO(1240846): It's weird that native function declarations are
1654 // introduced dynamically when we meet their declarations, whereas
1655 // other functions are set up when entering the surrounding scope.
1656 VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue());
1657 Declaration* declaration =
1658 factory()->NewVariableDeclaration(proxy, VAR, top_scope_, pos);
1659 Declare(declaration, true, CHECK_OK);
1660 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral(
1661 name, extension_, RelocInfo::kNoPosition);
1662 return factory()->NewExpressionStatement(
1663 factory()->NewAssignment(
1664 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition),
1669 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) {
1670 // FunctionDeclaration ::
1671 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
1672 // GeneratorDeclaration ::
1673 // 'function' '*' Identifier '(' FormalParameterListopt ')'
1674 // '{' FunctionBody '}'
1675 Expect(Token::FUNCTION, CHECK_OK);
1676 int pos = position();
1677 bool is_generator = allow_generators() && Check(Token::MUL);
1678 bool is_strict_reserved = false;
1679 Handle<String> name = ParseIdentifierOrStrictReservedWord(
1680 &is_strict_reserved, CHECK_OK);
1681 FunctionLiteral* fun = ParseFunctionLiteral(name,
1685 FunctionLiteral::DECLARATION,
1687 // Even if we're not at the top-level of the global or a function
1688 // scope, we treat it as such and introduce the function with its
1689 // initial value upon entering the corresponding scope.
1690 // In extended mode, a function behaves as a lexical binding, except in the
1693 is_extended_mode() && !top_scope_->is_global_scope() ? LET : VAR;
1694 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
1695 Declaration* declaration =
1696 factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_, pos);
1697 Declare(declaration, true, CHECK_OK);
1698 if (names) names->Add(name, zone());
1699 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1703 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) {
1704 if (top_scope_->is_extended_mode()) return ParseScopedBlock(labels, ok);
1707 // '{' Statement* '}'
1709 // Note that a Block does not introduce a new execution scope!
1710 // (ECMA-262, 3rd, 12.2)
1712 // Construct block expecting 16 statements.
1714 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
1715 Target target(&this->target_stack_, result);
1716 Expect(Token::LBRACE, CHECK_OK);
1717 while (peek() != Token::RBRACE) {
1718 Statement* stat = ParseStatement(NULL, CHECK_OK);
1719 if (stat && !stat->IsEmpty()) {
1720 result->AddStatement(stat, zone());
1723 Expect(Token::RBRACE, CHECK_OK);
1728 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) {
1729 // The harmony mode uses block elements instead of statements.
1732 // '{' BlockElement* '}'
1734 // Construct block expecting 16 statements.
1736 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
1737 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE);
1739 // Parse the statements and collect escaping labels.
1740 Expect(Token::LBRACE, CHECK_OK);
1741 block_scope->set_start_position(scanner().location().beg_pos);
1742 { BlockState block_state(this, block_scope);
1743 TargetCollector collector(zone());
1744 Target target(&this->target_stack_, &collector);
1745 Target target_body(&this->target_stack_, body);
1747 while (peek() != Token::RBRACE) {
1748 Statement* stat = ParseBlockElement(NULL, CHECK_OK);
1749 if (stat && !stat->IsEmpty()) {
1750 body->AddStatement(stat, zone());
1754 Expect(Token::RBRACE, CHECK_OK);
1755 block_scope->set_end_position(scanner().location().end_pos);
1756 block_scope = block_scope->FinalizeBlockScope();
1757 body->set_scope(block_scope);
1762 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
1763 ZoneStringList* names,
1765 // VariableStatement ::
1766 // VariableDeclarations ';'
1768 Handle<String> ignore;
1770 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK);
1771 ExpectSemicolon(CHECK_OK);
1776 bool Parser::IsEvalOrArguments(Handle<String> string) {
1777 return string.is_identical_to(isolate()->factory()->eval_string()) ||
1778 string.is_identical_to(isolate()->factory()->arguments_string());
1782 // If the variable declaration declares exactly one non-const
1783 // variable, then *out is set to that variable. In all other cases,
1784 // *out is untouched; in particular, it is the caller's responsibility
1785 // to initialize it properly. This mechanism is used for the parsing
1786 // of 'for-in' loops.
1787 Block* Parser::ParseVariableDeclarations(
1788 VariableDeclarationContext var_context,
1789 VariableDeclarationProperties* decl_props,
1790 ZoneStringList* names,
1791 Handle<String>* out,
1793 // VariableDeclarations ::
1794 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
1796 // The ES6 Draft Rev3 specifies the following grammar for const declarations
1798 // ConstDeclaration ::
1799 // const ConstBinding (',' ConstBinding)* ';'
1801 // Identifier '=' AssignmentExpression
1805 // BindingPattern '=' AssignmentExpression
1807 int pos = peek_position();
1808 VariableMode mode = VAR;
1809 // True if the binding needs initialization. 'let' and 'const' declared
1810 // bindings are created uninitialized by their declaration nodes and
1811 // need initialization. 'var' declared bindings are always initialized
1812 // immediately by their declaration nodes.
1813 bool needs_init = false;
1814 bool is_const = false;
1815 Token::Value init_op = Token::INIT_VAR;
1816 if (peek() == Token::VAR) {
1817 Consume(Token::VAR);
1818 } else if (peek() == Token::CONST) {
1819 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
1821 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
1823 // * It is a Syntax Error if the code that matches this production is not
1824 // contained in extended code.
1826 // However disallowing const in classic mode will break compatibility with
1827 // existing pages. Therefore we keep allowing const with the old
1828 // non-harmony semantics in classic mode.
1829 Consume(Token::CONST);
1830 switch (top_scope_->language_mode()) {
1833 init_op = Token::INIT_CONST;
1836 ReportMessage("strict_const", Vector<const char*>::empty());
1840 if (var_context == kStatement) {
1841 // In extended mode 'const' declarations are only allowed in source
1842 // element positions.
1843 ReportMessage("unprotected_const", Vector<const char*>::empty());
1847 mode = CONST_HARMONY;
1848 init_op = Token::INIT_CONST_HARMONY;
1852 } else if (peek() == Token::LET) {
1853 // ES6 Draft Rev4 section 12.2.1:
1855 // LetDeclaration : let LetBindingList ;
1857 // * It is a Syntax Error if the code that matches this production is not
1858 // contained in extended code.
1859 if (!is_extended_mode()) {
1860 ReportMessage("illegal_let", Vector<const char*>::empty());
1864 Consume(Token::LET);
1865 if (var_context == kStatement) {
1866 // Let declarations are only allowed in source element positions.
1867 ReportMessage("unprotected_let", Vector<const char*>::empty());
1873 init_op = Token::INIT_LET;
1875 UNREACHABLE(); // by current callers
1878 Scope* declaration_scope = DeclarationScope(mode);
1880 // The scope of a var/const declared variable anywhere inside a function
1881 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
1882 // transform a source-level var/const declaration into a (Function)
1883 // Scope declaration, and rewrite the source-level initialization into an
1884 // assignment statement. We use a block to collect multiple assignments.
1886 // We mark the block as initializer block because we don't want the
1887 // rewriter to add a '.result' assignment to such a block (to get compliant
1888 // behavior for code such as print(eval('var x = 7')), and for cosmetic
1889 // reasons when pretty-printing. Also, unless an assignment (initialization)
1890 // is inside an initializer block, it is ignored.
1892 // Create new block with one expected declaration.
1893 Block* block = factory()->NewBlock(NULL, 1, true, pos);
1894 int nvars = 0; // the number of variables declared
1895 Handle<String> name;
1897 if (fni_ != NULL) fni_->Enter();
1899 // Parse variable name.
1900 if (nvars > 0) Consume(Token::COMMA);
1901 name = ParseIdentifier(CHECK_OK);
1902 if (fni_ != NULL) fni_->PushVariableName(name);
1904 // Strict mode variables may not be named eval or arguments
1905 if (!declaration_scope->is_classic_mode() && IsEvalOrArguments(name)) {
1906 ReportMessage("strict_var_name", Vector<const char*>::empty());
1911 // Declare variable.
1912 // Note that we *always* must treat the initial value via a separate init
1913 // assignment for variables and constants because the value must be assigned
1914 // when the variable is encountered in the source. But the variable/constant
1915 // is declared (and set to 'undefined') upon entering the function within
1916 // which the variable or constant is declared. Only function variables have
1917 // an initial value in the declaration (because they are initialized upon
1918 // entering the function).
1920 // If we have a const declaration, in an inner scope, the proxy is always
1921 // bound to the declared variable (independent of possibly surrounding with
1923 // For let/const declarations in harmony mode, we can also immediately
1924 // pre-resolve the proxy because it resides in the same scope as the
1926 Interface* interface =
1927 is_const ? Interface::NewConst() : Interface::NewValue();
1928 VariableProxy* proxy = NewUnresolved(name, mode, interface);
1929 Declaration* declaration =
1930 factory()->NewVariableDeclaration(proxy, mode, top_scope_, pos);
1931 Declare(declaration, mode != VAR, CHECK_OK);
1933 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
1934 ReportMessageAt(scanner().location(), "too_many_variables",
1935 Vector<const char*>::empty());
1939 if (names) names->Add(name, zone());
1941 // Parse initialization expression if present and/or needed. A
1942 // declaration of the form:
1946 // is syntactic sugar for:
1950 // In particular, we need to re-lookup 'v' (in top_scope_, not
1951 // declaration_scope) as it may be a different 'v' than the 'v' in the
1952 // declaration (e.g., if we are inside a 'with' statement or 'catch'
1955 // However, note that const declarations are different! A const
1956 // declaration of the form:
1960 // is *not* syntactic sugar for:
1964 // The "variable" c initialized to x is the same as the declared
1965 // one - there is no re-lookup (see the last parameter of the
1966 // Declare() call above).
1968 Scope* initialization_scope = is_const ? declaration_scope : top_scope_;
1969 Expression* value = NULL;
1971 // Harmony consts have non-optional initializers.
1972 if (peek() == Token::ASSIGN || mode == CONST_HARMONY) {
1973 Expect(Token::ASSIGN, CHECK_OK);
1975 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
1976 // Don't infer if it is "a = function(){...}();"-like expression.
1978 value->AsCall() == NULL &&
1979 value->AsCallNew() == NULL) {
1982 fni_->RemoveLastFunction();
1984 if (decl_props != NULL) *decl_props = kHasInitializers;
1987 // Record the end position of the initializer.
1988 if (proxy->var() != NULL) {
1989 proxy->var()->set_initializer_position(position());
1992 // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
1993 if (value == NULL && needs_init) {
1994 value = GetLiteralUndefined(position());
1997 // Global variable declarations must be compiled in a specific
1998 // way. When the script containing the global variable declaration
1999 // is entered, the global variable must be declared, so that if it
2000 // doesn't exist (on the global object itself, see ES5 errata) it
2001 // gets created with an initial undefined value. This is handled
2002 // by the declarations part of the function representing the
2003 // top-level global code; see Runtime::DeclareGlobalVariable. If
2004 // it already exists (in the object or in a prototype), it is
2005 // *not* touched until the variable declaration statement is
2008 // Executing the variable declaration statement will always
2009 // guarantee to give the global object a "local" variable; a
2010 // variable defined in the global object and not in any
2011 // prototype. This way, global variable declarations can shadow
2012 // properties in the prototype chain, but only after the variable
2013 // declaration statement has been executed. This is important in
2014 // browsers where the global object (window) has lots of
2015 // properties defined in prototype objects.
2016 if (initialization_scope->is_global_scope() &&
2017 !IsLexicalVariableMode(mode)) {
2018 // Compute the arguments for the runtime call.
2019 ZoneList<Expression*>* arguments =
2020 new(zone()) ZoneList<Expression*>(3, zone());
2021 // We have at least 1 parameter.
2022 arguments->Add(factory()->NewLiteral(name, pos), zone());
2023 CallRuntime* initialize;
2026 arguments->Add(value, zone());
2027 value = NULL; // zap the value to avoid the unnecessary assignment
2029 // Construct the call to Runtime_InitializeConstGlobal
2030 // and add it to the initialization statement block.
2031 // Note that the function does different things depending on
2032 // the number of arguments (1 or 2).
2033 initialize = factory()->NewCallRuntime(
2034 isolate()->factory()->InitializeConstGlobal_string(),
2035 Runtime::FunctionForId(Runtime::kInitializeConstGlobal),
2039 // We may want to pass singleton to avoid Literal allocations.
2040 LanguageMode language_mode = initialization_scope->language_mode();
2041 arguments->Add(factory()->NewNumberLiteral(language_mode, pos), zone());
2043 // Be careful not to assign a value to the global variable if
2044 // we're in a with. The initialization value should not
2045 // necessarily be stored in the global object in that case,
2046 // which is why we need to generate a separate assignment node.
2047 if (value != NULL && !inside_with()) {
2048 arguments->Add(value, zone());
2049 value = NULL; // zap the value to avoid the unnecessary assignment
2052 // Construct the call to Runtime_InitializeVarGlobal
2053 // and add it to the initialization statement block.
2054 // Note that the function does different things depending on
2055 // the number of arguments (2 or 3).
2056 initialize = factory()->NewCallRuntime(
2057 isolate()->factory()->InitializeVarGlobal_string(),
2058 Runtime::FunctionForId(Runtime::kInitializeVarGlobal),
2062 block->AddStatement(
2063 factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition),
2065 } else if (needs_init) {
2066 // Constant initializations always assign to the declared constant which
2067 // is always at the function scope level. This is only relevant for
2068 // dynamically looked-up variables and constants (the start context for
2069 // constant lookups is always the function context, while it is the top
2070 // context for var declared variables). Sigh...
2071 // For 'let' and 'const' declared variables in harmony mode the
2072 // initialization also always assigns to the declared variable.
2073 ASSERT(proxy != NULL);
2074 ASSERT(proxy->var() != NULL);
2075 ASSERT(value != NULL);
2076 Assignment* assignment =
2077 factory()->NewAssignment(init_op, proxy, value, pos);
2078 block->AddStatement(
2079 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
2084 // Add an assignment node to the initialization statement block if we still
2085 // have a pending initialization value.
2086 if (value != NULL) {
2087 ASSERT(mode == VAR);
2088 // 'var' initializations are simply assignments (with all the consequences
2089 // if they are inside a 'with' statement - they may change a 'with' object
2091 VariableProxy* proxy =
2092 initialization_scope->NewUnresolved(factory(), name, interface);
2093 Assignment* assignment =
2094 factory()->NewAssignment(init_op, proxy, value, pos);
2095 block->AddStatement(
2096 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
2100 if (fni_ != NULL) fni_->Leave();
2101 } while (peek() == Token::COMMA);
2103 // If there was a single non-const declaration, return it in the output
2104 // parameter for possible use by for/in.
2105 if (nvars == 1 && !is_const) {
2113 static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) {
2114 ASSERT(!label.is_null());
2116 for (int i = labels->length(); i-- > 0; )
2117 if (labels->at(i).is_identical_to(label))
2124 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
2126 // ExpressionStatement | LabelledStatement ::
2128 // Identifier ':' Statement
2129 int pos = peek_position();
2130 bool starts_with_idenfifier = peek_any_identifier();
2131 Expression* expr = ParseExpression(true, CHECK_OK);
2132 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
2133 expr->AsVariableProxy() != NULL &&
2134 !expr->AsVariableProxy()->is_this()) {
2135 // Expression is a single identifier, and not, e.g., a parenthesized
2137 VariableProxy* var = expr->AsVariableProxy();
2138 Handle<String> label = var->name();
2139 // TODO(1240780): We don't check for redeclaration of labels
2140 // during preparsing since keeping track of the set of active
2141 // labels requires nontrivial changes to the way scopes are
2142 // structured. However, these are probably changes we want to
2143 // make later anyway so we should go back and fix this then.
2144 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
2145 SmartArrayPointer<char> c_string = label->ToCString(DISALLOW_NULLS);
2146 const char* elms[2] = { "Label", c_string.get() };
2147 Vector<const char*> args(elms, 2);
2148 ReportMessage("redeclaration", args);
2152 if (labels == NULL) {
2153 labels = new(zone()) ZoneStringList(4, zone());
2155 labels->Add(label, zone());
2156 // Remove the "ghost" variable that turned out to be a label
2157 // from the top scope. This way, we don't try to resolve it
2158 // during the scope processing.
2159 top_scope_->RemoveUnresolved(var);
2160 Expect(Token::COLON, CHECK_OK);
2161 return ParseStatement(labels, ok);
2164 // If we have an extension, we allow a native function declaration.
2165 // A native function declaration starts with "native function" with
2166 // no line-terminator between the two words.
2167 if (extension_ != NULL &&
2168 peek() == Token::FUNCTION &&
2169 !scanner().HasAnyLineTerminatorBeforeNext() &&
2171 expr->AsVariableProxy() != NULL &&
2172 expr->AsVariableProxy()->name()->Equals(
2173 isolate()->heap()->native_string()) &&
2174 !scanner().literal_contains_escapes()) {
2175 return ParseNativeDeclaration(ok);
2178 // Parsed expression statement, or the context-sensitive 'module' keyword.
2179 // Only expect semicolon in the former case.
2180 if (!FLAG_harmony_modules ||
2181 peek() != Token::IDENTIFIER ||
2182 scanner().HasAnyLineTerminatorBeforeNext() ||
2183 expr->AsVariableProxy() == NULL ||
2184 !expr->AsVariableProxy()->name()->Equals(
2185 isolate()->heap()->module_string()) ||
2186 scanner().literal_contains_escapes()) {
2187 ExpectSemicolon(CHECK_OK);
2189 return factory()->NewExpressionStatement(expr, pos);
2193 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) {
2195 // 'if' '(' Expression ')' Statement ('else' Statement)?
2197 int pos = peek_position();
2198 Expect(Token::IF, CHECK_OK);
2199 Expect(Token::LPAREN, CHECK_OK);
2200 Expression* condition = ParseExpression(true, CHECK_OK);
2201 Expect(Token::RPAREN, CHECK_OK);
2202 Statement* then_statement = ParseStatement(labels, CHECK_OK);
2203 Statement* else_statement = NULL;
2204 if (peek() == Token::ELSE) {
2206 else_statement = ParseStatement(labels, CHECK_OK);
2208 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2210 return factory()->NewIfStatement(
2211 condition, then_statement, else_statement, pos);
2215 Statement* Parser::ParseContinueStatement(bool* ok) {
2216 // ContinueStatement ::
2217 // 'continue' Identifier? ';'
2219 int pos = peek_position();
2220 Expect(Token::CONTINUE, CHECK_OK);
2221 Handle<String> label = Handle<String>::null();
2222 Token::Value tok = peek();
2223 if (!scanner().HasAnyLineTerminatorBeforeNext() &&
2224 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2225 label = ParseIdentifier(CHECK_OK);
2227 IterationStatement* target = NULL;
2228 target = LookupContinueTarget(label, CHECK_OK);
2229 if (target == NULL) {
2230 // Illegal continue statement.
2231 const char* message = "illegal_continue";
2232 Vector<Handle<String> > args;
2233 if (!label.is_null()) {
2234 message = "unknown_label";
2235 args = Vector<Handle<String> >(&label, 1);
2237 ReportMessageAt(scanner().location(), message, args);
2241 ExpectSemicolon(CHECK_OK);
2242 return factory()->NewContinueStatement(target, pos);
2246 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) {
2247 // BreakStatement ::
2248 // 'break' Identifier? ';'
2250 int pos = peek_position();
2251 Expect(Token::BREAK, CHECK_OK);
2252 Handle<String> label;
2253 Token::Value tok = peek();
2254 if (!scanner().HasAnyLineTerminatorBeforeNext() &&
2255 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2256 label = ParseIdentifier(CHECK_OK);
2258 // Parse labeled break statements that target themselves into
2259 // empty statements, e.g. 'l1: l2: l3: break l2;'
2260 if (!label.is_null() && ContainsLabel(labels, label)) {
2261 ExpectSemicolon(CHECK_OK);
2262 return factory()->NewEmptyStatement(pos);
2264 BreakableStatement* target = NULL;
2265 target = LookupBreakTarget(label, CHECK_OK);
2266 if (target == NULL) {
2267 // Illegal break statement.
2268 const char* message = "illegal_break";
2269 Vector<Handle<String> > args;
2270 if (!label.is_null()) {
2271 message = "unknown_label";
2272 args = Vector<Handle<String> >(&label, 1);
2274 ReportMessageAt(scanner().location(), message, args);
2278 ExpectSemicolon(CHECK_OK);
2279 return factory()->NewBreakStatement(target, pos);
2283 Statement* Parser::ParseReturnStatement(bool* ok) {
2284 // ReturnStatement ::
2285 // 'return' Expression? ';'
2287 // Consume the return token. It is necessary to do that before
2288 // reporting any errors on it, because of the way errors are
2289 // reported (underlining).
2290 Expect(Token::RETURN, CHECK_OK);
2291 int pos = position();
2293 Token::Value tok = peek();
2295 Expression* return_value;
2296 if (scanner().HasAnyLineTerminatorBeforeNext() ||
2297 tok == Token::SEMICOLON ||
2298 tok == Token::RBRACE ||
2299 tok == Token::EOS) {
2300 return_value = GetLiteralUndefined(position());
2302 return_value = ParseExpression(true, CHECK_OK);
2304 ExpectSemicolon(CHECK_OK);
2305 if (is_generator()) {
2306 Expression* generator = factory()->NewVariableProxy(
2307 current_function_state_->generator_object_variable());
2308 Expression* yield = factory()->NewYield(
2309 generator, return_value, Yield::FINAL, pos);
2310 result = factory()->NewExpressionStatement(yield, pos);
2312 result = factory()->NewReturnStatement(return_value, pos);
2315 // An ECMAScript program is considered syntactically incorrect if it
2316 // contains a return statement that is not within the body of a
2317 // function. See ECMA-262, section 12.9, page 67.
2319 // To be consistent with KJS we report the syntax error at runtime.
2320 Scope* declaration_scope = top_scope_->DeclarationScope();
2321 if (declaration_scope->is_global_scope() ||
2322 declaration_scope->is_eval_scope()) {
2323 Handle<String> message = isolate()->factory()->illegal_return_string();
2324 Expression* throw_error =
2325 NewThrowSyntaxError(message, Handle<Object>::null());
2326 return factory()->NewExpressionStatement(throw_error, pos);
2332 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) {
2334 // 'with' '(' Expression ')' Statement
2336 Expect(Token::WITH, CHECK_OK);
2337 int pos = position();
2339 if (!top_scope_->is_classic_mode()) {
2340 ReportMessage("strict_mode_with", Vector<const char*>::empty());
2345 Expect(Token::LPAREN, CHECK_OK);
2346 Expression* expr = ParseExpression(true, CHECK_OK);
2347 Expect(Token::RPAREN, CHECK_OK);
2349 top_scope_->DeclarationScope()->RecordWithStatement();
2350 Scope* with_scope = NewScope(top_scope_, WITH_SCOPE);
2352 { BlockState block_state(this, with_scope);
2353 with_scope->set_start_position(scanner().peek_location().beg_pos);
2354 stmt = ParseStatement(labels, CHECK_OK);
2355 with_scope->set_end_position(scanner().location().end_pos);
2357 return factory()->NewWithStatement(with_scope, expr, stmt, pos);
2361 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
2363 // 'case' Expression ':' Statement*
2364 // 'default' ':' Statement*
2366 Expression* label = NULL; // NULL expression indicates default case
2367 if (peek() == Token::CASE) {
2368 Expect(Token::CASE, CHECK_OK);
2369 label = ParseExpression(true, CHECK_OK);
2371 Expect(Token::DEFAULT, CHECK_OK);
2372 if (*default_seen_ptr) {
2373 ReportMessage("multiple_defaults_in_switch",
2374 Vector<const char*>::empty());
2378 *default_seen_ptr = true;
2380 Expect(Token::COLON, CHECK_OK);
2381 int pos = position();
2382 ZoneList<Statement*>* statements =
2383 new(zone()) ZoneList<Statement*>(5, zone());
2384 while (peek() != Token::CASE &&
2385 peek() != Token::DEFAULT &&
2386 peek() != Token::RBRACE) {
2387 Statement* stat = ParseStatement(NULL, CHECK_OK);
2388 statements->Add(stat, zone());
2391 return factory()->NewCaseClause(label, statements, pos);
2395 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels,
2397 // SwitchStatement ::
2398 // 'switch' '(' Expression ')' '{' CaseClause* '}'
2400 SwitchStatement* statement =
2401 factory()->NewSwitchStatement(labels, peek_position());
2402 Target target(&this->target_stack_, statement);
2404 Expect(Token::SWITCH, CHECK_OK);
2405 Expect(Token::LPAREN, CHECK_OK);
2406 Expression* tag = ParseExpression(true, CHECK_OK);
2407 Expect(Token::RPAREN, CHECK_OK);
2409 bool default_seen = false;
2410 ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4, zone());
2411 Expect(Token::LBRACE, CHECK_OK);
2412 while (peek() != Token::RBRACE) {
2413 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
2414 cases->Add(clause, zone());
2416 Expect(Token::RBRACE, CHECK_OK);
2418 if (statement) statement->Initialize(tag, cases);
2423 Statement* Parser::ParseThrowStatement(bool* ok) {
2424 // ThrowStatement ::
2425 // 'throw' Expression ';'
2427 Expect(Token::THROW, CHECK_OK);
2428 int pos = position();
2429 if (scanner().HasAnyLineTerminatorBeforeNext()) {
2430 ReportMessage("newline_after_throw", Vector<const char*>::empty());
2434 Expression* exception = ParseExpression(true, CHECK_OK);
2435 ExpectSemicolon(CHECK_OK);
2437 return factory()->NewExpressionStatement(
2438 factory()->NewThrow(exception, pos), pos);
2442 TryStatement* Parser::ParseTryStatement(bool* ok) {
2444 // 'try' Block Catch
2445 // 'try' Block Finally
2446 // 'try' Block Catch Finally
2449 // 'catch' '(' Identifier ')' Block
2454 Expect(Token::TRY, CHECK_OK);
2455 int pos = position();
2457 TargetCollector try_collector(zone());
2460 { Target target(&this->target_stack_, &try_collector);
2461 try_block = ParseBlock(NULL, CHECK_OK);
2464 Token::Value tok = peek();
2465 if (tok != Token::CATCH && tok != Token::FINALLY) {
2466 ReportMessage("no_catch_or_finally", Vector<const char*>::empty());
2471 // If we can break out from the catch block and there is a finally block,
2472 // then we will need to collect escaping targets from the catch
2473 // block. Since we don't know yet if there will be a finally block, we
2474 // always collect the targets.
2475 TargetCollector catch_collector(zone());
2476 Scope* catch_scope = NULL;
2477 Variable* catch_variable = NULL;
2478 Block* catch_block = NULL;
2479 Handle<String> name;
2480 if (tok == Token::CATCH) {
2481 Consume(Token::CATCH);
2483 Expect(Token::LPAREN, CHECK_OK);
2484 catch_scope = NewScope(top_scope_, CATCH_SCOPE);
2485 catch_scope->set_start_position(scanner().location().beg_pos);
2486 name = ParseIdentifier(CHECK_OK);
2488 if (!top_scope_->is_classic_mode() && IsEvalOrArguments(name)) {
2489 ReportMessage("strict_catch_variable", Vector<const char*>::empty());
2494 Expect(Token::RPAREN, CHECK_OK);
2496 if (peek() == Token::LBRACE) {
2497 Target target(&this->target_stack_, &catch_collector);
2498 VariableMode mode = is_extended_mode() ? LET : VAR;
2500 catch_scope->DeclareLocal(name, mode, kCreatedInitialized);
2502 BlockState block_state(this, catch_scope);
2503 catch_block = ParseBlock(NULL, CHECK_OK);
2505 Expect(Token::LBRACE, CHECK_OK);
2507 catch_scope->set_end_position(scanner().location().end_pos);
2511 Block* finally_block = NULL;
2512 if (tok == Token::FINALLY || catch_block == NULL) {
2513 Consume(Token::FINALLY);
2514 finally_block = ParseBlock(NULL, CHECK_OK);
2517 // Simplify the AST nodes by converting:
2518 // 'try B0 catch B1 finally B2'
2520 // 'try { try B0 catch B1 } finally B2'
2522 if (catch_block != NULL && finally_block != NULL) {
2523 // If we have both, create an inner try/catch.
2524 ASSERT(catch_scope != NULL && catch_variable != NULL);
2525 int index = current_function_state_->NextHandlerIndex();
2526 TryCatchStatement* statement = factory()->NewTryCatchStatement(
2527 index, try_block, catch_scope, catch_variable, catch_block,
2528 RelocInfo::kNoPosition);
2529 statement->set_escaping_targets(try_collector.targets());
2530 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
2531 try_block->AddStatement(statement, zone());
2532 catch_block = NULL; // Clear to indicate it's been handled.
2535 TryStatement* result = NULL;
2536 if (catch_block != NULL) {
2537 ASSERT(finally_block == NULL);
2538 ASSERT(catch_scope != NULL && catch_variable != NULL);
2539 int index = current_function_state_->NextHandlerIndex();
2540 result = factory()->NewTryCatchStatement(
2541 index, try_block, catch_scope, catch_variable, catch_block, pos);
2543 ASSERT(finally_block != NULL);
2544 int index = current_function_state_->NextHandlerIndex();
2545 result = factory()->NewTryFinallyStatement(
2546 index, try_block, finally_block, pos);
2547 // Combine the jump targets of the try block and the possible catch block.
2548 try_collector.targets()->AddAll(*catch_collector.targets(), zone());
2551 result->set_escaping_targets(try_collector.targets());
2556 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels,
2559 // 'do' Statement 'while' '(' Expression ')' ';'
2561 DoWhileStatement* loop =
2562 factory()->NewDoWhileStatement(labels, peek_position());
2563 Target target(&this->target_stack_, loop);
2565 Expect(Token::DO, CHECK_OK);
2566 Statement* body = ParseStatement(NULL, CHECK_OK);
2567 Expect(Token::WHILE, CHECK_OK);
2568 Expect(Token::LPAREN, CHECK_OK);
2570 Expression* cond = ParseExpression(true, CHECK_OK);
2571 Expect(Token::RPAREN, CHECK_OK);
2573 // Allow do-statements to be terminated with and without
2574 // semi-colons. This allows code such as 'do;while(0)return' to
2575 // parse, which would not be the case if we had used the
2576 // ExpectSemicolon() functionality here.
2577 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
2579 if (loop != NULL) loop->Initialize(cond, body);
2584 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) {
2585 // WhileStatement ::
2586 // 'while' '(' Expression ')' Statement
2588 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position());
2589 Target target(&this->target_stack_, loop);
2591 Expect(Token::WHILE, CHECK_OK);
2592 Expect(Token::LPAREN, CHECK_OK);
2593 Expression* cond = ParseExpression(true, CHECK_OK);
2594 Expect(Token::RPAREN, CHECK_OK);
2595 Statement* body = ParseStatement(NULL, CHECK_OK);
2597 if (loop != NULL) loop->Initialize(cond, body);
2602 bool Parser::CheckInOrOf(bool accept_OF,
2603 ForEachStatement::VisitMode* visit_mode) {
2604 if (Check(Token::IN)) {
2605 *visit_mode = ForEachStatement::ENUMERATE;
2607 } else if (allow_for_of() && accept_OF &&
2608 CheckContextualKeyword(CStrVector("of"))) {
2609 *visit_mode = ForEachStatement::ITERATE;
2616 void Parser::InitializeForEachStatement(ForEachStatement* stmt,
2618 Expression* subject,
2620 ForOfStatement* for_of = stmt->AsForOfStatement();
2622 if (for_of != NULL) {
2623 Factory* heap_factory = isolate()->factory();
2624 Variable* iterator = top_scope_->DeclarationScope()->NewTemporary(
2625 heap_factory->dot_iterator_string());
2626 Variable* result = top_scope_->DeclarationScope()->NewTemporary(
2627 heap_factory->dot_result_string());
2629 Expression* assign_iterator;
2630 Expression* next_result;
2631 Expression* result_done;
2632 Expression* assign_each;
2634 // var iterator = iterable;
2636 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
2637 assign_iterator = factory()->NewAssignment(
2638 Token::ASSIGN, iterator_proxy, subject, RelocInfo::kNoPosition);
2641 // var result = iterator.next();
2643 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
2644 Expression* next_literal = factory()->NewLiteral(
2645 heap_factory->next_string(), RelocInfo::kNoPosition);
2646 Expression* next_property = factory()->NewProperty(
2647 iterator_proxy, next_literal, RelocInfo::kNoPosition);
2648 ZoneList<Expression*>* next_arguments =
2649 new(zone()) ZoneList<Expression*>(0, zone());
2650 Expression* next_call = factory()->NewCall(
2651 next_property, next_arguments, RelocInfo::kNoPosition);
2652 Expression* result_proxy = factory()->NewVariableProxy(result);
2653 next_result = factory()->NewAssignment(
2654 Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition);
2659 Expression* done_literal = factory()->NewLiteral(
2660 heap_factory->done_string(), RelocInfo::kNoPosition);
2661 Expression* result_proxy = factory()->NewVariableProxy(result);
2662 result_done = factory()->NewProperty(
2663 result_proxy, done_literal, RelocInfo::kNoPosition);
2666 // each = result.value
2668 Expression* value_literal = factory()->NewLiteral(
2669 heap_factory->value_string(), RelocInfo::kNoPosition);
2670 Expression* result_proxy = factory()->NewVariableProxy(result);
2671 Expression* result_value = factory()->NewProperty(
2672 result_proxy, value_literal, RelocInfo::kNoPosition);
2673 assign_each = factory()->NewAssignment(
2674 Token::ASSIGN, each, result_value, RelocInfo::kNoPosition);
2677 for_of->Initialize(each, subject, body,
2678 assign_iterator, next_result, result_done, assign_each);
2680 stmt->Initialize(each, subject, body);
2685 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
2687 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
2689 int pos = peek_position();
2690 Statement* init = NULL;
2692 // Create an in-between scope for let-bound iteration variables.
2693 Scope* saved_scope = top_scope_;
2694 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE);
2695 top_scope_ = for_scope;
2697 Expect(Token::FOR, CHECK_OK);
2698 Expect(Token::LPAREN, CHECK_OK);
2699 for_scope->set_start_position(scanner().location().beg_pos);
2700 if (peek() != Token::SEMICOLON) {
2701 if (peek() == Token::VAR || peek() == Token::CONST) {
2702 bool is_const = peek() == Token::CONST;
2703 Handle<String> name;
2704 VariableDeclarationProperties decl_props = kHasNoInitializers;
2705 Block* variable_statement =
2706 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
2708 bool accept_OF = decl_props == kHasNoInitializers;
2709 ForEachStatement::VisitMode mode;
2711 if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) {
2712 Interface* interface =
2713 is_const ? Interface::NewConst() : Interface::NewValue();
2714 ForEachStatement* loop =
2715 factory()->NewForEachStatement(mode, labels, pos);
2716 Target target(&this->target_stack_, loop);
2718 Expression* enumerable = ParseExpression(true, CHECK_OK);
2719 Expect(Token::RPAREN, CHECK_OK);
2721 VariableProxy* each =
2722 top_scope_->NewUnresolved(factory(), name, interface);
2723 Statement* body = ParseStatement(NULL, CHECK_OK);
2724 InitializeForEachStatement(loop, each, enumerable, body);
2726 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
2727 result->AddStatement(variable_statement, zone());
2728 result->AddStatement(loop, zone());
2729 top_scope_ = saved_scope;
2730 for_scope->set_end_position(scanner().location().end_pos);
2731 for_scope = for_scope->FinalizeBlockScope();
2732 ASSERT(for_scope == NULL);
2733 // Parsed for-in loop w/ variable/const declaration.
2736 init = variable_statement;
2738 } else if (peek() == Token::LET) {
2739 Handle<String> name;
2740 VariableDeclarationProperties decl_props = kHasNoInitializers;
2741 Block* variable_statement =
2742 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
2744 bool accept_IN = !name.is_null() && decl_props != kHasInitializers;
2745 bool accept_OF = decl_props == kHasNoInitializers;
2746 ForEachStatement::VisitMode mode;
2748 if (accept_IN && CheckInOrOf(accept_OF, &mode)) {
2749 // Rewrite a for-in statement of the form
2751 // for (let x in e) b
2755 // <let x' be a temporary variable>
2762 // TODO(keuchel): Move the temporary variable to the block scope, after
2763 // implementing stack allocated block scoped variables.
2764 Factory* heap_factory = isolate()->factory();
2765 Handle<String> tempstr =
2766 heap_factory->NewConsString(heap_factory->dot_for_string(), name);
2767 Handle<String> tempname = heap_factory->InternalizeString(tempstr);
2768 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname);
2769 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
2770 ForEachStatement* loop =
2771 factory()->NewForEachStatement(mode, labels, pos);
2772 Target target(&this->target_stack_, loop);
2774 // The expression does not see the loop variable.
2775 top_scope_ = saved_scope;
2776 Expression* enumerable = ParseExpression(true, CHECK_OK);
2777 top_scope_ = for_scope;
2778 Expect(Token::RPAREN, CHECK_OK);
2780 VariableProxy* each =
2781 top_scope_->NewUnresolved(factory(), name, Interface::NewValue());
2782 Statement* body = ParseStatement(NULL, CHECK_OK);
2784 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
2785 Assignment* assignment = factory()->NewAssignment(
2786 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition);
2787 Statement* assignment_statement = factory()->NewExpressionStatement(
2788 assignment, RelocInfo::kNoPosition);
2789 body_block->AddStatement(variable_statement, zone());
2790 body_block->AddStatement(assignment_statement, zone());
2791 body_block->AddStatement(body, zone());
2792 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block);
2793 top_scope_ = saved_scope;
2794 for_scope->set_end_position(scanner().location().end_pos);
2795 for_scope = for_scope->FinalizeBlockScope();
2796 body_block->set_scope(for_scope);
2797 // Parsed for-in loop w/ let declaration.
2801 init = variable_statement;
2804 Expression* expression = ParseExpression(false, CHECK_OK);
2805 ForEachStatement::VisitMode mode;
2806 bool accept_OF = expression->AsVariableProxy();
2808 if (CheckInOrOf(accept_OF, &mode)) {
2809 // Signal a reference error if the expression is an invalid
2810 // left-hand side expression. We could report this as a syntax
2811 // error here but for compatibility with JSC we choose to report
2812 // the error at runtime.
2813 if (expression == NULL || !expression->IsValidLeftHandSide()) {
2814 Handle<String> message =
2815 isolate()->factory()->invalid_lhs_in_for_in_string();
2816 expression = NewThrowReferenceError(message);
2818 ForEachStatement* loop =
2819 factory()->NewForEachStatement(mode, labels, pos);
2820 Target target(&this->target_stack_, loop);
2822 Expression* enumerable = ParseExpression(true, CHECK_OK);
2823 Expect(Token::RPAREN, CHECK_OK);
2825 Statement* body = ParseStatement(NULL, CHECK_OK);
2826 InitializeForEachStatement(loop, expression, enumerable, body);
2827 top_scope_ = saved_scope;
2828 for_scope->set_end_position(scanner().location().end_pos);
2829 for_scope = for_scope->FinalizeBlockScope();
2830 ASSERT(for_scope == NULL);
2831 // Parsed for-in loop.
2835 init = factory()->NewExpressionStatement(
2836 expression, RelocInfo::kNoPosition);
2841 // Standard 'for' loop
2842 ForStatement* loop = factory()->NewForStatement(labels, pos);
2843 Target target(&this->target_stack_, loop);
2845 // Parsed initializer at this point.
2846 Expect(Token::SEMICOLON, CHECK_OK);
2848 Expression* cond = NULL;
2849 if (peek() != Token::SEMICOLON) {
2850 cond = ParseExpression(true, CHECK_OK);
2852 Expect(Token::SEMICOLON, CHECK_OK);
2854 Statement* next = NULL;
2855 if (peek() != Token::RPAREN) {
2856 Expression* exp = ParseExpression(true, CHECK_OK);
2857 next = factory()->NewExpressionStatement(exp, RelocInfo::kNoPosition);
2859 Expect(Token::RPAREN, CHECK_OK);
2861 Statement* body = ParseStatement(NULL, CHECK_OK);
2862 top_scope_ = saved_scope;
2863 for_scope->set_end_position(scanner().location().end_pos);
2864 for_scope = for_scope->FinalizeBlockScope();
2865 if (for_scope != NULL) {
2866 // Rewrite a for statement of the form
2868 // for (let x = i; c; n) b
2876 ASSERT(init != NULL);
2877 Block* result = factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
2878 result->AddStatement(init, zone());
2879 result->AddStatement(loop, zone());
2880 result->set_scope(for_scope);
2881 loop->Initialize(NULL, cond, next, body);
2884 loop->Initialize(init, cond, next, body);
2891 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) {
2893 // AssignmentExpression
2894 // Expression ',' AssignmentExpression
2896 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK);
2897 while (peek() == Token::COMMA) {
2898 Expect(Token::COMMA, CHECK_OK);
2899 int pos = position();
2900 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
2901 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
2908 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
2909 // AssignmentExpression ::
2910 // ConditionalExpression
2912 // LeftHandSideExpression AssignmentOperator AssignmentExpression
2914 if (peek() == Token::YIELD && is_generator()) {
2915 return ParseYieldExpression(ok);
2918 if (fni_ != NULL) fni_->Enter();
2919 Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK);
2921 if (!Token::IsAssignmentOp(peek())) {
2922 if (fni_ != NULL) fni_->Leave();
2923 // Parsed conditional expression only (no assignment).
2927 // Signal a reference error if the expression is an invalid left-hand
2928 // side expression. We could report this as a syntax error here but
2929 // for compatibility with JSC we choose to report the error at
2931 // TODO(ES5): Should change parsing for spec conformance.
2932 if (expression == NULL || !expression->IsValidLeftHandSide()) {
2933 Handle<String> message =
2934 isolate()->factory()->invalid_lhs_in_assignment_string();
2935 expression = NewThrowReferenceError(message);
2938 if (!top_scope_->is_classic_mode()) {
2939 // Assignment to eval or arguments is disallowed in strict mode.
2940 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK);
2942 MarkAsLValue(expression);
2944 Token::Value op = Next(); // Get assignment operator.
2945 int pos = position();
2946 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
2948 // TODO(1231235): We try to estimate the set of properties set by
2949 // constructors. We define a new property whenever there is an
2950 // assignment to a property of 'this'. We should probably only add
2951 // properties if we haven't seen them before. Otherwise we'll
2952 // probably overestimate the number of properties.
2953 Property* property = expression ? expression->AsProperty() : NULL;
2954 if (op == Token::ASSIGN &&
2956 property->obj()->AsVariableProxy() != NULL &&
2957 property->obj()->AsVariableProxy()->is_this()) {
2958 current_function_state_->AddProperty();
2961 // If we assign a function literal to a property we pretenure the
2962 // literal so it can be added as a constant function property.
2963 if (property != NULL && right->AsFunctionLiteral() != NULL) {
2964 right->AsFunctionLiteral()->set_pretenure();
2968 // Check if the right hand side is a call to avoid inferring a
2969 // name if we're dealing with "a = function(){...}();"-like
2971 if ((op == Token::INIT_VAR
2972 || op == Token::INIT_CONST
2973 || op == Token::ASSIGN)
2974 && (right->AsCall() == NULL && right->AsCallNew() == NULL)) {
2977 fni_->RemoveLastFunction();
2982 return factory()->NewAssignment(op, expression, right, pos);
2986 Expression* Parser::ParseYieldExpression(bool* ok) {
2987 // YieldExpression ::
2988 // 'yield' '*'? AssignmentExpression
2989 int pos = peek_position();
2990 Expect(Token::YIELD, CHECK_OK);
2992 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND;
2993 Expression* generator_object = factory()->NewVariableProxy(
2994 current_function_state_->generator_object_variable());
2995 Expression* expression = ParseAssignmentExpression(false, CHECK_OK);
2996 Yield* yield = factory()->NewYield(generator_object, expression, kind, pos);
2997 if (kind == Yield::DELEGATING) {
2998 yield->set_index(current_function_state_->NextHandlerIndex());
3005 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) {
3006 // ConditionalExpression ::
3007 // LogicalOrExpression
3008 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
3010 int pos = peek_position();
3011 // We start using the binary expression parser for prec >= 4 only!
3012 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
3013 if (peek() != Token::CONDITIONAL) return expression;
3014 Consume(Token::CONDITIONAL);
3015 // In parsing the first assignment expression in conditional
3016 // expressions we always accept the 'in' keyword; see ECMA-262,
3017 // section 11.12, page 58.
3018 Expression* left = ParseAssignmentExpression(true, CHECK_OK);
3019 Expect(Token::COLON, CHECK_OK);
3020 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
3021 return factory()->NewConditional(expression, left, right, pos);
3025 int ParserBase::Precedence(Token::Value tok, bool accept_IN) {
3026 if (tok == Token::IN && !accept_IN)
3027 return 0; // 0 precedence will terminate binary expression parsing
3029 return Token::Precedence(tok);
3034 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
3036 Expression* x = ParseUnaryExpression(CHECK_OK);
3037 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
3039 while (Precedence(peek(), accept_IN) == prec1) {
3040 Token::Value op = Next();
3041 int pos = position();
3042 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
3044 // Compute some expressions involving only number literals.
3045 if (x && x->AsLiteral() && x->AsLiteral()->value()->IsNumber() &&
3046 y && y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) {
3047 double x_val = x->AsLiteral()->value()->Number();
3048 double y_val = y->AsLiteral()->value()->Number();
3052 x = factory()->NewNumberLiteral(x_val + y_val, pos);
3055 x = factory()->NewNumberLiteral(x_val - y_val, pos);
3058 x = factory()->NewNumberLiteral(x_val * y_val, pos);
3061 x = factory()->NewNumberLiteral(x_val / y_val, pos);
3063 case Token::BIT_OR: {
3064 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
3065 x = factory()->NewNumberLiteral(value, pos);
3068 case Token::BIT_AND: {
3069 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
3070 x = factory()->NewNumberLiteral(value, pos);
3073 case Token::BIT_XOR: {
3074 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
3075 x = factory()->NewNumberLiteral(value, pos);
3079 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
3080 x = factory()->NewNumberLiteral(value, pos);
3084 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
3085 uint32_t value = DoubleToUint32(x_val) >> shift;
3086 x = factory()->NewNumberLiteral(value, pos);
3090 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
3091 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
3092 x = factory()->NewNumberLiteral(value, pos);
3100 // For now we distinguish between comparisons and other binary
3101 // operations. (We could combine the two and get rid of this
3102 // code and AST node eventually.)
3103 if (Token::IsCompareOp(op)) {
3104 // We have a comparison.
3105 Token::Value cmp = op;
3107 case Token::NE: cmp = Token::EQ; break;
3108 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
3111 x = factory()->NewCompareOperation(cmp, x, y, pos);
3113 // The comparison was negated - add a NOT.
3114 x = factory()->NewUnaryOperation(Token::NOT, x, pos);
3118 // We have a "normal" binary operation.
3119 x = factory()->NewBinaryOperation(op, x, y, pos);
3127 Expression* Parser::ParseUnaryExpression(bool* ok) {
3128 // UnaryExpression ::
3129 // PostfixExpression
3130 // 'delete' UnaryExpression
3131 // 'void' UnaryExpression
3132 // 'typeof' UnaryExpression
3133 // '++' UnaryExpression
3134 // '--' UnaryExpression
3135 // '+' UnaryExpression
3136 // '-' UnaryExpression
3137 // '~' UnaryExpression
3138 // '!' UnaryExpression
3140 Token::Value op = peek();
3141 if (Token::IsUnaryOp(op)) {
3143 int pos = position();
3144 Expression* expression = ParseUnaryExpression(CHECK_OK);
3146 if (expression != NULL && (expression->AsLiteral() != NULL)) {
3147 Handle<Object> literal = expression->AsLiteral()->value();
3148 if (op == Token::NOT) {
3149 // Convert the literal to a boolean condition and negate it.
3150 bool condition = literal->BooleanValue();
3151 Handle<Object> result = isolate()->factory()->ToBoolean(!condition);
3152 return factory()->NewLiteral(result, pos);
3153 } else if (literal->IsNumber()) {
3154 // Compute some expressions involving only number literals.
3155 double value = literal->Number();
3160 return factory()->NewNumberLiteral(-value, pos);
3161 case Token::BIT_NOT:
3162 return factory()->NewNumberLiteral(~DoubleToInt32(value), pos);
3169 // "delete identifier" is a syntax error in strict mode.
3170 if (op == Token::DELETE && !top_scope_->is_classic_mode()) {
3171 VariableProxy* operand = expression->AsVariableProxy();
3172 if (operand != NULL && !operand->is_this()) {
3173 ReportMessage("strict_delete", Vector<const char*>::empty());
3179 // Desugar '+foo' into 'foo*1', this enables the collection of type feedback
3180 // without any special stub and the multiplication is removed later in
3181 // Crankshaft's canonicalization pass.
3182 if (op == Token::ADD) {
3183 return factory()->NewBinaryOperation(Token::MUL,
3185 factory()->NewNumberLiteral(1, pos),
3188 // The same idea for '-foo' => 'foo*(-1)'.
3189 if (op == Token::SUB) {
3190 return factory()->NewBinaryOperation(Token::MUL,
3192 factory()->NewNumberLiteral(-1, pos),
3195 // ...and one more time for '~foo' => 'foo^(~0)'.
3196 if (op == Token::BIT_NOT) {
3197 return factory()->NewBinaryOperation(Token::BIT_XOR,
3199 factory()->NewNumberLiteral(~0, pos),
3203 return factory()->NewUnaryOperation(op, expression, pos);
3205 } else if (Token::IsCountOp(op)) {
3207 Expression* expression = ParseUnaryExpression(CHECK_OK);
3208 // Signal a reference error if the expression is an invalid
3209 // left-hand side expression. We could report this as a syntax
3210 // error here but for compatibility with JSC we choose to report the
3211 // error at runtime.
3212 if (expression == NULL || !expression->IsValidLeftHandSide()) {
3213 Handle<String> message =
3214 isolate()->factory()->invalid_lhs_in_prefix_op_string();
3215 expression = NewThrowReferenceError(message);
3218 if (!top_scope_->is_classic_mode()) {
3219 // Prefix expression operand in strict mode may not be eval or arguments.
3220 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
3222 MarkAsLValue(expression);
3224 return factory()->NewCountOperation(op,
3230 return ParsePostfixExpression(ok);
3235 Expression* Parser::ParsePostfixExpression(bool* ok) {
3236 // PostfixExpression ::
3237 // LeftHandSideExpression ('++' | '--')?
3239 Expression* expression = ParseLeftHandSideExpression(CHECK_OK);
3240 if (!scanner().HasAnyLineTerminatorBeforeNext() &&
3241 Token::IsCountOp(peek())) {
3242 // Signal a reference error if the expression is an invalid
3243 // left-hand side expression. We could report this as a syntax
3244 // error here but for compatibility with JSC we choose to report the
3245 // error at runtime.
3246 if (expression == NULL || !expression->IsValidLeftHandSide()) {
3247 Handle<String> message =
3248 isolate()->factory()->invalid_lhs_in_postfix_op_string();
3249 expression = NewThrowReferenceError(message);
3252 if (!top_scope_->is_classic_mode()) {
3253 // Postfix expression operand in strict mode may not be eval or arguments.
3254 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
3256 MarkAsLValue(expression);
3258 Token::Value next = Next();
3260 factory()->NewCountOperation(next,
3261 false /* postfix */,
3269 Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
3270 // LeftHandSideExpression ::
3271 // (NewExpression | MemberExpression) ...
3274 if (peek() == Token::NEW) {
3275 result = ParseNewExpression(CHECK_OK);
3277 result = ParseMemberExpression(CHECK_OK);
3282 case Token::LBRACK: {
3283 Consume(Token::LBRACK);
3284 int pos = position();
3285 Expression* index = ParseExpression(true, CHECK_OK);
3286 result = factory()->NewProperty(result, index, pos);
3287 Expect(Token::RBRACK, CHECK_OK);
3291 case Token::LPAREN: {
3293 if (scanner().current_token() == Token::IDENTIFIER) {
3294 // For call of an identifier we want to report position of
3295 // the identifier as position of the call in the stack trace.
3298 // For other kinds of calls we record position of the parenthesis as
3299 // position of the call. Note that this is extremely important for
3300 // expressions of the form function(){...}() for which call position
3301 // should not point to the closing brace otherwise it will intersect
3302 // with positions recorded for function literal and confuse debugger.
3303 pos = peek_position();
3304 // Also the trailing parenthesis are a hint that the function will
3305 // be called immediately. If we happen to have parsed a preceding
3306 // function literal eagerly, we can also compile it eagerly.
3307 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
3308 result->AsFunctionLiteral()->set_parenthesized();
3311 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
3313 // Keep track of eval() calls since they disable all local variable
3315 // The calls that need special treatment are the
3316 // direct eval calls. These calls are all of the form eval(...), with
3317 // no explicit receiver.
3318 // These calls are marked as potentially direct eval calls. Whether
3319 // they are actually direct calls to eval is determined at run time.
3320 VariableProxy* callee = result->AsVariableProxy();
3321 if (callee != NULL &&
3322 callee->IsVariable(isolate()->factory()->eval_string())) {
3323 top_scope_->DeclarationScope()->RecordEvalCall();
3325 result = factory()->NewCall(result, args, pos);
3326 if (fni_ != NULL) fni_->RemoveLastFunction();
3330 case Token::PERIOD: {
3331 Consume(Token::PERIOD);
3332 int pos = position();
3333 Handle<String> name = ParseIdentifierName(CHECK_OK);
3334 result = factory()->NewProperty(
3335 result, factory()->NewLiteral(name, pos), pos);
3336 if (fni_ != NULL) fni_->PushLiteralName(name);
3347 Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) {
3349 // ('new')+ MemberExpression
3351 // The grammar for new expressions is pretty warped. The keyword
3352 // 'new' can either be a part of the new expression (where it isn't
3353 // followed by an argument list) or a part of the member expression,
3354 // where it must be followed by an argument list. To accommodate
3355 // this, we parse the 'new' keywords greedily and keep track of how
3356 // many we have parsed. This information is then passed on to the
3357 // member expression parser, which is only allowed to match argument
3358 // lists as long as it has 'new' prefixes left
3359 Expect(Token::NEW, CHECK_OK);
3360 PositionStack::Element pos(stack, position());
3363 if (peek() == Token::NEW) {
3364 result = ParseNewPrefix(stack, CHECK_OK);
3366 result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK);
3369 if (!stack->is_empty()) {
3370 int last = stack->pop();
3371 result = factory()->NewCallNew(
3372 result, new(zone()) ZoneList<Expression*>(0, zone()), last);
3378 Expression* Parser::ParseNewExpression(bool* ok) {
3379 PositionStack stack(ok);
3380 return ParseNewPrefix(&stack, ok);
3384 Expression* Parser::ParseMemberExpression(bool* ok) {
3385 return ParseMemberWithNewPrefixesExpression(NULL, ok);
3389 Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
3391 // MemberExpression ::
3392 // (PrimaryExpression | FunctionLiteral)
3393 // ('[' Expression ']' | '.' Identifier | Arguments)*
3395 // Parse the initial primary or function expression.
3396 Expression* result = NULL;
3397 if (peek() == Token::FUNCTION) {
3398 Expect(Token::FUNCTION, CHECK_OK);
3399 int function_token_position = position();
3400 bool is_generator = allow_generators() && Check(Token::MUL);
3401 Handle<String> name;
3402 bool is_strict_reserved_name = false;
3403 if (peek_any_identifier()) {
3404 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
3407 FunctionLiteral::FunctionType function_type = name.is_null()
3408 ? FunctionLiteral::ANONYMOUS_EXPRESSION
3409 : FunctionLiteral::NAMED_EXPRESSION;
3410 result = ParseFunctionLiteral(name,
3411 is_strict_reserved_name,
3413 function_token_position,
3417 result = ParsePrimaryExpression(CHECK_OK);
3422 case Token::LBRACK: {
3423 Consume(Token::LBRACK);
3424 int pos = position();
3425 Expression* index = ParseExpression(true, CHECK_OK);
3426 result = factory()->NewProperty(result, index, pos);
3428 if (index->IsPropertyName()) {
3429 fni_->PushLiteralName(index->AsLiteral()->AsPropertyName());
3431 fni_->PushLiteralName(
3432 isolate()->factory()->anonymous_function_string());
3435 Expect(Token::RBRACK, CHECK_OK);
3438 case Token::PERIOD: {
3439 Consume(Token::PERIOD);
3440 int pos = position();
3441 Handle<String> name = ParseIdentifierName(CHECK_OK);
3442 result = factory()->NewProperty(
3443 result, factory()->NewLiteral(name, pos), pos);
3444 if (fni_ != NULL) fni_->PushLiteralName(name);
3447 case Token::LPAREN: {
3448 if ((stack == NULL) || stack->is_empty()) return result;
3449 // Consume one of the new prefixes (already parsed).
3450 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
3451 int pos = stack->pop();
3452 result = factory()->NewCallNew(result, args, pos);
3462 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
3463 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
3464 // contexts this is used as a statement which invokes the debugger as i a
3465 // break point is present.
3466 // DebuggerStatement ::
3469 int pos = peek_position();
3470 Expect(Token::DEBUGGER, CHECK_OK);
3471 ExpectSemicolon(CHECK_OK);
3472 return factory()->NewDebuggerStatement(pos);
3476 void Parser::ReportUnexpectedToken(Token::Value token) {
3477 // We don't report stack overflows here, to avoid increasing the
3478 // stack depth even further. Instead we report it after parsing is
3479 // over, in ParseProgram/ParseJson.
3480 if (token == Token::ILLEGAL && stack_overflow()) return;
3481 // Four of the tokens are treated specially
3484 return ReportMessage("unexpected_eos", Vector<const char*>::empty());
3486 return ReportMessage("unexpected_token_number",
3487 Vector<const char*>::empty());
3489 return ReportMessage("unexpected_token_string",
3490 Vector<const char*>::empty());
3491 case Token::IDENTIFIER:
3492 return ReportMessage("unexpected_token_identifier",
3493 Vector<const char*>::empty());
3494 case Token::FUTURE_RESERVED_WORD:
3495 return ReportMessage("unexpected_reserved",
3496 Vector<const char*>::empty());
3498 case Token::FUTURE_STRICT_RESERVED_WORD:
3499 return ReportMessage(top_scope_->is_classic_mode() ?
3500 "unexpected_token_identifier" :
3501 "unexpected_strict_reserved",
3502 Vector<const char*>::empty());
3504 const char* name = Token::String(token);
3505 ASSERT(name != NULL);
3506 ReportMessage("unexpected_token", Vector<const char*>(&name, 1));
3511 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) {
3512 SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS);
3513 const char* element[1] = { name_string.get() };
3514 ReportMessage("invalid_preparser_data",
3515 Vector<const char*>(element, 1));
3520 Expression* Parser::ParsePrimaryExpression(bool* ok) {
3521 // PrimaryExpression ::
3532 // '(' Expression ')'
3534 int pos = peek_position();
3535 Expression* result = NULL;
3538 Consume(Token::THIS);
3539 result = factory()->NewVariableProxy(top_scope_->receiver());
3543 case Token::NULL_LITERAL:
3544 Consume(Token::NULL_LITERAL);
3545 result = factory()->NewLiteral(isolate()->factory()->null_value(), pos);
3548 case Token::TRUE_LITERAL:
3549 Consume(Token::TRUE_LITERAL);
3550 result = factory()->NewLiteral(isolate()->factory()->true_value(), pos);
3553 case Token::FALSE_LITERAL:
3554 Consume(Token::FALSE_LITERAL);
3555 result = factory()->NewLiteral(isolate()->factory()->false_value(), pos);
3558 case Token::IDENTIFIER:
3560 case Token::FUTURE_STRICT_RESERVED_WORD: {
3561 Handle<String> name = ParseIdentifier(CHECK_OK);
3562 if (fni_ != NULL) fni_->PushVariableName(name);
3563 // The name may refer to a module instance object, so its type is unknown.
3565 if (FLAG_print_interface_details)
3566 PrintF("# Variable %s ", name->ToAsciiArray());
3568 Interface* interface = Interface::NewUnknown(zone());
3569 result = top_scope_->NewUnresolved(factory(), name, interface, pos);
3573 case Token::NUMBER: {
3574 Consume(Token::NUMBER);
3575 ASSERT(scanner().is_literal_ascii());
3576 double value = StringToDouble(isolate()->unicode_cache(),
3577 scanner().literal_ascii_string(),
3578 ALLOW_HEX | ALLOW_OCTAL |
3579 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY);
3580 result = factory()->NewNumberLiteral(value, pos);
3584 case Token::STRING: {
3585 Consume(Token::STRING);
3586 Handle<String> symbol = GetSymbol();
3587 result = factory()->NewLiteral(symbol, pos);
3588 if (fni_ != NULL) fni_->PushLiteralName(symbol);
3592 case Token::ASSIGN_DIV:
3593 result = ParseRegExpLiteral(true, CHECK_OK);
3597 result = ParseRegExpLiteral(false, CHECK_OK);
3601 result = ParseArrayLiteral(CHECK_OK);
3605 result = ParseObjectLiteral(CHECK_OK);
3609 Consume(Token::LPAREN);
3610 // Heuristically try to detect immediately called functions before
3611 // seeing the call parentheses.
3612 parenthesized_function_ = (peek() == Token::FUNCTION);
3613 result = ParseExpression(true, CHECK_OK);
3614 Expect(Token::RPAREN, CHECK_OK);
3618 if (allow_natives_syntax() || extension_ != NULL) {
3619 result = ParseV8Intrinsic(CHECK_OK);
3622 // If we're not allowing special syntax we fall-through to the
3626 Token::Value tok = Next();
3627 ReportUnexpectedToken(tok);
3637 Expression* Parser::ParseArrayLiteral(bool* ok) {
3639 // '[' Expression? (',' Expression?)* ']'
3641 int pos = peek_position();
3642 ZoneList<Expression*>* values = new(zone()) ZoneList<Expression*>(4, zone());
3643 Expect(Token::LBRACK, CHECK_OK);
3644 while (peek() != Token::RBRACK) {
3646 if (peek() == Token::COMMA) {
3647 elem = GetLiteralTheHole(peek_position());
3649 elem = ParseAssignmentExpression(true, CHECK_OK);
3651 values->Add(elem, zone());
3652 if (peek() != Token::RBRACK) {
3653 Expect(Token::COMMA, CHECK_OK);
3656 Expect(Token::RBRACK, CHECK_OK);
3658 // Update the scope information before the pre-parsing bailout.
3659 int literal_index = current_function_state_->NextMaterializedLiteralIndex();
3661 return factory()->NewArrayLiteral(values, literal_index, pos);
3665 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
3666 if (expression->AsLiteral() != NULL) return true;
3667 MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3668 return lit != NULL && lit->is_simple();
3672 Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate,
3673 Expression* expression) {
3674 Factory* factory = isolate->factory();
3675 ASSERT(IsCompileTimeValue(expression));
3676 Handle<FixedArray> result = factory->NewFixedArray(2, TENURED);
3677 ObjectLiteral* object_literal = expression->AsObjectLiteral();
3678 if (object_literal != NULL) {
3679 ASSERT(object_literal->is_simple());
3680 if (object_literal->fast_elements()) {
3681 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
3683 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
3685 result->set(kElementsSlot, *object_literal->constant_properties());
3687 ArrayLiteral* array_literal = expression->AsArrayLiteral();
3688 ASSERT(array_literal != NULL && array_literal->is_simple());
3689 result->set(kLiteralTypeSlot, Smi::FromInt(ARRAY_LITERAL));
3690 result->set(kElementsSlot, *array_literal->constant_elements());
3696 CompileTimeValue::LiteralType CompileTimeValue::GetLiteralType(
3697 Handle<FixedArray> value) {
3698 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot));
3699 return static_cast<LiteralType>(literal_type->value());
3703 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
3704 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
3708 Expression* Parser::ParseObjectLiteral(bool* ok) {
3711 // ((IdentifierName | String | Number) ':' AssignmentExpression)
3712 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
3715 int pos = peek_position();
3716 ZoneList<ObjectLiteral::Property*>* properties =
3717 new(zone()) ZoneList<ObjectLiteral::Property*>(4, zone());
3718 int number_of_boilerplate_properties = 0;
3719 bool has_function = false;
3721 ObjectLiteralChecker checker(this, top_scope_->language_mode());
3723 Expect(Token::LBRACE, CHECK_OK);
3725 while (peek() != Token::RBRACE) {
3726 if (fni_ != NULL) fni_->Enter();
3728 Literal* key = NULL;
3729 Token::Value next = peek();
3730 int next_pos = peek_position();
3733 case Token::FUTURE_RESERVED_WORD:
3734 case Token::FUTURE_STRICT_RESERVED_WORD:
3735 case Token::IDENTIFIER: {
3736 bool is_getter = false;
3737 bool is_setter = false;
3739 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
3740 if (fni_ != NULL) fni_->PushLiteralName(id);
3742 if ((is_getter || is_setter) && peek() != Token::COLON) {
3743 // Special handling of getter and setter syntax:
3744 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
3745 // We have already read the "get" or "set" keyword.
3746 Token::Value next = Next();
3747 bool is_keyword = Token::IsKeyword(next);
3748 if (next != i::Token::IDENTIFIER &&
3749 next != i::Token::FUTURE_RESERVED_WORD &&
3750 next != i::Token::FUTURE_STRICT_RESERVED_WORD &&
3751 next != i::Token::NUMBER &&
3752 next != i::Token::STRING &&
3754 // Unexpected token.
3755 ReportUnexpectedToken(next);
3759 // Validate the property.
3760 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
3761 checker.CheckProperty(next, type, CHECK_OK);
3762 Handle<String> name = is_keyword
3763 ? isolate_->factory()->InternalizeUtf8String(Token::String(next))
3765 FunctionLiteral* value =
3766 ParseFunctionLiteral(name,
3767 false, // reserved words are allowed here
3768 false, // not a generator
3769 RelocInfo::kNoPosition,
3770 FunctionLiteral::ANONYMOUS_EXPRESSION,
3772 // Allow any number of parameters for compatibilty with JSC.
3773 // Specification only allows zero parameters for get and one for set.
3774 ObjectLiteral::Property* property =
3775 factory()->NewObjectLiteralProperty(is_getter, value, next_pos);
3776 if (ObjectLiteral::IsBoilerplateProperty(property)) {
3777 number_of_boilerplate_properties++;
3779 properties->Add(property, zone());
3780 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
3786 continue; // restart the while
3788 // Failed to parse as get/set property, so it's just a property
3789 // called "get" or "set".
3790 key = factory()->NewLiteral(id, next_pos);
3793 case Token::STRING: {
3794 Consume(Token::STRING);
3795 Handle<String> string = GetSymbol();
3796 if (fni_ != NULL) fni_->PushLiteralName(string);
3798 if (!string.is_null() && string->AsArrayIndex(&index)) {
3799 key = factory()->NewNumberLiteral(index, next_pos);
3802 key = factory()->NewLiteral(string, next_pos);
3805 case Token::NUMBER: {
3806 Consume(Token::NUMBER);
3807 ASSERT(scanner().is_literal_ascii());
3808 double value = StringToDouble(isolate()->unicode_cache(),
3809 scanner().literal_ascii_string(),
3810 ALLOW_HEX | ALLOW_OCTAL |
3811 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY);
3812 key = factory()->NewNumberLiteral(value, next_pos);
3816 if (Token::IsKeyword(next)) {
3818 Handle<String> string = GetSymbol();
3819 key = factory()->NewLiteral(string, next_pos);
3821 // Unexpected token.
3822 Token::Value next = Next();
3823 ReportUnexpectedToken(next);
3829 // Validate the property
3830 checker.CheckProperty(next, kValueProperty, CHECK_OK);
3832 Expect(Token::COLON, CHECK_OK);
3833 Expression* value = ParseAssignmentExpression(true, CHECK_OK);
3835 ObjectLiteral::Property* property =
3836 factory()->NewObjectLiteralProperty(key, value);
3838 // Mark top-level object literals that contain function literals and
3839 // pretenure the literal so it can be added as a constant function
3841 if (top_scope_->DeclarationScope()->is_global_scope() &&
3842 value->AsFunctionLiteral() != NULL) {
3843 has_function = true;
3844 value->AsFunctionLiteral()->set_pretenure();
3847 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
3848 if (ObjectLiteral::IsBoilerplateProperty(property)) {
3849 number_of_boilerplate_properties++;
3851 properties->Add(property, zone());
3853 // TODO(1240767): Consider allowing trailing comma.
3854 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
3861 Expect(Token::RBRACE, CHECK_OK);
3863 // Computation of literal_index must happen before pre parse bailout.
3864 int literal_index = current_function_state_->NextMaterializedLiteralIndex();
3866 return factory()->NewObjectLiteral(properties,
3868 number_of_boilerplate_properties,
3874 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) {
3875 int pos = peek_position();
3876 if (!scanner().ScanRegExpPattern(seen_equal)) {
3878 ReportMessage("unterminated_regexp", Vector<const char*>::empty());
3883 int literal_index = current_function_state_->NextMaterializedLiteralIndex();
3885 Handle<String> js_pattern = NextLiteralString(TENURED);
3886 scanner().ScanRegExpFlags();
3887 Handle<String> js_flags = NextLiteralString(TENURED);
3890 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
3894 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) {
3896 // '(' (AssignmentExpression)*[','] ')'
3898 ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4, zone());
3899 Expect(Token::LPAREN, CHECK_OK);
3900 bool done = (peek() == Token::RPAREN);
3902 Expression* argument = ParseAssignmentExpression(true, CHECK_OK);
3903 result->Add(argument, zone());
3904 if (result->length() > Code::kMaxArguments) {
3905 ReportMessageAt(scanner().location(), "too_many_arguments",
3906 Vector<const char*>::empty());
3910 done = (peek() == Token::RPAREN);
3911 if (!done) Expect(Token::COMMA, CHECK_OK);
3913 Expect(Token::RPAREN, CHECK_OK);
3918 class SingletonLogger : public ParserRecorder {
3920 SingletonLogger() : has_error_(false), start_(-1), end_(-1) { }
3921 virtual ~SingletonLogger() { }
3923 void Reset() { has_error_ = false; }
3925 virtual void LogFunction(int start,
3929 LanguageMode mode) {
3930 ASSERT(!has_error_);
3933 literals_ = literals;
3934 properties_ = properties;
3938 // Logs a symbol creation of a literal or identifier.
3939 virtual void LogAsciiSymbol(int start, Vector<const char> literal) { }
3940 virtual void LogUtf16Symbol(int start, Vector<const uc16> literal) { }
3942 // Logs an error message and marks the log as containing an error.
3943 // Further logging will be ignored, and ExtractData will return a vector
3944 // representing the error only.
3945 virtual void LogMessage(int start,
3947 const char* message,
3948 const char* argument_opt) {
3949 if (has_error_) return;
3954 argument_opt_ = argument_opt;
3957 virtual int function_position() { return 0; }
3959 virtual int symbol_position() { return 0; }
3961 virtual int symbol_ids() { return -1; }
3963 virtual Vector<unsigned> ExtractData() {
3965 return Vector<unsigned>();
3968 virtual void PauseRecording() { }
3970 virtual void ResumeRecording() { }
3972 bool has_error() { return has_error_; }
3974 int start() { return start_; }
3975 int end() { return end_; }
3977 ASSERT(!has_error_);
3981 ASSERT(!has_error_);
3984 LanguageMode language_mode() {
3985 ASSERT(!has_error_);
3988 const char* message() {
3992 const char* argument_opt() {
3994 return argument_opt_;
4001 // For function entries.
4005 // For error messages.
4006 const char* message_;
4007 const char* argument_opt_;
4011 FunctionLiteral* Parser::ParseFunctionLiteral(
4012 Handle<String> function_name,
4013 bool name_is_strict_reserved,
4015 int function_token_pos,
4016 FunctionLiteral::FunctionType function_type,
4019 // '(' FormalParameterList? ')' '{' FunctionBody '}'
4021 int pos = function_token_pos == RelocInfo::kNoPosition
4022 ? peek_position() : function_token_pos;
4024 // Anonymous functions were passed either the empty symbol or a null
4025 // handle as the function name. Remember if we were passed a non-empty
4026 // handle to decide whether to invoke function name inference.
4027 bool should_infer_name = function_name.is_null();
4029 // We want a non-null handle as the function name.
4030 if (should_infer_name) {
4031 function_name = isolate()->factory()->empty_string();
4034 int num_parameters = 0;
4035 // Function declarations are function scoped in normal mode, so they are
4036 // hoisted. In harmony block scoping mode they are block scoped, so they
4039 // One tricky case are function declarations in a local sloppy-mode eval:
4040 // their declaration is hoisted, but they still see the local scope. E.g.,
4044 // try { throw 1 } catch (x) { eval("function g() { return x }") }
4048 // needs to return 1. To distinguish such cases, we need to detect
4049 // (1) whether a function stems from a sloppy eval, and
4050 // (2) whether it actually hoists across the eval.
4051 // Unfortunately, we do not represent sloppy eval scopes, so we do not have
4052 // either information available directly, especially not when lazily compiling
4053 // a function like 'g'. We hence rely on the following invariants:
4054 // - (1) is the case iff the innermost scope of the deserialized scope chain
4055 // under which we compile is _not_ a declaration scope. This holds because
4056 // in all normal cases, function declarations are fully hoisted to a
4057 // declaration scope and compiled relative to that.
4058 // - (2) is the case iff the current declaration scope is still the original
4059 // one relative to the deserialized scope chain. Otherwise we must be
4060 // compiling a function in an inner declaration scope in the eval, e.g. a
4061 // nested function, and hoisting works normally relative to that.
4062 Scope* declaration_scope = top_scope_->DeclarationScope();
4063 Scope* original_declaration_scope = original_scope_->DeclarationScope();
4065 function_type == FunctionLiteral::DECLARATION && !is_extended_mode() &&
4066 (original_scope_ == original_declaration_scope ||
4067 declaration_scope != original_declaration_scope)
4068 ? NewScope(declaration_scope, FUNCTION_SCOPE)
4069 : NewScope(top_scope_, FUNCTION_SCOPE);
4070 ZoneList<Statement*>* body = NULL;
4071 int materialized_literal_count = -1;
4072 int expected_property_count = -1;
4073 int handler_count = 0;
4074 FunctionLiteral::ParameterFlag duplicate_parameters =
4075 FunctionLiteral::kNoDuplicateParameters;
4076 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
4077 ? FunctionLiteral::kIsParenthesized
4078 : FunctionLiteral::kNotParenthesized;
4079 FunctionLiteral::IsGeneratorFlag generator = is_generator
4080 ? FunctionLiteral::kIsGenerator
4081 : FunctionLiteral::kNotGenerator;
4082 AstProperties ast_properties;
4083 BailoutReason dont_optimize_reason = kNoReason;
4084 // Parse function body.
4085 { FunctionState function_state(this, scope);
4086 top_scope_->SetScopeName(function_name);
4089 // For generators, allocating variables in contexts is currently a win
4090 // because it minimizes the work needed to suspend and resume an
4092 top_scope_->ForceContextAllocation();
4094 // Calling a generator returns a generator object. That object is stored
4095 // in a temporary variable, a definition that is used by "yield"
4096 // expressions. Presence of a variable for the generator object in the
4097 // FunctionState indicates that this function is a generator.
4098 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(
4099 isolate()->factory()->dot_generator_object_string());
4100 function_state.set_generator_object_variable(temp);
4103 // FormalParameterList ::
4104 // '(' (Identifier)*[','] ')'
4105 Expect(Token::LPAREN, CHECK_OK);
4106 scope->set_start_position(scanner().location().beg_pos);
4107 Scanner::Location name_loc = Scanner::Location::invalid();
4108 Scanner::Location dupe_loc = Scanner::Location::invalid();
4109 Scanner::Location reserved_loc = Scanner::Location::invalid();
4111 bool done = (peek() == Token::RPAREN);
4113 bool is_strict_reserved = false;
4114 Handle<String> param_name =
4115 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
4117 // Store locations for possible future error reports.
4118 if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) {
4119 name_loc = scanner().location();
4121 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) {
4122 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters;
4123 dupe_loc = scanner().location();
4125 if (!reserved_loc.IsValid() && is_strict_reserved) {
4126 reserved_loc = scanner().location();
4129 top_scope_->DeclareParameter(param_name, VAR);
4131 if (num_parameters > Code::kMaxArguments) {
4132 ReportMessageAt(scanner().location(), "too_many_parameters",
4133 Vector<const char*>::empty());
4137 done = (peek() == Token::RPAREN);
4138 if (!done) Expect(Token::COMMA, CHECK_OK);
4140 Expect(Token::RPAREN, CHECK_OK);
4142 Expect(Token::LBRACE, CHECK_OK);
4144 // If we have a named function expression, we add a local variable
4145 // declaration to the body of the function with the name of the
4146 // function and let it refer to the function itself (closure).
4147 // NOTE: We create a proxy and resolve it here so that in the
4148 // future we can change the AST to only refer to VariableProxies
4149 // instead of Variables and Proxis as is the case now.
4150 Variable* fvar = NULL;
4151 Token::Value fvar_init_op = Token::INIT_CONST;
4152 if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
4153 if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY;
4154 VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST;
4155 fvar = new(zone()) Variable(top_scope_,
4156 function_name, fvar_mode, true /* is valid LHS */,
4157 Variable::NORMAL, kCreatedInitialized, Interface::NewConst());
4158 VariableProxy* proxy = factory()->NewVariableProxy(fvar);
4159 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration(
4160 proxy, fvar_mode, top_scope_, RelocInfo::kNoPosition);
4161 top_scope_->DeclareFunctionVar(fvar_declaration);
4164 // Determine whether the function will be lazily compiled.
4165 // The heuristics are:
4166 // - It must not have been prohibited by the caller to Parse (some callers
4167 // need a full AST).
4168 // - The outer scope must allow lazy compilation of inner functions.
4169 // - The function mustn't be a function expression with an open parenthesis
4170 // before; we consider that a hint that the function will be called
4171 // immediately, and it would be a waste of time to make it lazily
4173 // These are all things we can know at this point, without looking at the
4175 bool is_lazily_compiled = (mode() == PARSE_LAZILY &&
4176 top_scope_->AllowsLazyCompilation() &&
4177 !parenthesized_function_);
4178 parenthesized_function_ = false; // The bit was set for this function only.
4180 if (is_lazily_compiled) {
4181 int function_block_pos = position();
4182 FunctionEntry entry;
4183 if (pre_parse_data_ != NULL) {
4184 // If we have pre_parse_data_, we use it to skip parsing the function
4185 // body. The preparser data contains the information we need to
4186 // construct the lazy function.
4187 entry = pre_parse_data()->GetFunctionEntry(function_block_pos);
4188 if (entry.is_valid()) {
4189 if (entry.end_pos() <= function_block_pos) {
4190 // End position greater than end of stream is safe, and hard
4192 ReportInvalidPreparseData(function_name, CHECK_OK);
4194 scanner().SeekForward(entry.end_pos() - 1);
4196 scope->set_end_position(entry.end_pos());
4197 Expect(Token::RBRACE, CHECK_OK);
4198 isolate()->counters()->total_preparse_skipped()->Increment(
4199 scope->end_position() - function_block_pos);
4200 materialized_literal_count = entry.literal_count();
4201 expected_property_count = entry.property_count();
4202 top_scope_->SetLanguageMode(entry.language_mode());
4204 is_lazily_compiled = false;
4207 // With no preparser data, we partially parse the function, without
4208 // building an AST. This gathers the data needed to build a lazy
4210 SingletonLogger logger;
4211 PreParser::PreParseResult result = LazyParseFunctionLiteral(&logger);
4212 if (result == PreParser::kPreParseStackOverflow) {
4213 // Propagate stack overflow.
4214 set_stack_overflow();
4218 if (logger.has_error()) {
4219 const char* arg = logger.argument_opt();
4220 Vector<const char*> args;
4222 args = Vector<const char*>(&arg, 1);
4224 ReportMessageAt(Scanner::Location(logger.start(), logger.end()),
4225 logger.message(), args);
4229 scope->set_end_position(logger.end());
4230 Expect(Token::RBRACE, CHECK_OK);
4231 isolate()->counters()->total_preparse_skipped()->Increment(
4232 scope->end_position() - function_block_pos);
4233 materialized_literal_count = logger.literals();
4234 expected_property_count = logger.properties();
4235 top_scope_->SetLanguageMode(logger.language_mode());
4239 if (!is_lazily_compiled) {
4240 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
4241 body = new(zone()) ZoneList<Statement*>(8, zone());
4243 VariableProxy* fproxy = top_scope_->NewUnresolved(
4244 factory(), function_name, Interface::NewConst());
4245 fproxy->BindTo(fvar);
4246 body->Add(factory()->NewExpressionStatement(
4247 factory()->NewAssignment(fvar_init_op,
4249 factory()->NewThisFunction(pos),
4250 RelocInfo::kNoPosition),
4251 RelocInfo::kNoPosition), zone());
4254 // For generators, allocate and yield an iterator on function entry.
4256 ZoneList<Expression*>* arguments =
4257 new(zone()) ZoneList<Expression*>(0, zone());
4258 CallRuntime* allocation = factory()->NewCallRuntime(
4259 isolate()->factory()->empty_string(),
4260 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject),
4262 VariableProxy* init_proxy = factory()->NewVariableProxy(
4263 current_function_state_->generator_object_variable());
4264 Assignment* assignment = factory()->NewAssignment(
4265 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
4266 VariableProxy* get_proxy = factory()->NewVariableProxy(
4267 current_function_state_->generator_object_variable());
4268 Yield* yield = factory()->NewYield(
4269 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition);
4270 body->Add(factory()->NewExpressionStatement(
4271 yield, RelocInfo::kNoPosition), zone());
4274 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK);
4277 VariableProxy* get_proxy = factory()->NewVariableProxy(
4278 current_function_state_->generator_object_variable());
4279 Expression *undefined = factory()->NewLiteral(
4280 isolate()->factory()->undefined_value(), RelocInfo::kNoPosition);
4281 Yield* yield = factory()->NewYield(
4282 get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition);
4283 body->Add(factory()->NewExpressionStatement(
4284 yield, RelocInfo::kNoPosition), zone());
4287 materialized_literal_count = function_state.materialized_literal_count();
4288 expected_property_count = function_state.expected_property_count();
4289 handler_count = function_state.handler_count();
4291 Expect(Token::RBRACE, CHECK_OK);
4292 scope->set_end_position(scanner().location().end_pos);
4295 // Validate strict mode.
4296 if (!top_scope_->is_classic_mode()) {
4297 if (IsEvalOrArguments(function_name)) {
4298 int start_pos = scope->start_position();
4299 int position = function_token_pos != RelocInfo::kNoPosition
4300 ? function_token_pos : (start_pos > 0 ? start_pos - 1 : start_pos);
4301 Scanner::Location location = Scanner::Location(position, start_pos);
4302 ReportMessageAt(location,
4303 "strict_function_name", Vector<const char*>::empty());
4307 if (name_loc.IsValid()) {
4308 ReportMessageAt(name_loc, "strict_param_name",
4309 Vector<const char*>::empty());
4313 if (dupe_loc.IsValid()) {
4314 ReportMessageAt(dupe_loc, "strict_param_dupe",
4315 Vector<const char*>::empty());
4319 if (name_is_strict_reserved) {
4320 int start_pos = scope->start_position();
4321 int position = function_token_pos != RelocInfo::kNoPosition
4322 ? function_token_pos : (start_pos > 0 ? start_pos - 1 : start_pos);
4323 Scanner::Location location = Scanner::Location(position, start_pos);
4324 ReportMessageAt(location, "strict_reserved_word",
4325 Vector<const char*>::empty());
4329 if (reserved_loc.IsValid()) {
4330 ReportMessageAt(reserved_loc, "strict_reserved_word",
4331 Vector<const char*>::empty());
4335 CheckOctalLiteral(scope->start_position(),
4336 scope->end_position(),
4339 ast_properties = *factory()->visitor()->ast_properties();
4340 dont_optimize_reason = factory()->visitor()->dont_optimize_reason();
4343 if (is_extended_mode()) {
4344 CheckConflictingVarDeclarations(scope, CHECK_OK);
4347 FunctionLiteral* function_literal =
4348 factory()->NewFunctionLiteral(function_name,
4351 materialized_literal_count,
4352 expected_property_count,
4355 duplicate_parameters,
4357 FunctionLiteral::kIsFunction,
4361 function_literal->set_function_token_position(function_token_pos);
4362 function_literal->set_ast_properties(&ast_properties);
4363 function_literal->set_dont_optimize_reason(dont_optimize_reason);
4365 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
4366 return function_literal;
4370 PreParser::PreParseResult Parser::LazyParseFunctionLiteral(
4371 SingletonLogger* logger) {
4372 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse());
4373 ASSERT_EQ(Token::LBRACE, scanner().current_token());
4375 if (reusable_preparser_ == NULL) {
4376 intptr_t stack_limit = isolate()->stack_guard()->real_climit();
4377 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit);
4378 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping());
4379 reusable_preparser_->set_allow_modules(allow_modules());
4380 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax());
4381 reusable_preparser_->set_allow_lazy(true);
4382 reusable_preparser_->set_allow_generators(allow_generators());
4383 reusable_preparser_->set_allow_for_of(allow_for_of());
4384 reusable_preparser_->set_allow_harmony_numeric_literals(
4385 allow_harmony_numeric_literals());
4387 PreParser::PreParseResult result =
4388 reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(),
4395 Expression* Parser::ParseV8Intrinsic(bool* ok) {
4397 // '%' Identifier Arguments
4399 int pos = peek_position();
4400 Expect(Token::MOD, CHECK_OK);
4401 Handle<String> name = ParseIdentifier(CHECK_OK);
4402 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
4404 if (extension_ != NULL) {
4405 // The extension structures are only accessible while parsing the
4406 // very first time not when reparsing because of lazy compilation.
4407 top_scope_->DeclarationScope()->ForceEagerCompilation();
4410 const Runtime::Function* function = Runtime::FunctionForName(name);
4412 // Check for built-in IS_VAR macro.
4413 if (function != NULL &&
4414 function->intrinsic_type == Runtime::RUNTIME &&
4415 function->function_id == Runtime::kIS_VAR) {
4416 // %IS_VAR(x) evaluates to x if x is a variable,
4417 // leads to a parse error otherwise. Could be implemented as an
4418 // inline function %_IS_VAR(x) to eliminate this special case.
4419 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
4422 ReportMessage("not_isvar", Vector<const char*>::empty());
4428 // Check that the expected number of arguments are being passed.
4429 if (function != NULL &&
4430 function->nargs != -1 &&
4431 function->nargs != args->length()) {
4432 ReportMessage("illegal_access", Vector<const char*>::empty());
4437 // Check that the function is defined if it's an inline runtime call.
4438 if (function == NULL && name->Get(0) == '_') {
4439 ReportMessage("not_defined", Vector<Handle<String> >(&name, 1));
4444 // We have a valid intrinsics call or a call to a builtin.
4445 return factory()->NewCallRuntime(name, function, args, pos);
4449 bool ParserBase::peek_any_identifier() {
4450 Token::Value next = peek();
4451 return next == Token::IDENTIFIER ||
4452 next == Token::FUTURE_RESERVED_WORD ||
4453 next == Token::FUTURE_STRICT_RESERVED_WORD ||
4454 next == Token::YIELD;
4458 bool ParserBase::CheckContextualKeyword(Vector<const char> keyword) {
4459 if (peek() == Token::IDENTIFIER &&
4460 scanner()->is_next_contextual_keyword(keyword)) {
4461 Consume(Token::IDENTIFIER);
4468 void ParserBase::ExpectSemicolon(bool* ok) {
4469 // Check for automatic semicolon insertion according to
4470 // the rules given in ECMA-262, section 7.9, page 21.
4471 Token::Value tok = peek();
4472 if (tok == Token::SEMICOLON) {
4476 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
4477 tok == Token::RBRACE ||
4478 tok == Token::EOS) {
4481 Expect(Token::SEMICOLON, ok);
4485 void ParserBase::ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
4486 Expect(Token::IDENTIFIER, ok);
4488 if (!scanner()->is_literal_contextual_keyword(keyword)) {
4489 ReportUnexpectedToken(scanner()->current_token());
4495 Literal* Parser::GetLiteralUndefined(int position) {
4496 return factory()->NewLiteral(
4497 isolate()->factory()->undefined_value(), position);
4501 Literal* Parser::GetLiteralTheHole(int position) {
4502 return factory()->NewLiteral(
4503 isolate()->factory()->the_hole_value(), RelocInfo::kNoPosition);
4507 // Parses an identifier that is valid for the current scope, in particular it
4508 // fails on strict mode future reserved keywords in a strict scope.
4509 Handle<String> Parser::ParseIdentifier(bool* ok) {
4510 Token::Value next = Next();
4511 if (next == Token::IDENTIFIER ||
4512 (top_scope_->is_classic_mode() &&
4513 (next == Token::FUTURE_STRICT_RESERVED_WORD ||
4514 (next == Token::YIELD && !is_generator())))) {
4517 ReportUnexpectedToken(next);
4519 return Handle<String>();
4524 // Parses and identifier or a strict mode future reserved word, and indicate
4525 // whether it is strict mode future reserved.
4526 Handle<String> Parser::ParseIdentifierOrStrictReservedWord(
4527 bool* is_strict_reserved, bool* ok) {
4528 Token::Value next = Next();
4529 if (next == Token::IDENTIFIER) {
4530 *is_strict_reserved = false;
4531 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD ||
4532 (next == Token::YIELD && !is_generator())) {
4533 *is_strict_reserved = true;
4535 ReportUnexpectedToken(next);
4537 return Handle<String>();
4543 Handle<String> Parser::ParseIdentifierName(bool* ok) {
4544 Token::Value next = Next();
4545 if (next != Token::IDENTIFIER &&
4546 next != Token::FUTURE_RESERVED_WORD &&
4547 next != Token::FUTURE_STRICT_RESERVED_WORD &&
4548 !Token::IsKeyword(next)) {
4549 ReportUnexpectedToken(next);
4551 return Handle<String>();
4557 void Parser::MarkAsLValue(Expression* expression) {
4558 VariableProxy* proxy = expression != NULL
4559 ? expression->AsVariableProxy()
4562 if (proxy != NULL) proxy->MarkAsLValue();
4566 // Checks LHS expression for assignment and prefix/postfix increment/decrement
4568 void Parser::CheckStrictModeLValue(Expression* expression,
4571 ASSERT(!top_scope_->is_classic_mode());
4572 VariableProxy* lhs = expression != NULL
4573 ? expression->AsVariableProxy()
4576 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) {
4577 ReportMessage(error, Vector<const char*>::empty());
4583 // Checks whether an octal literal was last seen between beg_pos and end_pos.
4584 // If so, reports an error. Only called for strict mode.
4585 void ParserBase::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
4586 Scanner::Location octal = scanner()->octal_position();
4587 if (octal.IsValid() && beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) {
4588 ReportMessageAt(octal, "strict_octal_literal");
4589 scanner()->clear_octal_position();
4595 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
4596 Declaration* decl = scope->CheckConflictingVarDeclarations();
4598 // In harmony mode we treat conflicting variable bindinds as early
4599 // errors. See ES5 16 for a definition of early errors.
4600 Handle<String> name = decl->proxy()->name();
4601 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
4602 const char* elms[2] = { "Variable", c_string.get() };
4603 Vector<const char*> args(elms, 2);
4604 int position = decl->proxy()->position();
4605 Scanner::Location location = position == RelocInfo::kNoPosition
4606 ? Scanner::Location::invalid()
4607 : Scanner::Location(position, position + 1);
4608 ReportMessageAt(location, "redeclaration", args);
4614 // This function reads an identifier name and determines whether or not it
4615 // is 'get' or 'set'.
4616 Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get,
4619 Handle<String> result = ParseIdentifierName(ok);
4620 if (!*ok) return Handle<String>();
4621 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) {
4622 const char* token = scanner().literal_ascii_string().start();
4623 *is_get = strncmp(token, "get", 3) == 0;
4624 *is_set = !*is_get && strncmp(token, "set", 3) == 0;
4630 // ----------------------------------------------------------------------------
4634 bool Parser::TargetStackContainsLabel(Handle<String> label) {
4635 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4636 BreakableStatement* stat = t->node()->AsBreakableStatement();
4637 if (stat != NULL && ContainsLabel(stat->labels(), label))
4644 BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) {
4645 bool anonymous = label.is_null();
4646 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4647 BreakableStatement* stat = t->node()->AsBreakableStatement();
4648 if (stat == NULL) continue;
4649 if ((anonymous && stat->is_target_for_anonymous()) ||
4650 (!anonymous && ContainsLabel(stat->labels(), label))) {
4651 RegisterTargetUse(stat->break_target(), t->previous());
4659 IterationStatement* Parser::LookupContinueTarget(Handle<String> label,
4661 bool anonymous = label.is_null();
4662 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4663 IterationStatement* stat = t->node()->AsIterationStatement();
4664 if (stat == NULL) continue;
4666 ASSERT(stat->is_target_for_anonymous());
4667 if (anonymous || ContainsLabel(stat->labels(), label)) {
4668 RegisterTargetUse(stat->continue_target(), t->previous());
4676 void Parser::RegisterTargetUse(Label* target, Target* stop) {
4677 // Register that a break target found at the given stop in the
4678 // target stack has been used from the top of the target stack. Add
4679 // the break target to any TargetCollectors passed on the stack.
4680 for (Target* t = target_stack_; t != stop; t = t->previous()) {
4681 TargetCollector* collector = t->node()->AsTargetCollector();
4682 if (collector != NULL) collector->AddTarget(target, zone());
4687 Expression* Parser::NewThrowReferenceError(Handle<String> message) {
4688 return NewThrowError(isolate()->factory()->MakeReferenceError_string(),
4689 message, HandleVector<Object>(NULL, 0));
4693 Expression* Parser::NewThrowSyntaxError(Handle<String> message,
4694 Handle<Object> first) {
4695 int argc = first.is_null() ? 0 : 1;
4696 Vector< Handle<Object> > arguments = HandleVector<Object>(&first, argc);
4697 return NewThrowError(
4698 isolate()->factory()->MakeSyntaxError_string(), message, arguments);
4702 Expression* Parser::NewThrowTypeError(Handle<String> message,
4703 Handle<Object> first,
4704 Handle<Object> second) {
4705 ASSERT(!first.is_null() && !second.is_null());
4706 Handle<Object> elements[] = { first, second };
4707 Vector< Handle<Object> > arguments =
4708 HandleVector<Object>(elements, ARRAY_SIZE(elements));
4709 return NewThrowError(
4710 isolate()->factory()->MakeTypeError_string(), message, arguments);
4714 Expression* Parser::NewThrowError(Handle<String> constructor,
4715 Handle<String> message,
4716 Vector< Handle<Object> > arguments) {
4717 int argc = arguments.length();
4718 Handle<FixedArray> elements = isolate()->factory()->NewFixedArray(argc,
4720 for (int i = 0; i < argc; i++) {
4721 Handle<Object> element = arguments[i];
4722 if (!element.is_null()) {
4723 elements->set(i, *element);
4726 Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements(
4727 elements, FAST_ELEMENTS, TENURED);
4729 int pos = position();
4730 ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2, zone());
4731 args->Add(factory()->NewLiteral(message, pos), zone());
4732 args->Add(factory()->NewLiteral(array, pos), zone());
4733 CallRuntime* call_constructor =
4734 factory()->NewCallRuntime(constructor, NULL, args, pos);
4735 return factory()->NewThrow(call_constructor, pos);
4739 // ----------------------------------------------------------------------------
4740 // Regular expressions
4743 RegExpParser::RegExpParser(FlatStringReader* in,
4744 Handle<String>* error,
4747 : isolate_(zone->isolate()),
4752 current_(kEndMarker),
4756 multiline_(multiline),
4758 contains_anchor_(false),
4759 is_scanned_for_captures_(false),
4765 uc32 RegExpParser::Next() {
4767 return in()->Get(next_pos_);
4774 void RegExpParser::Advance() {
4775 if (next_pos_ < in()->length()) {
4776 StackLimitCheck check(isolate());
4777 if (check.HasOverflowed()) {
4778 ReportError(CStrVector(Isolate::kStackOverflowMessage));
4779 } else if (zone()->excess_allocation()) {
4780 ReportError(CStrVector("Regular expression too large"));
4782 current_ = in()->Get(next_pos_);
4786 current_ = kEndMarker;
4792 void RegExpParser::Reset(int pos) {
4794 has_more_ = (pos < in()->length());
4799 void RegExpParser::Advance(int dist) {
4800 next_pos_ += dist - 1;
4805 bool RegExpParser::simple() {
4810 RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
4812 *error_ = isolate()->factory()->NewStringFromAscii(message, NOT_TENURED);
4813 // Zip to the end to make sure the no more input is read.
4814 current_ = kEndMarker;
4815 next_pos_ = in()->length();
4822 RegExpTree* RegExpParser::ParsePattern() {
4823 RegExpTree* result = ParseDisjunction(CHECK_FAILED);
4824 ASSERT(!has_more());
4825 // If the result of parsing is a literal string atom, and it has the
4826 // same length as the input, then the atom is identical to the input.
4827 if (result->IsAtom() && result->AsAtom()->length() == in()->length()) {
4836 // Alternative | Disjunction
4844 RegExpTree* RegExpParser::ParseDisjunction() {
4845 // Used to store current state while parsing subexpressions.
4846 RegExpParserState initial_state(NULL, INITIAL, 0, zone());
4847 RegExpParserState* stored_state = &initial_state;
4848 // Cache the builder in a local variable for quick access.
4849 RegExpBuilder* builder = initial_state.builder();
4851 switch (current()) {
4853 if (stored_state->IsSubexpression()) {
4854 // Inside a parenthesized group when hitting end of input.
4855 ReportError(CStrVector("Unterminated group") CHECK_FAILED);
4857 ASSERT_EQ(INITIAL, stored_state->group_type());
4858 // Parsing completed successfully.
4859 return builder->ToRegExp();
4861 if (!stored_state->IsSubexpression()) {
4862 ReportError(CStrVector("Unmatched ')'") CHECK_FAILED);
4864 ASSERT_NE(INITIAL, stored_state->group_type());
4867 // End disjunction parsing and convert builder content to new single
4869 RegExpTree* body = builder->ToRegExp();
4871 int end_capture_index = captures_started();
4873 int capture_index = stored_state->capture_index();
4874 SubexpressionType group_type = stored_state->group_type();
4876 // Restore previous state.
4877 stored_state = stored_state->previous_state();
4878 builder = stored_state->builder();
4880 // Build result of subexpression.
4881 if (group_type == CAPTURE) {
4882 RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index);
4883 captures_->at(capture_index - 1) = capture;
4885 } else if (group_type != GROUPING) {
4886 ASSERT(group_type == POSITIVE_LOOKAHEAD ||
4887 group_type == NEGATIVE_LOOKAHEAD);
4888 bool is_positive = (group_type == POSITIVE_LOOKAHEAD);
4889 body = new(zone()) RegExpLookahead(body,
4891 end_capture_index - capture_index,
4894 builder->AddAtom(body);
4895 // For compatability with JSC and ES3, we allow quantifiers after
4896 // lookaheads, and break in all cases.
4901 builder->NewAlternative();
4907 return ReportError(CStrVector("Nothing to repeat"));
4911 builder->AddAssertion(
4912 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE));
4914 builder->AddAssertion(
4915 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
4916 set_contains_anchor();
4922 RegExpAssertion::AssertionType assertion_type =
4923 multiline_ ? RegExpAssertion::END_OF_LINE :
4924 RegExpAssertion::END_OF_INPUT;
4925 builder->AddAssertion(new(zone()) RegExpAssertion(assertion_type));
4930 // everything except \x0a, \x0d, \u2028 and \u2029
4931 ZoneList<CharacterRange>* ranges =
4932 new(zone()) ZoneList<CharacterRange>(2, zone());
4933 CharacterRange::AddClassEscape('.', ranges, zone());
4934 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
4935 builder->AddAtom(atom);
4939 SubexpressionType subexpr_type = CAPTURE;
4941 if (current() == '?') {
4944 subexpr_type = GROUPING;
4947 subexpr_type = POSITIVE_LOOKAHEAD;
4950 subexpr_type = NEGATIVE_LOOKAHEAD;
4953 ReportError(CStrVector("Invalid group") CHECK_FAILED);
4958 if (captures_ == NULL) {
4959 captures_ = new(zone()) ZoneList<RegExpCapture*>(2, zone());
4961 if (captures_started() >= kMaxCaptures) {
4962 ReportError(CStrVector("Too many captures") CHECK_FAILED);
4964 captures_->Add(NULL, zone());
4966 // Store current state and begin new disjunction parsing.
4967 stored_state = new(zone()) RegExpParserState(stored_state, subexpr_type,
4968 captures_started(), zone());
4969 builder = stored_state->builder();
4973 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED);
4974 builder->AddAtom(atom);
4982 return ReportError(CStrVector("\\ at end of pattern"));
4985 builder->AddAssertion(
4986 new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
4990 builder->AddAssertion(
4991 new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
4994 // CharacterClassEscape
4996 // CharacterClassEscape :: one of
4998 case 'd': case 'D': case 's': case 'S': case 'w': case 'W': {
5001 ZoneList<CharacterRange>* ranges =
5002 new(zone()) ZoneList<CharacterRange>(2, zone());
5003 CharacterRange::AddClassEscape(c, ranges, zone());
5004 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
5005 builder->AddAtom(atom);
5008 case '1': case '2': case '3': case '4': case '5': case '6':
5009 case '7': case '8': case '9': {
5011 if (ParseBackReferenceIndex(&index)) {
5012 RegExpCapture* capture = NULL;
5013 if (captures_ != NULL && index <= captures_->length()) {
5014 capture = captures_->at(index - 1);
5016 if (capture == NULL) {
5017 builder->AddEmpty();
5020 RegExpTree* atom = new(zone()) RegExpBackReference(capture);
5021 builder->AddAtom(atom);
5024 uc32 first_digit = Next();
5025 if (first_digit == '8' || first_digit == '9') {
5026 // Treat as identity escape
5027 builder->AddCharacter(first_digit);
5035 uc32 octal = ParseOctalLiteral();
5036 builder->AddCharacter(octal);
5039 // ControlEscape :: one of
5043 builder->AddCharacter('\f');
5047 builder->AddCharacter('\n');
5051 builder->AddCharacter('\r');
5055 builder->AddCharacter('\t');
5059 builder->AddCharacter('\v');
5063 uc32 controlLetter = Next();
5064 // Special case if it is an ASCII letter.
5065 // Convert lower case letters to uppercase.
5066 uc32 letter = controlLetter & ~('a' ^ 'A');
5067 if (letter < 'A' || 'Z' < letter) {
5068 // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
5069 // This is outside the specification. We match JSC in
5070 // reading the backslash as a literal character instead
5071 // of as starting an escape.
5072 builder->AddCharacter('\\');
5075 builder->AddCharacter(controlLetter & 0x1f);
5082 if (ParseHexEscape(2, &value)) {
5083 builder->AddCharacter(value);
5085 builder->AddCharacter('x');
5092 if (ParseHexEscape(4, &value)) {
5093 builder->AddCharacter(value);
5095 builder->AddCharacter('u');
5101 builder->AddCharacter(Next());
5108 if (ParseIntervalQuantifier(&dummy, &dummy)) {
5109 ReportError(CStrVector("Nothing to repeat") CHECK_FAILED);
5114 builder->AddCharacter(current());
5117 } // end switch(current())
5121 switch (current()) {
5122 // QuantifierPrefix ::
5129 max = RegExpTree::kInfinity;
5134 max = RegExpTree::kInfinity;
5143 if (ParseIntervalQuantifier(&min, &max)) {
5145 ReportError(CStrVector("numbers out of order in {} quantifier.")
5155 RegExpQuantifier::QuantifierType quantifier_type = RegExpQuantifier::GREEDY;
5156 if (current() == '?') {
5157 quantifier_type = RegExpQuantifier::NON_GREEDY;
5159 } else if (FLAG_regexp_possessive_quantifier && current() == '+') {
5160 // FLAG_regexp_possessive_quantifier is a debug-only flag.
5161 quantifier_type = RegExpQuantifier::POSSESSIVE;
5164 builder->AddQuantifierToAtom(min, max, quantifier_type);
5170 // Currently only used in an ASSERT.
5171 static bool IsSpecialClassEscape(uc32 c) {
5184 // In order to know whether an escape is a backreference or not we have to scan
5185 // the entire regexp and find the number of capturing parentheses. However we
5186 // don't want to scan the regexp twice unless it is necessary. This mini-parser
5187 // is called when needed. It can see the difference between capturing and
5188 // noncapturing parentheses and can skip character classes and backslash-escaped
5190 void RegExpParser::ScanForCaptures() {
5191 // Start with captures started previous to current position
5192 int capture_count = captures_started();
5193 // Add count of captures after this position.
5195 while ((n = current()) != kEndMarker) {
5203 while ((c = current()) != kEndMarker) {
5208 if (c == ']') break;
5214 if (current() != '?') capture_count++;
5218 capture_count_ = capture_count;
5219 is_scanned_for_captures_ = true;
5223 bool RegExpParser::ParseBackReferenceIndex(int* index_out) {
5224 ASSERT_EQ('\\', current());
5225 ASSERT('1' <= Next() && Next() <= '9');
5226 // Try to parse a decimal literal that is no greater than the total number
5227 // of left capturing parentheses in the input.
5228 int start = position();
5229 int value = Next() - '0';
5233 if (IsDecimalDigit(c)) {
5234 value = 10 * value + (c - '0');
5235 if (value > kMaxCaptures) {
5244 if (value > captures_started()) {
5245 if (!is_scanned_for_captures_) {
5246 int saved_position = position();
5248 Reset(saved_position);
5250 if (value > capture_count_) {
5260 // QuantifierPrefix ::
5261 // { DecimalDigits }
5262 // { DecimalDigits , }
5263 // { DecimalDigits , DecimalDigits }
5265 // Returns true if parsing succeeds, and set the min_out and max_out
5266 // values. Values are truncated to RegExpTree::kInfinity if they overflow.
5267 bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
5268 ASSERT_EQ(current(), '{');
5269 int start = position();
5272 if (!IsDecimalDigit(current())) {
5276 while (IsDecimalDigit(current())) {
5277 int next = current() - '0';
5278 if (min > (RegExpTree::kInfinity - next) / 10) {
5279 // Overflow. Skip past remaining decimal digits and return -1.
5282 } while (IsDecimalDigit(current()));
5283 min = RegExpTree::kInfinity;
5286 min = 10 * min + next;
5290 if (current() == '}') {
5293 } else if (current() == ',') {
5295 if (current() == '}') {
5296 max = RegExpTree::kInfinity;
5299 while (IsDecimalDigit(current())) {
5300 int next = current() - '0';
5301 if (max > (RegExpTree::kInfinity - next) / 10) {
5304 } while (IsDecimalDigit(current()));
5305 max = RegExpTree::kInfinity;
5308 max = 10 * max + next;
5311 if (current() != '}') {
5327 uc32 RegExpParser::ParseOctalLiteral() {
5328 ASSERT('0' <= current() && current() <= '7');
5329 // For compatibility with some other browsers (not all), we parse
5330 // up to three octal digits with a value below 256.
5331 uc32 value = current() - '0';
5333 if ('0' <= current() && current() <= '7') {
5334 value = value * 8 + current() - '0';
5336 if (value < 32 && '0' <= current() && current() <= '7') {
5337 value = value * 8 + current() - '0';
5345 bool RegExpParser::ParseHexEscape(int length, uc32 *value) {
5346 int start = position();
5349 for (int i = 0; !done; i++) {
5351 int d = HexValue(c);
5358 if (i == length - 1) {
5367 uc32 RegExpParser::ParseClassCharacterEscape() {
5368 ASSERT(current() == '\\');
5369 ASSERT(has_next() && !IsSpecialClassEscape(Next()));
5371 switch (current()) {
5375 // ControlEscape :: one of
5393 uc32 controlLetter = Next();
5394 uc32 letter = controlLetter & ~('A' ^ 'a');
5395 // For compatibility with JSC, inside a character class
5396 // we also accept digits and underscore as control characters.
5397 if ((controlLetter >= '0' && controlLetter <= '9') ||
5398 controlLetter == '_' ||
5399 (letter >= 'A' && letter <= 'Z')) {
5401 // Control letters mapped to ASCII control characters in the range
5403 return controlLetter & 0x1f;
5405 // We match JSC in reading the backslash as a literal
5406 // character instead of as starting an escape.
5409 case '0': case '1': case '2': case '3': case '4': case '5':
5411 // For compatibility, we interpret a decimal escape that isn't
5412 // a back reference (and therefore either \0 or not valid according
5413 // to the specification) as a 1..3 digit octal character code.
5414 return ParseOctalLiteral();
5418 if (ParseHexEscape(2, &value)) {
5421 // If \x is not followed by a two-digit hexadecimal, treat it
5422 // as an identity escape.
5428 if (ParseHexEscape(4, &value)) {
5431 // If \u is not followed by a four-digit hexadecimal, treat it
5432 // as an identity escape.
5436 // Extended identity escape. We accept any character that hasn't
5437 // been matched by a more specific case, not just the subset required
5438 // by the ECMAScript specification.
5439 uc32 result = current();
5448 CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) {
5449 ASSERT_EQ(0, *char_class);
5450 uc32 first = current();
5451 if (first == '\\') {
5453 case 'w': case 'W': case 'd': case 'D': case 's': case 'S': {
5454 *char_class = Next();
5456 return CharacterRange::Singleton(0); // Return dummy value.
5459 return ReportError(CStrVector("\\ at end of pattern"));
5461 uc32 c = ParseClassCharacterEscape(CHECK_FAILED);
5462 return CharacterRange::Singleton(c);
5466 return CharacterRange::Singleton(first);
5471 static const uc16 kNoCharClass = 0;
5473 // Adds range or pre-defined character class to character ranges.
5474 // If char_class is not kInvalidClass, it's interpreted as a class
5475 // escape (i.e., 's' means whitespace, from '\s').
5476 static inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges,
5478 CharacterRange range,
5480 if (char_class != kNoCharClass) {
5481 CharacterRange::AddClassEscape(char_class, ranges, zone);
5483 ranges->Add(range, zone);
5488 RegExpTree* RegExpParser::ParseCharacterClass() {
5489 static const char* kUnterminated = "Unterminated character class";
5490 static const char* kRangeOutOfOrder = "Range out of order in character class";
5492 ASSERT_EQ(current(), '[');
5494 bool is_negated = false;
5495 if (current() == '^') {
5499 ZoneList<CharacterRange>* ranges =
5500 new(zone()) ZoneList<CharacterRange>(2, zone());
5501 while (has_more() && current() != ']') {
5502 uc16 char_class = kNoCharClass;
5503 CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED);
5504 if (current() == '-') {
5506 if (current() == kEndMarker) {
5507 // If we reach the end we break out of the loop and let the
5508 // following code report an error.
5510 } else if (current() == ']') {
5511 AddRangeOrEscape(ranges, char_class, first, zone());
5512 ranges->Add(CharacterRange::Singleton('-'), zone());
5515 uc16 char_class_2 = kNoCharClass;
5516 CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED);
5517 if (char_class != kNoCharClass || char_class_2 != kNoCharClass) {
5518 // Either end is an escaped character class. Treat the '-' verbatim.
5519 AddRangeOrEscape(ranges, char_class, first, zone());
5520 ranges->Add(CharacterRange::Singleton('-'), zone());
5521 AddRangeOrEscape(ranges, char_class_2, next, zone());
5524 if (first.from() > next.to()) {
5525 return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED);
5527 ranges->Add(CharacterRange::Range(first.from(), next.to()), zone());
5529 AddRangeOrEscape(ranges, char_class, first, zone());
5533 return ReportError(CStrVector(kUnterminated) CHECK_FAILED);
5536 if (ranges->length() == 0) {
5537 ranges->Add(CharacterRange::Everything(), zone());
5538 is_negated = !is_negated;
5540 return new(zone()) RegExpCharacterClass(ranges, is_negated);
5544 // ----------------------------------------------------------------------------
5545 // The Parser interface.
5547 ScriptDataImpl::~ScriptDataImpl() {
5548 if (owns_store_) store_.Dispose();
5552 int ScriptDataImpl::Length() {
5553 return store_.length() * sizeof(unsigned);
5557 const char* ScriptDataImpl::Data() {
5558 return reinterpret_cast<const char*>(store_.start());
5562 bool ScriptDataImpl::HasError() {
5567 void ScriptDataImpl::Initialize() {
5568 // Prepares state for use.
5569 if (store_.length() >= PreparseDataConstants::kHeaderSize) {
5570 function_index_ = PreparseDataConstants::kHeaderSize;
5571 int symbol_data_offset = PreparseDataConstants::kHeaderSize
5572 + store_[PreparseDataConstants::kFunctionsSizeOffset];
5573 if (store_.length() > symbol_data_offset) {
5574 symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]);
5576 // Partial preparse causes no symbol information.
5577 symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
5579 symbol_data_end_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
5584 int ScriptDataImpl::ReadNumber(byte** source) {
5585 // Reads a number from symbol_data_ in base 128. The most significant
5586 // bit marks that there are more digits.
5587 // If the first byte is 0x80 (kNumberTerminator), it would normally
5588 // represent a leading zero. Since that is useless, and therefore won't
5589 // appear as the first digit of any actual value, it is used to
5590 // mark the end of the input stream.
5591 byte* data = *source;
5592 if (data >= symbol_data_end_) return -1;
5594 if (input == PreparseDataConstants::kNumberTerminator) {
5595 // End of stream marker.
5598 int result = input & 0x7f;
5600 while ((input & 0x80u) != 0) {
5601 if (data >= symbol_data_end_) return -1;
5603 result = (result << 7) | (input & 0x7f);
5611 // Create a Scanner for the preparser to use as input, and preparse the source.
5612 ScriptDataImpl* PreParserApi::PreParse(Isolate* isolate,
5613 Utf16CharacterStream* source) {
5614 CompleteParserRecorder recorder;
5615 HistogramTimerScope timer(isolate->counters()->pre_parse());
5616 Scanner scanner(isolate->unicode_cache());
5617 intptr_t stack_limit = isolate->stack_guard()->real_climit();
5618 PreParser preparser(&scanner, &recorder, stack_limit);
5619 preparser.set_allow_lazy(true);
5620 preparser.set_allow_generators(FLAG_harmony_generators);
5621 preparser.set_allow_for_of(FLAG_harmony_iteration);
5622 preparser.set_allow_harmony_scoping(FLAG_harmony_scoping);
5623 preparser.set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
5624 scanner.Initialize(source);
5625 PreParser::PreParseResult result = preparser.PreParseProgram();
5626 if (result == PreParser::kPreParseStackOverflow) {
5627 isolate->StackOverflow();
5631 // Extract the accumulated data from the recorder as a single
5632 // contiguous vector that we are responsible for disposing.
5633 Vector<unsigned> store = recorder.ExtractData();
5634 return new ScriptDataImpl(store);
5638 bool RegExpParser::ParseRegExp(FlatStringReader* input,
5640 RegExpCompileData* result,
5642 ASSERT(result != NULL);
5643 RegExpParser parser(input, &result->error, multiline, zone);
5644 RegExpTree* tree = parser.ParsePattern();
5645 if (parser.failed()) {
5646 ASSERT(tree == NULL);
5647 ASSERT(!result->error.is_null());
5649 ASSERT(tree != NULL);
5650 ASSERT(result->error.is_null());
5651 result->tree = tree;
5652 int capture_count = parser.captures_started();
5653 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
5654 result->contains_anchor = parser.contains_anchor();
5655 result->capture_count = capture_count;
5657 return !parser.failed();
5661 bool Parser::Parse() {
5662 ASSERT(info()->function() == NULL);
5663 FunctionLiteral* result = NULL;
5664 if (info()->is_lazy()) {
5665 ASSERT(!info()->is_eval());
5666 if (info()->shared_info()->is_function()) {
5667 result = ParseLazy();
5669 result = ParseProgram();
5672 ScriptDataImpl* pre_parse_data = info()->pre_parse_data();
5673 set_pre_parse_data(pre_parse_data);
5674 if (pre_parse_data != NULL && pre_parse_data->has_error()) {
5675 Scanner::Location loc = pre_parse_data->MessageLocation();
5676 const char* message = pre_parse_data->BuildMessage();
5677 Vector<const char*> args = pre_parse_data->BuildArgs();
5678 ReportMessageAt(loc, message, args);
5679 DeleteArray(message);
5680 for (int i = 0; i < args.length(); i++) {
5681 DeleteArray(args[i]);
5683 DeleteArray(args.start());
5684 ASSERT(info()->isolate()->has_pending_exception());
5686 result = ParseProgram();
5689 info()->SetFunction(result);
5690 return (result != NULL);
5693 } } // namespace v8::internal