From bb0c22f11c220d42a16728c732e5e2cde80bf1a1 Mon Sep 17 00:00:00 2001 From: "mmaly@chromium.org" Date: Mon, 28 Feb 2011 19:07:02 +0000 Subject: [PATCH] Strict mode - allow function only in SourceElements. Review URL: http://codereview.chromium.org/6598023/ git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6975 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/messages.js | 1 + src/parser.cc | 26 ++++++++++++++++++++++++-- test/mjsunit/strict-mode.js | 8 ++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/messages.js b/src/messages.js index 7c74abc..db33753 100644 --- a/src/messages.js +++ b/src/messages.js @@ -227,6 +227,7 @@ function FormatMessage(message) { strict_delete: ["Delete of an unqualified identifier in strict mode."], strict_delete_property: ["Cannot delete property '", "%0", "' of ", "%1"], strict_const: ["Use of const in strict mode."], + strict_function: ["In strict mode code, functions can only be declared at top level or immediately within another function." ], }; } var message_type = %MessageGetType(message); diff --git a/src/parser.cc b/src/parser.cc index de3bcf9..9fedfc9 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -1106,7 +1106,20 @@ void* Parser::ParseSourceElements(ZoneList* processor, } Scanner::Location token_loc = scanner().peek_location(); - Statement* stat = ParseStatement(NULL, CHECK_OK); + + Statement* stat; + if (peek() == Token::FUNCTION) { + // FunctionDeclaration is only allowed in the context of SourceElements + // (Ecma 262 5th Edition, clause 14): + // SourceElement: + // Statement + // FunctionDeclaration + // Common language extension is to allow function declaration in place + // of any statement. This language extension is disabled in strict mode. + stat = ParseFunctionDeclaration(CHECK_OK); + } else { + stat = ParseStatement(NULL, CHECK_OK); + } if (stat == NULL || stat->IsEmpty()) { directive_prologue = false; // End of directive prologue. @@ -1263,8 +1276,17 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { return result; } - case Token::FUNCTION: + case Token::FUNCTION: { + // In strict mode, FunctionDeclaration is only allowed in the context + // of SourceElements. + if (temp_scope_->StrictMode()) { + ReportMessageAt(scanner().peek_location(), "strict_function", + Vector::empty()); + *ok = false; + return NULL; + } return ParseFunctionDeclaration(ok); + } case Token::NATIVE: return ParseNativeDeclaration(ok); diff --git a/test/mjsunit/strict-mode.js b/test/mjsunit/strict-mode.js index 28a0455..42d8355 100644 --- a/test/mjsunit/strict-mode.js +++ b/test/mjsunit/strict-mode.js @@ -285,6 +285,14 @@ CheckStrictMode("const x = 0;", SyntaxError); CheckStrictMode("for (const x = 0; false;) {}", SyntaxError); CheckStrictMode("function strict() { const x = 0; }", SyntaxError); +// Strict mode only allows functions in SourceElements +CheckStrictMode("if (true) { function invalid() {} }", SyntaxError); +CheckStrictMode("for (;false;) { function invalid() {} }", SyntaxError); +CheckStrictMode("{ function invalid() {} }", SyntaxError); +CheckStrictMode("try { function invalid() {} } catch(e) {}", SyntaxError); +CheckStrictMode("try { } catch(e) { function invalid() {} }", SyntaxError); +CheckStrictMode("function outer() {{ function invalid() {} }}", SyntaxError); + // Delete of an unqualified identifier CheckStrictMode("delete unqualified;", SyntaxError); CheckStrictMode("function strict() { delete unqualified; }", SyntaxError); -- 2.7.4