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

Unified Diff: src/parser.cc

Issue 1084983002: [strong] Implement static restrictions on switch statement (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: cl feedback 3 Created 5 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index 77c98b77e4c0cd6aadb003ec1965f82d879c30c8..597951c09325e4adbdf04bfc6797cc73ac914b73 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -1819,13 +1819,23 @@ Statement* Parser::ParseSubStatement(ZoneList<const AstRawString*>* labels,
return ParseForStatement(labels, ok);
case Token::CONTINUE:
- return ParseContinueStatement(ok);
-
case Token::BREAK:
- return ParseBreakStatement(labels, ok);
-
case Token::RETURN:
- return ParseReturnStatement(ok);
+ case Token::THROW:
+ case Token::TRY: {
+ // These statements must have their labels preserved in an enclosing
+ // block
+ if (labels == NULL) {
+ return ParseStatementAsUnlabelled(labels, ok);
+ } else {
+ Block* result =
+ factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition);
+ Target target(&this->target_stack_, result);
+ Statement* statement = ParseStatementAsUnlabelled(labels, CHECK_OK);
+ if (result) result->AddStatement(statement, zone());
+ return result;
+ }
+ }
case Token::WITH:
return ParseWithStatement(labels, ok);
@@ -1833,23 +1843,6 @@ Statement* Parser::ParseSubStatement(ZoneList<const AstRawString*>* labels,
case Token::SWITCH:
return ParseSwitchStatement(labels, ok);
- case Token::THROW:
- return ParseThrowStatement(ok);
-
- case Token::TRY: {
- // NOTE: It is somewhat complicated to have labels on
- // try-statements. When breaking out of a try-finally statement,
- // one must take great care not to treat it as a
- // fall-through. It is much easier just to wrap the entire
- // try-statement in a statement block and put the labels there
- Block* result =
- factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition);
- Target target(&this->target_stack_, result);
- TryStatement* statement = ParseTryStatement(CHECK_OK);
- if (result) result->AddStatement(statement, zone());
- return result;
- }
-
case Token::FUNCTION: {
// FunctionDeclaration is only allowed in the context of SourceElements
// (Ecma 262 5th Edition, clause 14):
@@ -1890,6 +1883,30 @@ Statement* Parser::ParseSubStatement(ZoneList<const AstRawString*>* labels,
}
}
+Statement* Parser::ParseStatementAsUnlabelled(
+ ZoneList<const AstRawString*>* labels, bool* ok) {
+ switch (peek()) {
+ case Token::CONTINUE:
+ return ParseContinueStatement(ok);
+
+ case Token::BREAK:
+ return ParseBreakStatement(labels, ok);
+
+ case Token::RETURN:
+ return ParseReturnStatement(ok);
+
+ case Token::THROW:
+ return ParseThrowStatement(ok);
+
+ case Token::TRY:
+ return ParseTryStatement(ok);
+
+ default:
+ UNREACHABLE();
+ return NULL;
+ }
+}
+
VariableProxy* Parser::NewUnresolved(const AstRawString* name,
VariableMode mode) {
@@ -2845,13 +2862,19 @@ CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
int pos = position();
ZoneList<Statement*>* statements =
new(zone()) ZoneList<Statement*>(5, zone());
+ Statement* stat = NULL;
while (peek() != Token::CASE &&
peek() != Token::DEFAULT &&
peek() != Token::RBRACE) {
- Statement* stat = ParseStatementListItem(CHECK_OK);
+ stat = ParseStatementListItem(CHECK_OK);
statements->Add(stat, zone());
}
-
+ if (is_strong(language_mode()) && stat != NULL && !stat->IsJump() &&
+ peek() != Token::RBRACE) {
+ ReportMessageAt(scanner()->location(), "strong_switch_fallthrough");
+ *ok = false;
+ return NULL;
+ }
return factory()->NewCaseClause(label, statements, pos);
}
@@ -4468,7 +4491,6 @@ void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
// ----------------------------------------------------------------------------
// Parser support
-
bool Parser::TargetStackContainsLabel(const AstRawString* label) {
for (Target* t = target_stack_; t != NULL; t = t->previous()) {
if (ContainsLabel(t->statement()->labels(), label)) return true;
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698