Make "native" not a keyword.
authorlrn@chromium.org <lrn@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 20 Jun 2011 10:20:57 +0000 (10:20 +0000)
committerlrn@chromium.org <lrn@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 20 Jun 2011 10:20:57 +0000 (10:20 +0000)
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

src/heap.h
src/parser.cc
src/preparser.cc
src/preparser.h
src/scanner-base.cc
src/token.h
test/cctest/test-parsing.cc
test/mjsunit/object-literal.js
test/mozilla/mozilla.status
test/sputnik/sputnik.status

index 8e8d877..4e7846d 100644 (file)
@@ -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")                                                   \
index dc669a8..1318dc9 100644 (file)
@@ -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();
index 0f87d10..818f02a 100644 (file)
@@ -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);
index 285cf03..afd3bc3 100644 (file)
@@ -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);
index 0e10191..89591ba 100644 (file)
@@ -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;
index a0afbc1..930d525 100644 (file)
@@ -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)                                              \
index 39856b6..08f117b 100755 (executable)
@@ -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
   };
index 5dcbb3b..3d0b33b 100644 (file)
@@ -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) {
index a748c9f..45911f1 100644 (file)
@@ -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
index 7426ac2..2fe9418 100644 (file)
@@ -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