• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_PREPARSER_H
6 #define V8_PREPARSER_H
7 
8 #include "src/func-name-inferrer.h"
9 #include "src/hashmap.h"
10 #include "src/scopes.h"
11 #include "src/token.h"
12 #include "src/scanner.h"
13 #include "src/v8.h"
14 
15 namespace v8 {
16 namespace internal {
17 
18 // Common base class shared between parser and pre-parser. Traits encapsulate
19 // the differences between Parser and PreParser:
20 
21 // - Return types: For example, Parser functions return Expression* and
22 // PreParser functions return PreParserExpression.
23 
24 // - Creating parse tree nodes: Parser generates an AST during the recursive
25 // descent. PreParser doesn't create a tree. Instead, it passes around minimal
26 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain
27 // just enough data for the upper layer functions. PreParserFactory is
28 // responsible for creating these dummy objects. It provides a similar kind of
29 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is
30 // used.
31 
32 // - Miscellanous other tasks interleaved with the recursive descent. For
33 // example, Parser keeps track of which function literals should be marked as
34 // pretenured, and PreParser doesn't care.
35 
36 // The traits are expected to contain the following typedefs:
37 // struct Traits {
38 //   // In particular...
39 //   struct Type {
40 //     // Used by FunctionState and BlockState.
41 //     typedef Scope;
42 //     typedef GeneratorVariable;
43 //     typedef Zone;
44 //     // Return types for traversing functions.
45 //     typedef Identifier;
46 //     typedef Expression;
47 //     typedef FunctionLiteral;
48 //     typedef ObjectLiteralProperty;
49 //     typedef Literal;
50 //     typedef ExpressionList;
51 //     typedef PropertyList;
52 //     // For constructing objects returned by the traversing functions.
53 //     typedef Factory;
54 //   };
55 //   // ...
56 // };
57 
58 template <typename Traits>
59 class ParserBase : public Traits {
60  public:
61   // Shorten type names defined by Traits.
62   typedef typename Traits::Type::Expression ExpressionT;
63   typedef typename Traits::Type::Identifier IdentifierT;
64 
ParserBase(Scanner * scanner,uintptr_t stack_limit,v8::Extension * extension,ParserRecorder * log,typename Traits::Type::Zone * zone,typename Traits::Type::Parser this_object)65   ParserBase(Scanner* scanner, uintptr_t stack_limit,
66              v8::Extension* extension,
67              ParserRecorder* log,
68              typename Traits::Type::Zone* zone,
69              typename Traits::Type::Parser this_object)
70       : Traits(this_object),
71         parenthesized_function_(false),
72         scope_(NULL),
73         function_state_(NULL),
74         extension_(extension),
75         fni_(NULL),
76         log_(log),
77         mode_(PARSE_EAGERLY),  // Lazy mode must be set explicitly.
78         scanner_(scanner),
79         stack_limit_(stack_limit),
80         stack_overflow_(false),
81         allow_lazy_(false),
82         allow_natives_syntax_(false),
83         allow_generators_(false),
84         allow_for_of_(false),
85         zone_(zone) { }
86 
87   // Getters that indicate whether certain syntactical constructs are
88   // allowed to be parsed by this instance of the parser.
allow_lazy()89   bool allow_lazy() const { return allow_lazy_; }
allow_natives_syntax()90   bool allow_natives_syntax() const { return allow_natives_syntax_; }
allow_generators()91   bool allow_generators() const { return allow_generators_; }
allow_for_of()92   bool allow_for_of() const { return allow_for_of_; }
allow_modules()93   bool allow_modules() const { return scanner()->HarmonyModules(); }
allow_harmony_scoping()94   bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); }
allow_harmony_numeric_literals()95   bool allow_harmony_numeric_literals() const {
96     return scanner()->HarmonyNumericLiterals();
97   }
98 
99   // Setters that determine whether certain syntactical constructs are
100   // allowed to be parsed by this instance of the parser.
set_allow_lazy(bool allow)101   void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
set_allow_natives_syntax(bool allow)102   void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
set_allow_generators(bool allow)103   void set_allow_generators(bool allow) { allow_generators_ = allow; }
set_allow_for_of(bool allow)104   void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
set_allow_modules(bool allow)105   void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); }
set_allow_harmony_scoping(bool allow)106   void set_allow_harmony_scoping(bool allow) {
107     scanner()->SetHarmonyScoping(allow);
108   }
set_allow_harmony_numeric_literals(bool allow)109   void set_allow_harmony_numeric_literals(bool allow) {
110     scanner()->SetHarmonyNumericLiterals(allow);
111   }
112 
113  protected:
114   enum AllowEvalOrArgumentsAsIdentifier {
115     kAllowEvalOrArguments,
116     kDontAllowEvalOrArguments
117   };
118 
119   enum Mode {
120     PARSE_LAZILY,
121     PARSE_EAGERLY
122   };
123 
124   // ---------------------------------------------------------------------------
125   // FunctionState and BlockState together implement the parser's scope stack.
126   // The parser's current scope is in scope_. BlockState and FunctionState
127   // constructors push on the scope stack and the destructors pop. They are also
128   // used to hold the parser's per-function and per-block state.
129   class BlockState BASE_EMBEDDED {
130    public:
BlockState(typename Traits::Type::Scope ** scope_stack,typename Traits::Type::Scope * scope)131     BlockState(typename Traits::Type::Scope** scope_stack,
132                typename Traits::Type::Scope* scope)
133         : scope_stack_(scope_stack),
134           outer_scope_(*scope_stack),
135           scope_(scope) {
136       *scope_stack_ = scope_;
137     }
~BlockState()138     ~BlockState() { *scope_stack_ = outer_scope_; }
139 
140    private:
141     typename Traits::Type::Scope** scope_stack_;
142     typename Traits::Type::Scope* outer_scope_;
143     typename Traits::Type::Scope* scope_;
144   };
145 
146   class FunctionState BASE_EMBEDDED {
147    public:
148     FunctionState(
149         FunctionState** function_state_stack,
150         typename Traits::Type::Scope** scope_stack,
151         typename Traits::Type::Scope* scope,
152         typename Traits::Type::Zone* zone = NULL);
153     ~FunctionState();
154 
NextMaterializedLiteralIndex()155     int NextMaterializedLiteralIndex() {
156       return next_materialized_literal_index_++;
157     }
materialized_literal_count()158     int materialized_literal_count() {
159       return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize;
160     }
161 
NextHandlerIndex()162     int NextHandlerIndex() { return next_handler_index_++; }
handler_count()163     int handler_count() { return next_handler_index_; }
164 
AddProperty()165     void AddProperty() { expected_property_count_++; }
expected_property_count()166     int expected_property_count() { return expected_property_count_; }
167 
set_is_generator(bool is_generator)168     void set_is_generator(bool is_generator) { is_generator_ = is_generator; }
is_generator()169     bool is_generator() const { return is_generator_; }
170 
set_generator_object_variable(typename Traits::Type::GeneratorVariable * variable)171     void set_generator_object_variable(
172         typename Traits::Type::GeneratorVariable* variable) {
173       ASSERT(variable != NULL);
174       ASSERT(!is_generator());
175       generator_object_variable_ = variable;
176       is_generator_ = true;
177     }
generator_object_variable()178     typename Traits::Type::GeneratorVariable* generator_object_variable()
179         const {
180       return generator_object_variable_;
181     }
182 
factory()183     typename Traits::Type::Factory* factory() { return &factory_; }
184 
185    private:
186     // Used to assign an index to each literal that needs materialization in
187     // the function.  Includes regexp literals, and boilerplate for object and
188     // array literals.
189     int next_materialized_literal_index_;
190 
191     // Used to assign a per-function index to try and catch handlers.
192     int next_handler_index_;
193 
194     // Properties count estimation.
195     int expected_property_count_;
196 
197     // Whether the function is a generator.
198     bool is_generator_;
199     // For generators, this variable may hold the generator object. It variable
200     // is used by yield expressions and return statements. It is not necessary
201     // for generator functions to have this variable set.
202     Variable* generator_object_variable_;
203 
204     FunctionState** function_state_stack_;
205     FunctionState* outer_function_state_;
206     typename Traits::Type::Scope** scope_stack_;
207     typename Traits::Type::Scope* outer_scope_;
208     int saved_ast_node_id_;  // Only used by ParserTraits.
209     typename Traits::Type::Zone* extra_param_;
210     typename Traits::Type::Factory factory_;
211 
212     friend class ParserTraits;
213   };
214 
215   class ParsingModeScope BASE_EMBEDDED {
216    public:
ParsingModeScope(ParserBase * parser,Mode mode)217     ParsingModeScope(ParserBase* parser, Mode mode)
218         : parser_(parser),
219           old_mode_(parser->mode()) {
220       parser_->mode_ = mode;
221     }
~ParsingModeScope()222     ~ParsingModeScope() {
223       parser_->mode_ = old_mode_;
224     }
225 
226    private:
227     ParserBase* parser_;
228     Mode old_mode_;
229   };
230 
scanner()231   Scanner* scanner() const { return scanner_; }
position()232   int position() { return scanner_->location().beg_pos; }
peek_position()233   int peek_position() { return scanner_->peek_location().beg_pos; }
stack_overflow()234   bool stack_overflow() const { return stack_overflow_; }
set_stack_overflow()235   void set_stack_overflow() { stack_overflow_ = true; }
mode()236   Mode mode() const { return mode_; }
zone()237   typename Traits::Type::Zone* zone() const { return zone_; }
238 
INLINE(Token::Value peek ())239   INLINE(Token::Value peek()) {
240     if (stack_overflow_) return Token::ILLEGAL;
241     return scanner()->peek();
242   }
243 
INLINE(Token::Value Next ())244   INLINE(Token::Value Next()) {
245     if (stack_overflow_) return Token::ILLEGAL;
246     {
247       int marker;
248       if (reinterpret_cast<uintptr_t>(&marker) < stack_limit_) {
249         // Any further calls to Next or peek will return the illegal token.
250         // The current call must return the next token, which might already
251         // have been peek'ed.
252         stack_overflow_ = true;
253       }
254     }
255     return scanner()->Next();
256   }
257 
Consume(Token::Value token)258   void Consume(Token::Value token) {
259     Token::Value next = Next();
260     USE(next);
261     USE(token);
262     ASSERT(next == token);
263   }
264 
Check(Token::Value token)265   bool Check(Token::Value token) {
266     Token::Value next = peek();
267     if (next == token) {
268       Consume(next);
269       return true;
270     }
271     return false;
272   }
273 
Expect(Token::Value token,bool * ok)274   void Expect(Token::Value token, bool* ok) {
275     Token::Value next = Next();
276     if (next != token) {
277       ReportUnexpectedToken(next);
278       *ok = false;
279     }
280   }
281 
ExpectSemicolon(bool * ok)282   void ExpectSemicolon(bool* ok) {
283     // Check for automatic semicolon insertion according to
284     // the rules given in ECMA-262, section 7.9, page 21.
285     Token::Value tok = peek();
286     if (tok == Token::SEMICOLON) {
287       Next();
288       return;
289     }
290     if (scanner()->HasAnyLineTerminatorBeforeNext() ||
291         tok == Token::RBRACE ||
292         tok == Token::EOS) {
293       return;
294     }
295     Expect(Token::SEMICOLON, ok);
296   }
297 
peek_any_identifier()298   bool peek_any_identifier() {
299     Token::Value next = peek();
300     return next == Token::IDENTIFIER ||
301         next == Token::FUTURE_RESERVED_WORD ||
302         next == Token::FUTURE_STRICT_RESERVED_WORD ||
303         next == Token::YIELD;
304   }
305 
CheckContextualKeyword(Vector<const char> keyword)306   bool CheckContextualKeyword(Vector<const char> keyword) {
307     if (peek() == Token::IDENTIFIER &&
308         scanner()->is_next_contextual_keyword(keyword)) {
309       Consume(Token::IDENTIFIER);
310       return true;
311     }
312     return false;
313   }
314 
ExpectContextualKeyword(Vector<const char> keyword,bool * ok)315   void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
316     Expect(Token::IDENTIFIER, ok);
317     if (!*ok) return;
318     if (!scanner()->is_literal_contextual_keyword(keyword)) {
319       ReportUnexpectedToken(scanner()->current_token());
320       *ok = false;
321     }
322   }
323 
324   // Checks whether an octal literal was last seen between beg_pos and end_pos.
325   // If so, reports an error. Only called for strict mode.
CheckOctalLiteral(int beg_pos,int end_pos,bool * ok)326   void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
327     Scanner::Location octal = scanner()->octal_position();
328     if (octal.IsValid() && beg_pos <= octal.beg_pos &&
329         octal.end_pos <= end_pos) {
330       ReportMessageAt(octal, "strict_octal_literal");
331       scanner()->clear_octal_position();
332       *ok = false;
333     }
334   }
335 
336   // Determine precedence of given token.
Precedence(Token::Value token,bool accept_IN)337   static int Precedence(Token::Value token, bool accept_IN) {
338     if (token == Token::IN && !accept_IN)
339       return 0;  // 0 precedence will terminate binary expression parsing
340     return Token::Precedence(token);
341   }
342 
factory()343   typename Traits::Type::Factory* factory() {
344     return function_state_->factory();
345   }
346 
strict_mode()347   StrictMode strict_mode() { return scope_->strict_mode(); }
is_generator()348   bool is_generator() const { return function_state_->is_generator(); }
349 
350   // Report syntax errors.
351   void ReportMessage(const char* message, const char* arg = NULL,
352                      bool is_reference_error = false) {
353     Scanner::Location source_location = scanner()->location();
354     Traits::ReportMessageAt(source_location, message, arg, is_reference_error);
355   }
356 
357   void ReportMessageAt(Scanner::Location location, const char* message,
358                        bool is_reference_error = false) {
359     Traits::ReportMessageAt(location, message, NULL, is_reference_error);
360   }
361 
362   void ReportUnexpectedToken(Token::Value token);
363 
364   // Recursive descent functions:
365 
366   // Parses an identifier that is valid for the current scope, in particular it
367   // fails on strict mode future reserved keywords in a strict scope. If
368   // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
369   // "arguments" as identifier even in strict mode (this is needed in cases like
370   // "var foo = eval;").
371   IdentifierT ParseIdentifier(
372       AllowEvalOrArgumentsAsIdentifier,
373       bool* ok);
374   // Parses an identifier or a strict mode future reserved word, and indicate
375   // whether it is strict mode future reserved.
376   IdentifierT ParseIdentifierOrStrictReservedWord(
377       bool* is_strict_reserved,
378       bool* ok);
379   IdentifierT ParseIdentifierName(bool* ok);
380   // Parses an identifier and determines whether or not it is 'get' or 'set'.
381   IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get,
382                                             bool* is_set,
383                                             bool* ok);
384 
385   ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok);
386 
387   ExpressionT ParsePrimaryExpression(bool* ok);
388   ExpressionT ParseExpression(bool accept_IN, bool* ok);
389   ExpressionT ParseArrayLiteral(bool* ok);
390   ExpressionT ParseObjectLiteral(bool* ok);
391   typename Traits::Type::ExpressionList ParseArguments(bool* ok);
392   ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok);
393   ExpressionT ParseYieldExpression(bool* ok);
394   ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
395   ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
396   ExpressionT ParseUnaryExpression(bool* ok);
397   ExpressionT ParsePostfixExpression(bool* ok);
398   ExpressionT ParseLeftHandSideExpression(bool* ok);
399   ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok);
400   ExpressionT ParseMemberExpression(bool* ok);
401   ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
402                                                 bool* ok);
403 
404   // Checks if the expression is a valid reference expression (e.g., on the
405   // left-hand side of assignments). Although ruled out by ECMA as early errors,
406   // we allow calls for web compatibility and rewrite them to a runtime throw.
407   ExpressionT CheckAndRewriteReferenceExpression(
408       ExpressionT expression,
409       Scanner::Location location, const char* message, bool* ok);
410 
411   // Used to detect duplicates in object literals. Each of the values
412   // kGetterProperty, kSetterProperty and kValueProperty represents
413   // a type of object literal property. When parsing a property, its
414   // type value is stored in the DuplicateFinder for the property name.
415   // Values are chosen so that having intersection bits means the there is
416   // an incompatibility.
417   // I.e., you can add a getter to a property that already has a setter, since
418   // kGetterProperty and kSetterProperty doesn't intersect, but not if it
419   // already has a getter or a value. Adding the getter to an existing
420   // setter will store the value (kGetterProperty | kSetterProperty), which
421   // is incompatible with adding any further properties.
422   enum PropertyKind {
423     kNone = 0,
424     // Bit patterns representing different object literal property types.
425     kGetterProperty = 1,
426     kSetterProperty = 2,
427     kValueProperty = 7,
428     // Helper constants.
429     kValueFlag = 4
430   };
431 
432   // Validation per ECMA 262 - 11.1.5 "Object Initialiser".
433   class ObjectLiteralChecker {
434    public:
ObjectLiteralChecker(ParserBase * parser,StrictMode strict_mode)435     ObjectLiteralChecker(ParserBase* parser, StrictMode strict_mode)
436         : parser_(parser),
437           finder_(scanner()->unicode_cache()),
438           strict_mode_(strict_mode) { }
439 
440     void CheckProperty(Token::Value property, PropertyKind type, bool* ok);
441 
442    private:
parser()443     ParserBase* parser() const { return parser_; }
scanner()444     Scanner* scanner() const { return parser_->scanner(); }
445 
446     // Checks the type of conflict based on values coming from PropertyType.
HasConflict(PropertyKind type1,PropertyKind type2)447     bool HasConflict(PropertyKind type1, PropertyKind type2) {
448       return (type1 & type2) != 0;
449     }
IsDataDataConflict(PropertyKind type1,PropertyKind type2)450     bool IsDataDataConflict(PropertyKind type1, PropertyKind type2) {
451       return ((type1 & type2) & kValueFlag) != 0;
452     }
IsDataAccessorConflict(PropertyKind type1,PropertyKind type2)453     bool IsDataAccessorConflict(PropertyKind type1, PropertyKind type2) {
454       return ((type1 ^ type2) & kValueFlag) != 0;
455     }
IsAccessorAccessorConflict(PropertyKind type1,PropertyKind type2)456     bool IsAccessorAccessorConflict(PropertyKind type1, PropertyKind type2) {
457       return ((type1 | type2) & kValueFlag) == 0;
458     }
459 
460     ParserBase* parser_;
461     DuplicateFinder finder_;
462     StrictMode strict_mode_;
463   };
464 
465   // If true, the next (and immediately following) function literal is
466   // preceded by a parenthesis.
467   // Heuristically that means that the function will be called immediately,
468   // so never lazily compile it.
469   bool parenthesized_function_;
470 
471   typename Traits::Type::Scope* scope_;  // Scope stack.
472   FunctionState* function_state_;  // Function state stack.
473   v8::Extension* extension_;
474   FuncNameInferrer* fni_;
475   ParserRecorder* log_;
476   Mode mode_;
477 
478  private:
479   Scanner* scanner_;
480   uintptr_t stack_limit_;
481   bool stack_overflow_;
482 
483   bool allow_lazy_;
484   bool allow_natives_syntax_;
485   bool allow_generators_;
486   bool allow_for_of_;
487 
488   typename Traits::Type::Zone* zone_;  // Only used by Parser.
489 };
490 
491 
492 class PreParserIdentifier {
493  public:
PreParserIdentifier()494   PreParserIdentifier() : type_(kUnknownIdentifier) {}
Default()495   static PreParserIdentifier Default() {
496     return PreParserIdentifier(kUnknownIdentifier);
497   }
Eval()498   static PreParserIdentifier Eval() {
499     return PreParserIdentifier(kEvalIdentifier);
500   }
Arguments()501   static PreParserIdentifier Arguments() {
502     return PreParserIdentifier(kArgumentsIdentifier);
503   }
FutureReserved()504   static PreParserIdentifier FutureReserved() {
505     return PreParserIdentifier(kFutureReservedIdentifier);
506   }
FutureStrictReserved()507   static PreParserIdentifier FutureStrictReserved() {
508     return PreParserIdentifier(kFutureStrictReservedIdentifier);
509   }
Yield()510   static PreParserIdentifier Yield() {
511     return PreParserIdentifier(kYieldIdentifier);
512   }
IsEval()513   bool IsEval() { return type_ == kEvalIdentifier; }
IsArguments()514   bool IsArguments() { return type_ == kArgumentsIdentifier; }
IsEvalOrArguments()515   bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; }
IsYield()516   bool IsYield() { return type_ == kYieldIdentifier; }
IsFutureReserved()517   bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; }
IsFutureStrictReserved()518   bool IsFutureStrictReserved() {
519     return type_ == kFutureStrictReservedIdentifier;
520   }
IsValidStrictVariable()521   bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; }
522 
523  private:
524   enum Type {
525     kUnknownIdentifier,
526     kFutureReservedIdentifier,
527     kFutureStrictReservedIdentifier,
528     kYieldIdentifier,
529     kEvalIdentifier,
530     kArgumentsIdentifier
531   };
PreParserIdentifier(Type type)532   explicit PreParserIdentifier(Type type) : type_(type) {}
533   Type type_;
534 
535   friend class PreParserExpression;
536 };
537 
538 
539 // Bits 0 and 1 are used to identify the type of expression:
540 // If bit 0 is set, it's an identifier.
541 // if bit 1 is set, it's a string literal.
542 // If neither is set, it's no particular type, and both set isn't
543 // use yet.
544 class PreParserExpression {
545  public:
Default()546   static PreParserExpression Default() {
547     return PreParserExpression(kUnknownExpression);
548   }
549 
FromIdentifier(PreParserIdentifier id)550   static PreParserExpression FromIdentifier(PreParserIdentifier id) {
551     return PreParserExpression(kIdentifierFlag |
552                                (id.type_ << kIdentifierShift));
553   }
554 
StringLiteral()555   static PreParserExpression StringLiteral() {
556     return PreParserExpression(kUnknownStringLiteral);
557   }
558 
UseStrictStringLiteral()559   static PreParserExpression UseStrictStringLiteral() {
560     return PreParserExpression(kUseStrictString);
561   }
562 
This()563   static PreParserExpression This() {
564     return PreParserExpression(kThisExpression);
565   }
566 
ThisProperty()567   static PreParserExpression ThisProperty() {
568     return PreParserExpression(kThisPropertyExpression);
569   }
570 
Property()571   static PreParserExpression Property() {
572     return PreParserExpression(kPropertyExpression);
573   }
574 
Call()575   static PreParserExpression Call() {
576     return PreParserExpression(kCallExpression);
577   }
578 
IsIdentifier()579   bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; }
580 
AsIdentifier()581   PreParserIdentifier AsIdentifier() {
582     ASSERT(IsIdentifier());
583     return PreParserIdentifier(
584         static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift));
585   }
586 
IsStringLiteral()587   bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; }
588 
IsUseStrictLiteral()589   bool IsUseStrictLiteral() {
590     return (code_ & kStringLiteralMask) == kUseStrictString;
591   }
592 
IsThis()593   bool IsThis() { return code_ == kThisExpression; }
594 
IsThisProperty()595   bool IsThisProperty() { return code_ == kThisPropertyExpression; }
596 
IsProperty()597   bool IsProperty() {
598     return code_ == kPropertyExpression || code_ == kThisPropertyExpression;
599   }
600 
IsCall()601   bool IsCall() { return code_ == kCallExpression; }
602 
IsValidReferenceExpression()603   bool IsValidReferenceExpression() {
604     return IsIdentifier() || IsProperty();
605   }
606 
607   // At the moment PreParser doesn't track these expression types.
IsFunctionLiteral()608   bool IsFunctionLiteral() const { return false; }
IsCallNew()609   bool IsCallNew() const { return false; }
610 
AsFunctionLiteral()611   PreParserExpression AsFunctionLiteral() { return *this; }
612 
613   // Dummy implementation for making expression->somefunc() work in both Parser
614   // and PreParser.
615   PreParserExpression* operator->() { return this; }
616 
617   // More dummy implementations of things PreParser doesn't need to track:
set_index(int index)618   void set_index(int index) {}  // For YieldExpressions
set_parenthesized()619   void set_parenthesized() {}
620 
621  private:
622   // Least significant 2 bits are used as flags. Bits 0 and 1 represent
623   // identifiers or strings literals, and are mutually exclusive, but can both
624   // be absent. If the expression is an identifier or a string literal, the
625   // other bits describe the type (see PreParserIdentifier::Type and string
626   // literal constants below).
627   enum {
628     kUnknownExpression = 0,
629     // Identifiers
630     kIdentifierFlag = 1,  // Used to detect labels.
631     kIdentifierShift = 3,
632 
633     kStringLiteralFlag = 2,  // Used to detect directive prologue.
634     kUnknownStringLiteral = kStringLiteralFlag,
635     kUseStrictString = kStringLiteralFlag | 8,
636     kStringLiteralMask = kUseStrictString,
637 
638     // Below here applies if neither identifier nor string literal. Reserve the
639     // 2 least significant bits for flags.
640     kThisExpression = 1 << 2,
641     kThisPropertyExpression = 2 << 2,
642     kPropertyExpression = 3 << 2,
643     kCallExpression = 4 << 2
644   };
645 
PreParserExpression(int expression_code)646   explicit PreParserExpression(int expression_code) : code_(expression_code) {}
647 
648   int code_;
649 };
650 
651 
652 // PreParserExpressionList doesn't actually store the expressions because
653 // PreParser doesn't need to.
654 class PreParserExpressionList {
655  public:
656   // These functions make list->Add(some_expression) work (and do nothing).
PreParserExpressionList()657   PreParserExpressionList() : length_(0) {}
658   PreParserExpressionList* operator->() { return this; }
Add(PreParserExpression,void *)659   void Add(PreParserExpression, void*) { ++length_; }
length()660   int length() const { return length_; }
661  private:
662   int length_;
663 };
664 
665 
666 class PreParserStatement {
667  public:
Default()668   static PreParserStatement Default() {
669     return PreParserStatement(kUnknownStatement);
670   }
671 
FunctionDeclaration()672   static PreParserStatement FunctionDeclaration() {
673     return PreParserStatement(kFunctionDeclaration);
674   }
675 
676   // Creates expression statement from expression.
677   // Preserves being an unparenthesized string literal, possibly
678   // "use strict".
ExpressionStatement(PreParserExpression expression)679   static PreParserStatement ExpressionStatement(
680       PreParserExpression expression) {
681     if (expression.IsUseStrictLiteral()) {
682       return PreParserStatement(kUseStrictExpressionStatement);
683     }
684     if (expression.IsStringLiteral()) {
685       return PreParserStatement(kStringLiteralExpressionStatement);
686     }
687     return Default();
688   }
689 
IsStringLiteral()690   bool IsStringLiteral() {
691     return code_ == kStringLiteralExpressionStatement;
692   }
693 
IsUseStrictLiteral()694   bool IsUseStrictLiteral() {
695     return code_ == kUseStrictExpressionStatement;
696   }
697 
IsFunctionDeclaration()698   bool IsFunctionDeclaration() {
699     return code_ == kFunctionDeclaration;
700   }
701 
702  private:
703   enum Type {
704     kUnknownStatement,
705     kStringLiteralExpressionStatement,
706     kUseStrictExpressionStatement,
707     kFunctionDeclaration
708   };
709 
PreParserStatement(Type code)710   explicit PreParserStatement(Type code) : code_(code) {}
711   Type code_;
712 };
713 
714 
715 
716 // PreParserStatementList doesn't actually store the statements because
717 // the PreParser does not need them.
718 class PreParserStatementList {
719  public:
720   // These functions make list->Add(some_expression) work as no-ops.
PreParserStatementList()721   PreParserStatementList() {}
722   PreParserStatementList* operator->() { return this; }
Add(PreParserStatement,void *)723   void Add(PreParserStatement, void*) {}
724 };
725 
726 
727 class PreParserScope {
728  public:
PreParserScope(PreParserScope * outer_scope,ScopeType scope_type)729   explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type)
730       : scope_type_(scope_type) {
731     strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY;
732   }
733 
type()734   ScopeType type() { return scope_type_; }
strict_mode()735   StrictMode strict_mode() const { return strict_mode_; }
SetStrictMode(StrictMode strict_mode)736   void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; }
737 
738  private:
739   ScopeType scope_type_;
740   StrictMode strict_mode_;
741 };
742 
743 
744 class PreParserFactory {
745  public:
PreParserFactory(void * extra_param)746   explicit PreParserFactory(void* extra_param) {}
NewLiteral(PreParserIdentifier identifier,int pos)747   PreParserExpression NewLiteral(PreParserIdentifier identifier,
748                                  int pos) {
749     return PreParserExpression::Default();
750   }
NewNumberLiteral(double number,int pos)751   PreParserExpression NewNumberLiteral(double number,
752                                        int pos) {
753     return PreParserExpression::Default();
754   }
NewRegExpLiteral(PreParserIdentifier js_pattern,PreParserIdentifier js_flags,int literal_index,int pos)755   PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
756                                        PreParserIdentifier js_flags,
757                                        int literal_index,
758                                        int pos) {
759     return PreParserExpression::Default();
760   }
NewArrayLiteral(PreParserExpressionList values,int literal_index,int pos)761   PreParserExpression NewArrayLiteral(PreParserExpressionList values,
762                                       int literal_index,
763                                       int pos) {
764     return PreParserExpression::Default();
765   }
NewObjectLiteralProperty(bool is_getter,PreParserExpression value,int pos)766   PreParserExpression NewObjectLiteralProperty(bool is_getter,
767                                                PreParserExpression value,
768                                                int pos) {
769     return PreParserExpression::Default();
770   }
NewObjectLiteralProperty(PreParserExpression key,PreParserExpression value)771   PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
772                                                PreParserExpression value) {
773     return PreParserExpression::Default();
774   }
NewObjectLiteral(PreParserExpressionList properties,int literal_index,int boilerplate_properties,bool has_function,int pos)775   PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
776                                        int literal_index,
777                                        int boilerplate_properties,
778                                        bool has_function,
779                                        int pos) {
780     return PreParserExpression::Default();
781   }
NewVariableProxy(void * generator_variable)782   PreParserExpression NewVariableProxy(void* generator_variable) {
783     return PreParserExpression::Default();
784   }
NewProperty(PreParserExpression obj,PreParserExpression key,int pos)785   PreParserExpression NewProperty(PreParserExpression obj,
786                                   PreParserExpression key,
787                                   int pos) {
788     if (obj.IsThis()) {
789       return PreParserExpression::ThisProperty();
790     }
791     return PreParserExpression::Property();
792   }
NewUnaryOperation(Token::Value op,PreParserExpression expression,int pos)793   PreParserExpression NewUnaryOperation(Token::Value op,
794                                         PreParserExpression expression,
795                                         int pos) {
796     return PreParserExpression::Default();
797   }
NewBinaryOperation(Token::Value op,PreParserExpression left,PreParserExpression right,int pos)798   PreParserExpression NewBinaryOperation(Token::Value op,
799                                          PreParserExpression left,
800                                          PreParserExpression right, int pos) {
801     return PreParserExpression::Default();
802   }
NewCompareOperation(Token::Value op,PreParserExpression left,PreParserExpression right,int pos)803   PreParserExpression NewCompareOperation(Token::Value op,
804                                           PreParserExpression left,
805                                           PreParserExpression right, int pos) {
806     return PreParserExpression::Default();
807   }
NewAssignment(Token::Value op,PreParserExpression left,PreParserExpression right,int pos)808   PreParserExpression NewAssignment(Token::Value op,
809                                     PreParserExpression left,
810                                     PreParserExpression right,
811                                     int pos) {
812     return PreParserExpression::Default();
813   }
NewYield(PreParserExpression generator_object,PreParserExpression expression,Yield::Kind yield_kind,int pos)814   PreParserExpression NewYield(PreParserExpression generator_object,
815                                PreParserExpression expression,
816                                Yield::Kind yield_kind,
817                                int pos) {
818     return PreParserExpression::Default();
819   }
NewConditional(PreParserExpression condition,PreParserExpression then_expression,PreParserExpression else_expression,int pos)820   PreParserExpression NewConditional(PreParserExpression condition,
821                                      PreParserExpression then_expression,
822                                      PreParserExpression else_expression,
823                                      int pos) {
824     return PreParserExpression::Default();
825   }
NewCountOperation(Token::Value op,bool is_prefix,PreParserExpression expression,int pos)826   PreParserExpression NewCountOperation(Token::Value op,
827                                         bool is_prefix,
828                                         PreParserExpression expression,
829                                         int pos) {
830     return PreParserExpression::Default();
831   }
NewCall(PreParserExpression expression,PreParserExpressionList arguments,int pos)832   PreParserExpression NewCall(PreParserExpression expression,
833                               PreParserExpressionList arguments,
834                               int pos) {
835     return PreParserExpression::Call();
836   }
NewCallNew(PreParserExpression expression,PreParserExpressionList arguments,int pos)837   PreParserExpression NewCallNew(PreParserExpression expression,
838                                  PreParserExpressionList arguments,
839                                  int pos) {
840     return PreParserExpression::Default();
841   }
842 };
843 
844 
845 class PreParser;
846 
847 class PreParserTraits {
848  public:
849   struct Type {
850     // TODO(marja): To be removed. The Traits object should contain all the data
851     // it needs.
852     typedef PreParser* Parser;
853 
854     // Used by FunctionState and BlockState.
855     typedef PreParserScope Scope;
856     // PreParser doesn't need to store generator variables.
857     typedef void GeneratorVariable;
858     // No interaction with Zones.
859     typedef void Zone;
860 
861     // Return types for traversing functions.
862     typedef PreParserIdentifier Identifier;
863     typedef PreParserExpression Expression;
864     typedef PreParserExpression YieldExpression;
865     typedef PreParserExpression FunctionLiteral;
866     typedef PreParserExpression ObjectLiteralProperty;
867     typedef PreParserExpression Literal;
868     typedef PreParserExpressionList ExpressionList;
869     typedef PreParserExpressionList PropertyList;
870     typedef PreParserStatementList StatementList;
871 
872     // For constructing objects returned by the traversing functions.
873     typedef PreParserFactory Factory;
874   };
875 
PreParserTraits(PreParser * pre_parser)876   explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
877 
878   // Custom operations executed when FunctionStates are created and
879   // destructed. (The PreParser doesn't need to do anything.)
880   template<typename FunctionState>
SetUpFunctionState(FunctionState * function_state,void *)881   static void SetUpFunctionState(FunctionState* function_state, void*) {}
882   template<typename FunctionState>
TearDownFunctionState(FunctionState * function_state,void *)883   static void TearDownFunctionState(FunctionState* function_state, void*) {}
884 
885   // Helper functions for recursive descent.
IsEvalOrArguments(PreParserIdentifier identifier)886   static bool IsEvalOrArguments(PreParserIdentifier identifier) {
887     return identifier.IsEvalOrArguments();
888   }
889 
890   // Returns true if the expression is of type "this.foo".
IsThisProperty(PreParserExpression expression)891   static bool IsThisProperty(PreParserExpression expression) {
892     return expression.IsThisProperty();
893   }
894 
IsIdentifier(PreParserExpression expression)895   static bool IsIdentifier(PreParserExpression expression) {
896     return expression.IsIdentifier();
897   }
898 
AsIdentifier(PreParserExpression expression)899   static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
900     return expression.AsIdentifier();
901   }
902 
IsBoilerplateProperty(PreParserExpression property)903   static bool IsBoilerplateProperty(PreParserExpression property) {
904     // PreParser doesn't count boilerplate properties.
905     return false;
906   }
907 
IsArrayIndex(PreParserIdentifier string,uint32_t * index)908   static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
909     return false;
910   }
911 
912   // Functions for encapsulating the differences between parsing and preparsing;
913   // operations interleaved with the recursive descent.
PushLiteralName(FuncNameInferrer * fni,PreParserIdentifier id)914   static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
915     // PreParser should not use FuncNameInferrer.
916     UNREACHABLE();
917   }
PushPropertyName(FuncNameInferrer * fni,PreParserExpression expression)918   static void PushPropertyName(FuncNameInferrer* fni,
919                                PreParserExpression expression) {
920     // PreParser should not use FuncNameInferrer.
921     UNREACHABLE();
922   }
923 
CheckFunctionLiteralInsideTopLevelObjectLiteral(PreParserScope * scope,PreParserExpression value,bool * has_function)924   static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
925       PreParserScope* scope, PreParserExpression value, bool* has_function) {}
926 
CheckAssigningFunctionLiteralToProperty(PreParserExpression left,PreParserExpression right)927   static void CheckAssigningFunctionLiteralToProperty(
928       PreParserExpression left, PreParserExpression right) {}
929 
930   // PreParser doesn't need to keep track of eval calls.
CheckPossibleEvalCall(PreParserExpression expression,PreParserScope * scope)931   static void CheckPossibleEvalCall(PreParserExpression expression,
932                                     PreParserScope* scope) {}
933 
MarkExpressionAsLValue(PreParserExpression expression)934   static PreParserExpression MarkExpressionAsLValue(
935       PreParserExpression expression) {
936     // TODO(marja): To be able to produce the same errors, the preparser needs
937     // to start tracking which expressions are variables and which are lvalues.
938     return expression;
939   }
940 
ShortcutNumericLiteralBinaryExpression(PreParserExpression * x,PreParserExpression y,Token::Value op,int pos,PreParserFactory * factory)941   bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
942                                               PreParserExpression y,
943                                               Token::Value op,
944                                               int pos,
945                                               PreParserFactory* factory) {
946     return false;
947   }
948 
BuildUnaryExpression(PreParserExpression expression,Token::Value op,int pos,PreParserFactory * factory)949   PreParserExpression BuildUnaryExpression(PreParserExpression expression,
950                                            Token::Value op, int pos,
951                                            PreParserFactory* factory) {
952     return PreParserExpression::Default();
953   }
954 
NewThrowReferenceError(const char * type,int pos)955   PreParserExpression NewThrowReferenceError(const char* type, int pos) {
956     return PreParserExpression::Default();
957   }
NewThrowSyntaxError(const char * type,Handle<Object> arg,int pos)958   PreParserExpression NewThrowSyntaxError(
959       const char* type, Handle<Object> arg, int pos) {
960     return PreParserExpression::Default();
961   }
NewThrowTypeError(const char * type,Handle<Object> arg,int pos)962   PreParserExpression NewThrowTypeError(
963       const char* type, Handle<Object> arg, int pos) {
964     return PreParserExpression::Default();
965   }
966 
967   // Reporting errors.
968   void ReportMessageAt(Scanner::Location location,
969                        const char* message,
970                        const char* arg = NULL,
971                        bool is_reference_error = false);
972   void ReportMessageAt(int start_pos,
973                        int end_pos,
974                        const char* message,
975                        const char* arg = NULL,
976                        bool is_reference_error = false);
977 
978   // "null" return type creators.
EmptyIdentifier()979   static PreParserIdentifier EmptyIdentifier() {
980     return PreParserIdentifier::Default();
981   }
EmptyExpression()982   static PreParserExpression EmptyExpression() {
983     return PreParserExpression::Default();
984   }
EmptyLiteral()985   static PreParserExpression EmptyLiteral() {
986     return PreParserExpression::Default();
987   }
NullExpressionList()988   static PreParserExpressionList NullExpressionList() {
989     return PreParserExpressionList();
990   }
991 
992   // Odd-ball literal creators.
GetLiteralTheHole(int position,PreParserFactory * factory)993   static PreParserExpression GetLiteralTheHole(int position,
994                                                PreParserFactory* factory) {
995     return PreParserExpression::Default();
996   }
997 
998   // Producing data during the recursive descent.
999   PreParserIdentifier GetSymbol(Scanner* scanner);
NextLiteralString(Scanner * scanner,PretenureFlag tenured)1000   static PreParserIdentifier NextLiteralString(Scanner* scanner,
1001                                                PretenureFlag tenured) {
1002     return PreParserIdentifier::Default();
1003   }
1004 
ThisExpression(PreParserScope * scope,PreParserFactory * factory)1005   static PreParserExpression ThisExpression(PreParserScope* scope,
1006                                             PreParserFactory* factory) {
1007     return PreParserExpression::This();
1008   }
1009 
ExpressionFromLiteral(Token::Value token,int pos,Scanner * scanner,PreParserFactory * factory)1010   static PreParserExpression ExpressionFromLiteral(
1011       Token::Value token, int pos, Scanner* scanner,
1012       PreParserFactory* factory) {
1013     return PreParserExpression::Default();
1014   }
1015 
ExpressionFromIdentifier(PreParserIdentifier name,int pos,PreParserScope * scope,PreParserFactory * factory)1016   static PreParserExpression ExpressionFromIdentifier(
1017       PreParserIdentifier name, int pos, PreParserScope* scope,
1018       PreParserFactory* factory) {
1019     return PreParserExpression::FromIdentifier(name);
1020   }
1021 
1022   PreParserExpression ExpressionFromString(int pos,
1023                                            Scanner* scanner,
1024                                            PreParserFactory* factory = NULL);
1025 
NewExpressionList(int size,void * zone)1026   static PreParserExpressionList NewExpressionList(int size, void* zone) {
1027     return PreParserExpressionList();
1028   }
1029 
NewStatementList(int size,void * zone)1030   static PreParserStatementList NewStatementList(int size, void* zone) {
1031     return PreParserStatementList();
1032   }
1033 
NewPropertyList(int size,void * zone)1034   static PreParserExpressionList NewPropertyList(int size, void* zone) {
1035     return PreParserExpressionList();
1036   }
1037 
1038   // Temporary glue; these functions will move to ParserBase.
1039   PreParserExpression ParseV8Intrinsic(bool* ok);
1040   PreParserExpression ParseFunctionLiteral(
1041       PreParserIdentifier name,
1042       Scanner::Location function_name_location,
1043       bool name_is_strict_reserved,
1044       bool is_generator,
1045       int function_token_position,
1046       FunctionLiteral::FunctionType type,
1047       FunctionLiteral::ArityRestriction arity_restriction,
1048       bool* ok);
1049 
1050  private:
1051   PreParser* pre_parser_;
1052 };
1053 
1054 
1055 // Preparsing checks a JavaScript program and emits preparse-data that helps
1056 // a later parsing to be faster.
1057 // See preparse-data-format.h for the data format.
1058 
1059 // The PreParser checks that the syntax follows the grammar for JavaScript,
1060 // and collects some information about the program along the way.
1061 // The grammar check is only performed in order to understand the program
1062 // sufficiently to deduce some information about it, that can be used
1063 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
1064 // rather it is to speed up properly written and correct programs.
1065 // That means that contextual checks (like a label being declared where
1066 // it is used) are generally omitted.
1067 class PreParser : public ParserBase<PreParserTraits> {
1068  public:
1069   typedef PreParserIdentifier Identifier;
1070   typedef PreParserExpression Expression;
1071   typedef PreParserStatement Statement;
1072 
1073   enum PreParseResult {
1074     kPreParseStackOverflow,
1075     kPreParseSuccess
1076   };
1077 
PreParser(Scanner * scanner,ParserRecorder * log,uintptr_t stack_limit)1078   PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit)
1079       : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL,
1080                                     this) {}
1081 
1082   // Pre-parse the program from the character stream; returns true on
1083   // success (even if parsing failed, the pre-parse data successfully
1084   // captured the syntax error), and false if a stack-overflow happened
1085   // during parsing.
PreParseProgram()1086   PreParseResult PreParseProgram() {
1087     PreParserScope scope(scope_, GLOBAL_SCOPE);
1088     FunctionState top_scope(&function_state_, &scope_, &scope, NULL);
1089     bool ok = true;
1090     int start_position = scanner()->peek_location().beg_pos;
1091     ParseSourceElements(Token::EOS, &ok);
1092     if (stack_overflow()) return kPreParseStackOverflow;
1093     if (!ok) {
1094       ReportUnexpectedToken(scanner()->current_token());
1095     } else if (scope_->strict_mode() == STRICT) {
1096       CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok);
1097     }
1098     return kPreParseSuccess;
1099   }
1100 
1101   // Parses a single function literal, from the opening parentheses before
1102   // parameters to the closing brace after the body.
1103   // Returns a FunctionEntry describing the body of the function in enough
1104   // detail that it can be lazily compiled.
1105   // The scanner is expected to have matched the "function" or "function*"
1106   // keyword and parameters, and have consumed the initial '{'.
1107   // At return, unless an error occurred, the scanner is positioned before the
1108   // the final '}'.
1109   PreParseResult PreParseLazyFunction(StrictMode strict_mode,
1110                                       bool is_generator,
1111                                       ParserRecorder* log);
1112 
1113  private:
1114   friend class PreParserTraits;
1115 
1116   // These types form an algebra over syntactic categories that is just
1117   // rich enough to let us recognize and propagate the constructs that
1118   // are either being counted in the preparser data, or is important
1119   // to throw the correct syntax error exceptions.
1120 
1121   enum VariableDeclarationContext {
1122     kSourceElement,
1123     kStatement,
1124     kForStatement
1125   };
1126 
1127   // If a list of variable declarations includes any initializers.
1128   enum VariableDeclarationProperties {
1129     kHasInitializers,
1130     kHasNoInitializers
1131   };
1132 
1133 
1134   enum SourceElements {
1135     kUnknownSourceElements
1136   };
1137 
1138   // All ParseXXX functions take as the last argument an *ok parameter
1139   // which is set to false if parsing failed; it is unchanged otherwise.
1140   // By making the 'exception handling' explicit, we are forced to check
1141   // for failure at the call sites.
1142   Statement ParseSourceElement(bool* ok);
1143   SourceElements ParseSourceElements(int end_token, bool* ok);
1144   Statement ParseStatement(bool* ok);
1145   Statement ParseFunctionDeclaration(bool* ok);
1146   Statement ParseBlock(bool* ok);
1147   Statement ParseVariableStatement(VariableDeclarationContext var_context,
1148                                    bool* ok);
1149   Statement ParseVariableDeclarations(VariableDeclarationContext var_context,
1150                                       VariableDeclarationProperties* decl_props,
1151                                       int* num_decl,
1152                                       bool* ok);
1153   Statement ParseExpressionOrLabelledStatement(bool* ok);
1154   Statement ParseIfStatement(bool* ok);
1155   Statement ParseContinueStatement(bool* ok);
1156   Statement ParseBreakStatement(bool* ok);
1157   Statement ParseReturnStatement(bool* ok);
1158   Statement ParseWithStatement(bool* ok);
1159   Statement ParseSwitchStatement(bool* ok);
1160   Statement ParseDoWhileStatement(bool* ok);
1161   Statement ParseWhileStatement(bool* ok);
1162   Statement ParseForStatement(bool* ok);
1163   Statement ParseThrowStatement(bool* ok);
1164   Statement ParseTryStatement(bool* ok);
1165   Statement ParseDebuggerStatement(bool* ok);
1166   Expression ParseConditionalExpression(bool accept_IN, bool* ok);
1167   Expression ParseObjectLiteral(bool* ok);
1168   Expression ParseV8Intrinsic(bool* ok);
1169 
1170   Expression ParseFunctionLiteral(
1171       Identifier name,
1172       Scanner::Location function_name_location,
1173       bool name_is_strict_reserved,
1174       bool is_generator,
1175       int function_token_pos,
1176       FunctionLiteral::FunctionType function_type,
1177       FunctionLiteral::ArityRestriction arity_restriction,
1178       bool* ok);
1179   void ParseLazyFunctionLiteralBody(bool* ok);
1180 
1181   bool CheckInOrOf(bool accept_OF);
1182 };
1183 
1184 template<class Traits>
FunctionState(FunctionState ** function_state_stack,typename Traits::Type::Scope ** scope_stack,typename Traits::Type::Scope * scope,typename Traits::Type::Zone * extra_param)1185 ParserBase<Traits>::FunctionState::FunctionState(
1186     FunctionState** function_state_stack,
1187     typename Traits::Type::Scope** scope_stack,
1188     typename Traits::Type::Scope* scope,
1189     typename Traits::Type::Zone* extra_param)
1190     : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
1191       next_handler_index_(0),
1192       expected_property_count_(0),
1193       is_generator_(false),
1194       generator_object_variable_(NULL),
1195       function_state_stack_(function_state_stack),
1196       outer_function_state_(*function_state_stack),
1197       scope_stack_(scope_stack),
1198       outer_scope_(*scope_stack),
1199       saved_ast_node_id_(0),
1200       extra_param_(extra_param),
1201       factory_(extra_param) {
1202   *scope_stack_ = scope;
1203   *function_state_stack = this;
1204   Traits::SetUpFunctionState(this, extra_param);
1205 }
1206 
1207 
1208 template<class Traits>
~FunctionState()1209 ParserBase<Traits>::FunctionState::~FunctionState() {
1210   *scope_stack_ = outer_scope_;
1211   *function_state_stack_ = outer_function_state_;
1212   Traits::TearDownFunctionState(this, extra_param_);
1213 }
1214 
1215 
1216 template<class Traits>
ReportUnexpectedToken(Token::Value token)1217 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
1218   Scanner::Location source_location = scanner()->location();
1219 
1220   // Four of the tokens are treated specially
1221   switch (token) {
1222     case Token::EOS:
1223       return ReportMessageAt(source_location, "unexpected_eos");
1224     case Token::NUMBER:
1225       return ReportMessageAt(source_location, "unexpected_token_number");
1226     case Token::STRING:
1227       return ReportMessageAt(source_location, "unexpected_token_string");
1228     case Token::IDENTIFIER:
1229       return ReportMessageAt(source_location, "unexpected_token_identifier");
1230     case Token::FUTURE_RESERVED_WORD:
1231       return ReportMessageAt(source_location, "unexpected_reserved");
1232     case Token::YIELD:
1233     case Token::FUTURE_STRICT_RESERVED_WORD:
1234       return ReportMessageAt(source_location, strict_mode() == SLOPPY
1235           ? "unexpected_token_identifier" : "unexpected_strict_reserved");
1236     default:
1237       const char* name = Token::String(token);
1238       ASSERT(name != NULL);
1239       Traits::ReportMessageAt(source_location, "unexpected_token", name);
1240   }
1241 }
1242 
1243 
1244 template<class Traits>
ParseIdentifier(AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments,bool * ok)1245 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
1246     AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments,
1247     bool* ok) {
1248   Token::Value next = Next();
1249   if (next == Token::IDENTIFIER) {
1250     IdentifierT name = this->GetSymbol(scanner());
1251     if (allow_eval_or_arguments == kDontAllowEvalOrArguments &&
1252         strict_mode() == STRICT && this->IsEvalOrArguments(name)) {
1253       ReportMessage("strict_eval_arguments");
1254       *ok = false;
1255     }
1256     return name;
1257   } else if (strict_mode() == SLOPPY &&
1258              (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1259              (next == Token::YIELD && !is_generator()))) {
1260     return this->GetSymbol(scanner());
1261   } else {
1262     this->ReportUnexpectedToken(next);
1263     *ok = false;
1264     return Traits::EmptyIdentifier();
1265   }
1266 }
1267 
1268 
1269 template <class Traits>
1270 typename ParserBase<Traits>::IdentifierT ParserBase<
ParseIdentifierOrStrictReservedWord(bool * is_strict_reserved,bool * ok)1271     Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
1272                                                  bool* ok) {
1273   Token::Value next = Next();
1274   if (next == Token::IDENTIFIER) {
1275     *is_strict_reserved = false;
1276   } else if (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1277              (next == Token::YIELD && !this->is_generator())) {
1278     *is_strict_reserved = true;
1279   } else {
1280     ReportUnexpectedToken(next);
1281     *ok = false;
1282     return Traits::EmptyIdentifier();
1283   }
1284   return this->GetSymbol(scanner());
1285 }
1286 
1287 
1288 template <class Traits>
1289 typename ParserBase<Traits>::IdentifierT
ParseIdentifierName(bool * ok)1290 ParserBase<Traits>::ParseIdentifierName(bool* ok) {
1291   Token::Value next = Next();
1292   if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD &&
1293       next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
1294     this->ReportUnexpectedToken(next);
1295     *ok = false;
1296     return Traits::EmptyIdentifier();
1297   }
1298   return this->GetSymbol(scanner());
1299 }
1300 
1301 
1302 template <class Traits>
1303 typename ParserBase<Traits>::IdentifierT
ParseIdentifierNameOrGetOrSet(bool * is_get,bool * is_set,bool * ok)1304 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get,
1305                                                   bool* is_set,
1306                                                   bool* ok) {
1307   IdentifierT result = ParseIdentifierName(ok);
1308   if (!*ok) return Traits::EmptyIdentifier();
1309   scanner()->IsGetOrSet(is_get, is_set);
1310   return result;
1311 }
1312 
1313 
1314 template <class Traits>
ParseRegExpLiteral(bool seen_equal,bool * ok)1315 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
1316     bool seen_equal, bool* ok) {
1317   int pos = peek_position();
1318   if (!scanner()->ScanRegExpPattern(seen_equal)) {
1319     Next();
1320     ReportMessage("unterminated_regexp");
1321     *ok = false;
1322     return Traits::EmptyExpression();
1323   }
1324 
1325   int literal_index = function_state_->NextMaterializedLiteralIndex();
1326 
1327   IdentifierT js_pattern = this->NextLiteralString(scanner(), TENURED);
1328   if (!scanner()->ScanRegExpFlags()) {
1329     Next();
1330     ReportMessage("invalid_regexp_flags");
1331     *ok = false;
1332     return Traits::EmptyExpression();
1333   }
1334   IdentifierT js_flags = this->NextLiteralString(scanner(), TENURED);
1335   Next();
1336   return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
1337 }
1338 
1339 
1340 #define CHECK_OK  ok); \
1341   if (!*ok) return this->EmptyExpression(); \
1342   ((void)0
1343 #define DUMMY )  // to make indentation work
1344 #undef DUMMY
1345 
1346 // Used in functions where the return type is not ExpressionT.
1347 #define CHECK_OK_CUSTOM(x) ok); \
1348   if (!*ok) return this->x(); \
1349   ((void)0
1350 #define DUMMY )  // to make indentation work
1351 #undef DUMMY
1352 
1353 template <class Traits>
1354 typename ParserBase<Traits>::ExpressionT
ParsePrimaryExpression(bool * ok)1355 ParserBase<Traits>::ParsePrimaryExpression(bool* ok) {
1356   // PrimaryExpression ::
1357   //   'this'
1358   //   'null'
1359   //   'true'
1360   //   'false'
1361   //   Identifier
1362   //   Number
1363   //   String
1364   //   ArrayLiteral
1365   //   ObjectLiteral
1366   //   RegExpLiteral
1367   //   '(' Expression ')'
1368 
1369   int pos = peek_position();
1370   ExpressionT result = this->EmptyExpression();
1371   Token::Value token = peek();
1372   switch (token) {
1373     case Token::THIS: {
1374       Consume(Token::THIS);
1375       result = this->ThisExpression(scope_, factory());
1376       break;
1377     }
1378 
1379     case Token::NULL_LITERAL:
1380     case Token::TRUE_LITERAL:
1381     case Token::FALSE_LITERAL:
1382     case Token::NUMBER:
1383       Next();
1384       result = this->ExpressionFromLiteral(token, pos, scanner(), factory());
1385       break;
1386 
1387     case Token::IDENTIFIER:
1388     case Token::YIELD:
1389     case Token::FUTURE_STRICT_RESERVED_WORD: {
1390       // Using eval or arguments in this context is OK even in strict mode.
1391       IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1392       result = this->ExpressionFromIdentifier(name, pos, scope_, factory());
1393       break;
1394     }
1395 
1396     case Token::STRING: {
1397       Consume(Token::STRING);
1398       result = this->ExpressionFromString(pos, scanner(), factory());
1399       break;
1400     }
1401 
1402     case Token::ASSIGN_DIV:
1403       result = this->ParseRegExpLiteral(true, CHECK_OK);
1404       break;
1405 
1406     case Token::DIV:
1407       result = this->ParseRegExpLiteral(false, CHECK_OK);
1408       break;
1409 
1410     case Token::LBRACK:
1411       result = this->ParseArrayLiteral(CHECK_OK);
1412       break;
1413 
1414     case Token::LBRACE:
1415       result = this->ParseObjectLiteral(CHECK_OK);
1416       break;
1417 
1418     case Token::LPAREN:
1419       Consume(Token::LPAREN);
1420       // Heuristically try to detect immediately called functions before
1421       // seeing the call parentheses.
1422       parenthesized_function_ = (peek() == Token::FUNCTION);
1423       result = this->ParseExpression(true, CHECK_OK);
1424       Expect(Token::RPAREN, CHECK_OK);
1425       break;
1426 
1427     case Token::MOD:
1428       if (allow_natives_syntax() || extension_ != NULL) {
1429         result = this->ParseV8Intrinsic(CHECK_OK);
1430         break;
1431       }
1432       // If we're not allowing special syntax we fall-through to the
1433       // default case.
1434 
1435     default: {
1436       Next();
1437       ReportUnexpectedToken(token);
1438       *ok = false;
1439     }
1440   }
1441 
1442   return result;
1443 }
1444 
1445 // Precedence = 1
1446 template <class Traits>
ParseExpression(bool accept_IN,bool * ok)1447 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
1448     bool accept_IN, bool* ok) {
1449   // Expression ::
1450   //   AssignmentExpression
1451   //   Expression ',' AssignmentExpression
1452 
1453   ExpressionT result = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
1454   while (peek() == Token::COMMA) {
1455     Expect(Token::COMMA, CHECK_OK);
1456     int pos = position();
1457     ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
1458     result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
1459   }
1460   return result;
1461 }
1462 
1463 
1464 template <class Traits>
ParseArrayLiteral(bool * ok)1465 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
1466     bool* ok) {
1467   // ArrayLiteral ::
1468   //   '[' Expression? (',' Expression?)* ']'
1469 
1470   int pos = peek_position();
1471   typename Traits::Type::ExpressionList values =
1472       this->NewExpressionList(4, zone_);
1473   Expect(Token::LBRACK, CHECK_OK);
1474   while (peek() != Token::RBRACK) {
1475     ExpressionT elem = this->EmptyExpression();
1476     if (peek() == Token::COMMA) {
1477       elem = this->GetLiteralTheHole(peek_position(), factory());
1478     } else {
1479       elem = this->ParseAssignmentExpression(true, CHECK_OK);
1480     }
1481     values->Add(elem, zone_);
1482     if (peek() != Token::RBRACK) {
1483       Expect(Token::COMMA, CHECK_OK);
1484     }
1485   }
1486   Expect(Token::RBRACK, CHECK_OK);
1487 
1488   // Update the scope information before the pre-parsing bailout.
1489   int literal_index = function_state_->NextMaterializedLiteralIndex();
1490 
1491   return factory()->NewArrayLiteral(values, literal_index, pos);
1492 }
1493 
1494 
1495 template <class Traits>
ParseObjectLiteral(bool * ok)1496 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
1497     bool* ok) {
1498   // ObjectLiteral ::
1499   // '{' ((
1500   //       ((IdentifierName | String | Number) ':' AssignmentExpression) |
1501   //       (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
1502   //      ) ',')* '}'
1503   // (Except that trailing comma is not required and not allowed.)
1504 
1505   int pos = peek_position();
1506   typename Traits::Type::PropertyList properties =
1507       this->NewPropertyList(4, zone_);
1508   int number_of_boilerplate_properties = 0;
1509   bool has_function = false;
1510 
1511   ObjectLiteralChecker checker(this, strict_mode());
1512 
1513   Expect(Token::LBRACE, CHECK_OK);
1514 
1515   while (peek() != Token::RBRACE) {
1516     if (fni_ != NULL) fni_->Enter();
1517 
1518     typename Traits::Type::Literal key = this->EmptyLiteral();
1519     Token::Value next = peek();
1520     int next_pos = peek_position();
1521 
1522     switch (next) {
1523       case Token::FUTURE_RESERVED_WORD:
1524       case Token::FUTURE_STRICT_RESERVED_WORD:
1525       case Token::IDENTIFIER: {
1526         bool is_getter = false;
1527         bool is_setter = false;
1528         IdentifierT id =
1529             ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
1530         if (fni_ != NULL) this->PushLiteralName(fni_, id);
1531 
1532         if ((is_getter || is_setter) && peek() != Token::COLON) {
1533           // Special handling of getter and setter syntax:
1534           // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
1535           // We have already read the "get" or "set" keyword.
1536           Token::Value next = Next();
1537           if (next != i::Token::IDENTIFIER &&
1538               next != i::Token::FUTURE_RESERVED_WORD &&
1539               next != i::Token::FUTURE_STRICT_RESERVED_WORD &&
1540               next != i::Token::NUMBER &&
1541               next != i::Token::STRING &&
1542               !Token::IsKeyword(next)) {
1543             ReportUnexpectedToken(next);
1544             *ok = false;
1545             return this->EmptyLiteral();
1546           }
1547           // Validate the property.
1548           PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
1549           checker.CheckProperty(next, type, CHECK_OK);
1550           IdentifierT name = this->GetSymbol(scanner_);
1551           typename Traits::Type::FunctionLiteral value =
1552               this->ParseFunctionLiteral(
1553                   name, scanner()->location(),
1554                   false,  // reserved words are allowed here
1555                   false,  // not a generator
1556                   RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
1557                   is_getter ? FunctionLiteral::GETTER_ARITY
1558                             : FunctionLiteral::SETTER_ARITY,
1559                   CHECK_OK);
1560           typename Traits::Type::ObjectLiteralProperty property =
1561               factory()->NewObjectLiteralProperty(is_getter, value, next_pos);
1562           if (this->IsBoilerplateProperty(property)) {
1563             number_of_boilerplate_properties++;
1564           }
1565           properties->Add(property, zone());
1566           if (peek() != Token::RBRACE) {
1567             // Need {} because of the CHECK_OK macro.
1568             Expect(Token::COMMA, CHECK_OK);
1569           }
1570 
1571           if (fni_ != NULL) {
1572             fni_->Infer();
1573             fni_->Leave();
1574           }
1575           continue;  // restart the while
1576         }
1577         // Failed to parse as get/set property, so it's just a normal property
1578         // (which might be called "get" or "set" or something else).
1579         key = factory()->NewLiteral(id, next_pos);
1580         break;
1581       }
1582       case Token::STRING: {
1583         Consume(Token::STRING);
1584         IdentifierT string = this->GetSymbol(scanner_);
1585         if (fni_ != NULL) this->PushLiteralName(fni_, string);
1586         uint32_t index;
1587         if (this->IsArrayIndex(string, &index)) {
1588           key = factory()->NewNumberLiteral(index, next_pos);
1589           break;
1590         }
1591         key = factory()->NewLiteral(string, next_pos);
1592         break;
1593       }
1594       case Token::NUMBER: {
1595         Consume(Token::NUMBER);
1596         key = this->ExpressionFromLiteral(Token::NUMBER, next_pos, scanner_,
1597                                           factory());
1598         break;
1599       }
1600       default:
1601         if (Token::IsKeyword(next)) {
1602           Consume(next);
1603           IdentifierT string = this->GetSymbol(scanner_);
1604           key = factory()->NewLiteral(string, next_pos);
1605         } else {
1606           Token::Value next = Next();
1607           ReportUnexpectedToken(next);
1608           *ok = false;
1609           return this->EmptyLiteral();
1610         }
1611     }
1612 
1613     // Validate the property
1614     checker.CheckProperty(next, kValueProperty, CHECK_OK);
1615 
1616     Expect(Token::COLON, CHECK_OK);
1617     ExpressionT value = this->ParseAssignmentExpression(true, CHECK_OK);
1618 
1619     typename Traits::Type::ObjectLiteralProperty property =
1620         factory()->NewObjectLiteralProperty(key, value);
1621 
1622     // Mark top-level object literals that contain function literals and
1623     // pretenure the literal so it can be added as a constant function
1624     // property. (Parser only.)
1625     this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, value,
1626                                                           &has_function);
1627 
1628     // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
1629     if (this->IsBoilerplateProperty(property)) {
1630       number_of_boilerplate_properties++;
1631     }
1632     properties->Add(property, zone());
1633 
1634     // TODO(1240767): Consider allowing trailing comma.
1635     if (peek() != Token::RBRACE) {
1636       // Need {} because of the CHECK_OK macro.
1637       Expect(Token::COMMA, CHECK_OK);
1638     }
1639 
1640     if (fni_ != NULL) {
1641       fni_->Infer();
1642       fni_->Leave();
1643     }
1644   }
1645   Expect(Token::RBRACE, CHECK_OK);
1646 
1647   // Computation of literal_index must happen before pre parse bailout.
1648   int literal_index = function_state_->NextMaterializedLiteralIndex();
1649 
1650   return factory()->NewObjectLiteral(properties,
1651                                      literal_index,
1652                                      number_of_boilerplate_properties,
1653                                      has_function,
1654                                      pos);
1655 }
1656 
1657 
1658 template <class Traits>
ParseArguments(bool * ok)1659 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
1660     bool* ok) {
1661   // Arguments ::
1662   //   '(' (AssignmentExpression)*[','] ')'
1663 
1664   typename Traits::Type::ExpressionList result =
1665       this->NewExpressionList(4, zone_);
1666   Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
1667   bool done = (peek() == Token::RPAREN);
1668   while (!done) {
1669     ExpressionT argument = this->ParseAssignmentExpression(
1670         true, CHECK_OK_CUSTOM(NullExpressionList));
1671     result->Add(argument, zone_);
1672     if (result->length() > Code::kMaxArguments) {
1673       ReportMessage("too_many_arguments");
1674       *ok = false;
1675       return this->NullExpressionList();
1676     }
1677     done = (peek() == Token::RPAREN);
1678     if (!done) {
1679       // Need {} because of the CHECK_OK_CUSTOM macro.
1680       Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList));
1681     }
1682   }
1683   Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList));
1684   return result;
1685 }
1686 
1687 // Precedence = 2
1688 template <class Traits>
1689 typename ParserBase<Traits>::ExpressionT
ParseAssignmentExpression(bool accept_IN,bool * ok)1690 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
1691   // AssignmentExpression ::
1692   //   ConditionalExpression
1693   //   YieldExpression
1694   //   LeftHandSideExpression AssignmentOperator AssignmentExpression
1695 
1696   Scanner::Location lhs_location = scanner()->peek_location();
1697 
1698   if (peek() == Token::YIELD && is_generator()) {
1699     return this->ParseYieldExpression(ok);
1700   }
1701 
1702   if (fni_ != NULL) fni_->Enter();
1703   ExpressionT expression =
1704       this->ParseConditionalExpression(accept_IN, CHECK_OK);
1705 
1706   if (!Token::IsAssignmentOp(peek())) {
1707     if (fni_ != NULL) fni_->Leave();
1708     // Parsed conditional expression only (no assignment).
1709     return expression;
1710   }
1711 
1712   expression = this->CheckAndRewriteReferenceExpression(
1713       expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK);
1714   expression = this->MarkExpressionAsLValue(expression);
1715 
1716   Token::Value op = Next();  // Get assignment operator.
1717   int pos = position();
1718   ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
1719 
1720   // TODO(1231235): We try to estimate the set of properties set by
1721   // constructors. We define a new property whenever there is an
1722   // assignment to a property of 'this'. We should probably only add
1723   // properties if we haven't seen them before. Otherwise we'll
1724   // probably overestimate the number of properties.
1725   if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
1726     function_state_->AddProperty();
1727   }
1728 
1729   this->CheckAssigningFunctionLiteralToProperty(expression, right);
1730 
1731   if (fni_ != NULL) {
1732     // Check if the right hand side is a call to avoid inferring a
1733     // name if we're dealing with "a = function(){...}();"-like
1734     // expression.
1735     if ((op == Token::INIT_VAR
1736          || op == Token::INIT_CONST_LEGACY
1737          || op == Token::ASSIGN)
1738         && (!right->IsCall() && !right->IsCallNew())) {
1739       fni_->Infer();
1740     } else {
1741       fni_->RemoveLastFunction();
1742     }
1743     fni_->Leave();
1744   }
1745 
1746   return factory()->NewAssignment(op, expression, right, pos);
1747 }
1748 
1749 template <class Traits>
1750 typename ParserBase<Traits>::ExpressionT
ParseYieldExpression(bool * ok)1751 ParserBase<Traits>::ParseYieldExpression(bool* ok) {
1752   // YieldExpression ::
1753   //   'yield' '*'? AssignmentExpression
1754   int pos = peek_position();
1755   Expect(Token::YIELD, CHECK_OK);
1756   Yield::Kind kind =
1757       Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND;
1758   ExpressionT generator_object =
1759       factory()->NewVariableProxy(function_state_->generator_object_variable());
1760   ExpressionT expression =
1761       ParseAssignmentExpression(false, CHECK_OK);
1762   typename Traits::Type::YieldExpression yield =
1763       factory()->NewYield(generator_object, expression, kind, pos);
1764   if (kind == Yield::DELEGATING) {
1765     yield->set_index(function_state_->NextHandlerIndex());
1766   }
1767   return yield;
1768 }
1769 
1770 
1771 // Precedence = 3
1772 template <class Traits>
1773 typename ParserBase<Traits>::ExpressionT
ParseConditionalExpression(bool accept_IN,bool * ok)1774 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, bool* ok) {
1775   // ConditionalExpression ::
1776   //   LogicalOrExpression
1777   //   LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
1778 
1779   int pos = peek_position();
1780   // We start using the binary expression parser for prec >= 4 only!
1781   ExpressionT expression = this->ParseBinaryExpression(4, accept_IN, CHECK_OK);
1782   if (peek() != Token::CONDITIONAL) return expression;
1783   Consume(Token::CONDITIONAL);
1784   // In parsing the first assignment expression in conditional
1785   // expressions we always accept the 'in' keyword; see ECMA-262,
1786   // section 11.12, page 58.
1787   ExpressionT left = ParseAssignmentExpression(true, CHECK_OK);
1788   Expect(Token::COLON, CHECK_OK);
1789   ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK);
1790   return factory()->NewConditional(expression, left, right, pos);
1791 }
1792 
1793 
1794 // Precedence >= 4
1795 template <class Traits>
1796 typename ParserBase<Traits>::ExpressionT
ParseBinaryExpression(int prec,bool accept_IN,bool * ok)1797 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
1798   ASSERT(prec >= 4);
1799   ExpressionT x = this->ParseUnaryExpression(CHECK_OK);
1800   for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
1801     // prec1 >= 4
1802     while (Precedence(peek(), accept_IN) == prec1) {
1803       Token::Value op = Next();
1804       int pos = position();
1805       ExpressionT y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
1806 
1807       if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
1808                                                        factory())) {
1809         continue;
1810       }
1811 
1812       // For now we distinguish between comparisons and other binary
1813       // operations.  (We could combine the two and get rid of this
1814       // code and AST node eventually.)
1815       if (Token::IsCompareOp(op)) {
1816         // We have a comparison.
1817         Token::Value cmp = op;
1818         switch (op) {
1819           case Token::NE: cmp = Token::EQ; break;
1820           case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
1821           default: break;
1822         }
1823         x = factory()->NewCompareOperation(cmp, x, y, pos);
1824         if (cmp != op) {
1825           // The comparison was negated - add a NOT.
1826           x = factory()->NewUnaryOperation(Token::NOT, x, pos);
1827         }
1828 
1829       } else {
1830         // We have a "normal" binary operation.
1831         x = factory()->NewBinaryOperation(op, x, y, pos);
1832       }
1833     }
1834   }
1835   return x;
1836 }
1837 
1838 
1839 template <class Traits>
1840 typename ParserBase<Traits>::ExpressionT
ParseUnaryExpression(bool * ok)1841 ParserBase<Traits>::ParseUnaryExpression(bool* ok) {
1842   // UnaryExpression ::
1843   //   PostfixExpression
1844   //   'delete' UnaryExpression
1845   //   'void' UnaryExpression
1846   //   'typeof' UnaryExpression
1847   //   '++' UnaryExpression
1848   //   '--' UnaryExpression
1849   //   '+' UnaryExpression
1850   //   '-' UnaryExpression
1851   //   '~' UnaryExpression
1852   //   '!' UnaryExpression
1853 
1854   Token::Value op = peek();
1855   if (Token::IsUnaryOp(op)) {
1856     op = Next();
1857     int pos = position();
1858     ExpressionT expression = ParseUnaryExpression(CHECK_OK);
1859 
1860     // "delete identifier" is a syntax error in strict mode.
1861     if (op == Token::DELETE && strict_mode() == STRICT &&
1862         this->IsIdentifier(expression)) {
1863       ReportMessage("strict_delete");
1864       *ok = false;
1865       return this->EmptyExpression();
1866     }
1867 
1868     // Allow Traits do rewrite the expression.
1869     return this->BuildUnaryExpression(expression, op, pos, factory());
1870   } else if (Token::IsCountOp(op)) {
1871     op = Next();
1872     Scanner::Location lhs_location = scanner()->peek_location();
1873     ExpressionT expression = this->ParseUnaryExpression(CHECK_OK);
1874     expression = this->CheckAndRewriteReferenceExpression(
1875         expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK);
1876     this->MarkExpressionAsLValue(expression);
1877 
1878     return factory()->NewCountOperation(op,
1879                                         true /* prefix */,
1880                                         expression,
1881                                         position());
1882 
1883   } else {
1884     return this->ParsePostfixExpression(ok);
1885   }
1886 }
1887 
1888 
1889 template <class Traits>
1890 typename ParserBase<Traits>::ExpressionT
ParsePostfixExpression(bool * ok)1891 ParserBase<Traits>::ParsePostfixExpression(bool* ok) {
1892   // PostfixExpression ::
1893   //   LeftHandSideExpression ('++' | '--')?
1894 
1895   Scanner::Location lhs_location = scanner()->peek_location();
1896   ExpressionT expression = this->ParseLeftHandSideExpression(CHECK_OK);
1897   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
1898       Token::IsCountOp(peek())) {
1899     expression = this->CheckAndRewriteReferenceExpression(
1900         expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK);
1901     expression = this->MarkExpressionAsLValue(expression);
1902 
1903     Token::Value next = Next();
1904     expression =
1905         factory()->NewCountOperation(next,
1906                                      false /* postfix */,
1907                                      expression,
1908                                      position());
1909   }
1910   return expression;
1911 }
1912 
1913 
1914 template <class Traits>
1915 typename ParserBase<Traits>::ExpressionT
ParseLeftHandSideExpression(bool * ok)1916 ParserBase<Traits>::ParseLeftHandSideExpression(bool* ok) {
1917   // LeftHandSideExpression ::
1918   //   (NewExpression | MemberExpression) ...
1919 
1920   ExpressionT result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
1921 
1922   while (true) {
1923     switch (peek()) {
1924       case Token::LBRACK: {
1925         Consume(Token::LBRACK);
1926         int pos = position();
1927         ExpressionT index = ParseExpression(true, CHECK_OK);
1928         result = factory()->NewProperty(result, index, pos);
1929         Expect(Token::RBRACK, CHECK_OK);
1930         break;
1931       }
1932 
1933       case Token::LPAREN: {
1934         int pos;
1935         if (scanner()->current_token() == Token::IDENTIFIER) {
1936           // For call of an identifier we want to report position of
1937           // the identifier as position of the call in the stack trace.
1938           pos = position();
1939         } else {
1940           // For other kinds of calls we record position of the parenthesis as
1941           // position of the call. Note that this is extremely important for
1942           // expressions of the form function(){...}() for which call position
1943           // should not point to the closing brace otherwise it will intersect
1944           // with positions recorded for function literal and confuse debugger.
1945           pos = peek_position();
1946           // Also the trailing parenthesis are a hint that the function will
1947           // be called immediately. If we happen to have parsed a preceding
1948           // function literal eagerly, we can also compile it eagerly.
1949           if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
1950             result->AsFunctionLiteral()->set_parenthesized();
1951           }
1952         }
1953         typename Traits::Type::ExpressionList args = ParseArguments(CHECK_OK);
1954 
1955         // Keep track of eval() calls since they disable all local variable
1956         // optimizations.
1957         // The calls that need special treatment are the
1958         // direct eval calls. These calls are all of the form eval(...), with
1959         // no explicit receiver.
1960         // These calls are marked as potentially direct eval calls. Whether
1961         // they are actually direct calls to eval is determined at run time.
1962         this->CheckPossibleEvalCall(result, scope_);
1963         result = factory()->NewCall(result, args, pos);
1964         if (fni_ != NULL) fni_->RemoveLastFunction();
1965         break;
1966       }
1967 
1968       case Token::PERIOD: {
1969         Consume(Token::PERIOD);
1970         int pos = position();
1971         IdentifierT name = ParseIdentifierName(CHECK_OK);
1972         result = factory()->NewProperty(
1973             result, factory()->NewLiteral(name, pos), pos);
1974         if (fni_ != NULL) this->PushLiteralName(fni_, name);
1975         break;
1976       }
1977 
1978       default:
1979         return result;
1980     }
1981   }
1982 }
1983 
1984 
1985 template <class Traits>
1986 typename ParserBase<Traits>::ExpressionT
ParseMemberWithNewPrefixesExpression(bool * ok)1987 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) {
1988   // NewExpression ::
1989   //   ('new')+ MemberExpression
1990 
1991   // The grammar for new expressions is pretty warped. We can have several 'new'
1992   // keywords following each other, and then a MemberExpression. When we see '('
1993   // after the MemberExpression, it's associated with the rightmost unassociated
1994   // 'new' to create a NewExpression with arguments. However, a NewExpression
1995   // can also occur without arguments.
1996 
1997   // Examples of new expression:
1998   // new foo.bar().baz means (new (foo.bar)()).baz
1999   // new foo()() means (new foo())()
2000   // new new foo()() means (new (new foo())())
2001   // new new foo means new (new foo)
2002   // new new foo() means new (new foo())
2003   // new new foo().bar().baz means (new (new foo()).bar()).baz
2004 
2005   if (peek() == Token::NEW) {
2006     Consume(Token::NEW);
2007     int new_pos = position();
2008     ExpressionT result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
2009     if (peek() == Token::LPAREN) {
2010       // NewExpression with arguments.
2011       typename Traits::Type::ExpressionList args =
2012           this->ParseArguments(CHECK_OK);
2013       result = factory()->NewCallNew(result, args, new_pos);
2014       // The expression can still continue with . or [ after the arguments.
2015       result = this->ParseMemberExpressionContinuation(result, CHECK_OK);
2016       return result;
2017     }
2018     // NewExpression without arguments.
2019     return factory()->NewCallNew(result, this->NewExpressionList(0, zone_),
2020                                  new_pos);
2021   }
2022   // No 'new' keyword.
2023   return this->ParseMemberExpression(ok);
2024 }
2025 
2026 
2027 template <class Traits>
2028 typename ParserBase<Traits>::ExpressionT
ParseMemberExpression(bool * ok)2029 ParserBase<Traits>::ParseMemberExpression(bool* ok) {
2030   // MemberExpression ::
2031   //   (PrimaryExpression | FunctionLiteral)
2032   //     ('[' Expression ']' | '.' Identifier | Arguments)*
2033 
2034   // The '[' Expression ']' and '.' Identifier parts are parsed by
2035   // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
2036   // caller.
2037 
2038   // Parse the initial primary or function expression.
2039   ExpressionT result = this->EmptyExpression();
2040   if (peek() == Token::FUNCTION) {
2041     Consume(Token::FUNCTION);
2042     int function_token_position = position();
2043     bool is_generator = allow_generators() && Check(Token::MUL);
2044     IdentifierT name = this->EmptyIdentifier();
2045     bool is_strict_reserved_name = false;
2046     Scanner::Location function_name_location = Scanner::Location::invalid();
2047     FunctionLiteral::FunctionType function_type =
2048         FunctionLiteral::ANONYMOUS_EXPRESSION;
2049     if (peek_any_identifier()) {
2050       name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
2051                                                  CHECK_OK);
2052       function_name_location = scanner()->location();
2053       function_type = FunctionLiteral::NAMED_EXPRESSION;
2054     }
2055     result = this->ParseFunctionLiteral(name,
2056                                         function_name_location,
2057                                         is_strict_reserved_name,
2058                                         is_generator,
2059                                         function_token_position,
2060                                         function_type,
2061                                         FunctionLiteral::NORMAL_ARITY,
2062                                         CHECK_OK);
2063   } else {
2064     result = ParsePrimaryExpression(CHECK_OK);
2065   }
2066 
2067   result = ParseMemberExpressionContinuation(result, CHECK_OK);
2068   return result;
2069 }
2070 
2071 
2072 template <class Traits>
2073 typename ParserBase<Traits>::ExpressionT
ParseMemberExpressionContinuation(ExpressionT expression,bool * ok)2074 ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression,
2075                                                       bool* ok) {
2076   // Parses this part of MemberExpression:
2077   // ('[' Expression ']' | '.' Identifier)*
2078   while (true) {
2079     switch (peek()) {
2080       case Token::LBRACK: {
2081         Consume(Token::LBRACK);
2082         int pos = position();
2083         ExpressionT index = this->ParseExpression(true, CHECK_OK);
2084         expression = factory()->NewProperty(expression, index, pos);
2085         if (fni_ != NULL) {
2086           this->PushPropertyName(fni_, index);
2087         }
2088         Expect(Token::RBRACK, CHECK_OK);
2089         break;
2090       }
2091       case Token::PERIOD: {
2092         Consume(Token::PERIOD);
2093         int pos = position();
2094         IdentifierT name = ParseIdentifierName(CHECK_OK);
2095         expression = factory()->NewProperty(
2096             expression, factory()->NewLiteral(name, pos), pos);
2097         if (fni_ != NULL) {
2098           this->PushLiteralName(fni_, name);
2099         }
2100         break;
2101       }
2102       default:
2103         return expression;
2104     }
2105   }
2106   ASSERT(false);
2107   return this->EmptyExpression();
2108 }
2109 
2110 
2111 template <typename Traits>
2112 typename ParserBase<Traits>::ExpressionT
CheckAndRewriteReferenceExpression(ExpressionT expression,Scanner::Location location,const char * message,bool * ok)2113 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
2114     ExpressionT expression,
2115     Scanner::Location location, const char* message, bool* ok) {
2116   if (strict_mode() == STRICT && this->IsIdentifier(expression) &&
2117       this->IsEvalOrArguments(this->AsIdentifier(expression))) {
2118     this->ReportMessageAt(location, "strict_eval_arguments", false);
2119     *ok = false;
2120     return this->EmptyExpression();
2121   } else if (expression->IsValidReferenceExpression()) {
2122     return expression;
2123   } else if (expression->IsCall()) {
2124     // If it is a call, make it a runtime error for legacy web compatibility.
2125     // Rewrite `expr' to `expr[throw ReferenceError]'.
2126     int pos = location.beg_pos;
2127     ExpressionT error = this->NewThrowReferenceError(message, pos);
2128     return factory()->NewProperty(expression, error, pos);
2129   } else {
2130     this->ReportMessageAt(location, message, true);
2131     *ok = false;
2132     return this->EmptyExpression();
2133   }
2134 }
2135 
2136 
2137 #undef CHECK_OK
2138 #undef CHECK_OK_CUSTOM
2139 
2140 
2141 template <typename Traits>
CheckProperty(Token::Value property,PropertyKind type,bool * ok)2142 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
2143     Token::Value property,
2144     PropertyKind type,
2145     bool* ok) {
2146   int old;
2147   if (property == Token::NUMBER) {
2148     old = scanner()->FindNumber(&finder_, type);
2149   } else {
2150     old = scanner()->FindSymbol(&finder_, type);
2151   }
2152   PropertyKind old_type = static_cast<PropertyKind>(old);
2153   if (HasConflict(old_type, type)) {
2154     if (IsDataDataConflict(old_type, type)) {
2155       // Both are data properties.
2156       if (strict_mode_ == SLOPPY) return;
2157       parser()->ReportMessage("strict_duplicate_property");
2158     } else if (IsDataAccessorConflict(old_type, type)) {
2159       // Both a data and an accessor property with the same name.
2160       parser()->ReportMessage("accessor_data_property");
2161     } else {
2162       ASSERT(IsAccessorAccessorConflict(old_type, type));
2163       // Both accessors of the same type.
2164       parser()->ReportMessage("accessor_get_set");
2165     }
2166     *ok = false;
2167   }
2168 }
2169 
2170 
2171 } }  // v8::internal
2172 
2173 #endif  // V8_PREPARSER_H
2174