Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_PREPARSER_H | 5 #ifndef V8_PREPARSER_H |
| 6 #define V8_PREPARSER_H | 6 #define V8_PREPARSER_H |
| 7 | 7 |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 338 } | 338 } |
| 339 ~ParsingModeScope() { | 339 ~ParsingModeScope() { |
| 340 parser_->mode_ = old_mode_; | 340 parser_->mode_ = old_mode_; |
| 341 } | 341 } |
| 342 | 342 |
| 343 private: | 343 private: |
| 344 ParserBase* parser_; | 344 ParserBase* parser_; |
| 345 Mode old_mode_; | 345 Mode old_mode_; |
| 346 }; | 346 }; |
| 347 | 347 |
| 348 Scope* NewScope(Scope* parent, ScopeType scope_type, | 348 Scope* NewScope(Scope* parent, ScopeType scope_type) { |
| 349 FunctionKind kind = kNormalFunction) { | 349 // Must always pass the function kind for FUNCTION_SCOPE and ARROW_SCOPE. |
| 350 DCHECK(scope_type != FUNCTION_SCOPE && scope_type != ARROW_SCOPE); | |
| 351 return NewScope(parent, scope_type, kNormalFunction); | |
| 352 } | |
| 353 | |
| 354 Scope* NewScope(Scope* parent, ScopeType scope_type, FunctionKind kind) { | |
| 350 DCHECK(ast_value_factory()); | 355 DCHECK(ast_value_factory()); |
| 351 DCHECK(scope_type != MODULE_SCOPE || allow_harmony_modules()); | 356 DCHECK(scope_type != MODULE_SCOPE || allow_harmony_modules()); |
| 352 DCHECK((scope_type == FUNCTION_SCOPE && IsValidFunctionKind(kind)) || | 357 DCHECK(scope_type != ARROW_SCOPE || IsArrowFunction(kind)); |
| 353 kind == kNormalFunction); | |
| 354 Scope* result = new (zone()) | 358 Scope* result = new (zone()) |
| 355 Scope(zone(), parent, scope_type, ast_value_factory(), kind); | 359 Scope(zone(), parent, scope_type, ast_value_factory(), kind); |
| 356 result->Initialize(); | 360 result->Initialize(); |
| 357 return result; | 361 return result; |
| 358 } | 362 } |
| 359 | 363 |
| 360 Scanner* scanner() const { return scanner_; } | 364 Scanner* scanner() const { return scanner_; } |
| 361 AstValueFactory* ast_value_factory() const { return ast_value_factory_; } | 365 AstValueFactory* ast_value_factory() const { return ast_value_factory_; } |
| 362 int position() { return scanner_->location().beg_pos; } | 366 int position() { return scanner_->location().beg_pos; } |
| 363 int peek_position() { return scanner_->peek_location().beg_pos; } | 367 int peek_position() { return scanner_->peek_location().beg_pos; } |
| (...skipping 1802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2166 break; | 2170 break; |
| 2167 | 2171 |
| 2168 case Token::LBRACE: | 2172 case Token::LBRACE: |
| 2169 result = this->ParseObjectLiteral(classifier, CHECK_OK); | 2173 result = this->ParseObjectLiteral(classifier, CHECK_OK); |
| 2170 break; | 2174 break; |
| 2171 | 2175 |
| 2172 case Token::LPAREN: | 2176 case Token::LPAREN: |
| 2173 Consume(Token::LPAREN); | 2177 Consume(Token::LPAREN); |
| 2174 if (allow_harmony_arrow_functions() && Check(Token::RPAREN)) { | 2178 if (allow_harmony_arrow_functions() && Check(Token::RPAREN)) { |
| 2175 // As a primary expression, the only thing that can follow "()" is "=>". | 2179 // As a primary expression, the only thing that can follow "()" is "=>". |
| 2176 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); | 2180 Scope* scope = |
| 2181 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); | |
| 2177 scope->set_start_position(beg_pos); | 2182 scope->set_start_position(beg_pos); |
| 2178 FormalParameterErrorLocations error_locs; | 2183 FormalParameterErrorLocations error_locs; |
| 2179 bool has_rest = false; | 2184 bool has_rest = false; |
| 2180 result = this->ParseArrowFunctionLiteral(scope, error_locs, has_rest, | 2185 result = this->ParseArrowFunctionLiteral(scope, error_locs, has_rest, |
| 2181 classifier, CHECK_OK); | 2186 classifier, CHECK_OK); |
| 2182 } else { | 2187 } else { |
| 2183 // Heuristically try to detect immediately called functions before | 2188 // Heuristically try to detect immediately called functions before |
| 2184 // seeing the call parentheses. | 2189 // seeing the call parentheses. |
| 2185 parenthesized_function_ = (peek() == Token::FUNCTION); | 2190 parenthesized_function_ = (peek() == Token::FUNCTION); |
| 2186 result = this->ParseExpression(true, classifier, CHECK_OK); | 2191 result = this->ParseExpression(true, classifier, CHECK_OK); |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2647 if (fni_ != NULL) fni_->Enter(); | 2652 if (fni_ != NULL) fni_->Enter(); |
| 2648 ParserBase<Traits>::Checkpoint checkpoint(this); | 2653 ParserBase<Traits>::Checkpoint checkpoint(this); |
| 2649 ExpressionT expression = | 2654 ExpressionT expression = |
| 2650 this->ParseConditionalExpression(accept_IN, classifier, CHECK_OK); | 2655 this->ParseConditionalExpression(accept_IN, classifier, CHECK_OK); |
| 2651 | 2656 |
| 2652 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { | 2657 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { |
| 2653 checkpoint.Restore(); | 2658 checkpoint.Restore(); |
| 2654 FormalParameterErrorLocations error_locs; | 2659 FormalParameterErrorLocations error_locs; |
| 2655 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos); | 2660 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos); |
| 2656 bool has_rest = false; | 2661 bool has_rest = false; |
| 2657 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); | 2662 Scope* scope = |
| 2663 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); | |
| 2658 scope->set_start_position(lhs_location.beg_pos); | 2664 scope->set_start_position(lhs_location.beg_pos); |
| 2659 this->ParseArrowFunctionFormalParameters(scope, expression, loc, | 2665 this->ParseArrowFunctionFormalParameters(scope, expression, loc, |
| 2660 &error_locs, &has_rest, CHECK_OK); | 2666 &error_locs, &has_rest, CHECK_OK); |
| 2661 expression = this->ParseArrowFunctionLiteral(scope, error_locs, has_rest, | 2667 expression = this->ParseArrowFunctionLiteral(scope, error_locs, has_rest, |
| 2662 classifier, CHECK_OK); | 2668 classifier, CHECK_OK); |
| 2663 return expression; | 2669 return expression; |
| 2664 } | 2670 } |
| 2665 | 2671 |
| 2666 if (!Token::IsAssignmentOp(peek())) { | 2672 if (!Token::IsAssignmentOp(peek())) { |
| 2667 if (fni_ != NULL) fni_->Leave(); | 2673 if (fni_ != NULL) fni_->Leave(); |
| (...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3244 } | 3250 } |
| 3245 | 3251 |
| 3246 | 3252 |
| 3247 template <class Traits> | 3253 template <class Traits> |
| 3248 typename ParserBase<Traits>::ExpressionT | 3254 typename ParserBase<Traits>::ExpressionT |
| 3249 ParserBase<Traits>::ParseSuperExpression(bool is_new, | 3255 ParserBase<Traits>::ParseSuperExpression(bool is_new, |
| 3250 ExpressionClassifier* classifier, | 3256 ExpressionClassifier* classifier, |
| 3251 bool* ok) { | 3257 bool* ok) { |
| 3252 Expect(Token::SUPER, CHECK_OK); | 3258 Expect(Token::SUPER, CHECK_OK); |
| 3253 | 3259 |
| 3254 // TODO(wingo): Does this actually work with lazily compiled arrows? | 3260 Scope* scope = scope_->DeclarationScope(); |
| 3255 FunctionState* function_state = function_state_; | 3261 |
| 3256 while (IsArrowFunction(function_state->kind())) { | 3262 while (scope->is_eval_scope() || scope->is_arrow_scope()) { |
| 3257 function_state = function_state->outer(); | 3263 scope = scope->outer_scope(); |
| 3264 DCHECK_NOT_NULL(scope); | |
| 3265 scope = scope->DeclarationScope(); | |
| 3258 } | 3266 } |
|
wingo
2015/05/06 14:47:38
Sounds like we could use a this_declaration_scope(
arv (Not doing code reviews)
2015/05/06 14:57:19
Yes. That would be perfect for both super and new.
| |
| 3259 // TODO(arv): Handle eval scopes similarly. | |
| 3260 | 3267 |
| 3261 FunctionKind kind = function_state->kind(); | 3268 FunctionKind kind = scope->function_kind(); |
| 3262 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || | 3269 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || |
| 3263 i::IsConstructor(kind)) { | 3270 i::IsConstructor(kind)) { |
| 3264 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { | 3271 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { |
| 3265 scope_->RecordSuperPropertyUsage(); | 3272 scope->RecordSuperPropertyUsage(); |
| 3266 return this->SuperReference(scope_, factory()); | 3273 return this->SuperReference(scope, factory()); |
| 3267 } | 3274 } |
| 3268 // new super() is never allowed. | 3275 // new super() is never allowed. |
| 3269 // super() is only allowed in derived constructor | 3276 // super() is only allowed in derived constructor |
| 3270 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { | 3277 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { |
| 3271 if (is_strong(language_mode())) { | 3278 if (is_strong(language_mode())) { |
| 3272 // Super calls in strong mode are parsed separately. | 3279 // Super calls in strong mode are parsed separately. |
| 3273 ReportMessageAt(scanner()->location(), "strong_constructor_super"); | 3280 ReportMessageAt(scanner()->location(), "strong_constructor_super"); |
| 3274 *ok = false; | 3281 *ok = false; |
| 3275 return this->EmptyExpression(); | 3282 return this->EmptyExpression(); |
| 3276 } | 3283 } |
| 3277 function_state->set_super_location(scanner()->location()); | 3284 // TODO(rossberg): This might not be the correct FunctionState for the |
|
arv (Not doing code reviews)
2015/04/24 15:15:41
Andreas, I'll remove this todo since you said you
| |
| 3278 return this->SuperReference(scope_, factory()); | 3285 // method here. |
| 3286 function_state_->set_super_location(scanner()->location()); | |
| 3287 return this->SuperReference(scope, factory()); | |
| 3279 } | 3288 } |
| 3280 } | 3289 } |
| 3281 | 3290 |
| 3282 ReportMessageAt(scanner()->location(), "unexpected_super"); | 3291 ReportMessageAt(scanner()->location(), "unexpected_super"); |
| 3283 *ok = false; | 3292 *ok = false; |
| 3284 return this->EmptyExpression(); | 3293 return this->EmptyExpression(); |
| 3285 } | 3294 } |
| 3286 | 3295 |
| 3287 | 3296 |
| 3288 template <class Traits> | 3297 template <class Traits> |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3713 *ok = false; | 3722 *ok = false; |
| 3714 return; | 3723 return; |
| 3715 } | 3724 } |
| 3716 has_seen_constructor_ = true; | 3725 has_seen_constructor_ = true; |
| 3717 return; | 3726 return; |
| 3718 } | 3727 } |
| 3719 } | 3728 } |
| 3720 } } // v8::internal | 3729 } } // v8::internal |
| 3721 | 3730 |
| 3722 #endif // V8_PREPARSER_H | 3731 #endif // V8_PREPARSER_H |
| OLD | NEW |