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) {}
55 ~PositionStack() { ASSERT(!*ok_ || is_empty()); }
59 Element(PositionStack* stack, int value) {
60 previous_ = stack->top();
66 Element* previous() { return previous_; }
67 int value() { return value_; }
68 friend class PositionStack;
73 bool is_empty() { return top_ == NULL; }
76 int result = top_->value();
77 top_ = top_->previous();
82 Element* top() { return top_; }
83 void set_top(Element* value) { top_ = value; }
89 RegExpBuilder::RegExpBuilder()
90 : zone_(Isolate::Current()->zone()),
91 pending_empty_(false),
96 , last_added_(ADD_NONE)
101 void RegExpBuilder::FlushCharacters() {
102 pending_empty_ = false;
103 if (characters_ != NULL) {
104 RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector());
112 void RegExpBuilder::FlushText() {
114 int num_text = text_.length();
117 } else if (num_text == 1) {
118 terms_.Add(text_.last());
120 RegExpText* text = new(zone()) RegExpText();
121 for (int i = 0; i < num_text; i++)
122 text_.Get(i)->AppendToText(text);
129 void RegExpBuilder::AddCharacter(uc16 c) {
130 pending_empty_ = false;
131 if (characters_ == NULL) {
132 characters_ = new(zone()) ZoneList<uc16>(4);
139 void RegExpBuilder::AddEmpty() {
140 pending_empty_ = true;
144 void RegExpBuilder::AddAtom(RegExpTree* term) {
145 if (term->IsEmpty()) {
149 if (term->IsTextElement()) {
160 void RegExpBuilder::AddAssertion(RegExpTree* assert) {
167 void RegExpBuilder::NewAlternative() {
172 void RegExpBuilder::FlushTerms() {
174 int num_terms = terms_.length();
175 RegExpTree* alternative;
176 if (num_terms == 0) {
177 alternative = RegExpEmpty::GetInstance();
178 } else if (num_terms == 1) {
179 alternative = terms_.last();
181 alternative = new(zone()) RegExpAlternative(terms_.GetList());
183 alternatives_.Add(alternative);
189 RegExpTree* RegExpBuilder::ToRegExp() {
191 int num_alternatives = alternatives_.length();
192 if (num_alternatives == 0) {
193 return RegExpEmpty::GetInstance();
195 if (num_alternatives == 1) {
196 return alternatives_.last();
198 return new(zone()) RegExpDisjunction(alternatives_.GetList());
202 void RegExpBuilder::AddQuantifierToAtom(int min,
204 RegExpQuantifier::Type type) {
205 if (pending_empty_) {
206 pending_empty_ = false;
210 if (characters_ != NULL) {
211 ASSERT(last_added_ == ADD_CHAR);
212 // Last atom was character.
213 Vector<const uc16> char_vector = characters_->ToConstVector();
214 int num_chars = char_vector.length();
216 Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1);
217 text_.Add(new(zone()) RegExpAtom(prefix));
218 char_vector = char_vector.SubVector(num_chars - 1, num_chars);
221 atom = new(zone()) RegExpAtom(char_vector);
223 } else if (text_.length() > 0) {
224 ASSERT(last_added_ == ADD_ATOM);
225 atom = text_.RemoveLast();
227 } else if (terms_.length() > 0) {
228 ASSERT(last_added_ == ADD_ATOM);
229 atom = terms_.RemoveLast();
230 if (atom->max_match() == 0) {
231 // Guaranteed to only match an empty string.
240 // Only call immediately after adding an atom or character!
244 terms_.Add(new(zone()) RegExpQuantifier(min, max, type, atom));
249 Handle<String> Parser::LookupSymbol(int symbol_id) {
250 // Length of symbol cache is the number of identified symbols.
251 // If we are larger than that, or negative, it's not a cached symbol.
252 // This might also happen if there is no preparser symbol data, even
253 // if there is some preparser data.
254 if (static_cast<unsigned>(symbol_id)
255 >= static_cast<unsigned>(symbol_cache_.length())) {
256 if (scanner().is_literal_ascii()) {
257 return isolate()->factory()->LookupAsciiSymbol(
258 scanner().literal_ascii_string());
260 return isolate()->factory()->LookupTwoByteSymbol(
261 scanner().literal_utf16_string());
264 return LookupCachedSymbol(symbol_id);
268 Handle<String> Parser::LookupCachedSymbol(int symbol_id) {
269 // Make sure the cache is large enough to hold the symbol identifier.
270 if (symbol_cache_.length() <= symbol_id) {
271 // Increase length to index + 1.
272 symbol_cache_.AddBlock(Handle<String>::null(),
273 symbol_id + 1 - symbol_cache_.length());
275 Handle<String> result = symbol_cache_.at(symbol_id);
276 if (result.is_null()) {
277 if (scanner().is_literal_ascii()) {
278 result = isolate()->factory()->LookupAsciiSymbol(
279 scanner().literal_ascii_string());
281 result = isolate()->factory()->LookupTwoByteSymbol(
282 scanner().literal_utf16_string());
284 symbol_cache_.at(symbol_id) = result;
287 isolate()->counters()->total_preparse_symbols_skipped()->Increment();
292 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) {
293 // The current pre-data entry must be a FunctionEntry with the given
295 if ((function_index_ + FunctionEntry::kSize <= store_.length())
296 && (static_cast<int>(store_[function_index_]) == start)) {
297 int index = function_index_;
298 function_index_ += FunctionEntry::kSize;
299 return FunctionEntry(store_.SubVector(index,
300 index + FunctionEntry::kSize));
302 return FunctionEntry();
306 int ScriptDataImpl::GetSymbolIdentifier() {
307 return ReadNumber(&symbol_data_);
311 bool ScriptDataImpl::SanityCheck() {
312 // Check that the header data is valid and doesn't specify
313 // point to positions outside the store.
314 if (store_.length() < PreparseDataConstants::kHeaderSize) return false;
315 if (magic() != PreparseDataConstants::kMagicNumber) return false;
316 if (version() != PreparseDataConstants::kCurrentVersion) return false;
318 // Extra sane sanity check for error message encoding.
319 if (store_.length() <= PreparseDataConstants::kHeaderSize
320 + PreparseDataConstants::kMessageTextPos) {
323 if (Read(PreparseDataConstants::kMessageStartPos) >
324 Read(PreparseDataConstants::kMessageEndPos)) {
327 unsigned arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
328 int pos = PreparseDataConstants::kMessageTextPos;
329 for (unsigned int i = 0; i <= arg_count; i++) {
330 if (store_.length() <= PreparseDataConstants::kHeaderSize + pos) {
333 int length = static_cast<int>(Read(pos));
334 if (length < 0) return false;
337 if (store_.length() < PreparseDataConstants::kHeaderSize + pos) {
342 // Check that the space allocated for function entries is sane.
344 static_cast<int>(store_[PreparseDataConstants::kFunctionsSizeOffset]);
345 if (functions_size < 0) return false;
346 if (functions_size % FunctionEntry::kSize != 0) return false;
347 // Check that the count of symbols is non-negative.
349 static_cast<int>(store_[PreparseDataConstants::kSymbolCountOffset]);
350 if (symbol_count < 0) return false;
351 // Check that the total size has room for header and function entries.
353 PreparseDataConstants::kHeaderSize + functions_size;
354 if (store_.length() < minimum_size) return false;
360 const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) {
361 int length = start[0];
362 char* result = NewArray<char>(length + 1);
363 for (int i = 0; i < length; i++) {
364 result[i] = start[i + 1];
366 result[length] = '\0';
367 if (chars != NULL) *chars = length;
371 Scanner::Location ScriptDataImpl::MessageLocation() {
372 int beg_pos = Read(PreparseDataConstants::kMessageStartPos);
373 int end_pos = Read(PreparseDataConstants::kMessageEndPos);
374 return Scanner::Location(beg_pos, end_pos);
378 const char* ScriptDataImpl::BuildMessage() {
379 unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos);
380 return ReadString(start, NULL);
384 Vector<const char*> ScriptDataImpl::BuildArgs() {
385 int arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
386 const char** array = NewArray<const char*>(arg_count);
387 // Position after text found by skipping past length field and
388 // length field content words.
389 int pos = PreparseDataConstants::kMessageTextPos + 1
390 + Read(PreparseDataConstants::kMessageTextPos);
391 for (int i = 0; i < arg_count; i++) {
393 array[i] = ReadString(ReadAddress(pos), &count);
396 return Vector<const char*>(array, arg_count);
400 unsigned ScriptDataImpl::Read(int position) {
401 return store_[PreparseDataConstants::kHeaderSize + position];
405 unsigned* ScriptDataImpl::ReadAddress(int position) {
406 return &store_[PreparseDataConstants::kHeaderSize + position];
410 Scope* Parser::NewScope(Scope* parent, ScopeType type) {
411 Scope* result = new(zone()) Scope(parent, type);
412 result->Initialize();
417 // ----------------------------------------------------------------------------
418 // Target is a support class to facilitate manipulation of the
419 // Parser's target_stack_ (the stack of potential 'break' and
420 // 'continue' statement targets). Upon construction, a new target is
421 // added; it is removed upon destruction.
423 class Target BASE_EMBEDDED {
425 Target(Target** variable, AstNode* node)
426 : variable_(variable), node_(node), previous_(*variable) {
431 *variable_ = previous_;
434 Target* previous() { return previous_; }
435 AstNode* node() { return node_; }
444 class TargetScope BASE_EMBEDDED {
446 explicit TargetScope(Target** variable)
447 : variable_(variable), previous_(*variable) {
452 *variable_ = previous_;
461 // ----------------------------------------------------------------------------
462 // FunctionState and BlockState together implement the parser's scope stack.
463 // The parser's current scope is in top_scope_. The BlockState and
464 // FunctionState constructors push on the scope stack and the destructors
465 // pop. They are also used to hold the parser's per-function and per-block
468 class Parser::BlockState BASE_EMBEDDED {
470 BlockState(Parser* parser, Scope* scope)
472 outer_scope_(parser->top_scope_) {
473 parser->top_scope_ = scope;
476 ~BlockState() { parser_->top_scope_ = outer_scope_; }
484 Parser::FunctionState::FunctionState(Parser* parser,
487 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
488 next_handler_index_(0),
489 expected_property_count_(0),
490 only_simple_this_property_assignments_(false),
491 this_property_assignments_(isolate->factory()->empty_fixed_array()),
493 outer_function_state_(parser->current_function_state_),
494 outer_scope_(parser->top_scope_),
495 saved_ast_node_id_(isolate->ast_node_id()),
497 parser->top_scope_ = scope;
498 parser->current_function_state_ = this;
499 isolate->set_ast_node_id(AstNode::kDeclarationsId + 1);
503 Parser::FunctionState::~FunctionState() {
504 parser_->top_scope_ = outer_scope_;
505 parser_->current_function_state_ = outer_function_state_;
506 if (outer_function_state_ != NULL) {
507 parser_->isolate()->set_ast_node_id(saved_ast_node_id_);
512 // ----------------------------------------------------------------------------
513 // The CHECK_OK macro is a convenient macro to enforce error
514 // handling for functions that may fail (by returning !*ok).
516 // CAUTION: This macro appends extra statements after a call,
517 // thus it must never be used where only a single statement
518 // is correct (e.g. an if statement branch w/o braces)!
520 #define CHECK_OK ok); \
521 if (!*ok) return NULL; \
523 #define DUMMY ) // to make indentation work
526 #define CHECK_FAILED /**/); \
527 if (failed_) return NULL; \
529 #define DUMMY ) // to make indentation work
532 // ----------------------------------------------------------------------------
533 // Implementation of Parser
535 Parser::Parser(Handle<Script> script,
537 v8::Extension* extension,
538 ScriptDataImpl* pre_data)
539 : isolate_(script->GetIsolate()),
540 symbol_cache_(pre_data ? pre_data->symbol_count() : 0),
542 scanner_(isolate_->unicode_cache()),
543 reusable_preparser_(NULL),
545 current_function_state_(NULL),
547 extension_(extension),
550 allow_natives_syntax_((parser_flags & kAllowNativesSyntax) != 0),
551 allow_lazy_((parser_flags & kAllowLazy) != 0),
552 allow_modules_((parser_flags & kAllowModules) != 0),
553 stack_overflow_(false),
554 parenthesized_function_(false) {
555 isolate_->set_ast_node_id(0);
556 if ((parser_flags & kLanguageModeMask) == EXTENDED_MODE) {
557 scanner().SetHarmonyScoping(true);
559 if ((parser_flags & kAllowModules) != 0) {
560 scanner().SetHarmonyModules(true);
565 FunctionLiteral* Parser::ParseProgram(CompilationInfo* info) {
566 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
568 HistogramTimerScope timer(isolate()->counters()->parse());
569 Handle<String> source(String::cast(script_->source()));
570 isolate()->counters()->total_parse_size()->Increment(source->length());
571 fni_ = new(zone()) FuncNameInferrer(isolate());
573 // Initialize parser state.
574 source->TryFlatten();
575 if (source->IsExternalTwoByteString()) {
576 // Notice that the stream is destroyed at the end of the branch block.
577 // The last line of the blocks can't be moved outside, even though they're
579 ExternalTwoByteStringUtf16CharacterStream stream(
580 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
581 scanner_.Initialize(&stream);
582 return DoParseProgram(info, source, &zone_scope);
584 GenericStringUtf16CharacterStream stream(source, 0, source->length());
585 scanner_.Initialize(&stream);
586 return DoParseProgram(info, source, &zone_scope);
591 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
592 Handle<String> source,
593 ZoneScope* zone_scope) {
594 ASSERT(top_scope_ == NULL);
595 ASSERT(target_stack_ == NULL);
596 if (pre_data_ != NULL) pre_data_->Initialize();
598 // Compute the parsing mode.
599 mode_ = (FLAG_lazy && allow_lazy_) ? PARSE_LAZILY : PARSE_EAGERLY;
600 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY;
602 Handle<String> no_name = isolate()->factory()->empty_symbol();
604 FunctionLiteral* result = NULL;
605 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE);
606 info->SetGlobalScope(scope);
607 if (info->is_eval()) {
608 Handle<SharedFunctionInfo> shared = info->shared_info();
609 if (!info->is_global() && (shared.is_null() || shared->is_function())) {
610 scope = Scope::DeserializeScopeChain(*info->calling_context(), scope);
612 if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) {
613 scope = NewScope(scope, EVAL_SCOPE);
616 scope->set_start_position(0);
617 scope->set_end_position(source->length());
618 FunctionState function_state(this, scope, isolate());
619 top_scope_->SetLanguageMode(info->language_mode());
620 if (info->is_qml_mode()) {
621 scope->EnableQmlModeFlag();
623 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16);
625 int beg_loc = scanner().location().beg_pos;
626 ParseSourceElements(body, Token::EOS, info->is_eval(), &ok);
627 if (ok && !top_scope_->is_classic_mode()) {
628 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
631 if (ok && is_extended_mode()) {
632 CheckConflictingVarDeclarations(top_scope_, &ok);
636 result = factory()->NewFunctionLiteral(
640 function_state.materialized_literal_count(),
641 function_state.expected_property_count(),
642 function_state.handler_count(),
643 function_state.only_simple_this_property_assignments(),
644 function_state.this_property_assignments(),
646 FunctionLiteral::kNoDuplicateParameters,
647 FunctionLiteral::ANONYMOUS_EXPRESSION,
648 FunctionLiteral::kGlobalOrEval);
649 result->set_ast_properties(factory()->visitor()->ast_properties());
650 } else if (stack_overflow_) {
651 isolate()->StackOverflow();
655 // Make sure the target stack is empty.
656 ASSERT(target_stack_ == NULL);
658 // If there was a syntax error we have to get rid of the AST
659 // and it is not safe to do so before the scope has been deleted.
660 if (result == NULL) zone_scope->DeleteOnExit();
665 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) {
666 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
667 HistogramTimerScope timer(isolate()->counters()->parse_lazy());
668 Handle<String> source(String::cast(script_->source()));
669 isolate()->counters()->total_parse_size()->Increment(source->length());
671 Handle<SharedFunctionInfo> shared_info = info->shared_info();
672 // Initialize parser state.
673 source->TryFlatten();
674 if (source->IsExternalTwoByteString()) {
675 ExternalTwoByteStringUtf16CharacterStream stream(
676 Handle<ExternalTwoByteString>::cast(source),
677 shared_info->start_position(),
678 shared_info->end_position());
679 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope);
682 GenericStringUtf16CharacterStream stream(source,
683 shared_info->start_position(),
684 shared_info->end_position());
685 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope);
691 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
692 Utf16CharacterStream* source,
693 ZoneScope* zone_scope) {
694 Handle<SharedFunctionInfo> shared_info = info->shared_info();
695 scanner_.Initialize(source);
696 ASSERT(top_scope_ == NULL);
697 ASSERT(target_stack_ == NULL);
699 Handle<String> name(String::cast(shared_info->name()));
700 fni_ = new(zone()) FuncNameInferrer(isolate());
701 fni_->PushEnclosingName(name);
703 mode_ = PARSE_EAGERLY;
705 // Place holder for the result.
706 FunctionLiteral* result = NULL;
709 // Parse the function literal.
710 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE);
711 info->SetGlobalScope(scope);
712 if (!info->closure().is_null()) {
713 scope = Scope::DeserializeScopeChain(info->closure()->context(), scope);
715 FunctionState function_state(this, scope, isolate());
716 ASSERT(scope->language_mode() != STRICT_MODE || !info->is_classic_mode());
717 ASSERT(scope->language_mode() != EXTENDED_MODE ||
718 info->is_extended_mode());
719 ASSERT(info->language_mode() == shared_info->language_mode());
720 scope->SetLanguageMode(shared_info->language_mode());
721 if (shared_info->qml_mode()) {
722 top_scope_->EnableQmlModeFlag();
724 FunctionLiteral::Type type = shared_info->is_expression()
725 ? (shared_info->is_anonymous()
726 ? FunctionLiteral::ANONYMOUS_EXPRESSION
727 : FunctionLiteral::NAMED_EXPRESSION)
728 : FunctionLiteral::DECLARATION;
730 result = ParseFunctionLiteral(name,
731 false, // Strict mode name already checked.
732 RelocInfo::kNoPosition,
735 // Make sure the results agree.
736 ASSERT(ok == (result != NULL));
739 // Make sure the target stack is empty.
740 ASSERT(target_stack_ == NULL);
742 // If there was a stack overflow we have to get rid of AST and it is
743 // not safe to do before scope has been deleted.
744 if (result == NULL) {
745 zone_scope->DeleteOnExit();
746 if (stack_overflow_) isolate()->StackOverflow();
748 Handle<String> inferred_name(shared_info->inferred_name());
749 result->set_inferred_name(inferred_name);
755 Handle<String> Parser::GetSymbol(bool* ok) {
757 if (pre_data() != NULL) {
758 symbol_id = pre_data()->GetSymbolIdentifier();
760 return LookupSymbol(symbol_id);
764 void Parser::ReportMessage(const char* type, Vector<const char*> args) {
765 Scanner::Location source_location = scanner().location();
766 ReportMessageAt(source_location, type, args);
770 void Parser::ReportMessage(const char* type, Vector<Handle<String> > args) {
771 Scanner::Location source_location = scanner().location();
772 ReportMessageAt(source_location, type, args);
776 void Parser::ReportMessageAt(Scanner::Location source_location,
778 Vector<const char*> args) {
779 MessageLocation location(script_,
780 source_location.beg_pos,
781 source_location.end_pos);
782 Factory* factory = isolate()->factory();
783 Handle<FixedArray> elements = factory->NewFixedArray(args.length());
784 for (int i = 0; i < args.length(); i++) {
785 Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i]));
786 elements->set(i, *arg_string);
788 Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
789 Handle<Object> result = factory->NewSyntaxError(type, array);
790 isolate()->Throw(*result, &location);
794 void Parser::ReportMessageAt(Scanner::Location source_location,
796 Vector<Handle<String> > args) {
797 MessageLocation location(script_,
798 source_location.beg_pos,
799 source_location.end_pos);
800 Factory* factory = isolate()->factory();
801 Handle<FixedArray> elements = factory->NewFixedArray(args.length());
802 for (int i = 0; i < args.length(); i++) {
803 elements->set(i, *args[i]);
805 Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
806 Handle<Object> result = factory->NewSyntaxError(type, array);
807 isolate()->Throw(*result, &location);
811 // Base class containing common code for the different finder classes used by
816 static Assignment* AsAssignment(Statement* stat) {
817 if (stat == NULL) return NULL;
818 ExpressionStatement* exp_stat = stat->AsExpressionStatement();
819 if (exp_stat == NULL) return NULL;
820 return exp_stat->expression()->AsAssignment();
825 // An InitializationBlockFinder finds and marks sequences of statements of the
826 // form expr.a = ...; expr.b = ...; etc.
827 class InitializationBlockFinder : public ParserFinder {
829 // We find and mark the initialization blocks in top level
830 // non-looping code only. This is because the optimization prevents
831 // reuse of the map transitions, so it should be used only for code
832 // that will only be run once.
833 InitializationBlockFinder(Scope* top_scope, Target* target)
834 : enabled_(top_scope->DeclarationScope()->is_global_scope() &&
835 !IsLoopTarget(target)),
836 first_in_block_(NULL),
837 last_in_block_(NULL),
840 ~InitializationBlockFinder() {
841 if (!enabled_) return;
842 if (InBlock()) EndBlock();
845 void Update(Statement* stat) {
846 if (!enabled_) return;
847 Assignment* assignment = AsAssignment(stat);
849 if (BlockContinues(assignment)) {
850 UpdateBlock(assignment);
855 if (!InBlock() && (assignment != NULL) &&
856 (assignment->op() == Token::ASSIGN)) {
857 StartBlock(assignment);
862 // The minimum number of contiguous assignment that will
863 // be treated as an initialization block. Benchmarks show that
864 // the overhead exceeds the savings below this limit.
865 static const int kMinInitializationBlock = 3;
867 static bool IsLoopTarget(Target* target) {
868 while (target != NULL) {
869 if (target->node()->AsIterationStatement() != NULL) return true;
870 target = target->previous();
875 // Returns true if the expressions appear to denote the same object.
876 // In the context of initialization blocks, we only consider expressions
877 // of the form 'expr.x' or expr["x"].
878 static bool SameObject(Expression* e1, Expression* e2) {
879 VariableProxy* v1 = e1->AsVariableProxy();
880 VariableProxy* v2 = e2->AsVariableProxy();
881 if (v1 != NULL && v2 != NULL) {
882 return v1->name()->Equals(*v2->name());
884 Property* p1 = e1->AsProperty();
885 Property* p2 = e2->AsProperty();
886 if ((p1 == NULL) || (p2 == NULL)) return false;
887 Literal* key1 = p1->key()->AsLiteral();
888 Literal* key2 = p2->key()->AsLiteral();
889 if ((key1 == NULL) || (key2 == NULL)) return false;
890 if (!key1->handle()->IsString() || !key2->handle()->IsString()) {
893 String* name1 = String::cast(*key1->handle());
894 String* name2 = String::cast(*key2->handle());
895 if (!name1->Equals(name2)) return false;
896 return SameObject(p1->obj(), p2->obj());
899 // Returns true if the expressions appear to denote different properties
900 // of the same object.
901 static bool PropertyOfSameObject(Expression* e1, Expression* e2) {
902 Property* p1 = e1->AsProperty();
903 Property* p2 = e2->AsProperty();
904 if ((p1 == NULL) || (p2 == NULL)) return false;
905 return SameObject(p1->obj(), p2->obj());
908 bool BlockContinues(Assignment* assignment) {
909 if ((assignment == NULL) || (first_in_block_ == NULL)) return false;
910 if (assignment->op() != Token::ASSIGN) return false;
911 return PropertyOfSameObject(first_in_block_->target(),
912 assignment->target());
915 void StartBlock(Assignment* assignment) {
916 first_in_block_ = assignment;
917 last_in_block_ = assignment;
921 void UpdateBlock(Assignment* assignment) {
922 last_in_block_ = assignment;
927 if (block_size_ >= kMinInitializationBlock) {
928 first_in_block_->mark_block_start();
929 last_in_block_->mark_block_end();
931 last_in_block_ = first_in_block_ = NULL;
935 bool InBlock() { return first_in_block_ != NULL; }
938 Assignment* first_in_block_;
939 Assignment* last_in_block_;
942 DISALLOW_COPY_AND_ASSIGN(InitializationBlockFinder);
946 // A ThisNamedPropertyAssignmentFinder finds and marks statements of the form
947 // this.x = ...;, where x is a named property. It also determines whether a
948 // function contains only assignments of this type.
949 class ThisNamedPropertyAssignmentFinder : public ParserFinder {
951 explicit ThisNamedPropertyAssignmentFinder(Isolate* isolate)
953 only_simple_this_property_assignments_(true),
955 assigned_arguments_(0),
956 assigned_constants_(0) {
959 void Update(Scope* scope, Statement* stat) {
960 // Bail out if function already has property assignment that are
961 // not simple this property assignments.
962 if (!only_simple_this_property_assignments_) {
966 // Check whether this statement is of the form this.x = ...;
967 Assignment* assignment = AsAssignment(stat);
968 if (IsThisPropertyAssignment(assignment)) {
969 HandleThisPropertyAssignment(scope, assignment);
971 only_simple_this_property_assignments_ = false;
975 // Returns whether only statements of the form this.x = y; where y is either a
976 // constant or a function argument was encountered.
977 bool only_simple_this_property_assignments() {
978 return only_simple_this_property_assignments_;
981 // Returns a fixed array containing three elements for each assignment of the
983 Handle<FixedArray> GetThisPropertyAssignments() {
984 if (names_.is_empty()) {
985 return isolate_->factory()->empty_fixed_array();
987 ASSERT_EQ(names_.length(), assigned_arguments_.length());
988 ASSERT_EQ(names_.length(), assigned_constants_.length());
989 Handle<FixedArray> assignments =
990 isolate_->factory()->NewFixedArray(names_.length() * 3);
991 for (int i = 0; i < names_.length(); ++i) {
992 assignments->set(i * 3, *names_[i]);
993 assignments->set(i * 3 + 1, Smi::FromInt(assigned_arguments_[i]));
994 assignments->set(i * 3 + 2, *assigned_constants_[i]);
1000 bool IsThisPropertyAssignment(Assignment* assignment) {
1001 if (assignment != NULL) {
1002 Property* property = assignment->target()->AsProperty();
1003 return assignment->op() == Token::ASSIGN
1005 && property->obj()->AsVariableProxy() != NULL
1006 && property->obj()->AsVariableProxy()->is_this();
1011 void HandleThisPropertyAssignment(Scope* scope, Assignment* assignment) {
1012 // Check that the property assigned to is a named property, which is not
1014 Property* property = assignment->target()->AsProperty();
1015 ASSERT(property != NULL);
1016 Literal* literal = property->key()->AsLiteral();
1018 if (literal != NULL &&
1019 literal->handle()->IsString() &&
1020 !String::cast(*(literal->handle()))->Equals(
1021 isolate_->heap()->Proto_symbol()) &&
1022 !String::cast(*(literal->handle()))->AsArrayIndex(&dummy)) {
1023 Handle<String> key = Handle<String>::cast(literal->handle());
1025 // Check whether the value assigned is either a constant or matches the
1026 // name of one of the arguments to the function.
1027 if (assignment->value()->AsLiteral() != NULL) {
1028 // Constant assigned.
1029 Literal* literal = assignment->value()->AsLiteral();
1030 AssignmentFromConstant(key, literal->handle());
1032 } else if (assignment->value()->AsVariableProxy() != NULL) {
1033 // Variable assigned.
1034 Handle<String> name =
1035 assignment->value()->AsVariableProxy()->name();
1036 // Check whether the variable assigned matches an argument name.
1037 for (int i = 0; i < scope->num_parameters(); i++) {
1038 if (*scope->parameter(i)->name() == *name) {
1039 // Assigned from function argument.
1040 AssignmentFromParameter(key, i);
1046 // It is not a simple "this.x = value;" assignment with a constant
1047 // or parameter value.
1048 AssignmentFromSomethingElse();
1054 // We will potentially reorder the property assignments, so they must be
1055 // simple enough that the ordering does not matter.
1056 void AssignmentFromParameter(Handle<String> name, int index) {
1057 EnsureInitialized();
1058 for (int i = 0; i < names_.length(); ++i) {
1059 if (name->Equals(*names_[i])) {
1060 assigned_arguments_[i] = index;
1061 assigned_constants_[i] = isolate_->factory()->undefined_value();
1066 assigned_arguments_.Add(index);
1067 assigned_constants_.Add(isolate_->factory()->undefined_value());
1070 void AssignmentFromConstant(Handle<String> name, Handle<Object> value) {
1071 EnsureInitialized();
1072 for (int i = 0; i < names_.length(); ++i) {
1073 if (name->Equals(*names_[i])) {
1074 assigned_arguments_[i] = -1;
1075 assigned_constants_[i] = value;
1080 assigned_arguments_.Add(-1);
1081 assigned_constants_.Add(value);
1084 void AssignmentFromSomethingElse() {
1085 // The this assignment is not a simple one.
1086 only_simple_this_property_assignments_ = false;
1089 void EnsureInitialized() {
1090 if (names_.capacity() == 0) {
1091 ASSERT(assigned_arguments_.capacity() == 0);
1092 ASSERT(assigned_constants_.capacity() == 0);
1093 names_.Initialize(4);
1094 assigned_arguments_.Initialize(4);
1095 assigned_constants_.Initialize(4);
1100 bool only_simple_this_property_assignments_;
1101 ZoneStringList names_;
1102 ZoneList<int> assigned_arguments_;
1103 ZoneObjectList assigned_constants_;
1107 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
1111 // SourceElements ::
1112 // (ModuleElement)* <end_token>
1114 // Allocate a target stack to use for this set of source
1115 // elements. This way, all scripts and functions get their own
1116 // target stack thus avoiding illegal breaks and continues across
1118 TargetScope scope(&this->target_stack_);
1120 ASSERT(processor != NULL);
1121 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1122 ThisNamedPropertyAssignmentFinder this_property_assignment_finder(isolate());
1123 bool directive_prologue = true; // Parsing directive prologue.
1125 while (peek() != end_token) {
1126 if (directive_prologue && peek() != Token::STRING) {
1127 directive_prologue = false;
1130 Scanner::Location token_loc = scanner().peek_location();
1131 Statement* stat = ParseModuleElement(NULL, CHECK_OK);
1132 if (stat == NULL || stat->IsEmpty()) {
1133 directive_prologue = false; // End of directive prologue.
1137 if (directive_prologue) {
1138 // A shot at a directive.
1139 ExpressionStatement* e_stat;
1141 // Still processing directive prologue?
1142 if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1143 (literal = e_stat->expression()->AsLiteral()) != NULL &&
1144 literal->handle()->IsString()) {
1145 Handle<String> directive = Handle<String>::cast(literal->handle());
1147 // Check "use strict" directive (ES5 14.1).
1148 if (top_scope_->is_classic_mode() &&
1149 directive->Equals(isolate()->heap()->use_strict()) &&
1150 token_loc.end_pos - token_loc.beg_pos ==
1151 isolate()->heap()->use_strict()->length() + 2) {
1152 // TODO(mstarzinger): Global strict eval calls, need their own scope
1153 // as specified in ES5 10.4.2(3). The correct fix would be to always
1154 // add this scope in DoParseProgram(), but that requires adaptations
1155 // all over the code base, so we go with a quick-fix for now.
1156 if (is_eval && !top_scope_->is_eval_scope()) {
1157 ASSERT(top_scope_->is_global_scope());
1158 Scope* scope = NewScope(top_scope_, EVAL_SCOPE);
1159 scope->set_start_position(top_scope_->start_position());
1160 scope->set_end_position(top_scope_->end_position());
1163 // TODO(ES6): Fix entering extended mode, once it is specified.
1164 top_scope_->SetLanguageMode(FLAG_harmony_scoping
1165 ? EXTENDED_MODE : STRICT_MODE);
1166 // "use strict" is the only directive for now.
1167 directive_prologue = false;
1170 // End of the directive prologue.
1171 directive_prologue = false;
1175 block_finder.Update(stat);
1176 // Find and mark all assignments to named properties in this (this.x =)
1177 if (top_scope_->is_function_scope()) {
1178 this_property_assignment_finder.Update(top_scope_, stat);
1180 processor->Add(stat);
1183 // Propagate the collected information on this property assignments.
1184 if (top_scope_->is_function_scope()) {
1185 bool only_simple_this_property_assignments =
1186 this_property_assignment_finder.only_simple_this_property_assignments()
1187 && top_scope_->declarations()->length() == 0;
1188 if (only_simple_this_property_assignments) {
1189 current_function_state_->SetThisPropertyAssignmentInfo(
1190 only_simple_this_property_assignments,
1191 this_property_assignment_finder.GetThisPropertyAssignments());
1199 Statement* Parser::ParseModuleElement(ZoneStringList* labels,
1201 // (Ecma 262 5th Edition, clause 14):
1204 // FunctionDeclaration
1206 // In harmony mode we allow additionally the following productions
1210 // ModuleDeclaration
1211 // ImportDeclaration
1212 // ExportDeclaration
1215 case Token::FUNCTION:
1216 return ParseFunctionDeclaration(NULL, ok);
1219 return ParseVariableStatement(kModuleElement, NULL, ok);
1221 return ParseImportDeclaration(ok);
1223 return ParseExportDeclaration(ok);
1225 Statement* stmt = ParseStatement(labels, CHECK_OK);
1226 // Handle 'module' as a context-sensitive keyword.
1227 if (FLAG_harmony_modules &&
1228 peek() == Token::IDENTIFIER &&
1229 !scanner().HasAnyLineTerminatorBeforeNext() &&
1231 ExpressionStatement* estmt = stmt->AsExpressionStatement();
1232 if (estmt != NULL &&
1233 estmt->expression()->AsVariableProxy() != NULL &&
1234 estmt->expression()->AsVariableProxy()->name()->Equals(
1235 isolate()->heap()->module_symbol()) &&
1236 !scanner().literal_contains_escapes()) {
1237 return ParseModuleDeclaration(NULL, ok);
1246 Block* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) {
1247 // ModuleDeclaration:
1248 // 'module' Identifier Module
1250 // Create new block with one expected declaration.
1251 Block* block = factory()->NewBlock(NULL, 1, true);
1252 Handle<String> name = ParseIdentifier(CHECK_OK);
1255 if (FLAG_print_interface_details)
1256 PrintF("# Module %s...\n", name->ToAsciiArray());
1259 Module* module = ParseModule(CHECK_OK);
1260 VariableProxy* proxy = NewUnresolved(name, LET, module->interface());
1261 Declaration* declaration =
1262 factory()->NewModuleDeclaration(proxy, module, top_scope_);
1263 Declare(declaration, true, CHECK_OK);
1266 if (FLAG_print_interface_details)
1267 PrintF("# Module %s.\n", name->ToAsciiArray());
1269 if (FLAG_print_interfaces) {
1270 PrintF("module %s : ", name->ToAsciiArray());
1271 module->interface()->Print();
1275 // TODO(rossberg): Add initialization statement to block.
1277 if (names) names->Add(name);
1282 Module* Parser::ParseModule(bool* ok) {
1284 // '{' ModuleElement '}'
1285 // '=' ModulePath ';'
1290 return ParseModuleLiteral(ok);
1292 case Token::ASSIGN: {
1293 Expect(Token::ASSIGN, CHECK_OK);
1294 Module* result = ParseModulePath(CHECK_OK);
1295 ExpectSemicolon(CHECK_OK);
1300 ExpectContextualKeyword("at", CHECK_OK);
1301 Module* result = ParseModuleUrl(CHECK_OK);
1302 ExpectSemicolon(CHECK_OK);
1309 Module* Parser::ParseModuleLiteral(bool* ok) {
1311 // '{' ModuleElement '}'
1313 // Construct block expecting 16 statements.
1314 Block* body = factory()->NewBlock(NULL, 16, false);
1316 if (FLAG_print_interface_details) PrintF("# Literal ");
1318 Scope* scope = NewScope(top_scope_, MODULE_SCOPE);
1320 Expect(Token::LBRACE, CHECK_OK);
1321 scope->set_start_position(scanner().location().beg_pos);
1322 scope->SetLanguageMode(EXTENDED_MODE);
1325 BlockState block_state(this, scope);
1326 TargetCollector collector;
1327 Target target(&this->target_stack_, &collector);
1328 Target target_body(&this->target_stack_, body);
1329 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1331 while (peek() != Token::RBRACE) {
1332 Statement* stat = ParseModuleElement(NULL, CHECK_OK);
1333 if (stat && !stat->IsEmpty()) {
1334 body->AddStatement(stat);
1335 block_finder.Update(stat);
1340 Expect(Token::RBRACE, CHECK_OK);
1341 scope->set_end_position(scanner().location().end_pos);
1342 body->set_block_scope(scope);
1344 scope->interface()->Freeze(ok);
1346 return factory()->NewModuleLiteral(body, scope->interface());
1350 Module* Parser::ParseModulePath(bool* ok) {
1353 // ModulePath '.' Identifier
1355 Module* result = ParseModuleVariable(CHECK_OK);
1356 while (Check(Token::PERIOD)) {
1357 Handle<String> name = ParseIdentifierName(CHECK_OK);
1359 if (FLAG_print_interface_details)
1360 PrintF("# Path .%s ", name->ToAsciiArray());
1362 Module* member = factory()->NewModulePath(result, name);
1363 result->interface()->Add(name, member->interface(), ok);
1366 if (FLAG_print_interfaces) {
1367 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray());
1369 result->interface()->Print();
1371 member->interface()->Print();
1374 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1));
1384 Module* Parser::ParseModuleVariable(bool* ok) {
1388 Handle<String> name = ParseIdentifier(CHECK_OK);
1390 if (FLAG_print_interface_details)
1391 PrintF("# Module variable %s ", name->ToAsciiArray());
1393 VariableProxy* proxy = top_scope_->NewUnresolved(
1394 factory(), name, scanner().location().beg_pos, Interface::NewModule());
1396 return factory()->NewModuleVariable(proxy);
1400 Module* Parser::ParseModuleUrl(bool* ok) {
1404 Expect(Token::STRING, CHECK_OK);
1405 Handle<String> symbol = GetSymbol(CHECK_OK);
1407 // TODO(ES6): Request JS resource from environment...
1410 if (FLAG_print_interface_details) PrintF("# Url ");
1412 return factory()->NewModuleUrl(symbol);
1416 Module* Parser::ParseModuleSpecifier(bool* ok) {
1421 if (peek() == Token::STRING) {
1422 return ParseModuleUrl(ok);
1424 return ParseModulePath(ok);
1429 Block* Parser::ParseImportDeclaration(bool* ok) {
1430 // ImportDeclaration:
1431 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';'
1433 // TODO(ES6): implement destructuring ImportSpecifiers
1435 Expect(Token::IMPORT, CHECK_OK);
1436 ZoneStringList names(1);
1438 Handle<String> name = ParseIdentifierName(CHECK_OK);
1440 while (peek() == Token::COMMA) {
1441 Consume(Token::COMMA);
1442 name = ParseIdentifierName(CHECK_OK);
1446 ExpectContextualKeyword("from", CHECK_OK);
1447 Module* module = ParseModuleSpecifier(CHECK_OK);
1448 ExpectSemicolon(CHECK_OK);
1450 // Generate a separate declaration for each identifier.
1451 // TODO(ES6): once we implement destructuring, make that one declaration.
1452 Block* block = factory()->NewBlock(NULL, 1, true);
1453 for (int i = 0; i < names.length(); ++i) {
1455 if (FLAG_print_interface_details)
1456 PrintF("# Import %s ", names[i]->ToAsciiArray());
1458 Interface* interface = Interface::NewUnknown();
1459 module->interface()->Add(names[i], interface, ok);
1462 if (FLAG_print_interfaces) {
1463 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray());
1465 module->interface()->Print();
1468 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1));
1471 VariableProxy* proxy = NewUnresolved(names[i], LET, interface);
1472 Declaration* declaration =
1473 factory()->NewImportDeclaration(proxy, module, top_scope_);
1474 Declare(declaration, true, CHECK_OK);
1475 // TODO(rossberg): Add initialization statement to block.
1482 Statement* Parser::ParseExportDeclaration(bool* ok) {
1483 // ExportDeclaration:
1484 // 'export' Identifier (',' Identifier)* ';'
1485 // 'export' VariableDeclaration
1486 // 'export' FunctionDeclaration
1487 // 'export' ModuleDeclaration
1489 // TODO(ES6): implement structuring ExportSpecifiers
1491 Expect(Token::EXPORT, CHECK_OK);
1493 Statement* result = NULL;
1494 ZoneStringList names(1);
1496 case Token::IDENTIFIER: {
1497 Handle<String> name = ParseIdentifier(CHECK_OK);
1498 // Handle 'module' as a context-sensitive keyword.
1499 if (!name->IsEqualTo(CStrVector("module"))) {
1501 while (peek() == Token::COMMA) {
1502 Consume(Token::COMMA);
1503 name = ParseIdentifier(CHECK_OK);
1506 ExpectSemicolon(CHECK_OK);
1507 result = factory()->NewEmptyStatement();
1509 result = ParseModuleDeclaration(&names, CHECK_OK);
1514 case Token::FUNCTION:
1515 result = ParseFunctionDeclaration(&names, CHECK_OK);
1521 result = ParseVariableStatement(kModuleElement, &names, CHECK_OK);
1526 ReportUnexpectedToken(scanner().current_token());
1530 // Extract declared names into export declarations and interface.
1531 Interface* interface = top_scope_->interface();
1532 for (int i = 0; i < names.length(); ++i) {
1534 if (FLAG_print_interface_details)
1535 PrintF("# Export %s ", names[i]->ToAsciiArray());
1537 Interface* inner = Interface::NewUnknown();
1538 interface->Add(names[i], inner, CHECK_OK);
1539 VariableProxy* proxy = NewUnresolved(names[i], LET, inner);
1541 // TODO(rossberg): Rethink whether we actually need to store export
1542 // declarations (for compilation?).
1543 // ExportDeclaration* declaration =
1544 // factory()->NewExportDeclaration(proxy, top_scope_);
1545 // top_scope_->AddDeclaration(declaration);
1548 ASSERT(result != NULL);
1553 Statement* Parser::ParseBlockElement(ZoneStringList* labels,
1555 // (Ecma 262 5th Edition, clause 14):
1558 // FunctionDeclaration
1560 // In harmony mode we allow additionally the following productions
1561 // BlockElement (aka SourceElement):
1566 case Token::FUNCTION:
1567 return ParseFunctionDeclaration(NULL, ok);
1570 return ParseVariableStatement(kModuleElement, NULL, ok);
1572 return ParseStatement(labels, ok);
1577 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
1580 // VariableStatement
1582 // ExpressionStatement
1584 // IterationStatement
1585 // ContinueStatement
1589 // LabelledStatement
1593 // DebuggerStatement
1595 // Note: Since labels can only be used by 'break' and 'continue'
1596 // statements, which themselves are only valid within blocks,
1597 // iterations or 'switch' statements (i.e., BreakableStatements),
1598 // labels can be simply ignored in all other cases; except for
1599 // trivial labeled break statements 'label: break label' which is
1600 // parsed into an empty statement.
1602 // Keep the source position of the statement
1603 int statement_pos = scanner().peek_location().beg_pos;
1604 Statement* stmt = NULL;
1607 return ParseBlock(labels, ok);
1609 case Token::CONST: // fall through
1612 stmt = ParseVariableStatement(kStatement, NULL, ok);
1615 case Token::SEMICOLON:
1617 return factory()->NewEmptyStatement();
1620 stmt = ParseIfStatement(labels, ok);
1624 stmt = ParseDoWhileStatement(labels, ok);
1628 stmt = ParseWhileStatement(labels, ok);
1632 stmt = ParseForStatement(labels, ok);
1635 case Token::CONTINUE:
1636 stmt = ParseContinueStatement(ok);
1640 stmt = ParseBreakStatement(labels, ok);
1644 stmt = ParseReturnStatement(ok);
1648 stmt = ParseWithStatement(labels, ok);
1652 stmt = ParseSwitchStatement(labels, ok);
1656 stmt = ParseThrowStatement(ok);
1660 // NOTE: It is somewhat complicated to have labels on
1661 // try-statements. When breaking out of a try-finally statement,
1662 // one must take great care not to treat it as a
1663 // fall-through. It is much easier just to wrap the entire
1664 // try-statement in a statement block and put the labels there
1665 Block* result = factory()->NewBlock(labels, 1, false);
1666 Target target(&this->target_stack_, result);
1667 TryStatement* statement = ParseTryStatement(CHECK_OK);
1669 statement->set_statement_pos(statement_pos);
1671 if (result) result->AddStatement(statement);
1675 case Token::FUNCTION: {
1676 // FunctionDeclaration is only allowed in the context of SourceElements
1677 // (Ecma 262 5th Edition, clause 14):
1680 // FunctionDeclaration
1681 // Common language extension is to allow function declaration in place
1682 // of any statement. This language extension is disabled in strict mode.
1683 if (!top_scope_->is_classic_mode()) {
1684 ReportMessageAt(scanner().peek_location(), "strict_function",
1685 Vector<const char*>::empty());
1689 return ParseFunctionDeclaration(NULL, ok);
1692 case Token::DEBUGGER:
1693 stmt = ParseDebuggerStatement(ok);
1697 stmt = ParseExpressionOrLabelledStatement(labels, ok);
1700 // Store the source position of the statement
1701 if (stmt != NULL) stmt->set_statement_pos(statement_pos);
1706 VariableProxy* Parser::NewUnresolved(
1707 Handle<String> name, VariableMode mode, Interface* interface) {
1708 // If we are inside a function, a declaration of a var/const variable is a
1709 // truly local variable, and the scope of the variable is always the function
1711 // Let/const variables in harmony mode are always added to the immediately
1713 return DeclarationScope(mode)->NewUnresolved(
1714 factory(), name, scanner().location().beg_pos, interface);
1718 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
1719 VariableProxy* proxy = declaration->proxy();
1720 Handle<String> name = proxy->name();
1721 VariableMode mode = declaration->mode();
1722 Scope* declaration_scope = DeclarationScope(mode);
1723 Variable* var = NULL;
1725 // If a function scope exists, then we can statically declare this
1726 // variable and also set its mode. In any case, a Declaration node
1727 // will be added to the scope so that the declaration can be added
1728 // to the corresponding activation frame at runtime if necessary.
1729 // For instance declarations inside an eval scope need to be added
1730 // to the calling function context.
1731 // Similarly, strict mode eval scope does not leak variable declarations to
1732 // the caller's scope so we declare all locals, too.
1733 // Also for block scoped let/const bindings the variable can be
1734 // statically declared.
1735 if (declaration_scope->is_function_scope() ||
1736 declaration_scope->is_strict_or_extended_eval_scope() ||
1737 declaration_scope->is_block_scope() ||
1738 declaration_scope->is_module_scope() ||
1739 declaration->AsModuleDeclaration() != NULL) {
1740 // Declare the variable in the function scope.
1741 var = declaration_scope->LocalLookup(name);
1743 // Declare the name.
1744 var = declaration_scope->DeclareLocal(
1745 name, mode, declaration->initialization(), proxy->interface());
1747 // The name was declared in this scope before; check for conflicting
1748 // re-declarations. We have a conflict if either of the declarations is
1749 // not a var. There is similar code in runtime.cc in the Declare
1750 // functions. The function CheckNonConflictingScope checks for conflicting
1751 // var and let bindings from different scopes whereas this is a check for
1752 // conflicting declarations within the same scope. This check also covers
1754 // function () { let x; { var x; } }
1756 // because the var declaration is hoisted to the function scope where 'x'
1757 // is already bound.
1758 if ((mode != VAR) || (var->mode() != VAR)) {
1759 // We only have vars, consts and lets in declarations.
1760 ASSERT(var->mode() == VAR ||
1761 var->mode() == CONST ||
1762 var->mode() == CONST_HARMONY ||
1763 var->mode() == LET);
1764 if (is_extended_mode()) {
1765 // In harmony mode we treat re-declarations as early errors. See
1766 // ES5 16 for a definition of early errors.
1767 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
1768 const char* elms[2] = { "Variable", *c_string };
1769 Vector<const char*> args(elms, 2);
1770 ReportMessage("redeclaration", args);
1774 const char* type = (var->mode() == VAR)
1775 ? "var" : var->is_const_mode() ? "const" : "let";
1776 Handle<String> type_string =
1777 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED);
1778 Expression* expression =
1779 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(),
1781 declaration_scope->SetIllegalRedeclaration(expression);
1786 // We add a declaration node for every declaration. The compiler
1787 // will only generate code if necessary. In particular, declarations
1788 // for inner local variables that do not represent functions won't
1789 // result in any generated code.
1791 // Note that we always add an unresolved proxy even if it's not
1792 // used, simply because we don't know in this method (w/o extra
1793 // parameters) if the proxy is needed or not. The proxy will be
1794 // bound during variable resolution time unless it was pre-bound
1797 // WARNING: This will lead to multiple declaration nodes for the
1798 // same variable if it is declared several times. This is not a
1799 // semantic issue as long as we keep the source order, but it may be
1800 // a performance issue since it may lead to repeated
1801 // Runtime::DeclareContextSlot() calls.
1802 declaration_scope->AddDeclaration(declaration);
1804 if ((mode == CONST || mode == CONST_HARMONY) &&
1805 declaration_scope->is_global_scope()) {
1806 // For global const variables we bind the proxy to a variable.
1807 ASSERT(resolve); // should be set by all callers
1808 Variable::Kind kind = Variable::NORMAL;
1809 var = new(zone()) Variable(declaration_scope,
1814 kNeedsInitialization);
1815 } else if (declaration_scope->is_eval_scope() &&
1816 declaration_scope->is_classic_mode()) {
1817 // For variable declarations in a non-strict eval scope the proxy is bound
1818 // to a lookup variable to force a dynamic declaration using the
1819 // DeclareContextSlot runtime function.
1820 Variable::Kind kind = Variable::NORMAL;
1821 var = new(zone()) Variable(declaration_scope,
1826 declaration->initialization());
1827 var->AllocateTo(Variable::LOOKUP, -1);
1831 // If requested and we have a local variable, bind the proxy to the variable
1832 // at parse-time. This is used for functions (and consts) declared inside
1833 // statements: the corresponding function (or const) variable must be in the
1834 // function scope and not a statement-local scope, e.g. as provided with a
1835 // 'with' statement:
1841 // which is translated into:
1844 // // in this case this is not: 'var f; f = function () {};'
1845 // var f = function () {};
1848 // Note that if 'f' is accessed from inside the 'with' statement, it
1849 // will be allocated in the context (because we must be able to look
1850 // it up dynamically) but it will also be accessed statically, i.e.,
1851 // with a context slot index and a context chain length for this
1852 // initialization code. Thus, inside the 'with' statement, we need
1853 // both access to the static and the dynamic context chain; the
1854 // runtime needs to provide both.
1855 if (resolve && var != NULL) {
1858 if (FLAG_harmony_modules) {
1861 if (FLAG_print_interface_details)
1862 PrintF("# Declare %s\n", var->name()->ToAsciiArray());
1864 proxy->interface()->Unify(var->interface(), &ok);
1867 if (FLAG_print_interfaces) {
1868 PrintF("DECLARE TYPE ERROR\n");
1870 proxy->interface()->Print();
1872 var->interface()->Print();
1875 ReportMessage("module_type_error", Vector<Handle<String> >(&name, 1));
1882 // Language extension which is only enabled for source files loaded
1883 // through the API's extension mechanism. A native function
1884 // declaration is resolved by looking up the function through a
1885 // callback provided by the extension.
1886 Statement* Parser::ParseNativeDeclaration(bool* ok) {
1887 Expect(Token::FUNCTION, CHECK_OK);
1888 Handle<String> name = ParseIdentifier(CHECK_OK);
1889 Expect(Token::LPAREN, CHECK_OK);
1890 bool done = (peek() == Token::RPAREN);
1892 ParseIdentifier(CHECK_OK);
1893 done = (peek() == Token::RPAREN);
1895 Expect(Token::COMMA, CHECK_OK);
1898 Expect(Token::RPAREN, CHECK_OK);
1899 Expect(Token::SEMICOLON, CHECK_OK);
1901 // Make sure that the function containing the native declaration
1902 // isn't lazily compiled. The extension structures are only
1903 // accessible while parsing the first time not when reparsing
1904 // because of lazy compilation.
1905 DeclarationScope(VAR)->ForceEagerCompilation();
1907 // Compute the function template for the native function.
1908 v8::Handle<v8::FunctionTemplate> fun_template =
1909 extension_->GetNativeFunction(v8::Utils::ToLocal(name));
1910 ASSERT(!fun_template.IsEmpty());
1912 // Instantiate the function and create a shared function info from it.
1913 Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->GetFunction());
1914 const int literals = fun->NumberOfLiterals();
1915 Handle<Code> code = Handle<Code>(fun->shared()->code());
1916 Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
1917 Handle<SharedFunctionInfo> shared =
1918 isolate()->factory()->NewSharedFunctionInfo(name, literals, code,
1919 Handle<ScopeInfo>(fun->shared()->scope_info()));
1920 shared->set_construct_stub(*construct_stub);
1922 // Copy the function data to the shared function info.
1923 shared->set_function_data(fun->shared()->function_data());
1924 int parameters = fun->shared()->formal_parameter_count();
1925 shared->set_formal_parameter_count(parameters);
1927 // TODO(1240846): It's weird that native function declarations are
1928 // introduced dynamically when we meet their declarations, whereas
1929 // other functions are set up when entering the surrounding scope.
1930 VariableProxy* proxy = NewUnresolved(name, VAR);
1931 Declaration* declaration =
1932 factory()->NewVariableDeclaration(proxy, VAR, top_scope_);
1933 Declare(declaration, true, CHECK_OK);
1934 SharedFunctionInfoLiteral* lit =
1935 factory()->NewSharedFunctionInfoLiteral(shared);
1936 return factory()->NewExpressionStatement(
1937 factory()->NewAssignment(
1938 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition));
1942 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) {
1943 // FunctionDeclaration ::
1944 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
1945 Expect(Token::FUNCTION, CHECK_OK);
1946 int function_token_position = scanner().location().beg_pos;
1947 bool is_strict_reserved = false;
1948 Handle<String> name = ParseIdentifierOrStrictReservedWord(
1949 &is_strict_reserved, CHECK_OK);
1950 FunctionLiteral* fun = ParseFunctionLiteral(name,
1952 function_token_position,
1953 FunctionLiteral::DECLARATION,
1955 // Even if we're not at the top-level of the global or a function
1956 // scope, we treat is as such and introduce the function with it's
1957 // initial value upon entering the corresponding scope.
1958 VariableMode mode = is_extended_mode() ? LET : VAR;
1959 VariableProxy* proxy = NewUnresolved(name, mode);
1960 Declaration* declaration =
1961 factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_);
1962 Declare(declaration, true, CHECK_OK);
1963 if (names) names->Add(name);
1964 return factory()->NewEmptyStatement();
1968 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) {
1969 if (top_scope_->is_extended_mode()) return ParseScopedBlock(labels, ok);
1972 // '{' Statement* '}'
1974 // Note that a Block does not introduce a new execution scope!
1975 // (ECMA-262, 3rd, 12.2)
1977 // Construct block expecting 16 statements.
1978 Block* result = factory()->NewBlock(labels, 16, false);
1979 Target target(&this->target_stack_, result);
1980 Expect(Token::LBRACE, CHECK_OK);
1981 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1982 while (peek() != Token::RBRACE) {
1983 Statement* stat = ParseStatement(NULL, CHECK_OK);
1984 if (stat && !stat->IsEmpty()) {
1985 result->AddStatement(stat);
1986 block_finder.Update(stat);
1989 Expect(Token::RBRACE, CHECK_OK);
1994 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) {
1995 // The harmony mode uses block elements instead of statements.
1998 // '{' BlockElement* '}'
2000 // Construct block expecting 16 statements.
2001 Block* body = factory()->NewBlock(labels, 16, false);
2002 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE);
2004 // Parse the statements and collect escaping labels.
2005 Expect(Token::LBRACE, CHECK_OK);
2006 block_scope->set_start_position(scanner().location().beg_pos);
2007 { BlockState block_state(this, block_scope);
2008 TargetCollector collector;
2009 Target target(&this->target_stack_, &collector);
2010 Target target_body(&this->target_stack_, body);
2011 InitializationBlockFinder block_finder(top_scope_, target_stack_);
2013 while (peek() != Token::RBRACE) {
2014 Statement* stat = ParseBlockElement(NULL, CHECK_OK);
2015 if (stat && !stat->IsEmpty()) {
2016 body->AddStatement(stat);
2017 block_finder.Update(stat);
2021 Expect(Token::RBRACE, CHECK_OK);
2022 block_scope->set_end_position(scanner().location().end_pos);
2023 block_scope = block_scope->FinalizeBlockScope();
2024 body->set_block_scope(block_scope);
2029 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
2030 ZoneStringList* names,
2032 // VariableStatement ::
2033 // VariableDeclarations ';'
2035 Handle<String> ignore;
2037 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK);
2038 ExpectSemicolon(CHECK_OK);
2043 bool Parser::IsEvalOrArguments(Handle<String> string) {
2044 return string.is_identical_to(isolate()->factory()->eval_symbol()) ||
2045 string.is_identical_to(isolate()->factory()->arguments_symbol());
2049 // If the variable declaration declares exactly one non-const
2050 // variable, then *out is set to that variable. In all other cases,
2051 // *out is untouched; in particular, it is the caller's responsibility
2052 // to initialize it properly. This mechanism is used for the parsing
2053 // of 'for-in' loops.
2054 Block* Parser::ParseVariableDeclarations(
2055 VariableDeclarationContext var_context,
2056 VariableDeclarationProperties* decl_props,
2057 ZoneStringList* names,
2058 Handle<String>* out,
2060 // VariableDeclarations ::
2061 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
2063 // The ES6 Draft Rev3 specifies the following grammar for const declarations
2065 // ConstDeclaration ::
2066 // const ConstBinding (',' ConstBinding)* ';'
2068 // Identifier '=' AssignmentExpression
2072 // BindingPattern '=' AssignmentExpression
2073 VariableMode mode = VAR;
2074 // True if the binding needs initialization. 'let' and 'const' declared
2075 // bindings are created uninitialized by their declaration nodes and
2076 // need initialization. 'var' declared bindings are always initialized
2077 // immediately by their declaration nodes.
2078 bool needs_init = false;
2079 bool is_const = false;
2080 Token::Value init_op = Token::INIT_VAR;
2081 if (peek() == Token::VAR) {
2082 Consume(Token::VAR);
2083 } else if (peek() == Token::CONST) {
2084 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
2086 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
2088 // * It is a Syntax Error if the code that matches this production is not
2089 // contained in extended code.
2091 // However disallowing const in classic mode will break compatibility with
2092 // existing pages. Therefore we keep allowing const with the old
2093 // non-harmony semantics in classic mode.
2094 Consume(Token::CONST);
2095 switch (top_scope_->language_mode()) {
2098 init_op = Token::INIT_CONST;
2101 ReportMessage("strict_const", Vector<const char*>::empty());
2105 if (var_context == kStatement) {
2106 // In extended mode 'const' declarations are only allowed in source
2107 // element positions.
2108 ReportMessage("unprotected_const", Vector<const char*>::empty());
2112 mode = CONST_HARMONY;
2113 init_op = Token::INIT_CONST_HARMONY;
2117 } else if (peek() == Token::LET) {
2118 // ES6 Draft Rev4 section 12.2.1:
2120 // LetDeclaration : let LetBindingList ;
2122 // * It is a Syntax Error if the code that matches this production is not
2123 // contained in extended code.
2124 if (!is_extended_mode()) {
2125 ReportMessage("illegal_let", Vector<const char*>::empty());
2129 Consume(Token::LET);
2130 if (var_context == kStatement) {
2131 // Let declarations are only allowed in source element positions.
2132 ReportMessage("unprotected_let", Vector<const char*>::empty());
2138 init_op = Token::INIT_LET;
2140 UNREACHABLE(); // by current callers
2143 Scope* declaration_scope = DeclarationScope(mode);
2145 // The scope of a var/const declared variable anywhere inside a function
2146 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
2147 // transform a source-level var/const declaration into a (Function)
2148 // Scope declaration, and rewrite the source-level initialization into an
2149 // assignment statement. We use a block to collect multiple assignments.
2151 // We mark the block as initializer block because we don't want the
2152 // rewriter to add a '.result' assignment to such a block (to get compliant
2153 // behavior for code such as print(eval('var x = 7')), and for cosmetic
2154 // reasons when pretty-printing. Also, unless an assignment (initialization)
2155 // is inside an initializer block, it is ignored.
2157 // Create new block with one expected declaration.
2158 Block* block = factory()->NewBlock(NULL, 1, true);
2159 int nvars = 0; // the number of variables declared
2160 Handle<String> name;
2162 if (fni_ != NULL) fni_->Enter();
2164 // Parse variable name.
2165 if (nvars > 0) Consume(Token::COMMA);
2166 name = ParseIdentifier(CHECK_OK);
2167 if (fni_ != NULL) fni_->PushVariableName(name);
2169 // Strict mode variables may not be named eval or arguments
2170 if (!declaration_scope->is_classic_mode() && IsEvalOrArguments(name)) {
2171 ReportMessage("strict_var_name", Vector<const char*>::empty());
2176 // Declare variable.
2177 // Note that we *always* must treat the initial value via a separate init
2178 // assignment for variables and constants because the value must be assigned
2179 // when the variable is encountered in the source. But the variable/constant
2180 // is declared (and set to 'undefined') upon entering the function within
2181 // which the variable or constant is declared. Only function variables have
2182 // an initial value in the declaration (because they are initialized upon
2183 // entering the function).
2185 // If we have a const declaration, in an inner scope, the proxy is always
2186 // bound to the declared variable (independent of possibly surrounding with
2188 // For let/const declarations in harmony mode, we can also immediately
2189 // pre-resolve the proxy because it resides in the same scope as the
2191 VariableProxy* proxy = NewUnresolved(name, mode);
2192 Declaration* declaration =
2193 factory()->NewVariableDeclaration(proxy, mode, top_scope_);
2194 Declare(declaration, mode != VAR, CHECK_OK);
2196 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
2197 ReportMessageAt(scanner().location(), "too_many_variables",
2198 Vector<const char*>::empty());
2202 if (names) names->Add(name);
2204 // Parse initialization expression if present and/or needed. A
2205 // declaration of the form:
2209 // is syntactic sugar for:
2213 // In particular, we need to re-lookup 'v' (in top_scope_, not
2214 // declaration_scope) as it may be a different 'v' than the 'v' in the
2215 // declaration (e.g., if we are inside a 'with' statement or 'catch'
2218 // However, note that const declarations are different! A const
2219 // declaration of the form:
2223 // is *not* syntactic sugar for:
2227 // The "variable" c initialized to x is the same as the declared
2228 // one - there is no re-lookup (see the last parameter of the
2229 // Declare() call above).
2231 Scope* initialization_scope = is_const ? declaration_scope : top_scope_;
2232 Expression* value = NULL;
2234 // Harmony consts have non-optional initializers.
2235 if (peek() == Token::ASSIGN || mode == CONST_HARMONY) {
2236 Expect(Token::ASSIGN, CHECK_OK);
2237 position = scanner().location().beg_pos;
2238 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
2239 // Don't infer if it is "a = function(){...}();"-like expression.
2241 value->AsCall() == NULL &&
2242 value->AsCallNew() == NULL) {
2245 fni_->RemoveLastFunction();
2247 if (decl_props != NULL) *decl_props = kHasInitializers;
2250 // Record the end position of the initializer.
2251 if (proxy->var() != NULL) {
2252 proxy->var()->set_initializer_position(scanner().location().end_pos);
2255 // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
2256 if (value == NULL && needs_init) {
2257 value = GetLiteralUndefined();
2260 // Global variable declarations must be compiled in a specific
2261 // way. When the script containing the global variable declaration
2262 // is entered, the global variable must be declared, so that if it
2263 // doesn't exist (not even in a prototype of the global object) it
2264 // gets created with an initial undefined value. This is handled
2265 // by the declarations part of the function representing the
2266 // top-level global code; see Runtime::DeclareGlobalVariable. If
2267 // it already exists (in the object or in a prototype), it is
2268 // *not* touched until the variable declaration statement is
2271 // Executing the variable declaration statement will always
2272 // guarantee to give the global object a "local" variable; a
2273 // variable defined in the global object and not in any
2274 // prototype. This way, global variable declarations can shadow
2275 // properties in the prototype chain, but only after the variable
2276 // declaration statement has been executed. This is important in
2277 // browsers where the global object (window) has lots of
2278 // properties defined in prototype objects.
2279 if (initialization_scope->is_global_scope()) {
2280 // Compute the arguments for the runtime call.
2281 ZoneList<Expression*>* arguments = new(zone()) ZoneList<Expression*>(3);
2282 // We have at least 1 parameter.
2283 arguments->Add(factory()->NewLiteral(name));
2284 CallRuntime* initialize;
2287 arguments->Add(value);
2288 value = NULL; // zap the value to avoid the unnecessary assignment
2291 if (top_scope_->is_qml_mode() && !Isolate::Current()->global()->HasProperty(*name))
2293 arguments->Add(factory()->NewNumberLiteral(qml_mode));
2295 // Construct the call to Runtime_InitializeConstGlobal
2296 // and add it to the initialization statement block.
2297 // Note that the function does different things depending on
2298 // the number of arguments (1 or 2).
2299 initialize = factory()->NewCallRuntime(
2300 isolate()->factory()->InitializeConstGlobal_symbol(),
2301 Runtime::FunctionForId(Runtime::kInitializeConstGlobal),
2305 // We may want to pass singleton to avoid Literal allocations.
2306 LanguageMode language_mode = initialization_scope->language_mode();
2307 arguments->Add(factory()->NewNumberLiteral(language_mode));
2310 if (top_scope_->is_qml_mode() && !Isolate::Current()->global()->HasProperty(*name))
2312 arguments->Add(factory()->NewNumberLiteral(qml_mode));
2314 // Be careful not to assign a value to the global variable if
2315 // we're in a with. The initialization value should not
2316 // necessarily be stored in the global object in that case,
2317 // which is why we need to generate a separate assignment node.
2318 if (value != NULL && !inside_with()) {
2319 arguments->Add(value);
2320 value = NULL; // zap the value to avoid the unnecessary assignment
2323 // Construct the call to Runtime_InitializeVarGlobal
2324 // and add it to the initialization statement block.
2325 // Note that the function does different things depending on
2326 // the number of arguments (2 or 3).
2327 initialize = factory()->NewCallRuntime(
2328 isolate()->factory()->InitializeVarGlobal_symbol(),
2329 Runtime::FunctionForId(Runtime::kInitializeVarGlobal),
2333 block->AddStatement(factory()->NewExpressionStatement(initialize));
2334 } else if (needs_init) {
2335 // Constant initializations always assign to the declared constant which
2336 // is always at the function scope level. This is only relevant for
2337 // dynamically looked-up variables and constants (the start context for
2338 // constant lookups is always the function context, while it is the top
2339 // context for var declared variables). Sigh...
2340 // For 'let' and 'const' declared variables in harmony mode the
2341 // initialization also always assigns to the declared variable.
2342 ASSERT(proxy != NULL);
2343 ASSERT(proxy->var() != NULL);
2344 ASSERT(value != NULL);
2345 Assignment* assignment =
2346 factory()->NewAssignment(init_op, proxy, value, position);
2347 block->AddStatement(factory()->NewExpressionStatement(assignment));
2351 // Add an assignment node to the initialization statement block if we still
2352 // have a pending initialization value.
2353 if (value != NULL) {
2354 ASSERT(mode == VAR);
2355 // 'var' initializations are simply assignments (with all the consequences
2356 // if they are inside a 'with' statement - they may change a 'with' object
2358 VariableProxy* proxy =
2359 initialization_scope->NewUnresolved(factory(), name);
2360 Assignment* assignment =
2361 factory()->NewAssignment(init_op, proxy, value, position);
2362 block->AddStatement(factory()->NewExpressionStatement(assignment));
2365 if (fni_ != NULL) fni_->Leave();
2366 } while (peek() == Token::COMMA);
2368 // If there was a single non-const declaration, return it in the output
2369 // parameter for possible use by for/in.
2370 if (nvars == 1 && !is_const) {
2378 static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) {
2379 ASSERT(!label.is_null());
2381 for (int i = labels->length(); i-- > 0; )
2382 if (labels->at(i).is_identical_to(label))
2389 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
2391 // ExpressionStatement | LabelledStatement ::
2393 // Identifier ':' Statement
2394 bool starts_with_idenfifier = peek_any_identifier();
2395 Expression* expr = ParseExpression(true, CHECK_OK);
2396 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
2397 expr->AsVariableProxy() != NULL &&
2398 !expr->AsVariableProxy()->is_this()) {
2399 // Expression is a single identifier, and not, e.g., a parenthesized
2401 VariableProxy* var = expr->AsVariableProxy();
2402 Handle<String> label = var->name();
2403 // TODO(1240780): We don't check for redeclaration of labels
2404 // during preparsing since keeping track of the set of active
2405 // labels requires nontrivial changes to the way scopes are
2406 // structured. However, these are probably changes we want to
2407 // make later anyway so we should go back and fix this then.
2408 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
2409 SmartArrayPointer<char> c_string = label->ToCString(DISALLOW_NULLS);
2410 const char* elms[2] = { "Label", *c_string };
2411 Vector<const char*> args(elms, 2);
2412 ReportMessage("redeclaration", args);
2416 if (labels == NULL) labels = new(zone()) ZoneStringList(4);
2418 // Remove the "ghost" variable that turned out to be a label
2419 // from the top scope. This way, we don't try to resolve it
2420 // during the scope processing.
2421 top_scope_->RemoveUnresolved(var);
2422 Expect(Token::COLON, CHECK_OK);
2423 return ParseStatement(labels, ok);
2426 // If we have an extension, we allow a native function declaration.
2427 // A native function declaration starts with "native function" with
2428 // no line-terminator between the two words.
2429 if (extension_ != NULL &&
2430 peek() == Token::FUNCTION &&
2431 !scanner().HasAnyLineTerminatorBeforeNext() &&
2433 expr->AsVariableProxy() != NULL &&
2434 expr->AsVariableProxy()->name()->Equals(
2435 isolate()->heap()->native_symbol()) &&
2436 !scanner().literal_contains_escapes()) {
2437 return ParseNativeDeclaration(ok);
2440 // Parsed expression statement, or the context-sensitive 'module' keyword.
2441 // Only expect semicolon in the former case.
2442 if (!FLAG_harmony_modules ||
2443 peek() != Token::IDENTIFIER ||
2444 scanner().HasAnyLineTerminatorBeforeNext() ||
2445 expr->AsVariableProxy() == NULL ||
2446 !expr->AsVariableProxy()->name()->Equals(
2447 isolate()->heap()->module_symbol()) ||
2448 scanner().literal_contains_escapes()) {
2449 ExpectSemicolon(CHECK_OK);
2451 return factory()->NewExpressionStatement(expr);
2455 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) {
2457 // 'if' '(' Expression ')' Statement ('else' Statement)?
2459 Expect(Token::IF, CHECK_OK);
2460 Expect(Token::LPAREN, CHECK_OK);
2461 Expression* condition = ParseExpression(true, CHECK_OK);
2462 Expect(Token::RPAREN, CHECK_OK);
2463 Statement* then_statement = ParseStatement(labels, CHECK_OK);
2464 Statement* else_statement = NULL;
2465 if (peek() == Token::ELSE) {
2467 else_statement = ParseStatement(labels, CHECK_OK);
2469 else_statement = factory()->NewEmptyStatement();
2471 return factory()->NewIfStatement(condition, then_statement, else_statement);
2475 Statement* Parser::ParseContinueStatement(bool* ok) {
2476 // ContinueStatement ::
2477 // 'continue' Identifier? ';'
2479 Expect(Token::CONTINUE, CHECK_OK);
2480 Handle<String> label = Handle<String>::null();
2481 Token::Value tok = peek();
2482 if (!scanner().HasAnyLineTerminatorBeforeNext() &&
2483 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2484 label = ParseIdentifier(CHECK_OK);
2486 IterationStatement* target = NULL;
2487 target = LookupContinueTarget(label, CHECK_OK);
2488 if (target == NULL) {
2489 // Illegal continue statement.
2490 const char* message = "illegal_continue";
2491 Vector<Handle<String> > args;
2492 if (!label.is_null()) {
2493 message = "unknown_label";
2494 args = Vector<Handle<String> >(&label, 1);
2496 ReportMessageAt(scanner().location(), message, args);
2500 ExpectSemicolon(CHECK_OK);
2501 return factory()->NewContinueStatement(target);
2505 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) {
2506 // BreakStatement ::
2507 // 'break' Identifier? ';'
2509 Expect(Token::BREAK, CHECK_OK);
2510 Handle<String> label;
2511 Token::Value tok = peek();
2512 if (!scanner().HasAnyLineTerminatorBeforeNext() &&
2513 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2514 label = ParseIdentifier(CHECK_OK);
2516 // Parse labeled break statements that target themselves into
2517 // empty statements, e.g. 'l1: l2: l3: break l2;'
2518 if (!label.is_null() && ContainsLabel(labels, label)) {
2519 ExpectSemicolon(CHECK_OK);
2520 return factory()->NewEmptyStatement();
2522 BreakableStatement* target = NULL;
2523 target = LookupBreakTarget(label, CHECK_OK);
2524 if (target == NULL) {
2525 // Illegal break statement.
2526 const char* message = "illegal_break";
2527 Vector<Handle<String> > args;
2528 if (!label.is_null()) {
2529 message = "unknown_label";
2530 args = Vector<Handle<String> >(&label, 1);
2532 ReportMessageAt(scanner().location(), message, args);
2536 ExpectSemicolon(CHECK_OK);
2537 return factory()->NewBreakStatement(target);
2541 Statement* Parser::ParseReturnStatement(bool* ok) {
2542 // ReturnStatement ::
2543 // 'return' Expression? ';'
2545 // Consume the return token. It is necessary to do the before
2546 // reporting any errors on it, because of the way errors are
2547 // reported (underlining).
2548 Expect(Token::RETURN, CHECK_OK);
2550 Token::Value tok = peek();
2552 if (scanner().HasAnyLineTerminatorBeforeNext() ||
2553 tok == Token::SEMICOLON ||
2554 tok == Token::RBRACE ||
2555 tok == Token::EOS) {
2556 ExpectSemicolon(CHECK_OK);
2557 result = factory()->NewReturnStatement(GetLiteralUndefined());
2559 Expression* expr = ParseExpression(true, CHECK_OK);
2560 ExpectSemicolon(CHECK_OK);
2561 result = factory()->NewReturnStatement(expr);
2564 // An ECMAScript program is considered syntactically incorrect if it
2565 // contains a return statement that is not within the body of a
2566 // function. See ECMA-262, section 12.9, page 67.
2568 // To be consistent with KJS we report the syntax error at runtime.
2569 Scope* declaration_scope = top_scope_->DeclarationScope();
2570 if (declaration_scope->is_global_scope() ||
2571 declaration_scope->is_eval_scope()) {
2572 Handle<String> type = isolate()->factory()->illegal_return_symbol();
2573 Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null());
2574 return factory()->NewExpressionStatement(throw_error);
2580 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) {
2582 // 'with' '(' Expression ')' Statement
2584 Expect(Token::WITH, CHECK_OK);
2586 if (!top_scope_->is_classic_mode()) {
2587 ReportMessage("strict_mode_with", Vector<const char*>::empty());
2592 Expect(Token::LPAREN, CHECK_OK);
2593 Expression* expr = ParseExpression(true, CHECK_OK);
2594 Expect(Token::RPAREN, CHECK_OK);
2596 top_scope_->DeclarationScope()->RecordWithStatement();
2597 Scope* with_scope = NewScope(top_scope_, WITH_SCOPE);
2599 { BlockState block_state(this, with_scope);
2600 with_scope->set_start_position(scanner().peek_location().beg_pos);
2601 stmt = ParseStatement(labels, CHECK_OK);
2602 with_scope->set_end_position(scanner().location().end_pos);
2604 return factory()->NewWithStatement(expr, stmt);
2608 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
2610 // 'case' Expression ':' Statement*
2611 // 'default' ':' Statement*
2613 Expression* label = NULL; // NULL expression indicates default case
2614 if (peek() == Token::CASE) {
2615 Expect(Token::CASE, CHECK_OK);
2616 label = ParseExpression(true, CHECK_OK);
2618 Expect(Token::DEFAULT, CHECK_OK);
2619 if (*default_seen_ptr) {
2620 ReportMessage("multiple_defaults_in_switch",
2621 Vector<const char*>::empty());
2625 *default_seen_ptr = true;
2627 Expect(Token::COLON, CHECK_OK);
2628 int pos = scanner().location().beg_pos;
2629 ZoneList<Statement*>* statements = new(zone()) ZoneList<Statement*>(5);
2630 while (peek() != Token::CASE &&
2631 peek() != Token::DEFAULT &&
2632 peek() != Token::RBRACE) {
2633 Statement* stat = ParseStatement(NULL, CHECK_OK);
2634 statements->Add(stat);
2637 return new(zone()) CaseClause(isolate(), label, statements, pos);
2641 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels,
2643 // SwitchStatement ::
2644 // 'switch' '(' Expression ')' '{' CaseClause* '}'
2646 SwitchStatement* statement = factory()->NewSwitchStatement(labels);
2647 Target target(&this->target_stack_, statement);
2649 Expect(Token::SWITCH, CHECK_OK);
2650 Expect(Token::LPAREN, CHECK_OK);
2651 Expression* tag = ParseExpression(true, CHECK_OK);
2652 Expect(Token::RPAREN, CHECK_OK);
2654 bool default_seen = false;
2655 ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4);
2656 Expect(Token::LBRACE, CHECK_OK);
2657 while (peek() != Token::RBRACE) {
2658 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
2661 Expect(Token::RBRACE, CHECK_OK);
2663 if (statement) statement->Initialize(tag, cases);
2668 Statement* Parser::ParseThrowStatement(bool* ok) {
2669 // ThrowStatement ::
2670 // 'throw' Expression ';'
2672 Expect(Token::THROW, CHECK_OK);
2673 int pos = scanner().location().beg_pos;
2674 if (scanner().HasAnyLineTerminatorBeforeNext()) {
2675 ReportMessage("newline_after_throw", Vector<const char*>::empty());
2679 Expression* exception = ParseExpression(true, CHECK_OK);
2680 ExpectSemicolon(CHECK_OK);
2682 return factory()->NewExpressionStatement(factory()->NewThrow(exception, pos));
2686 TryStatement* Parser::ParseTryStatement(bool* ok) {
2688 // 'try' Block Catch
2689 // 'try' Block Finally
2690 // 'try' Block Catch Finally
2693 // 'catch' '(' Identifier ')' Block
2698 Expect(Token::TRY, CHECK_OK);
2700 TargetCollector try_collector;
2703 { Target target(&this->target_stack_, &try_collector);
2704 try_block = ParseBlock(NULL, CHECK_OK);
2707 Token::Value tok = peek();
2708 if (tok != Token::CATCH && tok != Token::FINALLY) {
2709 ReportMessage("no_catch_or_finally", Vector<const char*>::empty());
2714 // If we can break out from the catch block and there is a finally block,
2715 // then we will need to collect escaping targets from the catch
2716 // block. Since we don't know yet if there will be a finally block, we
2717 // always collect the targets.
2718 TargetCollector catch_collector;
2719 Scope* catch_scope = NULL;
2720 Variable* catch_variable = NULL;
2721 Block* catch_block = NULL;
2722 Handle<String> name;
2723 if (tok == Token::CATCH) {
2724 Consume(Token::CATCH);
2726 Expect(Token::LPAREN, CHECK_OK);
2727 catch_scope = NewScope(top_scope_, CATCH_SCOPE);
2728 catch_scope->set_start_position(scanner().location().beg_pos);
2729 name = ParseIdentifier(CHECK_OK);
2731 if (!top_scope_->is_classic_mode() && IsEvalOrArguments(name)) {
2732 ReportMessage("strict_catch_variable", Vector<const char*>::empty());
2737 Expect(Token::RPAREN, CHECK_OK);
2739 if (peek() == Token::LBRACE) {
2740 Target target(&this->target_stack_, &catch_collector);
2741 VariableMode mode = is_extended_mode() ? LET : VAR;
2743 catch_scope->DeclareLocal(name, mode, kCreatedInitialized);
2745 BlockState block_state(this, catch_scope);
2746 catch_block = ParseBlock(NULL, CHECK_OK);
2748 Expect(Token::LBRACE, CHECK_OK);
2750 catch_scope->set_end_position(scanner().location().end_pos);
2754 Block* finally_block = NULL;
2755 if (tok == Token::FINALLY || catch_block == NULL) {
2756 Consume(Token::FINALLY);
2757 finally_block = ParseBlock(NULL, CHECK_OK);
2760 // Simplify the AST nodes by converting:
2761 // 'try B0 catch B1 finally B2'
2763 // 'try { try B0 catch B1 } finally B2'
2765 if (catch_block != NULL && finally_block != NULL) {
2766 // If we have both, create an inner try/catch.
2767 ASSERT(catch_scope != NULL && catch_variable != NULL);
2768 int index = current_function_state_->NextHandlerIndex();
2769 TryCatchStatement* statement = factory()->NewTryCatchStatement(
2770 index, try_block, catch_scope, catch_variable, catch_block);
2771 statement->set_escaping_targets(try_collector.targets());
2772 try_block = factory()->NewBlock(NULL, 1, false);
2773 try_block->AddStatement(statement);
2774 catch_block = NULL; // Clear to indicate it's been handled.
2777 TryStatement* result = NULL;
2778 if (catch_block != NULL) {
2779 ASSERT(finally_block == NULL);
2780 ASSERT(catch_scope != NULL && catch_variable != NULL);
2781 int index = current_function_state_->NextHandlerIndex();
2782 result = factory()->NewTryCatchStatement(
2783 index, try_block, catch_scope, catch_variable, catch_block);
2785 ASSERT(finally_block != NULL);
2786 int index = current_function_state_->NextHandlerIndex();
2787 result = factory()->NewTryFinallyStatement(index, try_block, finally_block);
2788 // Combine the jump targets of the try block and the possible catch block.
2789 try_collector.targets()->AddAll(*catch_collector.targets());
2792 result->set_escaping_targets(try_collector.targets());
2797 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels,
2800 // 'do' Statement 'while' '(' Expression ')' ';'
2802 DoWhileStatement* loop = factory()->NewDoWhileStatement(labels);
2803 Target target(&this->target_stack_, loop);
2805 Expect(Token::DO, CHECK_OK);
2806 Statement* body = ParseStatement(NULL, CHECK_OK);
2807 Expect(Token::WHILE, CHECK_OK);
2808 Expect(Token::LPAREN, CHECK_OK);
2811 int position = scanner().location().beg_pos;
2812 loop->set_condition_position(position);
2815 Expression* cond = ParseExpression(true, CHECK_OK);
2816 Expect(Token::RPAREN, CHECK_OK);
2818 // Allow do-statements to be terminated with and without
2819 // semi-colons. This allows code such as 'do;while(0)return' to
2820 // parse, which would not be the case if we had used the
2821 // ExpectSemicolon() functionality here.
2822 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
2824 if (loop != NULL) loop->Initialize(cond, body);
2829 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) {
2830 // WhileStatement ::
2831 // 'while' '(' Expression ')' Statement
2833 WhileStatement* loop = factory()->NewWhileStatement(labels);
2834 Target target(&this->target_stack_, loop);
2836 Expect(Token::WHILE, CHECK_OK);
2837 Expect(Token::LPAREN, CHECK_OK);
2838 Expression* cond = ParseExpression(true, CHECK_OK);
2839 Expect(Token::RPAREN, CHECK_OK);
2840 Statement* body = ParseStatement(NULL, CHECK_OK);
2842 if (loop != NULL) loop->Initialize(cond, body);
2847 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
2849 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
2851 Statement* init = NULL;
2853 // Create an in-between scope for let-bound iteration variables.
2854 Scope* saved_scope = top_scope_;
2855 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE);
2856 top_scope_ = for_scope;
2858 Expect(Token::FOR, CHECK_OK);
2859 Expect(Token::LPAREN, CHECK_OK);
2860 for_scope->set_start_position(scanner().location().beg_pos);
2861 if (peek() != Token::SEMICOLON) {
2862 if (peek() == Token::VAR || peek() == Token::CONST) {
2863 Handle<String> name;
2864 Block* variable_statement =
2865 ParseVariableDeclarations(kForStatement, NULL, NULL, &name, CHECK_OK);
2867 if (peek() == Token::IN && !name.is_null()) {
2868 VariableProxy* each = top_scope_->NewUnresolved(factory(), name);
2869 ForInStatement* loop = factory()->NewForInStatement(labels);
2870 Target target(&this->target_stack_, loop);
2872 Expect(Token::IN, CHECK_OK);
2873 Expression* enumerable = ParseExpression(true, CHECK_OK);
2874 Expect(Token::RPAREN, CHECK_OK);
2876 Statement* body = ParseStatement(NULL, CHECK_OK);
2877 loop->Initialize(each, enumerable, body);
2878 Block* result = factory()->NewBlock(NULL, 2, false);
2879 result->AddStatement(variable_statement);
2880 result->AddStatement(loop);
2881 top_scope_ = saved_scope;
2882 for_scope->set_end_position(scanner().location().end_pos);
2883 for_scope = for_scope->FinalizeBlockScope();
2884 ASSERT(for_scope == NULL);
2885 // Parsed for-in loop w/ variable/const declaration.
2888 init = variable_statement;
2890 } else if (peek() == Token::LET) {
2891 Handle<String> name;
2892 VariableDeclarationProperties decl_props = kHasNoInitializers;
2893 Block* variable_statement =
2894 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
2896 bool accept_IN = !name.is_null() && decl_props != kHasInitializers;
2897 if (peek() == Token::IN && accept_IN) {
2898 // Rewrite a for-in statement of the form
2900 // for (let x in e) b
2904 // <let x' be a temporary variable>
2911 // TODO(keuchel): Move the temporary variable to the block scope, after
2912 // implementing stack allocated block scoped variables.
2913 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(name);
2914 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
2915 VariableProxy* each = top_scope_->NewUnresolved(factory(), name);
2916 ForInStatement* loop = factory()->NewForInStatement(labels);
2917 Target target(&this->target_stack_, loop);
2919 Expect(Token::IN, CHECK_OK);
2920 Expression* enumerable = ParseExpression(true, CHECK_OK);
2921 Expect(Token::RPAREN, CHECK_OK);
2923 Statement* body = ParseStatement(NULL, CHECK_OK);
2924 Block* body_block = factory()->NewBlock(NULL, 3, false);
2925 Assignment* assignment = factory()->NewAssignment(
2926 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition);
2927 Statement* assignment_statement =
2928 factory()->NewExpressionStatement(assignment);
2929 body_block->AddStatement(variable_statement);
2930 body_block->AddStatement(assignment_statement);
2931 body_block->AddStatement(body);
2932 loop->Initialize(temp_proxy, enumerable, body_block);
2933 top_scope_ = saved_scope;
2934 for_scope->set_end_position(scanner().location().end_pos);
2935 for_scope = for_scope->FinalizeBlockScope();
2936 body_block->set_block_scope(for_scope);
2937 // Parsed for-in loop w/ let declaration.
2941 init = variable_statement;
2944 Expression* expression = ParseExpression(false, CHECK_OK);
2945 if (peek() == Token::IN) {
2946 // Signal a reference error if the expression is an invalid
2947 // left-hand side expression. We could report this as a syntax
2948 // error here but for compatibility with JSC we choose to report
2949 // the error at runtime.
2950 if (expression == NULL || !expression->IsValidLeftHandSide()) {
2951 Handle<String> type =
2952 isolate()->factory()->invalid_lhs_in_for_in_symbol();
2953 expression = NewThrowReferenceError(type);
2955 ForInStatement* loop = factory()->NewForInStatement(labels);
2956 Target target(&this->target_stack_, loop);
2958 Expect(Token::IN, CHECK_OK);
2959 Expression* enumerable = ParseExpression(true, CHECK_OK);
2960 Expect(Token::RPAREN, CHECK_OK);
2962 Statement* body = ParseStatement(NULL, CHECK_OK);
2963 if (loop) loop->Initialize(expression, enumerable, body);
2964 top_scope_ = saved_scope;
2965 for_scope->set_end_position(scanner().location().end_pos);
2966 for_scope = for_scope->FinalizeBlockScope();
2967 ASSERT(for_scope == NULL);
2968 // Parsed for-in loop.
2972 init = factory()->NewExpressionStatement(expression);
2977 // Standard 'for' loop
2978 ForStatement* loop = factory()->NewForStatement(labels);
2979 Target target(&this->target_stack_, loop);
2981 // Parsed initializer at this point.
2982 Expect(Token::SEMICOLON, CHECK_OK);
2984 Expression* cond = NULL;
2985 if (peek() != Token::SEMICOLON) {
2986 cond = ParseExpression(true, CHECK_OK);
2988 Expect(Token::SEMICOLON, CHECK_OK);
2990 Statement* next = NULL;
2991 if (peek() != Token::RPAREN) {
2992 Expression* exp = ParseExpression(true, CHECK_OK);
2993 next = factory()->NewExpressionStatement(exp);
2995 Expect(Token::RPAREN, CHECK_OK);
2997 Statement* body = ParseStatement(NULL, CHECK_OK);
2998 top_scope_ = saved_scope;
2999 for_scope->set_end_position(scanner().location().end_pos);
3000 for_scope = for_scope->FinalizeBlockScope();
3001 if (for_scope != NULL) {
3002 // Rewrite a for statement of the form
3004 // for (let x = i; c; n) b
3012 ASSERT(init != NULL);
3013 Block* result = factory()->NewBlock(NULL, 2, false);
3014 result->AddStatement(init);
3015 result->AddStatement(loop);
3016 result->set_block_scope(for_scope);
3017 if (loop) loop->Initialize(NULL, cond, next, body);
3020 if (loop) loop->Initialize(init, cond, next, body);
3027 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) {
3029 // AssignmentExpression
3030 // Expression ',' AssignmentExpression
3032 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK);
3033 while (peek() == Token::COMMA) {
3034 Expect(Token::COMMA, CHECK_OK);
3035 int position = scanner().location().beg_pos;
3036 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
3038 factory()->NewBinaryOperation(Token::COMMA, result, right, position);
3045 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
3046 // AssignmentExpression ::
3047 // ConditionalExpression
3048 // LeftHandSideExpression AssignmentOperator AssignmentExpression
3050 if (fni_ != NULL) fni_->Enter();
3051 Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK);
3053 if (!Token::IsAssignmentOp(peek())) {
3054 if (fni_ != NULL) fni_->Leave();
3055 // Parsed conditional expression only (no assignment).
3059 // Signal a reference error if the expression is an invalid left-hand
3060 // side expression. We could report this as a syntax error here but
3061 // for compatibility with JSC we choose to report the error at
3063 if (expression == NULL || !expression->IsValidLeftHandSide()) {
3064 Handle<String> type =
3065 isolate()->factory()->invalid_lhs_in_assignment_symbol();
3066 expression = NewThrowReferenceError(type);
3069 if (!top_scope_->is_classic_mode()) {
3070 // Assignment to eval or arguments is disallowed in strict mode.
3071 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK);
3073 MarkAsLValue(expression);
3075 Token::Value op = Next(); // Get assignment operator.
3076 int pos = scanner().location().beg_pos;
3077 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
3079 // TODO(1231235): We try to estimate the set of properties set by
3080 // constructors. We define a new property whenever there is an
3081 // assignment to a property of 'this'. We should probably only add
3082 // properties if we haven't seen them before. Otherwise we'll
3083 // probably overestimate the number of properties.
3084 Property* property = expression ? expression->AsProperty() : NULL;
3085 if (op == Token::ASSIGN &&
3087 property->obj()->AsVariableProxy() != NULL &&
3088 property->obj()->AsVariableProxy()->is_this()) {
3089 current_function_state_->AddProperty();
3092 // If we assign a function literal to a property we pretenure the
3093 // literal so it can be added as a constant function property.
3094 if (property != NULL && right->AsFunctionLiteral() != NULL) {
3095 right->AsFunctionLiteral()->set_pretenure();
3099 // Check if the right hand side is a call to avoid inferring a
3100 // name if we're dealing with "a = function(){...}();"-like
3102 if ((op == Token::INIT_VAR
3103 || op == Token::INIT_CONST
3104 || op == Token::ASSIGN)
3105 && (right->AsCall() == NULL && right->AsCallNew() == NULL)) {
3108 fni_->RemoveLastFunction();
3113 return factory()->NewAssignment(op, expression, right, pos);
3118 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) {
3119 // ConditionalExpression ::
3120 // LogicalOrExpression
3121 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
3123 // We start using the binary expression parser for prec >= 4 only!
3124 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
3125 if (peek() != Token::CONDITIONAL) return expression;
3126 Consume(Token::CONDITIONAL);
3127 // In parsing the first assignment expression in conditional
3128 // expressions we always accept the 'in' keyword; see ECMA-262,
3129 // section 11.12, page 58.
3130 int left_position = scanner().peek_location().beg_pos;
3131 Expression* left = ParseAssignmentExpression(true, CHECK_OK);
3132 Expect(Token::COLON, CHECK_OK);
3133 int right_position = scanner().peek_location().beg_pos;
3134 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
3135 return factory()->NewConditional(
3136 expression, left, right, left_position, right_position);
3140 static int Precedence(Token::Value tok, bool accept_IN) {
3141 if (tok == Token::IN && !accept_IN)
3142 return 0; // 0 precedence will terminate binary expression parsing
3144 return Token::Precedence(tok);
3149 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
3151 Expression* x = ParseUnaryExpression(CHECK_OK);
3152 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
3154 while (Precedence(peek(), accept_IN) == prec1) {
3155 Token::Value op = Next();
3156 int position = scanner().location().beg_pos;
3157 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
3159 // Compute some expressions involving only number literals.
3160 if (x && x->AsLiteral() && x->AsLiteral()->handle()->IsNumber() &&
3161 y && y->AsLiteral() && y->AsLiteral()->handle()->IsNumber()) {
3162 double x_val = x->AsLiteral()->handle()->Number();
3163 double y_val = y->AsLiteral()->handle()->Number();
3167 x = factory()->NewNumberLiteral(x_val + y_val);
3170 x = factory()->NewNumberLiteral(x_val - y_val);
3173 x = factory()->NewNumberLiteral(x_val * y_val);
3176 x = factory()->NewNumberLiteral(x_val / y_val);
3178 case Token::BIT_OR: {
3179 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
3180 x = factory()->NewNumberLiteral(value);
3183 case Token::BIT_AND: {
3184 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
3185 x = factory()->NewNumberLiteral(value);
3188 case Token::BIT_XOR: {
3189 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
3190 x = factory()->NewNumberLiteral(value);
3194 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
3195 x = factory()->NewNumberLiteral(value);
3199 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
3200 uint32_t value = DoubleToUint32(x_val) >> shift;
3201 x = factory()->NewNumberLiteral(value);
3205 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
3206 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
3207 x = factory()->NewNumberLiteral(value);
3215 // For now we distinguish between comparisons and other binary
3216 // operations. (We could combine the two and get rid of this
3217 // code and AST node eventually.)
3218 if (Token::IsCompareOp(op)) {
3219 // We have a comparison.
3220 Token::Value cmp = op;
3222 case Token::NE: cmp = Token::EQ; break;
3223 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
3226 x = factory()->NewCompareOperation(cmp, x, y, position);
3228 // The comparison was negated - add a NOT.
3229 x = factory()->NewUnaryOperation(Token::NOT, x, position);
3233 // We have a "normal" binary operation.
3234 x = factory()->NewBinaryOperation(op, x, y, position);
3242 Expression* Parser::ParseUnaryExpression(bool* ok) {
3243 // UnaryExpression ::
3244 // PostfixExpression
3245 // 'delete' UnaryExpression
3246 // 'void' UnaryExpression
3247 // 'typeof' UnaryExpression
3248 // '++' UnaryExpression
3249 // '--' UnaryExpression
3250 // '+' UnaryExpression
3251 // '-' UnaryExpression
3252 // '~' UnaryExpression
3253 // '!' UnaryExpression
3255 Token::Value op = peek();
3256 if (Token::IsUnaryOp(op)) {
3258 int position = scanner().location().beg_pos;
3259 Expression* expression = ParseUnaryExpression(CHECK_OK);
3261 if (expression != NULL && (expression->AsLiteral() != NULL)) {
3262 Handle<Object> literal = expression->AsLiteral()->handle();
3263 if (op == Token::NOT) {
3264 // Convert the literal to a boolean condition and negate it.
3265 bool condition = literal->ToBoolean()->IsTrue();
3266 Handle<Object> result(isolate()->heap()->ToBoolean(!condition));
3267 return factory()->NewLiteral(result);
3268 } else if (literal->IsNumber()) {
3269 // Compute some expressions involving only number literals.
3270 double value = literal->Number();
3275 return factory()->NewNumberLiteral(-value);
3276 case Token::BIT_NOT:
3277 return factory()->NewNumberLiteral(~DoubleToInt32(value));
3284 // "delete identifier" is a syntax error in strict mode.
3285 if (op == Token::DELETE && !top_scope_->is_classic_mode()) {
3286 VariableProxy* operand = expression->AsVariableProxy();
3287 if (operand != NULL && !operand->is_this()) {
3288 ReportMessage("strict_delete", Vector<const char*>::empty());
3294 return factory()->NewUnaryOperation(op, expression, position);
3296 } else if (Token::IsCountOp(op)) {
3298 Expression* expression = ParseUnaryExpression(CHECK_OK);
3299 // Signal a reference error if the expression is an invalid
3300 // left-hand side expression. We could report this as a syntax
3301 // error here but for compatibility with JSC we choose to report the
3302 // error at runtime.
3303 if (expression == NULL || !expression->IsValidLeftHandSide()) {
3304 Handle<String> type =
3305 isolate()->factory()->invalid_lhs_in_prefix_op_symbol();
3306 expression = NewThrowReferenceError(type);
3309 if (!top_scope_->is_classic_mode()) {
3310 // Prefix expression operand in strict mode may not be eval or arguments.
3311 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
3313 MarkAsLValue(expression);
3315 int position = scanner().location().beg_pos;
3316 return factory()->NewCountOperation(op,
3322 return ParsePostfixExpression(ok);
3327 Expression* Parser::ParsePostfixExpression(bool* ok) {
3328 // PostfixExpression ::
3329 // LeftHandSideExpression ('++' | '--')?
3331 Expression* expression = ParseLeftHandSideExpression(CHECK_OK);
3332 if (!scanner().HasAnyLineTerminatorBeforeNext() &&
3333 Token::IsCountOp(peek())) {
3334 // Signal a reference error if the expression is an invalid
3335 // left-hand side expression. We could report this as a syntax
3336 // error here but for compatibility with JSC we choose to report the
3337 // error at runtime.
3338 if (expression == NULL || !expression->IsValidLeftHandSide()) {
3339 Handle<String> type =
3340 isolate()->factory()->invalid_lhs_in_postfix_op_symbol();
3341 expression = NewThrowReferenceError(type);
3344 if (!top_scope_->is_classic_mode()) {
3345 // Postfix expression operand in strict mode may not be eval or arguments.
3346 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
3348 MarkAsLValue(expression);
3350 Token::Value next = Next();
3351 int position = scanner().location().beg_pos;
3353 factory()->NewCountOperation(next,
3354 false /* postfix */,
3362 Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
3363 // LeftHandSideExpression ::
3364 // (NewExpression | MemberExpression) ...
3367 if (peek() == Token::NEW) {
3368 result = ParseNewExpression(CHECK_OK);
3370 result = ParseMemberExpression(CHECK_OK);
3375 case Token::LBRACK: {
3376 Consume(Token::LBRACK);
3377 int pos = scanner().location().beg_pos;
3378 Expression* index = ParseExpression(true, CHECK_OK);
3379 result = factory()->NewProperty(result, index, pos);
3380 Expect(Token::RBRACK, CHECK_OK);
3384 case Token::LPAREN: {
3386 if (scanner().current_token() == Token::IDENTIFIER) {
3387 // For call of an identifier we want to report position of
3388 // the identifier as position of the call in the stack trace.
3389 pos = scanner().location().beg_pos;
3391 // For other kinds of calls we record position of the parenthesis as
3392 // position of the call. Note that this is extremely important for
3393 // expressions of the form function(){...}() for which call position
3394 // should not point to the closing brace otherwise it will intersect
3395 // with positions recorded for function literal and confuse debugger.
3396 pos = scanner().peek_location().beg_pos;
3398 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
3400 // Keep track of eval() calls since they disable all local variable
3402 // The calls that need special treatment are the
3403 // direct eval calls. These calls are all of the form eval(...), with
3404 // no explicit receiver.
3405 // These calls are marked as potentially direct eval calls. Whether
3406 // they are actually direct calls to eval is determined at run time.
3407 VariableProxy* callee = result->AsVariableProxy();
3408 if (callee != NULL &&
3409 callee->IsVariable(isolate()->factory()->eval_symbol())) {
3410 top_scope_->DeclarationScope()->RecordEvalCall();
3412 result = factory()->NewCall(result, args, pos);
3416 case Token::PERIOD: {
3417 Consume(Token::PERIOD);
3418 int pos = scanner().location().beg_pos;
3419 Handle<String> name = ParseIdentifierName(CHECK_OK);
3421 factory()->NewProperty(result, factory()->NewLiteral(name), pos);
3422 if (fni_ != NULL) fni_->PushLiteralName(name);
3433 Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) {
3435 // ('new')+ MemberExpression
3437 // The grammar for new expressions is pretty warped. The keyword
3438 // 'new' can either be a part of the new expression (where it isn't
3439 // followed by an argument list) or a part of the member expression,
3440 // where it must be followed by an argument list. To accommodate
3441 // this, we parse the 'new' keywords greedily and keep track of how
3442 // many we have parsed. This information is then passed on to the
3443 // member expression parser, which is only allowed to match argument
3444 // lists as long as it has 'new' prefixes left
3445 Expect(Token::NEW, CHECK_OK);
3446 PositionStack::Element pos(stack, scanner().location().beg_pos);
3449 if (peek() == Token::NEW) {
3450 result = ParseNewPrefix(stack, CHECK_OK);
3452 result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK);
3455 if (!stack->is_empty()) {
3456 int last = stack->pop();
3457 result = factory()->NewCallNew(
3458 result, new(zone()) ZoneList<Expression*>(0), last);
3464 Expression* Parser::ParseNewExpression(bool* ok) {
3465 PositionStack stack(ok);
3466 return ParseNewPrefix(&stack, ok);
3470 Expression* Parser::ParseMemberExpression(bool* ok) {
3471 return ParseMemberWithNewPrefixesExpression(NULL, ok);
3475 Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
3477 // MemberExpression ::
3478 // (PrimaryExpression | FunctionLiteral)
3479 // ('[' Expression ']' | '.' Identifier | Arguments)*
3481 // Parse the initial primary or function expression.
3482 Expression* result = NULL;
3483 if (peek() == Token::FUNCTION) {
3484 Expect(Token::FUNCTION, CHECK_OK);
3485 int function_token_position = scanner().location().beg_pos;
3486 Handle<String> name;
3487 bool is_strict_reserved_name = false;
3488 if (peek_any_identifier()) {
3489 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
3492 FunctionLiteral::Type type = name.is_null()
3493 ? FunctionLiteral::ANONYMOUS_EXPRESSION
3494 : FunctionLiteral::NAMED_EXPRESSION;
3495 result = ParseFunctionLiteral(name,
3496 is_strict_reserved_name,
3497 function_token_position,
3501 result = ParsePrimaryExpression(CHECK_OK);
3506 case Token::LBRACK: {
3507 Consume(Token::LBRACK);
3508 int pos = scanner().location().beg_pos;
3509 Expression* index = ParseExpression(true, CHECK_OK);
3510 result = factory()->NewProperty(result, index, pos);
3512 if (index->IsPropertyName()) {
3513 fni_->PushLiteralName(index->AsLiteral()->AsPropertyName());
3515 fni_->PushLiteralName(
3516 isolate()->factory()->anonymous_function_symbol());
3519 Expect(Token::RBRACK, CHECK_OK);
3522 case Token::PERIOD: {
3523 Consume(Token::PERIOD);
3524 int pos = scanner().location().beg_pos;
3525 Handle<String> name = ParseIdentifierName(CHECK_OK);
3527 factory()->NewProperty(result, factory()->NewLiteral(name), pos);
3528 if (fni_ != NULL) fni_->PushLiteralName(name);
3531 case Token::LPAREN: {
3532 if ((stack == NULL) || stack->is_empty()) return result;
3533 // Consume one of the new prefixes (already parsed).
3534 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
3535 int last = stack->pop();
3536 result = factory()->NewCallNew(result, args, last);
3546 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
3547 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
3548 // contexts this is used as a statement which invokes the debugger as i a
3549 // break point is present.
3550 // DebuggerStatement ::
3553 Expect(Token::DEBUGGER, CHECK_OK);
3554 ExpectSemicolon(CHECK_OK);
3555 return factory()->NewDebuggerStatement();
3559 void Parser::ReportUnexpectedToken(Token::Value token) {
3560 // We don't report stack overflows here, to avoid increasing the
3561 // stack depth even further. Instead we report it after parsing is
3562 // over, in ParseProgram/ParseJson.
3563 if (token == Token::ILLEGAL && stack_overflow_) return;
3564 // Four of the tokens are treated specially
3567 return ReportMessage("unexpected_eos", Vector<const char*>::empty());
3569 return ReportMessage("unexpected_token_number",
3570 Vector<const char*>::empty());
3572 return ReportMessage("unexpected_token_string",
3573 Vector<const char*>::empty());
3574 case Token::IDENTIFIER:
3575 return ReportMessage("unexpected_token_identifier",
3576 Vector<const char*>::empty());
3577 case Token::FUTURE_RESERVED_WORD:
3578 return ReportMessage("unexpected_reserved",
3579 Vector<const char*>::empty());
3580 case Token::FUTURE_STRICT_RESERVED_WORD:
3581 return ReportMessage(top_scope_->is_classic_mode() ?
3582 "unexpected_token_identifier" :
3583 "unexpected_strict_reserved",
3584 Vector<const char*>::empty());
3586 const char* name = Token::String(token);
3587 ASSERT(name != NULL);
3588 ReportMessage("unexpected_token", Vector<const char*>(&name, 1));
3593 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) {
3594 SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS);
3595 const char* element[1] = { *name_string };
3596 ReportMessage("invalid_preparser_data",
3597 Vector<const char*>(element, 1));
3602 Expression* Parser::ParsePrimaryExpression(bool* ok) {
3603 // PrimaryExpression ::
3614 // '(' Expression ')'
3616 Expression* result = NULL;
3619 Consume(Token::THIS);
3620 result = factory()->NewVariableProxy(top_scope_->receiver());
3624 case Token::NULL_LITERAL:
3625 Consume(Token::NULL_LITERAL);
3626 result = factory()->NewLiteral(isolate()->factory()->null_value());
3629 case Token::TRUE_LITERAL:
3630 Consume(Token::TRUE_LITERAL);
3631 result = factory()->NewLiteral(isolate()->factory()->true_value());
3634 case Token::FALSE_LITERAL:
3635 Consume(Token::FALSE_LITERAL);
3636 result = factory()->NewLiteral(isolate()->factory()->false_value());
3639 case Token::IDENTIFIER:
3640 case Token::FUTURE_STRICT_RESERVED_WORD: {
3641 Handle<String> name = ParseIdentifier(CHECK_OK);
3642 if (fni_ != NULL) fni_->PushVariableName(name);
3643 // The name may refer to a module instance object, so its type is unknown.
3645 if (FLAG_print_interface_details)
3646 PrintF("# Variable %s ", name->ToAsciiArray());
3648 Interface* interface = Interface::NewUnknown();
3649 result = top_scope_->NewUnresolved(
3650 factory(), name, scanner().location().beg_pos, interface);
3654 case Token::NUMBER: {
3655 Consume(Token::NUMBER);
3656 ASSERT(scanner().is_literal_ascii());
3657 double value = StringToDouble(isolate()->unicode_cache(),
3658 scanner().literal_ascii_string(),
3659 ALLOW_HEX | ALLOW_OCTALS);
3660 result = factory()->NewNumberLiteral(value);
3664 case Token::STRING: {
3665 Consume(Token::STRING);
3666 Handle<String> symbol = GetSymbol(CHECK_OK);
3667 result = factory()->NewLiteral(symbol);
3668 if (fni_ != NULL) fni_->PushLiteralName(symbol);
3672 case Token::ASSIGN_DIV:
3673 result = ParseRegExpLiteral(true, CHECK_OK);
3677 result = ParseRegExpLiteral(false, CHECK_OK);
3681 result = ParseArrayLiteral(CHECK_OK);
3685 result = ParseObjectLiteral(CHECK_OK);
3689 Consume(Token::LPAREN);
3690 // Heuristically try to detect immediately called functions before
3691 // seeing the call parentheses.
3692 parenthesized_function_ = (peek() == Token::FUNCTION);
3693 result = ParseExpression(true, CHECK_OK);
3694 Expect(Token::RPAREN, CHECK_OK);
3698 if (allow_natives_syntax_ || extension_ != NULL) {
3699 result = ParseV8Intrinsic(CHECK_OK);
3702 // If we're not allowing special syntax we fall-through to the
3706 Token::Value tok = Next();
3707 ReportUnexpectedToken(tok);
3717 void Parser::BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* values,
3718 Handle<FixedArray> literals,
3721 // Fill in the literals.
3722 // Accumulate output values in local variables.
3723 bool is_simple_acc = true;
3725 for (int i = 0; i < values->length(); i++) {
3726 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral();
3727 if (m_literal != NULL && m_literal->depth() >= depth_acc) {
3728 depth_acc = m_literal->depth() + 1;
3730 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i));
3731 if (boilerplate_value->IsUndefined()) {
3732 literals->set_the_hole(i);
3733 is_simple_acc = false;
3735 literals->set(i, *boilerplate_value);
3739 *is_simple = is_simple_acc;
3744 Expression* Parser::ParseArrayLiteral(bool* ok) {
3746 // '[' Expression? (',' Expression?)* ']'
3748 ZoneList<Expression*>* values = new(zone()) ZoneList<Expression*>(4);
3749 Expect(Token::LBRACK, CHECK_OK);
3750 while (peek() != Token::RBRACK) {
3752 if (peek() == Token::COMMA) {
3753 elem = GetLiteralTheHole();
3755 elem = ParseAssignmentExpression(true, CHECK_OK);
3758 if (peek() != Token::RBRACK) {
3759 Expect(Token::COMMA, CHECK_OK);
3762 Expect(Token::RBRACK, CHECK_OK);
3764 // Update the scope information before the pre-parsing bailout.
3765 int literal_index = current_function_state_->NextMaterializedLiteralIndex();
3767 // Allocate a fixed array to hold all the object literals.
3768 Handle<FixedArray> object_literals =
3769 isolate()->factory()->NewFixedArray(values->length(), TENURED);
3770 Handle<FixedDoubleArray> double_literals;
3771 ElementsKind elements_kind = FAST_SMI_ONLY_ELEMENTS;
3772 bool has_only_undefined_values = true;
3774 // Fill in the literals.
3775 bool is_simple = true;
3777 for (int i = 0, n = values->length(); i < n; i++) {
3778 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral();
3779 if (m_literal != NULL && m_literal->depth() + 1 > depth) {
3780 depth = m_literal->depth() + 1;
3782 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i));
3783 if (boilerplate_value->IsUndefined()) {
3784 object_literals->set_the_hole(i);
3785 if (elements_kind == FAST_DOUBLE_ELEMENTS) {
3786 double_literals->set_the_hole(i);
3790 // Examine each literal element, and adjust the ElementsKind if the
3791 // literal element is not of a type that can be stored in the current
3792 // ElementsKind. Start with FAST_SMI_ONLY_ELEMENTS, and transition to
3793 // FAST_DOUBLE_ELEMENTS and FAST_ELEMENTS as necessary. Always remember
3794 // the tagged value, no matter what the ElementsKind is in case we
3795 // ultimately end up in FAST_ELEMENTS.
3796 has_only_undefined_values = false;
3797 object_literals->set(i, *boilerplate_value);
3798 if (elements_kind == FAST_SMI_ONLY_ELEMENTS) {
3799 // Smi only elements. Notice if a transition to FAST_DOUBLE_ELEMENTS or
3800 // FAST_ELEMENTS is required.
3801 if (!boilerplate_value->IsSmi()) {
3802 if (boilerplate_value->IsNumber() && FLAG_smi_only_arrays) {
3803 // Allocate a double array on the FAST_DOUBLE_ELEMENTS transition to
3804 // avoid over-allocating in TENURED space.
3805 double_literals = isolate()->factory()->NewFixedDoubleArray(
3806 values->length(), TENURED);
3807 // Copy the contents of the FAST_SMI_ONLY_ELEMENT array to the
3808 // FAST_DOUBLE_ELEMENTS array so that they are in sync.
3809 for (int j = 0; j < i; ++j) {
3810 Object* smi_value = object_literals->get(j);
3811 if (smi_value->IsTheHole()) {
3812 double_literals->set_the_hole(j);
3814 double_literals->set(j, Smi::cast(smi_value)->value());
3817 double_literals->set(i, boilerplate_value->Number());
3818 elements_kind = FAST_DOUBLE_ELEMENTS;
3820 elements_kind = FAST_ELEMENTS;
3823 } else if (elements_kind == FAST_DOUBLE_ELEMENTS) {
3824 // Continue to store double values in to FAST_DOUBLE_ELEMENTS arrays
3825 // until the first value is seen that can't be stored as a double.
3826 if (boilerplate_value->IsNumber()) {
3827 double_literals->set(i, boilerplate_value->Number());
3829 elements_kind = FAST_ELEMENTS;
3835 // Very small array literals that don't have a concrete hint about their type
3836 // from a constant value should default to the slow case to avoid lots of
3837 // elements transitions on really small objects.
3838 if (has_only_undefined_values && values->length() <= 2) {
3839 elements_kind = FAST_ELEMENTS;
3842 // Simple and shallow arrays can be lazily copied, we transform the
3843 // elements array to a copy-on-write array.
3844 if (is_simple && depth == 1 && values->length() > 0 &&
3845 elements_kind != FAST_DOUBLE_ELEMENTS) {
3846 object_literals->set_map(isolate()->heap()->fixed_cow_array_map());
3849 Handle<FixedArrayBase> element_values = elements_kind == FAST_DOUBLE_ELEMENTS
3850 ? Handle<FixedArrayBase>(double_literals)
3851 : Handle<FixedArrayBase>(object_literals);
3853 // Remember both the literal's constant values as well as the ElementsKind
3854 // in a 2-element FixedArray.
3855 Handle<FixedArray> literals =
3856 isolate()->factory()->NewFixedArray(2, TENURED);
3858 literals->set(0, Smi::FromInt(elements_kind));
3859 literals->set(1, *element_values);
3861 return factory()->NewArrayLiteral(
3862 literals, values, literal_index, is_simple, depth);
3866 bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) {
3867 return property != NULL &&
3868 property->kind() != ObjectLiteral::Property::PROTOTYPE;
3872 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
3873 if (expression->AsLiteral() != NULL) return true;
3874 MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3875 return lit != NULL && lit->is_simple();
3879 bool CompileTimeValue::ArrayLiteralElementNeedsInitialization(
3880 Expression* value) {
3881 // If value is a literal the property value is already set in the
3882 // boilerplate object.
3883 if (value->AsLiteral() != NULL) return false;
3884 // If value is a materialized literal the property value is already set
3885 // in the boilerplate object if it is simple.
3886 if (CompileTimeValue::IsCompileTimeValue(value)) return false;
3891 Handle<FixedArray> CompileTimeValue::GetValue(Expression* expression) {
3892 ASSERT(IsCompileTimeValue(expression));
3893 Handle<FixedArray> result = FACTORY->NewFixedArray(2, TENURED);
3894 ObjectLiteral* object_literal = expression->AsObjectLiteral();
3895 if (object_literal != NULL) {
3896 ASSERT(object_literal->is_simple());
3897 if (object_literal->fast_elements()) {
3898 result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
3900 result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
3902 result->set(kElementsSlot, *object_literal->constant_properties());
3904 ArrayLiteral* array_literal = expression->AsArrayLiteral();
3905 ASSERT(array_literal != NULL && array_literal->is_simple());
3906 result->set(kTypeSlot, Smi::FromInt(ARRAY_LITERAL));
3907 result->set(kElementsSlot, *array_literal->constant_elements());
3913 CompileTimeValue::Type CompileTimeValue::GetType(Handle<FixedArray> value) {
3914 Smi* type_value = Smi::cast(value->get(kTypeSlot));
3915 return static_cast<Type>(type_value->value());
3919 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
3920 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
3924 Handle<Object> Parser::GetBoilerplateValue(Expression* expression) {
3925 if (expression->AsLiteral() != NULL) {
3926 return expression->AsLiteral()->handle();
3928 if (CompileTimeValue::IsCompileTimeValue(expression)) {
3929 return CompileTimeValue::GetValue(expression);
3931 return isolate()->factory()->undefined_value();
3934 // Validation per 11.1.5 Object Initialiser
3935 class ObjectLiteralPropertyChecker {
3937 ObjectLiteralPropertyChecker(Parser* parser, LanguageMode language_mode) :
3938 props_(Literal::Match),
3940 language_mode_(language_mode) {
3944 ObjectLiteral::Property* property,
3945 Scanner::Location loc,
3950 kGetAccessor = 0x01,
3951 kSetAccessor = 0x02,
3952 kAccessor = kGetAccessor | kSetAccessor,
3956 static intptr_t GetPropertyKind(ObjectLiteral::Property* property) {
3957 switch (property->kind()) {
3958 case ObjectLiteral::Property::GETTER:
3959 return kGetAccessor;
3960 case ObjectLiteral::Property::SETTER:
3961 return kSetAccessor;
3969 LanguageMode language_mode_;
3973 void ObjectLiteralPropertyChecker::CheckProperty(
3974 ObjectLiteral::Property* property,
3975 Scanner::Location loc,
3977 ASSERT(property != NULL);
3978 Literal* literal = property->key();
3979 HashMap::Entry* entry = props_.Lookup(literal, literal->Hash(), true);
3980 intptr_t prev = reinterpret_cast<intptr_t> (entry->value);
3981 intptr_t curr = GetPropertyKind(property);
3983 // Duplicate data properties are illegal in strict or extended mode.
3984 if (language_mode_ != CLASSIC_MODE && (curr & prev & kData) != 0) {
3985 parser_->ReportMessageAt(loc, "strict_duplicate_property",
3986 Vector<const char*>::empty());
3990 // Data property conflicting with an accessor.
3991 if (((curr & kData) && (prev & kAccessor)) ||
3992 ((prev & kData) && (curr & kAccessor))) {
3993 parser_->ReportMessageAt(loc, "accessor_data_property",
3994 Vector<const char*>::empty());
3998 // Two accessors of the same type conflicting
3999 if ((curr & prev & kAccessor) != 0) {
4000 parser_->ReportMessageAt(loc, "accessor_get_set",
4001 Vector<const char*>::empty());
4007 entry->value = reinterpret_cast<void*> (prev | curr);
4012 void Parser::BuildObjectLiteralConstantProperties(
4013 ZoneList<ObjectLiteral::Property*>* properties,
4014 Handle<FixedArray> constant_properties,
4016 bool* fast_elements,
4019 // Accumulate the value in local variables and store it at the end.
4020 bool is_simple_acc = true;
4022 uint32_t max_element_index = 0;
4023 uint32_t elements = 0;
4024 for (int i = 0; i < properties->length(); i++) {
4025 ObjectLiteral::Property* property = properties->at(i);
4026 if (!IsBoilerplateProperty(property)) {
4027 is_simple_acc = false;
4030 MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral();
4031 if (m_literal != NULL && m_literal->depth() >= depth_acc) {
4032 depth_acc = m_literal->depth() + 1;
4035 // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined
4036 // value for COMPUTED properties, the real value is filled in at
4037 // runtime. The enumeration order is maintained.
4038 Handle<Object> key = property->key()->handle();
4039 Handle<Object> value = GetBoilerplateValue(property->value());
4040 is_simple_acc = is_simple_acc && !value->IsUndefined();
4042 // Keep track of the number of elements in the object literal and
4043 // the largest element index. If the largest element index is
4044 // much larger than the number of elements, creating an object
4045 // literal with fast elements will be a waste of space.
4046 uint32_t element_index = 0;
4048 && Handle<String>::cast(key)->AsArrayIndex(&element_index)
4049 && element_index > max_element_index) {
4050 max_element_index = element_index;
4052 } else if (key->IsSmi()) {
4053 int key_value = Smi::cast(*key)->value();
4055 && static_cast<uint32_t>(key_value) > max_element_index) {
4056 max_element_index = key_value;
4061 // Add name, value pair to the fixed array.
4062 constant_properties->set(position++, *key);
4063 constant_properties->set(position++, *value);
4066 (max_element_index <= 32) || ((2 * elements) >= max_element_index);
4067 *is_simple = is_simple_acc;
4072 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
4074 // Special handling of getter and setter syntax:
4075 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
4076 // We have already read the "get" or "set" keyword.
4077 Token::Value next = Next();
4078 bool is_keyword = Token::IsKeyword(next);
4079 if (next == Token::IDENTIFIER || next == Token::NUMBER ||
4080 next == Token::FUTURE_RESERVED_WORD ||
4081 next == Token::FUTURE_STRICT_RESERVED_WORD ||
4082 next == Token::STRING || is_keyword) {
4083 Handle<String> name;
4085 name = isolate_->factory()->LookupAsciiSymbol(Token::String(next));
4087 name = GetSymbol(CHECK_OK);
4089 FunctionLiteral* value =
4090 ParseFunctionLiteral(name,
4091 false, // reserved words are allowed here
4092 RelocInfo::kNoPosition,
4093 FunctionLiteral::ANONYMOUS_EXPRESSION,
4095 // Allow any number of parameters for compatibilty with JSC.
4096 // Specification only allows zero parameters for get and one for set.
4097 return factory()->NewObjectLiteralProperty(is_getter, value);
4099 ReportUnexpectedToken(next);
4106 Expression* Parser::ParseObjectLiteral(bool* ok) {
4109 // ((IdentifierName | String | Number) ':' AssignmentExpression)
4110 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
4113 ZoneList<ObjectLiteral::Property*>* properties =
4114 new(zone()) ZoneList<ObjectLiteral::Property*>(4);
4115 int number_of_boilerplate_properties = 0;
4116 bool has_function = false;
4118 ObjectLiteralPropertyChecker checker(this, top_scope_->language_mode());
4120 Expect(Token::LBRACE, CHECK_OK);
4122 while (peek() != Token::RBRACE) {
4123 if (fni_ != NULL) fni_->Enter();
4125 Literal* key = NULL;
4126 Token::Value next = peek();
4128 // Location of the property name token
4129 Scanner::Location loc = scanner().peek_location();
4132 case Token::FUTURE_RESERVED_WORD:
4133 case Token::FUTURE_STRICT_RESERVED_WORD:
4134 case Token::IDENTIFIER: {
4135 bool is_getter = false;
4136 bool is_setter = false;
4138 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
4139 if (fni_ != NULL) fni_->PushLiteralName(id);
4141 if ((is_getter || is_setter) && peek() != Token::COLON) {
4142 // Update loc to point to the identifier
4143 loc = scanner().peek_location();
4144 ObjectLiteral::Property* property =
4145 ParseObjectLiteralGetSet(is_getter, CHECK_OK);
4146 if (IsBoilerplateProperty(property)) {
4147 number_of_boilerplate_properties++;
4149 // Validate the property.
4150 checker.CheckProperty(property, loc, CHECK_OK);
4151 properties->Add(property);
4152 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
4158 continue; // restart the while
4160 // Failed to parse as get/set property, so it's just a property
4161 // called "get" or "set".
4162 key = factory()->NewLiteral(id);
4165 case Token::STRING: {
4166 Consume(Token::STRING);
4167 Handle<String> string = GetSymbol(CHECK_OK);
4168 if (fni_ != NULL) fni_->PushLiteralName(string);
4170 if (!string.is_null() && string->AsArrayIndex(&index)) {
4171 key = factory()->NewNumberLiteral(index);
4174 key = factory()->NewLiteral(string);
4177 case Token::NUMBER: {
4178 Consume(Token::NUMBER);
4179 ASSERT(scanner().is_literal_ascii());
4180 double value = StringToDouble(isolate()->unicode_cache(),
4181 scanner().literal_ascii_string(),
4182 ALLOW_HEX | ALLOW_OCTALS);
4183 key = factory()->NewNumberLiteral(value);
4187 if (Token::IsKeyword(next)) {
4189 Handle<String> string = GetSymbol(CHECK_OK);
4190 key = factory()->NewLiteral(string);
4192 // Unexpected token.
4193 Token::Value next = Next();
4194 ReportUnexpectedToken(next);
4200 Expect(Token::COLON, CHECK_OK);
4201 Expression* value = ParseAssignmentExpression(true, CHECK_OK);
4203 ObjectLiteral::Property* property =
4204 new(zone()) ObjectLiteral::Property(key, value, isolate());
4206 // Mark top-level object literals that contain function literals and
4207 // pretenure the literal so it can be added as a constant function
4209 if (top_scope_->DeclarationScope()->is_global_scope() &&
4210 value->AsFunctionLiteral() != NULL) {
4211 has_function = true;
4212 value->AsFunctionLiteral()->set_pretenure();
4215 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
4216 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++;
4217 // Validate the property
4218 checker.CheckProperty(property, loc, CHECK_OK);
4219 properties->Add(property);
4221 // TODO(1240767): Consider allowing trailing comma.
4222 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
4229 Expect(Token::RBRACE, CHECK_OK);
4231 // Computation of literal_index must happen before pre parse bailout.
4232 int literal_index = current_function_state_->NextMaterializedLiteralIndex();
4234 Handle<FixedArray> constant_properties = isolate()->factory()->NewFixedArray(
4235 number_of_boilerplate_properties * 2, TENURED);
4237 bool is_simple = true;
4238 bool fast_elements = true;
4240 BuildObjectLiteralConstantProperties(properties,
4241 constant_properties,
4245 return factory()->NewObjectLiteral(constant_properties,
4255 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) {
4256 if (!scanner().ScanRegExpPattern(seen_equal)) {
4258 ReportMessage("unterminated_regexp", Vector<const char*>::empty());
4263 int literal_index = current_function_state_->NextMaterializedLiteralIndex();
4265 Handle<String> js_pattern = NextLiteralString(TENURED);
4266 scanner().ScanRegExpFlags();
4267 Handle<String> js_flags = NextLiteralString(TENURED);
4270 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index);
4274 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) {
4276 // '(' (AssignmentExpression)*[','] ')'
4278 ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4);
4279 Expect(Token::LPAREN, CHECK_OK);
4280 bool done = (peek() == Token::RPAREN);
4282 Expression* argument = ParseAssignmentExpression(true, CHECK_OK);
4283 result->Add(argument);
4284 if (result->length() > kMaxNumFunctionParameters) {
4285 ReportMessageAt(scanner().location(), "too_many_arguments",
4286 Vector<const char*>::empty());
4290 done = (peek() == Token::RPAREN);
4291 if (!done) Expect(Token::COMMA, CHECK_OK);
4293 Expect(Token::RPAREN, CHECK_OK);
4298 class SingletonLogger : public ParserRecorder {
4300 SingletonLogger() : has_error_(false), start_(-1), end_(-1) { }
4301 virtual ~SingletonLogger() { }
4303 void Reset() { has_error_ = false; }
4305 virtual void LogFunction(int start,
4309 LanguageMode mode) {
4310 ASSERT(!has_error_);
4313 literals_ = literals;
4314 properties_ = properties;
4318 // Logs a symbol creation of a literal or identifier.
4319 virtual void LogAsciiSymbol(int start, Vector<const char> literal) { }
4320 virtual void LogUtf16Symbol(int start, Vector<const uc16> literal) { }
4322 // Logs an error message and marks the log as containing an error.
4323 // Further logging will be ignored, and ExtractData will return a vector
4324 // representing the error only.
4325 virtual void LogMessage(int start,
4327 const char* message,
4328 const char* argument_opt) {
4333 argument_opt_ = argument_opt;
4336 virtual int function_position() { return 0; }
4338 virtual int symbol_position() { return 0; }
4340 virtual int symbol_ids() { return -1; }
4342 virtual Vector<unsigned> ExtractData() {
4344 return Vector<unsigned>();
4347 virtual void PauseRecording() { }
4349 virtual void ResumeRecording() { }
4351 bool has_error() { return has_error_; }
4353 int start() { return start_; }
4354 int end() { return end_; }
4356 ASSERT(!has_error_);
4360 ASSERT(!has_error_);
4363 LanguageMode language_mode() {
4364 ASSERT(!has_error_);
4367 const char* message() {
4371 const char* argument_opt() {
4373 return argument_opt_;
4380 // For function entries.
4384 // For error messages.
4385 const char* message_;
4386 const char* argument_opt_;
4390 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
4391 bool name_is_strict_reserved,
4392 int function_token_position,
4393 FunctionLiteral::Type type,
4396 // '(' FormalParameterList? ')' '{' FunctionBody '}'
4398 // Anonymous functions were passed either the empty symbol or a null
4399 // handle as the function name. Remember if we were passed a non-empty
4400 // handle to decide whether to invoke function name inference.
4401 bool should_infer_name = function_name.is_null();
4403 // We want a non-null handle as the function name.
4404 if (should_infer_name) {
4405 function_name = isolate()->factory()->empty_symbol();
4408 int num_parameters = 0;
4409 // Function declarations are function scoped in normal mode, so they are
4410 // hoisted. In harmony block scoping mode they are block scoped, so they
4412 Scope* scope = (type == FunctionLiteral::DECLARATION && !is_extended_mode())
4413 ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE)
4414 : NewScope(top_scope_, FUNCTION_SCOPE);
4415 ZoneList<Statement*>* body = NULL;
4416 int materialized_literal_count = -1;
4417 int expected_property_count = -1;
4418 int handler_count = 0;
4419 bool only_simple_this_property_assignments;
4420 Handle<FixedArray> this_property_assignments;
4421 FunctionLiteral::ParameterFlag duplicate_parameters =
4422 FunctionLiteral::kNoDuplicateParameters;
4423 AstProperties ast_properties;
4424 // Parse function body.
4425 { FunctionState function_state(this, scope, isolate());
4426 top_scope_->SetScopeName(function_name);
4428 // FormalParameterList ::
4429 // '(' (Identifier)*[','] ')'
4430 Expect(Token::LPAREN, CHECK_OK);
4431 scope->set_start_position(scanner().location().beg_pos);
4432 Scanner::Location name_loc = Scanner::Location::invalid();
4433 Scanner::Location dupe_loc = Scanner::Location::invalid();
4434 Scanner::Location reserved_loc = Scanner::Location::invalid();
4436 bool done = (peek() == Token::RPAREN);
4438 bool is_strict_reserved = false;
4439 Handle<String> param_name =
4440 ParseIdentifierOrStrictReservedWord(&is_strict_reserved,
4443 // Store locations for possible future error reports.
4444 if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) {
4445 name_loc = scanner().location();
4447 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) {
4448 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters;
4449 dupe_loc = scanner().location();
4451 if (!reserved_loc.IsValid() && is_strict_reserved) {
4452 reserved_loc = scanner().location();
4455 top_scope_->DeclareParameter(param_name, VAR);
4457 if (num_parameters > kMaxNumFunctionParameters) {
4458 ReportMessageAt(scanner().location(), "too_many_parameters",
4459 Vector<const char*>::empty());
4463 done = (peek() == Token::RPAREN);
4464 if (!done) Expect(Token::COMMA, CHECK_OK);
4466 Expect(Token::RPAREN, CHECK_OK);
4468 Expect(Token::LBRACE, CHECK_OK);
4470 // If we have a named function expression, we add a local variable
4471 // declaration to the body of the function with the name of the
4472 // function and let it refer to the function itself (closure).
4473 // NOTE: We create a proxy and resolve it here so that in the
4474 // future we can change the AST to only refer to VariableProxies
4475 // instead of Variables and Proxis as is the case now.
4476 Variable* fvar = NULL;
4477 Token::Value fvar_init_op = Token::INIT_CONST;
4478 if (type == FunctionLiteral::NAMED_EXPRESSION) {
4479 VariableMode fvar_mode;
4480 if (is_extended_mode()) {
4481 fvar_mode = CONST_HARMONY;
4482 fvar_init_op = Token::INIT_CONST_HARMONY;
4487 top_scope_->DeclareFunctionVar(function_name, fvar_mode, factory());
4490 // Determine whether the function will be lazily compiled.
4491 // The heuristics are:
4492 // - It must not have been prohibited by the caller to Parse (some callers
4493 // need a full AST).
4494 // - The outer scope must be trivial (only global variables in scope).
4495 // - The function mustn't be a function expression with an open parenthesis
4496 // before; we consider that a hint that the function will be called
4497 // immediately, and it would be a waste of time to make it lazily
4499 // These are all things we can know at this point, without looking at the
4501 bool is_lazily_compiled = (mode() == PARSE_LAZILY &&
4502 top_scope_->outer_scope()->is_global_scope() &&
4503 top_scope_->HasTrivialOuterContext() &&
4504 !parenthesized_function_);
4505 parenthesized_function_ = false; // The bit was set for this function only.
4507 if (is_lazily_compiled) {
4508 int function_block_pos = scanner().location().beg_pos;
4509 FunctionEntry entry;
4510 if (pre_data_ != NULL) {
4511 // If we have pre_data_, we use it to skip parsing the function body.
4512 // the preparser data contains the information we need to construct the
4514 entry = pre_data()->GetFunctionEntry(function_block_pos);
4515 if (entry.is_valid()) {
4516 if (entry.end_pos() <= function_block_pos) {
4517 // End position greater than end of stream is safe, and hard
4519 ReportInvalidPreparseData(function_name, CHECK_OK);
4521 scanner().SeekForward(entry.end_pos() - 1);
4523 scope->set_end_position(entry.end_pos());
4524 Expect(Token::RBRACE, CHECK_OK);
4525 isolate()->counters()->total_preparse_skipped()->Increment(
4526 scope->end_position() - function_block_pos);
4527 materialized_literal_count = entry.literal_count();
4528 expected_property_count = entry.property_count();
4529 top_scope_->SetLanguageMode(entry.language_mode());
4530 only_simple_this_property_assignments = false;
4531 this_property_assignments = isolate()->factory()->empty_fixed_array();
4533 is_lazily_compiled = false;
4536 // With no preparser data, we partially parse the function, without
4537 // building an AST. This gathers the data needed to build a lazy
4539 SingletonLogger logger;
4540 preparser::PreParser::PreParseResult result =
4541 LazyParseFunctionLiteral(&logger);
4542 if (result == preparser::PreParser::kPreParseStackOverflow) {
4543 // Propagate stack overflow.
4544 stack_overflow_ = true;
4548 if (logger.has_error()) {
4549 const char* arg = logger.argument_opt();
4550 Vector<const char*> args;
4552 args = Vector<const char*>(&arg, 1);
4554 ReportMessageAt(Scanner::Location(logger.start(), logger.end()),
4555 logger.message(), args);
4559 scope->set_end_position(logger.end());
4560 Expect(Token::RBRACE, CHECK_OK);
4561 isolate()->counters()->total_preparse_skipped()->Increment(
4562 scope->end_position() - function_block_pos);
4563 materialized_literal_count = logger.literals();
4564 expected_property_count = logger.properties();
4565 top_scope_->SetLanguageMode(logger.language_mode());
4566 only_simple_this_property_assignments = false;
4567 this_property_assignments = isolate()->factory()->empty_fixed_array();
4571 if (!is_lazily_compiled) {
4572 body = new(zone()) ZoneList<Statement*>(8);
4574 VariableProxy* fproxy =
4575 top_scope_->NewUnresolved(factory(), function_name);
4576 fproxy->BindTo(fvar);
4577 body->Add(factory()->NewExpressionStatement(
4578 factory()->NewAssignment(fvar_init_op,
4580 factory()->NewThisFunction(),
4581 RelocInfo::kNoPosition)));
4583 ParseSourceElements(body, Token::RBRACE, false, CHECK_OK);
4585 materialized_literal_count = function_state.materialized_literal_count();
4586 expected_property_count = function_state.expected_property_count();
4587 handler_count = function_state.handler_count();
4588 only_simple_this_property_assignments =
4589 function_state.only_simple_this_property_assignments();
4590 this_property_assignments = function_state.this_property_assignments();
4592 Expect(Token::RBRACE, CHECK_OK);
4593 scope->set_end_position(scanner().location().end_pos);
4596 // Validate strict mode.
4597 if (!top_scope_->is_classic_mode()) {
4598 if (IsEvalOrArguments(function_name)) {
4599 int start_pos = scope->start_position();
4600 int position = function_token_position != RelocInfo::kNoPosition
4601 ? function_token_position
4602 : (start_pos > 0 ? start_pos - 1 : start_pos);
4603 Scanner::Location location = Scanner::Location(position, start_pos);
4604 ReportMessageAt(location,
4605 "strict_function_name", Vector<const char*>::empty());
4609 if (name_loc.IsValid()) {
4610 ReportMessageAt(name_loc, "strict_param_name",
4611 Vector<const char*>::empty());
4615 if (dupe_loc.IsValid()) {
4616 ReportMessageAt(dupe_loc, "strict_param_dupe",
4617 Vector<const char*>::empty());
4621 if (name_is_strict_reserved) {
4622 int start_pos = scope->start_position();
4623 int position = function_token_position != RelocInfo::kNoPosition
4624 ? function_token_position
4625 : (start_pos > 0 ? start_pos - 1 : start_pos);
4626 Scanner::Location location = Scanner::Location(position, start_pos);
4627 ReportMessageAt(location, "strict_reserved_word",
4628 Vector<const char*>::empty());
4632 if (reserved_loc.IsValid()) {
4633 ReportMessageAt(reserved_loc, "strict_reserved_word",
4634 Vector<const char*>::empty());
4638 CheckOctalLiteral(scope->start_position(),
4639 scope->end_position(),
4642 ast_properties = *factory()->visitor()->ast_properties();
4645 if (is_extended_mode()) {
4646 CheckConflictingVarDeclarations(scope, CHECK_OK);
4649 FunctionLiteral* function_literal =
4650 factory()->NewFunctionLiteral(function_name,
4653 materialized_literal_count,
4654 expected_property_count,
4656 only_simple_this_property_assignments,
4657 this_property_assignments,
4659 duplicate_parameters,
4661 FunctionLiteral::kIsFunction);
4662 function_literal->set_function_token_position(function_token_position);
4663 function_literal->set_ast_properties(&ast_properties);
4665 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
4666 return function_literal;
4670 preparser::PreParser::PreParseResult Parser::LazyParseFunctionLiteral(
4671 SingletonLogger* logger) {
4672 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse());
4673 ASSERT_EQ(Token::LBRACE, scanner().current_token());
4675 if (reusable_preparser_ == NULL) {
4676 intptr_t stack_limit = isolate()->stack_guard()->real_climit();
4677 bool do_allow_lazy = true;
4678 reusable_preparser_ = new preparser::PreParser(&scanner_,
4682 allow_natives_syntax_,
4685 preparser::PreParser::PreParseResult result =
4686 reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(),
4692 Expression* Parser::ParseV8Intrinsic(bool* ok) {
4694 // '%' Identifier Arguments
4696 Expect(Token::MOD, CHECK_OK);
4697 Handle<String> name = ParseIdentifier(CHECK_OK);
4698 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
4700 if (extension_ != NULL) {
4701 // The extension structures are only accessible while parsing the
4702 // very first time not when reparsing because of lazy compilation.
4703 top_scope_->DeclarationScope()->ForceEagerCompilation();
4706 const Runtime::Function* function = Runtime::FunctionForSymbol(name);
4708 // Check for built-in IS_VAR macro.
4709 if (function != NULL &&
4710 function->intrinsic_type == Runtime::RUNTIME &&
4711 function->function_id == Runtime::kIS_VAR) {
4712 // %IS_VAR(x) evaluates to x if x is a variable,
4713 // leads to a parse error otherwise. Could be implemented as an
4714 // inline function %_IS_VAR(x) to eliminate this special case.
4715 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
4718 ReportMessage("unable_to_parse", Vector<const char*>::empty());
4724 // Check that the expected number of arguments are being passed.
4725 if (function != NULL &&
4726 function->nargs != -1 &&
4727 function->nargs != args->length()) {
4728 ReportMessage("illegal_access", Vector<const char*>::empty());
4733 // We have a valid intrinsics call or a call to a builtin.
4734 return factory()->NewCallRuntime(name, function, args);
4738 bool Parser::peek_any_identifier() {
4739 Token::Value next = peek();
4740 return next == Token::IDENTIFIER ||
4741 next == Token::FUTURE_RESERVED_WORD ||
4742 next == Token::FUTURE_STRICT_RESERVED_WORD;
4746 void Parser::Consume(Token::Value token) {
4747 Token::Value next = Next();
4750 ASSERT(next == token);
4754 void Parser::Expect(Token::Value token, bool* ok) {
4755 Token::Value next = Next();
4756 if (next == token) return;
4757 ReportUnexpectedToken(next);
4762 bool Parser::Check(Token::Value token) {
4763 Token::Value next = peek();
4764 if (next == token) {
4772 void Parser::ExpectSemicolon(bool* ok) {
4773 // Check for automatic semicolon insertion according to
4774 // the rules given in ECMA-262, section 7.9, page 21.
4775 Token::Value tok = peek();
4776 if (tok == Token::SEMICOLON) {
4780 if (scanner().HasAnyLineTerminatorBeforeNext() ||
4781 tok == Token::RBRACE ||
4782 tok == Token::EOS) {
4785 Expect(Token::SEMICOLON, ok);
4789 void Parser::ExpectContextualKeyword(const char* keyword, bool* ok) {
4790 Expect(Token::IDENTIFIER, ok);
4792 Handle<String> symbol = GetSymbol(ok);
4794 if (!symbol->IsEqualTo(CStrVector(keyword))) {
4796 ReportUnexpectedToken(scanner().current_token());
4801 Literal* Parser::GetLiteralUndefined() {
4802 return factory()->NewLiteral(isolate()->factory()->undefined_value());
4806 Literal* Parser::GetLiteralTheHole() {
4807 return factory()->NewLiteral(isolate()->factory()->the_hole_value());
4811 // Parses an identifier that is valid for the current scope, in particular it
4812 // fails on strict mode future reserved keywords in a strict scope.
4813 Handle<String> Parser::ParseIdentifier(bool* ok) {
4814 if (!top_scope_->is_classic_mode()) {
4815 Expect(Token::IDENTIFIER, ok);
4816 } else if (!Check(Token::IDENTIFIER)) {
4817 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
4819 if (!*ok) return Handle<String>();
4820 return GetSymbol(ok);
4824 // Parses and identifier or a strict mode future reserved word, and indicate
4825 // whether it is strict mode future reserved.
4826 Handle<String> Parser::ParseIdentifierOrStrictReservedWord(
4827 bool* is_strict_reserved, bool* ok) {
4828 *is_strict_reserved = false;
4829 if (!Check(Token::IDENTIFIER)) {
4830 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
4831 *is_strict_reserved = true;
4833 if (!*ok) return Handle<String>();
4834 return GetSymbol(ok);
4838 Handle<String> Parser::ParseIdentifierName(bool* ok) {
4839 Token::Value next = Next();
4840 if (next != Token::IDENTIFIER &&
4841 next != Token::FUTURE_RESERVED_WORD &&
4842 next != Token::FUTURE_STRICT_RESERVED_WORD &&
4843 !Token::IsKeyword(next)) {
4844 ReportUnexpectedToken(next);
4846 return Handle<String>();
4848 return GetSymbol(ok);
4852 void Parser::MarkAsLValue(Expression* expression) {
4853 VariableProxy* proxy = expression != NULL
4854 ? expression->AsVariableProxy()
4857 if (proxy != NULL) proxy->MarkAsLValue();
4861 // Checks LHS expression for assignment and prefix/postfix increment/decrement
4863 void Parser::CheckStrictModeLValue(Expression* expression,
4866 ASSERT(!top_scope_->is_classic_mode());
4867 VariableProxy* lhs = expression != NULL
4868 ? expression->AsVariableProxy()
4871 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) {
4872 ReportMessage(error, Vector<const char*>::empty());
4878 // Checks whether an octal literal was last seen between beg_pos and end_pos.
4879 // If so, reports an error. Only called for strict mode.
4880 void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
4881 Scanner::Location octal = scanner().octal_position();
4882 if (octal.IsValid() &&
4883 beg_pos <= octal.beg_pos &&
4884 octal.end_pos <= end_pos) {
4885 ReportMessageAt(octal, "strict_octal_literal",
4886 Vector<const char*>::empty());
4887 scanner().clear_octal_position();
4893 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
4894 Declaration* decl = scope->CheckConflictingVarDeclarations();
4896 // In harmony mode we treat conflicting variable bindinds as early
4897 // errors. See ES5 16 for a definition of early errors.
4898 Handle<String> name = decl->proxy()->name();
4899 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
4900 const char* elms[2] = { "Variable", *c_string };
4901 Vector<const char*> args(elms, 2);
4902 int position = decl->proxy()->position();
4903 Scanner::Location location = position == RelocInfo::kNoPosition
4904 ? Scanner::Location::invalid()
4905 : Scanner::Location(position, position + 1);
4906 ReportMessageAt(location, "redeclaration", args);
4912 // This function reads an identifier name and determines whether or not it
4913 // is 'get' or 'set'.
4914 Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get,
4917 Handle<String> result = ParseIdentifierName(ok);
4918 if (!*ok) return Handle<String>();
4919 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) {
4920 const char* token = scanner().literal_ascii_string().start();
4921 *is_get = strncmp(token, "get", 3) == 0;
4922 *is_set = !*is_get && strncmp(token, "set", 3) == 0;
4928 // ----------------------------------------------------------------------------
4932 bool Parser::TargetStackContainsLabel(Handle<String> label) {
4933 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4934 BreakableStatement* stat = t->node()->AsBreakableStatement();
4935 if (stat != NULL && ContainsLabel(stat->labels(), label))
4942 BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) {
4943 bool anonymous = label.is_null();
4944 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4945 BreakableStatement* stat = t->node()->AsBreakableStatement();
4946 if (stat == NULL) continue;
4947 if ((anonymous && stat->is_target_for_anonymous()) ||
4948 (!anonymous && ContainsLabel(stat->labels(), label))) {
4949 RegisterTargetUse(stat->break_target(), t->previous());
4957 IterationStatement* Parser::LookupContinueTarget(Handle<String> label,
4959 bool anonymous = label.is_null();
4960 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4961 IterationStatement* stat = t->node()->AsIterationStatement();
4962 if (stat == NULL) continue;
4964 ASSERT(stat->is_target_for_anonymous());
4965 if (anonymous || ContainsLabel(stat->labels(), label)) {
4966 RegisterTargetUse(stat->continue_target(), t->previous());
4974 void Parser::RegisterTargetUse(Label* target, Target* stop) {
4975 // Register that a break target found at the given stop in the
4976 // target stack has been used from the top of the target stack. Add
4977 // the break target to any TargetCollectors passed on the stack.
4978 for (Target* t = target_stack_; t != stop; t = t->previous()) {
4979 TargetCollector* collector = t->node()->AsTargetCollector();
4980 if (collector != NULL) collector->AddTarget(target);
4985 Expression* Parser::NewThrowReferenceError(Handle<String> type) {
4986 return NewThrowError(isolate()->factory()->MakeReferenceError_symbol(),
4987 type, HandleVector<Object>(NULL, 0));
4991 Expression* Parser::NewThrowSyntaxError(Handle<String> type,
4992 Handle<Object> first) {
4993 int argc = first.is_null() ? 0 : 1;
4994 Vector< Handle<Object> > arguments = HandleVector<Object>(&first, argc);
4995 return NewThrowError(
4996 isolate()->factory()->MakeSyntaxError_symbol(), type, arguments);
5000 Expression* Parser::NewThrowTypeError(Handle<String> type,
5001 Handle<Object> first,
5002 Handle<Object> second) {
5003 ASSERT(!first.is_null() && !second.is_null());
5004 Handle<Object> elements[] = { first, second };
5005 Vector< Handle<Object> > arguments =
5006 HandleVector<Object>(elements, ARRAY_SIZE(elements));
5007 return NewThrowError(
5008 isolate()->factory()->MakeTypeError_symbol(), type, arguments);
5012 Expression* Parser::NewThrowError(Handle<String> constructor,
5013 Handle<String> type,
5014 Vector< Handle<Object> > arguments) {
5015 int argc = arguments.length();
5016 Handle<FixedArray> elements = isolate()->factory()->NewFixedArray(argc,
5018 for (int i = 0; i < argc; i++) {
5019 Handle<Object> element = arguments[i];
5020 if (!element.is_null()) {
5021 elements->set(i, *element);
5024 Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements(
5025 elements, FAST_ELEMENTS, TENURED);
5027 ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2);
5028 args->Add(factory()->NewLiteral(type));
5029 args->Add(factory()->NewLiteral(array));
5030 CallRuntime* call_constructor =
5031 factory()->NewCallRuntime(constructor, NULL, args);
5032 return factory()->NewThrow(call_constructor, scanner().location().beg_pos);
5035 // ----------------------------------------------------------------------------
5036 // Regular expressions
5039 RegExpParser::RegExpParser(FlatStringReader* in,
5040 Handle<String>* error,
5042 : isolate_(Isolate::Current()),
5046 current_(kEndMarker),
5050 multiline_(multiline),
5052 contains_anchor_(false),
5053 is_scanned_for_captures_(false),
5059 uc32 RegExpParser::Next() {
5061 return in()->Get(next_pos_);
5068 void RegExpParser::Advance() {
5069 if (next_pos_ < in()->length()) {
5070 StackLimitCheck check(isolate());
5071 if (check.HasOverflowed()) {
5072 ReportError(CStrVector(Isolate::kStackOverflowMessage));
5073 } else if (isolate()->zone()->excess_allocation()) {
5074 ReportError(CStrVector("Regular expression too large"));
5076 current_ = in()->Get(next_pos_);
5080 current_ = kEndMarker;
5086 void RegExpParser::Reset(int pos) {
5092 void RegExpParser::Advance(int dist) {
5093 next_pos_ += dist - 1;
5098 bool RegExpParser::simple() {
5102 RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
5104 *error_ = isolate()->factory()->NewStringFromAscii(message, NOT_TENURED);
5105 // Zip to the end to make sure the no more input is read.
5106 current_ = kEndMarker;
5107 next_pos_ = in()->length();
5114 RegExpTree* RegExpParser::ParsePattern() {
5115 RegExpTree* result = ParseDisjunction(CHECK_FAILED);
5116 ASSERT(!has_more());
5117 // If the result of parsing is a literal string atom, and it has the
5118 // same length as the input, then the atom is identical to the input.
5119 if (result->IsAtom() && result->AsAtom()->length() == in()->length()) {
5128 // Alternative | Disjunction
5136 RegExpTree* RegExpParser::ParseDisjunction() {
5137 // Used to store current state while parsing subexpressions.
5138 RegExpParserState initial_state(NULL, INITIAL, 0);
5139 RegExpParserState* stored_state = &initial_state;
5140 // Cache the builder in a local variable for quick access.
5141 RegExpBuilder* builder = initial_state.builder();
5143 switch (current()) {
5145 if (stored_state->IsSubexpression()) {
5146 // Inside a parenthesized group when hitting end of input.
5147 ReportError(CStrVector("Unterminated group") CHECK_FAILED);
5149 ASSERT_EQ(INITIAL, stored_state->group_type());
5150 // Parsing completed successfully.
5151 return builder->ToRegExp();
5153 if (!stored_state->IsSubexpression()) {
5154 ReportError(CStrVector("Unmatched ')'") CHECK_FAILED);
5156 ASSERT_NE(INITIAL, stored_state->group_type());
5159 // End disjunction parsing and convert builder content to new single
5161 RegExpTree* body = builder->ToRegExp();
5163 int end_capture_index = captures_started();
5165 int capture_index = stored_state->capture_index();
5166 SubexpressionType type = stored_state->group_type();
5168 // Restore previous state.
5169 stored_state = stored_state->previous_state();
5170 builder = stored_state->builder();
5172 // Build result of subexpression.
5173 if (type == CAPTURE) {
5174 RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index);
5175 captures_->at(capture_index - 1) = capture;
5177 } else if (type != GROUPING) {
5178 ASSERT(type == POSITIVE_LOOKAHEAD || type == NEGATIVE_LOOKAHEAD);
5179 bool is_positive = (type == POSITIVE_LOOKAHEAD);
5180 body = new(zone()) RegExpLookahead(body,
5182 end_capture_index - capture_index,
5185 builder->AddAtom(body);
5186 // For compatability with JSC and ES3, we allow quantifiers after
5187 // lookaheads, and break in all cases.
5192 builder->NewAlternative();
5198 return ReportError(CStrVector("Nothing to repeat"));
5202 builder->AddAssertion(
5203 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE));
5205 builder->AddAssertion(
5206 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
5207 set_contains_anchor();
5213 RegExpAssertion::Type type =
5214 multiline_ ? RegExpAssertion::END_OF_LINE :
5215 RegExpAssertion::END_OF_INPUT;
5216 builder->AddAssertion(new(zone()) RegExpAssertion(type));
5221 // everything except \x0a, \x0d, \u2028 and \u2029
5222 ZoneList<CharacterRange>* ranges =
5223 new(zone()) ZoneList<CharacterRange>(2);
5224 CharacterRange::AddClassEscape('.', ranges);
5225 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
5226 builder->AddAtom(atom);
5230 SubexpressionType type = CAPTURE;
5232 if (current() == '?') {
5238 type = POSITIVE_LOOKAHEAD;
5241 type = NEGATIVE_LOOKAHEAD;
5244 ReportError(CStrVector("Invalid group") CHECK_FAILED);
5249 if (captures_ == NULL) {
5250 captures_ = new(zone()) ZoneList<RegExpCapture*>(2);
5252 if (captures_started() >= kMaxCaptures) {
5253 ReportError(CStrVector("Too many captures") CHECK_FAILED);
5255 captures_->Add(NULL);
5257 // Store current state and begin new disjunction parsing.
5258 stored_state = new(zone()) RegExpParserState(stored_state,
5260 captures_started());
5261 builder = stored_state->builder();
5265 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED);
5266 builder->AddAtom(atom);
5274 return ReportError(CStrVector("\\ at end of pattern"));
5277 builder->AddAssertion(
5278 new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
5282 builder->AddAssertion(
5283 new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
5286 // CharacterClassEscape
5288 // CharacterClassEscape :: one of
5290 case 'd': case 'D': case 's': case 'S': case 'w': case 'W': {
5293 ZoneList<CharacterRange>* ranges =
5294 new(zone()) ZoneList<CharacterRange>(2);
5295 CharacterRange::AddClassEscape(c, ranges);
5296 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
5297 builder->AddAtom(atom);
5300 case '1': case '2': case '3': case '4': case '5': case '6':
5301 case '7': case '8': case '9': {
5303 if (ParseBackReferenceIndex(&index)) {
5304 RegExpCapture* capture = NULL;
5305 if (captures_ != NULL && index <= captures_->length()) {
5306 capture = captures_->at(index - 1);
5308 if (capture == NULL) {
5309 builder->AddEmpty();
5312 RegExpTree* atom = new(zone()) RegExpBackReference(capture);
5313 builder->AddAtom(atom);
5316 uc32 first_digit = Next();
5317 if (first_digit == '8' || first_digit == '9') {
5318 // Treat as identity escape
5319 builder->AddCharacter(first_digit);
5327 uc32 octal = ParseOctalLiteral();
5328 builder->AddCharacter(octal);
5331 // ControlEscape :: one of
5335 builder->AddCharacter('\f');
5339 builder->AddCharacter('\n');
5343 builder->AddCharacter('\r');
5347 builder->AddCharacter('\t');
5351 builder->AddCharacter('\v');
5355 uc32 controlLetter = Next();
5356 // Special case if it is an ASCII letter.
5357 // Convert lower case letters to uppercase.
5358 uc32 letter = controlLetter & ~('a' ^ 'A');
5359 if (letter < 'A' || 'Z' < letter) {
5360 // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
5361 // This is outside the specification. We match JSC in
5362 // reading the backslash as a literal character instead
5363 // of as starting an escape.
5364 builder->AddCharacter('\\');
5367 builder->AddCharacter(controlLetter & 0x1f);
5374 if (ParseHexEscape(2, &value)) {
5375 builder->AddCharacter(value);
5377 builder->AddCharacter('x');
5384 if (ParseHexEscape(4, &value)) {
5385 builder->AddCharacter(value);
5387 builder->AddCharacter('u');
5393 builder->AddCharacter(Next());
5400 if (ParseIntervalQuantifier(&dummy, &dummy)) {
5401 ReportError(CStrVector("Nothing to repeat") CHECK_FAILED);
5406 builder->AddCharacter(current());
5409 } // end switch(current())
5413 switch (current()) {
5414 // QuantifierPrefix ::
5421 max = RegExpTree::kInfinity;
5426 max = RegExpTree::kInfinity;
5435 if (ParseIntervalQuantifier(&min, &max)) {
5437 ReportError(CStrVector("numbers out of order in {} quantifier.")
5447 RegExpQuantifier::Type type = RegExpQuantifier::GREEDY;
5448 if (current() == '?') {
5449 type = RegExpQuantifier::NON_GREEDY;
5451 } else if (FLAG_regexp_possessive_quantifier && current() == '+') {
5452 // FLAG_regexp_possessive_quantifier is a debug-only flag.
5453 type = RegExpQuantifier::POSSESSIVE;
5456 builder->AddQuantifierToAtom(min, max, type);
5462 // Currently only used in an ASSERT.
5463 static bool IsSpecialClassEscape(uc32 c) {
5476 // In order to know whether an escape is a backreference or not we have to scan
5477 // the entire regexp and find the number of capturing parentheses. However we
5478 // don't want to scan the regexp twice unless it is necessary. This mini-parser
5479 // is called when needed. It can see the difference between capturing and
5480 // noncapturing parentheses and can skip character classes and backslash-escaped
5482 void RegExpParser::ScanForCaptures() {
5483 // Start with captures started previous to current position
5484 int capture_count = captures_started();
5485 // Add count of captures after this position.
5487 while ((n = current()) != kEndMarker) {
5495 while ((c = current()) != kEndMarker) {
5500 if (c == ']') break;
5506 if (current() != '?') capture_count++;
5510 capture_count_ = capture_count;
5511 is_scanned_for_captures_ = true;
5515 bool RegExpParser::ParseBackReferenceIndex(int* index_out) {
5516 ASSERT_EQ('\\', current());
5517 ASSERT('1' <= Next() && Next() <= '9');
5518 // Try to parse a decimal literal that is no greater than the total number
5519 // of left capturing parentheses in the input.
5520 int start = position();
5521 int value = Next() - '0';
5525 if (IsDecimalDigit(c)) {
5526 value = 10 * value + (c - '0');
5527 if (value > kMaxCaptures) {
5536 if (value > captures_started()) {
5537 if (!is_scanned_for_captures_) {
5538 int saved_position = position();
5540 Reset(saved_position);
5542 if (value > capture_count_) {
5552 // QuantifierPrefix ::
5553 // { DecimalDigits }
5554 // { DecimalDigits , }
5555 // { DecimalDigits , DecimalDigits }
5557 // Returns true if parsing succeeds, and set the min_out and max_out
5558 // values. Values are truncated to RegExpTree::kInfinity if they overflow.
5559 bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
5560 ASSERT_EQ(current(), '{');
5561 int start = position();
5564 if (!IsDecimalDigit(current())) {
5568 while (IsDecimalDigit(current())) {
5569 int next = current() - '0';
5570 if (min > (RegExpTree::kInfinity - next) / 10) {
5571 // Overflow. Skip past remaining decimal digits and return -1.
5574 } while (IsDecimalDigit(current()));
5575 min = RegExpTree::kInfinity;
5578 min = 10 * min + next;
5582 if (current() == '}') {
5585 } else if (current() == ',') {
5587 if (current() == '}') {
5588 max = RegExpTree::kInfinity;
5591 while (IsDecimalDigit(current())) {
5592 int next = current() - '0';
5593 if (max > (RegExpTree::kInfinity - next) / 10) {
5596 } while (IsDecimalDigit(current()));
5597 max = RegExpTree::kInfinity;
5600 max = 10 * max + next;
5603 if (current() != '}') {
5619 uc32 RegExpParser::ParseOctalLiteral() {
5620 ASSERT('0' <= current() && current() <= '7');
5621 // For compatibility with some other browsers (not all), we parse
5622 // up to three octal digits with a value below 256.
5623 uc32 value = current() - '0';
5625 if ('0' <= current() && current() <= '7') {
5626 value = value * 8 + current() - '0';
5628 if (value < 32 && '0' <= current() && current() <= '7') {
5629 value = value * 8 + current() - '0';
5637 bool RegExpParser::ParseHexEscape(int length, uc32 *value) {
5638 int start = position();
5641 for (int i = 0; !done; i++) {
5643 int d = HexValue(c);
5650 if (i == length - 1) {
5659 uc32 RegExpParser::ParseClassCharacterEscape() {
5660 ASSERT(current() == '\\');
5661 ASSERT(has_next() && !IsSpecialClassEscape(Next()));
5663 switch (current()) {
5667 // ControlEscape :: one of
5685 uc32 controlLetter = Next();
5686 uc32 letter = controlLetter & ~('A' ^ 'a');
5687 // For compatibility with JSC, inside a character class
5688 // we also accept digits and underscore as control characters.
5689 if ((controlLetter >= '0' && controlLetter <= '9') ||
5690 controlLetter == '_' ||
5691 (letter >= 'A' && letter <= 'Z')) {
5693 // Control letters mapped to ASCII control characters in the range
5695 return controlLetter & 0x1f;
5697 // We match JSC in reading the backslash as a literal
5698 // character instead of as starting an escape.
5701 case '0': case '1': case '2': case '3': case '4': case '5':
5703 // For compatibility, we interpret a decimal escape that isn't
5704 // a back reference (and therefore either \0 or not valid according
5705 // to the specification) as a 1..3 digit octal character code.
5706 return ParseOctalLiteral();
5710 if (ParseHexEscape(2, &value)) {
5713 // If \x is not followed by a two-digit hexadecimal, treat it
5714 // as an identity escape.
5720 if (ParseHexEscape(4, &value)) {
5723 // If \u is not followed by a four-digit hexadecimal, treat it
5724 // as an identity escape.
5728 // Extended identity escape. We accept any character that hasn't
5729 // been matched by a more specific case, not just the subset required
5730 // by the ECMAScript specification.
5731 uc32 result = current();
5740 CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) {
5741 ASSERT_EQ(0, *char_class);
5742 uc32 first = current();
5743 if (first == '\\') {
5745 case 'w': case 'W': case 'd': case 'D': case 's': case 'S': {
5746 *char_class = Next();
5748 return CharacterRange::Singleton(0); // Return dummy value.
5751 return ReportError(CStrVector("\\ at end of pattern"));
5753 uc32 c = ParseClassCharacterEscape(CHECK_FAILED);
5754 return CharacterRange::Singleton(c);
5758 return CharacterRange::Singleton(first);
5763 static const uc16 kNoCharClass = 0;
5765 // Adds range or pre-defined character class to character ranges.
5766 // If char_class is not kInvalidClass, it's interpreted as a class
5767 // escape (i.e., 's' means whitespace, from '\s').
5768 static inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges,
5770 CharacterRange range) {
5771 if (char_class != kNoCharClass) {
5772 CharacterRange::AddClassEscape(char_class, ranges);
5779 RegExpTree* RegExpParser::ParseCharacterClass() {
5780 static const char* kUnterminated = "Unterminated character class";
5781 static const char* kRangeOutOfOrder = "Range out of order in character class";
5783 ASSERT_EQ(current(), '[');
5785 bool is_negated = false;
5786 if (current() == '^') {
5790 ZoneList<CharacterRange>* ranges = new(zone()) ZoneList<CharacterRange>(2);
5791 while (has_more() && current() != ']') {
5792 uc16 char_class = kNoCharClass;
5793 CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED);
5794 if (current() == '-') {
5796 if (current() == kEndMarker) {
5797 // If we reach the end we break out of the loop and let the
5798 // following code report an error.
5800 } else if (current() == ']') {
5801 AddRangeOrEscape(ranges, char_class, first);
5802 ranges->Add(CharacterRange::Singleton('-'));
5805 uc16 char_class_2 = kNoCharClass;
5806 CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED);
5807 if (char_class != kNoCharClass || char_class_2 != kNoCharClass) {
5808 // Either end is an escaped character class. Treat the '-' verbatim.
5809 AddRangeOrEscape(ranges, char_class, first);
5810 ranges->Add(CharacterRange::Singleton('-'));
5811 AddRangeOrEscape(ranges, char_class_2, next);
5814 if (first.from() > next.to()) {
5815 return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED);
5817 ranges->Add(CharacterRange::Range(first.from(), next.to()));
5819 AddRangeOrEscape(ranges, char_class, first);
5823 return ReportError(CStrVector(kUnterminated) CHECK_FAILED);
5826 if (ranges->length() == 0) {
5827 ranges->Add(CharacterRange::Everything());
5828 is_negated = !is_negated;
5830 return new(zone()) RegExpCharacterClass(ranges, is_negated);
5834 // ----------------------------------------------------------------------------
5835 // The Parser interface.
5837 ParserMessage::~ParserMessage() {
5838 for (int i = 0; i < args().length(); i++)
5839 DeleteArray(args()[i]);
5840 DeleteArray(args().start());
5844 ScriptDataImpl::~ScriptDataImpl() {
5845 if (owns_store_) store_.Dispose();
5849 int ScriptDataImpl::Length() {
5850 return store_.length() * sizeof(unsigned);
5854 const char* ScriptDataImpl::Data() {
5855 return reinterpret_cast<const char*>(store_.start());
5859 bool ScriptDataImpl::HasError() {
5864 void ScriptDataImpl::Initialize() {
5865 // Prepares state for use.
5866 if (store_.length() >= PreparseDataConstants::kHeaderSize) {
5867 function_index_ = PreparseDataConstants::kHeaderSize;
5868 int symbol_data_offset = PreparseDataConstants::kHeaderSize
5869 + store_[PreparseDataConstants::kFunctionsSizeOffset];
5870 if (store_.length() > symbol_data_offset) {
5871 symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]);
5873 // Partial preparse causes no symbol information.
5874 symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
5876 symbol_data_end_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
5881 int ScriptDataImpl::ReadNumber(byte** source) {
5882 // Reads a number from symbol_data_ in base 128. The most significant
5883 // bit marks that there are more digits.
5884 // If the first byte is 0x80 (kNumberTerminator), it would normally
5885 // represent a leading zero. Since that is useless, and therefore won't
5886 // appear as the first digit of any actual value, it is used to
5887 // mark the end of the input stream.
5888 byte* data = *source;
5889 if (data >= symbol_data_end_) return -1;
5891 if (input == PreparseDataConstants::kNumberTerminator) {
5892 // End of stream marker.
5895 int result = input & 0x7f;
5897 while ((input & 0x80u) != 0) {
5898 if (data >= symbol_data_end_) return -1;
5900 result = (result << 7) | (input & 0x7f);
5908 // Create a Scanner for the preparser to use as input, and preparse the source.
5909 static ScriptDataImpl* DoPreParse(Utf16CharacterStream* source,
5911 ParserRecorder* recorder) {
5912 Isolate* isolate = Isolate::Current();
5913 HistogramTimerScope timer(isolate->counters()->pre_parse());
5914 Scanner scanner(isolate->unicode_cache());
5915 scanner.SetHarmonyScoping(FLAG_harmony_scoping);
5916 scanner.Initialize(source);
5917 intptr_t stack_limit = isolate->stack_guard()->real_climit();
5918 preparser::PreParser::PreParseResult result =
5919 preparser::PreParser::PreParseProgram(&scanner,
5923 if (result == preparser::PreParser::kPreParseStackOverflow) {
5924 isolate->StackOverflow();
5928 // Extract the accumulated data from the recorder as a single
5929 // contiguous vector that we are responsible for disposing.
5930 Vector<unsigned> store = recorder->ExtractData();
5931 return new ScriptDataImpl(store);
5935 // Preparse, but only collect data that is immediately useful,
5936 // even if the preparser data is only used once.
5937 ScriptDataImpl* ParserApi::PartialPreParse(Handle<String> source,
5938 v8::Extension* extension,
5940 bool allow_lazy = FLAG_lazy && (extension == NULL);
5942 // Partial preparsing is only about lazily compiled functions.
5943 // If we don't allow lazy compilation, the log data will be empty.
5946 flags |= kAllowLazy;
5947 PartialParserRecorder recorder;
5948 int source_length = source->length();
5949 if (source->IsExternalTwoByteString()) {
5950 ExternalTwoByteStringUtf16CharacterStream stream(
5951 Handle<ExternalTwoByteString>::cast(source), 0, source_length);
5952 return DoPreParse(&stream, flags, &recorder);
5954 GenericStringUtf16CharacterStream stream(source, 0, source_length);
5955 return DoPreParse(&stream, flags, &recorder);
5960 ScriptDataImpl* ParserApi::PreParse(Utf16CharacterStream* source,
5961 v8::Extension* extension,
5963 Handle<Script> no_script;
5964 if (FLAG_lazy && (extension == NULL)) {
5965 flags |= kAllowLazy;
5967 CompleteParserRecorder recorder;
5968 return DoPreParse(source, flags, &recorder);
5972 bool RegExpParser::ParseRegExp(FlatStringReader* input,
5974 RegExpCompileData* result) {
5975 ASSERT(result != NULL);
5976 RegExpParser parser(input, &result->error, multiline);
5977 RegExpTree* tree = parser.ParsePattern();
5978 if (parser.failed()) {
5979 ASSERT(tree == NULL);
5980 ASSERT(!result->error.is_null());
5982 ASSERT(tree != NULL);
5983 ASSERT(result->error.is_null());
5984 result->tree = tree;
5985 int capture_count = parser.captures_started();
5986 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
5987 result->contains_anchor = parser.contains_anchor();
5988 result->capture_count = capture_count;
5990 return !parser.failed();
5994 bool ParserApi::Parse(CompilationInfo* info, int parsing_flags) {
5995 ASSERT(info->function() == NULL);
5996 FunctionLiteral* result = NULL;
5997 Handle<Script> script = info->script();
5998 ASSERT((parsing_flags & kLanguageModeMask) == CLASSIC_MODE);
5999 if (!info->is_native() && FLAG_harmony_scoping) {
6000 // Harmony scoping is requested.
6001 parsing_flags |= EXTENDED_MODE;
6003 if (!info->is_native() && FLAG_harmony_modules) {
6004 parsing_flags |= kAllowModules;
6006 if (FLAG_allow_natives_syntax || info->is_native()) {
6007 // We require %identifier(..) syntax.
6008 parsing_flags |= kAllowNativesSyntax;
6010 if (info->is_lazy()) {
6011 ASSERT(!info->is_eval());
6012 Parser parser(script, parsing_flags, NULL, NULL);
6013 if (info->shared_info()->is_function()) {
6014 result = parser.ParseLazy(info);
6016 result = parser.ParseProgram(info);
6019 ScriptDataImpl* pre_data = info->pre_parse_data();
6020 Parser parser(script, parsing_flags, info->extension(), pre_data);
6021 if (pre_data != NULL && pre_data->has_error()) {
6022 Scanner::Location loc = pre_data->MessageLocation();
6023 const char* message = pre_data->BuildMessage();
6024 Vector<const char*> args = pre_data->BuildArgs();
6025 parser.ReportMessageAt(loc, message, args);
6026 DeleteArray(message);
6027 for (int i = 0; i < args.length(); i++) {
6028 DeleteArray(args[i]);
6030 DeleteArray(args.start());
6031 ASSERT(info->isolate()->has_pending_exception());
6033 result = parser.ParseProgram(info);
6036 info->SetFunction(result);
6037 return (result != NULL);
6040 } } // namespace v8::internal