Line data Source code
1 : // Copyright 2018 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_EXPRESSION_SCOPE_H_
6 : #define V8_PARSING_EXPRESSION_SCOPE_H_
7 :
8 : #include "src/ast/scopes.h"
9 : #include "src/function-kind.h"
10 : #include "src/message-template.h"
11 : #include "src/parsing/scanner.h"
12 : #include "src/zone/zone.h" // For ScopedPtrList.
13 :
14 : namespace v8 {
15 : namespace internal {
16 :
17 : template <typename Types>
18 : class ExpressionParsingScope;
19 : template <typename Types>
20 : class AccumulationScope;
21 : template <typename Types>
22 : class ArrowHeadParsingScope;
23 : template <typename Types>
24 : class ParameterDeclarationParsingScope;
25 : template <typename Types>
26 : class VariableDeclarationParsingScope;
27 : class VariableProxy;
28 :
29 : // ExpressionScope is used in a stack fashion, and is used to specialize
30 : // expression parsing for the task at hand. It allows the parser to reuse the
31 : // same code to parse destructuring declarations, assignment patterns,
32 : // expressions, and (async) arrow function heads.
33 : //
34 : // One of the specific subclasses needs to be instantiated to tell the parser
35 : // the meaning of the expression it will parse next. The parser then calls
36 : // Record* on the expression_scope() to indicate errors. The expression_scope
37 : // will either discard those errors, immediately report those errors, or
38 : // classify the errors for later validation.
39 : // TODO(verwaest): Record is a slightly odd name since it will directly throw
40 : // for unambiguous scopes.
41 : template <typename Types>
42 : class ExpressionScope {
43 : public:
44 : typedef typename Types::Impl ParserT;
45 : typedef typename Types::Expression ExpressionT;
46 :
47 70635026 : VariableProxy* NewVariable(const AstRawString* name,
48 103512523 : int pos = kNoSourcePosition) {
49 70635026 : VariableProxy* result = parser_->NewRawVariable(name, pos);
50 70639153 : if (CanBeExpression()) {
51 49576890 : AsExpressionParsingScope()->TrackVariable(result);
52 : } else {
53 21062263 : Variable* var = Declare(name, pos);
54 42824435 : if (IsVarDeclaration() && !parser()->scope()->is_declaration_scope()) {
55 : // Make sure we'll properly resolve the variable since we might be in a
56 : // with or catch scope. In those cases the proxy isn't guaranteed to
57 : // refer to the declared variable, so consider it unresolved.
58 929752 : parser()->scope()->AddUnresolved(result);
59 20133049 : } else if (var) {
60 20133102 : result->BindTo(var);
61 : }
62 : }
63 70637891 : return result;
64 : }
65 :
66 23274150 : Variable* Declare(const AstRawString* name, int pos = kNoSourcePosition) {
67 23274150 : if (type_ == kParameterDeclaration) {
68 7797953 : return AsParameterDeclarationParsingScope()->Declare(name, pos);
69 : }
70 15476197 : return AsVariableDeclarationParsingScope()->Declare(name, pos);
71 : }
72 :
73 4245669 : void MarkIdentifierAsAssigned() {
74 5009227 : if (!CanBeExpression()) return;
75 4190254 : AsExpressionParsingScope()->MarkIdentifierAsAssigned();
76 : }
77 :
78 189733 : void ValidateAsPattern(ExpressionT expression, int begin, int end) {
79 189733 : if (!CanBeExpression()) return;
80 188465 : AsExpressionParsingScope()->ValidatePattern(expression, begin, end);
81 : AsExpressionParsingScope()->ClearExpressionError();
82 : }
83 :
84 : // Record async arrow parameters errors in all ambiguous async arrow scopes in
85 : // the chain up to the first unambiguous scope.
86 22381 : void RecordAsyncArrowParametersError(const Scanner::Location& loc,
87 22968 : MessageTemplate message) {
88 : // Only ambiguous scopes (ExpressionParsingScope, *ArrowHeadParsingScope)
89 : // need to propagate errors to a possible kAsyncArrowHeadParsingScope, so
90 : // immediately return if the current scope is not ambiguous.
91 45349 : if (!CanBeExpression()) return;
92 : AsExpressionParsingScope()->RecordAsyncArrowParametersError(loc, message);
93 : }
94 :
95 : // Record initializer errors in all scopes that can turn into parameter scopes
96 : // (ArrowHeadParsingScopes) up to the first known unambiguous parameter scope.
97 96805 : void RecordParameterInitializerError(const Scanner::Location& loc,
98 7752 : MessageTemplate message) {
99 196447 : ExpressionScope* scope = this;
100 236610 : while (!scope->IsCertainlyParameterDeclaration()) {
101 132053 : if (!has_possible_parameter_in_scope_chain_) return;
102 56642 : if (scope->CanBeParameterDeclaration()) {
103 : scope->AsArrowHeadParsingScope()->RecordDeclarationError(loc, message);
104 : }
105 : scope = scope->parent();
106 56642 : if (scope == nullptr) return;
107 : }
108 : Report(loc, message);
109 : }
110 :
111 5411546 : void RecordThisUse() {
112 11316944 : ExpressionScope* scope = this;
113 5658472 : do {
114 5658472 : if (scope->IsArrowHeadParsingScope()) {
115 : scope->AsArrowHeadParsingScope()->RecordThisUse();
116 : }
117 : scope = scope->parent();
118 : } while (scope != nullptr);
119 5411546 : }
120 :
121 10687568 : void RecordPatternError(const Scanner::Location& loc,
122 42368 : MessageTemplate message) {
123 : // TODO(verwaest): Non-assigning expression?
124 10687568 : if (IsCertainlyPattern()) {
125 : Report(loc, message);
126 : } else {
127 : AsExpressionParsingScope()->RecordPatternError(loc, message);
128 : }
129 10687568 : }
130 :
131 59512 : void RecordStrictModeParameterError(const Scanner::Location& loc,
132 59512 : MessageTemplate message) {
133 : DCHECK_IMPLIES(!has_error(), loc.IsValid());
134 119024 : if (!CanBeParameterDeclaration()) return;
135 20562 : if (IsCertainlyParameterDeclaration()) {
136 17106 : if (is_strict(parser_->language_mode())) {
137 : Report(loc, message);
138 : } else {
139 8553 : parser_->parameters_->set_strict_parameter_error(loc, message);
140 : }
141 : } else {
142 12009 : parser_->next_arrow_function_info_.strict_parameter_error_location = loc;
143 12009 : parser_->next_arrow_function_info_.strict_parameter_error_message =
144 : message;
145 : }
146 : }
147 :
148 31848415 : void RecordDeclarationError(const Scanner::Location& loc,
149 31852274 : MessageTemplate message) {
150 63696830 : if (!CanBeDeclaration()) return;
151 2805351 : if (IsCertainlyDeclaration()) {
152 : Report(loc, message);
153 : } else {
154 : AsArrowHeadParsingScope()->RecordDeclarationError(loc, message);
155 : }
156 : }
157 :
158 : void RecordExpressionError(const Scanner::Location& loc,
159 33122 : MessageTemplate message) {
160 33122 : if (!CanBeExpression()) return;
161 : // TODO(verwaest): Non-assigning expression?
162 : // if (IsCertainlyExpression()) Report(loc, message);
163 : AsExpressionParsingScope()->RecordExpressionError(loc, message);
164 : }
165 :
166 11361215 : void RecordNonSimpleParameter() {
167 11361215 : if (!IsArrowHeadParsingScope()) return;
168 : AsArrowHeadParsingScope()->RecordNonSimpleParameter();
169 : }
170 :
171 : protected:
172 : enum ScopeType : uint8_t {
173 : // Expression or assignment target.
174 : kExpression,
175 :
176 : // Declaration or expression or assignment target.
177 : kMaybeArrowParameterDeclaration,
178 : kMaybeAsyncArrowParameterDeclaration,
179 :
180 : // Declarations.
181 : kParameterDeclaration,
182 : kVarDeclaration,
183 : kLexicalDeclaration,
184 : };
185 :
186 : ParserT* parser() const { return parser_; }
187 : ExpressionScope* parent() const { return parent_; }
188 :
189 : void Report(const Scanner::Location& loc, MessageTemplate message) const {
190 98775 : parser_->ReportMessageAt(loc, message);
191 : }
192 :
193 : ExpressionScope(ParserT* parser, ScopeType type)
194 : : parser_(parser),
195 : parent_(parser->expression_scope_),
196 : type_(type),
197 : has_possible_parameter_in_scope_chain_(
198 : CanBeParameterDeclaration() ||
199 148032883 : (parent_ && parent_->has_possible_parameter_in_scope_chain_)) {
200 76197272 : parser->expression_scope_ = this;
201 : }
202 :
203 : ~ExpressionScope() {
204 : DCHECK(parser_->expression_scope_ == this ||
205 : parser_->expression_scope_ == parent_);
206 76200492 : parser_->expression_scope_ = parent_;
207 : }
208 :
209 : ExpressionParsingScope<Types>* AsExpressionParsingScope() {
210 : DCHECK(CanBeExpression());
211 : return static_cast<ExpressionParsingScope<Types>*>(this);
212 : }
213 :
214 : #ifdef DEBUG
215 : bool has_error() const { return parser_->has_error(); }
216 : #endif
217 :
218 : bool CanBeExpression() const {
219 : return IsInRange(type_, kExpression, kMaybeAsyncArrowParameterDeclaration);
220 : }
221 : bool CanBeDeclaration() const {
222 : return IsInRange(type_, kMaybeArrowParameterDeclaration,
223 : kLexicalDeclaration);
224 : }
225 : bool IsCertainlyDeclaration() const {
226 : return IsInRange(type_, kParameterDeclaration, kLexicalDeclaration);
227 : }
228 : bool IsVariableDeclaration() const {
229 : return IsInRange(type_, kVarDeclaration, kLexicalDeclaration);
230 : }
231 : bool IsLexicalDeclaration() const { return type_ == kLexicalDeclaration; }
232 : bool IsAsyncArrowHeadParsingScope() const {
233 : return type_ == kMaybeAsyncArrowParameterDeclaration;
234 : }
235 : bool IsVarDeclaration() const { return type_ == kVarDeclaration; }
236 :
237 : private:
238 : friend class AccumulationScope<Types>;
239 : friend class ExpressionParsingScope<Types>;
240 :
241 : ArrowHeadParsingScope<Types>* AsArrowHeadParsingScope() {
242 : DCHECK(IsArrowHeadParsingScope());
243 : return static_cast<ArrowHeadParsingScope<Types>*>(this);
244 : }
245 :
246 : ParameterDeclarationParsingScope<Types>*
247 : AsParameterDeclarationParsingScope() {
248 : DCHECK(IsCertainlyParameterDeclaration());
249 : return static_cast<ParameterDeclarationParsingScope<Types>*>(this);
250 : }
251 :
252 : VariableDeclarationParsingScope<Types>* AsVariableDeclarationParsingScope() {
253 : DCHECK(IsVariableDeclaration());
254 : return static_cast<VariableDeclarationParsingScope<Types>*>(this);
255 : }
256 :
257 : bool IsArrowHeadParsingScope() const {
258 : return IsInRange(type_, kMaybeArrowParameterDeclaration,
259 : kMaybeAsyncArrowParameterDeclaration);
260 : }
261 10687568 : bool IsCertainlyPattern() const { return IsCertainlyDeclaration(); }
262 : bool CanBeParameterDeclaration() const {
263 : return IsInRange(type_, kMaybeArrowParameterDeclaration,
264 : kParameterDeclaration);
265 : }
266 : bool IsCertainlyParameterDeclaration() const {
267 : return type_ == kParameterDeclaration;
268 : }
269 :
270 : ParserT* parser_;
271 : ExpressionScope<Types>* parent_;
272 : ScopeType type_;
273 : bool has_possible_parameter_in_scope_chain_;
274 :
275 : DISALLOW_COPY_AND_ASSIGN(ExpressionScope);
276 : };
277 :
278 : // Used to unambiguously parse var, let, const declarations.
279 : template <typename Types>
280 17950 : class VariableDeclarationParsingScope : public ExpressionScope<Types> {
281 : public:
282 : typedef typename Types::Impl ParserT;
283 : typedef class ExpressionScope<Types> ExpressionScopeT;
284 : typedef typename ExpressionScopeT::ScopeType ScopeType;
285 :
286 8975 : VariableDeclarationParsingScope(ParserT* parser, VariableMode mode,
287 : ZonePtrList<const AstRawString>* names)
288 : : ExpressionScopeT(parser, IsLexicalVariableMode(mode)
289 : ? ExpressionScopeT::kLexicalDeclaration
290 : : ExpressionScopeT::kVarDeclaration),
291 : mode_(mode),
292 27235912 : names_(names) {}
293 :
294 15476187 : Variable* Declare(const AstRawString* name, int pos) {
295 : VariableKind kind = NORMAL_VARIABLE;
296 : bool was_added;
297 : Variable* var = this->parser()->DeclareVariable(
298 15476187 : name, kind, mode_, Variable::DefaultInitializationFlag(mode_),
299 76299110 : this->parser()->scope(), &was_added, pos);
300 29093625 : if (was_added &&
301 13617029 : this->parser()->scope()->num_var() > kMaxNumFunctionLocals) {
302 0 : this->parser()->ReportMessage(MessageTemplate::kTooManyVariables);
303 : }
304 16249895 : if (names_) names_->Add(name, this->parser()->zone());
305 15476405 : if (this->IsLexicalDeclaration()) {
306 4775628 : if (this->parser()->IsLet(name)) {
307 6836 : this->parser()->ReportMessageAt(
308 3418 : Scanner::Location(pos, pos + name->length()),
309 : MessageTemplate::kLetInLexicalBinding);
310 : }
311 : } else {
312 26177236 : if (this->parser()->loop_nesting_depth() > 0) {
313 : // Due to hoisting, the value of a 'var'-declared variable may actually
314 : // change even if the code contains only the "initial" assignment,
315 : // namely when that assignment occurs inside a loop. For example:
316 : //
317 : // let i = 10;
318 : // do { var x = i } while (i--):
319 : //
320 : // Note that non-lexical variables include temporaries, which may also
321 : // get assigned inside a loop due to the various rewritings that the
322 : // parser performs.
323 : //
324 : // Pessimistically mark all vars in loops as assigned. This
325 : // overapproximates the actual assigned vars due to unassigned var
326 : // without initializer, but that's unlikely anyway.
327 : //
328 : // This also handles marking of loop variables in for-in and for-of
329 : // loops, as determined by loop-nesting-depth.
330 774567 : if (V8_LIKELY(var)) {
331 : var->set_maybe_assigned();
332 : }
333 : }
334 : }
335 15476459 : return var;
336 : }
337 :
338 : private:
339 : // Limit the allowed number of local variables in a function. The hard limit
340 : // in Ignition is 2^31-1 due to the size of register operands. We limit it to
341 : // a more reasonable lower up-limit.
342 : static const int kMaxNumFunctionLocals = (1 << 23) - 1;
343 :
344 : VariableMode mode_;
345 : ZonePtrList<const AstRawString>* names_;
346 :
347 : DISALLOW_COPY_AND_ASSIGN(VariableDeclarationParsingScope);
348 : };
349 :
350 : template <typename Types>
351 : class ParameterDeclarationParsingScope : public ExpressionScope<Types> {
352 : public:
353 : typedef typename Types::Impl ParserT;
354 : typedef class ExpressionScope<Types> ExpressionScopeT;
355 : typedef typename ExpressionScopeT::ScopeType ScopeType;
356 :
357 : explicit ParameterDeclarationParsingScope(ParserT* parser)
358 4361661 : : ExpressionScopeT(parser, ExpressionScopeT::kParameterDeclaration) {}
359 :
360 7797941 : Variable* Declare(const AstRawString* name, int pos) {
361 : VariableKind kind = PARAMETER_VARIABLE;
362 : VariableMode mode = VariableMode::kVar;
363 : bool was_added;
364 : Variable* var = this->parser()->DeclareVariable(
365 : name, kind, mode, Variable::DefaultInitializationFlag(mode),
366 7797941 : this->parser()->scope(), &was_added, pos);
367 7798174 : if (!has_duplicate() && !was_added) {
368 7202 : duplicate_loc_ = Scanner::Location(pos, pos + name->length());
369 : }
370 7798174 : return var;
371 : }
372 :
373 : bool has_duplicate() const { return duplicate_loc_.IsValid(); }
374 :
375 : const Scanner::Location& duplicate_location() const { return duplicate_loc_; }
376 :
377 : private:
378 : Scanner::Location duplicate_loc_ = Scanner::Location::invalid();
379 : DISALLOW_COPY_AND_ASSIGN(ParameterDeclarationParsingScope);
380 : };
381 :
382 : // Parsing expressions is always ambiguous between at least left-hand-side and
383 : // right-hand-side of assignments. This class is used to keep track of errors
384 : // relevant for either side until it is clear what was being parsed.
385 : // The class also keeps track of all variable proxies that are created while the
386 : // scope was active. If the scope is an expression, the variable proxies will be
387 : // added to the unresolved list. Otherwise they are declarations and aren't
388 : // added. The list is also used to mark the variables as assigned in case we are
389 : // parsing an assignment expression.
390 : template <typename Types>
391 : class ExpressionParsingScope : public ExpressionScope<Types> {
392 : public:
393 : typedef typename Types::Impl ParserT;
394 : typedef typename Types::Expression ExpressionT;
395 : typedef class ExpressionScope<Types> ExpressionScopeT;
396 : typedef typename ExpressionScopeT::ScopeType ScopeType;
397 :
398 58217655 : ExpressionParsingScope(ParserT* parser,
399 : ScopeType type = ExpressionScopeT::kExpression)
400 : : ExpressionScopeT(parser, type),
401 : variable_list_(parser->variable_buffer()),
402 : has_async_arrow_in_scope_chain_(
403 : type == ExpressionScopeT::kMaybeAsyncArrowParameterDeclaration ||
404 27128007 : (this->parent() && this->parent()->CanBeExpression() &&
405 : this->parent()
406 : ->AsExpressionParsingScope()
407 318216496 : ->has_async_arrow_in_scope_chain_)) {
408 : DCHECK(this->CanBeExpression());
409 : clear(kExpressionIndex);
410 : clear(kPatternIndex);
411 58217655 : }
412 :
413 : void RecordAsyncArrowParametersError(const Scanner::Location& loc,
414 : MessageTemplate message) {
415 21031 : for (ExpressionScopeT* scope = this; scope != nullptr;
416 : scope = scope->parent()) {
417 18203 : if (!has_async_arrow_in_scope_chain_) break;
418 10225 : if (scope->type_ ==
419 : ExpressionScopeT::kMaybeAsyncArrowParameterDeclaration) {
420 : scope->AsArrowHeadParsingScope()->RecordDeclarationError(loc, message);
421 : }
422 : }
423 : }
424 :
425 108586689 : ~ExpressionParsingScope() { DCHECK(this->has_error() || verified_); }
426 :
427 104446 : ExpressionT ValidateAndRewriteReference(ExpressionT expression, int beg_pos,
428 : int end_pos) {
429 113483 : if (V8_LIKELY(this->parser()->IsAssignableIdentifier(expression))) {
430 93088 : MarkIdentifierAsAssigned();
431 : this->mark_verified();
432 93089 : return expression;
433 11359 : } else if (V8_LIKELY(expression->IsProperty())) {
434 : ValidateExpression();
435 2322 : return expression;
436 : }
437 : this->mark_verified();
438 : return this->parser()->RewriteInvalidReferenceExpression(
439 : expression, beg_pos, end_pos, MessageTemplate::kInvalidLhsInFor,
440 9037 : kSyntaxError);
441 : }
442 :
443 : void RecordExpressionError(const Scanner::Location& loc,
444 : MessageTemplate message) {
445 : Record(kExpressionIndex, loc, message);
446 : }
447 :
448 : void RecordPatternError(const Scanner::Location& loc,
449 : MessageTemplate message) {
450 : Record(kPatternIndex, loc, message);
451 : }
452 :
453 57872383 : void ValidateExpression() { Validate(kExpressionIndex); }
454 :
455 361871 : void ValidatePattern(ExpressionT expression, int begin, int end) {
456 240743 : Validate(kPatternIndex);
457 240745 : if (expression->is_parenthesized()) {
458 : ExpressionScopeT::Report(Scanner::Location(begin, end),
459 3414 : MessageTemplate::kInvalidDestructuringTarget);
460 : }
461 787709 : for (int i = 0; i < variable_list_.length(); i++) {
462 787709 : variable_list_.at(i)->set_is_assigned();
463 : }
464 240745 : }
465 :
466 : void ClearExpressionError() {
467 : DCHECK(verified_);
468 : #ifdef DEBUG
469 : verified_ = false;
470 : #endif
471 : clear(kExpressionIndex);
472 : }
473 :
474 49576765 : void TrackVariable(VariableProxy* variable) {
475 99153530 : if (!this->CanBeDeclaration()) {
476 45963934 : this->parser()->scope()->AddUnresolved(variable);
477 : }
478 49576147 : variable_list_.Add(variable);
479 49575317 : }
480 :
481 4283214 : void MarkIdentifierAsAssigned() {
482 : // It's possible we're parsing a syntax error. In that case it's not
483 : // guaranteed that there's a variable in the list.
484 17129991 : if (variable_list_.length() == 0) return;
485 4280349 : variable_list_.at(variable_list_.length() - 1)->set_is_assigned();
486 : }
487 :
488 : protected:
489 : bool is_verified() const {
490 : #ifdef DEBUG
491 : return verified_;
492 : #else
493 : return false;
494 : #endif
495 : }
496 :
497 504761 : void ValidatePattern() { Validate(kPatternIndex); }
498 :
499 : ScopedPtrList<VariableProxy>* variable_list() { return &variable_list_; }
500 :
501 : private:
502 : friend class AccumulationScope<Types>;
503 :
504 : enum ErrorNumber : uint8_t {
505 : kExpressionIndex = 0,
506 : kPatternIndex = 1,
507 : kNumberOfErrors = 2,
508 : };
509 : void clear(int index) {
510 320011359 : messages_[index] = MessageTemplate::kNone;
511 320011359 : locations_[index] = Scanner::Location::invalid();
512 : }
513 164851503 : bool is_valid(int index) const { return !locations_[index].IsValid(); }
514 : void Record(int index, const Scanner::Location& loc,
515 : MessageTemplate message) {
516 : DCHECK_IMPLIES(!this->has_error(), loc.IsValid());
517 10663409 : if (!is_valid(index)) return;
518 7904308 : messages_[index] = message;
519 7904308 : locations_[index] = loc;
520 : }
521 58616527 : void Validate(int index) {
522 : DCHECK(!this->is_verified());
523 58616527 : if (!is_valid(index)) Report(index);
524 : this->mark_verified();
525 58616527 : }
526 : void Report(int index) const {
527 26347 : ExpressionScopeT::Report(locations_[index], messages_[index]);
528 : }
529 :
530 : // Debug verification to make sure every scope is validated exactly once.
531 : void mark_verified() {
532 : #ifdef DEBUG
533 : verified_ = true;
534 : #endif
535 : }
536 : void clear_verified() {
537 : #ifdef DEBUG
538 : verified_ = false;
539 : #endif
540 : }
541 : #ifdef DEBUG
542 : bool verified_ = false;
543 : #endif
544 :
545 : ScopedPtrList<VariableProxy> variable_list_;
546 : MessageTemplate messages_[kNumberOfErrors];
547 : Scanner::Location locations_[kNumberOfErrors];
548 : bool has_async_arrow_in_scope_chain_;
549 :
550 : DISALLOW_COPY_AND_ASSIGN(ExpressionParsingScope);
551 : };
552 :
553 : // This class is used to parse multiple ambiguous expressions and declarations
554 : // in the same scope. E.g., in async(X,Y,Z) or [X,Y,Z], X and Y and Z will all
555 : // be parsed in the respective outer ArrowHeadParsingScope and
556 : // ExpressionParsingScope. It provides a clean error state in the underlying
557 : // scope to parse the individual expressions, while keeping track of the
558 : // expression and pattern errors since the start. The AccumulationScope is only
559 : // used to keep track of the errors so far, and the underlying ExpressionScope
560 : // keeps being used as the expression_scope(). If the expression_scope() isn't
561 : // ambiguous, this class does not do anything.
562 : template <typename Types>
563 : class AccumulationScope {
564 : public:
565 : typedef typename Types::Impl ParserT;
566 :
567 : static const int kNumberOfErrors =
568 : ExpressionParsingScope<Types>::kNumberOfErrors;
569 160082229 : explicit AccumulationScope(ExpressionScope<Types>* scope) : scope_(nullptr) {
570 106723314 : if (!scope->CanBeExpression()) return;
571 53119411 : scope_ = scope->AsExpressionParsingScope();
572 159282136 : for (int i = 0; i < kNumberOfErrors; i++) {
573 : // If the underlying scope is already invalid at the start, stop
574 : // accumulating. That means an error was found outside of an
575 : // accumulating path.
576 106234976 : if (!scope_->is_valid(i)) {
577 72251 : scope_ = nullptr;
578 72251 : break;
579 : }
580 : copy(i);
581 : }
582 : }
583 :
584 : // Merge errors from the underlying ExpressionParsingScope into this scope.
585 : // Only keeps the first error across all accumulate calls, and removes the
586 : // error from the underlying scope.
587 105810576 : void Accumulate() {
588 211621152 : if (scope_ == nullptr) return;
589 : DCHECK(!scope_->is_verified());
590 203075581 : for (int i = 0; i < kNumberOfErrors; i++) {
591 406151162 : if (!locations_[i].IsValid()) copy(i);
592 203075581 : scope_->clear(i);
593 : }
594 : }
595 :
596 : // This is called instead of Accumulate in case the parsed member is already
597 : // known to be an expression. In that case we don't need to accumulate the
598 : // expression but rather validate it immediately. We also ignore the pattern
599 : // error since the parsed member is known to not be a pattern. This is
600 : // necessary for "{x:1}.y" parsed as part of an assignment pattern. {x:1} will
601 : // record a pattern error, but "{x:1}.y" is actually a valid as part of an
602 : // assignment pattern since it's a property access.
603 312589 : void ValidateExpression() {
604 625178 : if (scope_ == nullptr) return;
605 : DCHECK(!scope_->is_verified());
606 : scope_->ValidateExpression();
607 : DCHECK(scope_->is_verified());
608 312003 : scope_->clear(ExpressionParsingScope<Types>::kPatternIndex);
609 : #ifdef DEBUG
610 : scope_->clear_verified();
611 : #endif
612 : }
613 :
614 53359684 : ~AccumulationScope() {
615 53359684 : if (scope_ == nullptr) return;
616 53042912 : Accumulate();
617 159126868 : for (int i = 0; i < kNumberOfErrors; i++) copy_back(i);
618 53360376 : }
619 :
620 : private:
621 : void copy(int entry) {
622 301515236 : messages_[entry] = scope_->messages_[entry];
623 301515236 : locations_[entry] = scope_->locations_[entry];
624 : }
625 :
626 : void copy_back(int entry) {
627 212166528 : if (!locations_[entry].IsValid()) return;
628 2036521 : scope_->messages_[entry] = messages_[entry];
629 2036521 : scope_->locations_[entry] = locations_[entry];
630 : }
631 :
632 : ExpressionParsingScope<Types>* scope_;
633 : MessageTemplate messages_[2];
634 : Scanner::Location locations_[2];
635 :
636 : DISALLOW_COPY_AND_ASSIGN(AccumulationScope);
637 : };
638 :
639 : // The head of an arrow function is ambiguous between expression, assignment
640 : // pattern and declaration. This keeps track of the additional declaration
641 : // error and allows the scope to be validated as a declaration rather than an
642 : // expression or a pattern.
643 : template <typename Types>
644 : class ArrowHeadParsingScope : public ExpressionParsingScope<Types> {
645 : public:
646 : typedef typename Types::Impl ParserT;
647 : typedef typename ExpressionScope<Types>::ScopeType ScopeType;
648 :
649 : ArrowHeadParsingScope(ParserT* parser, FunctionKind kind)
650 : : ExpressionParsingScope<Types>(
651 : parser,
652 : kind == FunctionKind::kArrowFunction
653 : ? ExpressionScope<Types>::kMaybeArrowParameterDeclaration
654 : : ExpressionScope<
655 3444001 : Types>::kMaybeAsyncArrowParameterDeclaration) {
656 : DCHECK(kind == FunctionKind::kAsyncArrowFunction ||
657 : kind == FunctionKind::kArrowFunction);
658 : DCHECK(this->CanBeDeclaration());
659 : DCHECK(!this->IsCertainlyDeclaration());
660 : }
661 :
662 2939313 : void ValidateExpression() {
663 : // Turns out this is not an arrow head. Clear any possible tracked strict
664 : // parameter errors, and reinterpret tracked variables as unresolved
665 : // references.
666 5990418 : this->parser()->next_arrow_function_info_.ClearStrictParameterError();
667 2939313 : ExpressionParsingScope<Types>::ValidateExpression();
668 11980830 : for (int i = 0; i < this->variable_list()->length(); i++) {
669 6102210 : this->parser()->scope()->AddUnresolved(this->variable_list()->at(i));
670 : }
671 2939310 : }
672 :
673 504760 : DeclarationScope* ValidateAndCreateScope() {
674 : DCHECK(!this->is_verified());
675 504760 : if (declaration_error_location.IsValid()) {
676 : ExpressionScope<Types>::Report(declaration_error_location,
677 1589618 : declaration_error_message);
678 : }
679 504761 : this->ValidatePattern();
680 :
681 1009540 : DeclarationScope* result = this->parser()->NewFunctionScope(kind());
682 504750 : if (!has_simple_parameter_list_) result->SetHasNonSimpleParameters();
683 : VariableKind kind = PARAMETER_VARIABLE;
684 : VariableMode mode =
685 504750 : has_simple_parameter_list_ ? VariableMode::kVar : VariableMode::kLet;
686 2136212 : for (int i = 0; i < this->variable_list()->length(); i++) {
687 563344 : VariableProxy* proxy = this->variable_list()->at(i);
688 : bool was_added;
689 1267453 : this->parser()->DeclareAndBindVariable(
690 : proxy, kind, mode, Variable::DefaultInitializationFlag(mode), result,
691 : &was_added, proxy->position());
692 563356 : if (!was_added) {
693 : ExpressionScope<Types>::Report(proxy->location(),
694 2562 : MessageTemplate::kParamDupe);
695 : }
696 : }
697 :
698 504762 : int initializer_position = this->parser()->end_position();
699 1150292 : for (auto declaration : *result->declarations()) {
700 : declaration->var()->set_initializer_position(initializer_position);
701 : }
702 504762 : if (uses_this_) result->UsesThis();
703 504762 : return result;
704 : }
705 :
706 : void RecordDeclarationError(const Scanner::Location& loc,
707 : MessageTemplate message) {
708 : DCHECK_IMPLIES(!this->has_error(), loc.IsValid());
709 2824856 : declaration_error_location = loc;
710 2824856 : declaration_error_message = message;
711 : }
712 :
713 203955 : void RecordNonSimpleParameter() { has_simple_parameter_list_ = false; }
714 2564 : void RecordThisUse() { uses_this_ = true; }
715 :
716 : private:
717 : FunctionKind kind() const {
718 : return this->IsAsyncArrowHeadParsingScope()
719 504770 : ? FunctionKind::kAsyncArrowFunction
720 504770 : : FunctionKind::kArrowFunction;
721 : }
722 :
723 : Scanner::Location declaration_error_location = Scanner::Location::invalid();
724 : MessageTemplate declaration_error_message = MessageTemplate::kNone;
725 : bool has_simple_parameter_list_ = true;
726 : bool uses_this_ = false;
727 :
728 : DISALLOW_COPY_AND_ASSIGN(ArrowHeadParsingScope);
729 : };
730 :
731 : } // namespace internal
732 : } // namespace v8
733 :
734 : #endif // V8_PARSING_EXPRESSION_SCOPE_H_
|