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