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) {
FunctionLiteral* ParserTraits::ParseFunctionLiteral(
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,
FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
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);
}
......@@ -1227,9 +1227,8 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info,
shared_info->end_position());
} else {
result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(),
false, // Strict mode name already checked.
shared_info->kind(), RelocInfo::kNoPosition,
function_type,
kSkipFunctionNameCheck, shared_info->kind(),
RelocInfo::kNoPosition, function_type,
FunctionLiteral::NORMAL_ARITY, &ok);
}
// Make sure the results agree.
......@@ -2194,7 +2193,9 @@ Statement* Parser::ParseFunctionDeclaration(
const AstRawString* name = ParseIdentifierOrStrictReservedWord(
&is_strict_reserved, CHECK_OK);
FunctionLiteral* fun =
ParseFunctionLiteral(name, scanner()->location(), is_strict_reserved,
ParseFunctionLiteral(name, scanner()->location(),
is_strict_reserved ? kFunctionNameIsStrictReserved
: kFunctionNameValidityUnknown,
is_generator ? FunctionKind::kGeneratorFunction
: FunctionKind::kNormalFunction,
pos, FunctionLiteral::DECLARATION,
......@@ -3914,8 +3915,8 @@ void ParserTraits::ReindexLiterals(
FunctionLiteral* Parser::ParseFunctionLiteral(
const AstRawString* function_name, Scanner::Location function_name_location,
bool name_is_strict_reserved, FunctionKind kind, int function_token_pos,
FunctionLiteral::FunctionType function_type,
FunctionNameValidity function_name_validity, FunctionKind kind,
int function_token_pos, FunctionLiteral::FunctionType function_type,
FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
// Function ::
// '(' FormalParameterList? ')' '{' FunctionBody '}'
......@@ -4128,9 +4129,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// Validate name and parameter names. We can do this only after parsing the
// function, since the function can declare itself strict.
CheckFunctionName(language_mode(), kind, function_name,
name_is_strict_reserved, function_name_location,
CHECK_OK);
CheckFunctionName(language_mode(), function_name, function_name_validity,
function_name_location, CHECK_OK);
const bool use_strict_params =
!parsing_state.is_simple_parameter_list || IsConciseMethod(kind);
const bool allow_duplicate_parameters =
......
......@@ -794,7 +794,7 @@ class ParserTraits {
Expression* ParseV8Intrinsic(bool* ok);
FunctionLiteral* ParseFunctionLiteral(
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,
FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
V8_INLINE void SkipLazyFunctionBody(
......@@ -1096,7 +1096,7 @@ class Parser : public ParserBase<ParserTraits> {
FunctionLiteral* ParseFunctionLiteral(
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,
FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
......
......@@ -91,11 +91,11 @@ PreParserExpression PreParserTraits::ParseV8Intrinsic(bool* ok) {
PreParserExpression PreParserTraits::ParseFunctionLiteral(
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,
FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
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);
}
......@@ -419,7 +419,9 @@ PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
bool is_strict_reserved = false;
Identifier name = ParseIdentifierOrStrictReservedWord(
&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
: FunctionKind::kNormalFunction,
pos, FunctionLiteral::DECLARATION,
......@@ -1028,8 +1030,8 @@ PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
PreParser::Expression PreParser::ParseFunctionLiteral(
Identifier function_name, Scanner::Location function_name_location,
bool name_is_strict_reserved, FunctionKind kind, int function_token_pos,
FunctionLiteral::FunctionType function_type,
FunctionNameValidity function_name_validity, FunctionKind kind,
int function_token_pos, FunctionLiteral::FunctionType function_type,
FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
// Function ::
// '(' FormalParameterList? ')' '{' FunctionBody '}'
......@@ -1072,8 +1074,8 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
// Validate name and parameter names. We can do this only after parsing the
// function, since the function can declare itself strict.
CheckFunctionName(language_mode(), kind, function_name,
name_is_strict_reserved, function_name_location, CHECK_OK);
CheckFunctionName(language_mode(), function_name, function_name_validity,
function_name_location, CHECK_OK);
const bool strict_formal_parameters =
!parsing_state.is_simple_parameter_list || IsConciseMethod(kind);
const bool allow_duplicate_parameters =
......
......@@ -19,6 +19,14 @@
namespace v8 {
namespace internal {
enum FunctionNameValidity {
kFunctionNameIsStrictReserved,
kSkipFunctionNameCheck,
kFunctionNameValidityUnknown
};
// Common base class shared between parser and pre-parser. Traits encapsulate
// the differences between Parser and PreParser:
......@@ -449,13 +457,10 @@ class ParserBase : public Traits {
// Checking the name of a function literal. This has to be done after parsing
// the function, since the function can declare itself strict.
void CheckFunctionName(LanguageMode language_mode, FunctionKind kind,
IdentifierT function_name,
bool function_name_is_strict_reserved,
const Scanner::Location& function_name_loc,
bool* ok) {
// Property names are never checked.
if (IsConciseMethod(kind) || IsAccessorFunction(kind)) return;
void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name,
FunctionNameValidity function_name_validity,
const Scanner::Location& function_name_loc, bool* ok) {
if (function_name_validity == kSkipFunctionNameCheck) return;
// The function name needs to be checked in strict mode.
if (is_sloppy(language_mode)) return;
......@@ -465,7 +470,7 @@ class ParserBase : public Traits {
*ok = false;
return;
}
if (function_name_is_strict_reserved) {
if (function_name_validity == kFunctionNameIsStrictReserved) {
Traits::ReportMessageAt(function_name_loc,
MessageTemplate::kUnexpectedStrictReserved);
*ok = false;
......@@ -1620,7 +1625,7 @@ class PreParserTraits {
PreParserExpression ParseV8Intrinsic(bool* ok);
PreParserExpression ParseFunctionLiteral(
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,
FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
......@@ -1768,8 +1773,8 @@ class PreParser : public ParserBase<PreParserTraits> {
Expression ParseFunctionLiteral(
Identifier name, Scanner::Location function_name_location,
bool name_is_strict_reserved, FunctionKind kind, int function_token_pos,
FunctionLiteral::FunctionType function_type,
FunctionNameValidity function_name_validity, FunctionKind kind,
int function_token_pos, FunctionLiteral::FunctionType function_type,
FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
void ParseLazyFunctionLiteralBody(bool* ok,
Scanner::BookmarkScope* bookmark = nullptr);
......@@ -2543,9 +2548,8 @@ ParserBase<Traits>::ParsePropertyDefinition(
if (!in_class) kind = WithObjectLiteralBit(kind);
value = this->ParseFunctionLiteral(
name, scanner()->location(),
false, // reserved words are allowed here
kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
name, scanner()->location(), kSkipFunctionNameCheck, kind,
RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
FunctionLiteral::NORMAL_ARITY,
CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
......@@ -2576,9 +2580,8 @@ ParserBase<Traits>::ParsePropertyDefinition(
FunctionKind kind = FunctionKind::kAccessorFunction;
if (!in_class) kind = WithObjectLiteralBit(kind);
typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
name, scanner()->location(),
false, // reserved words are allowed here
kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
name, scanner()->location(), kSkipFunctionNameCheck, kind,
RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY,
CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
......@@ -3293,7 +3296,9 @@ ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
function_type = FunctionLiteral::NAMED_EXPRESSION;
}
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
: FunctionKind::kNormalFunction,
function_token_position, function_type, FunctionLiteral::NORMAL_ARITY,
......
......@@ -713,27 +713,6 @@
'intl402/13.2.1_5': [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 #####################
'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