Title: [89109] trunk
Revision
89109
Author
[email protected]
Date
2011-06-16 20:17:11 -0700 (Thu, 16 Jun 2011)

Log Message

https://bugs.webkit.org/show_bug.cgi?id=53014
ES5 strict mode keyword restrictions aren't implemented

Reviewed by Oliver Hunt.

The following are future restricted words is strict mode code:
    implements, interface, let, package, private, protected, public, static, yield

Source/_javascript_Core: 

* parser/JSParser.h:
    - Add RESERVED_IF_STRICT token.
* parser/Keywords.table:
    - Add new future restricted words.
* parser/Lexer.cpp:
(JSC::Lexer::parseIdentifier):
    - Check for RESERVED_IF_STRICT; in nonstrict code this is converted to IDENT.
(JSC::Lexer::lex):
    - Pass strictMode flag to parseIdentifier.
* parser/Lexer.h:
    - parseIdentifier needs a strictMode flag.
* runtime/CommonIdentifiers.h:
    - Add identifiers for new reserved words.

LayoutTests: 

* fast/js/keywords-and-reserved_words-expected.txt: Added.
* fast/js/keywords-and-reserved_words.html: Added.
* fast/js/script-tests/keywords-and-reserved_words.js: Added.
(isKeyword):
(isStrictKeyword):
(classifyIdentifier):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (89108 => 89109)


--- trunk/LayoutTests/ChangeLog	2011-06-17 03:10:36 UTC (rev 89108)
+++ trunk/LayoutTests/ChangeLog	2011-06-17 03:17:11 UTC (rev 89109)
@@ -1,3 +1,20 @@
+2011-06-16  Gavin Barraclough  <[email protected]>
+
+        Reviewed by Oliver Hunt.
+
+        https://bugs.webkit.org/show_bug.cgi?id=53014
+        ES5 strict mode keyword restrictions aren't implemented
+
+        The following are future restricted words is strict mode code:
+            implements, interface, let, package, private, protected, public, static, yield
+
+        * fast/js/keywords-and-reserved_words-expected.txt: Added.
+        * fast/js/keywords-and-reserved_words.html: Added.
+        * fast/js/script-tests/keywords-and-reserved_words.js: Added.
+        (isKeyword):
+        (isStrictKeyword):
+        (classifyIdentifier):
+
 2011-06-16  Yuta Kitamura  <[email protected]>
 
         Unreviewed, rolling out r89107.

Added: trunk/LayoutTests/fast/js/keywords-and-reserved_words-expected.txt (0 => 89109)


--- trunk/LayoutTests/fast/js/keywords-and-reserved_words-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/js/keywords-and-reserved_words-expected.txt	2011-06-17 03:17:11 UTC (rev 89109)
@@ -0,0 +1,73 @@
+This test verifies that keywords and reserved words match those specified in ES5 section 7.6.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS classifyIdentifier("x") is "identifier"
+PASS classifyIdentifier("id") is "identifier"
+PASS classifyIdentifier("identifier") is "identifier"
+PASS classifyIdentifier("keyword") is "identifier"
+PASS classifyIdentifier("strict") is "identifier"
+PASS classifyIdentifier("use") is "identifier"
+PASS classifyIdentifier("abstract") is "identifier"
+PASS classifyIdentifier("boolean") is "identifier"
+PASS classifyIdentifier("byte") is "identifier"
+PASS classifyIdentifier("char") is "identifier"
+PASS classifyIdentifier("double") is "identifier"
+PASS classifyIdentifier("final") is "identifier"
+PASS classifyIdentifier("float") is "identifier"
+PASS classifyIdentifier("goto") is "identifier"
+PASS classifyIdentifier("int") is "identifier"
+PASS classifyIdentifier("long") is "identifier"
+PASS classifyIdentifier("native") is "identifier"
+PASS classifyIdentifier("short") is "identifier"
+PASS classifyIdentifier("synchronized") is "identifier"
+PASS classifyIdentifier("throws") is "identifier"
+PASS classifyIdentifier("transient") is "identifier"
+PASS classifyIdentifier("volatile") is "identifier"
+PASS classifyIdentifier("break") is "keyword"
+PASS classifyIdentifier("case") is "keyword"
+PASS classifyIdentifier("catch") is "keyword"
+PASS classifyIdentifier("continue") is "keyword"
+PASS classifyIdentifier("debugger") is "keyword"
+PASS classifyIdentifier("default") is "keyword"
+PASS classifyIdentifier("delete") is "keyword"
+PASS classifyIdentifier("do") is "keyword"
+PASS classifyIdentifier("else") is "keyword"
+PASS classifyIdentifier("finally") is "keyword"
+PASS classifyIdentifier("for") is "keyword"
+PASS classifyIdentifier("function") is "keyword"
+PASS classifyIdentifier("if") is "keyword"
+PASS classifyIdentifier("in") is "keyword"
+PASS classifyIdentifier("instanceof") is "keyword"
+PASS classifyIdentifier("new") is "keyword"
+PASS classifyIdentifier("return") is "keyword"
+PASS classifyIdentifier("switch") is "keyword"
+PASS classifyIdentifier("this") is "keyword"
+PASS classifyIdentifier("throw") is "keyword"
+PASS classifyIdentifier("try") is "keyword"
+PASS classifyIdentifier("typeof") is "keyword"
+PASS classifyIdentifier("var") is "keyword"
+PASS classifyIdentifier("void") is "keyword"
+PASS classifyIdentifier("while") is "keyword"
+PASS classifyIdentifier("with") is "keyword"
+PASS classifyIdentifier("class") is "keyword"
+PASS classifyIdentifier("const") is "keyword"
+PASS classifyIdentifier("enum") is "keyword"
+PASS classifyIdentifier("export") is "keyword"
+PASS classifyIdentifier("extends") is "keyword"
+PASS classifyIdentifier("import") is "keyword"
+PASS classifyIdentifier("super") is "keyword"
+PASS classifyIdentifier("implements") is "strict"
+PASS classifyIdentifier("interface") is "strict"
+PASS classifyIdentifier("let") is "strict"
+PASS classifyIdentifier("package") is "strict"
+PASS classifyIdentifier("private") is "strict"
+PASS classifyIdentifier("protected") is "strict"
+PASS classifyIdentifier("public") is "strict"
+PASS classifyIdentifier("static") is "strict"
+PASS classifyIdentifier("yield") is "strict"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/js/keywords-and-reserved_words.html (0 => 89109)


--- trunk/LayoutTests/fast/js/keywords-and-reserved_words.html	                        (rev 0)
+++ trunk/LayoutTests/fast/js/keywords-and-reserved_words.html	2011-06-17 03:17:11 UTC (rev 89109)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href=""
+<script src=""
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/fast/js/script-tests/keywords-and-reserved_words.js (0 => 89109)


--- trunk/LayoutTests/fast/js/script-tests/keywords-and-reserved_words.js	                        (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/keywords-and-reserved_words.js	2011-06-17 03:17:11 UTC (rev 89109)
@@ -0,0 +1,115 @@
+description(
+"This test verifies that keywords and reserved words match those specified in ES5 section 7.6."
+);
+
+function isKeyword(x)
+{
+    try {
+        eval("var "+x+";");
+    } catch(e) {
+        return true;
+    }
+    
+    return false;
+}
+
+function isStrictKeyword(x)
+{
+    try {
+        eval("'use strict'; var "+x+";");
+    } catch(e) {
+        return true;
+    }
+    
+    return false;
+}
+
+function classifyIdentifier(x)
+{
+    if (isKeyword(x)) {
+        // All non-strict keywords are also keywords in strict code.
+        if (!isStrictKeyword(x))
+            return "ERROR";
+        return "keyword";
+    }
+
+    // Check for strict mode future reserved words.
+    if (isStrictKeyword(x))
+        return "strict";
+
+    return "identifier";
+}
+
+// Not keywords - these are all just identifiers.
+shouldBe('classifyIdentifier("x")', '"identifier"');
+shouldBe('classifyIdentifier("id")', '"identifier"');
+shouldBe('classifyIdentifier("identifier")', '"identifier"');
+shouldBe('classifyIdentifier("keyword")', '"identifier"');
+shouldBe('classifyIdentifier("strict")', '"identifier"');
+shouldBe('classifyIdentifier("use")', '"identifier"');
+// These are identifiers that we used to treat as keywords!
+shouldBe('classifyIdentifier("abstract")', '"identifier"');
+shouldBe('classifyIdentifier("boolean")', '"identifier"');
+shouldBe('classifyIdentifier("byte")', '"identifier"');
+shouldBe('classifyIdentifier("char")', '"identifier"');
+shouldBe('classifyIdentifier("double")', '"identifier"');
+shouldBe('classifyIdentifier("final")', '"identifier"');
+shouldBe('classifyIdentifier("float")', '"identifier"');
+shouldBe('classifyIdentifier("goto")', '"identifier"');
+shouldBe('classifyIdentifier("int")', '"identifier"');
+shouldBe('classifyIdentifier("long")', '"identifier"');
+shouldBe('classifyIdentifier("native")', '"identifier"');
+shouldBe('classifyIdentifier("short")', '"identifier"');
+shouldBe('classifyIdentifier("synchronized")', '"identifier"');
+shouldBe('classifyIdentifier("throws")', '"identifier"');
+shouldBe('classifyIdentifier("transient")', '"identifier"');
+shouldBe('classifyIdentifier("volatile")', '"identifier"');
+
+// Keywords.
+shouldBe('classifyIdentifier("break")', '"keyword"');
+shouldBe('classifyIdentifier("case")', '"keyword"');
+shouldBe('classifyIdentifier("catch")', '"keyword"');
+shouldBe('classifyIdentifier("continue")', '"keyword"');
+shouldBe('classifyIdentifier("debugger")', '"keyword"');
+shouldBe('classifyIdentifier("default")', '"keyword"');
+shouldBe('classifyIdentifier("delete")', '"keyword"');
+shouldBe('classifyIdentifier("do")', '"keyword"');
+shouldBe('classifyIdentifier("else")', '"keyword"');
+shouldBe('classifyIdentifier("finally")', '"keyword"');
+shouldBe('classifyIdentifier("for")', '"keyword"');
+shouldBe('classifyIdentifier("function")', '"keyword"');
+shouldBe('classifyIdentifier("if")', '"keyword"');
+shouldBe('classifyIdentifier("in")', '"keyword"');
+shouldBe('classifyIdentifier("instanceof")', '"keyword"');
+shouldBe('classifyIdentifier("new")', '"keyword"');
+shouldBe('classifyIdentifier("return")', '"keyword"');
+shouldBe('classifyIdentifier("switch")', '"keyword"');
+shouldBe('classifyIdentifier("this")', '"keyword"');
+shouldBe('classifyIdentifier("throw")', '"keyword"');
+shouldBe('classifyIdentifier("try")', '"keyword"');
+shouldBe('classifyIdentifier("typeof")', '"keyword"');
+shouldBe('classifyIdentifier("var")', '"keyword"');
+shouldBe('classifyIdentifier("void")', '"keyword"');
+shouldBe('classifyIdentifier("while")', '"keyword"');
+shouldBe('classifyIdentifier("with")', '"keyword"');
+// Technically these are "Future Reserved Words"!
+shouldBe('classifyIdentifier("class")', '"keyword"');
+shouldBe('classifyIdentifier("const")', '"keyword"');
+shouldBe('classifyIdentifier("enum")', '"keyword"');
+shouldBe('classifyIdentifier("export")', '"keyword"');
+shouldBe('classifyIdentifier("extends")', '"keyword"');
+shouldBe('classifyIdentifier("import")', '"keyword"');
+shouldBe('classifyIdentifier("super")', '"keyword"');
+
+// Future Reserved Words, in strict mode only.
+shouldBe('classifyIdentifier("implements")', '"strict"');
+shouldBe('classifyIdentifier("interface")', '"strict"');
+shouldBe('classifyIdentifier("let")', '"strict"');
+shouldBe('classifyIdentifier("package")', '"strict"');
+shouldBe('classifyIdentifier("private")', '"strict"');
+shouldBe('classifyIdentifier("protected")', '"strict"');
+shouldBe('classifyIdentifier("public")', '"strict"');
+shouldBe('classifyIdentifier("static")', '"strict"');
+shouldBe('classifyIdentifier("yield")', '"strict"');
+
+var successfullyParsed = true;

Modified: trunk/Source/_javascript_Core/ChangeLog (89108 => 89109)


--- trunk/Source/_javascript_Core/ChangeLog	2011-06-17 03:10:36 UTC (rev 89108)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-06-17 03:17:11 UTC (rev 89109)
@@ -2,6 +2,30 @@
 
         Reviewed by Oliver Hunt.
 
+        https://bugs.webkit.org/show_bug.cgi?id=53014
+        ES5 strict mode keyword restrictions aren't implemented
+
+        The following are future restricted words is strict mode code:
+            implements, interface, let, package, private, protected, public, static, yield
+
+        * parser/JSParser.h:
+            - Add RESERVED_IF_STRICT token.
+        * parser/Keywords.table:
+            - Add new future restricted words.
+        * parser/Lexer.cpp:
+        (JSC::Lexer::parseIdentifier):
+            - Check for RESERVED_IF_STRICT; in nonstrict code this is converted to IDENT.
+        (JSC::Lexer::lex):
+            - Pass strictMode flag to parseIdentifier.
+        * parser/Lexer.h:
+            - parseIdentifier needs a strictMode flag.
+        * runtime/CommonIdentifiers.h:
+            - Add identifiers for new reserved words.
+
+2011-06-16  Gavin Barraclough  <[email protected]>
+
+        Reviewed by Oliver Hunt.
+
         https://bugs.webkit.org/show_bug.cgi?id=23611
         Multiline _javascript_ comments cause incorrect parsing of following script.
 

Modified: trunk/Source/_javascript_Core/parser/JSParser.h (89108 => 89109)


--- trunk/Source/_javascript_Core/parser/JSParser.h	2011-06-17 03:10:36 UTC (rev 89108)
+++ trunk/Source/_javascript_Core/parser/JSParser.h	2011-06-17 03:17:11 UTC (rev 89109)
@@ -66,6 +66,7 @@
     SWITCH,
     WITH,
     RESERVED,
+    RESERVED_IF_STRICT,
     THROW,
     TRY,
     CATCH,

Modified: trunk/Source/_javascript_Core/parser/Keywords.table (89108 => 89109)


--- trunk/Source/_javascript_Core/parser/Keywords.table	2011-06-17 03:10:36 UTC (rev 89108)
+++ trunk/Source/_javascript_Core/parser/Keywords.table	2011-06-17 03:17:11 UTC (rev 89109)
@@ -1,5 +1,5 @@
 # main keywords
-@begin mainTable 41
+@begin mainTable 47
 
 # types
 null		NULLTOKEN
@@ -43,30 +43,16 @@
 import          RESERVED
 super           RESERVED
 
-# these words are reserved for future use in the ECMA spec, but not in WinIE
-# (see http://bugs.webkit.org/show_bug.cgi?id=6179)
-# abstract      RESERVED
-# boolean       RESERVED
-# byte          RESERVED
-# char          RESERVED
-# double        RESERVED
-# final         RESERVED
-# float         RESERVED
-# goto          RESERVED
-# implements    RESERVED
-# int           RESERVED
-# interface     RESERVED
-# long          RESERVED
-# native        RESERVED
-# package       RESERVED
-# private       RESERVED
-# protected     RESERVED
-# public        RESERVED
-# short         RESERVED
-# static        RESERVED
-# synchronized  RESERVED
-# throws        RESERVED
-# transient     RESERVED
-# volatile      RESERVED
+# reserved for future use in strict code
+implements      RESERVED_IF_STRICT
+interface       RESERVED_IF_STRICT
+let             RESERVED_IF_STRICT
+package         RESERVED_IF_STRICT
+private         RESERVED_IF_STRICT
+protected       RESERVED_IF_STRICT
+public          RESERVED_IF_STRICT
+static          RESERVED_IF_STRICT
+yield           RESERVED_IF_STRICT
+
 @end
 

Modified: trunk/Source/_javascript_Core/parser/Lexer.cpp (89108 => 89109)


--- trunk/Source/_javascript_Core/parser/Lexer.cpp	2011-06-17 03:10:36 UTC (rev 89108)
+++ trunk/Source/_javascript_Core/parser/Lexer.cpp	2011-06-17 03:17:11 UTC (rev 89109)
@@ -405,12 +405,12 @@
     record16(UChar(static_cast<unsigned short>(c)));
 }
 
-template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer::parseIdentifier(JSTokenData* tokenData, unsigned lexType)
+template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer::parseIdentifier(JSTokenData* tokenData, unsigned lexType, bool strictMode)
 {
     const ptrdiff_t remaining = m_codeEnd - m_code;
     if ((remaining >= maxTokenLength) && !(lexType & IgnoreReservedWords)) {
         JSTokenType keyword = parseKeyword<shouldCreateIdentifier>(tokenData);
-        if (keyword != IDENT) {
+        if (keyword != IDENT && (keyword != RESERVED_IF_STRICT || strictMode)) {
             ASSERT((!shouldCreateIdentifier) || tokenData->ident);
             return keyword;
         }
@@ -469,7 +469,10 @@
         if (remaining < maxTokenLength) {
             const HashEntry* entry = m_keywordTable.entry(m_globalData, *ident);
             ASSERT((remaining < maxTokenLength) || !entry);
-            return entry ? static_cast<JSTokenType>(entry->lexerValue()) : IDENT;
+            if (!entry)
+                return IDENT;
+            JSTokenType token = static_cast<JSTokenType>(entry->lexerValue());
+            return (token != RESERVED_IF_STRICT) || strictMode ? token : IDENT;
         }
         return IDENT;
     }
@@ -1082,9 +1085,9 @@
         // Fall through into CharacterBackSlash.
     case CharacterBackSlash:
         if (lexType & DontBuildKeywords)
-            token = parseIdentifier<false>(tokenData, lexType);
+            token = parseIdentifier<false>(tokenData, lexType, strictMode);
         else
-            token = parseIdentifier<true>(tokenData, lexType);
+            token = parseIdentifier<true>(tokenData, lexType, strictMode);
         break;
     case CharacterLineTerminator:
         ASSERT(isLineTerminator(m_current));

Modified: trunk/Source/_javascript_Core/parser/Lexer.h (89108 => 89109)


--- trunk/Source/_javascript_Core/parser/Lexer.h	2011-06-17 03:10:36 UTC (rev 89108)
+++ trunk/Source/_javascript_Core/parser/Lexer.h	2011-06-17 03:17:11 UTC (rev 89109)
@@ -118,7 +118,7 @@
         enum ShiftType { DoBoundsCheck, DoNotBoundsCheck };
         template <int shiftAmount, ShiftType shouldBoundsCheck> void internalShift();
         template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType parseKeyword(JSTokenData*);
-        template <bool shouldBuildIdentifiers> ALWAYS_INLINE JSTokenType parseIdentifier(JSTokenData*, unsigned);
+        template <bool shouldBuildIdentifiers> ALWAYS_INLINE JSTokenType parseIdentifier(JSTokenData*, unsigned, bool strictMode);
         template <bool shouldBuildStrings> ALWAYS_INLINE bool parseString(JSTokenData*, bool strictMode);
         ALWAYS_INLINE void parseHex(double& returnValue);
         ALWAYS_INLINE bool parseOctal(double& returnValue);

Modified: trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h (89108 => 89109)


--- trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h	2011-06-17 03:10:36 UTC (rev 89108)
+++ trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h	2011-06-17 03:17:11 UTC (rev 89109)
@@ -111,7 +111,16 @@
     macro(export) \
     macro(extends) \
     macro(import) \
-    macro(super)
+    macro(super) \
+    macro(implements) \
+    macro(interface) \
+    macro(let) \
+    macro(package) \
+    macro(private) \
+    macro(protected) \
+    macro(public) \
+    macro(static) \
+    macro(yield)
 
 namespace JSC {
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to