Commit 33a37398 authored by adamk's avatar adamk Committed by Commit bot

Fix lazy compilation of eval() under nosnap/--use-strict

When running without a snapshot, the GlobalEval function gets lazy compiled.
By the time we compile it, its name is "eval", which causes the parser to
choke (functions named "eval" aren't allowed in strict mode!).

Instead, we now always skip checking the function name when lazy-parsing,
as the name has already been checked appropriately by the preparser.

Also cleaned up other cases that don't require name checking by introducing
FunctionNameValidity enum and passing appropriate values throughout the
parser and preparser.

This lets us pass an additional 18 test262 tests.

BUG=v8:4198
LOG=n

Review URL: https://codereview.chromium.org/1227093005

Cr-Commit-Position: refs/heads/master@{#29559}
parent 6d32be24
...@@ -871,11 +871,11 @@ Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { ...@@ -871,11 +871,11 @@ Expression* ParserTraits::ParseV8Intrinsic(bool* ok) {
FunctionLiteral* ParserTraits::ParseFunctionLiteral( FunctionLiteral* ParserTraits::ParseFunctionLiteral(
const AstRawString* name, Scanner::Location function_name_location, const AstRawString* name, Scanner::Location function_name_location,
bool name_is_strict_reserved, FunctionKind kind, FunctionNameValidity function_name_validity, FunctionKind kind,
int function_token_position, FunctionLiteral::FunctionType type, int function_token_position, FunctionLiteral::FunctionType type,
FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
return parser_->ParseFunctionLiteral( return parser_->ParseFunctionLiteral(
name, function_name_location, name_is_strict_reserved, kind, name, function_name_location, function_name_validity, kind,
function_token_position, type, arity_restriction, ok); function_token_position, type, arity_restriction, ok);
} }
...@@ -1227,9 +1227,8 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info, ...@@ -1227,9 +1227,8 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info,
shared_info->end_position()); shared_info->end_position());
} else { } else {
result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(), result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(),
false, // Strict mode name already checked. kSkipFunctionNameCheck, shared_info->kind(),
shared_info->kind(), RelocInfo::kNoPosition, RelocInfo::kNoPosition, function_type,
function_type,
FunctionLiteral::NORMAL_ARITY, &ok); FunctionLiteral::NORMAL_ARITY, &ok);
} }
// Make sure the results agree. // Make sure the results agree.
...@@ -2194,7 +2193,9 @@ Statement* Parser::ParseFunctionDeclaration( ...@@ -2194,7 +2193,9 @@ Statement* Parser::ParseFunctionDeclaration(
const AstRawString* name = ParseIdentifierOrStrictReservedWord( const AstRawString* name = ParseIdentifierOrStrictReservedWord(
&is_strict_reserved, CHECK_OK); &is_strict_reserved, CHECK_OK);
FunctionLiteral* fun = FunctionLiteral* fun =
ParseFunctionLiteral(name, scanner()->location(), is_strict_reserved, ParseFunctionLiteral(name, scanner()->location(),
is_strict_reserved ? kFunctionNameIsStrictReserved
: kFunctionNameValidityUnknown,
is_generator ? FunctionKind::kGeneratorFunction is_generator ? FunctionKind::kGeneratorFunction
: FunctionKind::kNormalFunction, : FunctionKind::kNormalFunction,
pos, FunctionLiteral::DECLARATION, pos, FunctionLiteral::DECLARATION,
...@@ -3914,8 +3915,8 @@ void ParserTraits::ReindexLiterals( ...@@ -3914,8 +3915,8 @@ void ParserTraits::ReindexLiterals(
FunctionLiteral* Parser::ParseFunctionLiteral( FunctionLiteral* Parser::ParseFunctionLiteral(
const AstRawString* function_name, Scanner::Location function_name_location, const AstRawString* function_name, Scanner::Location function_name_location,
bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, FunctionNameValidity function_name_validity, FunctionKind kind,
FunctionLiteral::FunctionType function_type, int function_token_pos, FunctionLiteral::FunctionType function_type,
FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
// Function :: // Function ::
// '(' FormalParameterList? ')' '{' FunctionBody '}' // '(' FormalParameterList? ')' '{' FunctionBody '}'
...@@ -4128,9 +4129,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -4128,9 +4129,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// Validate name and parameter names. We can do this only after parsing the // Validate name and parameter names. We can do this only after parsing the
// function, since the function can declare itself strict. // function, since the function can declare itself strict.
CheckFunctionName(language_mode(), kind, function_name, CheckFunctionName(language_mode(), function_name, function_name_validity,
name_is_strict_reserved, function_name_location, function_name_location, CHECK_OK);
CHECK_OK);
const bool use_strict_params = const bool use_strict_params =
!parsing_state.is_simple_parameter_list || IsConciseMethod(kind); !parsing_state.is_simple_parameter_list || IsConciseMethod(kind);
const bool allow_duplicate_parameters = const bool allow_duplicate_parameters =
......
...@@ -794,7 +794,7 @@ class ParserTraits { ...@@ -794,7 +794,7 @@ class ParserTraits {
Expression* ParseV8Intrinsic(bool* ok); Expression* ParseV8Intrinsic(bool* ok);
FunctionLiteral* ParseFunctionLiteral( FunctionLiteral* ParseFunctionLiteral(
const AstRawString* name, Scanner::Location function_name_location, const AstRawString* name, Scanner::Location function_name_location,
bool name_is_strict_reserved, FunctionKind kind, FunctionNameValidity function_name_validity, FunctionKind kind,
int function_token_position, FunctionLiteral::FunctionType type, int function_token_position, FunctionLiteral::FunctionType type,
FunctionLiteral::ArityRestriction arity_restriction, bool* ok); FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
V8_INLINE void SkipLazyFunctionBody( V8_INLINE void SkipLazyFunctionBody(
...@@ -1096,7 +1096,7 @@ class Parser : public ParserBase<ParserTraits> { ...@@ -1096,7 +1096,7 @@ class Parser : public ParserBase<ParserTraits> {
FunctionLiteral* ParseFunctionLiteral( FunctionLiteral* ParseFunctionLiteral(
const AstRawString* name, Scanner::Location function_name_location, const AstRawString* name, Scanner::Location function_name_location,
bool name_is_strict_reserved, FunctionKind kind, FunctionNameValidity function_name_validity, FunctionKind kind,
int function_token_position, FunctionLiteral::FunctionType type, int function_token_position, FunctionLiteral::FunctionType type,
FunctionLiteral::ArityRestriction arity_restriction, bool* ok); FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
......
...@@ -91,11 +91,11 @@ PreParserExpression PreParserTraits::ParseV8Intrinsic(bool* ok) { ...@@ -91,11 +91,11 @@ PreParserExpression PreParserTraits::ParseV8Intrinsic(bool* ok) {
PreParserExpression PreParserTraits::ParseFunctionLiteral( PreParserExpression PreParserTraits::ParseFunctionLiteral(
PreParserIdentifier name, Scanner::Location function_name_location, PreParserIdentifier name, Scanner::Location function_name_location,
bool name_is_strict_reserved, FunctionKind kind, FunctionNameValidity function_name_validity, FunctionKind kind,
int function_token_position, FunctionLiteral::FunctionType type, int function_token_position, FunctionLiteral::FunctionType type,
FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
return pre_parser_->ParseFunctionLiteral( return pre_parser_->ParseFunctionLiteral(
name, function_name_location, name_is_strict_reserved, kind, name, function_name_location, function_name_validity, kind,
function_token_position, type, arity_restriction, ok); function_token_position, type, arity_restriction, ok);
} }
...@@ -419,7 +419,9 @@ PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { ...@@ -419,7 +419,9 @@ PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
bool is_strict_reserved = false; bool is_strict_reserved = false;
Identifier name = ParseIdentifierOrStrictReservedWord( Identifier name = ParseIdentifierOrStrictReservedWord(
&is_strict_reserved, CHECK_OK); &is_strict_reserved, CHECK_OK);
ParseFunctionLiteral(name, scanner()->location(), is_strict_reserved, ParseFunctionLiteral(name, scanner()->location(),
is_strict_reserved ? kFunctionNameIsStrictReserved
: kFunctionNameValidityUnknown,
is_generator ? FunctionKind::kGeneratorFunction is_generator ? FunctionKind::kGeneratorFunction
: FunctionKind::kNormalFunction, : FunctionKind::kNormalFunction,
pos, FunctionLiteral::DECLARATION, pos, FunctionLiteral::DECLARATION,
...@@ -1028,8 +1030,8 @@ PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) { ...@@ -1028,8 +1030,8 @@ PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
PreParser::Expression PreParser::ParseFunctionLiteral( PreParser::Expression PreParser::ParseFunctionLiteral(
Identifier function_name, Scanner::Location function_name_location, Identifier function_name, Scanner::Location function_name_location,
bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, FunctionNameValidity function_name_validity, FunctionKind kind,
FunctionLiteral::FunctionType function_type, int function_token_pos, FunctionLiteral::FunctionType function_type,
FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
// Function :: // Function ::
// '(' FormalParameterList? ')' '{' FunctionBody '}' // '(' FormalParameterList? ')' '{' FunctionBody '}'
...@@ -1072,8 +1074,8 @@ PreParser::Expression PreParser::ParseFunctionLiteral( ...@@ -1072,8 +1074,8 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
// Validate name and parameter names. We can do this only after parsing the // Validate name and parameter names. We can do this only after parsing the
// function, since the function can declare itself strict. // function, since the function can declare itself strict.
CheckFunctionName(language_mode(), kind, function_name, CheckFunctionName(language_mode(), function_name, function_name_validity,
name_is_strict_reserved, function_name_location, CHECK_OK); function_name_location, CHECK_OK);
const bool strict_formal_parameters = const bool strict_formal_parameters =
!parsing_state.is_simple_parameter_list || IsConciseMethod(kind); !parsing_state.is_simple_parameter_list || IsConciseMethod(kind);
const bool allow_duplicate_parameters = const bool allow_duplicate_parameters =
......
...@@ -19,6 +19,14 @@ ...@@ -19,6 +19,14 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
enum FunctionNameValidity {
kFunctionNameIsStrictReserved,
kSkipFunctionNameCheck,
kFunctionNameValidityUnknown
};
// Common base class shared between parser and pre-parser. Traits encapsulate // Common base class shared between parser and pre-parser. Traits encapsulate
// the differences between Parser and PreParser: // the differences between Parser and PreParser:
...@@ -449,13 +457,10 @@ class ParserBase : public Traits { ...@@ -449,13 +457,10 @@ class ParserBase : public Traits {
// Checking the name of a function literal. This has to be done after parsing // Checking the name of a function literal. This has to be done after parsing
// the function, since the function can declare itself strict. // the function, since the function can declare itself strict.
void CheckFunctionName(LanguageMode language_mode, FunctionKind kind, void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name,
IdentifierT function_name, FunctionNameValidity function_name_validity,
bool function_name_is_strict_reserved, const Scanner::Location& function_name_loc, bool* ok) {
const Scanner::Location& function_name_loc, if (function_name_validity == kSkipFunctionNameCheck) return;
bool* ok) {
// Property names are never checked.
if (IsConciseMethod(kind) || IsAccessorFunction(kind)) return;
// The function name needs to be checked in strict mode. // The function name needs to be checked in strict mode.
if (is_sloppy(language_mode)) return; if (is_sloppy(language_mode)) return;
...@@ -465,7 +470,7 @@ class ParserBase : public Traits { ...@@ -465,7 +470,7 @@ class ParserBase : public Traits {
*ok = false; *ok = false;
return; return;
} }
if (function_name_is_strict_reserved) { if (function_name_validity == kFunctionNameIsStrictReserved) {
Traits::ReportMessageAt(function_name_loc, Traits::ReportMessageAt(function_name_loc,
MessageTemplate::kUnexpectedStrictReserved); MessageTemplate::kUnexpectedStrictReserved);
*ok = false; *ok = false;
...@@ -1620,7 +1625,7 @@ class PreParserTraits { ...@@ -1620,7 +1625,7 @@ class PreParserTraits {
PreParserExpression ParseV8Intrinsic(bool* ok); PreParserExpression ParseV8Intrinsic(bool* ok);
PreParserExpression ParseFunctionLiteral( PreParserExpression ParseFunctionLiteral(
PreParserIdentifier name, Scanner::Location function_name_location, PreParserIdentifier name, Scanner::Location function_name_location,
bool name_is_strict_reserved, FunctionKind kind, FunctionNameValidity function_name_validity, FunctionKind kind,
int function_token_position, FunctionLiteral::FunctionType type, int function_token_position, FunctionLiteral::FunctionType type,
FunctionLiteral::ArityRestriction arity_restriction, bool* ok); FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
...@@ -1768,8 +1773,8 @@ class PreParser : public ParserBase<PreParserTraits> { ...@@ -1768,8 +1773,8 @@ class PreParser : public ParserBase<PreParserTraits> {
Expression ParseFunctionLiteral( Expression ParseFunctionLiteral(
Identifier name, Scanner::Location function_name_location, Identifier name, Scanner::Location function_name_location,
bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, FunctionNameValidity function_name_validity, FunctionKind kind,
FunctionLiteral::FunctionType function_type, int function_token_pos, FunctionLiteral::FunctionType function_type,
FunctionLiteral::ArityRestriction arity_restriction, bool* ok); FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
void ParseLazyFunctionLiteralBody(bool* ok, void ParseLazyFunctionLiteralBody(bool* ok,
Scanner::BookmarkScope* bookmark = nullptr); Scanner::BookmarkScope* bookmark = nullptr);
...@@ -2543,9 +2548,8 @@ ParserBase<Traits>::ParsePropertyDefinition( ...@@ -2543,9 +2548,8 @@ ParserBase<Traits>::ParsePropertyDefinition(
if (!in_class) kind = WithObjectLiteralBit(kind); if (!in_class) kind = WithObjectLiteralBit(kind);
value = this->ParseFunctionLiteral( value = this->ParseFunctionLiteral(
name, scanner()->location(), name, scanner()->location(), kSkipFunctionNameCheck, kind,
false, // reserved words are allowed here RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
FunctionLiteral::NORMAL_ARITY, FunctionLiteral::NORMAL_ARITY,
CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
...@@ -2576,9 +2580,8 @@ ParserBase<Traits>::ParsePropertyDefinition( ...@@ -2576,9 +2580,8 @@ ParserBase<Traits>::ParsePropertyDefinition(
FunctionKind kind = FunctionKind::kAccessorFunction; FunctionKind kind = FunctionKind::kAccessorFunction;
if (!in_class) kind = WithObjectLiteralBit(kind); if (!in_class) kind = WithObjectLiteralBit(kind);
typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
name, scanner()->location(), name, scanner()->location(), kSkipFunctionNameCheck, kind,
false, // reserved words are allowed here RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY, is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY,
CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
...@@ -3293,7 +3296,9 @@ ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier, ...@@ -3293,7 +3296,9 @@ ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
function_type = FunctionLiteral::NAMED_EXPRESSION; function_type = FunctionLiteral::NAMED_EXPRESSION;
} }
result = this->ParseFunctionLiteral( result = this->ParseFunctionLiteral(
name, function_name_location, is_strict_reserved_name, name, function_name_location,
is_strict_reserved_name ? kFunctionNameIsStrictReserved
: kFunctionNameValidityUnknown,
is_generator ? FunctionKind::kGeneratorFunction is_generator ? FunctionKind::kGeneratorFunction
: FunctionKind::kNormalFunction, : FunctionKind::kNormalFunction,
function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, function_token_position, function_type, FunctionLiteral::NORMAL_ARITY,
......
...@@ -713,27 +713,6 @@ ...@@ -713,27 +713,6 @@
'intl402/13.2.1_5': [PASS, FAIL], 'intl402/13.2.1_5': [PASS, FAIL],
'intl402/13.3.0_7': [PASS, FAIL], 'intl402/13.3.0_7': [PASS, FAIL],
# These tests fail in nosnap in strict mode
# https://code.google.com/p/v8/issues/detail?id=4198
'built-ins/String/S15.5.1.1_A1_T6': [PASS, FAIL_OK],
'built-ins/eval/S15.1.2.1_A1.1_T1': [PASS, FAIL_OK],
'built-ins/eval/S15.1.2.1_A1.1_T2': [PASS, FAIL_OK],
'built-ins/eval/S15.1.2.1_A4.3': [PASS, FAIL_OK],
'built-ins/eval/S15.1.2.1_A4.4': [PASS, FAIL_OK],
'language/eval-code/10.4.2-1-1': [PASS, FAIL_OK],
'language/eval-code/10.4.2-1-2': [PASS, FAIL_OK],
'language/eval-code/10.4.2-1-3': [PASS, FAIL_OK],
'language/eval-code/10.4.2-1-5': [PASS, FAIL_OK],
'language/eval-code/S10.4.2.1_A1': [PASS, FAIL_OK],
'language/function-code/10.4.3-1-19-s': [PASS, FAIL_OK],
'language/function-code/10.4.3-1-19gs': [PASS, FAIL_OK],
'language/function-code/10.4.3-1-20-s': [PASS, FAIL_OK],
'language/function-code/10.4.3-1-20gs': [PASS, FAIL_OK],
'language/statements/variable/12.2.1-10-s': [PASS, FAIL_OK],
'language/statements/variable/12.2.1-20-s': [PASS, FAIL_OK],
'language/statements/variable/12.2.1-21-s': [PASS, FAIL_OK],
'language/statements/variable/12.2.1-9-s': [PASS, FAIL_OK],
##################### DELIBERATE INCOMPATIBILITIES ##################### ##################### DELIBERATE INCOMPATIBILITIES #####################
'built-ins/Math/exp/S15.8.2.8_A6': [PASS, FAIL_OK], # Math.exp (less precise with --fast-math) 'built-ins/Math/exp/S15.8.2.8_A6': [PASS, FAIL_OK], # Math.exp (less precise with --fast-math)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment