Title: [200121] trunk/Source
Revision
200121
Author
sbar...@apple.com
Date
2016-04-27 00:12:06 -0700 (Wed, 27 Apr 2016)

Log Message

JSC should have an option to allow global const redeclarations
https://bugs.webkit.org/show_bug.cgi?id=157006

Reviewed by Geoffrey Garen.

Source/_javascript_Core:

This patch implements an option that dictates whether
const redeclarations at the program level will throw.
This option defaults to true but allows users of JSC
to set it to false. This option is per VM. This is needed
for backwards compatibility with our old const implementation.

* jsc.cpp:
(GlobalObject::finishCreation):
(functionShadowChickenFunctionsOnStack):
(functionSetGlobalConstRedeclarationShouldNotThrow):
(functionReadline):
* runtime/Executable.cpp:
(JSC::ProgramExecutable::initializeGlobalProperties):
* runtime/JSGlobalLexicalEnvironment.cpp:
(JSC::JSGlobalLexicalEnvironment::put):
(JSC::JSGlobalLexicalEnvironment::isConstVariable):
* runtime/JSGlobalLexicalEnvironment.h:
(JSC::JSGlobalLexicalEnvironment::isEmpty):
* runtime/VM.h:
(JSC::VM::setGlobalConstRedeclarationShouldThrow):
(JSC::VM::globalConstRedeclarationShouldThrow):
* tests/stress/global-const-redeclaration-setting: Added.
* tests/stress/global-const-redeclaration-setting-2.js: Added.
(assert):
* tests/stress/global-const-redeclaration-setting-3.js: Added.
(assert):
(catch):
* tests/stress/global-const-redeclaration-setting-4.js: Added.
(assert):
(catch):
* tests/stress/global-const-redeclaration-setting-5.js: Added.
(assert):
(catch):
* tests/stress/global-const-redeclaration-setting.js: Added.
(assert):
* tests/stress/global-const-redeclaration-setting/first.js: Added.
* tests/stress/global-const-redeclaration-setting/let.js: Added.
* tests/stress/global-const-redeclaration-setting/second.js: Added.
* tests/stress/global-const-redeclaration-setting/strict.js: Added.

Source/WebCore:

This patch makes the JS VM not throw global const redeclaration
errors when the application is iBooks.

* bindings/js/JSDOMWindowBase.cpp:
(WebCore::JSDOMWindowBase::commonVM):
* page/Settings.h:
(WebCore::Settings::shouldUseHighResolutionTimers):
(WebCore::Settings::globalConstRedeclarationShouldThrow):
(WebCore::Settings::backgroundShouldExtendBeyondPage):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (200120 => 200121)


--- trunk/Source/_javascript_Core/ChangeLog	2016-04-27 03:21:58 UTC (rev 200120)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-04-27 07:12:06 UTC (rev 200121)
@@ -1,3 +1,50 @@
+2016-04-27  Saam barati  <sbar...@apple.com>
+
+        JSC should have an option to allow global const redeclarations
+        https://bugs.webkit.org/show_bug.cgi?id=157006
+
+        Reviewed by Geoffrey Garen.
+
+        This patch implements an option that dictates whether
+        const redeclarations at the program level will throw.
+        This option defaults to true but allows users of JSC
+        to set it to false. This option is per VM. This is needed
+        for backwards compatibility with our old const implementation.
+
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionShadowChickenFunctionsOnStack):
+        (functionSetGlobalConstRedeclarationShouldNotThrow):
+        (functionReadline):
+        * runtime/Executable.cpp:
+        (JSC::ProgramExecutable::initializeGlobalProperties):
+        * runtime/JSGlobalLexicalEnvironment.cpp:
+        (JSC::JSGlobalLexicalEnvironment::put):
+        (JSC::JSGlobalLexicalEnvironment::isConstVariable):
+        * runtime/JSGlobalLexicalEnvironment.h:
+        (JSC::JSGlobalLexicalEnvironment::isEmpty):
+        * runtime/VM.h:
+        (JSC::VM::setGlobalConstRedeclarationShouldThrow):
+        (JSC::VM::globalConstRedeclarationShouldThrow):
+        * tests/stress/global-const-redeclaration-setting: Added.
+        * tests/stress/global-const-redeclaration-setting-2.js: Added.
+        (assert):
+        * tests/stress/global-const-redeclaration-setting-3.js: Added.
+        (assert):
+        (catch):
+        * tests/stress/global-const-redeclaration-setting-4.js: Added.
+        (assert):
+        (catch):
+        * tests/stress/global-const-redeclaration-setting-5.js: Added.
+        (assert):
+        (catch):
+        * tests/stress/global-const-redeclaration-setting.js: Added.
+        (assert):
+        * tests/stress/global-const-redeclaration-setting/first.js: Added.
+        * tests/stress/global-const-redeclaration-setting/let.js: Added.
+        * tests/stress/global-const-redeclaration-setting/second.js: Added.
+        * tests/stress/global-const-redeclaration-setting/strict.js: Added.
+
 2016-04-26  Michael Saboff  <msab...@apple.com>
 
         [ES] Implement RegExp.prototype.@@replace and use it for String.prototype.replace

Modified: trunk/Source/_javascript_Core/jsc.cpp (200120 => 200121)


--- trunk/Source/_javascript_Core/jsc.cpp	2016-04-27 03:21:58 UTC (rev 200120)
+++ trunk/Source/_javascript_Core/jsc.cpp	2016-04-27 07:12:06 UTC (rev 200121)
@@ -634,6 +634,7 @@
 #endif
 
 static EncodedJSValue JSC_HOST_CALL functionShadowChickenFunctionsOnStack(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionSetGlobalConstRedeclarationShouldNotThrow(ExecState*);
 
 struct Script {
     bool isFile;
@@ -778,6 +779,7 @@
         addFunction(vm, "clearSamplingFlags", functionClearSamplingFlags, 1);
 #endif
         addFunction(vm, "shadowChickenFunctionsOnStack", functionShadowChickenFunctionsOnStack, 0);
+        addFunction(vm, "setGlobalConstRedeclarationShouldNotThrow", functionSetGlobalConstRedeclarationShouldNotThrow, 0);
         addConstructableFunction(vm, "Root", functionCreateRoot, 0);
         addConstructableFunction(vm, "Element", functionCreateElement, 1);
         addFunction(vm, "getElement", functionGetElement, 1);
@@ -1494,6 +1496,12 @@
     return JSValue::encode(exec->vm().shadowChicken().functionsOnStack(exec));
 }
 
+EncodedJSValue JSC_HOST_CALL functionSetGlobalConstRedeclarationShouldNotThrow(ExecState* exec)
+{
+    exec->vm().setGlobalConstRedeclarationShouldThrow(false);
+    return JSValue::encode(jsUndefined());
+}
+
 EncodedJSValue JSC_HOST_CALL functionReadline(ExecState* exec)
 {
     Vector<char, 256> line;

Modified: trunk/Source/_javascript_Core/runtime/Executable.cpp (200120 => 200121)


--- trunk/Source/_javascript_Core/runtime/Executable.cpp	2016-04-27 03:21:58 UTC (rev 200120)
+++ trunk/Source/_javascript_Core/runtime/Executable.cpp	2016-04-27 07:12:06 UTC (rev 200121)
@@ -606,8 +606,15 @@
             if (globalObject->hasProperty(exec, entry.key.get()))
                 return createSyntaxError(exec, makeString("Can't create duplicate variable that shadows a global property: '", String(entry.key.get()), "'"));
 
-            if (globalLexicalEnvironment->hasProperty(exec, entry.key.get()))
+            if (globalLexicalEnvironment->hasProperty(exec, entry.key.get())) {
+                if (UNLIKELY(entry.value.isConst() && !vm.globalConstRedeclarationShouldThrow() && !isStrictMode())) {
+                    // We only allow "const" duplicate declarations under this setting.
+                    // For example, we don't "let" variables to be overridden by "const" variables.
+                    if (globalLexicalEnvironment->isConstVariable(entry.key.get()))
+                        continue;
+                }
                 return createSyntaxError(exec, makeString("Can't create duplicate variable: '", String(entry.key.get()), "'"));
+            }
         }
 
         // Check if any new "var"s will shadow any previous "let"/"const"/"class" names.
@@ -646,6 +653,10 @@
         SymbolTable* symbolTable = globalLexicalEnvironment->symbolTable();
         ConcurrentJITLocker locker(symbolTable->m_lock);
         for (auto& entry : lexicalDeclarations) {
+            if (UNLIKELY(entry.value.isConst() && !vm.globalConstRedeclarationShouldThrow() && !isStrictMode())) {
+                if (symbolTable->contains(locker, entry.key.get()))
+                    continue;
+            }
             ScopeOffset offset = symbolTable->takeNextScopeOffset(locker);
             SymbolTableEntry newEntry(VarOffset(offset), entry.value.isConst() ? ReadOnly : 0);
             newEntry.prepareToWatch();

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalLexicalEnvironment.cpp (200120 => 200121)


--- trunk/Source/_javascript_Core/runtime/JSGlobalLexicalEnvironment.cpp	2016-04-27 03:21:58 UTC (rev 200120)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalLexicalEnvironment.cpp	2016-04-27 07:12:06 UTC (rev 200121)
@@ -49,4 +49,11 @@
     return putResult;
 }
 
+bool JSGlobalLexicalEnvironment::isConstVariable(UniquedStringImpl* impl)
+{
+    SymbolTableEntry entry = symbolTable()->get(impl);
+    ASSERT(!entry.isNull());
+    return entry.isReadOnly();
+}
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalLexicalEnvironment.h (200120 => 200121)


--- trunk/Source/_javascript_Core/runtime/JSGlobalLexicalEnvironment.h	2016-04-27 03:21:58 UTC (rev 200120)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalLexicalEnvironment.h	2016-04-27 07:12:06 UTC (rev 200121)
@@ -50,6 +50,7 @@
     static bool put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
 
     bool isEmpty() const { return !symbolTable()->size(); }
+    bool isConstVariable(UniquedStringImpl*);
     
     DECLARE_INFO;
 

Modified: trunk/Source/_javascript_Core/runtime/VM.h (200120 => 200121)


--- trunk/Source/_javascript_Core/runtime/VM.h	2016-04-27 03:21:58 UTC (rev 200120)
+++ trunk/Source/_javascript_Core/runtime/VM.h	2016-04-27 07:12:06 UTC (rev 200121)
@@ -602,6 +602,8 @@
 
     JS_EXPORT_PRIVATE void queueMicrotask(JSGlobalObject*, PassRefPtr<Microtask>);
     JS_EXPORT_PRIVATE void drainMicrotasks();
+    JS_EXPORT_PRIVATE void setGlobalConstRedeclarationShouldThrow(bool globalConstRedeclarationThrow) { m_globalConstRedeclarationShouldThrow = globalConstRedeclarationThrow; }
+    ALWAYS_INLINE bool globalConstRedeclarationShouldThrow() const { return m_globalConstRedeclarationShouldThrow; }
 
     inline bool shouldTriggerTermination(ExecState*);
 
@@ -662,6 +664,7 @@
     Exception* m_lastException { nullptr };
     bool m_failNextNewCodeBlock { false };
     bool m_inDefineOwnProperty;
+    bool m_globalConstRedeclarationShouldThrow { true };
     bool m_shouldBuildPCToCodeOriginMapping { false };
     std::unique_ptr<CodeCache> m_codeCache;
     LegacyProfiler* m_enabledProfiler;

Added: trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting/first.js (0 => 200121)


--- trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting/first.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting/first.js	2016-04-27 07:12:06 UTC (rev 200121)
@@ -0,0 +1 @@
+const foo = 20;

Added: trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting/let.js (0 => 200121)


--- trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting/let.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting/let.js	2016-04-27 07:12:06 UTC (rev 200121)
@@ -0,0 +1 @@
+let foo = 50;

Added: trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting/second.js (0 => 200121)


--- trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting/second.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting/second.js	2016-04-27 07:12:06 UTC (rev 200121)
@@ -0,0 +1 @@
+const foo = 40;

Added: trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting/strict.js (0 => 200121)


--- trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting/strict.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting/strict.js	2016-04-27 07:12:06 UTC (rev 200121)
@@ -0,0 +1,2 @@
+"use strict";
+const foo = 45;

Added: trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting-2.js (0 => 200121)


--- trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting-2.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting-2.js	2016-04-27 07:12:06 UTC (rev 200121)
@@ -0,0 +1,13 @@
+function assert(b) {
+    if (!b)
+        throw new Error("Bad assertion.");
+}
+
+setGlobalConstRedeclarationShouldNotThrow(); // Allow duplicate const declarations at the global level.
+
+for (let i = 0; i < 100; i++) {
+    load("./global-const-redeclaration-setting/first.js");
+    assert(foo === 20);
+    load("./global-const-redeclaration-setting/second.js");
+    assert(foo === 40);
+}

Added: trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting-3.js (0 => 200121)


--- trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting-3.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting-3.js	2016-04-27 07:12:06 UTC (rev 200121)
@@ -0,0 +1,18 @@
+function assert(b) {
+    if (!b)
+        throw new Error("Bad assertion.");
+}
+
+setGlobalConstRedeclarationShouldNotThrow(); // Allow duplicate const declarations at the global level.
+
+load("./global-const-redeclaration-setting/first.js");
+assert(foo === 20);
+let threw = false;
+try {
+    load("./global-const-redeclaration-setting/strict.js"); // We ignore the setting and always throw an error when in strict mode!
+} catch(e) {
+    threw = true;
+}
+
+assert(threw);
+assert(foo === 20);

Added: trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting-4.js (0 => 200121)


--- trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting-4.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting-4.js	2016-04-27 07:12:06 UTC (rev 200121)
@@ -0,0 +1,18 @@
+function assert(b) {
+    if (!b)
+        throw new Error("Bad assertion.");
+}
+
+setGlobalConstRedeclarationShouldNotThrow(); // Allow duplicate const declarations at the global level.
+
+load("./global-const-redeclaration-setting/first.js");
+assert(foo === 20);
+let threw = false;
+try {
+    load("./global-const-redeclaration-setting/let.js"); // Redeclaration a 'let' variable should throw because this doesn't break backwards compat.
+} catch(e) {
+    threw = true;
+}
+
+assert(threw);
+assert(foo === 20);

Added: trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting-5.js (0 => 200121)


--- trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting-5.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting-5.js	2016-04-27 07:12:06 UTC (rev 200121)
@@ -0,0 +1,18 @@
+function assert(b) {
+    if (!b)
+        throw new Error("Bad assertion.");
+}
+
+setGlobalConstRedeclarationShouldNotThrow(); // Allow duplicate const declarations at the global level.
+
+load("./global-const-redeclaration-setting/let.js");
+assert(foo === 50);
+let threw = false;
+try {
+    load("./global-const-redeclaration-setting/first.js"); // Redeclaration of a 'let' to 'const' should always throw because it isn't breaking backwards compat.
+} catch(e) {
+    threw = true;
+}
+
+assert(threw);
+assert(foo === 50);

Added: trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting.js (0 => 200121)


--- trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/global-const-redeclaration-setting.js	2016-04-27 07:12:06 UTC (rev 200121)
@@ -0,0 +1,11 @@
+function assert(b) {
+    if (!b)
+        throw new Error("Bad assertion.");
+}
+
+setGlobalConstRedeclarationShouldNotThrow(); // Allow duplicate const declarations at the global level.
+
+load("./global-const-redeclaration-setting/first.js");
+assert(foo === 20);
+load("./global-const-redeclaration-setting/second.js");
+assert(foo === 40);

Modified: trunk/Source/WebCore/ChangeLog (200120 => 200121)


--- trunk/Source/WebCore/ChangeLog	2016-04-27 03:21:58 UTC (rev 200120)
+++ trunk/Source/WebCore/ChangeLog	2016-04-27 07:12:06 UTC (rev 200121)
@@ -1,3 +1,20 @@
+2016-04-27  Saam barati  <sbar...@apple.com>
+
+        JSC should have an option to allow global const redeclarations
+        https://bugs.webkit.org/show_bug.cgi?id=157006
+
+        Reviewed by Geoffrey Garen.
+
+        This patch makes the JS VM not throw global const redeclaration
+        errors when the application is iBooks.
+
+        * bindings/js/JSDOMWindowBase.cpp:
+        (WebCore::JSDOMWindowBase::commonVM):
+        * page/Settings.h:
+        (WebCore::Settings::shouldUseHighResolutionTimers):
+        (WebCore::Settings::globalConstRedeclarationShouldThrow):
+        (WebCore::Settings::backgroundShouldExtendBeyondPage):
+
 2016-04-26  John Wilander  <wilan...@apple.com>
 
         Support legacy HTTP headers in WebSockets

Modified: trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp (200120 => 200121)


--- trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp	2016-04-27 03:21:58 UTC (rev 200120)
+++ trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp	2016-04-27 07:12:06 UTC (rev 200121)
@@ -269,6 +269,8 @@
         vm->heap.machineThreads().addCurrentThread();
 #endif
 
+        vm->setGlobalConstRedeclarationShouldThrow(Settings::globalConstRedeclarationShouldThrow());
+
         initNormalWorldClientData(vm);
     }
 

Modified: trunk/Source/WebCore/page/Settings.h (200120 => 200121)


--- trunk/Source/WebCore/page/Settings.h	2016-04-27 03:21:58 UTC (rev 200120)
+++ trunk/Source/WebCore/page/Settings.h	2016-04-27 07:12:06 UTC (rev 200121)
@@ -30,6 +30,7 @@
 #include "ClipboardAccessPolicy.h"
 #include "EditingBehaviorTypes.h"
 #include "IntSize.h"
+#include "RuntimeApplicationChecks.h"
 #include "SecurityOrigin.h"
 #include "SettingsMacros.h"
 #include "TextFlags.h"
@@ -189,6 +190,17 @@
     static bool shouldUseHighResolutionTimers() { return gShouldUseHighResolutionTimers; }
 #endif
 
+    static bool globalConstRedeclarationShouldThrow()
+    { 
+#if PLATFORM(MAC)
+        return !MacApplication::isIBooks();
+#elif PLATFORM(IOS)
+        return !IOSApplication::isIBooks();
+#else
+        return true;
+#endif
+    }
+
     WEBCORE_EXPORT void setBackgroundShouldExtendBeyondPage(bool);
     bool backgroundShouldExtendBeyondPage() const { return m_backgroundShouldExtendBeyondPage; }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to