• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011 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
4 // met:
5 //
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.
15 //
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.
27 
28 #include "v8.h"
29 
30 #include "api.h"
31 #include "ast.h"
32 #include "bootstrapper.h"
33 #include "codegen.h"
34 #include "compiler.h"
35 #include "func-name-inferrer.h"
36 #include "messages.h"
37 #include "parser.h"
38 #include "platform.h"
39 #include "preparser.h"
40 #include "runtime.h"
41 #include "scopeinfo.h"
42 #include "string-stream.h"
43 
44 #include "ast-inl.h"
45 
46 namespace v8 {
47 namespace internal {
48 
49 // PositionStack is used for on-stack allocation of token positions for
50 // new expressions. Please look at ParseNewExpression.
51 
52 class PositionStack  {
53  public:
PositionStack(bool * ok)54   explicit PositionStack(bool* ok) : top_(NULL), ok_(ok) {}
~PositionStack()55   ~PositionStack() { ASSERT(!*ok_ || is_empty()); }
56 
57   class Element  {
58    public:
Element(PositionStack * stack,int value)59     Element(PositionStack* stack, int value) {
60       previous_ = stack->top();
61       value_ = value;
62       stack->set_top(this);
63     }
64 
65    private:
previous()66     Element* previous() { return previous_; }
value()67     int value() { return value_; }
68     friend class PositionStack;
69     Element* previous_;
70     int value_;
71   };
72 
is_empty()73   bool is_empty() { return top_ == NULL; }
pop()74   int pop() {
75     ASSERT(!is_empty());
76     int result = top_->value();
77     top_ = top_->previous();
78     return result;
79   }
80 
81  private:
top()82   Element* top() { return top_; }
set_top(Element * value)83   void set_top(Element* value) { top_ = value; }
84   Element* top_;
85   bool* ok_;
86 };
87 
88 
RegExpBuilder()89 RegExpBuilder::RegExpBuilder()
90     : zone_(Isolate::Current()->zone()),
91       pending_empty_(false),
92       characters_(NULL),
93       terms_(),
94       alternatives_()
95 #ifdef DEBUG
96     , last_added_(ADD_NONE)
97 #endif
98   {}
99 
100 
FlushCharacters()101 void RegExpBuilder::FlushCharacters() {
102   pending_empty_ = false;
103   if (characters_ != NULL) {
104     RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector());
105     characters_ = NULL;
106     text_.Add(atom);
107     LAST(ADD_ATOM);
108   }
109 }
110 
111 
FlushText()112 void RegExpBuilder::FlushText() {
113   FlushCharacters();
114   int num_text = text_.length();
115   if (num_text == 0) {
116     return;
117   } else if (num_text == 1) {
118     terms_.Add(text_.last());
119   } else {
120     RegExpText* text = new(zone()) RegExpText();
121     for (int i = 0; i < num_text; i++)
122       text_.Get(i)->AppendToText(text);
123     terms_.Add(text);
124   }
125   text_.Clear();
126 }
127 
128 
AddCharacter(uc16 c)129 void RegExpBuilder::AddCharacter(uc16 c) {
130   pending_empty_ = false;
131   if (characters_ == NULL) {
132     characters_ = new ZoneList<uc16>(4);
133   }
134   characters_->Add(c);
135   LAST(ADD_CHAR);
136 }
137 
138 
AddEmpty()139 void RegExpBuilder::AddEmpty() {
140   pending_empty_ = true;
141 }
142 
143 
AddAtom(RegExpTree * term)144 void RegExpBuilder::AddAtom(RegExpTree* term) {
145   if (term->IsEmpty()) {
146     AddEmpty();
147     return;
148   }
149   if (term->IsTextElement()) {
150     FlushCharacters();
151     text_.Add(term);
152   } else {
153     FlushText();
154     terms_.Add(term);
155   }
156   LAST(ADD_ATOM);
157 }
158 
159 
AddAssertion(RegExpTree * assert)160 void RegExpBuilder::AddAssertion(RegExpTree* assert) {
161   FlushText();
162   terms_.Add(assert);
163   LAST(ADD_ASSERT);
164 }
165 
166 
NewAlternative()167 void RegExpBuilder::NewAlternative() {
168   FlushTerms();
169 }
170 
171 
FlushTerms()172 void RegExpBuilder::FlushTerms() {
173   FlushText();
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();
180   } else {
181     alternative = new(zone()) RegExpAlternative(terms_.GetList());
182   }
183   alternatives_.Add(alternative);
184   terms_.Clear();
185   LAST(ADD_NONE);
186 }
187 
188 
ToRegExp()189 RegExpTree* RegExpBuilder::ToRegExp() {
190   FlushTerms();
191   int num_alternatives = alternatives_.length();
192   if (num_alternatives == 0) {
193     return RegExpEmpty::GetInstance();
194   }
195   if (num_alternatives == 1) {
196     return alternatives_.last();
197   }
198   return new(zone()) RegExpDisjunction(alternatives_.GetList());
199 }
200 
201 
AddQuantifierToAtom(int min,int max,RegExpQuantifier::Type type)202 void RegExpBuilder::AddQuantifierToAtom(int min,
203                                         int max,
204                                         RegExpQuantifier::Type type) {
205   if (pending_empty_) {
206     pending_empty_ = false;
207     return;
208   }
209   RegExpTree* atom;
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();
215     if (num_chars > 1) {
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);
219     }
220     characters_ = NULL;
221     atom = new(zone()) RegExpAtom(char_vector);
222     FlushText();
223   } else if (text_.length() > 0) {
224     ASSERT(last_added_ == ADD_ATOM);
225     atom = text_.RemoveLast();
226     FlushText();
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.
232       LAST(ADD_TERM);
233       if (min == 0) {
234         return;
235       }
236       terms_.Add(atom);
237       return;
238     }
239   } else {
240     // Only call immediately after adding an atom or character!
241     UNREACHABLE();
242     return;
243   }
244   terms_.Add(new(zone()) RegExpQuantifier(min, max, type, atom));
245   LAST(ADD_TERM);
246 }
247 
248 
LookupSymbol(int symbol_id)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());
259     } else {
260       return isolate()->factory()->LookupTwoByteSymbol(
261           scanner().literal_uc16_string());
262     }
263   }
264   return LookupCachedSymbol(symbol_id);
265 }
266 
267 
LookupCachedSymbol(int 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());
274   }
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());
280     } else {
281       result = isolate()->factory()->LookupTwoByteSymbol(
282           scanner().literal_uc16_string());
283     }
284     symbol_cache_.at(symbol_id) = result;
285     return result;
286   }
287   isolate()->counters()->total_preparse_symbols_skipped()->Increment();
288   return result;
289 }
290 
291 
GetFunctionEntry(int start)292 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) {
293   // The current pre-data entry must be a FunctionEntry with the given
294   // start position.
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));
301   }
302   return FunctionEntry();
303 }
304 
305 
GetSymbolIdentifier()306 int ScriptDataImpl::GetSymbolIdentifier() {
307   return ReadNumber(&symbol_data_);
308 }
309 
310 
SanityCheck()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;
317   if (has_error()) {
318     // Extra sane sanity check for error message encoding.
319     if (store_.length() <= PreparseDataConstants::kHeaderSize
320                          + PreparseDataConstants::kMessageTextPos) {
321       return false;
322     }
323     if (Read(PreparseDataConstants::kMessageStartPos) >
324         Read(PreparseDataConstants::kMessageEndPos)) {
325       return false;
326     }
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) {
331         return false;
332       }
333       int length = static_cast<int>(Read(pos));
334       if (length < 0) return false;
335       pos += 1 + length;
336     }
337     if (store_.length() < PreparseDataConstants::kHeaderSize + pos) {
338       return false;
339     }
340     return true;
341   }
342   // Check that the space allocated for function entries is sane.
343   int functions_size =
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.
348   int symbol_count =
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.
352   int minimum_size =
353       PreparseDataConstants::kHeaderSize + functions_size;
354   if (store_.length() < minimum_size) return false;
355   return true;
356 }
357 
358 
359 
ReadString(unsigned * start,int * chars)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];
365   }
366   result[length] = '\0';
367   if (chars != NULL) *chars = length;
368   return result;
369 }
370 
MessageLocation()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);
375 }
376 
377 
BuildMessage()378 const char* ScriptDataImpl::BuildMessage() {
379   unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos);
380   return ReadString(start, NULL);
381 }
382 
383 
BuildArgs()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++) {
392     int count = 0;
393     array[i] = ReadString(ReadAddress(pos), &count);
394     pos += count + 1;
395   }
396   return Vector<const char*>(array, arg_count);
397 }
398 
399 
Read(int position)400 unsigned ScriptDataImpl::Read(int position) {
401   return store_[PreparseDataConstants::kHeaderSize + position];
402 }
403 
404 
ReadAddress(int position)405 unsigned* ScriptDataImpl::ReadAddress(int position) {
406   return &store_[PreparseDataConstants::kHeaderSize + position];
407 }
408 
409 
NewScope(Scope * parent,Scope::Type type,bool inside_with)410 Scope* Parser::NewScope(Scope* parent, Scope::Type type, bool inside_with) {
411   Scope* result = new(zone()) Scope(parent, type);
412   result->Initialize(inside_with);
413   return result;
414 }
415 
416 // ----------------------------------------------------------------------------
417 // Target is a support class to facilitate manipulation of the
418 // Parser's target_stack_ (the stack of potential 'break' and
419 // 'continue' statement targets). Upon construction, a new target is
420 // added; it is removed upon destruction.
421 
422 class Target BASE_EMBEDDED {
423  public:
Target(Target ** variable,AstNode * node)424   Target(Target** variable, AstNode* node)
425       : variable_(variable), node_(node), previous_(*variable) {
426     *variable = this;
427   }
428 
~Target()429   ~Target() {
430     *variable_ = previous_;
431   }
432 
previous()433   Target* previous() { return previous_; }
node()434   AstNode* node() { return node_; }
435 
436  private:
437   Target** variable_;
438   AstNode* node_;
439   Target* previous_;
440 };
441 
442 
443 class TargetScope BASE_EMBEDDED {
444  public:
TargetScope(Target ** variable)445   explicit TargetScope(Target** variable)
446       : variable_(variable), previous_(*variable) {
447     *variable = NULL;
448   }
449 
~TargetScope()450   ~TargetScope() {
451     *variable_ = previous_;
452   }
453 
454  private:
455   Target** variable_;
456   Target* previous_;
457 };
458 
459 
460 // ----------------------------------------------------------------------------
461 // LexicalScope is a support class to facilitate manipulation of the
462 // Parser's scope stack. The constructor sets the parser's top scope
463 // to the incoming scope, and the destructor resets it.
464 //
465 // Additionally, it stores transient information used during parsing.
466 // These scopes are not kept around after parsing or referenced by syntax
467 // trees so they can be stack-allocated and hence used by the pre-parser.
468 
469 class LexicalScope BASE_EMBEDDED {
470  public:
471   LexicalScope(Parser* parser, Scope* scope, Isolate* isolate);
472   ~LexicalScope();
473 
NextMaterializedLiteralIndex()474   int NextMaterializedLiteralIndex() {
475     int next_index =
476         materialized_literal_count_ + JSFunction::kLiteralsPrefixSize;
477     materialized_literal_count_++;
478     return next_index;
479   }
materialized_literal_count()480   int materialized_literal_count() { return materialized_literal_count_; }
481 
SetThisPropertyAssignmentInfo(bool only_simple_this_property_assignments,Handle<FixedArray> this_property_assignments)482   void SetThisPropertyAssignmentInfo(
483       bool only_simple_this_property_assignments,
484       Handle<FixedArray> this_property_assignments) {
485     only_simple_this_property_assignments_ =
486         only_simple_this_property_assignments;
487     this_property_assignments_ = this_property_assignments;
488   }
only_simple_this_property_assignments()489   bool only_simple_this_property_assignments() {
490     return only_simple_this_property_assignments_;
491   }
this_property_assignments()492   Handle<FixedArray> this_property_assignments() {
493     return this_property_assignments_;
494   }
495 
AddProperty()496   void AddProperty() { expected_property_count_++; }
expected_property_count()497   int expected_property_count() { return expected_property_count_; }
498 
499  private:
500   // Captures the number of literals that need materialization in the
501   // function.  Includes regexp literals, and boilerplate for object
502   // and array literals.
503   int materialized_literal_count_;
504 
505   // Properties count estimation.
506   int expected_property_count_;
507 
508   // Keeps track of assignments to properties of this. Used for
509   // optimizing constructors.
510   bool only_simple_this_property_assignments_;
511   Handle<FixedArray> this_property_assignments_;
512 
513   // Bookkeeping
514   Parser* parser_;
515   // Previous values
516   LexicalScope* lexical_scope_parent_;
517   Scope* previous_scope_;
518   int previous_with_nesting_level_;
519   unsigned previous_ast_node_id_;
520 };
521 
522 
LexicalScope(Parser * parser,Scope * scope,Isolate * isolate)523 LexicalScope::LexicalScope(Parser* parser, Scope* scope, Isolate* isolate)
524   : materialized_literal_count_(0),
525     expected_property_count_(0),
526     only_simple_this_property_assignments_(false),
527     this_property_assignments_(isolate->factory()->empty_fixed_array()),
528     parser_(parser),
529     lexical_scope_parent_(parser->lexical_scope_),
530     previous_scope_(parser->top_scope_),
531     previous_with_nesting_level_(parser->with_nesting_level_),
532     previous_ast_node_id_(isolate->ast_node_id()) {
533   parser->top_scope_ = scope;
534   parser->lexical_scope_ = this;
535   parser->with_nesting_level_ = 0;
536   isolate->set_ast_node_id(AstNode::kFunctionEntryId + 1);
537 }
538 
539 
~LexicalScope()540 LexicalScope::~LexicalScope() {
541   parser_->top_scope_->Leave();
542   parser_->top_scope_ = previous_scope_;
543   parser_->lexical_scope_ = lexical_scope_parent_;
544   parser_->with_nesting_level_ = previous_with_nesting_level_;
545   parser_->isolate()->set_ast_node_id(previous_ast_node_id_);
546 }
547 
548 
549 // ----------------------------------------------------------------------------
550 // The CHECK_OK macro is a convenient macro to enforce error
551 // handling for functions that may fail (by returning !*ok).
552 //
553 // CAUTION: This macro appends extra statements after a call,
554 // thus it must never be used where only a single statement
555 // is correct (e.g. an if statement branch w/o braces)!
556 
557 #define CHECK_OK  ok);   \
558   if (!*ok) return NULL; \
559   ((void)0
560 #define DUMMY )  // to make indentation work
561 #undef DUMMY
562 
563 #define CHECK_FAILED  /**/);   \
564   if (failed_) return NULL; \
565   ((void)0
566 #define DUMMY )  // to make indentation work
567 #undef DUMMY
568 
569 // ----------------------------------------------------------------------------
570 // Implementation of Parser
571 
Parser(Handle<Script> script,bool allow_natives_syntax,v8::Extension * extension,ScriptDataImpl * pre_data)572 Parser::Parser(Handle<Script> script,
573                bool allow_natives_syntax,
574                v8::Extension* extension,
575                ScriptDataImpl* pre_data)
576     : isolate_(script->GetIsolate()),
577       symbol_cache_(pre_data ? pre_data->symbol_count() : 0),
578       script_(script),
579       scanner_(isolate_->unicode_cache()),
580       top_scope_(NULL),
581       with_nesting_level_(0),
582       lexical_scope_(NULL),
583       target_stack_(NULL),
584       allow_natives_syntax_(allow_natives_syntax),
585       extension_(extension),
586       pre_data_(pre_data),
587       fni_(NULL),
588       stack_overflow_(false),
589       parenthesized_function_(false) {
590   AstNode::ResetIds();
591 }
592 
593 
ParseProgram(Handle<String> source,bool in_global_context,StrictModeFlag strict_mode)594 FunctionLiteral* Parser::ParseProgram(Handle<String> source,
595                                       bool in_global_context,
596                                       StrictModeFlag strict_mode) {
597   CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
598 
599   HistogramTimerScope timer(isolate()->counters()->parse());
600   isolate()->counters()->total_parse_size()->Increment(source->length());
601   fni_ = new(zone()) FuncNameInferrer();
602 
603   // Initialize parser state.
604   source->TryFlatten();
605   if (source->IsExternalTwoByteString()) {
606     // Notice that the stream is destroyed at the end of the branch block.
607     // The last line of the blocks can't be moved outside, even though they're
608     // identical calls.
609     ExternalTwoByteStringUC16CharacterStream stream(
610         Handle<ExternalTwoByteString>::cast(source), 0, source->length());
611     scanner_.Initialize(&stream);
612     return DoParseProgram(source, in_global_context, strict_mode, &zone_scope);
613   } else {
614     GenericStringUC16CharacterStream stream(source, 0, source->length());
615     scanner_.Initialize(&stream);
616     return DoParseProgram(source, in_global_context, strict_mode, &zone_scope);
617   }
618 }
619 
620 
DoParseProgram(Handle<String> source,bool in_global_context,StrictModeFlag strict_mode,ZoneScope * zone_scope)621 FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
622                                         bool in_global_context,
623                                         StrictModeFlag strict_mode,
624                                         ZoneScope* zone_scope) {
625   ASSERT(target_stack_ == NULL);
626   if (pre_data_ != NULL) pre_data_->Initialize();
627 
628   // Compute the parsing mode.
629   mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY;
630   if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY;
631 
632   Scope::Type type =
633     in_global_context
634       ? Scope::GLOBAL_SCOPE
635       : Scope::EVAL_SCOPE;
636   Handle<String> no_name = isolate()->factory()->empty_symbol();
637 
638   FunctionLiteral* result = NULL;
639   { Scope* scope = NewScope(top_scope_, type, inside_with());
640     LexicalScope lexical_scope(this, scope, isolate());
641     if (strict_mode == kStrictMode) {
642       top_scope_->EnableStrictMode();
643     }
644     ZoneList<Statement*>* body = new ZoneList<Statement*>(16);
645     bool ok = true;
646     int beg_loc = scanner().location().beg_pos;
647     ParseSourceElements(body, Token::EOS, &ok);
648     if (ok && top_scope_->is_strict_mode()) {
649       CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
650     }
651     if (ok) {
652       result = new(zone()) FunctionLiteral(
653           no_name,
654           top_scope_,
655           body,
656           lexical_scope.materialized_literal_count(),
657           lexical_scope.expected_property_count(),
658           lexical_scope.only_simple_this_property_assignments(),
659           lexical_scope.this_property_assignments(),
660           0,
661           0,
662           source->length(),
663           false);
664     } else if (stack_overflow_) {
665       isolate()->StackOverflow();
666     }
667   }
668 
669   // Make sure the target stack is empty.
670   ASSERT(target_stack_ == NULL);
671 
672   // If there was a syntax error we have to get rid of the AST
673   // and it is not safe to do so before the scope has been deleted.
674   if (result == NULL) zone_scope->DeleteOnExit();
675   return result;
676 }
677 
ParseLazy(CompilationInfo * info)678 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) {
679   CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
680   HistogramTimerScope timer(isolate()->counters()->parse_lazy());
681   Handle<String> source(String::cast(script_->source()));
682   isolate()->counters()->total_parse_size()->Increment(source->length());
683 
684   Handle<SharedFunctionInfo> shared_info = info->shared_info();
685   // Initialize parser state.
686   source->TryFlatten();
687   if (source->IsExternalTwoByteString()) {
688     ExternalTwoByteStringUC16CharacterStream stream(
689         Handle<ExternalTwoByteString>::cast(source),
690         shared_info->start_position(),
691         shared_info->end_position());
692     FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope);
693     return result;
694   } else {
695     GenericStringUC16CharacterStream stream(source,
696                                             shared_info->start_position(),
697                                             shared_info->end_position());
698     FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope);
699     return result;
700   }
701 }
702 
703 
ParseLazy(CompilationInfo * info,UC16CharacterStream * source,ZoneScope * zone_scope)704 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
705                                    UC16CharacterStream* source,
706                                    ZoneScope* zone_scope) {
707   Handle<SharedFunctionInfo> shared_info = info->shared_info();
708   scanner_.Initialize(source);
709   ASSERT(target_stack_ == NULL);
710 
711   Handle<String> name(String::cast(shared_info->name()));
712   fni_ = new(zone()) FuncNameInferrer();
713   fni_->PushEnclosingName(name);
714 
715   mode_ = PARSE_EAGERLY;
716 
717   // Place holder for the result.
718   FunctionLiteral* result = NULL;
719 
720   {
721     // Parse the function literal.
722     Handle<String> no_name = isolate()->factory()->empty_symbol();
723     Scope* scope = NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with());
724     if (!info->closure().is_null()) {
725       scope = Scope::DeserializeScopeChain(info, scope);
726     }
727     LexicalScope lexical_scope(this, scope, isolate());
728 
729     if (shared_info->strict_mode()) {
730       top_scope_->EnableStrictMode();
731     }
732 
733     FunctionLiteralType type =
734         shared_info->is_expression() ? EXPRESSION : DECLARATION;
735     bool ok = true;
736     result = ParseFunctionLiteral(name,
737                                   false,    // Strict mode name already checked.
738                                   RelocInfo::kNoPosition, type, &ok);
739     // Make sure the results agree.
740     ASSERT(ok == (result != NULL));
741   }
742 
743   // Make sure the target stack is empty.
744   ASSERT(target_stack_ == NULL);
745 
746   // If there was a stack overflow we have to get rid of AST and it is
747   // not safe to do before scope has been deleted.
748   if (result == NULL) {
749     zone_scope->DeleteOnExit();
750     if (stack_overflow_) isolate()->StackOverflow();
751   } else {
752     Handle<String> inferred_name(shared_info->inferred_name());
753     result->set_inferred_name(inferred_name);
754   }
755   return result;
756 }
757 
758 
GetSymbol(bool * ok)759 Handle<String> Parser::GetSymbol(bool* ok) {
760   int symbol_id = -1;
761   if (pre_data() != NULL) {
762     symbol_id = pre_data()->GetSymbolIdentifier();
763   }
764   return LookupSymbol(symbol_id);
765 }
766 
767 
ReportMessage(const char * type,Vector<const char * > args)768 void Parser::ReportMessage(const char* type, Vector<const char*> args) {
769   Scanner::Location source_location = scanner().location();
770   ReportMessageAt(source_location, type, args);
771 }
772 
773 
ReportMessageAt(Scanner::Location source_location,const char * type,Vector<const char * > args)774 void Parser::ReportMessageAt(Scanner::Location source_location,
775                              const char* type,
776                              Vector<const char*> args) {
777   MessageLocation location(script_,
778                            source_location.beg_pos,
779                            source_location.end_pos);
780   Factory* factory = isolate()->factory();
781   Handle<FixedArray> elements = factory->NewFixedArray(args.length());
782   for (int i = 0; i < args.length(); i++) {
783     Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i]));
784     elements->set(i, *arg_string);
785   }
786   Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
787   Handle<Object> result = factory->NewSyntaxError(type, array);
788   isolate()->Throw(*result, &location);
789 }
790 
791 
ReportMessageAt(Scanner::Location source_location,const char * type,Vector<Handle<String>> args)792 void Parser::ReportMessageAt(Scanner::Location source_location,
793                              const char* type,
794                              Vector<Handle<String> > args) {
795   MessageLocation location(script_,
796                            source_location.beg_pos,
797                            source_location.end_pos);
798   Factory* factory = isolate()->factory();
799   Handle<FixedArray> elements = factory->NewFixedArray(args.length());
800   for (int i = 0; i < args.length(); i++) {
801     elements->set(i, *args[i]);
802   }
803   Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
804   Handle<Object> result = factory->NewSyntaxError(type, array);
805   isolate()->Throw(*result, &location);
806 }
807 
808 
809 // Base class containing common code for the different finder classes used by
810 // the parser.
811 class ParserFinder {
812  protected:
ParserFinder()813   ParserFinder() {}
AsAssignment(Statement * stat)814   static Assignment* AsAssignment(Statement* stat) {
815     if (stat == NULL) return NULL;
816     ExpressionStatement* exp_stat = stat->AsExpressionStatement();
817     if (exp_stat == NULL) return NULL;
818     return exp_stat->expression()->AsAssignment();
819   }
820 };
821 
822 
823 // An InitializationBlockFinder finds and marks sequences of statements of the
824 // form expr.a = ...; expr.b = ...; etc.
825 class InitializationBlockFinder : public ParserFinder {
826  public:
InitializationBlockFinder()827   InitializationBlockFinder()
828     : first_in_block_(NULL), last_in_block_(NULL), block_size_(0) {}
829 
~InitializationBlockFinder()830   ~InitializationBlockFinder() {
831     if (InBlock()) EndBlock();
832   }
833 
Update(Statement * stat)834   void Update(Statement* stat) {
835     Assignment* assignment = AsAssignment(stat);
836     if (InBlock()) {
837       if (BlockContinues(assignment)) {
838         UpdateBlock(assignment);
839       } else {
840         EndBlock();
841       }
842     }
843     if (!InBlock() && (assignment != NULL) &&
844         (assignment->op() == Token::ASSIGN)) {
845       StartBlock(assignment);
846     }
847   }
848 
849  private:
850   // The minimum number of contiguous assignment that will
851   // be treated as an initialization block. Benchmarks show that
852   // the overhead exceeds the savings below this limit.
853   static const int kMinInitializationBlock = 3;
854 
855   // Returns true if the expressions appear to denote the same object.
856   // In the context of initialization blocks, we only consider expressions
857   // of the form 'expr.x' or expr["x"].
SameObject(Expression * e1,Expression * e2)858   static bool SameObject(Expression* e1, Expression* e2) {
859     VariableProxy* v1 = e1->AsVariableProxy();
860     VariableProxy* v2 = e2->AsVariableProxy();
861     if (v1 != NULL && v2 != NULL) {
862       return v1->name()->Equals(*v2->name());
863     }
864     Property* p1 = e1->AsProperty();
865     Property* p2 = e2->AsProperty();
866     if ((p1 == NULL) || (p2 == NULL)) return false;
867     Literal* key1 = p1->key()->AsLiteral();
868     Literal* key2 = p2->key()->AsLiteral();
869     if ((key1 == NULL) || (key2 == NULL)) return false;
870     if (!key1->handle()->IsString() || !key2->handle()->IsString()) {
871       return false;
872     }
873     String* name1 = String::cast(*key1->handle());
874     String* name2 = String::cast(*key2->handle());
875     if (!name1->Equals(name2)) return false;
876     return SameObject(p1->obj(), p2->obj());
877   }
878 
879   // Returns true if the expressions appear to denote different properties
880   // of the same object.
PropertyOfSameObject(Expression * e1,Expression * e2)881   static bool PropertyOfSameObject(Expression* e1, Expression* e2) {
882     Property* p1 = e1->AsProperty();
883     Property* p2 = e2->AsProperty();
884     if ((p1 == NULL) || (p2 == NULL)) return false;
885     return SameObject(p1->obj(), p2->obj());
886   }
887 
BlockContinues(Assignment * assignment)888   bool BlockContinues(Assignment* assignment) {
889     if ((assignment == NULL) || (first_in_block_ == NULL)) return false;
890     if (assignment->op() != Token::ASSIGN) return false;
891     return PropertyOfSameObject(first_in_block_->target(),
892                                 assignment->target());
893   }
894 
StartBlock(Assignment * assignment)895   void StartBlock(Assignment* assignment) {
896     first_in_block_ = assignment;
897     last_in_block_ = assignment;
898     block_size_ = 1;
899   }
900 
UpdateBlock(Assignment * assignment)901   void UpdateBlock(Assignment* assignment) {
902     last_in_block_ = assignment;
903     ++block_size_;
904   }
905 
EndBlock()906   void EndBlock() {
907     if (block_size_ >= kMinInitializationBlock) {
908       first_in_block_->mark_block_start();
909       last_in_block_->mark_block_end();
910     }
911     last_in_block_ = first_in_block_ = NULL;
912     block_size_ = 0;
913   }
914 
InBlock()915   bool InBlock() { return first_in_block_ != NULL; }
916 
917   Assignment* first_in_block_;
918   Assignment* last_in_block_;
919   int block_size_;
920 
921   DISALLOW_COPY_AND_ASSIGN(InitializationBlockFinder);
922 };
923 
924 
925 // A ThisNamedPropertyAssigmentFinder finds and marks statements of the form
926 // this.x = ...;, where x is a named property. It also determines whether a
927 // function contains only assignments of this type.
928 class ThisNamedPropertyAssigmentFinder : public ParserFinder {
929  public:
ThisNamedPropertyAssigmentFinder(Isolate * isolate)930   explicit ThisNamedPropertyAssigmentFinder(Isolate* isolate)
931       : isolate_(isolate),
932         only_simple_this_property_assignments_(true),
933         names_(NULL),
934         assigned_arguments_(NULL),
935         assigned_constants_(NULL) {}
936 
Update(Scope * scope,Statement * stat)937   void Update(Scope* scope, Statement* stat) {
938     // Bail out if function already has property assignment that are
939     // not simple this property assignments.
940     if (!only_simple_this_property_assignments_) {
941       return;
942     }
943 
944     // Check whether this statement is of the form this.x = ...;
945     Assignment* assignment = AsAssignment(stat);
946     if (IsThisPropertyAssignment(assignment)) {
947       HandleThisPropertyAssignment(scope, assignment);
948     } else {
949       only_simple_this_property_assignments_ = false;
950     }
951   }
952 
953   // Returns whether only statements of the form this.x = y; where y is either a
954   // constant or a function argument was encountered.
only_simple_this_property_assignments()955   bool only_simple_this_property_assignments() {
956     return only_simple_this_property_assignments_;
957   }
958 
959   // Returns a fixed array containing three elements for each assignment of the
960   // form this.x = y;
GetThisPropertyAssignments()961   Handle<FixedArray> GetThisPropertyAssignments() {
962     if (names_ == NULL) {
963       return isolate_->factory()->empty_fixed_array();
964     }
965     ASSERT(names_ != NULL);
966     ASSERT(assigned_arguments_ != NULL);
967     ASSERT_EQ(names_->length(), assigned_arguments_->length());
968     ASSERT_EQ(names_->length(), assigned_constants_->length());
969     Handle<FixedArray> assignments =
970         isolate_->factory()->NewFixedArray(names_->length() * 3);
971     for (int i = 0; i < names_->length(); i++) {
972       assignments->set(i * 3, *names_->at(i));
973       assignments->set(i * 3 + 1, Smi::FromInt(assigned_arguments_->at(i)));
974       assignments->set(i * 3 + 2, *assigned_constants_->at(i));
975     }
976     return assignments;
977   }
978 
979  private:
IsThisPropertyAssignment(Assignment * assignment)980   bool IsThisPropertyAssignment(Assignment* assignment) {
981     if (assignment != NULL) {
982       Property* property = assignment->target()->AsProperty();
983       return assignment->op() == Token::ASSIGN
984              && property != NULL
985              && property->obj()->AsVariableProxy() != NULL
986              && property->obj()->AsVariableProxy()->is_this();
987     }
988     return false;
989   }
990 
HandleThisPropertyAssignment(Scope * scope,Assignment * assignment)991   void HandleThisPropertyAssignment(Scope* scope, Assignment* assignment) {
992     // Check that the property assigned to is a named property, which is not
993     // __proto__.
994     Property* property = assignment->target()->AsProperty();
995     ASSERT(property != NULL);
996     Literal* literal = property->key()->AsLiteral();
997     uint32_t dummy;
998     if (literal != NULL &&
999         literal->handle()->IsString() &&
1000         !String::cast(*(literal->handle()))->Equals(
1001             isolate_->heap()->Proto_symbol()) &&
1002         !String::cast(*(literal->handle()))->AsArrayIndex(&dummy)) {
1003       Handle<String> key = Handle<String>::cast(literal->handle());
1004 
1005       // Check whether the value assigned is either a constant or matches the
1006       // name of one of the arguments to the function.
1007       if (assignment->value()->AsLiteral() != NULL) {
1008         // Constant assigned.
1009         Literal* literal = assignment->value()->AsLiteral();
1010         AssignmentFromConstant(key, literal->handle());
1011         return;
1012       } else if (assignment->value()->AsVariableProxy() != NULL) {
1013         // Variable assigned.
1014         Handle<String> name =
1015             assignment->value()->AsVariableProxy()->name();
1016         // Check whether the variable assigned matches an argument name.
1017         for (int i = 0; i < scope->num_parameters(); i++) {
1018           if (*scope->parameter(i)->name() == *name) {
1019             // Assigned from function argument.
1020             AssignmentFromParameter(key, i);
1021             return;
1022           }
1023         }
1024       }
1025     }
1026     // It is not a simple "this.x = value;" assignment with a constant
1027     // or parameter value.
1028     AssignmentFromSomethingElse();
1029   }
1030 
AssignmentFromParameter(Handle<String> name,int index)1031   void AssignmentFromParameter(Handle<String> name, int index) {
1032     EnsureAllocation();
1033     names_->Add(name);
1034     assigned_arguments_->Add(index);
1035     assigned_constants_->Add(isolate_->factory()->undefined_value());
1036   }
1037 
AssignmentFromConstant(Handle<String> name,Handle<Object> value)1038   void AssignmentFromConstant(Handle<String> name, Handle<Object> value) {
1039     EnsureAllocation();
1040     names_->Add(name);
1041     assigned_arguments_->Add(-1);
1042     assigned_constants_->Add(value);
1043   }
1044 
AssignmentFromSomethingElse()1045   void AssignmentFromSomethingElse() {
1046     // The this assignment is not a simple one.
1047     only_simple_this_property_assignments_ = false;
1048   }
1049 
EnsureAllocation()1050   void EnsureAllocation() {
1051     if (names_ == NULL) {
1052       ASSERT(assigned_arguments_ == NULL);
1053       ASSERT(assigned_constants_ == NULL);
1054       names_ = new ZoneStringList(4);
1055       assigned_arguments_ = new ZoneList<int>(4);
1056       assigned_constants_ = new ZoneObjectList(4);
1057     }
1058   }
1059 
1060   Isolate* isolate_;
1061   bool only_simple_this_property_assignments_;
1062   ZoneStringList* names_;
1063   ZoneList<int>* assigned_arguments_;
1064   ZoneObjectList* assigned_constants_;
1065 };
1066 
1067 
ParseSourceElements(ZoneList<Statement * > * processor,int end_token,bool * ok)1068 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
1069                                   int end_token,
1070                                   bool* ok) {
1071   // SourceElements ::
1072   //   (Statement)* <end_token>
1073 
1074   // Allocate a target stack to use for this set of source
1075   // elements. This way, all scripts and functions get their own
1076   // target stack thus avoiding illegal breaks and continues across
1077   // functions.
1078   TargetScope scope(&this->target_stack_);
1079 
1080   ASSERT(processor != NULL);
1081   InitializationBlockFinder block_finder;
1082   ThisNamedPropertyAssigmentFinder this_property_assignment_finder(isolate());
1083   bool directive_prologue = true;     // Parsing directive prologue.
1084 
1085   while (peek() != end_token) {
1086     if (directive_prologue && peek() != Token::STRING) {
1087       directive_prologue = false;
1088     }
1089 
1090     Scanner::Location token_loc = scanner().peek_location();
1091 
1092     Statement* stat;
1093     if (peek() == Token::FUNCTION) {
1094       // FunctionDeclaration is only allowed in the context of SourceElements
1095       // (Ecma 262 5th Edition, clause 14):
1096       // SourceElement:
1097       //    Statement
1098       //    FunctionDeclaration
1099       // Common language extension is to allow function declaration in place
1100       // of any statement. This language extension is disabled in strict mode.
1101       stat = ParseFunctionDeclaration(CHECK_OK);
1102     } else {
1103       stat = ParseStatement(NULL, CHECK_OK);
1104     }
1105 
1106     if (stat == NULL || stat->IsEmpty()) {
1107       directive_prologue = false;   // End of directive prologue.
1108       continue;
1109     }
1110 
1111     if (directive_prologue) {
1112       // A shot at a directive.
1113       ExpressionStatement *e_stat;
1114       Literal *literal;
1115       // Still processing directive prologue?
1116       if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1117           (literal = e_stat->expression()->AsLiteral()) != NULL &&
1118           literal->handle()->IsString()) {
1119         Handle<String> directive = Handle<String>::cast(literal->handle());
1120 
1121         // Check "use strict" directive (ES5 14.1).
1122         if (!top_scope_->is_strict_mode() &&
1123             directive->Equals(isolate()->heap()->use_strict()) &&
1124             token_loc.end_pos - token_loc.beg_pos ==
1125               isolate()->heap()->use_strict()->length() + 2) {
1126           top_scope_->EnableStrictMode();
1127           // "use strict" is the only directive for now.
1128           directive_prologue = false;
1129         }
1130       } else {
1131         // End of the directive prologue.
1132         directive_prologue = false;
1133       }
1134     }
1135 
1136     // We find and mark the initialization blocks on top level code only.
1137     // This is because the optimization prevents reuse of the map transitions,
1138     // so it should be used only for code that will only be run once.
1139     if (top_scope_->is_global_scope()) {
1140       block_finder.Update(stat);
1141     }
1142     // Find and mark all assignments to named properties in this (this.x =)
1143     if (top_scope_->is_function_scope()) {
1144       this_property_assignment_finder.Update(top_scope_, stat);
1145     }
1146     processor->Add(stat);
1147   }
1148 
1149   // Propagate the collected information on this property assignments.
1150   if (top_scope_->is_function_scope()) {
1151     bool only_simple_this_property_assignments =
1152         this_property_assignment_finder.only_simple_this_property_assignments()
1153         && top_scope_->declarations()->length() == 0;
1154     if (only_simple_this_property_assignments) {
1155       lexical_scope_->SetThisPropertyAssignmentInfo(
1156           only_simple_this_property_assignments,
1157           this_property_assignment_finder.GetThisPropertyAssignments());
1158     }
1159   }
1160   return 0;
1161 }
1162 
1163 
ParseStatement(ZoneStringList * labels,bool * ok)1164 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
1165   // Statement ::
1166   //   Block
1167   //   VariableStatement
1168   //   EmptyStatement
1169   //   ExpressionStatement
1170   //   IfStatement
1171   //   IterationStatement
1172   //   ContinueStatement
1173   //   BreakStatement
1174   //   ReturnStatement
1175   //   WithStatement
1176   //   LabelledStatement
1177   //   SwitchStatement
1178   //   ThrowStatement
1179   //   TryStatement
1180   //   DebuggerStatement
1181 
1182   // Note: Since labels can only be used by 'break' and 'continue'
1183   // statements, which themselves are only valid within blocks,
1184   // iterations or 'switch' statements (i.e., BreakableStatements),
1185   // labels can be simply ignored in all other cases; except for
1186   // trivial labeled break statements 'label: break label' which is
1187   // parsed into an empty statement.
1188 
1189   // Keep the source position of the statement
1190   int statement_pos = scanner().peek_location().beg_pos;
1191   Statement* stmt = NULL;
1192   switch (peek()) {
1193     case Token::LBRACE:
1194       return ParseBlock(labels, ok);
1195 
1196     case Token::CONST:  // fall through
1197     case Token::VAR:
1198       stmt = ParseVariableStatement(ok);
1199       break;
1200 
1201     case Token::SEMICOLON:
1202       Next();
1203       return EmptyStatement();
1204 
1205     case Token::IF:
1206       stmt = ParseIfStatement(labels, ok);
1207       break;
1208 
1209     case Token::DO:
1210       stmt = ParseDoWhileStatement(labels, ok);
1211       break;
1212 
1213     case Token::WHILE:
1214       stmt = ParseWhileStatement(labels, ok);
1215       break;
1216 
1217     case Token::FOR:
1218       stmt = ParseForStatement(labels, ok);
1219       break;
1220 
1221     case Token::CONTINUE:
1222       stmt = ParseContinueStatement(ok);
1223       break;
1224 
1225     case Token::BREAK:
1226       stmt = ParseBreakStatement(labels, ok);
1227       break;
1228 
1229     case Token::RETURN:
1230       stmt = ParseReturnStatement(ok);
1231       break;
1232 
1233     case Token::WITH:
1234       stmt = ParseWithStatement(labels, ok);
1235       break;
1236 
1237     case Token::SWITCH:
1238       stmt = ParseSwitchStatement(labels, ok);
1239       break;
1240 
1241     case Token::THROW:
1242       stmt = ParseThrowStatement(ok);
1243       break;
1244 
1245     case Token::TRY: {
1246       // NOTE: It is somewhat complicated to have labels on
1247       // try-statements. When breaking out of a try-finally statement,
1248       // one must take great care not to treat it as a
1249       // fall-through. It is much easier just to wrap the entire
1250       // try-statement in a statement block and put the labels there
1251       Block* result = new(zone()) Block(labels, 1, false);
1252       Target target(&this->target_stack_, result);
1253       TryStatement* statement = ParseTryStatement(CHECK_OK);
1254       if (statement) {
1255         statement->set_statement_pos(statement_pos);
1256       }
1257       if (result) result->AddStatement(statement);
1258       return result;
1259     }
1260 
1261     case Token::FUNCTION: {
1262       // In strict mode, FunctionDeclaration is only allowed in the context
1263       // of SourceElements.
1264       if (top_scope_->is_strict_mode()) {
1265         ReportMessageAt(scanner().peek_location(), "strict_function",
1266                         Vector<const char*>::empty());
1267         *ok = false;
1268         return NULL;
1269       }
1270       return ParseFunctionDeclaration(ok);
1271     }
1272 
1273     case Token::NATIVE:
1274       return ParseNativeDeclaration(ok);
1275 
1276     case Token::DEBUGGER:
1277       stmt = ParseDebuggerStatement(ok);
1278       break;
1279 
1280     default:
1281       stmt = ParseExpressionOrLabelledStatement(labels, ok);
1282   }
1283 
1284   // Store the source position of the statement
1285   if (stmt != NULL) stmt->set_statement_pos(statement_pos);
1286   return stmt;
1287 }
1288 
1289 
Declare(Handle<String> name,Variable::Mode mode,FunctionLiteral * fun,bool resolve,bool * ok)1290 VariableProxy* Parser::Declare(Handle<String> name,
1291                                Variable::Mode mode,
1292                                FunctionLiteral* fun,
1293                                bool resolve,
1294                                bool* ok) {
1295   Variable* var = NULL;
1296   // If we are inside a function, a declaration of a variable
1297   // is a truly local variable, and the scope of the variable
1298   // is always the function scope.
1299 
1300   // If a function scope exists, then we can statically declare this
1301   // variable and also set its mode. In any case, a Declaration node
1302   // will be added to the scope so that the declaration can be added
1303   // to the corresponding activation frame at runtime if necessary.
1304   // For instance declarations inside an eval scope need to be added
1305   // to the calling function context.
1306   if (top_scope_->is_function_scope()) {
1307     // Declare the variable in the function scope.
1308     var = top_scope_->LocalLookup(name);
1309     if (var == NULL) {
1310       // Declare the name.
1311       var = top_scope_->DeclareLocal(name, mode, Scope::VAR_OR_CONST);
1312     } else {
1313       // The name was declared before; check for conflicting
1314       // re-declarations. If the previous declaration was a const or the
1315       // current declaration is a const then we have a conflict. There is
1316       // similar code in runtime.cc in the Declare functions.
1317       if ((mode == Variable::CONST) || (var->mode() == Variable::CONST)) {
1318         // We only have vars and consts in declarations.
1319         ASSERT(var->mode() == Variable::VAR ||
1320                var->mode() == Variable::CONST);
1321         const char* type = (var->mode() == Variable::VAR) ? "var" : "const";
1322         Handle<String> type_string =
1323             isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED);
1324         Expression* expression =
1325             NewThrowTypeError(isolate()->factory()->redeclaration_symbol(),
1326                               type_string, name);
1327         top_scope_->SetIllegalRedeclaration(expression);
1328       }
1329     }
1330   }
1331 
1332   // We add a declaration node for every declaration. The compiler
1333   // will only generate code if necessary. In particular, declarations
1334   // for inner local variables that do not represent functions won't
1335   // result in any generated code.
1336   //
1337   // Note that we always add an unresolved proxy even if it's not
1338   // used, simply because we don't know in this method (w/o extra
1339   // parameters) if the proxy is needed or not. The proxy will be
1340   // bound during variable resolution time unless it was pre-bound
1341   // below.
1342   //
1343   // WARNING: This will lead to multiple declaration nodes for the
1344   // same variable if it is declared several times. This is not a
1345   // semantic issue as long as we keep the source order, but it may be
1346   // a performance issue since it may lead to repeated
1347   // Runtime::DeclareContextSlot() calls.
1348   VariableProxy* proxy = top_scope_->NewUnresolved(name, inside_with());
1349   top_scope_->AddDeclaration(new(zone()) Declaration(proxy, mode, fun));
1350 
1351   // For global const variables we bind the proxy to a variable.
1352   if (mode == Variable::CONST && top_scope_->is_global_scope()) {
1353     ASSERT(resolve);  // should be set by all callers
1354     Variable::Kind kind = Variable::NORMAL;
1355     var = new(zone()) Variable(top_scope_, name, Variable::CONST, true, kind);
1356   }
1357 
1358   // If requested and we have a local variable, bind the proxy to the variable
1359   // at parse-time. This is used for functions (and consts) declared inside
1360   // statements: the corresponding function (or const) variable must be in the
1361   // function scope and not a statement-local scope, e.g. as provided with a
1362   // 'with' statement:
1363   //
1364   //   with (obj) {
1365   //     function f() {}
1366   //   }
1367   //
1368   // which is translated into:
1369   //
1370   //   with (obj) {
1371   //     // in this case this is not: 'var f; f = function () {};'
1372   //     var f = function () {};
1373   //   }
1374   //
1375   // Note that if 'f' is accessed from inside the 'with' statement, it
1376   // will be allocated in the context (because we must be able to look
1377   // it up dynamically) but it will also be accessed statically, i.e.,
1378   // with a context slot index and a context chain length for this
1379   // initialization code. Thus, inside the 'with' statement, we need
1380   // both access to the static and the dynamic context chain; the
1381   // runtime needs to provide both.
1382   if (resolve && var != NULL) proxy->BindTo(var);
1383 
1384   return proxy;
1385 }
1386 
1387 
1388 // Language extension which is only enabled for source files loaded
1389 // through the API's extension mechanism.  A native function
1390 // declaration is resolved by looking up the function through a
1391 // callback provided by the extension.
ParseNativeDeclaration(bool * ok)1392 Statement* Parser::ParseNativeDeclaration(bool* ok) {
1393   if (extension_ == NULL) {
1394     ReportUnexpectedToken(Token::NATIVE);
1395     *ok = false;
1396     return NULL;
1397   }
1398 
1399   Expect(Token::NATIVE, CHECK_OK);
1400   Expect(Token::FUNCTION, CHECK_OK);
1401   Handle<String> name = ParseIdentifier(CHECK_OK);
1402   Expect(Token::LPAREN, CHECK_OK);
1403   bool done = (peek() == Token::RPAREN);
1404   while (!done) {
1405     ParseIdentifier(CHECK_OK);
1406     done = (peek() == Token::RPAREN);
1407     if (!done) {
1408       Expect(Token::COMMA, CHECK_OK);
1409     }
1410   }
1411   Expect(Token::RPAREN, CHECK_OK);
1412   Expect(Token::SEMICOLON, CHECK_OK);
1413 
1414   // Make sure that the function containing the native declaration
1415   // isn't lazily compiled. The extension structures are only
1416   // accessible while parsing the first time not when reparsing
1417   // because of lazy compilation.
1418   top_scope_->ForceEagerCompilation();
1419 
1420   // Compute the function template for the native function.
1421   v8::Handle<v8::FunctionTemplate> fun_template =
1422       extension_->GetNativeFunction(v8::Utils::ToLocal(name));
1423   ASSERT(!fun_template.IsEmpty());
1424 
1425   // Instantiate the function and create a shared function info from it.
1426   Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->GetFunction());
1427   const int literals = fun->NumberOfLiterals();
1428   Handle<Code> code = Handle<Code>(fun->shared()->code());
1429   Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
1430   Handle<SharedFunctionInfo> shared =
1431       isolate()->factory()->NewSharedFunctionInfo(name, literals, code,
1432           Handle<SerializedScopeInfo>(fun->shared()->scope_info()));
1433   shared->set_construct_stub(*construct_stub);
1434 
1435   // Copy the function data to the shared function info.
1436   shared->set_function_data(fun->shared()->function_data());
1437   int parameters = fun->shared()->formal_parameter_count();
1438   shared->set_formal_parameter_count(parameters);
1439 
1440   // TODO(1240846): It's weird that native function declarations are
1441   // introduced dynamically when we meet their declarations, whereas
1442   // other functions are setup when entering the surrounding scope.
1443   SharedFunctionInfoLiteral* lit =
1444       new(zone()) SharedFunctionInfoLiteral(shared);
1445   VariableProxy* var = Declare(name, Variable::VAR, NULL, true, CHECK_OK);
1446   return new(zone()) ExpressionStatement(new(zone()) Assignment(
1447       Token::INIT_VAR, var, lit, RelocInfo::kNoPosition));
1448 }
1449 
1450 
ParseFunctionDeclaration(bool * ok)1451 Statement* Parser::ParseFunctionDeclaration(bool* ok) {
1452   // FunctionDeclaration ::
1453   //   'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
1454   Expect(Token::FUNCTION, CHECK_OK);
1455   int function_token_position = scanner().location().beg_pos;
1456   bool is_reserved = false;
1457   Handle<String> name = ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK);
1458   FunctionLiteral* fun = ParseFunctionLiteral(name,
1459                                               is_reserved,
1460                                               function_token_position,
1461                                               DECLARATION,
1462                                               CHECK_OK);
1463   // Even if we're not at the top-level of the global or a function
1464   // scope, we treat is as such and introduce the function with it's
1465   // initial value upon entering the corresponding scope.
1466   Declare(name, Variable::VAR, fun, true, CHECK_OK);
1467   return EmptyStatement();
1468 }
1469 
1470 
ParseBlock(ZoneStringList * labels,bool * ok)1471 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) {
1472   // Block ::
1473   //   '{' Statement* '}'
1474 
1475   // Note that a Block does not introduce a new execution scope!
1476   // (ECMA-262, 3rd, 12.2)
1477   //
1478   // Construct block expecting 16 statements.
1479   Block* result = new(zone()) Block(labels, 16, false);
1480   Target target(&this->target_stack_, result);
1481   Expect(Token::LBRACE, CHECK_OK);
1482   while (peek() != Token::RBRACE) {
1483     Statement* stat = ParseStatement(NULL, CHECK_OK);
1484     if (stat && !stat->IsEmpty()) result->AddStatement(stat);
1485   }
1486   Expect(Token::RBRACE, CHECK_OK);
1487   return result;
1488 }
1489 
1490 
ParseVariableStatement(bool * ok)1491 Block* Parser::ParseVariableStatement(bool* ok) {
1492   // VariableStatement ::
1493   //   VariableDeclarations ';'
1494 
1495   Expression* dummy;  // to satisfy the ParseVariableDeclarations() signature
1496   Block* result = ParseVariableDeclarations(true, &dummy, CHECK_OK);
1497   ExpectSemicolon(CHECK_OK);
1498   return result;
1499 }
1500 
1501 
IsEvalOrArguments(Handle<String> string)1502 bool Parser::IsEvalOrArguments(Handle<String> string) {
1503   return string.is_identical_to(isolate()->factory()->eval_symbol()) ||
1504       string.is_identical_to(isolate()->factory()->arguments_symbol());
1505 }
1506 
1507 
1508 // If the variable declaration declares exactly one non-const
1509 // variable, then *var is set to that variable. In all other cases,
1510 // *var is untouched; in particular, it is the caller's responsibility
1511 // to initialize it properly. This mechanism is used for the parsing
1512 // of 'for-in' loops.
ParseVariableDeclarations(bool accept_IN,Expression ** var,bool * ok)1513 Block* Parser::ParseVariableDeclarations(bool accept_IN,
1514                                          Expression** var,
1515                                          bool* ok) {
1516   // VariableDeclarations ::
1517   //   ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
1518 
1519   Variable::Mode mode = Variable::VAR;
1520   bool is_const = false;
1521   if (peek() == Token::VAR) {
1522     Consume(Token::VAR);
1523   } else if (peek() == Token::CONST) {
1524     Consume(Token::CONST);
1525     if (top_scope_->is_strict_mode()) {
1526       ReportMessage("strict_const", Vector<const char*>::empty());
1527       *ok = false;
1528       return NULL;
1529     }
1530     mode = Variable::CONST;
1531     is_const = true;
1532   } else {
1533     UNREACHABLE();  // by current callers
1534   }
1535 
1536   // The scope of a variable/const declared anywhere inside a function
1537   // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
1538   // transform a source-level variable/const declaration into a (Function)
1539   // Scope declaration, and rewrite the source-level initialization into an
1540   // assignment statement. We use a block to collect multiple assignments.
1541   //
1542   // We mark the block as initializer block because we don't want the
1543   // rewriter to add a '.result' assignment to such a block (to get compliant
1544   // behavior for code such as print(eval('var x = 7')), and for cosmetic
1545   // reasons when pretty-printing. Also, unless an assignment (initialization)
1546   // is inside an initializer block, it is ignored.
1547   //
1548   // Create new block with one expected declaration.
1549   Block* block = new(zone()) Block(NULL, 1, true);
1550   VariableProxy* last_var = NULL;  // the last variable declared
1551   int nvars = 0;  // the number of variables declared
1552   do {
1553     if (fni_ != NULL) fni_->Enter();
1554 
1555     // Parse variable name.
1556     if (nvars > 0) Consume(Token::COMMA);
1557     Handle<String> name = ParseIdentifier(CHECK_OK);
1558     if (fni_ != NULL) fni_->PushVariableName(name);
1559 
1560     // Strict mode variables may not be named eval or arguments
1561     if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) {
1562       ReportMessage("strict_var_name", Vector<const char*>::empty());
1563       *ok = false;
1564       return NULL;
1565     }
1566 
1567     // Declare variable.
1568     // Note that we *always* must treat the initial value via a separate init
1569     // assignment for variables and constants because the value must be assigned
1570     // when the variable is encountered in the source. But the variable/constant
1571     // is declared (and set to 'undefined') upon entering the function within
1572     // which the variable or constant is declared. Only function variables have
1573     // an initial value in the declaration (because they are initialized upon
1574     // entering the function).
1575     //
1576     // If we have a const declaration, in an inner scope, the proxy is always
1577     // bound to the declared variable (independent of possibly surrounding with
1578     // statements).
1579     last_var = Declare(name, mode, NULL,
1580                        is_const /* always bound for CONST! */,
1581                        CHECK_OK);
1582     nvars++;
1583     if (top_scope_->num_var_or_const() > kMaxNumFunctionLocals) {
1584       ReportMessageAt(scanner().location(), "too_many_variables",
1585                       Vector<const char*>::empty());
1586       *ok = false;
1587       return NULL;
1588     }
1589 
1590     // Parse initialization expression if present and/or needed. A
1591     // declaration of the form:
1592     //
1593     //    var v = x;
1594     //
1595     // is syntactic sugar for:
1596     //
1597     //    var v; v = x;
1598     //
1599     // In particular, we need to re-lookup 'v' as it may be a
1600     // different 'v' than the 'v' in the declaration (if we are inside
1601     // a 'with' statement that makes a object property with name 'v'
1602     // visible).
1603     //
1604     // However, note that const declarations are different! A const
1605     // declaration of the form:
1606     //
1607     //   const c = x;
1608     //
1609     // is *not* syntactic sugar for:
1610     //
1611     //   const c; c = x;
1612     //
1613     // The "variable" c initialized to x is the same as the declared
1614     // one - there is no re-lookup (see the last parameter of the
1615     // Declare() call above).
1616 
1617     Expression* value = NULL;
1618     int position = -1;
1619     if (peek() == Token::ASSIGN) {
1620       Expect(Token::ASSIGN, CHECK_OK);
1621       position = scanner().location().beg_pos;
1622       value = ParseAssignmentExpression(accept_IN, CHECK_OK);
1623       // Don't infer if it is "a = function(){...}();"-like expression.
1624       if (fni_ != NULL && value->AsCall() == NULL) fni_->Infer();
1625     }
1626 
1627     // Make sure that 'const c' actually initializes 'c' to undefined
1628     // even though it seems like a stupid thing to do.
1629     if (value == NULL && is_const) {
1630       value = GetLiteralUndefined();
1631     }
1632 
1633     // Global variable declarations must be compiled in a specific
1634     // way. When the script containing the global variable declaration
1635     // is entered, the global variable must be declared, so that if it
1636     // doesn't exist (not even in a prototype of the global object) it
1637     // gets created with an initial undefined value. This is handled
1638     // by the declarations part of the function representing the
1639     // top-level global code; see Runtime::DeclareGlobalVariable. If
1640     // it already exists (in the object or in a prototype), it is
1641     // *not* touched until the variable declaration statement is
1642     // executed.
1643     //
1644     // Executing the variable declaration statement will always
1645     // guarantee to give the global object a "local" variable; a
1646     // variable defined in the global object and not in any
1647     // prototype. This way, global variable declarations can shadow
1648     // properties in the prototype chain, but only after the variable
1649     // declaration statement has been executed. This is important in
1650     // browsers where the global object (window) has lots of
1651     // properties defined in prototype objects.
1652 
1653     if (top_scope_->is_global_scope()) {
1654       // Compute the arguments for the runtime call.
1655       ZoneList<Expression*>* arguments = new ZoneList<Expression*>(3);
1656       // We have at least 1 parameter.
1657       arguments->Add(new(zone()) Literal(name));
1658       CallRuntime* initialize;
1659 
1660       if (is_const) {
1661         arguments->Add(value);
1662         value = NULL;  // zap the value to avoid the unnecessary assignment
1663 
1664         // Construct the call to Runtime_InitializeConstGlobal
1665         // and add it to the initialization statement block.
1666         // Note that the function does different things depending on
1667         // the number of arguments (1 or 2).
1668         initialize =
1669             new(zone()) CallRuntime(
1670               isolate()->factory()->InitializeConstGlobal_symbol(),
1671               Runtime::FunctionForId(Runtime::kInitializeConstGlobal),
1672               arguments);
1673       } else {
1674         // Add strict mode.
1675         // We may want to pass singleton to avoid Literal allocations.
1676         arguments->Add(NewNumberLiteral(
1677             top_scope_->is_strict_mode() ? kStrictMode : kNonStrictMode));
1678 
1679         // Be careful not to assign a value to the global variable if
1680         // we're in a with. The initialization value should not
1681         // necessarily be stored in the global object in that case,
1682         // which is why we need to generate a separate assignment node.
1683         if (value != NULL && !inside_with()) {
1684           arguments->Add(value);
1685           value = NULL;  // zap the value to avoid the unnecessary assignment
1686         }
1687 
1688         // Construct the call to Runtime_InitializeVarGlobal
1689         // and add it to the initialization statement block.
1690         // Note that the function does different things depending on
1691         // the number of arguments (2 or 3).
1692         initialize =
1693             new(zone()) CallRuntime(
1694               isolate()->factory()->InitializeVarGlobal_symbol(),
1695               Runtime::FunctionForId(Runtime::kInitializeVarGlobal),
1696               arguments);
1697       }
1698 
1699       block->AddStatement(new(zone()) ExpressionStatement(initialize));
1700     }
1701 
1702     // Add an assignment node to the initialization statement block if
1703     // we still have a pending initialization value. We must distinguish
1704     // between variables and constants: Variable initializations are simply
1705     // assignments (with all the consequences if they are inside a 'with'
1706     // statement - they may change a 'with' object property). Constant
1707     // initializations always assign to the declared constant which is
1708     // always at the function scope level. This is only relevant for
1709     // dynamically looked-up variables and constants (the start context
1710     // for constant lookups is always the function context, while it is
1711     // the top context for variables). Sigh...
1712     if (value != NULL) {
1713       Token::Value op = (is_const ? Token::INIT_CONST : Token::INIT_VAR);
1714       Assignment* assignment =
1715           new(zone()) Assignment(op, last_var, value, position);
1716       if (block) {
1717         block->AddStatement(new(zone()) ExpressionStatement(assignment));
1718       }
1719     }
1720 
1721     if (fni_ != NULL) fni_->Leave();
1722   } while (peek() == Token::COMMA);
1723 
1724   if (!is_const && nvars == 1) {
1725     // We have a single, non-const variable.
1726     ASSERT(last_var != NULL);
1727     *var = last_var;
1728   }
1729 
1730   return block;
1731 }
1732 
1733 
ContainsLabel(ZoneStringList * labels,Handle<String> label)1734 static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) {
1735   ASSERT(!label.is_null());
1736   if (labels != NULL)
1737     for (int i = labels->length(); i-- > 0; )
1738       if (labels->at(i).is_identical_to(label))
1739         return true;
1740 
1741   return false;
1742 }
1743 
1744 
ParseExpressionOrLabelledStatement(ZoneStringList * labels,bool * ok)1745 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
1746                                                       bool* ok) {
1747   // ExpressionStatement | LabelledStatement ::
1748   //   Expression ';'
1749   //   Identifier ':' Statement
1750   bool starts_with_idenfifier = peek_any_identifier();
1751   Expression* expr = ParseExpression(true, CHECK_OK);
1752   if (peek() == Token::COLON && starts_with_idenfifier && expr &&
1753       expr->AsVariableProxy() != NULL &&
1754       !expr->AsVariableProxy()->is_this()) {
1755     // Expression is a single identifier, and not, e.g., a parenthesized
1756     // identifier.
1757     VariableProxy* var = expr->AsVariableProxy();
1758     Handle<String> label = var->name();
1759     // TODO(1240780): We don't check for redeclaration of labels
1760     // during preparsing since keeping track of the set of active
1761     // labels requires nontrivial changes to the way scopes are
1762     // structured.  However, these are probably changes we want to
1763     // make later anyway so we should go back and fix this then.
1764     if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
1765       SmartPointer<char> c_string = label->ToCString(DISALLOW_NULLS);
1766       const char* elms[2] = { "Label", *c_string };
1767       Vector<const char*> args(elms, 2);
1768       ReportMessage("redeclaration", args);
1769       *ok = false;
1770       return NULL;
1771     }
1772     if (labels == NULL) labels = new ZoneStringList(4);
1773     labels->Add(label);
1774     // Remove the "ghost" variable that turned out to be a label
1775     // from the top scope. This way, we don't try to resolve it
1776     // during the scope processing.
1777     top_scope_->RemoveUnresolved(var);
1778     Expect(Token::COLON, CHECK_OK);
1779     return ParseStatement(labels, ok);
1780   }
1781 
1782   // Parsed expression statement.
1783   ExpectSemicolon(CHECK_OK);
1784   return new(zone()) ExpressionStatement(expr);
1785 }
1786 
1787 
ParseIfStatement(ZoneStringList * labels,bool * ok)1788 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) {
1789   // IfStatement ::
1790   //   'if' '(' Expression ')' Statement ('else' Statement)?
1791 
1792   Expect(Token::IF, CHECK_OK);
1793   Expect(Token::LPAREN, CHECK_OK);
1794   Expression* condition = ParseExpression(true, CHECK_OK);
1795   Expect(Token::RPAREN, CHECK_OK);
1796   Statement* then_statement = ParseStatement(labels, CHECK_OK);
1797   Statement* else_statement = NULL;
1798   if (peek() == Token::ELSE) {
1799     Next();
1800     else_statement = ParseStatement(labels, CHECK_OK);
1801   } else {
1802     else_statement = EmptyStatement();
1803   }
1804   return new(zone()) IfStatement(condition, then_statement, else_statement);
1805 }
1806 
1807 
ParseContinueStatement(bool * ok)1808 Statement* Parser::ParseContinueStatement(bool* ok) {
1809   // ContinueStatement ::
1810   //   'continue' Identifier? ';'
1811 
1812   Expect(Token::CONTINUE, CHECK_OK);
1813   Handle<String> label = Handle<String>::null();
1814   Token::Value tok = peek();
1815   if (!scanner().has_line_terminator_before_next() &&
1816       tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
1817     label = ParseIdentifier(CHECK_OK);
1818   }
1819   IterationStatement* target = NULL;
1820   target = LookupContinueTarget(label, CHECK_OK);
1821   if (target == NULL) {
1822     // Illegal continue statement.
1823     const char* message = "illegal_continue";
1824     Vector<Handle<String> > args;
1825     if (!label.is_null()) {
1826       message = "unknown_label";
1827       args = Vector<Handle<String> >(&label, 1);
1828     }
1829     ReportMessageAt(scanner().location(), message, args);
1830     *ok = false;
1831     return NULL;
1832   }
1833   ExpectSemicolon(CHECK_OK);
1834   return new(zone()) ContinueStatement(target);
1835 }
1836 
1837 
ParseBreakStatement(ZoneStringList * labels,bool * ok)1838 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) {
1839   // BreakStatement ::
1840   //   'break' Identifier? ';'
1841 
1842   Expect(Token::BREAK, CHECK_OK);
1843   Handle<String> label;
1844   Token::Value tok = peek();
1845   if (!scanner().has_line_terminator_before_next() &&
1846       tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
1847     label = ParseIdentifier(CHECK_OK);
1848   }
1849   // Parse labeled break statements that target themselves into
1850   // empty statements, e.g. 'l1: l2: l3: break l2;'
1851   if (!label.is_null() && ContainsLabel(labels, label)) {
1852     return EmptyStatement();
1853   }
1854   BreakableStatement* target = NULL;
1855   target = LookupBreakTarget(label, CHECK_OK);
1856   if (target == NULL) {
1857     // Illegal break statement.
1858     const char* message = "illegal_break";
1859     Vector<Handle<String> > args;
1860     if (!label.is_null()) {
1861       message = "unknown_label";
1862       args = Vector<Handle<String> >(&label, 1);
1863     }
1864     ReportMessageAt(scanner().location(), message, args);
1865     *ok = false;
1866     return NULL;
1867   }
1868   ExpectSemicolon(CHECK_OK);
1869   return new(zone()) BreakStatement(target);
1870 }
1871 
1872 
ParseReturnStatement(bool * ok)1873 Statement* Parser::ParseReturnStatement(bool* ok) {
1874   // ReturnStatement ::
1875   //   'return' Expression? ';'
1876 
1877   // Consume the return token. It is necessary to do the before
1878   // reporting any errors on it, because of the way errors are
1879   // reported (underlining).
1880   Expect(Token::RETURN, CHECK_OK);
1881 
1882   // An ECMAScript program is considered syntactically incorrect if it
1883   // contains a return statement that is not within the body of a
1884   // function. See ECMA-262, section 12.9, page 67.
1885   //
1886   // To be consistent with KJS we report the syntax error at runtime.
1887   if (!top_scope_->is_function_scope()) {
1888     Handle<String> type = isolate()->factory()->illegal_return_symbol();
1889     Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null());
1890     return new(zone()) ExpressionStatement(throw_error);
1891   }
1892 
1893   Token::Value tok = peek();
1894   if (scanner().has_line_terminator_before_next() ||
1895       tok == Token::SEMICOLON ||
1896       tok == Token::RBRACE ||
1897       tok == Token::EOS) {
1898     ExpectSemicolon(CHECK_OK);
1899     return new(zone()) ReturnStatement(GetLiteralUndefined());
1900   }
1901 
1902   Expression* expr = ParseExpression(true, CHECK_OK);
1903   ExpectSemicolon(CHECK_OK);
1904   return new(zone()) ReturnStatement(expr);
1905 }
1906 
1907 
WithHelper(Expression * obj,ZoneStringList * labels,bool is_catch_block,bool * ok)1908 Block* Parser::WithHelper(Expression* obj,
1909                           ZoneStringList* labels,
1910                           bool is_catch_block,
1911                           bool* ok) {
1912   // Parse the statement and collect escaping labels.
1913   ZoneList<Label*>* target_list = new ZoneList<Label*>(0);
1914   TargetCollector collector(target_list);
1915   Statement* stat;
1916   { Target target(&this->target_stack_, &collector);
1917     with_nesting_level_++;
1918     top_scope_->RecordWithStatement();
1919     stat = ParseStatement(labels, CHECK_OK);
1920     with_nesting_level_--;
1921   }
1922   // Create resulting block with two statements.
1923   // 1: Evaluate the with expression.
1924   // 2: The try-finally block evaluating the body.
1925   Block* result = new(zone()) Block(NULL, 2, false);
1926 
1927   if (result != NULL) {
1928     result->AddStatement(new(zone()) WithEnterStatement(obj, is_catch_block));
1929 
1930     // Create body block.
1931     Block* body = new(zone()) Block(NULL, 1, false);
1932     body->AddStatement(stat);
1933 
1934     // Create exit block.
1935     Block* exit = new(zone()) Block(NULL, 1, false);
1936     exit->AddStatement(new(zone()) WithExitStatement());
1937 
1938     // Return a try-finally statement.
1939     TryFinallyStatement* wrapper = new(zone()) TryFinallyStatement(body, exit);
1940     wrapper->set_escaping_targets(collector.targets());
1941     result->AddStatement(wrapper);
1942   }
1943   return result;
1944 }
1945 
1946 
ParseWithStatement(ZoneStringList * labels,bool * ok)1947 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) {
1948   // WithStatement ::
1949   //   'with' '(' Expression ')' Statement
1950 
1951   Expect(Token::WITH, CHECK_OK);
1952 
1953   if (top_scope_->is_strict_mode()) {
1954     ReportMessage("strict_mode_with", Vector<const char*>::empty());
1955     *ok = false;
1956     return NULL;
1957   }
1958 
1959   Expect(Token::LPAREN, CHECK_OK);
1960   Expression* expr = ParseExpression(true, CHECK_OK);
1961   Expect(Token::RPAREN, CHECK_OK);
1962 
1963   return WithHelper(expr, labels, false, CHECK_OK);
1964 }
1965 
1966 
ParseCaseClause(bool * default_seen_ptr,bool * ok)1967 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
1968   // CaseClause ::
1969   //   'case' Expression ':' Statement*
1970   //   'default' ':' Statement*
1971 
1972   Expression* label = NULL;  // NULL expression indicates default case
1973   if (peek() == Token::CASE) {
1974     Expect(Token::CASE, CHECK_OK);
1975     label = ParseExpression(true, CHECK_OK);
1976   } else {
1977     Expect(Token::DEFAULT, CHECK_OK);
1978     if (*default_seen_ptr) {
1979       ReportMessage("multiple_defaults_in_switch",
1980                     Vector<const char*>::empty());
1981       *ok = false;
1982       return NULL;
1983     }
1984     *default_seen_ptr = true;
1985   }
1986   Expect(Token::COLON, CHECK_OK);
1987   int pos = scanner().location().beg_pos;
1988   ZoneList<Statement*>* statements = new ZoneList<Statement*>(5);
1989   while (peek() != Token::CASE &&
1990          peek() != Token::DEFAULT &&
1991          peek() != Token::RBRACE) {
1992     Statement* stat = ParseStatement(NULL, CHECK_OK);
1993     statements->Add(stat);
1994   }
1995 
1996   return new(zone()) CaseClause(label, statements, pos);
1997 }
1998 
1999 
ParseSwitchStatement(ZoneStringList * labels,bool * ok)2000 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels,
2001                                               bool* ok) {
2002   // SwitchStatement ::
2003   //   'switch' '(' Expression ')' '{' CaseClause* '}'
2004 
2005   SwitchStatement* statement = new(zone()) SwitchStatement(labels);
2006   Target target(&this->target_stack_, statement);
2007 
2008   Expect(Token::SWITCH, CHECK_OK);
2009   Expect(Token::LPAREN, CHECK_OK);
2010   Expression* tag = ParseExpression(true, CHECK_OK);
2011   Expect(Token::RPAREN, CHECK_OK);
2012 
2013   bool default_seen = false;
2014   ZoneList<CaseClause*>* cases = new ZoneList<CaseClause*>(4);
2015   Expect(Token::LBRACE, CHECK_OK);
2016   while (peek() != Token::RBRACE) {
2017     CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
2018     cases->Add(clause);
2019   }
2020   Expect(Token::RBRACE, CHECK_OK);
2021 
2022   if (statement) statement->Initialize(tag, cases);
2023   return statement;
2024 }
2025 
2026 
ParseThrowStatement(bool * ok)2027 Statement* Parser::ParseThrowStatement(bool* ok) {
2028   // ThrowStatement ::
2029   //   'throw' Expression ';'
2030 
2031   Expect(Token::THROW, CHECK_OK);
2032   int pos = scanner().location().beg_pos;
2033   if (scanner().has_line_terminator_before_next()) {
2034     ReportMessage("newline_after_throw", Vector<const char*>::empty());
2035     *ok = false;
2036     return NULL;
2037   }
2038   Expression* exception = ParseExpression(true, CHECK_OK);
2039   ExpectSemicolon(CHECK_OK);
2040 
2041   return new(zone()) ExpressionStatement(new(zone()) Throw(exception, pos));
2042 }
2043 
2044 
ParseTryStatement(bool * ok)2045 TryStatement* Parser::ParseTryStatement(bool* ok) {
2046   // TryStatement ::
2047   //   'try' Block Catch
2048   //   'try' Block Finally
2049   //   'try' Block Catch Finally
2050   //
2051   // Catch ::
2052   //   'catch' '(' Identifier ')' Block
2053   //
2054   // Finally ::
2055   //   'finally' Block
2056 
2057   Expect(Token::TRY, CHECK_OK);
2058 
2059   ZoneList<Label*>* target_list = new ZoneList<Label*>(0);
2060   TargetCollector collector(target_list);
2061   Block* try_block;
2062 
2063   { Target target(&this->target_stack_, &collector);
2064     try_block = ParseBlock(NULL, CHECK_OK);
2065   }
2066 
2067   Block* catch_block = NULL;
2068   Variable* catch_var = NULL;
2069   Block* finally_block = NULL;
2070 
2071   Token::Value tok = peek();
2072   if (tok != Token::CATCH && tok != Token::FINALLY) {
2073     ReportMessage("no_catch_or_finally", Vector<const char*>::empty());
2074     *ok = false;
2075     return NULL;
2076   }
2077 
2078   // If we can break out from the catch block and there is a finally block,
2079   // then we will need to collect jump targets from the catch block. Since
2080   // we don't know yet if there will be a finally block, we always collect
2081   // the jump targets.
2082   ZoneList<Label*>* catch_target_list = new ZoneList<Label*>(0);
2083   TargetCollector catch_collector(catch_target_list);
2084   bool has_catch = false;
2085   if (tok == Token::CATCH) {
2086     has_catch = true;
2087     Consume(Token::CATCH);
2088 
2089     Expect(Token::LPAREN, CHECK_OK);
2090     Handle<String> name = ParseIdentifier(CHECK_OK);
2091 
2092     if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) {
2093       ReportMessage("strict_catch_variable", Vector<const char*>::empty());
2094       *ok = false;
2095       return NULL;
2096     }
2097 
2098     Expect(Token::RPAREN, CHECK_OK);
2099 
2100     if (peek() == Token::LBRACE) {
2101       // Allocate a temporary for holding the finally state while
2102       // executing the finally block.
2103       catch_var =
2104           top_scope_->NewTemporary(isolate()->factory()->catch_var_symbol());
2105       Literal* name_literal = new(zone()) Literal(name);
2106       VariableProxy* catch_var_use = new(zone()) VariableProxy(catch_var);
2107       Expression* obj =
2108           new(zone()) CatchExtensionObject(name_literal, catch_var_use);
2109       { Target target(&this->target_stack_, &catch_collector);
2110         catch_block = WithHelper(obj, NULL, true, CHECK_OK);
2111       }
2112     } else {
2113       Expect(Token::LBRACE, CHECK_OK);
2114     }
2115 
2116     tok = peek();
2117   }
2118 
2119   if (tok == Token::FINALLY || !has_catch) {
2120     Consume(Token::FINALLY);
2121     // Declare a variable for holding the finally state while
2122     // executing the finally block.
2123     finally_block = ParseBlock(NULL, CHECK_OK);
2124   }
2125 
2126   // Simplify the AST nodes by converting:
2127   //   'try { } catch { } finally { }'
2128   // to:
2129   //   'try { try { } catch { } } finally { }'
2130 
2131   if (catch_block != NULL && finally_block != NULL) {
2132     VariableProxy* catch_var_defn = new(zone()) VariableProxy(catch_var);
2133     TryCatchStatement* statement =
2134         new(zone()) TryCatchStatement(try_block, catch_var_defn, catch_block);
2135     statement->set_escaping_targets(collector.targets());
2136     try_block = new(zone()) Block(NULL, 1, false);
2137     try_block->AddStatement(statement);
2138     catch_block = NULL;
2139   }
2140 
2141   TryStatement* result = NULL;
2142   if (catch_block != NULL) {
2143     ASSERT(finally_block == NULL);
2144     VariableProxy* catch_var_defn = new(zone()) VariableProxy(catch_var);
2145     result =
2146         new(zone()) TryCatchStatement(try_block, catch_var_defn, catch_block);
2147     result->set_escaping_targets(collector.targets());
2148   } else {
2149     ASSERT(finally_block != NULL);
2150     result = new(zone()) TryFinallyStatement(try_block, finally_block);
2151     // Add the jump targets of the try block and the catch block.
2152     for (int i = 0; i < collector.targets()->length(); i++) {
2153       catch_collector.AddTarget(collector.targets()->at(i));
2154     }
2155     result->set_escaping_targets(catch_collector.targets());
2156   }
2157 
2158   return result;
2159 }
2160 
2161 
ParseDoWhileStatement(ZoneStringList * labels,bool * ok)2162 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels,
2163                                                 bool* ok) {
2164   // DoStatement ::
2165   //   'do' Statement 'while' '(' Expression ')' ';'
2166 
2167   DoWhileStatement* loop = new(zone()) DoWhileStatement(labels);
2168   Target target(&this->target_stack_, loop);
2169 
2170   Expect(Token::DO, CHECK_OK);
2171   Statement* body = ParseStatement(NULL, CHECK_OK);
2172   Expect(Token::WHILE, CHECK_OK);
2173   Expect(Token::LPAREN, CHECK_OK);
2174 
2175   if (loop != NULL) {
2176     int position = scanner().location().beg_pos;
2177     loop->set_condition_position(position);
2178   }
2179 
2180   Expression* cond = ParseExpression(true, CHECK_OK);
2181   Expect(Token::RPAREN, CHECK_OK);
2182 
2183   // Allow do-statements to be terminated with and without
2184   // semi-colons. This allows code such as 'do;while(0)return' to
2185   // parse, which would not be the case if we had used the
2186   // ExpectSemicolon() functionality here.
2187   if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
2188 
2189   if (loop != NULL) loop->Initialize(cond, body);
2190   return loop;
2191 }
2192 
2193 
ParseWhileStatement(ZoneStringList * labels,bool * ok)2194 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) {
2195   // WhileStatement ::
2196   //   'while' '(' Expression ')' Statement
2197 
2198   WhileStatement* loop = new(zone()) WhileStatement(labels);
2199   Target target(&this->target_stack_, loop);
2200 
2201   Expect(Token::WHILE, CHECK_OK);
2202   Expect(Token::LPAREN, CHECK_OK);
2203   Expression* cond = ParseExpression(true, CHECK_OK);
2204   Expect(Token::RPAREN, CHECK_OK);
2205   Statement* body = ParseStatement(NULL, CHECK_OK);
2206 
2207   if (loop != NULL) loop->Initialize(cond, body);
2208   return loop;
2209 }
2210 
2211 
ParseForStatement(ZoneStringList * labels,bool * ok)2212 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
2213   // ForStatement ::
2214   //   'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
2215 
2216   Statement* init = NULL;
2217 
2218   Expect(Token::FOR, CHECK_OK);
2219   Expect(Token::LPAREN, CHECK_OK);
2220   if (peek() != Token::SEMICOLON) {
2221     if (peek() == Token::VAR || peek() == Token::CONST) {
2222       Expression* each = NULL;
2223       Block* variable_statement =
2224           ParseVariableDeclarations(false, &each, CHECK_OK);
2225       if (peek() == Token::IN && each != NULL) {
2226         ForInStatement* loop = new(zone()) ForInStatement(labels);
2227         Target target(&this->target_stack_, loop);
2228 
2229         Expect(Token::IN, CHECK_OK);
2230         Expression* enumerable = ParseExpression(true, CHECK_OK);
2231         Expect(Token::RPAREN, CHECK_OK);
2232 
2233         Statement* body = ParseStatement(NULL, CHECK_OK);
2234         loop->Initialize(each, enumerable, body);
2235         Block* result = new(zone()) Block(NULL, 2, false);
2236         result->AddStatement(variable_statement);
2237         result->AddStatement(loop);
2238         // Parsed for-in loop w/ variable/const declaration.
2239         return result;
2240       } else {
2241         init = variable_statement;
2242       }
2243 
2244     } else {
2245       Expression* expression = ParseExpression(false, CHECK_OK);
2246       if (peek() == Token::IN) {
2247         // Signal a reference error if the expression is an invalid
2248         // left-hand side expression.  We could report this as a syntax
2249         // error here but for compatibility with JSC we choose to report
2250         // the error at runtime.
2251         if (expression == NULL || !expression->IsValidLeftHandSide()) {
2252           Handle<String> type =
2253               isolate()->factory()->invalid_lhs_in_for_in_symbol();
2254           expression = NewThrowReferenceError(type);
2255         }
2256         ForInStatement* loop = new(zone()) ForInStatement(labels);
2257         Target target(&this->target_stack_, loop);
2258 
2259         Expect(Token::IN, CHECK_OK);
2260         Expression* enumerable = ParseExpression(true, CHECK_OK);
2261         Expect(Token::RPAREN, CHECK_OK);
2262 
2263         Statement* body = ParseStatement(NULL, CHECK_OK);
2264         if (loop) loop->Initialize(expression, enumerable, body);
2265         // Parsed for-in loop.
2266         return loop;
2267 
2268       } else {
2269         init = new(zone()) ExpressionStatement(expression);
2270       }
2271     }
2272   }
2273 
2274   // Standard 'for' loop
2275   ForStatement* loop = new(zone()) ForStatement(labels);
2276   Target target(&this->target_stack_, loop);
2277 
2278   // Parsed initializer at this point.
2279   Expect(Token::SEMICOLON, CHECK_OK);
2280 
2281   Expression* cond = NULL;
2282   if (peek() != Token::SEMICOLON) {
2283     cond = ParseExpression(true, CHECK_OK);
2284   }
2285   Expect(Token::SEMICOLON, CHECK_OK);
2286 
2287   Statement* next = NULL;
2288   if (peek() != Token::RPAREN) {
2289     Expression* exp = ParseExpression(true, CHECK_OK);
2290     next = new(zone()) ExpressionStatement(exp);
2291   }
2292   Expect(Token::RPAREN, CHECK_OK);
2293 
2294   Statement* body = ParseStatement(NULL, CHECK_OK);
2295   if (loop) loop->Initialize(init, cond, next, body);
2296   return loop;
2297 }
2298 
2299 
2300 // Precedence = 1
ParseExpression(bool accept_IN,bool * ok)2301 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) {
2302   // Expression ::
2303   //   AssignmentExpression
2304   //   Expression ',' AssignmentExpression
2305 
2306   Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK);
2307   while (peek() == Token::COMMA) {
2308     Expect(Token::COMMA, CHECK_OK);
2309     int position = scanner().location().beg_pos;
2310     Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
2311     result = new(zone()) BinaryOperation(Token::COMMA, result, right, position);
2312   }
2313   return result;
2314 }
2315 
2316 
2317 // Precedence = 2
ParseAssignmentExpression(bool accept_IN,bool * ok)2318 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
2319   // AssignmentExpression ::
2320   //   ConditionalExpression
2321   //   LeftHandSideExpression AssignmentOperator AssignmentExpression
2322 
2323   if (fni_ != NULL) fni_->Enter();
2324   Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK);
2325 
2326   if (!Token::IsAssignmentOp(peek())) {
2327     if (fni_ != NULL) fni_->Leave();
2328     // Parsed conditional expression only (no assignment).
2329     return expression;
2330   }
2331 
2332   // Signal a reference error if the expression is an invalid left-hand
2333   // side expression.  We could report this as a syntax error here but
2334   // for compatibility with JSC we choose to report the error at
2335   // runtime.
2336   if (expression == NULL || !expression->IsValidLeftHandSide()) {
2337     Handle<String> type =
2338         isolate()->factory()->invalid_lhs_in_assignment_symbol();
2339     expression = NewThrowReferenceError(type);
2340   }
2341 
2342   if (top_scope_->is_strict_mode()) {
2343     // Assignment to eval or arguments is disallowed in strict mode.
2344     CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK);
2345   }
2346 
2347   Token::Value op = Next();  // Get assignment operator.
2348   int pos = scanner().location().beg_pos;
2349   Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
2350 
2351   // TODO(1231235): We try to estimate the set of properties set by
2352   // constructors. We define a new property whenever there is an
2353   // assignment to a property of 'this'. We should probably only add
2354   // properties if we haven't seen them before. Otherwise we'll
2355   // probably overestimate the number of properties.
2356   Property* property = expression ? expression->AsProperty() : NULL;
2357   if (op == Token::ASSIGN &&
2358       property != NULL &&
2359       property->obj()->AsVariableProxy() != NULL &&
2360       property->obj()->AsVariableProxy()->is_this()) {
2361     lexical_scope_->AddProperty();
2362   }
2363 
2364   // If we assign a function literal to a property we pretenure the
2365   // literal so it can be added as a constant function property.
2366   if (property != NULL && right->AsFunctionLiteral() != NULL) {
2367     right->AsFunctionLiteral()->set_pretenure(true);
2368   }
2369 
2370   if (fni_ != NULL) {
2371     // Check if the right hand side is a call to avoid inferring a
2372     // name if we're dealing with "a = function(){...}();"-like
2373     // expression.
2374     if ((op == Token::INIT_VAR
2375          || op == Token::INIT_CONST
2376          || op == Token::ASSIGN)
2377         && (right->AsCall() == NULL)) {
2378       fni_->Infer();
2379     }
2380     fni_->Leave();
2381   }
2382 
2383   return new(zone()) Assignment(op, expression, right, pos);
2384 }
2385 
2386 
2387 // Precedence = 3
ParseConditionalExpression(bool accept_IN,bool * ok)2388 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) {
2389   // ConditionalExpression ::
2390   //   LogicalOrExpression
2391   //   LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
2392 
2393   // We start using the binary expression parser for prec >= 4 only!
2394   Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
2395   if (peek() != Token::CONDITIONAL) return expression;
2396   Consume(Token::CONDITIONAL);
2397   // In parsing the first assignment expression in conditional
2398   // expressions we always accept the 'in' keyword; see ECMA-262,
2399   // section 11.12, page 58.
2400   int left_position = scanner().peek_location().beg_pos;
2401   Expression* left = ParseAssignmentExpression(true, CHECK_OK);
2402   Expect(Token::COLON, CHECK_OK);
2403   int right_position = scanner().peek_location().beg_pos;
2404   Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
2405   return new(zone()) Conditional(expression, left, right,
2406                          left_position, right_position);
2407 }
2408 
2409 
Precedence(Token::Value tok,bool accept_IN)2410 static int Precedence(Token::Value tok, bool accept_IN) {
2411   if (tok == Token::IN && !accept_IN)
2412     return 0;  // 0 precedence will terminate binary expression parsing
2413 
2414   return Token::Precedence(tok);
2415 }
2416 
2417 
2418 // Precedence >= 4
ParseBinaryExpression(int prec,bool accept_IN,bool * ok)2419 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
2420   ASSERT(prec >= 4);
2421   Expression* x = ParseUnaryExpression(CHECK_OK);
2422   for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
2423     // prec1 >= 4
2424     while (Precedence(peek(), accept_IN) == prec1) {
2425       Token::Value op = Next();
2426       int position = scanner().location().beg_pos;
2427       Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
2428 
2429       // Compute some expressions involving only number literals.
2430       if (x && x->AsLiteral() && x->AsLiteral()->handle()->IsNumber() &&
2431           y && y->AsLiteral() && y->AsLiteral()->handle()->IsNumber()) {
2432         double x_val = x->AsLiteral()->handle()->Number();
2433         double y_val = y->AsLiteral()->handle()->Number();
2434 
2435         switch (op) {
2436           case Token::ADD:
2437             x = NewNumberLiteral(x_val + y_val);
2438             continue;
2439           case Token::SUB:
2440             x = NewNumberLiteral(x_val - y_val);
2441             continue;
2442           case Token::MUL:
2443             x = NewNumberLiteral(x_val * y_val);
2444             continue;
2445           case Token::DIV:
2446             x = NewNumberLiteral(x_val / y_val);
2447             continue;
2448           case Token::BIT_OR:
2449             x = NewNumberLiteral(DoubleToInt32(x_val) | DoubleToInt32(y_val));
2450             continue;
2451           case Token::BIT_AND:
2452             x = NewNumberLiteral(DoubleToInt32(x_val) & DoubleToInt32(y_val));
2453             continue;
2454           case Token::BIT_XOR:
2455             x = NewNumberLiteral(DoubleToInt32(x_val) ^ DoubleToInt32(y_val));
2456             continue;
2457           case Token::SHL: {
2458             int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
2459             x = NewNumberLiteral(value);
2460             continue;
2461           }
2462           case Token::SHR: {
2463             uint32_t shift = DoubleToInt32(y_val) & 0x1f;
2464             uint32_t value = DoubleToUint32(x_val) >> shift;
2465             x = NewNumberLiteral(value);
2466             continue;
2467           }
2468           case Token::SAR: {
2469             uint32_t shift = DoubleToInt32(y_val) & 0x1f;
2470             int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
2471             x = NewNumberLiteral(value);
2472             continue;
2473           }
2474           default:
2475             break;
2476         }
2477       }
2478 
2479       // For now we distinguish between comparisons and other binary
2480       // operations.  (We could combine the two and get rid of this
2481       // code and AST node eventually.)
2482       if (Token::IsCompareOp(op)) {
2483         // We have a comparison.
2484         Token::Value cmp = op;
2485         switch (op) {
2486           case Token::NE: cmp = Token::EQ; break;
2487           case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
2488           default: break;
2489         }
2490         x = NewCompareNode(cmp, x, y, position);
2491         if (cmp != op) {
2492           // The comparison was negated - add a NOT.
2493           x = new(zone()) UnaryOperation(Token::NOT, x);
2494         }
2495 
2496       } else {
2497         // We have a "normal" binary operation.
2498         x = new(zone()) BinaryOperation(op, x, y, position);
2499       }
2500     }
2501   }
2502   return x;
2503 }
2504 
2505 
NewCompareNode(Token::Value op,Expression * x,Expression * y,int position)2506 Expression* Parser::NewCompareNode(Token::Value op,
2507                                    Expression* x,
2508                                    Expression* y,
2509                                    int position) {
2510   ASSERT(op != Token::NE && op != Token::NE_STRICT);
2511   if (op == Token::EQ || op == Token::EQ_STRICT) {
2512     bool is_strict = (op == Token::EQ_STRICT);
2513     Literal* x_literal = x->AsLiteral();
2514     if (x_literal != NULL && x_literal->IsNull()) {
2515       return new(zone()) CompareToNull(is_strict, y);
2516     }
2517 
2518     Literal* y_literal = y->AsLiteral();
2519     if (y_literal != NULL && y_literal->IsNull()) {
2520       return new(zone()) CompareToNull(is_strict, x);
2521     }
2522   }
2523   return new(zone()) CompareOperation(op, x, y, position);
2524 }
2525 
2526 
ParseUnaryExpression(bool * ok)2527 Expression* Parser::ParseUnaryExpression(bool* ok) {
2528   // UnaryExpression ::
2529   //   PostfixExpression
2530   //   'delete' UnaryExpression
2531   //   'void' UnaryExpression
2532   //   'typeof' UnaryExpression
2533   //   '++' UnaryExpression
2534   //   '--' UnaryExpression
2535   //   '+' UnaryExpression
2536   //   '-' UnaryExpression
2537   //   '~' UnaryExpression
2538   //   '!' UnaryExpression
2539 
2540   Token::Value op = peek();
2541   if (Token::IsUnaryOp(op)) {
2542     op = Next();
2543     Expression* expression = ParseUnaryExpression(CHECK_OK);
2544 
2545     // Compute some expressions involving only number literals.
2546     if (expression != NULL && expression->AsLiteral() &&
2547         expression->AsLiteral()->handle()->IsNumber()) {
2548       double value = expression->AsLiteral()->handle()->Number();
2549       switch (op) {
2550         case Token::ADD:
2551           return expression;
2552         case Token::SUB:
2553           return NewNumberLiteral(-value);
2554         case Token::BIT_NOT:
2555           return NewNumberLiteral(~DoubleToInt32(value));
2556         default: break;
2557       }
2558     }
2559 
2560     // "delete identifier" is a syntax error in strict mode.
2561     if (op == Token::DELETE && top_scope_->is_strict_mode()) {
2562       VariableProxy* operand = expression->AsVariableProxy();
2563       if (operand != NULL && !operand->is_this()) {
2564         ReportMessage("strict_delete", Vector<const char*>::empty());
2565         *ok = false;
2566         return NULL;
2567       }
2568     }
2569 
2570     return new(zone()) UnaryOperation(op, expression);
2571 
2572   } else if (Token::IsCountOp(op)) {
2573     op = Next();
2574     Expression* expression = ParseUnaryExpression(CHECK_OK);
2575     // Signal a reference error if the expression is an invalid
2576     // left-hand side expression.  We could report this as a syntax
2577     // error here but for compatibility with JSC we choose to report the
2578     // error at runtime.
2579     if (expression == NULL || !expression->IsValidLeftHandSide()) {
2580       Handle<String> type =
2581           isolate()->factory()->invalid_lhs_in_prefix_op_symbol();
2582       expression = NewThrowReferenceError(type);
2583     }
2584 
2585     if (top_scope_->is_strict_mode()) {
2586       // Prefix expression operand in strict mode may not be eval or arguments.
2587       CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
2588     }
2589 
2590     int position = scanner().location().beg_pos;
2591     return new(zone()) CountOperation(op,
2592                                       true /* prefix */,
2593                                       expression,
2594                                       position);
2595 
2596   } else {
2597     return ParsePostfixExpression(ok);
2598   }
2599 }
2600 
2601 
ParsePostfixExpression(bool * ok)2602 Expression* Parser::ParsePostfixExpression(bool* ok) {
2603   // PostfixExpression ::
2604   //   LeftHandSideExpression ('++' | '--')?
2605 
2606   Expression* expression = ParseLeftHandSideExpression(CHECK_OK);
2607   if (!scanner().has_line_terminator_before_next() &&
2608       Token::IsCountOp(peek())) {
2609     // Signal a reference error if the expression is an invalid
2610     // left-hand side expression.  We could report this as a syntax
2611     // error here but for compatibility with JSC we choose to report the
2612     // error at runtime.
2613     if (expression == NULL || !expression->IsValidLeftHandSide()) {
2614       Handle<String> type =
2615           isolate()->factory()->invalid_lhs_in_postfix_op_symbol();
2616       expression = NewThrowReferenceError(type);
2617     }
2618 
2619     if (top_scope_->is_strict_mode()) {
2620       // Postfix expression operand in strict mode may not be eval or arguments.
2621       CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
2622     }
2623 
2624     Token::Value next = Next();
2625     int position = scanner().location().beg_pos;
2626     expression =
2627         new(zone()) CountOperation(next,
2628                                    false /* postfix */,
2629                                    expression,
2630                                    position);
2631   }
2632   return expression;
2633 }
2634 
2635 
ParseLeftHandSideExpression(bool * ok)2636 Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
2637   // LeftHandSideExpression ::
2638   //   (NewExpression | MemberExpression) ...
2639 
2640   Expression* result;
2641   if (peek() == Token::NEW) {
2642     result = ParseNewExpression(CHECK_OK);
2643   } else {
2644     result = ParseMemberExpression(CHECK_OK);
2645   }
2646 
2647   while (true) {
2648     switch (peek()) {
2649       case Token::LBRACK: {
2650         Consume(Token::LBRACK);
2651         int pos = scanner().location().beg_pos;
2652         Expression* index = ParseExpression(true, CHECK_OK);
2653         result = new(zone()) Property(result, index, pos);
2654         Expect(Token::RBRACK, CHECK_OK);
2655         break;
2656       }
2657 
2658       case Token::LPAREN: {
2659         int pos = scanner().location().beg_pos;
2660         ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
2661 
2662         // Keep track of eval() calls since they disable all local variable
2663         // optimizations.
2664         // The calls that need special treatment are the
2665         // direct (i.e. not aliased) eval calls. These calls are all of the
2666         // form eval(...) with no explicit receiver object where eval is not
2667         // declared in the current scope chain.
2668         // These calls are marked as potentially direct eval calls. Whether
2669         // they are actually direct calls to eval is determined at run time.
2670         // TODO(994): In ES5, it doesn't matter if the "eval" var is declared
2671         // in the local scope chain. It only matters that it's called "eval",
2672         // is called without a receiver and it refers to the original eval
2673         // function.
2674         VariableProxy* callee = result->AsVariableProxy();
2675         if (callee != NULL &&
2676             callee->IsVariable(isolate()->factory()->eval_symbol())) {
2677           Handle<String> name = callee->name();
2678           Variable* var = top_scope_->Lookup(name);
2679           if (var == NULL) {
2680             top_scope_->RecordEvalCall();
2681           }
2682         }
2683         result = NewCall(result, args, pos);
2684         break;
2685       }
2686 
2687       case Token::PERIOD: {
2688         Consume(Token::PERIOD);
2689         int pos = scanner().location().beg_pos;
2690         Handle<String> name = ParseIdentifierName(CHECK_OK);
2691         result = new(zone()) Property(result, new(zone()) Literal(name), pos);
2692         if (fni_ != NULL) fni_->PushLiteralName(name);
2693         break;
2694       }
2695 
2696       default:
2697         return result;
2698     }
2699   }
2700 }
2701 
2702 
ParseNewPrefix(PositionStack * stack,bool * ok)2703 Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) {
2704   // NewExpression ::
2705   //   ('new')+ MemberExpression
2706 
2707   // The grammar for new expressions is pretty warped. The keyword
2708   // 'new' can either be a part of the new expression (where it isn't
2709   // followed by an argument list) or a part of the member expression,
2710   // where it must be followed by an argument list. To accommodate
2711   // this, we parse the 'new' keywords greedily and keep track of how
2712   // many we have parsed. This information is then passed on to the
2713   // member expression parser, which is only allowed to match argument
2714   // lists as long as it has 'new' prefixes left
2715   Expect(Token::NEW, CHECK_OK);
2716   PositionStack::Element pos(stack, scanner().location().beg_pos);
2717 
2718   Expression* result;
2719   if (peek() == Token::NEW) {
2720     result = ParseNewPrefix(stack, CHECK_OK);
2721   } else {
2722     result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK);
2723   }
2724 
2725   if (!stack->is_empty()) {
2726     int last = stack->pop();
2727     result = new(zone()) CallNew(result, new ZoneList<Expression*>(0), last);
2728   }
2729   return result;
2730 }
2731 
2732 
ParseNewExpression(bool * ok)2733 Expression* Parser::ParseNewExpression(bool* ok) {
2734   PositionStack stack(ok);
2735   return ParseNewPrefix(&stack, ok);
2736 }
2737 
2738 
ParseMemberExpression(bool * ok)2739 Expression* Parser::ParseMemberExpression(bool* ok) {
2740   return ParseMemberWithNewPrefixesExpression(NULL, ok);
2741 }
2742 
2743 
ParseMemberWithNewPrefixesExpression(PositionStack * stack,bool * ok)2744 Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
2745                                                          bool* ok) {
2746   // MemberExpression ::
2747   //   (PrimaryExpression | FunctionLiteral)
2748   //     ('[' Expression ']' | '.' Identifier | Arguments)*
2749 
2750   // Parse the initial primary or function expression.
2751   Expression* result = NULL;
2752   if (peek() == Token::FUNCTION) {
2753     Expect(Token::FUNCTION, CHECK_OK);
2754     int function_token_position = scanner().location().beg_pos;
2755     Handle<String> name;
2756     bool is_reserved_name = false;
2757     if (peek_any_identifier()) {
2758         name = ParseIdentifierOrReservedWord(&is_reserved_name, CHECK_OK);
2759     }
2760     result = ParseFunctionLiteral(name, is_reserved_name,
2761                                   function_token_position, NESTED, CHECK_OK);
2762   } else {
2763     result = ParsePrimaryExpression(CHECK_OK);
2764   }
2765 
2766   while (true) {
2767     switch (peek()) {
2768       case Token::LBRACK: {
2769         Consume(Token::LBRACK);
2770         int pos = scanner().location().beg_pos;
2771         Expression* index = ParseExpression(true, CHECK_OK);
2772         result = new(zone()) Property(result, index, pos);
2773         Expect(Token::RBRACK, CHECK_OK);
2774         break;
2775       }
2776       case Token::PERIOD: {
2777         Consume(Token::PERIOD);
2778         int pos = scanner().location().beg_pos;
2779         Handle<String> name = ParseIdentifierName(CHECK_OK);
2780         result = new(zone()) Property(result, new(zone()) Literal(name), pos);
2781         if (fni_ != NULL) fni_->PushLiteralName(name);
2782         break;
2783       }
2784       case Token::LPAREN: {
2785         if ((stack == NULL) || stack->is_empty()) return result;
2786         // Consume one of the new prefixes (already parsed).
2787         ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
2788         int last = stack->pop();
2789         result = new CallNew(result, args, last);
2790         break;
2791       }
2792       default:
2793         return result;
2794     }
2795   }
2796 }
2797 
2798 
ParseDebuggerStatement(bool * ok)2799 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
2800   // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
2801   // contexts this is used as a statement which invokes the debugger as i a
2802   // break point is present.
2803   // DebuggerStatement ::
2804   //   'debugger' ';'
2805 
2806   Expect(Token::DEBUGGER, CHECK_OK);
2807   ExpectSemicolon(CHECK_OK);
2808   return new(zone()) DebuggerStatement();
2809 }
2810 
2811 
ReportUnexpectedToken(Token::Value token)2812 void Parser::ReportUnexpectedToken(Token::Value token) {
2813   // We don't report stack overflows here, to avoid increasing the
2814   // stack depth even further.  Instead we report it after parsing is
2815   // over, in ParseProgram/ParseJson.
2816   if (token == Token::ILLEGAL && stack_overflow_) return;
2817   // Four of the tokens are treated specially
2818   switch (token) {
2819     case Token::EOS:
2820       return ReportMessage("unexpected_eos", Vector<const char*>::empty());
2821     case Token::NUMBER:
2822       return ReportMessage("unexpected_token_number",
2823                            Vector<const char*>::empty());
2824     case Token::STRING:
2825       return ReportMessage("unexpected_token_string",
2826                            Vector<const char*>::empty());
2827     case Token::IDENTIFIER:
2828       return ReportMessage("unexpected_token_identifier",
2829                            Vector<const char*>::empty());
2830     case Token::FUTURE_RESERVED_WORD:
2831       return ReportMessage(top_scope_->is_strict_mode() ?
2832                                "unexpected_strict_reserved" :
2833                                "unexpected_token_identifier",
2834                            Vector<const char*>::empty());
2835     default:
2836       const char* name = Token::String(token);
2837       ASSERT(name != NULL);
2838       ReportMessage("unexpected_token", Vector<const char*>(&name, 1));
2839   }
2840 }
2841 
2842 
ReportInvalidPreparseData(Handle<String> name,bool * ok)2843 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) {
2844   SmartPointer<char> name_string = name->ToCString(DISALLOW_NULLS);
2845   const char* element[1] = { *name_string };
2846   ReportMessage("invalid_preparser_data",
2847                 Vector<const char*>(element, 1));
2848   *ok = false;
2849 }
2850 
2851 
ParsePrimaryExpression(bool * ok)2852 Expression* Parser::ParsePrimaryExpression(bool* ok) {
2853   // PrimaryExpression ::
2854   //   'this'
2855   //   'null'
2856   //   'true'
2857   //   'false'
2858   //   Identifier
2859   //   Number
2860   //   String
2861   //   ArrayLiteral
2862   //   ObjectLiteral
2863   //   RegExpLiteral
2864   //   '(' Expression ')'
2865 
2866   Expression* result = NULL;
2867   switch (peek()) {
2868     case Token::THIS: {
2869       Consume(Token::THIS);
2870       VariableProxy* recv = top_scope_->receiver();
2871       result = recv;
2872       break;
2873     }
2874 
2875     case Token::NULL_LITERAL:
2876       Consume(Token::NULL_LITERAL);
2877       result = new(zone()) Literal(isolate()->factory()->null_value());
2878       break;
2879 
2880     case Token::TRUE_LITERAL:
2881       Consume(Token::TRUE_LITERAL);
2882       result = new(zone()) Literal(isolate()->factory()->true_value());
2883       break;
2884 
2885     case Token::FALSE_LITERAL:
2886       Consume(Token::FALSE_LITERAL);
2887       result = new(zone()) Literal(isolate()->factory()->false_value());
2888       break;
2889 
2890     case Token::IDENTIFIER:
2891     case Token::FUTURE_RESERVED_WORD: {
2892       Handle<String> name = ParseIdentifier(CHECK_OK);
2893       if (fni_ != NULL) fni_->PushVariableName(name);
2894       result = top_scope_->NewUnresolved(name,
2895                                          inside_with(),
2896                                          scanner().location().beg_pos);
2897       break;
2898     }
2899 
2900     case Token::NUMBER: {
2901       Consume(Token::NUMBER);
2902       ASSERT(scanner().is_literal_ascii());
2903       double value = StringToDouble(isolate()->unicode_cache(),
2904                                     scanner().literal_ascii_string(),
2905                                     ALLOW_HEX | ALLOW_OCTALS);
2906       result = NewNumberLiteral(value);
2907       break;
2908     }
2909 
2910     case Token::STRING: {
2911       Consume(Token::STRING);
2912       Handle<String> symbol = GetSymbol(CHECK_OK);
2913       result = new(zone()) Literal(symbol);
2914       if (fni_ != NULL) fni_->PushLiteralName(symbol);
2915       break;
2916     }
2917 
2918     case Token::ASSIGN_DIV:
2919       result = ParseRegExpLiteral(true, CHECK_OK);
2920       break;
2921 
2922     case Token::DIV:
2923       result = ParseRegExpLiteral(false, CHECK_OK);
2924       break;
2925 
2926     case Token::LBRACK:
2927       result = ParseArrayLiteral(CHECK_OK);
2928       break;
2929 
2930     case Token::LBRACE:
2931       result = ParseObjectLiteral(CHECK_OK);
2932       break;
2933 
2934     case Token::LPAREN:
2935       Consume(Token::LPAREN);
2936       // Heuristically try to detect immediately called functions before
2937       // seeing the call parentheses.
2938       parenthesized_function_ = (peek() == Token::FUNCTION);
2939       result = ParseExpression(true, CHECK_OK);
2940       Expect(Token::RPAREN, CHECK_OK);
2941       break;
2942 
2943     case Token::MOD:
2944       if (allow_natives_syntax_ || extension_ != NULL) {
2945         result = ParseV8Intrinsic(CHECK_OK);
2946         break;
2947       }
2948       // If we're not allowing special syntax we fall-through to the
2949       // default case.
2950 
2951     default: {
2952       Token::Value tok = Next();
2953       ReportUnexpectedToken(tok);
2954       *ok = false;
2955       return NULL;
2956     }
2957   }
2958 
2959   return result;
2960 }
2961 
2962 
BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression * > * values,Handle<FixedArray> literals,bool * is_simple,int * depth)2963 void Parser::BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* values,
2964                                                   Handle<FixedArray> literals,
2965                                                   bool* is_simple,
2966                                                   int* depth) {
2967   // Fill in the literals.
2968   // Accumulate output values in local variables.
2969   bool is_simple_acc = true;
2970   int depth_acc = 1;
2971   for (int i = 0; i < values->length(); i++) {
2972     MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral();
2973     if (m_literal != NULL && m_literal->depth() >= depth_acc) {
2974       depth_acc = m_literal->depth() + 1;
2975     }
2976     Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i));
2977     if (boilerplate_value->IsUndefined()) {
2978       literals->set_the_hole(i);
2979       is_simple_acc = false;
2980     } else {
2981       literals->set(i, *boilerplate_value);
2982     }
2983   }
2984 
2985   *is_simple = is_simple_acc;
2986   *depth = depth_acc;
2987 }
2988 
2989 
ParseArrayLiteral(bool * ok)2990 Expression* Parser::ParseArrayLiteral(bool* ok) {
2991   // ArrayLiteral ::
2992   //   '[' Expression? (',' Expression?)* ']'
2993 
2994   ZoneList<Expression*>* values = new ZoneList<Expression*>(4);
2995   Expect(Token::LBRACK, CHECK_OK);
2996   while (peek() != Token::RBRACK) {
2997     Expression* elem;
2998     if (peek() == Token::COMMA) {
2999       elem = GetLiteralTheHole();
3000     } else {
3001       elem = ParseAssignmentExpression(true, CHECK_OK);
3002     }
3003     values->Add(elem);
3004     if (peek() != Token::RBRACK) {
3005       Expect(Token::COMMA, CHECK_OK);
3006     }
3007   }
3008   Expect(Token::RBRACK, CHECK_OK);
3009 
3010   // Update the scope information before the pre-parsing bailout.
3011   int literal_index = lexical_scope_->NextMaterializedLiteralIndex();
3012 
3013   // Allocate a fixed array with all the literals.
3014   Handle<FixedArray> literals =
3015       isolate()->factory()->NewFixedArray(values->length(), TENURED);
3016 
3017   // Fill in the literals.
3018   bool is_simple = true;
3019   int depth = 1;
3020   for (int i = 0, n = values->length(); i < n; i++) {
3021     MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral();
3022     if (m_literal != NULL && m_literal->depth() + 1 > depth) {
3023       depth = m_literal->depth() + 1;
3024     }
3025     Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i));
3026     if (boilerplate_value->IsUndefined()) {
3027       literals->set_the_hole(i);
3028       is_simple = false;
3029     } else {
3030       literals->set(i, *boilerplate_value);
3031     }
3032   }
3033 
3034   // Simple and shallow arrays can be lazily copied, we transform the
3035   // elements array to a copy-on-write array.
3036   if (is_simple && depth == 1 && values->length() > 0) {
3037     literals->set_map(isolate()->heap()->fixed_cow_array_map());
3038   }
3039 
3040   return new(zone()) ArrayLiteral(literals, values,
3041                           literal_index, is_simple, depth);
3042 }
3043 
3044 
IsBoilerplateProperty(ObjectLiteral::Property * property)3045 bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) {
3046   return property != NULL &&
3047          property->kind() != ObjectLiteral::Property::PROTOTYPE;
3048 }
3049 
3050 
IsCompileTimeValue(Expression * expression)3051 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
3052   if (expression->AsLiteral() != NULL) return true;
3053   MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3054   return lit != NULL && lit->is_simple();
3055 }
3056 
3057 
ArrayLiteralElementNeedsInitialization(Expression * value)3058 bool CompileTimeValue::ArrayLiteralElementNeedsInitialization(
3059     Expression* value) {
3060   // If value is a literal the property value is already set in the
3061   // boilerplate object.
3062   if (value->AsLiteral() != NULL) return false;
3063   // If value is a materialized literal the property value is already set
3064   // in the boilerplate object if it is simple.
3065   if (CompileTimeValue::IsCompileTimeValue(value)) return false;
3066   return true;
3067 }
3068 
3069 
GetValue(Expression * expression)3070 Handle<FixedArray> CompileTimeValue::GetValue(Expression* expression) {
3071   ASSERT(IsCompileTimeValue(expression));
3072   Handle<FixedArray> result = FACTORY->NewFixedArray(2, TENURED);
3073   ObjectLiteral* object_literal = expression->AsObjectLiteral();
3074   if (object_literal != NULL) {
3075     ASSERT(object_literal->is_simple());
3076     if (object_literal->fast_elements()) {
3077       result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
3078     } else {
3079       result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
3080     }
3081     result->set(kElementsSlot, *object_literal->constant_properties());
3082   } else {
3083     ArrayLiteral* array_literal = expression->AsArrayLiteral();
3084     ASSERT(array_literal != NULL && array_literal->is_simple());
3085     result->set(kTypeSlot, Smi::FromInt(ARRAY_LITERAL));
3086     result->set(kElementsSlot, *array_literal->constant_elements());
3087   }
3088   return result;
3089 }
3090 
3091 
GetType(Handle<FixedArray> value)3092 CompileTimeValue::Type CompileTimeValue::GetType(Handle<FixedArray> value) {
3093   Smi* type_value = Smi::cast(value->get(kTypeSlot));
3094   return static_cast<Type>(type_value->value());
3095 }
3096 
3097 
GetElements(Handle<FixedArray> value)3098 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
3099   return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
3100 }
3101 
3102 
GetBoilerplateValue(Expression * expression)3103 Handle<Object> Parser::GetBoilerplateValue(Expression* expression) {
3104   if (expression->AsLiteral() != NULL) {
3105     return expression->AsLiteral()->handle();
3106   }
3107   if (CompileTimeValue::IsCompileTimeValue(expression)) {
3108     return CompileTimeValue::GetValue(expression);
3109   }
3110   return isolate()->factory()->undefined_value();
3111 }
3112 
3113 // Defined in ast.cc
3114 bool IsEqualString(void* first, void* second);
3115 bool IsEqualNumber(void* first, void* second);
3116 
3117 
3118 // Validation per 11.1.5 Object Initialiser
3119 class ObjectLiteralPropertyChecker {
3120  public:
ObjectLiteralPropertyChecker(Parser * parser,bool strict)3121   ObjectLiteralPropertyChecker(Parser* parser, bool strict) :
3122     props(&IsEqualString),
3123     elems(&IsEqualNumber),
3124     parser_(parser),
3125     strict_(strict) {
3126   }
3127 
3128   void CheckProperty(
3129     ObjectLiteral::Property* property,
3130     Scanner::Location loc,
3131     bool* ok);
3132 
3133  private:
3134   enum PropertyKind {
3135     kGetAccessor = 0x01,
3136     kSetAccessor = 0x02,
3137     kAccessor = kGetAccessor | kSetAccessor,
3138     kData = 0x04
3139   };
3140 
GetPropertyKind(ObjectLiteral::Property * property)3141   static intptr_t GetPropertyKind(ObjectLiteral::Property* property) {
3142     switch (property->kind()) {
3143       case ObjectLiteral::Property::GETTER:
3144         return kGetAccessor;
3145       case ObjectLiteral::Property::SETTER:
3146         return kSetAccessor;
3147       default:
3148         return kData;
3149     }
3150   }
3151 
3152   HashMap props;
3153   HashMap elems;
3154   Parser* parser_;
3155   bool strict_;
3156 };
3157 
3158 
CheckProperty(ObjectLiteral::Property * property,Scanner::Location loc,bool * ok)3159 void ObjectLiteralPropertyChecker::CheckProperty(
3160     ObjectLiteral::Property* property,
3161     Scanner::Location loc,
3162     bool* ok) {
3163 
3164   ASSERT(property != NULL);
3165 
3166   Literal *lit = property->key();
3167   Handle<Object> handle = lit->handle();
3168 
3169   uint32_t hash;
3170   HashMap* map;
3171   void* key;
3172 
3173   if (handle->IsSymbol()) {
3174     Handle<String> name(String::cast(*handle));
3175     if (name->AsArrayIndex(&hash)) {
3176       Handle<Object> key_handle = FACTORY->NewNumberFromUint(hash);
3177       key = key_handle.location();
3178       map = &elems;
3179     } else {
3180       key = handle.location();
3181       hash = name->Hash();
3182       map = &props;
3183     }
3184   } else if (handle->ToArrayIndex(&hash)) {
3185     key = handle.location();
3186     map = &elems;
3187   } else {
3188     ASSERT(handle->IsNumber());
3189     double num = handle->Number();
3190     char arr[100];
3191     Vector<char> buffer(arr, ARRAY_SIZE(arr));
3192     const char* str = DoubleToCString(num, buffer);
3193     Handle<String> name = FACTORY->NewStringFromAscii(CStrVector(str));
3194     key = name.location();
3195     hash = name->Hash();
3196     map = &props;
3197   }
3198 
3199   // Lookup property previously defined, if any.
3200   HashMap::Entry* entry = map->Lookup(key, hash, true);
3201   intptr_t prev = reinterpret_cast<intptr_t> (entry->value);
3202   intptr_t curr = GetPropertyKind(property);
3203 
3204   // Duplicate data properties are illegal in strict mode.
3205   if (strict_ && (curr & prev & kData) != 0) {
3206     parser_->ReportMessageAt(loc, "strict_duplicate_property",
3207                              Vector<const char*>::empty());
3208     *ok = false;
3209     return;
3210   }
3211   // Data property conflicting with an accessor.
3212   if (((curr & kData) && (prev & kAccessor)) ||
3213       ((prev & kData) && (curr & kAccessor))) {
3214     parser_->ReportMessageAt(loc, "accessor_data_property",
3215                              Vector<const char*>::empty());
3216     *ok = false;
3217     return;
3218   }
3219   // Two accessors of the same type conflicting
3220   if ((curr & prev & kAccessor) != 0) {
3221     parser_->ReportMessageAt(loc, "accessor_get_set",
3222                              Vector<const char*>::empty());
3223     *ok = false;
3224     return;
3225   }
3226 
3227   // Update map
3228   entry->value = reinterpret_cast<void*> (prev | curr);
3229   *ok = true;
3230 }
3231 
3232 
BuildObjectLiteralConstantProperties(ZoneList<ObjectLiteral::Property * > * properties,Handle<FixedArray> constant_properties,bool * is_simple,bool * fast_elements,int * depth)3233 void Parser::BuildObjectLiteralConstantProperties(
3234     ZoneList<ObjectLiteral::Property*>* properties,
3235     Handle<FixedArray> constant_properties,
3236     bool* is_simple,
3237     bool* fast_elements,
3238     int* depth) {
3239   int position = 0;
3240   // Accumulate the value in local variables and store it at the end.
3241   bool is_simple_acc = true;
3242   int depth_acc = 1;
3243   uint32_t max_element_index = 0;
3244   uint32_t elements = 0;
3245   for (int i = 0; i < properties->length(); i++) {
3246     ObjectLiteral::Property* property = properties->at(i);
3247     if (!IsBoilerplateProperty(property)) {
3248       is_simple_acc = false;
3249       continue;
3250     }
3251     MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral();
3252     if (m_literal != NULL && m_literal->depth() >= depth_acc) {
3253       depth_acc = m_literal->depth() + 1;
3254     }
3255 
3256     // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined
3257     // value for COMPUTED properties, the real value is filled in at
3258     // runtime. The enumeration order is maintained.
3259     Handle<Object> key = property->key()->handle();
3260     Handle<Object> value = GetBoilerplateValue(property->value());
3261     is_simple_acc = is_simple_acc && !value->IsUndefined();
3262 
3263     // Keep track of the number of elements in the object literal and
3264     // the largest element index.  If the largest element index is
3265     // much larger than the number of elements, creating an object
3266     // literal with fast elements will be a waste of space.
3267     uint32_t element_index = 0;
3268     if (key->IsString()
3269         && Handle<String>::cast(key)->AsArrayIndex(&element_index)
3270         && element_index > max_element_index) {
3271       max_element_index = element_index;
3272       elements++;
3273     } else if (key->IsSmi()) {
3274       int key_value = Smi::cast(*key)->value();
3275       if (key_value > 0
3276           && static_cast<uint32_t>(key_value) > max_element_index) {
3277         max_element_index = key_value;
3278       }
3279       elements++;
3280     }
3281 
3282     // Add name, value pair to the fixed array.
3283     constant_properties->set(position++, *key);
3284     constant_properties->set(position++, *value);
3285   }
3286   *fast_elements =
3287       (max_element_index <= 32) || ((2 * elements) >= max_element_index);
3288   *is_simple = is_simple_acc;
3289   *depth = depth_acc;
3290 }
3291 
3292 
ParseObjectLiteralGetSet(bool is_getter,bool * ok)3293 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
3294                                                           bool* ok) {
3295   // Special handling of getter and setter syntax:
3296   // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
3297   // We have already read the "get" or "set" keyword.
3298   Token::Value next = Next();
3299   bool is_keyword = Token::IsKeyword(next);
3300   if (next == Token::IDENTIFIER || next == Token::NUMBER ||
3301       next == Token::FUTURE_RESERVED_WORD ||
3302       next == Token::STRING || is_keyword) {
3303     Handle<String> name;
3304     if (is_keyword) {
3305       name = isolate_->factory()->LookupAsciiSymbol(Token::String(next));
3306     } else {
3307       name = GetSymbol(CHECK_OK);
3308     }
3309     FunctionLiteral* value =
3310         ParseFunctionLiteral(name,
3311                              false,   // reserved words are allowed here
3312                              RelocInfo::kNoPosition,
3313                              DECLARATION,
3314                              CHECK_OK);
3315     // Allow any number of parameters for compatiabilty with JSC.
3316     // Specification only allows zero parameters for get and one for set.
3317     ObjectLiteral::Property* property =
3318         new(zone()) ObjectLiteral::Property(is_getter, value);
3319     return property;
3320   } else {
3321     ReportUnexpectedToken(next);
3322     *ok = false;
3323     return NULL;
3324   }
3325 }
3326 
3327 
ParseObjectLiteral(bool * ok)3328 Expression* Parser::ParseObjectLiteral(bool* ok) {
3329   // ObjectLiteral ::
3330   //   '{' (
3331   //       ((IdentifierName | String | Number) ':' AssignmentExpression)
3332   //     | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
3333   //    )*[','] '}'
3334 
3335   ZoneList<ObjectLiteral::Property*>* properties =
3336       new ZoneList<ObjectLiteral::Property*>(4);
3337   int number_of_boilerplate_properties = 0;
3338   bool has_function = false;
3339 
3340   ObjectLiteralPropertyChecker checker(this, top_scope_->is_strict_mode());
3341 
3342   Expect(Token::LBRACE, CHECK_OK);
3343   Scanner::Location loc = scanner().location();
3344 
3345   while (peek() != Token::RBRACE) {
3346     if (fni_ != NULL) fni_->Enter();
3347 
3348     Literal* key = NULL;
3349     Token::Value next = peek();
3350 
3351     // Location of the property name token
3352     Scanner::Location loc = scanner().peek_location();
3353 
3354     switch (next) {
3355       case Token::FUTURE_RESERVED_WORD:
3356       case Token::IDENTIFIER: {
3357         bool is_getter = false;
3358         bool is_setter = false;
3359         Handle<String> id =
3360             ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
3361         if (fni_ != NULL) fni_->PushLiteralName(id);
3362 
3363         if ((is_getter || is_setter) && peek() != Token::COLON) {
3364             // Update loc to point to the identifier
3365             loc = scanner().peek_location();
3366             ObjectLiteral::Property* property =
3367                 ParseObjectLiteralGetSet(is_getter, CHECK_OK);
3368             if (IsBoilerplateProperty(property)) {
3369               number_of_boilerplate_properties++;
3370             }
3371             // Validate the property.
3372             checker.CheckProperty(property, loc, CHECK_OK);
3373             properties->Add(property);
3374             if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
3375 
3376             if (fni_ != NULL) {
3377               fni_->Infer();
3378               fni_->Leave();
3379             }
3380             continue;  // restart the while
3381         }
3382         // Failed to parse as get/set property, so it's just a property
3383         // called "get" or "set".
3384         key = new(zone()) Literal(id);
3385         break;
3386       }
3387       case Token::STRING: {
3388         Consume(Token::STRING);
3389         Handle<String> string = GetSymbol(CHECK_OK);
3390         if (fni_ != NULL) fni_->PushLiteralName(string);
3391         uint32_t index;
3392         if (!string.is_null() && string->AsArrayIndex(&index)) {
3393           key = NewNumberLiteral(index);
3394           break;
3395         }
3396         key = new(zone()) Literal(string);
3397         break;
3398       }
3399       case Token::NUMBER: {
3400         Consume(Token::NUMBER);
3401         ASSERT(scanner().is_literal_ascii());
3402         double value = StringToDouble(isolate()->unicode_cache(),
3403                                       scanner().literal_ascii_string(),
3404                                       ALLOW_HEX | ALLOW_OCTALS);
3405         key = NewNumberLiteral(value);
3406         break;
3407       }
3408       default:
3409         if (Token::IsKeyword(next)) {
3410           Consume(next);
3411           Handle<String> string = GetSymbol(CHECK_OK);
3412           key = new(zone()) Literal(string);
3413         } else {
3414           // Unexpected token.
3415           Token::Value next = Next();
3416           ReportUnexpectedToken(next);
3417           *ok = false;
3418           return NULL;
3419         }
3420     }
3421 
3422     Expect(Token::COLON, CHECK_OK);
3423     Expression* value = ParseAssignmentExpression(true, CHECK_OK);
3424 
3425     ObjectLiteral::Property* property =
3426         new(zone()) ObjectLiteral::Property(key, value);
3427 
3428     // Mark object literals that contain function literals and pretenure the
3429     // literal so it can be added as a constant function property.
3430     if (value->AsFunctionLiteral() != NULL) {
3431       has_function = true;
3432       value->AsFunctionLiteral()->set_pretenure(true);
3433     }
3434 
3435     // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
3436     if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++;
3437     // Validate the property
3438     checker.CheckProperty(property, loc, CHECK_OK);
3439     properties->Add(property);
3440 
3441     // TODO(1240767): Consider allowing trailing comma.
3442     if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
3443 
3444     if (fni_ != NULL) {
3445       fni_->Infer();
3446       fni_->Leave();
3447     }
3448   }
3449   Expect(Token::RBRACE, CHECK_OK);
3450 
3451   // Computation of literal_index must happen before pre parse bailout.
3452   int literal_index = lexical_scope_->NextMaterializedLiteralIndex();
3453 
3454   Handle<FixedArray> constant_properties = isolate()->factory()->NewFixedArray(
3455       number_of_boilerplate_properties * 2, TENURED);
3456 
3457   bool is_simple = true;
3458   bool fast_elements = true;
3459   int depth = 1;
3460   BuildObjectLiteralConstantProperties(properties,
3461                                        constant_properties,
3462                                        &is_simple,
3463                                        &fast_elements,
3464                                        &depth);
3465   return new(zone()) ObjectLiteral(constant_properties,
3466                            properties,
3467                            literal_index,
3468                            is_simple,
3469                            fast_elements,
3470                            depth,
3471                            has_function);
3472 }
3473 
3474 
ParseRegExpLiteral(bool seen_equal,bool * ok)3475 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) {
3476   if (!scanner().ScanRegExpPattern(seen_equal)) {
3477     Next();
3478     ReportMessage("unterminated_regexp", Vector<const char*>::empty());
3479     *ok = false;
3480     return NULL;
3481   }
3482 
3483   int literal_index = lexical_scope_->NextMaterializedLiteralIndex();
3484 
3485   Handle<String> js_pattern = NextLiteralString(TENURED);
3486   scanner().ScanRegExpFlags();
3487   Handle<String> js_flags = NextLiteralString(TENURED);
3488   Next();
3489 
3490   return new(zone()) RegExpLiteral(js_pattern, js_flags, literal_index);
3491 }
3492 
3493 
ParseArguments(bool * ok)3494 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) {
3495   // Arguments ::
3496   //   '(' (AssignmentExpression)*[','] ')'
3497 
3498   ZoneList<Expression*>* result = new ZoneList<Expression*>(4);
3499   Expect(Token::LPAREN, CHECK_OK);
3500   bool done = (peek() == Token::RPAREN);
3501   while (!done) {
3502     Expression* argument = ParseAssignmentExpression(true, CHECK_OK);
3503     result->Add(argument);
3504     if (result->length() > kMaxNumFunctionParameters) {
3505       ReportMessageAt(scanner().location(), "too_many_arguments",
3506                       Vector<const char*>::empty());
3507       *ok = false;
3508       return NULL;
3509     }
3510     done = (peek() == Token::RPAREN);
3511     if (!done) Expect(Token::COMMA, CHECK_OK);
3512   }
3513   Expect(Token::RPAREN, CHECK_OK);
3514   return result;
3515 }
3516 
3517 
ParseFunctionLiteral(Handle<String> var_name,bool name_is_reserved,int function_token_position,FunctionLiteralType type,bool * ok)3518 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
3519                                               bool name_is_reserved,
3520                                               int function_token_position,
3521                                               FunctionLiteralType type,
3522                                               bool* ok) {
3523   // Function ::
3524   //   '(' FormalParameterList? ')' '{' FunctionBody '}'
3525   bool is_named = !var_name.is_null();
3526 
3527   // The name associated with this function. If it's a function expression,
3528   // this is the actual function name, otherwise this is the name of the
3529   // variable declared and initialized with the function (expression). In
3530   // that case, we don't have a function name (it's empty).
3531   Handle<String> name =
3532       is_named ? var_name : isolate()->factory()->empty_symbol();
3533   // The function name, if any.
3534   Handle<String> function_name = isolate()->factory()->empty_symbol();
3535   if (is_named && (type == EXPRESSION || type == NESTED)) {
3536     function_name = name;
3537   }
3538 
3539   int num_parameters = 0;
3540   Scope* scope = NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with());
3541   ZoneList<Statement*>* body = new ZoneList<Statement*>(8);
3542   int materialized_literal_count;
3543   int expected_property_count;
3544   int start_pos;
3545   int end_pos;
3546   bool only_simple_this_property_assignments;
3547   Handle<FixedArray> this_property_assignments;
3548   // Parse function body.
3549   { LexicalScope lexical_scope(this, scope, isolate());
3550     top_scope_->SetScopeName(name);
3551 
3552     //  FormalParameterList ::
3553     //    '(' (Identifier)*[','] ')'
3554     Expect(Token::LPAREN, CHECK_OK);
3555     start_pos = scanner().location().beg_pos;
3556     Scanner::Location name_loc = Scanner::NoLocation();
3557     Scanner::Location dupe_loc = Scanner::NoLocation();
3558     Scanner::Location reserved_loc = Scanner::NoLocation();
3559 
3560     bool done = (peek() == Token::RPAREN);
3561     while (!done) {
3562       bool is_reserved = false;
3563       Handle<String> param_name =
3564           ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK);
3565 
3566       // Store locations for possible future error reports.
3567       if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) {
3568         name_loc = scanner().location();
3569       }
3570       if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) {
3571         dupe_loc = scanner().location();
3572       }
3573       if (!reserved_loc.IsValid() && is_reserved) {
3574         reserved_loc = scanner().location();
3575       }
3576 
3577       Variable* parameter = top_scope_->DeclareLocal(param_name,
3578                                                      Variable::VAR,
3579                                                      Scope::PARAMETER);
3580       top_scope_->AddParameter(parameter);
3581       num_parameters++;
3582       if (num_parameters > kMaxNumFunctionParameters) {
3583         ReportMessageAt(scanner().location(), "too_many_parameters",
3584                         Vector<const char*>::empty());
3585         *ok = false;
3586         return NULL;
3587       }
3588       done = (peek() == Token::RPAREN);
3589       if (!done) Expect(Token::COMMA, CHECK_OK);
3590     }
3591     Expect(Token::RPAREN, CHECK_OK);
3592 
3593     Expect(Token::LBRACE, CHECK_OK);
3594 
3595     // If we have a named function expression, we add a local variable
3596     // declaration to the body of the function with the name of the
3597     // function and let it refer to the function itself (closure).
3598     // NOTE: We create a proxy and resolve it here so that in the
3599     // future we can change the AST to only refer to VariableProxies
3600     // instead of Variables and Proxis as is the case now.
3601     if (!function_name.is_null() && function_name->length() > 0) {
3602       Variable* fvar = top_scope_->DeclareFunctionVar(function_name);
3603       VariableProxy* fproxy =
3604           top_scope_->NewUnresolved(function_name, inside_with());
3605       fproxy->BindTo(fvar);
3606       body->Add(new(zone()) ExpressionStatement(
3607                     new(zone()) Assignment(Token::INIT_CONST, fproxy,
3608                                    new(zone()) ThisFunction(),
3609                                    RelocInfo::kNoPosition)));
3610     }
3611 
3612     // Determine if the function will be lazily compiled. The mode can
3613     // only be PARSE_LAZILY if the --lazy flag is true.
3614     bool is_lazily_compiled = (mode() == PARSE_LAZILY &&
3615                                top_scope_->outer_scope()->is_global_scope() &&
3616                                top_scope_->HasTrivialOuterContext() &&
3617                                !parenthesized_function_);
3618     parenthesized_function_ = false;  // The bit was set for this function only.
3619 
3620     int function_block_pos = scanner().location().beg_pos;
3621     if (is_lazily_compiled && pre_data() != NULL) {
3622       FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos);
3623       if (!entry.is_valid()) {
3624         ReportInvalidPreparseData(name, CHECK_OK);
3625       }
3626       end_pos = entry.end_pos();
3627       if (end_pos <= function_block_pos) {
3628         // End position greater than end of stream is safe, and hard to check.
3629         ReportInvalidPreparseData(name, CHECK_OK);
3630       }
3631       isolate()->counters()->total_preparse_skipped()->Increment(
3632           end_pos - function_block_pos);
3633       // Seek to position just before terminal '}'.
3634       scanner().SeekForward(end_pos - 1);
3635       materialized_literal_count = entry.literal_count();
3636       expected_property_count = entry.property_count();
3637       only_simple_this_property_assignments = false;
3638       this_property_assignments = isolate()->factory()->empty_fixed_array();
3639       Expect(Token::RBRACE, CHECK_OK);
3640     } else {
3641       ParseSourceElements(body, Token::RBRACE, CHECK_OK);
3642 
3643       materialized_literal_count = lexical_scope.materialized_literal_count();
3644       expected_property_count = lexical_scope.expected_property_count();
3645       only_simple_this_property_assignments =
3646           lexical_scope.only_simple_this_property_assignments();
3647       this_property_assignments = lexical_scope.this_property_assignments();
3648 
3649       Expect(Token::RBRACE, CHECK_OK);
3650       end_pos = scanner().location().end_pos;
3651     }
3652 
3653     // Validate strict mode.
3654     if (top_scope_->is_strict_mode()) {
3655       if (IsEvalOrArguments(name)) {
3656         int position = function_token_position != RelocInfo::kNoPosition
3657             ? function_token_position
3658             : (start_pos > 0 ? start_pos - 1 : start_pos);
3659         Scanner::Location location = Scanner::Location(position, start_pos);
3660         ReportMessageAt(location,
3661                         "strict_function_name", Vector<const char*>::empty());
3662         *ok = false;
3663         return NULL;
3664       }
3665       if (name_loc.IsValid()) {
3666         ReportMessageAt(name_loc, "strict_param_name",
3667                         Vector<const char*>::empty());
3668         *ok = false;
3669         return NULL;
3670       }
3671       if (dupe_loc.IsValid()) {
3672         ReportMessageAt(dupe_loc, "strict_param_dupe",
3673                         Vector<const char*>::empty());
3674         *ok = false;
3675         return NULL;
3676       }
3677       if (name_is_reserved) {
3678         int position = function_token_position != RelocInfo::kNoPosition
3679             ? function_token_position
3680             : (start_pos > 0 ? start_pos - 1 : start_pos);
3681         Scanner::Location location = Scanner::Location(position, start_pos);
3682         ReportMessageAt(location, "strict_reserved_word",
3683                         Vector<const char*>::empty());
3684         *ok = false;
3685         return NULL;
3686       }
3687       if (reserved_loc.IsValid()) {
3688         ReportMessageAt(reserved_loc, "strict_reserved_word",
3689                         Vector<const char*>::empty());
3690         *ok = false;
3691         return NULL;
3692       }
3693       CheckOctalLiteral(start_pos, end_pos, CHECK_OK);
3694     }
3695   }
3696 
3697   FunctionLiteral* function_literal =
3698       new(zone()) FunctionLiteral(name,
3699                                   scope,
3700                                   body,
3701                                   materialized_literal_count,
3702                                   expected_property_count,
3703                                   only_simple_this_property_assignments,
3704                                   this_property_assignments,
3705                                   num_parameters,
3706                                   start_pos,
3707                                   end_pos,
3708                                   (function_name->length() > 0));
3709   function_literal->set_function_token_position(function_token_position);
3710 
3711   if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal);
3712   return function_literal;
3713 }
3714 
3715 
ParseV8Intrinsic(bool * ok)3716 Expression* Parser::ParseV8Intrinsic(bool* ok) {
3717   // CallRuntime ::
3718   //   '%' Identifier Arguments
3719 
3720   Expect(Token::MOD, CHECK_OK);
3721   Handle<String> name = ParseIdentifier(CHECK_OK);
3722   ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
3723 
3724   if (extension_ != NULL) {
3725     // The extension structures are only accessible while parsing the
3726     // very first time not when reparsing because of lazy compilation.
3727     top_scope_->ForceEagerCompilation();
3728   }
3729 
3730   const Runtime::Function* function = Runtime::FunctionForSymbol(name);
3731 
3732   // Check for built-in IS_VAR macro.
3733   if (function != NULL &&
3734       function->intrinsic_type == Runtime::RUNTIME &&
3735       function->function_id == Runtime::kIS_VAR) {
3736     // %IS_VAR(x) evaluates to x if x is a variable,
3737     // leads to a parse error otherwise.  Could be implemented as an
3738     // inline function %_IS_VAR(x) to eliminate this special case.
3739     if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
3740       return args->at(0);
3741     } else {
3742       ReportMessage("unable_to_parse", Vector<const char*>::empty());
3743       *ok = false;
3744       return NULL;
3745     }
3746   }
3747 
3748   // Check that the expected number of arguments are being passed.
3749   if (function != NULL &&
3750       function->nargs != -1 &&
3751       function->nargs != args->length()) {
3752     ReportMessage("illegal_access", Vector<const char*>::empty());
3753     *ok = false;
3754     return NULL;
3755   }
3756 
3757   // We have a valid intrinsics call or a call to a builtin.
3758   return new(zone()) CallRuntime(name, function, args);
3759 }
3760 
3761 
peek_any_identifier()3762 bool Parser::peek_any_identifier() {
3763   Token::Value next = peek();
3764   return next == Token::IDENTIFIER ||
3765          next == Token::FUTURE_RESERVED_WORD;
3766 }
3767 
3768 
Consume(Token::Value token)3769 void Parser::Consume(Token::Value token) {
3770   Token::Value next = Next();
3771   USE(next);
3772   USE(token);
3773   ASSERT(next == token);
3774 }
3775 
3776 
Expect(Token::Value token,bool * ok)3777 void Parser::Expect(Token::Value token, bool* ok) {
3778   Token::Value next = Next();
3779   if (next == token) return;
3780   ReportUnexpectedToken(next);
3781   *ok = false;
3782 }
3783 
3784 
Check(Token::Value token)3785 bool Parser::Check(Token::Value token) {
3786   Token::Value next = peek();
3787   if (next == token) {
3788     Consume(next);
3789     return true;
3790   }
3791   return false;
3792 }
3793 
3794 
ExpectSemicolon(bool * ok)3795 void Parser::ExpectSemicolon(bool* ok) {
3796   // Check for automatic semicolon insertion according to
3797   // the rules given in ECMA-262, section 7.9, page 21.
3798   Token::Value tok = peek();
3799   if (tok == Token::SEMICOLON) {
3800     Next();
3801     return;
3802   }
3803   if (scanner().has_line_terminator_before_next() ||
3804       tok == Token::RBRACE ||
3805       tok == Token::EOS) {
3806     return;
3807   }
3808   Expect(Token::SEMICOLON, ok);
3809 }
3810 
3811 
GetLiteralUndefined()3812 Literal* Parser::GetLiteralUndefined() {
3813   return new(zone()) Literal(isolate()->factory()->undefined_value());
3814 }
3815 
3816 
GetLiteralTheHole()3817 Literal* Parser::GetLiteralTheHole() {
3818   return new(zone()) Literal(isolate()->factory()->the_hole_value());
3819 }
3820 
3821 
GetLiteralNumber(double value)3822 Literal* Parser::GetLiteralNumber(double value) {
3823   return NewNumberLiteral(value);
3824 }
3825 
3826 
ParseIdentifier(bool * ok)3827 Handle<String> Parser::ParseIdentifier(bool* ok) {
3828   bool is_reserved;
3829   return ParseIdentifierOrReservedWord(&is_reserved, ok);
3830 }
3831 
3832 
ParseIdentifierOrReservedWord(bool * is_reserved,bool * ok)3833 Handle<String> Parser::ParseIdentifierOrReservedWord(bool* is_reserved,
3834                                                      bool* ok) {
3835   *is_reserved = false;
3836   if (top_scope_->is_strict_mode()) {
3837     Expect(Token::IDENTIFIER, ok);
3838   } else {
3839     if (!Check(Token::IDENTIFIER)) {
3840       Expect(Token::FUTURE_RESERVED_WORD, ok);
3841       *is_reserved = true;
3842     }
3843   }
3844   if (!*ok) return Handle<String>();
3845   return GetSymbol(ok);
3846 }
3847 
3848 
ParseIdentifierName(bool * ok)3849 Handle<String> Parser::ParseIdentifierName(bool* ok) {
3850   Token::Value next = Next();
3851   if (next != Token::IDENTIFIER &&
3852           next != Token::FUTURE_RESERVED_WORD &&
3853           !Token::IsKeyword(next)) {
3854     ReportUnexpectedToken(next);
3855     *ok = false;
3856     return Handle<String>();
3857   }
3858   return GetSymbol(ok);
3859 }
3860 
3861 
3862 // Checks LHS expression for assignment and prefix/postfix increment/decrement
3863 // in strict mode.
CheckStrictModeLValue(Expression * expression,const char * error,bool * ok)3864 void Parser::CheckStrictModeLValue(Expression* expression,
3865                                    const char* error,
3866                                    bool* ok) {
3867   ASSERT(top_scope_->is_strict_mode());
3868   VariableProxy* lhs = expression != NULL
3869       ? expression->AsVariableProxy()
3870       : NULL;
3871 
3872   if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) {
3873     ReportMessage(error, Vector<const char*>::empty());
3874     *ok = false;
3875   }
3876 }
3877 
3878 
3879 // Checks whether octal literal last seen is between beg_pos and end_pos.
3880 // If so, reports an error.
CheckOctalLiteral(int beg_pos,int end_pos,bool * ok)3881 void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
3882   int octal = scanner().octal_position();
3883   if (beg_pos <= octal && octal <= end_pos) {
3884     ReportMessageAt(Scanner::Location(octal, octal + 1), "strict_octal_literal",
3885                     Vector<const char*>::empty());
3886     scanner().clear_octal_position();
3887     *ok = false;
3888   }
3889 }
3890 
3891 
3892 // This function reads an identifier and determines whether or not it
3893 // is 'get' or 'set'.
ParseIdentifierOrGetOrSet(bool * is_get,bool * is_set,bool * ok)3894 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get,
3895                                                  bool* is_set,
3896                                                  bool* ok) {
3897   Handle<String> result = ParseIdentifier(ok);
3898   if (!*ok) return Handle<String>();
3899   if (scanner().is_literal_ascii() && scanner().literal_length() == 3) {
3900     const char* token = scanner().literal_ascii_string().start();
3901     *is_get = strncmp(token, "get", 3) == 0;
3902     *is_set = !*is_get && strncmp(token, "set", 3) == 0;
3903   }
3904   return result;
3905 }
3906 
3907 
3908 // ----------------------------------------------------------------------------
3909 // Parser support
3910 
3911 
TargetStackContainsLabel(Handle<String> label)3912 bool Parser::TargetStackContainsLabel(Handle<String> label) {
3913   for (Target* t = target_stack_; t != NULL; t = t->previous()) {
3914     BreakableStatement* stat = t->node()->AsBreakableStatement();
3915     if (stat != NULL && ContainsLabel(stat->labels(), label))
3916       return true;
3917   }
3918   return false;
3919 }
3920 
3921 
LookupBreakTarget(Handle<String> label,bool * ok)3922 BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) {
3923   bool anonymous = label.is_null();
3924   for (Target* t = target_stack_; t != NULL; t = t->previous()) {
3925     BreakableStatement* stat = t->node()->AsBreakableStatement();
3926     if (stat == NULL) continue;
3927     if ((anonymous && stat->is_target_for_anonymous()) ||
3928         (!anonymous && ContainsLabel(stat->labels(), label))) {
3929       RegisterTargetUse(stat->break_target(), t->previous());
3930       return stat;
3931     }
3932   }
3933   return NULL;
3934 }
3935 
3936 
LookupContinueTarget(Handle<String> label,bool * ok)3937 IterationStatement* Parser::LookupContinueTarget(Handle<String> label,
3938                                                  bool* ok) {
3939   bool anonymous = label.is_null();
3940   for (Target* t = target_stack_; t != NULL; t = t->previous()) {
3941     IterationStatement* stat = t->node()->AsIterationStatement();
3942     if (stat == NULL) continue;
3943 
3944     ASSERT(stat->is_target_for_anonymous());
3945     if (anonymous || ContainsLabel(stat->labels(), label)) {
3946       RegisterTargetUse(stat->continue_target(), t->previous());
3947       return stat;
3948     }
3949   }
3950   return NULL;
3951 }
3952 
3953 
RegisterTargetUse(Label * target,Target * stop)3954 void Parser::RegisterTargetUse(Label* target, Target* stop) {
3955   // Register that a break target found at the given stop in the
3956   // target stack has been used from the top of the target stack. Add
3957   // the break target to any TargetCollectors passed on the stack.
3958   for (Target* t = target_stack_; t != stop; t = t->previous()) {
3959     TargetCollector* collector = t->node()->AsTargetCollector();
3960     if (collector != NULL) collector->AddTarget(target);
3961   }
3962 }
3963 
3964 
NewNumberLiteral(double number)3965 Literal* Parser::NewNumberLiteral(double number) {
3966   return new(zone()) Literal(isolate()->factory()->NewNumber(number, TENURED));
3967 }
3968 
3969 
NewThrowReferenceError(Handle<String> type)3970 Expression* Parser::NewThrowReferenceError(Handle<String> type) {
3971   return NewThrowError(isolate()->factory()->MakeReferenceError_symbol(),
3972                        type, HandleVector<Object>(NULL, 0));
3973 }
3974 
3975 
NewThrowSyntaxError(Handle<String> type,Handle<Object> first)3976 Expression* Parser::NewThrowSyntaxError(Handle<String> type,
3977                                         Handle<Object> first) {
3978   int argc = first.is_null() ? 0 : 1;
3979   Vector< Handle<Object> > arguments = HandleVector<Object>(&first, argc);
3980   return NewThrowError(
3981       isolate()->factory()->MakeSyntaxError_symbol(), type, arguments);
3982 }
3983 
3984 
NewThrowTypeError(Handle<String> type,Handle<Object> first,Handle<Object> second)3985 Expression* Parser::NewThrowTypeError(Handle<String> type,
3986                                       Handle<Object> first,
3987                                       Handle<Object> second) {
3988   ASSERT(!first.is_null() && !second.is_null());
3989   Handle<Object> elements[] = { first, second };
3990   Vector< Handle<Object> > arguments =
3991       HandleVector<Object>(elements, ARRAY_SIZE(elements));
3992   return NewThrowError(
3993       isolate()->factory()->MakeTypeError_symbol(), type, arguments);
3994 }
3995 
3996 
NewThrowError(Handle<String> constructor,Handle<String> type,Vector<Handle<Object>> arguments)3997 Expression* Parser::NewThrowError(Handle<String> constructor,
3998                                   Handle<String> type,
3999                                   Vector< Handle<Object> > arguments) {
4000   int argc = arguments.length();
4001   Handle<FixedArray> elements = isolate()->factory()->NewFixedArray(argc,
4002                                                                     TENURED);
4003   for (int i = 0; i < argc; i++) {
4004     Handle<Object> element = arguments[i];
4005     if (!element.is_null()) {
4006       elements->set(i, *element);
4007     }
4008   }
4009   Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements(elements,
4010                                                                        TENURED);
4011 
4012   ZoneList<Expression*>* args = new ZoneList<Expression*>(2);
4013   args->Add(new(zone()) Literal(type));
4014   args->Add(new(zone()) Literal(array));
4015   return new(zone()) Throw(new(zone()) CallRuntime(constructor, NULL, args),
4016                    scanner().location().beg_pos);
4017 }
4018 
4019 // ----------------------------------------------------------------------------
4020 // JSON
4021 
ParseJson(Handle<String> script,UC16CharacterStream * source)4022 Handle<Object> JsonParser::ParseJson(Handle<String> script,
4023                                      UC16CharacterStream* source) {
4024   scanner_.Initialize(source);
4025   stack_overflow_ = false;
4026   Handle<Object> result = ParseJsonValue();
4027   if (result.is_null() || scanner_.Next() != Token::EOS) {
4028     if (stack_overflow_) {
4029       // Scanner failed.
4030       isolate()->StackOverflow();
4031     } else {
4032       // Parse failed. Scanner's current token is the unexpected token.
4033       Token::Value token = scanner_.current_token();
4034 
4035       const char* message;
4036       const char* name_opt = NULL;
4037 
4038       switch (token) {
4039         case Token::EOS:
4040           message = "unexpected_eos";
4041           break;
4042         case Token::NUMBER:
4043           message = "unexpected_token_number";
4044           break;
4045         case Token::STRING:
4046           message = "unexpected_token_string";
4047           break;
4048         case Token::IDENTIFIER:
4049         case Token::FUTURE_RESERVED_WORD:
4050           message = "unexpected_token_identifier";
4051           break;
4052         default:
4053           message = "unexpected_token";
4054           name_opt = Token::String(token);
4055           ASSERT(name_opt != NULL);
4056           break;
4057       }
4058 
4059       Scanner::Location source_location = scanner_.location();
4060       Factory* factory = isolate()->factory();
4061       MessageLocation location(factory->NewScript(script),
4062                                source_location.beg_pos,
4063                                source_location.end_pos);
4064       Handle<JSArray> array;
4065       if (name_opt == NULL) {
4066         array = factory->NewJSArray(0);
4067       } else {
4068         Handle<String> name = factory->NewStringFromUtf8(CStrVector(name_opt));
4069         Handle<FixedArray> element = factory->NewFixedArray(1);
4070         element->set(0, *name);
4071         array = factory->NewJSArrayWithElements(element);
4072       }
4073       Handle<Object> result = factory->NewSyntaxError(message, array);
4074       isolate()->Throw(*result, &location);
4075       return Handle<Object>::null();
4076     }
4077   }
4078   return result;
4079 }
4080 
4081 
GetString()4082 Handle<String> JsonParser::GetString() {
4083   int literal_length = scanner_.literal_length();
4084   if (literal_length == 0) {
4085     return isolate()->factory()->empty_string();
4086   }
4087   if (scanner_.is_literal_ascii()) {
4088     return isolate()->factory()->NewStringFromAscii(
4089         scanner_.literal_ascii_string());
4090   } else {
4091     return isolate()->factory()->NewStringFromTwoByte(
4092         scanner_.literal_uc16_string());
4093   }
4094 }
4095 
4096 
4097 // Parse any JSON value.
ParseJsonValue()4098 Handle<Object> JsonParser::ParseJsonValue() {
4099   Token::Value token = scanner_.Next();
4100   switch (token) {
4101     case Token::STRING:
4102       return GetString();
4103     case Token::NUMBER:
4104       return isolate()->factory()->NewNumber(scanner_.number());
4105     case Token::FALSE_LITERAL:
4106       return isolate()->factory()->false_value();
4107     case Token::TRUE_LITERAL:
4108       return isolate()->factory()->true_value();
4109     case Token::NULL_LITERAL:
4110       return isolate()->factory()->null_value();
4111     case Token::LBRACE:
4112       return ParseJsonObject();
4113     case Token::LBRACK:
4114       return ParseJsonArray();
4115     default:
4116       return ReportUnexpectedToken();
4117   }
4118 }
4119 
4120 
4121 // Parse a JSON object. Scanner must be right after '{' token.
ParseJsonObject()4122 Handle<Object> JsonParser::ParseJsonObject() {
4123   Handle<JSFunction> object_constructor(
4124       isolate()->global_context()->object_function());
4125   Handle<JSObject> json_object =
4126       isolate()->factory()->NewJSObject(object_constructor);
4127   if (scanner_.peek() == Token::RBRACE) {
4128     scanner_.Next();
4129   } else {
4130     if (StackLimitCheck(isolate()).HasOverflowed()) {
4131       stack_overflow_ = true;
4132       return Handle<Object>::null();
4133     }
4134     do {
4135       if (scanner_.Next() != Token::STRING) {
4136         return ReportUnexpectedToken();
4137       }
4138       Handle<String> key = GetString();
4139       if (scanner_.Next() != Token::COLON) {
4140         return ReportUnexpectedToken();
4141       }
4142       Handle<Object> value = ParseJsonValue();
4143       if (value.is_null()) return Handle<Object>::null();
4144       uint32_t index;
4145       if (key->AsArrayIndex(&index)) {
4146         SetOwnElement(json_object, index, value, kNonStrictMode);
4147       } else if (key->Equals(isolate()->heap()->Proto_symbol())) {
4148         // We can't remove the __proto__ accessor since it's hardcoded
4149         // in several places. Instead go along and add the value as
4150         // the prototype of the created object if possible.
4151         SetPrototype(json_object, value);
4152       } else {
4153         SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE);
4154       }
4155     } while (scanner_.Next() == Token::COMMA);
4156     if (scanner_.current_token() != Token::RBRACE) {
4157       return ReportUnexpectedToken();
4158     }
4159   }
4160   return json_object;
4161 }
4162 
4163 
4164 // Parse a JSON array. Scanner must be right after '[' token.
ParseJsonArray()4165 Handle<Object> JsonParser::ParseJsonArray() {
4166   ZoneScope zone_scope(DELETE_ON_EXIT);
4167   ZoneList<Handle<Object> > elements(4);
4168 
4169   Token::Value token = scanner_.peek();
4170   if (token == Token::RBRACK) {
4171     scanner_.Next();
4172   } else {
4173     if (StackLimitCheck(isolate()).HasOverflowed()) {
4174       stack_overflow_ = true;
4175       return Handle<Object>::null();
4176     }
4177     do {
4178       Handle<Object> element = ParseJsonValue();
4179       if (element.is_null()) return Handle<Object>::null();
4180       elements.Add(element);
4181       token = scanner_.Next();
4182     } while (token == Token::COMMA);
4183     if (token != Token::RBRACK) {
4184       return ReportUnexpectedToken();
4185     }
4186   }
4187 
4188   // Allocate a fixed array with all the elements.
4189   Handle<FixedArray> fast_elements =
4190       isolate()->factory()->NewFixedArray(elements.length());
4191 
4192   for (int i = 0, n = elements.length(); i < n; i++) {
4193     fast_elements->set(i, *elements[i]);
4194   }
4195 
4196   return isolate()->factory()->NewJSArrayWithElements(fast_elements);
4197 }
4198 
4199 // ----------------------------------------------------------------------------
4200 // Regular expressions
4201 
4202 
RegExpParser(FlatStringReader * in,Handle<String> * error,bool multiline)4203 RegExpParser::RegExpParser(FlatStringReader* in,
4204                            Handle<String>* error,
4205                            bool multiline)
4206     : isolate_(Isolate::Current()),
4207       error_(error),
4208       captures_(NULL),
4209       in_(in),
4210       current_(kEndMarker),
4211       next_pos_(0),
4212       capture_count_(0),
4213       has_more_(true),
4214       multiline_(multiline),
4215       simple_(false),
4216       contains_anchor_(false),
4217       is_scanned_for_captures_(false),
4218       failed_(false) {
4219   Advance();
4220 }
4221 
4222 
Next()4223 uc32 RegExpParser::Next() {
4224   if (has_next()) {
4225     return in()->Get(next_pos_);
4226   } else {
4227     return kEndMarker;
4228   }
4229 }
4230 
4231 
Advance()4232 void RegExpParser::Advance() {
4233   if (next_pos_ < in()->length()) {
4234     StackLimitCheck check(isolate());
4235     if (check.HasOverflowed()) {
4236       ReportError(CStrVector(Isolate::kStackOverflowMessage));
4237     } else if (isolate()->zone()->excess_allocation()) {
4238       ReportError(CStrVector("Regular expression too large"));
4239     } else {
4240       current_ = in()->Get(next_pos_);
4241       next_pos_++;
4242     }
4243   } else {
4244     current_ = kEndMarker;
4245     has_more_ = false;
4246   }
4247 }
4248 
4249 
Reset(int pos)4250 void RegExpParser::Reset(int pos) {
4251   next_pos_ = pos;
4252   Advance();
4253 }
4254 
4255 
Advance(int dist)4256 void RegExpParser::Advance(int dist) {
4257   next_pos_ += dist - 1;
4258   Advance();
4259 }
4260 
4261 
simple()4262 bool RegExpParser::simple() {
4263   return simple_;
4264 }
4265 
ReportError(Vector<const char> message)4266 RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
4267   failed_ = true;
4268   *error_ = isolate()->factory()->NewStringFromAscii(message, NOT_TENURED);
4269   // Zip to the end to make sure the no more input is read.
4270   current_ = kEndMarker;
4271   next_pos_ = in()->length();
4272   return NULL;
4273 }
4274 
4275 
4276 // Pattern ::
4277 //   Disjunction
ParsePattern()4278 RegExpTree* RegExpParser::ParsePattern() {
4279   RegExpTree* result = ParseDisjunction(CHECK_FAILED);
4280   ASSERT(!has_more());
4281   // If the result of parsing is a literal string atom, and it has the
4282   // same length as the input, then the atom is identical to the input.
4283   if (result->IsAtom() && result->AsAtom()->length() == in()->length()) {
4284     simple_ = true;
4285   }
4286   return result;
4287 }
4288 
4289 
4290 // Disjunction ::
4291 //   Alternative
4292 //   Alternative | Disjunction
4293 // Alternative ::
4294 //   [empty]
4295 //   Term Alternative
4296 // Term ::
4297 //   Assertion
4298 //   Atom
4299 //   Atom Quantifier
ParseDisjunction()4300 RegExpTree* RegExpParser::ParseDisjunction() {
4301   // Used to store current state while parsing subexpressions.
4302   RegExpParserState initial_state(NULL, INITIAL, 0);
4303   RegExpParserState* stored_state = &initial_state;
4304   // Cache the builder in a local variable for quick access.
4305   RegExpBuilder* builder = initial_state.builder();
4306   while (true) {
4307     switch (current()) {
4308     case kEndMarker:
4309       if (stored_state->IsSubexpression()) {
4310         // Inside a parenthesized group when hitting end of input.
4311         ReportError(CStrVector("Unterminated group") CHECK_FAILED);
4312       }
4313       ASSERT_EQ(INITIAL, stored_state->group_type());
4314       // Parsing completed successfully.
4315       return builder->ToRegExp();
4316     case ')': {
4317       if (!stored_state->IsSubexpression()) {
4318         ReportError(CStrVector("Unmatched ')'") CHECK_FAILED);
4319       }
4320       ASSERT_NE(INITIAL, stored_state->group_type());
4321 
4322       Advance();
4323       // End disjunction parsing and convert builder content to new single
4324       // regexp atom.
4325       RegExpTree* body = builder->ToRegExp();
4326 
4327       int end_capture_index = captures_started();
4328 
4329       int capture_index = stored_state->capture_index();
4330       SubexpressionType type = stored_state->group_type();
4331 
4332       // Restore previous state.
4333       stored_state = stored_state->previous_state();
4334       builder = stored_state->builder();
4335 
4336       // Build result of subexpression.
4337       if (type == CAPTURE) {
4338         RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index);
4339         captures_->at(capture_index - 1) = capture;
4340         body = capture;
4341       } else if (type != GROUPING) {
4342         ASSERT(type == POSITIVE_LOOKAHEAD || type == NEGATIVE_LOOKAHEAD);
4343         bool is_positive = (type == POSITIVE_LOOKAHEAD);
4344         body = new(zone()) RegExpLookahead(body,
4345                                    is_positive,
4346                                    end_capture_index - capture_index,
4347                                    capture_index);
4348       }
4349       builder->AddAtom(body);
4350       // For compatability with JSC and ES3, we allow quantifiers after
4351       // lookaheads, and break in all cases.
4352       break;
4353     }
4354     case '|': {
4355       Advance();
4356       builder->NewAlternative();
4357       continue;
4358     }
4359     case '*':
4360     case '+':
4361     case '?':
4362       return ReportError(CStrVector("Nothing to repeat"));
4363     case '^': {
4364       Advance();
4365       if (multiline_) {
4366         builder->AddAssertion(
4367             new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE));
4368       } else {
4369         builder->AddAssertion(
4370             new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
4371         set_contains_anchor();
4372       }
4373       continue;
4374     }
4375     case '$': {
4376       Advance();
4377       RegExpAssertion::Type type =
4378           multiline_ ? RegExpAssertion::END_OF_LINE :
4379                        RegExpAssertion::END_OF_INPUT;
4380       builder->AddAssertion(new(zone()) RegExpAssertion(type));
4381       continue;
4382     }
4383     case '.': {
4384       Advance();
4385       // everything except \x0a, \x0d, \u2028 and \u2029
4386       ZoneList<CharacterRange>* ranges = new ZoneList<CharacterRange>(2);
4387       CharacterRange::AddClassEscape('.', ranges);
4388       RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
4389       builder->AddAtom(atom);
4390       break;
4391     }
4392     case '(': {
4393       SubexpressionType type = CAPTURE;
4394       Advance();
4395       if (current() == '?') {
4396         switch (Next()) {
4397           case ':':
4398             type = GROUPING;
4399             break;
4400           case '=':
4401             type = POSITIVE_LOOKAHEAD;
4402             break;
4403           case '!':
4404             type = NEGATIVE_LOOKAHEAD;
4405             break;
4406           default:
4407             ReportError(CStrVector("Invalid group") CHECK_FAILED);
4408             break;
4409         }
4410         Advance(2);
4411       } else {
4412         if (captures_ == NULL) {
4413           captures_ = new ZoneList<RegExpCapture*>(2);
4414         }
4415         if (captures_started() >= kMaxCaptures) {
4416           ReportError(CStrVector("Too many captures") CHECK_FAILED);
4417         }
4418         captures_->Add(NULL);
4419       }
4420       // Store current state and begin new disjunction parsing.
4421       stored_state = new(zone()) RegExpParserState(stored_state,
4422                                            type,
4423                                            captures_started());
4424       builder = stored_state->builder();
4425       continue;
4426     }
4427     case '[': {
4428       RegExpTree* atom = ParseCharacterClass(CHECK_FAILED);
4429       builder->AddAtom(atom);
4430       break;
4431     }
4432     // Atom ::
4433     //   \ AtomEscape
4434     case '\\':
4435       switch (Next()) {
4436       case kEndMarker:
4437         return ReportError(CStrVector("\\ at end of pattern"));
4438       case 'b':
4439         Advance(2);
4440         builder->AddAssertion(
4441             new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
4442         continue;
4443       case 'B':
4444         Advance(2);
4445         builder->AddAssertion(
4446             new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
4447         continue;
4448       // AtomEscape ::
4449       //   CharacterClassEscape
4450       //
4451       // CharacterClassEscape :: one of
4452       //   d D s S w W
4453       case 'd': case 'D': case 's': case 'S': case 'w': case 'W': {
4454         uc32 c = Next();
4455         Advance(2);
4456         ZoneList<CharacterRange>* ranges = new ZoneList<CharacterRange>(2);
4457         CharacterRange::AddClassEscape(c, ranges);
4458         RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
4459         builder->AddAtom(atom);
4460         break;
4461       }
4462       case '1': case '2': case '3': case '4': case '5': case '6':
4463       case '7': case '8': case '9': {
4464         int index = 0;
4465         if (ParseBackReferenceIndex(&index)) {
4466           RegExpCapture* capture = NULL;
4467           if (captures_ != NULL && index <= captures_->length()) {
4468             capture = captures_->at(index - 1);
4469           }
4470           if (capture == NULL) {
4471             builder->AddEmpty();
4472             break;
4473           }
4474           RegExpTree* atom = new(zone()) RegExpBackReference(capture);
4475           builder->AddAtom(atom);
4476           break;
4477         }
4478         uc32 first_digit = Next();
4479         if (first_digit == '8' || first_digit == '9') {
4480           // Treat as identity escape
4481           builder->AddCharacter(first_digit);
4482           Advance(2);
4483           break;
4484         }
4485       }
4486       // FALLTHROUGH
4487       case '0': {
4488         Advance();
4489         uc32 octal = ParseOctalLiteral();
4490         builder->AddCharacter(octal);
4491         break;
4492       }
4493       // ControlEscape :: one of
4494       //   f n r t v
4495       case 'f':
4496         Advance(2);
4497         builder->AddCharacter('\f');
4498         break;
4499       case 'n':
4500         Advance(2);
4501         builder->AddCharacter('\n');
4502         break;
4503       case 'r':
4504         Advance(2);
4505         builder->AddCharacter('\r');
4506         break;
4507       case 't':
4508         Advance(2);
4509         builder->AddCharacter('\t');
4510         break;
4511       case 'v':
4512         Advance(2);
4513         builder->AddCharacter('\v');
4514         break;
4515       case 'c': {
4516         Advance();
4517         uc32 controlLetter = Next();
4518         // Special case if it is an ASCII letter.
4519         // Convert lower case letters to uppercase.
4520         uc32 letter = controlLetter & ~('a' ^ 'A');
4521         if (letter < 'A' || 'Z' < letter) {
4522           // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
4523           // This is outside the specification. We match JSC in
4524           // reading the backslash as a literal character instead
4525           // of as starting an escape.
4526           builder->AddCharacter('\\');
4527         } else {
4528           Advance(2);
4529           builder->AddCharacter(controlLetter & 0x1f);
4530         }
4531         break;
4532       }
4533       case 'x': {
4534         Advance(2);
4535         uc32 value;
4536         if (ParseHexEscape(2, &value)) {
4537           builder->AddCharacter(value);
4538         } else {
4539           builder->AddCharacter('x');
4540         }
4541         break;
4542       }
4543       case 'u': {
4544         Advance(2);
4545         uc32 value;
4546         if (ParseHexEscape(4, &value)) {
4547           builder->AddCharacter(value);
4548         } else {
4549           builder->AddCharacter('u');
4550         }
4551         break;
4552       }
4553       default:
4554         // Identity escape.
4555         builder->AddCharacter(Next());
4556         Advance(2);
4557         break;
4558       }
4559       break;
4560     case '{': {
4561       int dummy;
4562       if (ParseIntervalQuantifier(&dummy, &dummy)) {
4563         ReportError(CStrVector("Nothing to repeat") CHECK_FAILED);
4564       }
4565       // fallthrough
4566     }
4567     default:
4568       builder->AddCharacter(current());
4569       Advance();
4570       break;
4571     }  // end switch(current())
4572 
4573     int min;
4574     int max;
4575     switch (current()) {
4576     // QuantifierPrefix ::
4577     //   *
4578     //   +
4579     //   ?
4580     //   {
4581     case '*':
4582       min = 0;
4583       max = RegExpTree::kInfinity;
4584       Advance();
4585       break;
4586     case '+':
4587       min = 1;
4588       max = RegExpTree::kInfinity;
4589       Advance();
4590       break;
4591     case '?':
4592       min = 0;
4593       max = 1;
4594       Advance();
4595       break;
4596     case '{':
4597       if (ParseIntervalQuantifier(&min, &max)) {
4598         if (max < min) {
4599           ReportError(CStrVector("numbers out of order in {} quantifier.")
4600                       CHECK_FAILED);
4601         }
4602         break;
4603       } else {
4604         continue;
4605       }
4606     default:
4607       continue;
4608     }
4609     RegExpQuantifier::Type type = RegExpQuantifier::GREEDY;
4610     if (current() == '?') {
4611       type = RegExpQuantifier::NON_GREEDY;
4612       Advance();
4613     } else if (FLAG_regexp_possessive_quantifier && current() == '+') {
4614       // FLAG_regexp_possessive_quantifier is a debug-only flag.
4615       type = RegExpQuantifier::POSSESSIVE;
4616       Advance();
4617     }
4618     builder->AddQuantifierToAtom(min, max, type);
4619   }
4620 }
4621 
4622 
4623 #ifdef DEBUG
4624 // Currently only used in an ASSERT.
IsSpecialClassEscape(uc32 c)4625 static bool IsSpecialClassEscape(uc32 c) {
4626   switch (c) {
4627     case 'd': case 'D':
4628     case 's': case 'S':
4629     case 'w': case 'W':
4630       return true;
4631     default:
4632       return false;
4633   }
4634 }
4635 #endif
4636 
4637 
4638 // In order to know whether an escape is a backreference or not we have to scan
4639 // the entire regexp and find the number of capturing parentheses.  However we
4640 // don't want to scan the regexp twice unless it is necessary.  This mini-parser
4641 // is called when needed.  It can see the difference between capturing and
4642 // noncapturing parentheses and can skip character classes and backslash-escaped
4643 // characters.
ScanForCaptures()4644 void RegExpParser::ScanForCaptures() {
4645   // Start with captures started previous to current position
4646   int capture_count = captures_started();
4647   // Add count of captures after this position.
4648   int n;
4649   while ((n = current()) != kEndMarker) {
4650     Advance();
4651     switch (n) {
4652       case '\\':
4653         Advance();
4654         break;
4655       case '[': {
4656         int c;
4657         while ((c = current()) != kEndMarker) {
4658           Advance();
4659           if (c == '\\') {
4660             Advance();
4661           } else {
4662             if (c == ']') break;
4663           }
4664         }
4665         break;
4666       }
4667       case '(':
4668         if (current() != '?') capture_count++;
4669         break;
4670     }
4671   }
4672   capture_count_ = capture_count;
4673   is_scanned_for_captures_ = true;
4674 }
4675 
4676 
ParseBackReferenceIndex(int * index_out)4677 bool RegExpParser::ParseBackReferenceIndex(int* index_out) {
4678   ASSERT_EQ('\\', current());
4679   ASSERT('1' <= Next() && Next() <= '9');
4680   // Try to parse a decimal literal that is no greater than the total number
4681   // of left capturing parentheses in the input.
4682   int start = position();
4683   int value = Next() - '0';
4684   Advance(2);
4685   while (true) {
4686     uc32 c = current();
4687     if (IsDecimalDigit(c)) {
4688       value = 10 * value + (c - '0');
4689       if (value > kMaxCaptures) {
4690         Reset(start);
4691         return false;
4692       }
4693       Advance();
4694     } else {
4695       break;
4696     }
4697   }
4698   if (value > captures_started()) {
4699     if (!is_scanned_for_captures_) {
4700       int saved_position = position();
4701       ScanForCaptures();
4702       Reset(saved_position);
4703     }
4704     if (value > capture_count_) {
4705       Reset(start);
4706       return false;
4707     }
4708   }
4709   *index_out = value;
4710   return true;
4711 }
4712 
4713 
4714 // QuantifierPrefix ::
4715 //   { DecimalDigits }
4716 //   { DecimalDigits , }
4717 //   { DecimalDigits , DecimalDigits }
4718 //
4719 // Returns true if parsing succeeds, and set the min_out and max_out
4720 // values. Values are truncated to RegExpTree::kInfinity if they overflow.
ParseIntervalQuantifier(int * min_out,int * max_out)4721 bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
4722   ASSERT_EQ(current(), '{');
4723   int start = position();
4724   Advance();
4725   int min = 0;
4726   if (!IsDecimalDigit(current())) {
4727     Reset(start);
4728     return false;
4729   }
4730   while (IsDecimalDigit(current())) {
4731     int next = current() - '0';
4732     if (min > (RegExpTree::kInfinity - next) / 10) {
4733       // Overflow. Skip past remaining decimal digits and return -1.
4734       do {
4735         Advance();
4736       } while (IsDecimalDigit(current()));
4737       min = RegExpTree::kInfinity;
4738       break;
4739     }
4740     min = 10 * min + next;
4741     Advance();
4742   }
4743   int max = 0;
4744   if (current() == '}') {
4745     max = min;
4746     Advance();
4747   } else if (current() == ',') {
4748     Advance();
4749     if (current() == '}') {
4750       max = RegExpTree::kInfinity;
4751       Advance();
4752     } else {
4753       while (IsDecimalDigit(current())) {
4754         int next = current() - '0';
4755         if (max > (RegExpTree::kInfinity - next) / 10) {
4756           do {
4757             Advance();
4758           } while (IsDecimalDigit(current()));
4759           max = RegExpTree::kInfinity;
4760           break;
4761         }
4762         max = 10 * max + next;
4763         Advance();
4764       }
4765       if (current() != '}') {
4766         Reset(start);
4767         return false;
4768       }
4769       Advance();
4770     }
4771   } else {
4772     Reset(start);
4773     return false;
4774   }
4775   *min_out = min;
4776   *max_out = max;
4777   return true;
4778 }
4779 
4780 
ParseOctalLiteral()4781 uc32 RegExpParser::ParseOctalLiteral() {
4782   ASSERT('0' <= current() && current() <= '7');
4783   // For compatibility with some other browsers (not all), we parse
4784   // up to three octal digits with a value below 256.
4785   uc32 value = current() - '0';
4786   Advance();
4787   if ('0' <= current() && current() <= '7') {
4788     value = value * 8 + current() - '0';
4789     Advance();
4790     if (value < 32 && '0' <= current() && current() <= '7') {
4791       value = value * 8 + current() - '0';
4792       Advance();
4793     }
4794   }
4795   return value;
4796 }
4797 
4798 
ParseHexEscape(int length,uc32 * value)4799 bool RegExpParser::ParseHexEscape(int length, uc32 *value) {
4800   int start = position();
4801   uc32 val = 0;
4802   bool done = false;
4803   for (int i = 0; !done; i++) {
4804     uc32 c = current();
4805     int d = HexValue(c);
4806     if (d < 0) {
4807       Reset(start);
4808       return false;
4809     }
4810     val = val * 16 + d;
4811     Advance();
4812     if (i == length - 1) {
4813       done = true;
4814     }
4815   }
4816   *value = val;
4817   return true;
4818 }
4819 
4820 
ParseClassCharacterEscape()4821 uc32 RegExpParser::ParseClassCharacterEscape() {
4822   ASSERT(current() == '\\');
4823   ASSERT(has_next() && !IsSpecialClassEscape(Next()));
4824   Advance();
4825   switch (current()) {
4826     case 'b':
4827       Advance();
4828       return '\b';
4829     // ControlEscape :: one of
4830     //   f n r t v
4831     case 'f':
4832       Advance();
4833       return '\f';
4834     case 'n':
4835       Advance();
4836       return '\n';
4837     case 'r':
4838       Advance();
4839       return '\r';
4840     case 't':
4841       Advance();
4842       return '\t';
4843     case 'v':
4844       Advance();
4845       return '\v';
4846     case 'c': {
4847       uc32 controlLetter = Next();
4848       uc32 letter = controlLetter & ~('A' ^ 'a');
4849       // For compatibility with JSC, inside a character class
4850       // we also accept digits and underscore as control characters.
4851       if ((controlLetter >= '0' && controlLetter <= '9') ||
4852           controlLetter == '_' ||
4853           (letter >= 'A' && letter <= 'Z')) {
4854         Advance(2);
4855         // Control letters mapped to ASCII control characters in the range
4856         // 0x00-0x1f.
4857         return controlLetter & 0x1f;
4858       }
4859       // We match JSC in reading the backslash as a literal
4860       // character instead of as starting an escape.
4861       return '\\';
4862     }
4863     case '0': case '1': case '2': case '3': case '4': case '5':
4864     case '6': case '7':
4865       // For compatibility, we interpret a decimal escape that isn't
4866       // a back reference (and therefore either \0 or not valid according
4867       // to the specification) as a 1..3 digit octal character code.
4868       return ParseOctalLiteral();
4869     case 'x': {
4870       Advance();
4871       uc32 value;
4872       if (ParseHexEscape(2, &value)) {
4873         return value;
4874       }
4875       // If \x is not followed by a two-digit hexadecimal, treat it
4876       // as an identity escape.
4877       return 'x';
4878     }
4879     case 'u': {
4880       Advance();
4881       uc32 value;
4882       if (ParseHexEscape(4, &value)) {
4883         return value;
4884       }
4885       // If \u is not followed by a four-digit hexadecimal, treat it
4886       // as an identity escape.
4887       return 'u';
4888     }
4889     default: {
4890       // Extended identity escape. We accept any character that hasn't
4891       // been matched by a more specific case, not just the subset required
4892       // by the ECMAScript specification.
4893       uc32 result = current();
4894       Advance();
4895       return result;
4896     }
4897   }
4898   return 0;
4899 }
4900 
4901 
ParseClassAtom(uc16 * char_class)4902 CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) {
4903   ASSERT_EQ(0, *char_class);
4904   uc32 first = current();
4905   if (first == '\\') {
4906     switch (Next()) {
4907       case 'w': case 'W': case 'd': case 'D': case 's': case 'S': {
4908         *char_class = Next();
4909         Advance(2);
4910         return CharacterRange::Singleton(0);  // Return dummy value.
4911       }
4912       case kEndMarker:
4913         return ReportError(CStrVector("\\ at end of pattern"));
4914       default:
4915         uc32 c = ParseClassCharacterEscape(CHECK_FAILED);
4916         return CharacterRange::Singleton(c);
4917     }
4918   } else {
4919     Advance();
4920     return CharacterRange::Singleton(first);
4921   }
4922 }
4923 
4924 
4925 static const uc16 kNoCharClass = 0;
4926 
4927 // Adds range or pre-defined character class to character ranges.
4928 // If char_class is not kInvalidClass, it's interpreted as a class
4929 // escape (i.e., 's' means whitespace, from '\s').
AddRangeOrEscape(ZoneList<CharacterRange> * ranges,uc16 char_class,CharacterRange range)4930 static inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges,
4931                                     uc16 char_class,
4932                                     CharacterRange range) {
4933   if (char_class != kNoCharClass) {
4934     CharacterRange::AddClassEscape(char_class, ranges);
4935   } else {
4936     ranges->Add(range);
4937   }
4938 }
4939 
4940 
ParseCharacterClass()4941 RegExpTree* RegExpParser::ParseCharacterClass() {
4942   static const char* kUnterminated = "Unterminated character class";
4943   static const char* kRangeOutOfOrder = "Range out of order in character class";
4944 
4945   ASSERT_EQ(current(), '[');
4946   Advance();
4947   bool is_negated = false;
4948   if (current() == '^') {
4949     is_negated = true;
4950     Advance();
4951   }
4952   ZoneList<CharacterRange>* ranges = new ZoneList<CharacterRange>(2);
4953   while (has_more() && current() != ']') {
4954     uc16 char_class = kNoCharClass;
4955     CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED);
4956     if (current() == '-') {
4957       Advance();
4958       if (current() == kEndMarker) {
4959         // If we reach the end we break out of the loop and let the
4960         // following code report an error.
4961         break;
4962       } else if (current() == ']') {
4963         AddRangeOrEscape(ranges, char_class, first);
4964         ranges->Add(CharacterRange::Singleton('-'));
4965         break;
4966       }
4967       uc16 char_class_2 = kNoCharClass;
4968       CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED);
4969       if (char_class != kNoCharClass || char_class_2 != kNoCharClass) {
4970         // Either end is an escaped character class. Treat the '-' verbatim.
4971         AddRangeOrEscape(ranges, char_class, first);
4972         ranges->Add(CharacterRange::Singleton('-'));
4973         AddRangeOrEscape(ranges, char_class_2, next);
4974         continue;
4975       }
4976       if (first.from() > next.to()) {
4977         return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED);
4978       }
4979       ranges->Add(CharacterRange::Range(first.from(), next.to()));
4980     } else {
4981       AddRangeOrEscape(ranges, char_class, first);
4982     }
4983   }
4984   if (!has_more()) {
4985     return ReportError(CStrVector(kUnterminated) CHECK_FAILED);
4986   }
4987   Advance();
4988   if (ranges->length() == 0) {
4989     ranges->Add(CharacterRange::Everything());
4990     is_negated = !is_negated;
4991   }
4992   return new(zone()) RegExpCharacterClass(ranges, is_negated);
4993 }
4994 
4995 
4996 // ----------------------------------------------------------------------------
4997 // The Parser interface.
4998 
~ParserMessage()4999 ParserMessage::~ParserMessage() {
5000   for (int i = 0; i < args().length(); i++)
5001     DeleteArray(args()[i]);
5002   DeleteArray(args().start());
5003 }
5004 
5005 
~ScriptDataImpl()5006 ScriptDataImpl::~ScriptDataImpl() {
5007   if (owns_store_) store_.Dispose();
5008 }
5009 
5010 
Length()5011 int ScriptDataImpl::Length() {
5012   return store_.length() * sizeof(unsigned);
5013 }
5014 
5015 
Data()5016 const char* ScriptDataImpl::Data() {
5017   return reinterpret_cast<const char*>(store_.start());
5018 }
5019 
5020 
HasError()5021 bool ScriptDataImpl::HasError() {
5022   return has_error();
5023 }
5024 
5025 
Initialize()5026 void ScriptDataImpl::Initialize() {
5027   // Prepares state for use.
5028   if (store_.length() >= PreparseDataConstants::kHeaderSize) {
5029     function_index_ = PreparseDataConstants::kHeaderSize;
5030     int symbol_data_offset = PreparseDataConstants::kHeaderSize
5031         + store_[PreparseDataConstants::kFunctionsSizeOffset];
5032     if (store_.length() > symbol_data_offset) {
5033       symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]);
5034     } else {
5035       // Partial preparse causes no symbol information.
5036       symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
5037     }
5038     symbol_data_end_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
5039   }
5040 }
5041 
5042 
ReadNumber(byte ** source)5043 int ScriptDataImpl::ReadNumber(byte** source) {
5044   // Reads a number from symbol_data_ in base 128. The most significant
5045   // bit marks that there are more digits.
5046   // If the first byte is 0x80 (kNumberTerminator), it would normally
5047   // represent a leading zero. Since that is useless, and therefore won't
5048   // appear as the first digit of any actual value, it is used to
5049   // mark the end of the input stream.
5050   byte* data = *source;
5051   if (data >= symbol_data_end_) return -1;
5052   byte input = *data;
5053   if (input == PreparseDataConstants::kNumberTerminator) {
5054     // End of stream marker.
5055     return -1;
5056   }
5057   int result = input & 0x7f;
5058   data++;
5059   while ((input & 0x80u) != 0) {
5060     if (data >= symbol_data_end_) return -1;
5061     input = *data;
5062     result = (result << 7) | (input & 0x7f);
5063     data++;
5064   }
5065   *source = data;
5066   return result;
5067 }
5068 
5069 
5070 // Create a Scanner for the preparser to use as input, and preparse the source.
DoPreParse(UC16CharacterStream * source,bool allow_lazy,ParserRecorder * recorder)5071 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source,
5072                                   bool allow_lazy,
5073                                   ParserRecorder* recorder) {
5074   Isolate* isolate = Isolate::Current();
5075   V8JavaScriptScanner scanner(isolate->unicode_cache());
5076   scanner.Initialize(source);
5077   intptr_t stack_limit = isolate->stack_guard()->real_climit();
5078   if (!preparser::PreParser::PreParseProgram(&scanner,
5079                                              recorder,
5080                                              allow_lazy,
5081                                              stack_limit)) {
5082     isolate->StackOverflow();
5083     return NULL;
5084   }
5085 
5086   // Extract the accumulated data from the recorder as a single
5087   // contiguous vector that we are responsible for disposing.
5088   Vector<unsigned> store = recorder->ExtractData();
5089   return new ScriptDataImpl(store);
5090 }
5091 
5092 
5093 // Preparse, but only collect data that is immediately useful,
5094 // even if the preparser data is only used once.
PartialPreParse(UC16CharacterStream * source,v8::Extension * extension)5095 ScriptDataImpl* ParserApi::PartialPreParse(UC16CharacterStream* source,
5096                                            v8::Extension* extension) {
5097   bool allow_lazy = FLAG_lazy && (extension == NULL);
5098   if (!allow_lazy) {
5099     // Partial preparsing is only about lazily compiled functions.
5100     // If we don't allow lazy compilation, the log data will be empty.
5101     return NULL;
5102   }
5103   PartialParserRecorder recorder;
5104   return DoPreParse(source, allow_lazy, &recorder);
5105 }
5106 
5107 
PreParse(UC16CharacterStream * source,v8::Extension * extension)5108 ScriptDataImpl* ParserApi::PreParse(UC16CharacterStream* source,
5109                                     v8::Extension* extension) {
5110   Handle<Script> no_script;
5111   bool allow_lazy = FLAG_lazy && (extension == NULL);
5112   CompleteParserRecorder recorder;
5113   return DoPreParse(source, allow_lazy, &recorder);
5114 }
5115 
5116 
ParseRegExp(FlatStringReader * input,bool multiline,RegExpCompileData * result)5117 bool RegExpParser::ParseRegExp(FlatStringReader* input,
5118                                bool multiline,
5119                                RegExpCompileData* result) {
5120   ASSERT(result != NULL);
5121   RegExpParser parser(input, &result->error, multiline);
5122   RegExpTree* tree = parser.ParsePattern();
5123   if (parser.failed()) {
5124     ASSERT(tree == NULL);
5125     ASSERT(!result->error.is_null());
5126   } else {
5127     ASSERT(tree != NULL);
5128     ASSERT(result->error.is_null());
5129     result->tree = tree;
5130     int capture_count = parser.captures_started();
5131     result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
5132     result->contains_anchor = parser.contains_anchor();
5133     result->capture_count = capture_count;
5134   }
5135   return !parser.failed();
5136 }
5137 
5138 
Parse(CompilationInfo * info)5139 bool ParserApi::Parse(CompilationInfo* info) {
5140   ASSERT(info->function() == NULL);
5141   FunctionLiteral* result = NULL;
5142   Handle<Script> script = info->script();
5143   if (info->is_lazy()) {
5144     bool allow_natives_syntax =
5145         FLAG_allow_natives_syntax ||
5146         info->is_native();
5147     Parser parser(script, allow_natives_syntax, NULL, NULL);
5148     result = parser.ParseLazy(info);
5149   } else {
5150     bool allow_natives_syntax =
5151         info->is_native() || FLAG_allow_natives_syntax;
5152     ScriptDataImpl* pre_data = info->pre_parse_data();
5153     Parser parser(script, allow_natives_syntax, info->extension(), pre_data);
5154     if (pre_data != NULL && pre_data->has_error()) {
5155       Scanner::Location loc = pre_data->MessageLocation();
5156       const char* message = pre_data->BuildMessage();
5157       Vector<const char*> args = pre_data->BuildArgs();
5158       parser.ReportMessageAt(loc, message, args);
5159       DeleteArray(message);
5160       for (int i = 0; i < args.length(); i++) {
5161         DeleteArray(args[i]);
5162       }
5163       DeleteArray(args.start());
5164       ASSERT(info->isolate()->has_pending_exception());
5165     } else {
5166       Handle<String> source = Handle<String>(String::cast(script->source()));
5167       result = parser.ParseProgram(source,
5168                                    info->is_global(),
5169                                    info->StrictMode());
5170     }
5171   }
5172 
5173   info->SetFunction(result);
5174   return (result != NULL);
5175 }
5176 
5177 } }  // namespace v8::internal
5178