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

Side by Side Diff: src/parser.cc

Issue 1024063002: [strong] checking of this & super in constructors (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Typo Created 5 years, 9 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
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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast.h" 8 #include "src/ast.h"
9 #include "src/bailout-reason.h" 9 #include "src/bailout-reason.h"
10 #include "src/base/platform/platform.h" 10 #include "src/base/platform/platform.h"
(...skipping 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1201 TargetScope scope(&this->target_stack_); 1201 TargetScope scope(&this->target_stack_);
1202 1202
1203 DCHECK(body != NULL); 1203 DCHECK(body != NULL);
1204 bool directive_prologue = true; // Parsing directive prologue. 1204 bool directive_prologue = true; // Parsing directive prologue.
1205 1205
1206 while (peek() != end_token) { 1206 while (peek() != end_token) {
1207 if (directive_prologue && peek() != Token::STRING) { 1207 if (directive_prologue && peek() != Token::STRING) {
1208 directive_prologue = false; 1208 directive_prologue = false;
1209 } 1209 }
1210 1210
1211 Token::Value token = peek();
1212 Scanner::Location token_loc = scanner()->peek_location(); 1211 Scanner::Location token_loc = scanner()->peek_location();
1213 Scanner::Location old_super_loc = function_state_->super_call_location(); 1212 Scanner::Location old_this_loc = function_state_->this_location();
1213 Scanner::Location old_super_loc = function_state_->super_location();
1214 Statement* stat = ParseStatementListItem(CHECK_OK); 1214 Statement* stat = ParseStatementListItem(CHECK_OK);
1215 Scanner::Location super_loc = function_state_->super_call_location();
1216 1215
1217 if (is_strong(language_mode()) && 1216 if (is_strong(language_mode()) &&
1218 i::IsConstructor(function_state_->kind()) && 1217 scope_->is_function_scope() &&
1219 !old_super_loc.IsValid() && super_loc.IsValid() && 1218 i::IsConstructor(function_state_->kind())) {
1220 token != Token::SUPER) { 1219 Scanner::Location this_loc = function_state_->this_location();
1221 // TODO(rossberg): This is more permissive than spec'ed, it allows e.g. 1220 Scanner::Location super_loc = function_state_->super_location();
1222 // super(), 1; 1221 if (this_loc.beg_pos != old_this_loc.beg_pos &&
1223 // super() + ""; 1222 this_loc.beg_pos != token_loc.beg_pos) {
1224 // super() = 0; 1223 ReportMessageAt(this_loc, "strong_constructor_this");
1225 // That should still be safe, though, thanks to left-to-right evaluation. 1224 *ok = false;
1226 // The proper check would be difficult to implement in the preparser. 1225 return nullptr;
1227 ReportMessageAt(super_loc, "strong_super_call_nested"); 1226 }
1228 *ok = false; 1227 if (super_loc.beg_pos != old_super_loc.beg_pos &&
1229 return NULL; 1228 super_loc.beg_pos != token_loc.beg_pos) {
1229 ReportMessageAt(super_loc, "strong_constructor_super");
1230 *ok = false;
1231 return nullptr;
1232 }
1230 } 1233 }
1231 1234
1232 if (stat == NULL || stat->IsEmpty()) { 1235 if (stat == NULL || stat->IsEmpty()) {
1233 directive_prologue = false; // End of directive prologue. 1236 directive_prologue = false; // End of directive prologue.
1234 continue; 1237 continue;
1235 } 1238 }
1236 1239
1237 if (directive_prologue) { 1240 if (directive_prologue) {
1238 // A shot at a directive. 1241 // A shot at a directive.
1239 ExpressionStatement* e_stat; 1242 ExpressionStatement* e_stat;
(...skipping 1304 matching lines...) Expand 10 before | Expand all | Expand 10 after
2544 2547
2545 Statement* Parser::ParseExpressionOrLabelledStatement( 2548 Statement* Parser::ParseExpressionOrLabelledStatement(
2546 ZoneList<const AstRawString*>* labels, bool* ok) { 2549 ZoneList<const AstRawString*>* labels, bool* ok) {
2547 // ExpressionStatement | LabelledStatement :: 2550 // ExpressionStatement | LabelledStatement ::
2548 // Expression ';' 2551 // Expression ';'
2549 // Identifier ':' Statement 2552 // Identifier ':' Statement
2550 // 2553 //
2551 // ExpressionStatement[Yield] : 2554 // ExpressionStatement[Yield] :
2552 // [lookahead ∉ {{, function, class, let [}] Expression[In, ?Yield] ; 2555 // [lookahead ∉ {{, function, class, let [}] Expression[In, ?Yield] ;
2553 2556
2557 int pos = peek_position();
2558
2554 switch (peek()) { 2559 switch (peek()) {
2555 case Token::FUNCTION: 2560 case Token::FUNCTION:
2556 case Token::LBRACE: 2561 case Token::LBRACE:
2557 UNREACHABLE(); // Always handled by the callers. 2562 UNREACHABLE(); // Always handled by the callers.
2558 case Token::CLASS: 2563 case Token::CLASS:
2559 ReportUnexpectedToken(Next()); 2564 ReportUnexpectedToken(Next());
2560 *ok = false; 2565 *ok = false;
2561 return nullptr; 2566 return nullptr;
2562 2567
2568 case Token::THIS:
2569 case Token::SUPER:
2570 if (is_strong(language_mode()) &&
2571 i::IsConstructor(function_state_->kind())) {
2572 bool is_this = peek() == Token::THIS;
2573 Expression* expr;
2574 if (is_this) {
2575 expr = ParseStrongInitializationExpression(CHECK_OK);
2576 } else {
2577 expr = ParseStrongSuperCallExpression(CHECK_OK);
2578 }
2579 switch (peek()) {
2580 case Token::SEMICOLON:
2581 Consume(Token::SEMICOLON);
2582 break;
2583 case Token::RBRACE:
2584 case Token::EOS:
2585 break;
2586 default:
2587 if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
2588 ReportMessageAt(function_state_->this_location(),
2589 is_this ? "strong_constructor_this"
2590 : "strong_constructor_super");
2591 *ok = false;
2592 return nullptr;
2593 }
2594 }
2595 return factory()->NewExpressionStatement(expr, pos);
2596 }
2597 break;
2598
2563 // TODO(arv): Handle `let [` 2599 // TODO(arv): Handle `let [`
2564 // https://code.google.com/p/v8/issues/detail?id=3847 2600 // https://code.google.com/p/v8/issues/detail?id=3847
2565 2601
2566 default: 2602 default:
2567 break; 2603 break;
2568 } 2604 }
2569 2605
2570 int pos = peek_position();
2571 bool starts_with_idenfifier = peek_any_identifier(); 2606 bool starts_with_idenfifier = peek_any_identifier();
2572 Expression* expr = ParseExpression(true, CHECK_OK); 2607 Expression* expr = ParseExpression(true, CHECK_OK);
2573 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && 2608 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
2574 expr->AsVariableProxy() != NULL && 2609 expr->AsVariableProxy() != NULL &&
2575 !expr->AsVariableProxy()->is_this()) { 2610 !expr->AsVariableProxy()->is_this()) {
2576 // Expression is a single identifier, and not, e.g., a parenthesized 2611 // Expression is a single identifier, and not, e.g., a parenthesized
2577 // identifier. 2612 // identifier.
2578 VariableProxy* var = expr->AsVariableProxy(); 2613 VariableProxy* var = expr->AsVariableProxy();
2579 const AstRawString* label = var->raw_name(); 2614 const AstRawString* label = var->raw_name();
2580 // TODO(1240780): We don't check for redeclaration of labels 2615 // TODO(1240780): We don't check for redeclaration of labels
(...skipping 1373 matching lines...) Expand 10 before | Expand all | Expand 10 after
3954 reserved_error_loc, CHECK_OK); 3989 reserved_error_loc, CHECK_OK);
3955 3990
3956 if (is_strict(language_mode())) { 3991 if (is_strict(language_mode())) {
3957 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), 3992 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
3958 CHECK_OK); 3993 CHECK_OK);
3959 } 3994 }
3960 if (is_strict(language_mode())) { 3995 if (is_strict(language_mode())) {
3961 CheckConflictingVarDeclarations(scope, CHECK_OK); 3996 CheckConflictingVarDeclarations(scope, CHECK_OK);
3962 } 3997 }
3963 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { 3998 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) {
3964 if (!function_state.super_call_location().IsValid()) { 3999 if (!function_state.super_location().IsValid()) {
3965 ReportMessageAt(function_name_location, "strong_super_call_missing", 4000 ReportMessageAt(function_name_location, "strong_super_call_missing",
3966 kReferenceError); 4001 kReferenceError);
3967 *ok = false; 4002 *ok = false;
3968 return nullptr; 4003 return nullptr;
3969 } 4004 }
3970 } 4005 }
3971 } 4006 }
3972 4007
3973 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 4008 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
3974 function_name, ast_value_factory(), scope, body, 4009 function_name, ast_value_factory(), scope, body,
(...skipping 1585 matching lines...) Expand 10 before | Expand all | Expand 10 after
5560 } else { 5595 } else {
5561 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); 5596 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
5562 running_hash = StringHasher::ComputeRunningHash(running_hash, data, 5597 running_hash = StringHasher::ComputeRunningHash(running_hash, data,
5563 raw_string->length()); 5598 raw_string->length());
5564 } 5599 }
5565 } 5600 }
5566 5601
5567 return running_hash; 5602 return running_hash;
5568 } 5603 }
5569 } } // namespace v8::internal 5604 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/messages.js ('k') | src/preparser.h » ('j') | test/cctest/test-parsing.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698