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 {