1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef V8_PARSING_PREPARSER_H
6 #define V8_PARSING_PREPARSER_H
7
8 #include "src/ast/scopes.h"
9 #include "src/bailout-reason.h"
10 #include "src/hashmap.h"
11 #include "src/messages.h"
12 #include "src/parsing/expression-classifier.h"
13 #include "src/parsing/func-name-inferrer.h"
14 #include "src/parsing/parser-base.h"
15 #include "src/parsing/scanner.h"
16 #include "src/parsing/token.h"
17
18 namespace v8 {
19 namespace internal {
20
21
22 class PreParserIdentifier {
23 public:
PreParserIdentifier()24 PreParserIdentifier() : type_(kUnknownIdentifier) {}
Default()25 static PreParserIdentifier Default() {
26 return PreParserIdentifier(kUnknownIdentifier);
27 }
Eval()28 static PreParserIdentifier Eval() {
29 return PreParserIdentifier(kEvalIdentifier);
30 }
Arguments()31 static PreParserIdentifier Arguments() {
32 return PreParserIdentifier(kArgumentsIdentifier);
33 }
Undefined()34 static PreParserIdentifier Undefined() {
35 return PreParserIdentifier(kUndefinedIdentifier);
36 }
FutureReserved()37 static PreParserIdentifier FutureReserved() {
38 return PreParserIdentifier(kFutureReservedIdentifier);
39 }
FutureStrictReserved()40 static PreParserIdentifier FutureStrictReserved() {
41 return PreParserIdentifier(kFutureStrictReservedIdentifier);
42 }
Let()43 static PreParserIdentifier Let() {
44 return PreParserIdentifier(kLetIdentifier);
45 }
Static()46 static PreParserIdentifier Static() {
47 return PreParserIdentifier(kStaticIdentifier);
48 }
Yield()49 static PreParserIdentifier Yield() {
50 return PreParserIdentifier(kYieldIdentifier);
51 }
Prototype()52 static PreParserIdentifier Prototype() {
53 return PreParserIdentifier(kPrototypeIdentifier);
54 }
Constructor()55 static PreParserIdentifier Constructor() {
56 return PreParserIdentifier(kConstructorIdentifier);
57 }
IsEval()58 bool IsEval() const { return type_ == kEvalIdentifier; }
IsArguments()59 bool IsArguments() const { return type_ == kArgumentsIdentifier; }
IsEvalOrArguments()60 bool IsEvalOrArguments() const { return IsEval() || IsArguments(); }
IsUndefined()61 bool IsUndefined() const { return type_ == kUndefinedIdentifier; }
IsLet()62 bool IsLet() const { return type_ == kLetIdentifier; }
IsStatic()63 bool IsStatic() const { return type_ == kStaticIdentifier; }
IsYield()64 bool IsYield() const { return type_ == kYieldIdentifier; }
IsPrototype()65 bool IsPrototype() const { return type_ == kPrototypeIdentifier; }
IsConstructor()66 bool IsConstructor() const { return type_ == kConstructorIdentifier; }
IsFutureReserved()67 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; }
IsFutureStrictReserved()68 bool IsFutureStrictReserved() const {
69 return type_ == kFutureStrictReservedIdentifier ||
70 type_ == kLetIdentifier || type_ == kStaticIdentifier ||
71 type_ == kYieldIdentifier;
72 }
73
74 // Allow identifier->name()[->length()] to work. The preparser
75 // does not need the actual positions/lengths of the identifiers.
76 const PreParserIdentifier* operator->() const { return this; }
raw_name()77 const PreParserIdentifier raw_name() const { return *this; }
78
position()79 int position() const { return 0; }
length()80 int length() const { return 0; }
81
82 private:
83 enum Type {
84 kUnknownIdentifier,
85 kFutureReservedIdentifier,
86 kFutureStrictReservedIdentifier,
87 kLetIdentifier,
88 kStaticIdentifier,
89 kYieldIdentifier,
90 kEvalIdentifier,
91 kArgumentsIdentifier,
92 kUndefinedIdentifier,
93 kPrototypeIdentifier,
94 kConstructorIdentifier
95 };
96
PreParserIdentifier(Type type)97 explicit PreParserIdentifier(Type type) : type_(type) {}
98 Type type_;
99
100 friend class PreParserExpression;
101 };
102
103
104 class PreParserExpression {
105 public:
Default()106 static PreParserExpression Default() {
107 return PreParserExpression(TypeField::encode(kExpression));
108 }
109
Spread(PreParserExpression expression)110 static PreParserExpression Spread(PreParserExpression expression) {
111 return PreParserExpression(TypeField::encode(kSpreadExpression));
112 }
113
FromIdentifier(PreParserIdentifier id)114 static PreParserExpression FromIdentifier(PreParserIdentifier id) {
115 return PreParserExpression(TypeField::encode(kIdentifierExpression) |
116 IdentifierTypeField::encode(id.type_));
117 }
118
BinaryOperation(PreParserExpression left,Token::Value op,PreParserExpression right)119 static PreParserExpression BinaryOperation(PreParserExpression left,
120 Token::Value op,
121 PreParserExpression right) {
122 return PreParserExpression(TypeField::encode(kBinaryOperationExpression));
123 }
124
Assignment()125 static PreParserExpression Assignment() {
126 return PreParserExpression(TypeField::encode(kExpression) |
127 ExpressionTypeField::encode(kAssignment));
128 }
129
ObjectLiteral()130 static PreParserExpression ObjectLiteral() {
131 return PreParserExpression(TypeField::encode(kObjectLiteralExpression));
132 }
133
ArrayLiteral()134 static PreParserExpression ArrayLiteral() {
135 return PreParserExpression(TypeField::encode(kArrayLiteralExpression));
136 }
137
StringLiteral()138 static PreParserExpression StringLiteral() {
139 return PreParserExpression(TypeField::encode(kStringLiteralExpression));
140 }
141
UseStrictStringLiteral()142 static PreParserExpression UseStrictStringLiteral() {
143 return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
144 IsUseStrictField::encode(true));
145 }
146
UseStrongStringLiteral()147 static PreParserExpression UseStrongStringLiteral() {
148 return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
149 IsUseStrongField::encode(true));
150 }
151
This()152 static PreParserExpression This() {
153 return PreParserExpression(TypeField::encode(kExpression) |
154 ExpressionTypeField::encode(kThisExpression));
155 }
156
ThisProperty()157 static PreParserExpression ThisProperty() {
158 return PreParserExpression(
159 TypeField::encode(kExpression) |
160 ExpressionTypeField::encode(kThisPropertyExpression));
161 }
162
Property()163 static PreParserExpression Property() {
164 return PreParserExpression(
165 TypeField::encode(kExpression) |
166 ExpressionTypeField::encode(kPropertyExpression));
167 }
168
Call()169 static PreParserExpression Call() {
170 return PreParserExpression(TypeField::encode(kExpression) |
171 ExpressionTypeField::encode(kCallExpression));
172 }
173
SuperCallReference()174 static PreParserExpression SuperCallReference() {
175 return PreParserExpression(
176 TypeField::encode(kExpression) |
177 ExpressionTypeField::encode(kSuperCallReference));
178 }
179
NoTemplateTag()180 static PreParserExpression NoTemplateTag() {
181 return PreParserExpression(
182 TypeField::encode(kExpression) |
183 ExpressionTypeField::encode(kNoTemplateTagExpression));
184 }
185
IsIdentifier()186 bool IsIdentifier() const {
187 return TypeField::decode(code_) == kIdentifierExpression;
188 }
189
AsIdentifier()190 PreParserIdentifier AsIdentifier() const {
191 DCHECK(IsIdentifier());
192 return PreParserIdentifier(IdentifierTypeField::decode(code_));
193 }
194
IsAssignment()195 bool IsAssignment() const {
196 return TypeField::decode(code_) == kExpression &&
197 ExpressionTypeField::decode(code_) == kAssignment;
198 }
199
IsObjectLiteral()200 bool IsObjectLiteral() const {
201 return TypeField::decode(code_) == kObjectLiteralExpression;
202 }
203
IsArrayLiteral()204 bool IsArrayLiteral() const {
205 return TypeField::decode(code_) == kArrayLiteralExpression;
206 }
207
IsStringLiteral()208 bool IsStringLiteral() const {
209 return TypeField::decode(code_) == kStringLiteralExpression;
210 }
211
IsUseStrictLiteral()212 bool IsUseStrictLiteral() const {
213 return TypeField::decode(code_) == kStringLiteralExpression &&
214 IsUseStrictField::decode(code_);
215 }
216
IsUseStrongLiteral()217 bool IsUseStrongLiteral() const {
218 return TypeField::decode(code_) == kStringLiteralExpression &&
219 IsUseStrongField::decode(code_);
220 }
221
IsThis()222 bool IsThis() const {
223 return TypeField::decode(code_) == kExpression &&
224 ExpressionTypeField::decode(code_) == kThisExpression;
225 }
226
IsThisProperty()227 bool IsThisProperty() const {
228 return TypeField::decode(code_) == kExpression &&
229 ExpressionTypeField::decode(code_) == kThisPropertyExpression;
230 }
231
IsProperty()232 bool IsProperty() const {
233 return TypeField::decode(code_) == kExpression &&
234 (ExpressionTypeField::decode(code_) == kPropertyExpression ||
235 ExpressionTypeField::decode(code_) == kThisPropertyExpression);
236 }
237
IsCall()238 bool IsCall() const {
239 return TypeField::decode(code_) == kExpression &&
240 ExpressionTypeField::decode(code_) == kCallExpression;
241 }
242
IsSuperCallReference()243 bool IsSuperCallReference() const {
244 return TypeField::decode(code_) == kExpression &&
245 ExpressionTypeField::decode(code_) == kSuperCallReference;
246 }
247
IsValidReferenceExpression()248 bool IsValidReferenceExpression() const {
249 return IsIdentifier() || IsProperty();
250 }
251
252 // At the moment PreParser doesn't track these expression types.
IsFunctionLiteral()253 bool IsFunctionLiteral() const { return false; }
IsCallNew()254 bool IsCallNew() const { return false; }
255
IsNoTemplateTag()256 bool IsNoTemplateTag() const {
257 return TypeField::decode(code_) == kExpression &&
258 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression;
259 }
260
IsSpreadExpression()261 bool IsSpreadExpression() const {
262 return TypeField::decode(code_) == kSpreadExpression;
263 }
264
AsFunctionLiteral()265 PreParserExpression AsFunctionLiteral() { return *this; }
266
IsBinaryOperation()267 bool IsBinaryOperation() const {
268 return TypeField::decode(code_) == kBinaryOperationExpression;
269 }
270
271 // Dummy implementation for making expression->somefunc() work in both Parser
272 // and PreParser.
273 PreParserExpression* operator->() { return this; }
274
275 // More dummy implementations of things PreParser doesn't need to track:
set_index(int index)276 void set_index(int index) {} // For YieldExpressions
set_should_eager_compile()277 void set_should_eager_compile() {}
278
position()279 int position() const { return RelocInfo::kNoPosition; }
set_function_token_position(int position)280 void set_function_token_position(int position) {}
281
282 // Parenthesized expressions in the form `( Expression )`.
set_is_parenthesized()283 void set_is_parenthesized() {
284 code_ = ParenthesizedField::update(code_, true);
285 }
is_parenthesized()286 bool is_parenthesized() const { return ParenthesizedField::decode(code_); }
287
288 private:
289 enum Type {
290 kExpression,
291 kIdentifierExpression,
292 kStringLiteralExpression,
293 kBinaryOperationExpression,
294 kSpreadExpression,
295 kObjectLiteralExpression,
296 kArrayLiteralExpression
297 };
298
299 enum ExpressionType {
300 kThisExpression,
301 kThisPropertyExpression,
302 kPropertyExpression,
303 kCallExpression,
304 kSuperCallReference,
305 kNoTemplateTagExpression,
306 kAssignment
307 };
308
PreParserExpression(uint32_t expression_code)309 explicit PreParserExpression(uint32_t expression_code)
310 : code_(expression_code) {}
311
312 // The first three bits are for the Type.
313 typedef BitField<Type, 0, 3> TypeField;
314
315 // The high order bit applies only to nodes which would inherit from the
316 // Expression ASTNode --- This is by necessity, due to the fact that
317 // Expression nodes may be represented as multiple Types, not exclusively
318 // through kExpression.
319 // TODO(caitp, adamk): clean up PreParserExpression bitfields.
320 typedef BitField<bool, 31, 1> ParenthesizedField;
321
322 // The rest of the bits are interpreted depending on the value
323 // of the Type field, so they can share the storage.
324 typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField;
325 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField;
326 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField;
327 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10>
328 IdentifierTypeField;
329 typedef BitField<bool, TypeField::kNext, 1> HasCoverInitializedNameField;
330
331 uint32_t code_;
332 };
333
334
335 // The pre-parser doesn't need to build lists of expressions, identifiers, or
336 // the like.
337 template <typename T>
338 class PreParserList {
339 public:
340 // These functions make list->Add(some_expression) work (and do nothing).
PreParserList()341 PreParserList() : length_(0) {}
342 PreParserList* operator->() { return this; }
Add(T,void *)343 void Add(T, void*) { ++length_; }
length()344 int length() const { return length_; }
345 private:
346 int length_;
347 };
348
349
350 typedef PreParserList<PreParserExpression> PreParserExpressionList;
351
352
353 class PreParserStatement {
354 public:
Default()355 static PreParserStatement Default() {
356 return PreParserStatement(kUnknownStatement);
357 }
358
Jump()359 static PreParserStatement Jump() {
360 return PreParserStatement(kJumpStatement);
361 }
362
FunctionDeclaration()363 static PreParserStatement FunctionDeclaration() {
364 return PreParserStatement(kFunctionDeclaration);
365 }
366
367 // Creates expression statement from expression.
368 // Preserves being an unparenthesized string literal, possibly
369 // "use strict".
ExpressionStatement(PreParserExpression expression)370 static PreParserStatement ExpressionStatement(
371 PreParserExpression expression) {
372 if (expression.IsUseStrictLiteral()) {
373 return PreParserStatement(kUseStrictExpressionStatement);
374 }
375 if (expression.IsUseStrongLiteral()) {
376 return PreParserStatement(kUseStrongExpressionStatement);
377 }
378 if (expression.IsStringLiteral()) {
379 return PreParserStatement(kStringLiteralExpressionStatement);
380 }
381 return Default();
382 }
383
IsStringLiteral()384 bool IsStringLiteral() {
385 return code_ == kStringLiteralExpressionStatement;
386 }
387
IsUseStrictLiteral()388 bool IsUseStrictLiteral() {
389 return code_ == kUseStrictExpressionStatement;
390 }
391
IsUseStrongLiteral()392 bool IsUseStrongLiteral() { return code_ == kUseStrongExpressionStatement; }
393
IsFunctionDeclaration()394 bool IsFunctionDeclaration() {
395 return code_ == kFunctionDeclaration;
396 }
397
IsJumpStatement()398 bool IsJumpStatement() {
399 return code_ == kJumpStatement;
400 }
401
402 private:
403 enum Type {
404 kUnknownStatement,
405 kJumpStatement,
406 kStringLiteralExpressionStatement,
407 kUseStrictExpressionStatement,
408 kUseStrongExpressionStatement,
409 kFunctionDeclaration
410 };
411
PreParserStatement(Type code)412 explicit PreParserStatement(Type code) : code_(code) {}
413 Type code_;
414 };
415
416
417 typedef PreParserList<PreParserStatement> PreParserStatementList;
418
419
420 class PreParserFactory {
421 public:
PreParserFactory(void * unused_value_factory)422 explicit PreParserFactory(void* unused_value_factory) {}
NewStringLiteral(PreParserIdentifier identifier,int pos)423 PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
424 int pos) {
425 return PreParserExpression::Default();
426 }
NewNumberLiteral(double number,int pos)427 PreParserExpression NewNumberLiteral(double number,
428 int pos) {
429 return PreParserExpression::Default();
430 }
NewRegExpLiteral(PreParserIdentifier js_pattern,int js_flags,int literal_index,bool is_strong,int pos)431 PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
432 int js_flags, int literal_index,
433 bool is_strong, int pos) {
434 return PreParserExpression::Default();
435 }
NewArrayLiteral(PreParserExpressionList values,int literal_index,bool is_strong,int pos)436 PreParserExpression NewArrayLiteral(PreParserExpressionList values,
437 int literal_index,
438 bool is_strong,
439 int pos) {
440 return PreParserExpression::ArrayLiteral();
441 }
NewArrayLiteral(PreParserExpressionList values,int first_spread_index,int literal_index,bool is_strong,int pos)442 PreParserExpression NewArrayLiteral(PreParserExpressionList values,
443 int first_spread_index, int literal_index,
444 bool is_strong, int pos) {
445 return PreParserExpression::ArrayLiteral();
446 }
NewObjectLiteralProperty(PreParserExpression key,PreParserExpression value,ObjectLiteralProperty::Kind kind,bool is_static,bool is_computed_name)447 PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
448 PreParserExpression value,
449 ObjectLiteralProperty::Kind kind,
450 bool is_static,
451 bool is_computed_name) {
452 return PreParserExpression::Default();
453 }
NewObjectLiteralProperty(PreParserExpression key,PreParserExpression value,bool is_static,bool is_computed_name)454 PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
455 PreParserExpression value,
456 bool is_static,
457 bool is_computed_name) {
458 return PreParserExpression::Default();
459 }
NewObjectLiteral(PreParserExpressionList properties,int literal_index,int boilerplate_properties,bool has_function,bool is_strong,int pos)460 PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
461 int literal_index,
462 int boilerplate_properties,
463 bool has_function,
464 bool is_strong,
465 int pos) {
466 return PreParserExpression::ObjectLiteral();
467 }
NewVariableProxy(void * variable)468 PreParserExpression NewVariableProxy(void* variable) {
469 return PreParserExpression::Default();
470 }
NewProperty(PreParserExpression obj,PreParserExpression key,int pos)471 PreParserExpression NewProperty(PreParserExpression obj,
472 PreParserExpression key,
473 int pos) {
474 if (obj.IsThis()) {
475 return PreParserExpression::ThisProperty();
476 }
477 return PreParserExpression::Property();
478 }
NewUnaryOperation(Token::Value op,PreParserExpression expression,int pos)479 PreParserExpression NewUnaryOperation(Token::Value op,
480 PreParserExpression expression,
481 int pos) {
482 return PreParserExpression::Default();
483 }
NewBinaryOperation(Token::Value op,PreParserExpression left,PreParserExpression right,int pos)484 PreParserExpression NewBinaryOperation(Token::Value op,
485 PreParserExpression left,
486 PreParserExpression right, int pos) {
487 return PreParserExpression::BinaryOperation(left, op, right);
488 }
NewCompareOperation(Token::Value op,PreParserExpression left,PreParserExpression right,int pos)489 PreParserExpression NewCompareOperation(Token::Value op,
490 PreParserExpression left,
491 PreParserExpression right, int pos) {
492 return PreParserExpression::Default();
493 }
NewRewritableAssignmentExpression(PreParserExpression expression)494 PreParserExpression NewRewritableAssignmentExpression(
495 PreParserExpression expression) {
496 return expression;
497 }
NewAssignment(Token::Value op,PreParserExpression left,PreParserExpression right,int pos)498 PreParserExpression NewAssignment(Token::Value op,
499 PreParserExpression left,
500 PreParserExpression right,
501 int pos) {
502 return PreParserExpression::Assignment();
503 }
NewYield(PreParserExpression generator_object,PreParserExpression expression,Yield::Kind yield_kind,int pos)504 PreParserExpression NewYield(PreParserExpression generator_object,
505 PreParserExpression expression,
506 Yield::Kind yield_kind,
507 int pos) {
508 return PreParserExpression::Default();
509 }
NewConditional(PreParserExpression condition,PreParserExpression then_expression,PreParserExpression else_expression,int pos)510 PreParserExpression NewConditional(PreParserExpression condition,
511 PreParserExpression then_expression,
512 PreParserExpression else_expression,
513 int pos) {
514 return PreParserExpression::Default();
515 }
NewCountOperation(Token::Value op,bool is_prefix,PreParserExpression expression,int pos)516 PreParserExpression NewCountOperation(Token::Value op,
517 bool is_prefix,
518 PreParserExpression expression,
519 int pos) {
520 return PreParserExpression::Default();
521 }
NewCall(PreParserExpression expression,PreParserExpressionList arguments,int pos)522 PreParserExpression NewCall(PreParserExpression expression,
523 PreParserExpressionList arguments,
524 int pos) {
525 return PreParserExpression::Call();
526 }
NewCallNew(PreParserExpression expression,PreParserExpressionList arguments,int pos)527 PreParserExpression NewCallNew(PreParserExpression expression,
528 PreParserExpressionList arguments,
529 int pos) {
530 return PreParserExpression::Default();
531 }
NewCallRuntime(const AstRawString * name,const Runtime::Function * function,PreParserExpressionList arguments,int pos)532 PreParserExpression NewCallRuntime(const AstRawString* name,
533 const Runtime::Function* function,
534 PreParserExpressionList arguments,
535 int pos) {
536 return PreParserExpression::Default();
537 }
NewReturnStatement(PreParserExpression expression,int pos)538 PreParserStatement NewReturnStatement(PreParserExpression expression,
539 int pos) {
540 return PreParserStatement::Default();
541 }
NewFunctionLiteral(PreParserIdentifier name,Scope * scope,PreParserStatementList body,int materialized_literal_count,int expected_property_count,int parameter_count,FunctionLiteral::ParameterFlag has_duplicate_parameters,FunctionLiteral::FunctionType function_type,FunctionLiteral::EagerCompileHint eager_compile_hint,FunctionKind kind,int position)542 PreParserExpression NewFunctionLiteral(
543 PreParserIdentifier name, Scope* scope, PreParserStatementList body,
544 int materialized_literal_count, int expected_property_count,
545 int parameter_count,
546 FunctionLiteral::ParameterFlag has_duplicate_parameters,
547 FunctionLiteral::FunctionType function_type,
548 FunctionLiteral::EagerCompileHint eager_compile_hint, FunctionKind kind,
549 int position) {
550 return PreParserExpression::Default();
551 }
552
NewSpread(PreParserExpression expression,int pos)553 PreParserExpression NewSpread(PreParserExpression expression, int pos) {
554 return PreParserExpression::Spread(expression);
555 }
556
NewEmptyParentheses(int pos)557 PreParserExpression NewEmptyParentheses(int pos) {
558 return PreParserExpression::Default();
559 }
560
561 // Return the object itself as AstVisitor and implement the needed
562 // dummy method right in this class.
visitor()563 PreParserFactory* visitor() { return this; }
ast_properties()564 int* ast_properties() {
565 static int dummy = 42;
566 return &dummy;
567 }
568 };
569
570
571 struct PreParserFormalParameters : FormalParametersBase {
PreParserFormalParametersPreParserFormalParameters572 explicit PreParserFormalParameters(Scope* scope)
573 : FormalParametersBase(scope) {}
574 int arity = 0;
575
ArityPreParserFormalParameters576 int Arity() const { return arity; }
atPreParserFormalParameters577 PreParserIdentifier at(int i) { return PreParserIdentifier(); } // Dummy
578 };
579
580
581 class PreParser;
582
583 class PreParserTraits {
584 public:
585 struct Type {
586 // TODO(marja): To be removed. The Traits object should contain all the data
587 // it needs.
588 typedef PreParser* Parser;
589
590 // PreParser doesn't need to store generator variables.
591 typedef void GeneratorVariable;
592
593 typedef int AstProperties;
594
595 // Return types for traversing functions.
596 typedef PreParserIdentifier Identifier;
597 typedef PreParserExpression Expression;
598 typedef PreParserExpression YieldExpression;
599 typedef PreParserExpression FunctionLiteral;
600 typedef PreParserExpression ClassLiteral;
601 typedef PreParserExpression ObjectLiteralProperty;
602 typedef PreParserExpression Literal;
603 typedef PreParserExpressionList ExpressionList;
604 typedef PreParserExpressionList PropertyList;
605 typedef PreParserIdentifier FormalParameter;
606 typedef PreParserFormalParameters FormalParameters;
607 typedef PreParserStatementList StatementList;
608
609 // For constructing objects returned by the traversing functions.
610 typedef PreParserFactory Factory;
611 };
612
PreParserTraits(PreParser * pre_parser)613 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
614
615 // Helper functions for recursive descent.
IsEval(PreParserIdentifier identifier)616 static bool IsEval(PreParserIdentifier identifier) {
617 return identifier.IsEval();
618 }
619
IsArguments(PreParserIdentifier identifier)620 static bool IsArguments(PreParserIdentifier identifier) {
621 return identifier.IsArguments();
622 }
623
IsEvalOrArguments(PreParserIdentifier identifier)624 static bool IsEvalOrArguments(PreParserIdentifier identifier) {
625 return identifier.IsEvalOrArguments();
626 }
627
IsUndefined(PreParserIdentifier identifier)628 static bool IsUndefined(PreParserIdentifier identifier) {
629 return identifier.IsUndefined();
630 }
631
IsPrototype(PreParserIdentifier identifier)632 static bool IsPrototype(PreParserIdentifier identifier) {
633 return identifier.IsPrototype();
634 }
635
IsConstructor(PreParserIdentifier identifier)636 static bool IsConstructor(PreParserIdentifier identifier) {
637 return identifier.IsConstructor();
638 }
639
640 // Returns true if the expression is of type "this.foo".
IsThisProperty(PreParserExpression expression)641 static bool IsThisProperty(PreParserExpression expression) {
642 return expression.IsThisProperty();
643 }
644
IsIdentifier(PreParserExpression expression)645 static bool IsIdentifier(PreParserExpression expression) {
646 return expression.IsIdentifier();
647 }
648
AsIdentifier(PreParserExpression expression)649 static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
650 return expression.AsIdentifier();
651 }
652
IsFutureStrictReserved(PreParserIdentifier identifier)653 static bool IsFutureStrictReserved(PreParserIdentifier identifier) {
654 return identifier.IsFutureStrictReserved();
655 }
656
IsBoilerplateProperty(PreParserExpression property)657 static bool IsBoilerplateProperty(PreParserExpression property) {
658 // PreParser doesn't count boilerplate properties.
659 return false;
660 }
661
IsArrayIndex(PreParserIdentifier string,uint32_t * index)662 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
663 return false;
664 }
665
GetPropertyValue(PreParserExpression property)666 static PreParserExpression GetPropertyValue(PreParserExpression property) {
667 return PreParserExpression::Default();
668 }
669
670 // Functions for encapsulating the differences between parsing and preparsing;
671 // operations interleaved with the recursive descent.
PushLiteralName(FuncNameInferrer * fni,PreParserIdentifier id)672 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
673 // PreParser should not use FuncNameInferrer.
674 UNREACHABLE();
675 }
676
PushPropertyName(FuncNameInferrer * fni,PreParserExpression expression)677 static void PushPropertyName(FuncNameInferrer* fni,
678 PreParserExpression expression) {
679 // PreParser should not use FuncNameInferrer.
680 UNREACHABLE();
681 }
682
InferFunctionName(FuncNameInferrer * fni,PreParserExpression expression)683 static void InferFunctionName(FuncNameInferrer* fni,
684 PreParserExpression expression) {
685 // PreParser should not use FuncNameInferrer.
686 UNREACHABLE();
687 }
688
CheckFunctionLiteralInsideTopLevelObjectLiteral(Scope * scope,PreParserExpression property,bool * has_function)689 static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
690 Scope* scope, PreParserExpression property, bool* has_function) {}
691
CheckAssigningFunctionLiteralToProperty(PreParserExpression left,PreParserExpression right)692 static void CheckAssigningFunctionLiteralToProperty(
693 PreParserExpression left, PreParserExpression right) {}
694
MarkExpressionAsAssigned(PreParserExpression expression)695 static PreParserExpression MarkExpressionAsAssigned(
696 PreParserExpression expression) {
697 // TODO(marja): To be able to produce the same errors, the preparser needs
698 // to start tracking which expressions are variables and which are assigned.
699 return expression;
700 }
701
ShortcutNumericLiteralBinaryExpression(PreParserExpression * x,PreParserExpression y,Token::Value op,int pos,PreParserFactory * factory)702 bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
703 PreParserExpression y,
704 Token::Value op,
705 int pos,
706 PreParserFactory* factory) {
707 return false;
708 }
709
BuildUnaryExpression(PreParserExpression expression,Token::Value op,int pos,PreParserFactory * factory)710 PreParserExpression BuildUnaryExpression(PreParserExpression expression,
711 Token::Value op, int pos,
712 PreParserFactory* factory) {
713 return PreParserExpression::Default();
714 }
715
NewThrowReferenceError(MessageTemplate::Template message,int pos)716 PreParserExpression NewThrowReferenceError(MessageTemplate::Template message,
717 int pos) {
718 return PreParserExpression::Default();
719 }
NewThrowSyntaxError(MessageTemplate::Template message,Handle<Object> arg,int pos)720 PreParserExpression NewThrowSyntaxError(MessageTemplate::Template message,
721 Handle<Object> arg, int pos) {
722 return PreParserExpression::Default();
723 }
NewThrowTypeError(MessageTemplate::Template message,Handle<Object> arg,int pos)724 PreParserExpression NewThrowTypeError(MessageTemplate::Template message,
725 Handle<Object> arg, int pos) {
726 return PreParserExpression::Default();
727 }
728
729 // Reporting errors.
730 void ReportMessageAt(Scanner::Location location,
731 MessageTemplate::Template message,
732 const char* arg = NULL,
733 ParseErrorType error_type = kSyntaxError);
734 void ReportMessageAt(int start_pos, int end_pos,
735 MessageTemplate::Template message,
736 const char* arg = NULL,
737 ParseErrorType error_type = kSyntaxError);
738
739 // "null" return type creators.
EmptyIdentifier()740 static PreParserIdentifier EmptyIdentifier() {
741 return PreParserIdentifier::Default();
742 }
EmptyIdentifierString()743 static PreParserIdentifier EmptyIdentifierString() {
744 return PreParserIdentifier::Default();
745 }
EmptyExpression()746 static PreParserExpression EmptyExpression() {
747 return PreParserExpression::Default();
748 }
EmptyLiteral()749 static PreParserExpression EmptyLiteral() {
750 return PreParserExpression::Default();
751 }
EmptyObjectLiteralProperty()752 static PreParserExpression EmptyObjectLiteralProperty() {
753 return PreParserExpression::Default();
754 }
EmptyFunctionLiteral()755 static PreParserExpression EmptyFunctionLiteral() {
756 return PreParserExpression::Default();
757 }
NullExpressionList()758 static PreParserExpressionList NullExpressionList() {
759 return PreParserExpressionList();
760 }
761
762 // Odd-ball literal creators.
GetLiteralTheHole(int position,PreParserFactory * factory)763 static PreParserExpression GetLiteralTheHole(int position,
764 PreParserFactory* factory) {
765 return PreParserExpression::Default();
766 }
767
768 // Producing data during the recursive descent.
769 PreParserIdentifier GetSymbol(Scanner* scanner);
770 PreParserIdentifier GetNumberAsSymbol(Scanner* scanner);
771
GetNextSymbol(Scanner * scanner)772 static PreParserIdentifier GetNextSymbol(Scanner* scanner) {
773 return PreParserIdentifier::Default();
774 }
775
ThisExpression(Scope * scope,PreParserFactory * factory,int pos)776 static PreParserExpression ThisExpression(Scope* scope,
777 PreParserFactory* factory,
778 int pos) {
779 return PreParserExpression::This();
780 }
781
SuperPropertyReference(Scope * scope,PreParserFactory * factory,int pos)782 static PreParserExpression SuperPropertyReference(Scope* scope,
783 PreParserFactory* factory,
784 int pos) {
785 return PreParserExpression::Default();
786 }
787
SuperCallReference(Scope * scope,PreParserFactory * factory,int pos)788 static PreParserExpression SuperCallReference(Scope* scope,
789 PreParserFactory* factory,
790 int pos) {
791 return PreParserExpression::SuperCallReference();
792 }
793
NewTargetExpression(Scope * scope,PreParserFactory * factory,int pos)794 static PreParserExpression NewTargetExpression(Scope* scope,
795 PreParserFactory* factory,
796 int pos) {
797 return PreParserExpression::Default();
798 }
799
DefaultConstructor(bool call_super,Scope * scope,int pos,int end_pos)800 static PreParserExpression DefaultConstructor(bool call_super, Scope* scope,
801 int pos, int end_pos) {
802 return PreParserExpression::Default();
803 }
804
ExpressionFromLiteral(Token::Value token,int pos,Scanner * scanner,PreParserFactory * factory)805 static PreParserExpression ExpressionFromLiteral(
806 Token::Value token, int pos, Scanner* scanner,
807 PreParserFactory* factory) {
808 return PreParserExpression::Default();
809 }
810
ExpressionFromIdentifier(PreParserIdentifier name,int start_position,int end_position,Scope * scope,PreParserFactory * factory)811 static PreParserExpression ExpressionFromIdentifier(
812 PreParserIdentifier name, int start_position, int end_position,
813 Scope* scope, PreParserFactory* factory) {
814 return PreParserExpression::FromIdentifier(name);
815 }
816
817 PreParserExpression ExpressionFromString(int pos,
818 Scanner* scanner,
819 PreParserFactory* factory = NULL);
820
GetIterator(PreParserExpression iterable,PreParserFactory * factory,int pos)821 PreParserExpression GetIterator(PreParserExpression iterable,
822 PreParserFactory* factory, int pos) {
823 return PreParserExpression::Default();
824 }
825
NewExpressionList(int size,Zone * zone)826 static PreParserExpressionList NewExpressionList(int size, Zone* zone) {
827 return PreParserExpressionList();
828 }
829
NewStatementList(int size,Zone * zone)830 static PreParserStatementList NewStatementList(int size, Zone* zone) {
831 return PreParserStatementList();
832 }
833
NewPropertyList(int size,Zone * zone)834 static PreParserExpressionList NewPropertyList(int size, Zone* zone) {
835 return PreParserExpressionList();
836 }
837
AddParameterInitializationBlock(const PreParserFormalParameters & parameters,PreParserStatementList list,bool * ok)838 static void AddParameterInitializationBlock(
839 const PreParserFormalParameters& parameters,
840 PreParserStatementList list, bool* ok) {}
841
SkipLazyFunctionBody(int * materialized_literal_count,int * expected_property_count,bool * ok)842 V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count,
843 int* expected_property_count, bool* ok) {
844 UNREACHABLE();
845 }
846
847 V8_INLINE PreParserStatementList ParseEagerFunctionBody(
848 PreParserIdentifier function_name, int pos,
849 const PreParserFormalParameters& parameters, FunctionKind kind,
850 FunctionLiteral::FunctionType function_type, bool* ok);
851
852 V8_INLINE void ParseArrowFunctionFormalParameterList(
853 PreParserFormalParameters* parameters,
854 PreParserExpression expression, const Scanner::Location& params_loc,
855 Scanner::Location* duplicate_loc, bool* ok);
856
ReindexLiterals(const PreParserFormalParameters & paramaters)857 void ReindexLiterals(const PreParserFormalParameters& paramaters) {}
858
859 struct TemplateLiteralState {};
860
OpenTemplateLiteral(int pos)861 TemplateLiteralState OpenTemplateLiteral(int pos) {
862 return TemplateLiteralState();
863 }
AddTemplateSpan(TemplateLiteralState *,bool)864 void AddTemplateSpan(TemplateLiteralState*, bool) {}
AddTemplateExpression(TemplateLiteralState *,PreParserExpression)865 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {}
CloseTemplateLiteral(TemplateLiteralState *,int,PreParserExpression tag)866 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int,
867 PreParserExpression tag) {
868 if (IsTaggedTemplate(tag)) {
869 // Emulate generation of array literals for tag callsite
870 // 1st is array of cooked strings, second is array of raw strings
871 MaterializeTemplateCallsiteLiterals();
872 }
873 return EmptyExpression();
874 }
875 inline void MaterializeTemplateCallsiteLiterals();
NoTemplateTag()876 PreParserExpression NoTemplateTag() {
877 return PreParserExpression::NoTemplateTag();
878 }
IsTaggedTemplate(const PreParserExpression tag)879 static bool IsTaggedTemplate(const PreParserExpression tag) {
880 return !tag.IsNoTemplateTag();
881 }
882
AddFormalParameter(PreParserFormalParameters * parameters,PreParserExpression pattern,PreParserExpression initializer,int initializer_end_position,bool is_rest)883 void AddFormalParameter(PreParserFormalParameters* parameters,
884 PreParserExpression pattern,
885 PreParserExpression initializer,
886 int initializer_end_position, bool is_rest) {
887 ++parameters->arity;
888 }
DeclareFormalParameter(Scope * scope,PreParserIdentifier parameter,ExpressionClassifier * classifier)889 void DeclareFormalParameter(Scope* scope, PreParserIdentifier parameter,
890 ExpressionClassifier* classifier) {
891 if (!classifier->is_simple_parameter_list()) {
892 scope->SetHasNonSimpleParameters();
893 }
894 }
895
CheckConflictingVarDeclarations(Scope * scope,bool * ok)896 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {}
897
898 // Temporary glue; these functions will move to ParserBase.
899 PreParserExpression ParseV8Intrinsic(bool* ok);
900 V8_INLINE PreParserExpression ParseDoExpression(bool* ok);
901 PreParserExpression ParseFunctionLiteral(
902 PreParserIdentifier name, Scanner::Location function_name_location,
903 FunctionNameValidity function_name_validity, FunctionKind kind,
904 int function_token_position, FunctionLiteral::FunctionType type,
905 FunctionLiteral::ArityRestriction arity_restriction,
906 LanguageMode language_mode, bool* ok);
907
908 PreParserExpression ParseClassLiteral(PreParserIdentifier name,
909 Scanner::Location class_name_location,
910 bool name_is_strict_reserved, int pos,
911 bool* ok);
912
PrepareSpreadArguments(PreParserExpressionList list)913 PreParserExpressionList PrepareSpreadArguments(PreParserExpressionList list) {
914 return list;
915 }
916
917 inline void MaterializeUnspreadArgumentsLiterals(int count);
918
919 inline PreParserExpression SpreadCall(PreParserExpression function,
920 PreParserExpressionList args, int pos);
921
922 inline PreParserExpression SpreadCallNew(PreParserExpression function,
923 PreParserExpressionList args,
924 int pos);
925
RewriteDestructuringAssignments()926 inline void RewriteDestructuringAssignments() {}
927
QueueDestructuringAssignmentForRewriting(PreParserExpression)928 inline void QueueDestructuringAssignmentForRewriting(PreParserExpression) {}
929
SetFunctionNameFromPropertyName(PreParserExpression,PreParserIdentifier)930 void SetFunctionNameFromPropertyName(PreParserExpression,
931 PreParserIdentifier) {}
SetFunctionNameFromIdentifierRef(PreParserExpression,PreParserExpression)932 void SetFunctionNameFromIdentifierRef(PreParserExpression,
933 PreParserExpression) {}
934
935 inline PreParserExpression RewriteNonPattern(
936 PreParserExpression expr, const ExpressionClassifier* classifier,
937 bool* ok);
938 inline PreParserExpression RewriteNonPatternArguments(
939 PreParserExpression args, const ExpressionClassifier* classifier,
940 bool* ok);
941 inline PreParserExpression RewriteNonPatternObjectLiteralProperty(
942 PreParserExpression property, const ExpressionClassifier* classifier,
943 bool* ok);
944
945 private:
946 PreParser* pre_parser_;
947 };
948
949
950 // Preparsing checks a JavaScript program and emits preparse-data that helps
951 // a later parsing to be faster.
952 // See preparse-data-format.h for the data format.
953
954 // The PreParser checks that the syntax follows the grammar for JavaScript,
955 // and collects some information about the program along the way.
956 // The grammar check is only performed in order to understand the program
957 // sufficiently to deduce some information about it, that can be used
958 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
959 // rather it is to speed up properly written and correct programs.
960 // That means that contextual checks (like a label being declared where
961 // it is used) are generally omitted.
962 class PreParser : public ParserBase<PreParserTraits> {
963 public:
964 typedef PreParserIdentifier Identifier;
965 typedef PreParserExpression Expression;
966 typedef PreParserStatement Statement;
967
968 enum PreParseResult {
969 kPreParseStackOverflow,
970 kPreParseSuccess
971 };
972
PreParser(Zone * zone,Scanner * scanner,AstValueFactory * ast_value_factory,ParserRecorder * log,uintptr_t stack_limit)973 PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory,
974 ParserRecorder* log, uintptr_t stack_limit)
975 : ParserBase<PreParserTraits>(zone, scanner, stack_limit, NULL,
976 ast_value_factory, log, this) {}
977
978 // Pre-parse the program from the character stream; returns true on
979 // success (even if parsing failed, the pre-parse data successfully
980 // captured the syntax error), and false if a stack-overflow happened
981 // during parsing.
982 PreParseResult PreParseProgram(int* materialized_literals = 0) {
983 Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
984 PreParserFactory factory(NULL);
985 FunctionState top_scope(&function_state_, &scope_, scope, kNormalFunction,
986 &factory);
987 bool ok = true;
988 int start_position = scanner()->peek_location().beg_pos;
989 ParseStatementList(Token::EOS, &ok);
990 if (stack_overflow()) return kPreParseStackOverflow;
991 if (!ok) {
992 ReportUnexpectedToken(scanner()->current_token());
993 } else if (is_strict(scope_->language_mode())) {
994 CheckStrictOctalLiteral(start_position, scanner()->location().end_pos,
995 &ok);
996 }
997 if (materialized_literals) {
998 *materialized_literals = function_state_->materialized_literal_count();
999 }
1000 return kPreParseSuccess;
1001 }
1002
1003 // Parses a single function literal, from the opening parentheses before
1004 // parameters to the closing brace after the body.
1005 // Returns a FunctionEntry describing the body of the function in enough
1006 // detail that it can be lazily compiled.
1007 // The scanner is expected to have matched the "function" or "function*"
1008 // keyword and parameters, and have consumed the initial '{'.
1009 // At return, unless an error occurred, the scanner is positioned before the
1010 // the final '}'.
1011 PreParseResult PreParseLazyFunction(
1012 LanguageMode language_mode, FunctionKind kind, bool has_simple_parameters,
1013 ParserRecorder* log, Scanner::BookmarkScope* bookmark = nullptr);
1014
1015 private:
1016 friend class PreParserTraits;
1017
1018 static const int kLazyParseTrialLimit = 200;
1019
1020 // These types form an algebra over syntactic categories that is just
1021 // rich enough to let us recognize and propagate the constructs that
1022 // are either being counted in the preparser data, or is important
1023 // to throw the correct syntax error exceptions.
1024
1025 // All ParseXXX functions take as the last argument an *ok parameter
1026 // which is set to false if parsing failed; it is unchanged otherwise.
1027 // By making the 'exception handling' explicit, we are forced to check
1028 // for failure at the call sites.
1029 Statement ParseStatementListItem(bool* ok);
1030 void ParseStatementList(int end_token, bool* ok,
1031 Scanner::BookmarkScope* bookmark = nullptr);
1032 Statement ParseStatement(bool* ok);
1033 Statement ParseSubStatement(bool* ok);
1034 Statement ParseFunctionDeclaration(bool* ok);
1035 Statement ParseClassDeclaration(bool* ok);
1036 Statement ParseBlock(bool* ok);
1037 Statement ParseVariableStatement(VariableDeclarationContext var_context,
1038 bool* ok);
1039 Statement ParseVariableDeclarations(VariableDeclarationContext var_context,
1040 int* num_decl, bool* is_lexical,
1041 bool* is_binding_pattern,
1042 Scanner::Location* first_initializer_loc,
1043 Scanner::Location* bindings_loc,
1044 bool* ok);
1045 Statement ParseExpressionOrLabelledStatement(bool* ok);
1046 Statement ParseIfStatement(bool* ok);
1047 Statement ParseContinueStatement(bool* ok);
1048 Statement ParseBreakStatement(bool* ok);
1049 Statement ParseReturnStatement(bool* ok);
1050 Statement ParseWithStatement(bool* ok);
1051 Statement ParseSwitchStatement(bool* ok);
1052 Statement ParseDoWhileStatement(bool* ok);
1053 Statement ParseWhileStatement(bool* ok);
1054 Statement ParseForStatement(bool* ok);
1055 Statement ParseThrowStatement(bool* ok);
1056 Statement ParseTryStatement(bool* ok);
1057 Statement ParseDebuggerStatement(bool* ok);
1058 Expression ParseConditionalExpression(bool accept_IN, bool* ok);
1059 Expression ParseObjectLiteral(bool* ok);
1060 Expression ParseV8Intrinsic(bool* ok);
1061 Expression ParseDoExpression(bool* ok);
1062
1063 V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count,
1064 int* expected_property_count, bool* ok);
1065 V8_INLINE PreParserStatementList ParseEagerFunctionBody(
1066 PreParserIdentifier function_name, int pos,
1067 const PreParserFormalParameters& parameters, FunctionKind kind,
1068 FunctionLiteral::FunctionType function_type, bool* ok);
1069
1070 Expression ParseFunctionLiteral(
1071 Identifier name, Scanner::Location function_name_location,
1072 FunctionNameValidity function_name_validity, FunctionKind kind,
1073 int function_token_pos, FunctionLiteral::FunctionType function_type,
1074 FunctionLiteral::ArityRestriction arity_restriction,
1075 LanguageMode language_mode, bool* ok);
1076 void ParseLazyFunctionLiteralBody(bool* ok,
1077 Scanner::BookmarkScope* bookmark = nullptr);
1078
1079 PreParserExpression ParseClassLiteral(PreParserIdentifier name,
1080 Scanner::Location class_name_location,
1081 bool name_is_strict_reserved, int pos,
1082 bool* ok);
1083 };
1084
1085
MaterializeTemplateCallsiteLiterals()1086 void PreParserTraits::MaterializeTemplateCallsiteLiterals() {
1087 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1088 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1089 }
1090
1091
MaterializeUnspreadArgumentsLiterals(int count)1092 void PreParserTraits::MaterializeUnspreadArgumentsLiterals(int count) {
1093 for (int i = 0; i < count; ++i) {
1094 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1095 }
1096 }
1097
1098
SpreadCall(PreParserExpression function,PreParserExpressionList args,int pos)1099 PreParserExpression PreParserTraits::SpreadCall(PreParserExpression function,
1100 PreParserExpressionList args,
1101 int pos) {
1102 return pre_parser_->factory()->NewCall(function, args, pos);
1103 }
1104
SpreadCallNew(PreParserExpression function,PreParserExpressionList args,int pos)1105 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function,
1106 PreParserExpressionList args,
1107 int pos) {
1108 return pre_parser_->factory()->NewCallNew(function, args, pos);
1109 }
1110
1111
ParseArrowFunctionFormalParameterList(PreParserFormalParameters * parameters,PreParserExpression params,const Scanner::Location & params_loc,Scanner::Location * duplicate_loc,bool * ok)1112 void PreParserTraits::ParseArrowFunctionFormalParameterList(
1113 PreParserFormalParameters* parameters,
1114 PreParserExpression params, const Scanner::Location& params_loc,
1115 Scanner::Location* duplicate_loc, bool* ok) {
1116 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter
1117 // lists that are too long.
1118 }
1119
1120
ParseDoExpression(bool * ok)1121 PreParserExpression PreParserTraits::ParseDoExpression(bool* ok) {
1122 return pre_parser_->ParseDoExpression(ok);
1123 }
1124
1125
RewriteNonPattern(PreParserExpression expr,const ExpressionClassifier * classifier,bool * ok)1126 PreParserExpression PreParserTraits::RewriteNonPattern(
1127 PreParserExpression expr, const ExpressionClassifier* classifier,
1128 bool* ok) {
1129 pre_parser_->ValidateExpression(classifier, ok);
1130 return expr;
1131 }
1132
1133
RewriteNonPatternArguments(PreParserExpression args,const ExpressionClassifier * classifier,bool * ok)1134 PreParserExpression PreParserTraits::RewriteNonPatternArguments(
1135 PreParserExpression args, const ExpressionClassifier* classifier,
1136 bool* ok) {
1137 pre_parser_->ValidateExpression(classifier, ok);
1138 return args;
1139 }
1140
1141
RewriteNonPatternObjectLiteralProperty(PreParserExpression property,const ExpressionClassifier * classifier,bool * ok)1142 PreParserExpression PreParserTraits::RewriteNonPatternObjectLiteralProperty(
1143 PreParserExpression property, const ExpressionClassifier* classifier,
1144 bool* ok) {
1145 pre_parser_->ValidateExpression(classifier, ok);
1146 return property;
1147 }
1148
1149
ParseEagerFunctionBody(PreParserIdentifier function_name,int pos,const PreParserFormalParameters & parameters,FunctionKind kind,FunctionLiteral::FunctionType function_type,bool * ok)1150 PreParserStatementList PreParser::ParseEagerFunctionBody(
1151 PreParserIdentifier function_name, int pos,
1152 const PreParserFormalParameters& parameters, FunctionKind kind,
1153 FunctionLiteral::FunctionType function_type, bool* ok) {
1154 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1155
1156 ParseStatementList(Token::RBRACE, ok);
1157 if (!*ok) return PreParserStatementList();
1158
1159 Expect(Token::RBRACE, ok);
1160 return PreParserStatementList();
1161 }
1162
1163
ParseEagerFunctionBody(PreParserIdentifier function_name,int pos,const PreParserFormalParameters & parameters,FunctionKind kind,FunctionLiteral::FunctionType function_type,bool * ok)1164 PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
1165 PreParserIdentifier function_name, int pos,
1166 const PreParserFormalParameters& parameters, FunctionKind kind,
1167 FunctionLiteral::FunctionType function_type, bool* ok) {
1168 return pre_parser_->ParseEagerFunctionBody(function_name, pos, parameters,
1169 kind, function_type, ok);
1170 }
1171
1172 } // namespace internal
1173 } // namespace v8
1174
1175 #endif // V8_PARSING_PREPARSER_H
1176