Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(180)

Side by Side Diff: src/preparser.h

Issue 915563003: super is only allowed in methods, accessors and constructor (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: further test cleanup Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | test/cctest/test-parsing.cc » ('j') | test/cctest/test-parsing.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 214
215 int NextHandlerIndex() { return next_handler_index_++; } 215 int NextHandlerIndex() { return next_handler_index_++; }
216 int handler_count() { return next_handler_index_; } 216 int handler_count() { return next_handler_index_; }
217 217
218 void AddProperty() { expected_property_count_++; } 218 void AddProperty() { expected_property_count_++; }
219 int expected_property_count() { return expected_property_count_; } 219 int expected_property_count() { return expected_property_count_; }
220 220
221 bool is_generator() const { return IsGeneratorFunction(kind_); } 221 bool is_generator() const { return IsGeneratorFunction(kind_); }
222 222
223 FunctionKind kind() const { return kind_; } 223 FunctionKind kind() const { return kind_; }
224 FunctionState* outer() const { return outer_function_state_; }
224 225
225 void set_generator_object_variable( 226 void set_generator_object_variable(
226 typename Traits::Type::GeneratorVariable* variable) { 227 typename Traits::Type::GeneratorVariable* variable) {
227 DCHECK(variable != NULL); 228 DCHECK(variable != NULL);
228 DCHECK(is_generator()); 229 DCHECK(is_generator());
229 generator_object_variable_ = variable; 230 generator_object_variable_ = variable;
230 } 231 }
231 typename Traits::Type::GeneratorVariable* generator_object_variable() 232 typename Traits::Type::GeneratorVariable* generator_object_variable()
232 const { 233 const {
233 return generator_object_variable_; 234 return generator_object_variable_;
(...skipping 12 matching lines...) Expand all
246 247
247 // Properties count estimation. 248 // Properties count estimation.
248 int expected_property_count_; 249 int expected_property_count_;
249 250
250 FunctionKind kind_; 251 FunctionKind kind_;
251 // For generators, this variable may hold the generator object. It variable 252 // For generators, this variable may hold the generator object. It variable
252 // is used by yield expressions and return statements. It is not necessary 253 // is used by yield expressions and return statements. It is not necessary
253 // for generator functions to have this variable set. 254 // for generator functions to have this variable set.
254 Variable* generator_object_variable_; 255 Variable* generator_object_variable_;
255 256
256
257 FunctionState** function_state_stack_; 257 FunctionState** function_state_stack_;
258 FunctionState* outer_function_state_; 258 FunctionState* outer_function_state_;
259 typename Traits::Type::Scope** scope_stack_; 259 typename Traits::Type::Scope** scope_stack_;
260 typename Traits::Type::Scope* outer_scope_; 260 typename Traits::Type::Scope* outer_scope_;
261 typename Traits::Type::Factory* factory_; 261 typename Traits::Type::Factory* factory_;
262 262
263 friend class ParserTraits; 263 friend class ParserTraits;
264 friend class Checkpoint; 264 friend class Checkpoint;
265 }; 265 };
266 266
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 ExpressionT ParsePostfixExpression(bool* ok); 552 ExpressionT ParsePostfixExpression(bool* ok);
553 ExpressionT ParseLeftHandSideExpression(bool* ok); 553 ExpressionT ParseLeftHandSideExpression(bool* ok);
554 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); 554 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok);
555 ExpressionT ParseMemberExpression(bool* ok); 555 ExpressionT ParseMemberExpression(bool* ok);
556 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, 556 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
557 bool* ok); 557 bool* ok);
558 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, 558 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast,
559 bool* ok); 559 bool* ok);
560 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); 560 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok);
561 void AddTemplateExpression(ExpressionT); 561 void AddTemplateExpression(ExpressionT);
562 ExpressionT ParseSuperExpression(bool is_new, bool* ok);
562 563
563 // Checks if the expression is a valid reference expression (e.g., on the 564 // Checks if the expression is a valid reference expression (e.g., on the
564 // left-hand side of assignments). Although ruled out by ECMA as early errors, 565 // left-hand side of assignments). Although ruled out by ECMA as early errors,
565 // we allow calls for web compatibility and rewrite them to a runtime throw. 566 // we allow calls for web compatibility and rewrite them to a runtime throw.
566 ExpressionT CheckAndRewriteReferenceExpression( 567 ExpressionT CheckAndRewriteReferenceExpression(
567 ExpressionT expression, 568 ExpressionT expression,
568 Scanner::Location location, const char* message, bool* ok); 569 Scanner::Location location, const char* message, bool* ok);
569 570
570 // Used to validate property names in object literals and class literals 571 // Used to validate property names in object literals and class literals
571 enum PropertyKind { 572 enum PropertyKind {
(...skipping 2130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2702 // new foo()() means (new foo())() 2703 // new foo()() means (new foo())()
2703 // new new foo()() means (new (new foo())()) 2704 // new new foo()() means (new (new foo())())
2704 // new new foo means new (new foo) 2705 // new new foo means new (new foo)
2705 // new new foo() means new (new foo()) 2706 // new new foo() means new (new foo())
2706 // new new foo().bar().baz means (new (new foo()).bar()).baz 2707 // new new foo().bar().baz means (new (new foo()).bar()).baz
2707 2708
2708 if (peek() == Token::NEW) { 2709 if (peek() == Token::NEW) {
2709 Consume(Token::NEW); 2710 Consume(Token::NEW);
2710 int new_pos = position(); 2711 int new_pos = position();
2711 ExpressionT result = this->EmptyExpression(); 2712 ExpressionT result = this->EmptyExpression();
2712 if (Check(Token::SUPER)) { 2713 if (peek() == Token::SUPER) {
2713 result = this->SuperReference(scope_, factory()); 2714 const bool is_new = true;
2715 result = ParseSuperExpression(is_new, CHECK_OK);
2714 } else { 2716 } else {
2715 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); 2717 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
2716 } 2718 }
2717 if (peek() == Token::LPAREN) { 2719 if (peek() == Token::LPAREN) {
2718 // NewExpression with arguments. 2720 // NewExpression with arguments.
2719 typename Traits::Type::ExpressionList args = 2721 typename Traits::Type::ExpressionList args =
2720 this->ParseArguments(CHECK_OK); 2722 this->ParseArguments(CHECK_OK);
2721 result = factory()->NewCallNew(result, args, new_pos); 2723 result = factory()->NewCallNew(result, args, new_pos);
2722 // The expression can still continue with . or [ after the arguments. 2724 // The expression can still continue with . or [ after the arguments.
2723 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); 2725 result = this->ParseMemberExpressionContinuation(result, CHECK_OK);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2760 function_name_location = scanner()->location(); 2762 function_name_location = scanner()->location();
2761 function_type = FunctionLiteral::NAMED_EXPRESSION; 2763 function_type = FunctionLiteral::NAMED_EXPRESSION;
2762 } 2764 }
2763 result = this->ParseFunctionLiteral( 2765 result = this->ParseFunctionLiteral(
2764 name, function_name_location, is_strict_reserved_name, 2766 name, function_name_location, is_strict_reserved_name,
2765 is_generator ? FunctionKind::kGeneratorFunction 2767 is_generator ? FunctionKind::kGeneratorFunction
2766 : FunctionKind::kNormalFunction, 2768 : FunctionKind::kNormalFunction,
2767 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, 2769 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY,
2768 CHECK_OK); 2770 CHECK_OK);
2769 } else if (peek() == Token::SUPER) { 2771 } else if (peek() == Token::SUPER) {
2770 int beg_pos = position(); 2772 const bool is_new = false;
2771 Consume(Token::SUPER); 2773 result = ParseSuperExpression(is_new, CHECK_OK);
2772 Token::Value next = peek();
2773 if (next == Token::PERIOD || next == Token::LBRACK) {
2774 scope_->RecordSuperPropertyUsage();
2775 result = this->SuperReference(scope_, factory());
2776 } else if (next == Token::LPAREN) {
2777 scope_->RecordSuperConstructorCallUsage();
2778 result = this->SuperReference(scope_, factory());
2779 } else {
2780 ReportMessageAt(Scanner::Location(beg_pos, position()),
2781 "unexpected_super");
2782 *ok = false;
2783 return this->EmptyExpression();
2784 }
2785 } else { 2774 } else {
2786 result = ParsePrimaryExpression(CHECK_OK); 2775 result = ParsePrimaryExpression(CHECK_OK);
2787 } 2776 }
2788 2777
2789 result = ParseMemberExpressionContinuation(result, CHECK_OK); 2778 result = ParseMemberExpressionContinuation(result, CHECK_OK);
2790 return result; 2779 return result;
2791 } 2780 }
2792 2781
2793 2782
2794 template <class Traits> 2783 template <class Traits>
2795 typename ParserBase<Traits>::ExpressionT 2784 typename ParserBase<Traits>::ExpressionT
2785 ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) {
2786 int beg_pos = position();
2787 Expect(Token::SUPER, CHECK_OK);
2788
2789 FunctionState* function_state = function_state_;
2790 while (IsArrowFunction(function_state->kind())) {
2791 function_state = function_state->outer();
2792 }
2793 // TODO(arv): Handle eval scopes similarly.
2794
2795 FunctionKind kind = function_state->kind();
2796 if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
2797 IsConstructor(kind)) {
2798 if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
2799 scope_->RecordSuperPropertyUsage();
2800 return this->SuperReference(scope_, factory());
2801 }
2802 // new super() is never allowed.
2803 // super() is only allowed in constructor
2804 if (!is_new && peek() == Token::LPAREN && IsConstructor(kind)) {
2805 scope_->RecordSuperConstructorCallUsage();
2806 return this->SuperReference(scope_, factory());
2807 }
2808 }
2809
2810 ReportMessageAt(Scanner::Location(beg_pos, position()), "unexpected_super");
2811 *ok = false;
2812 return this->EmptyExpression();
2813 }
2814
2815
2816 template <class Traits>
2817 typename ParserBase<Traits>::ExpressionT
2796 ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression, 2818 ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression,
2797 bool* ok) { 2819 bool* ok) {
2798 // Parses this part of MemberExpression: 2820 // Parses this part of MemberExpression:
2799 // ('[' Expression ']' | '.' Identifier)* 2821 // ('[' Expression ']' | '.' Identifier)*
2800 while (true) { 2822 while (true) {
2801 switch (peek()) { 2823 switch (peek()) {
2802 case Token::LBRACK: { 2824 case Token::LBRACK: {
2803 Consume(Token::LBRACK); 2825 Consume(Token::LBRACK);
2804 int pos = position(); 2826 int pos = position();
2805 ExpressionT index = this->ParseExpression(true, CHECK_OK); 2827 ExpressionT index = this->ParseExpression(true, CHECK_OK);
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
3104 *ok = false; 3126 *ok = false;
3105 return; 3127 return;
3106 } 3128 }
3107 has_seen_constructor_ = true; 3129 has_seen_constructor_ = true;
3108 return; 3130 return;
3109 } 3131 }
3110 } 3132 }
3111 } } // v8::internal 3133 } } // v8::internal
3112 3134
3113 #endif // V8_PREPARSER_H 3135 #endif // V8_PREPARSER_H
OLDNEW
« no previous file with comments | « no previous file | test/cctest/test-parsing.cc » ('j') | test/cctest/test-parsing.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698