Make "native" not a keyword.
We now only recognize "native function" when it occurs in extension scripts (parsing with a non-NULL extension), and only if there is no line-terminator between "native" and "function" (so that it would otherwise be a Syntax Error). Preparsing never recognizes native functions, which is acceptable since we never preparse extension scripts (because we don't allow lazy functions anyway). BUG=v8:1097 Review URL: http://codereview.chromium.org/7206020 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8326 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
b789cb8c94
commit
480ec43c4e
@ -159,6 +159,7 @@ inline Heap* _inline_get_heap_();
|
||||
V(function_symbol, "function") \
|
||||
V(length_symbol, "length") \
|
||||
V(name_symbol, "name") \
|
||||
V(native_symbol, "native") \
|
||||
V(number_symbol, "number") \
|
||||
V(Number_symbol, "Number") \
|
||||
V(nan_symbol, "NaN") \
|
||||
|
@ -1269,9 +1269,6 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
|
||||
return ParseFunctionDeclaration(ok);
|
||||
}
|
||||
|
||||
case Token::NATIVE:
|
||||
return ParseNativeDeclaration(ok);
|
||||
|
||||
case Token::DEBUGGER:
|
||||
stmt = ParseDebuggerStatement(ok);
|
||||
break;
|
||||
@ -1392,13 +1389,6 @@ VariableProxy* Parser::Declare(Handle<String> name,
|
||||
// declaration is resolved by looking up the function through a
|
||||
// callback provided by the extension.
|
||||
Statement* Parser::ParseNativeDeclaration(bool* ok) {
|
||||
if (extension_ == NULL) {
|
||||
ReportUnexpectedToken(Token::NATIVE);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Expect(Token::NATIVE, CHECK_OK);
|
||||
Expect(Token::FUNCTION, CHECK_OK);
|
||||
Handle<String> name = ParseIdentifier(CHECK_OK);
|
||||
Expect(Token::LPAREN, CHECK_OK);
|
||||
@ -1751,7 +1741,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
|
||||
// Identifier ':' Statement
|
||||
bool starts_with_idenfifier = peek_any_identifier();
|
||||
Expression* expr = ParseExpression(true, CHECK_OK);
|
||||
if (peek() == Token::COLON && starts_with_idenfifier && expr &&
|
||||
if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
|
||||
expr->AsVariableProxy() != NULL &&
|
||||
!expr->AsVariableProxy()->is_this()) {
|
||||
// Expression is a single identifier, and not, e.g., a parenthesized
|
||||
@ -1781,6 +1771,19 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
|
||||
return ParseStatement(labels, ok);
|
||||
}
|
||||
|
||||
// If we have an extension, we allow a native function declaration.
|
||||
// A native function declaration starts with "native function" with
|
||||
// no line-terminator between the two words.
|
||||
if (extension_ != NULL &&
|
||||
peek() == Token::FUNCTION &&
|
||||
!scanner().has_line_terminator_before_next() &&
|
||||
expr != NULL &&
|
||||
expr->AsVariableProxy() != NULL &&
|
||||
expr->AsVariableProxy()->name()->Equals(
|
||||
isolate()->heap()->native_symbol())) {
|
||||
return ParseNativeDeclaration(ok);
|
||||
}
|
||||
|
||||
// Parsed expression statement.
|
||||
ExpectSemicolon(CHECK_OK);
|
||||
return new(zone()) ExpressionStatement(expr);
|
||||
@ -4982,6 +4985,7 @@ bool ParserApi::Parse(CompilationInfo* info) {
|
||||
Parser parser(script, true, NULL, NULL);
|
||||
result = parser.ParseLazy(info);
|
||||
} else {
|
||||
// Whether we allow %identifier(..) syntax.
|
||||
bool allow_natives_syntax =
|
||||
info->allows_natives_syntax() || FLAG_allow_natives_syntax;
|
||||
ScriptDataImpl* pre_data = info->pre_parse_data();
|
||||
|
@ -209,9 +209,6 @@ PreParser::Statement PreParser::ParseStatement(bool* ok) {
|
||||
case i::Token::FUNCTION:
|
||||
return ParseFunctionDeclaration(ok);
|
||||
|
||||
case i::Token::NATIVE:
|
||||
return ParseNativeDeclaration(ok);
|
||||
|
||||
case i::Token::DEBUGGER:
|
||||
return ParseDebuggerStatement(ok);
|
||||
|
||||
@ -246,29 +243,6 @@ PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
|
||||
}
|
||||
|
||||
|
||||
// Language extension which is only enabled for source files loaded
|
||||
// through the API's extension mechanism. A native function
|
||||
// declaration is resolved by looking up the function through a
|
||||
// callback provided by the extension.
|
||||
PreParser::Statement PreParser::ParseNativeDeclaration(bool* ok) {
|
||||
Expect(i::Token::NATIVE, CHECK_OK);
|
||||
Expect(i::Token::FUNCTION, CHECK_OK);
|
||||
ParseIdentifier(CHECK_OK);
|
||||
Expect(i::Token::LPAREN, CHECK_OK);
|
||||
bool done = (peek() == i::Token::RPAREN);
|
||||
while (!done) {
|
||||
ParseIdentifier(CHECK_OK);
|
||||
done = (peek() == i::Token::RPAREN);
|
||||
if (!done) {
|
||||
Expect(i::Token::COMMA, CHECK_OK);
|
||||
}
|
||||
}
|
||||
Expect(i::Token::RPAREN, CHECK_OK);
|
||||
Expect(i::Token::SEMICOLON, CHECK_OK);
|
||||
return Statement::Default();
|
||||
}
|
||||
|
||||
|
||||
PreParser::Statement PreParser::ParseBlock(bool* ok) {
|
||||
// Block ::
|
||||
// '{' Statement* '}'
|
||||
@ -362,8 +336,9 @@ PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
|
||||
// Identifier ':' Statement
|
||||
|
||||
Expression expr = ParseExpression(true, CHECK_OK);
|
||||
if (peek() == i::Token::COLON && expr.IsRawIdentifier()) {
|
||||
if (!strict_mode() || !expr.AsIdentifier().IsFutureReserved()) {
|
||||
if (expr.IsRawIdentifier()) {
|
||||
if (peek() == i::Token::COLON &&
|
||||
(!strict_mode() || !expr.AsIdentifier().IsFutureReserved())) {
|
||||
Consume(i::Token::COLON);
|
||||
i::Scanner::Location start_location = scanner_->peek_location();
|
||||
Statement statement = ParseStatement(CHECK_OK);
|
||||
@ -375,6 +350,9 @@ PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
|
||||
}
|
||||
return Statement::Default();
|
||||
}
|
||||
// Preparsing is disabled for extensions (because the extension details
|
||||
// aren't passed to lazily compiled functions), so we don't
|
||||
// accept "native function" in the preparser.
|
||||
}
|
||||
// Parsed expression statement.
|
||||
ExpectSemicolon(CHECK_OK);
|
||||
|
@ -373,7 +373,6 @@ class PreParser {
|
||||
SourceElements ParseSourceElements(int end_token, bool* ok);
|
||||
Statement ParseStatement(bool* ok);
|
||||
Statement ParseFunctionDeclaration(bool* ok);
|
||||
Statement ParseNativeDeclaration(bool* ok);
|
||||
Statement ParseBlock(bool* ok);
|
||||
Statement ParseVariableStatement(bool* ok);
|
||||
Statement ParseVariableDeclarations(bool accept_IN, int* num_decl, bool* ok);
|
||||
|
@ -897,7 +897,6 @@ void KeywordMatcher::Step(unibrow::uchar input) {
|
||||
if (MatchKeywordStart(input, "instanceof", 2, Token::INSTANCEOF)) return;
|
||||
break;
|
||||
case N:
|
||||
if (MatchKeywordStart(input, "native", 1, Token::NATIVE)) return;
|
||||
if (MatchKeywordStart(input, "new", 1, Token::NEW)) return;
|
||||
if (MatchKeywordStart(input, "null", 1, Token::NULL_LITERAL)) return;
|
||||
break;
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2006-2008 the V8 project authors. All rights reserved.
|
||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
@ -168,7 +168,6 @@ namespace internal {
|
||||
/* Future reserved words (ECMA-262, section 7.6.1.2). */ \
|
||||
T(FUTURE_RESERVED_WORD, NULL, 0) \
|
||||
K(CONST, "const", 0) \
|
||||
K(NATIVE, "native", 0) \
|
||||
\
|
||||
/* Illegal token - not able to scan. */ \
|
||||
T(ILLEGAL, "ILLEGAL", 0) \
|
||||
|
@ -253,7 +253,7 @@ TEST(StandAlonePreParser) {
|
||||
"{label: 42}",
|
||||
"var x = 42;",
|
||||
"function foo(x, y) { return x + y; }",
|
||||
"native function foo(); return %ArgleBargle(glop);",
|
||||
"%ArgleBargle(glop);",
|
||||
"var x = new new Function('this.x = 42');",
|
||||
NULL
|
||||
};
|
||||
|
@ -105,7 +105,7 @@ assertFalse(a.a.b === b.a.b);
|
||||
assertFalse(a.a.c === b.a.c);
|
||||
|
||||
|
||||
// Test keywords valid as property names in initializers and dot-access.
|
||||
// Test keywords are valid as property names in initializers and dot-access.
|
||||
var keywords = [
|
||||
"break",
|
||||
"case",
|
||||
@ -124,7 +124,6 @@ var keywords = [
|
||||
"if",
|
||||
"in",
|
||||
"instanceof",
|
||||
"native",
|
||||
"new",
|
||||
"null",
|
||||
"return",
|
||||
@ -137,7 +136,7 @@ var keywords = [
|
||||
"var",
|
||||
"void",
|
||||
"while",
|
||||
"with",
|
||||
"with"
|
||||
];
|
||||
|
||||
function testKeywordProperty(keyword) {
|
||||
|
@ -466,10 +466,6 @@ js1_5/extensions/regress-356378: FAIL_OK
|
||||
js1_5/extensions/regress-452178: FAIL_OK
|
||||
|
||||
|
||||
# 'native' *is* a keyword in V8.
|
||||
js1_5/Regress/regress-240317: FAIL_OK
|
||||
|
||||
|
||||
# Requires Mozilla-specific strict mode or options() function.
|
||||
ecma_3/Object/8.6.1-01: FAIL_OK
|
||||
js1_5/Exceptions/regress-315147: FAIL_OK
|
||||
|
@ -89,22 +89,20 @@ S7.8.4_A7.4_T1: FAIL_OK
|
||||
S7.8.4_A4.3_T5: FAIL_OK
|
||||
S7.8.4_A7.2_T5: FAIL_OK
|
||||
|
||||
# We allow some keywords to be used as identifiers
|
||||
S7.5.3_A1.26: FAIL_OK
|
||||
S7.5.3_A1.18: FAIL_OK
|
||||
S7.5.3_A1.27: FAIL_OK
|
||||
# We allow some keywords to be used as identifiers.
|
||||
S7.5.3_A1.5: FAIL_OK
|
||||
S7.5.3_A1.9: FAIL_OK
|
||||
S7.5.3_A1.10: FAIL_OK
|
||||
S7.5.3_A1.11: FAIL_OK
|
||||
# native
|
||||
S7.5.3_A1.20: FAIL_OK
|
||||
S7.5.3_A1.15: FAIL_OK
|
||||
S7.5.3_A1.16: FAIL_OK
|
||||
S7.5.3_A1.18: FAIL_OK
|
||||
S7.5.3_A1.21: FAIL_OK
|
||||
S7.5.3_A1.22: FAIL_OK
|
||||
S7.5.3_A1.23: FAIL_OK
|
||||
S7.5.3_A1.15: FAIL_OK
|
||||
S7.5.3_A1.24: FAIL_OK
|
||||
S7.5.3_A1.16: FAIL_OK
|
||||
S7.5.3_A1.26: FAIL_OK
|
||||
S7.5.3_A1.27: FAIL_OK
|
||||
|
||||
# This checks for non-262 behavior
|
||||
S12.6.4_A14_T1: PASS || FAIL_OK
|
||||
|
Loading…
Reference in New Issue
Block a user