<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[214145] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/214145">214145</a></dd>
<dt>Author</dt> <dd>cdumez@apple.com</dd>
<dt>Date</dt> <dd>2017-03-19 10:45:39 -0700 (Sun, 19 Mar 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>`const location = &quot;foo&quot;` throws in a worker
https://bugs.webkit.org/show_bug.cgi?id=169839

Reviewed by Mark Lam.

JSTests:

* ChakraCore/test/es6/letconst_global_shadow_builtins_nonconfigurable.baseline-jsc:
Update expected jsc result now that we throw a SyntaxError when trying to shadow undefined
with a let variable. We used not to throw because the value is undefined but this was not
as per EcmaScript. Both Firefox and Chrome throw in this case.

* stress/global-lexical-redeclare-variable.js:
(catch):
Update test that defines a non-configurable 'zoo' property on the global object and then
expected shadowing it with a 'let zoo' variable to work because its value was undefined.
This was not as per EcmaScript spec and both Firefox and Chrome throw in this case.

Source/JavaScriptCore:

Our HasRestrictedGlobalProperty check in JSC was slightly wrong, causing us
to sometimes throw a Syntax exception when we shouldn't when declaring a
const/let variable and sometimes not throw an exception when we should have.

This aligns our behavior with ES6, Firefox and Chrome.

* runtime/ProgramExecutable.cpp:
(JSC::hasRestrictedGlobalProperty):
(JSC::ProgramExecutable::initializeGlobalProperties):
Rewrite hasRestrictedGlobalProperty logic as per the EcmaScript spec:
- http://www.ecma-international.org/ecma-262/6.0/index.html#sec-hasproperty
In particular, they were 2 issues:
- We should throw a SyntaxError if hasProperty() returned true but getOwnProperty()
  would fail to return a descriptor. This would happen for properties that are
  not OWN properties, but defined somewhere in the prototype chain. The spec does
  not say to use hasProperty(), only getOwnProperty() and says we should return
  false if getOwnProperty() does not return a descriptor. This is what we do now.
- We would fail to throw when declaring a let/const variable that shadows an own
  property whose value is undefined. This is because the previous code was
  explicitly checking for this case. I believe this was a misinterpretation of
  ES6 which says:
  &quot;&quot;&quot;
  Let desc be O.[[GetOwnProperty]](P).
  If desc is undefined, return false.
  &quot;&quot;&quot;
  We should check that desc is undefined, not desc.value. This is now fixed.

LayoutTests:

* fast/dom/window-const-variable-shadowing-expected.txt: Added.
* fast/dom/window-const-variable-shadowing.html: Added.
* fast/workers/const-location-variable-expected.txt: Added.
* fast/workers/const-location-variable.html: Added.
* fast/workers/resources/worker-const-location.js: Added.
Add layout test coverage for behavior changes. Those tests pass in Firefox and Chrome.

* js/dom/const-expected.txt:
* js/dom/const.html:
Update test which wrongly expected a let variable not to be able to shadow a
window named property. This test was failing in Chrome and Firefox. The reason
this does not throw is because window named properties are not on the window
object, they are on the WindowProperties object in the Window prototype chain.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJSTestsChakraCoretestes6letconst_global_shadow_builtins_nonconfigurablebaselinejsc">trunk/JSTests/ChakraCore/test/es6/letconst_global_shadow_builtins_nonconfigurable.baseline-jsc</a></li>
<li><a href="#trunkJSTestsChakraCoreyaml">trunk/JSTests/ChakraCore.yaml</a></li>
<li><a href="#trunkJSTestsChangeLog">trunk/JSTests/ChangeLog</a></li>
<li><a href="#trunkJSTestsstressgloballexicalredeclarevariablejs">trunk/JSTests/stress/global-lexical-redeclare-variable.js</a></li>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsjsdomconstexpectedtxt">trunk/LayoutTests/js/dom/const-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsdomconsthtml">trunk/LayoutTests/js/dom/const.html</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeProgramExecutablecpp">trunk/Source/JavaScriptCore/runtime/ProgramExecutable.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastdomwindowconstvariableshadowingexpectedtxt">trunk/LayoutTests/fast/dom/window-const-variable-shadowing-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastdomwindowconstvariableshadowinghtml">trunk/LayoutTests/fast/dom/window-const-variable-shadowing.html</a></li>
<li><a href="#trunkLayoutTestsfastworkersconstlocationvariableexpectedtxt">trunk/LayoutTests/fast/workers/const-location-variable-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastworkersconstlocationvariablehtml">trunk/LayoutTests/fast/workers/const-location-variable.html</a></li>
<li><a href="#trunkLayoutTestsfastworkersresourcesworkerconstlocationjs">trunk/LayoutTests/fast/workers/resources/worker-const-location.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJSTestsChakraCoretestes6letconst_global_shadow_builtins_nonconfigurablebaselinejsc"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChakraCore/test/es6/letconst_global_shadow_builtins_nonconfigurable.baseline-jsc (214144 => 214145)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChakraCore/test/es6/letconst_global_shadow_builtins_nonconfigurable.baseline-jsc        2017-03-19 15:54:32 UTC (rev 214144)
+++ trunk/JSTests/ChakraCore/test/es6/letconst_global_shadow_builtins_nonconfigurable.baseline-jsc        2017-03-19 17:45:39 UTC (rev 214145)
</span><span class="lines">@@ -1,2 +1 @@
</span><del>-Exception: ReferenceError: Cannot access uninitialized variable.
-global code@letconst_global_shadow_builtins_nonconfigurable.js:8:16
</del><ins>+Exception: SyntaxError: Can't create duplicate variable that shadows a global property: 'undefined'
</ins></span></pre></div>
<a id="trunkJSTestsChakraCoreyaml"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChakraCore.yaml (214144 => 214145)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChakraCore.yaml        2017-03-19 15:54:32 UTC (rev 214144)
+++ trunk/JSTests/ChakraCore.yaml        2017-03-19 17:45:39 UTC (rev 214145)
</span><span class="lines">@@ -1580,7 +1580,7 @@
</span><span class="cx"> - path: ChakraCore/test/es6/letconst_global_shadow_builtins.js
</span><span class="cx">   cmd: runChakra :baseline, &quot;NoException&quot;, &quot;letconst_global_shadow_builtins.baseline-jsc&quot;, []
</span><span class="cx"> - path: ChakraCore/test/es6/letconst_global_shadow_builtins_nonconfigurable.js
</span><del>-  cmd: runChakra :baseline, &quot;ReferenceError&quot;, &quot;letconst_global_shadow_builtins_nonconfigurable.baseline-jsc&quot;, []
</del><ins>+  cmd: runChakra :baseline, &quot;SyntaxError&quot;, &quot;letconst_global_shadow_builtins_nonconfigurable.baseline-jsc&quot;, []
</ins><span class="cx"> - path: ChakraCore/test/es6/letconst_global_shadow_deleted.js
</span><span class="cx">   cmd: runChakra :baseline, &quot;NoException&quot;, &quot;letconst_global_shadow_deleted.baseline&quot;, [&quot;letconst_global_shadow_deleted_2.js&quot;]
</span><span class="cx"> - path: ChakraCore/test/es6/letconst_global_shadow_accessor.js
</span></span></pre></div>
<a id="trunkJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChangeLog (214144 => 214145)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChangeLog        2017-03-19 15:54:32 UTC (rev 214144)
+++ trunk/JSTests/ChangeLog        2017-03-19 17:45:39 UTC (rev 214145)
</span><span class="lines">@@ -1,3 +1,21 @@
</span><ins>+2017-03-19  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        `const location = &quot;foo&quot;` throws in a worker
+        https://bugs.webkit.org/show_bug.cgi?id=169839
+
+        Reviewed by Mark Lam.
+
+        * ChakraCore/test/es6/letconst_global_shadow_builtins_nonconfigurable.baseline-jsc:
+        Update expected jsc result now that we throw a SyntaxError when trying to shadow undefined
+        with a let variable. We used not to throw because the value is undefined but this was not
+        as per EcmaScript. Both Firefox and Chrome throw in this case.
+
+        * stress/global-lexical-redeclare-variable.js:
+        (catch):
+        Update test that defines a non-configurable 'zoo' property on the global object and then
+        expected shadowing it with a 'let zoo' variable to work because its value was undefined.
+        This was not as per EcmaScript spec and both Firefox and Chrome throw in this case.
+
</ins><span class="cx"> 2017-03-19  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         import(arg) crashes when ToString(arg) throws
</span></span></pre></div>
<a id="trunkJSTestsstressgloballexicalredeclarevariablejs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/stress/global-lexical-redeclare-variable.js (214144 => 214145)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/global-lexical-redeclare-variable.js        2017-03-19 15:54:32 UTC (rev 214144)
+++ trunk/JSTests/stress/global-lexical-redeclare-variable.js        2017-03-19 17:45:39 UTC (rev 214145)
</span><span class="lines">@@ -105,11 +105,11 @@
</span><span class="cx"> assert(errorCount === 6);
</span><span class="cx"> 
</span><span class="cx"> try {
</span><del>-    sentinel = &quot;bad&quot;;
</del><span class="cx">     Object.defineProperty(this, 'zoo', {value: undefined, configurable: false, writable: true});
</span><span class="cx">     load(&quot;./multiple-files-tests/global-lexical-redeclare-variable/tenth.js&quot;);
</span><span class="cx"> } catch(e) {
</span><del>-    assert(false);
</del><ins>+    assertProperError(e);
</ins><span class="cx"> }
</span><span class="cx"> assertExpectations();
</span><span class="cx"> 
</span><ins>+assert(errorCount === 7);
</ins></span></pre></div>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (214144 => 214145)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2017-03-19 15:54:32 UTC (rev 214144)
+++ trunk/LayoutTests/ChangeLog        2017-03-19 17:45:39 UTC (rev 214145)
</span><span class="lines">@@ -1,3 +1,24 @@
</span><ins>+2017-03-19  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        `const location = &quot;foo&quot;` throws in a worker
+        https://bugs.webkit.org/show_bug.cgi?id=169839
+
+        Reviewed by Mark Lam.
+
+        * fast/dom/window-const-variable-shadowing-expected.txt: Added.
+        * fast/dom/window-const-variable-shadowing.html: Added.
+        * fast/workers/const-location-variable-expected.txt: Added.
+        * fast/workers/const-location-variable.html: Added.
+        * fast/workers/resources/worker-const-location.js: Added.
+        Add layout test coverage for behavior changes. Those tests pass in Firefox and Chrome.
+
+        * js/dom/const-expected.txt:
+        * js/dom/const.html:
+        Update test which wrongly expected a let variable not to be able to shadow a
+        window named property. This test was failing in Chrome and Firefox. The reason
+        this does not throw is because window named properties are not on the window
+        object, they are on the WindowProperties object in the Window prototype chain.
+
</ins><span class="cx"> 2017-03-18  Jon Lee  &lt;jonlee@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add support for ImplementedAs, Clamp, EnforceRange, TreatNullAs for dictionary members
</span></span></pre></div>
<a id="trunkLayoutTestsfastdomwindowconstvariableshadowingexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/dom/window-const-variable-shadowing-expected.txt (0 => 214145)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/dom/window-const-variable-shadowing-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/dom/window-const-variable-shadowing-expected.txt        2017-03-19 17:45:39 UTC (rev 214145)
</span><span class="lines">@@ -0,0 +1,24 @@
</span><ins>+CONSOLE MESSAGE: SyntaxError: Can't create duplicate variable that shadows a global property: 'location'
+CONSOLE MESSAGE: SyntaxError: Can't create duplicate variable that shadows a global property: 'foo'
+Tests various cases of const variable shadowing on Window.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Should throw because Window has a non-configurable location own property.
+PASS sentinel is &quot;good&quot;
+
+Should throw because window has an own property foo that is not configurable, even though its value is undefined.
+PASS sentinel is &quot;good&quot;
+
+Should work because Window's own bar property is configurable.
+PASS bar is 3
+PASS sentinel is &quot;good&quot;
+
+Should work because dispatchEvent is not an own property, it comes from the prototype chain.
+PASS dispatchEvent is 3
+PASS sentinel is &quot;good&quot;
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastdomwindowconstvariableshadowinghtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/dom/window-const-variable-shadowing.html (0 => 214145)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/dom/window-const-variable-shadowing.html                                (rev 0)
+++ trunk/LayoutTests/fast/dom/window-const-variable-shadowing.html        2017-03-19 17:45:39 UTC (rev 214145)
</span><span class="lines">@@ -0,0 +1,68 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+description(&quot;Tests various cases of const variable shadowing on Window.&quot;);
+
+let sentinel = &quot;good&quot;;
+&lt;/script&gt;
+&lt;script&gt;
+debug(&quot;Should throw because Window has a non-configurable location own property.&quot;);
+&lt;/script&gt;
+&lt;script&gt;
+const location = 3;
+sentinel = &quot;bad&quot;;
+&lt;/script&gt;
+&lt;script&gt;
+shouldBeEqualToString(&quot;sentinel&quot;, &quot;good&quot;);
+&lt;/script&gt;
+
+&lt;script&gt;
+debug(&quot;&quot;);
+debug(&quot;Should throw because window has an own property foo that is not configurable, even though its value is undefined.&quot;);
+Object.defineProperty(window, 'foo', {value: undefined, configurable: false, writable: true});
+&lt;/script&gt;
+&lt;script&gt;
+const foo = 3;
+sentinel = &quot;bad&quot;;
+&lt;/script&gt;
+&lt;script&gt;
+shouldBeEqualToString(&quot;sentinel&quot;, &quot;good&quot;);
+&lt;/script&gt;
+
+&lt;script&gt;
+debug(&quot;&quot;);
+debug(&quot;Should work because Window's own bar property is configurable.&quot;);
+Object.defineProperty(window, 'bar', {value: 2, configurable: true, writable: true});
+sentinel = &quot;bad&quot;;
+&lt;/script&gt;
+&lt;script&gt;
+const bar = 3;
+sentinel = &quot;good&quot;;
+shouldBe(&quot;bar&quot;, &quot;3&quot;);
+&lt;/script&gt;
+&lt;script&gt;
+shouldBeEqualToString(&quot;sentinel&quot;, &quot;good&quot;);
+&lt;/script&gt;
+
+&lt;script&gt;
+debug(&quot;&quot;);
+debug(&quot;Should work because dispatchEvent is not an own property, it comes from the prototype chain.&quot;);
+sentinel = &quot;bad&quot;
+&lt;/script&gt;
+&lt;script&gt;
+const dispatchEvent = 3;
+sentinel = &quot;good&quot;;
+shouldBe(&quot;dispatchEvent&quot;, &quot;3&quot;);
+&lt;/script&gt;
+&lt;script&gt;
+shouldBeEqualToString(&quot;sentinel&quot;, &quot;good&quot;);
+&lt;/script&gt;
+
+&lt;script&gt;
+successfullyParsed = true;
+&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastworkersconstlocationvariableexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/workers/const-location-variable-expected.txt (0 => 214145)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/workers/const-location-variable-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/workers/const-location-variable-expected.txt        2017-03-19 17:45:39 UTC (rev 214145)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+Tests that declaring a const &quot;location&quot; variable in a worker does not throw.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+SUCCESS: location was properly shadowed
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastworkersconstlocationvariablehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/workers/const-location-variable.html (0 => 214145)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/workers/const-location-variable.html                                (rev 0)
+++ trunk/LayoutTests/fast/workers/const-location-variable.html        2017-03-19 17:45:39 UTC (rev 214145)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+description('Tests that declaring a const &quot;location&quot; variable in a worker does not throw.');
+jsTestIsAsync = true;
+
+function runTest() {
+    var worker = new Worker('resources/worker-const-location.js');
+    worker.onmessage = function(event) {
+        if (event.data == 'DONE')
+            finishJSTest();
+        else
+            debug(event.data);
+    }
+    worker.postMessage('');
+}
+
+window.onload = runTest;
+&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastworkersresourcesworkerconstlocationjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/workers/resources/worker-const-location.js (0 => 214145)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/workers/resources/worker-const-location.js                                (rev 0)
+++ trunk/LayoutTests/fast/workers/resources/worker-const-location.js        2017-03-19 17:45:39 UTC (rev 214145)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+const location = 2; // Should not throw.
+
+function log(message)
+{
+    postMessage(message);
+}
+
+onmessage = function(event) {
+    if (location == 2)
+        log(&quot;SUCCESS: location was properly shadowed&quot;);
+    else
+        log(&quot;FAIL: location was not shadowed&quot;);
+
+    log(&quot;DONE&quot;);
+}
</ins></span></pre></div>
<a id="trunkLayoutTestsjsdomconstexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/dom/const-expected.txt (214144 => 214145)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/const-expected.txt        2017-03-19 15:54:32 UTC (rev 214144)
+++ trunk/LayoutTests/js/dom/const-expected.txt        2017-03-19 17:45:39 UTC (rev 214145)
</span><span class="lines">@@ -1,8 +1,9 @@
</span><del>-CONSOLE MESSAGE: SyntaxError: Can't create duplicate variable that shadows a global property: 'bodyId'
-This test checks that const variables can't shadow global object properties. Note that this test expects SyntaxErrors in below
</del><ins>+This test checks that const variables can shadow global object's named properties.
</ins><span class="cx"> 
</span><del>-PASS sentinel is &quot;__s__&quot;
-PASS bodyId is document.getElementById('bodyId')
</del><ins>+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS bodyId is 3
</ins><span class="cx"> PASS successfullyParsed is true
</span><span class="cx"> 
</span><span class="cx"> TEST COMPLETE
</span></span></pre></div>
<a id="trunkLayoutTestsjsdomconsthtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/dom/const.html (214144 => 214145)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/const.html        2017-03-19 15:54:32 UTC (rev 214144)
+++ trunk/LayoutTests/js/dom/const.html        2017-03-19 17:45:39 UTC (rev 214145)
</span><span class="lines">@@ -7,24 +7,15 @@
</span><span class="cx"> &lt;body id=&quot;bodyId&quot;&gt;
</span><span class="cx"> 
</span><span class="cx"> &lt;script&gt;
</span><del>-
-description(
-    &quot;This test checks that const variables can't shadow global object properties.  Note that this test expects SyntaxErrors in below &lt;script&gt;&quot;
-);
-
-let sentinel = &quot;__s__&quot;;
</del><ins>+description(&quot;This test checks that const variables can shadow global object's named properties.&quot;);
</ins><span class="cx"> &lt;/script&gt;
</span><span class="cx"> 
</span><span class="cx"> &lt;script&gt;
</span><del>-// Make sure we can't override properties placed on the global object
-const bodyId = &quot;lah la lah la lah, I should never execute.&quot;;
-sentinel = &quot;bad&quot;;
</del><ins>+const bodyId = 3;
</ins><span class="cx"> &lt;/script&gt;
</span><span class="cx"> 
</span><span class="cx"> &lt;script&gt;
</span><del>-shouldBe(&quot;sentinel&quot;, '&quot;__s__&quot;');
-shouldBe(&quot;bodyId&quot;, &quot;document.getElementById('bodyId')&quot;);
-successfullyParsed = true;
</del><ins>+shouldBe(&quot;bodyId&quot;, &quot;3&quot;);
</ins><span class="cx"> &lt;/script&gt;
</span><span class="cx"> 
</span><span class="cx"> &lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (214144 => 214145)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2017-03-19 15:54:32 UTC (rev 214144)
+++ trunk/Source/JavaScriptCore/ChangeLog        2017-03-19 17:45:39 UTC (rev 214145)
</span><span class="lines">@@ -1,3 +1,37 @@
</span><ins>+2017-03-19  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        `const location = &quot;foo&quot;` throws in a worker
+        https://bugs.webkit.org/show_bug.cgi?id=169839
+
+        Reviewed by Mark Lam.
+
+        Our HasRestrictedGlobalProperty check in JSC was slightly wrong, causing us
+        to sometimes throw a Syntax exception when we shouldn't when declaring a
+        const/let variable and sometimes not throw an exception when we should have.
+
+        This aligns our behavior with ES6, Firefox and Chrome.
+
+        * runtime/ProgramExecutable.cpp:
+        (JSC::hasRestrictedGlobalProperty):
+        (JSC::ProgramExecutable::initializeGlobalProperties):
+        Rewrite hasRestrictedGlobalProperty logic as per the EcmaScript spec:
+        - http://www.ecma-international.org/ecma-262/6.0/index.html#sec-hasproperty
+        In particular, they were 2 issues:
+        - We should throw a SyntaxError if hasProperty() returned true but getOwnProperty()
+          would fail to return a descriptor. This would happen for properties that are
+          not OWN properties, but defined somewhere in the prototype chain. The spec does
+          not say to use hasProperty(), only getOwnProperty() and says we should return
+          false if getOwnProperty() does not return a descriptor. This is what we do now.
+        - We would fail to throw when declaring a let/const variable that shadows an own
+          property whose value is undefined. This is because the previous code was
+          explicitly checking for this case. I believe this was a misinterpretation of
+          ES6 which says:
+          &quot;&quot;&quot;
+          Let desc be O.[[GetOwnProperty]](P).
+          If desc is undefined, return false.
+          &quot;&quot;&quot;
+          We should check that desc is undefined, not desc.value. This is now fixed.
+
</ins><span class="cx"> 2017-03-19  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         import(arg) crashes when ToString(arg) throws
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeProgramExecutablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ProgramExecutable.cpp (214144 => 214145)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ProgramExecutable.cpp        2017-03-19 15:54:32 UTC (rev 214144)
+++ trunk/Source/JavaScriptCore/runtime/ProgramExecutable.cpp        2017-03-19 17:45:39 UTC (rev 214145)
</span><span class="lines">@@ -72,6 +72,17 @@
</span><span class="cx">     return error.toErrorObject(lexicalGlobalObject, m_source);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+// http://www.ecma-international.org/ecma-262/6.0/index.html#sec-hasrestrictedglobalproperty
+static bool hasRestrictedGlobalProperty(ExecState* exec, JSGlobalObject* globalObject, PropertyName propertyName)
+{
+    PropertyDescriptor descriptor;
+    if (!globalObject-&gt;getOwnPropertyDescriptor(exec, propertyName, descriptor))
+        return false;
+    if (descriptor.configurable())
+        return false;
+    return true;
+}
+
</ins><span class="cx"> JSObject* ProgramExecutable::initializeGlobalProperties(VM&amp; vm, CallFrame* callFrame, JSScope* scope)
</span><span class="cx"> {
</span><span class="cx">     auto throwScope = DECLARE_THROW_SCOPE(vm);
</span><span class="lines">@@ -118,19 +129,11 @@
</span><span class="cx">         // Check if any new &quot;let&quot;/&quot;const&quot;/&quot;class&quot; will shadow any pre-existing global property names, or &quot;var&quot;/&quot;let&quot;/&quot;const&quot; variables.
</span><span class="cx">         // It's an error to introduce a shadow.
</span><span class="cx">         for (auto&amp; entry : lexicalDeclarations) {
</span><del>-            bool hasProperty = globalObject-&gt;hasProperty(exec, entry.key.get());
-            RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
-            if (hasProperty) {
-                // The ES6 spec says that just RestrictedGlobalProperty can't be shadowed
-                // This carried out section 8.1.1.4.14 of the ES6 spec: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-hasrestrictedglobalproperty
-                PropertyDescriptor descriptor;
-                globalObject-&gt;getOwnPropertyDescriptor(exec, entry.key.get(), descriptor);
-                
-                if (descriptor.value() != jsUndefined() &amp;&amp; !descriptor.configurable())
-                    return createSyntaxError(exec, makeString(&quot;Can't create duplicate variable that shadows a global property: '&quot;, String(entry.key.get()), &quot;'&quot;));
-            }
</del><ins>+            // The ES6 spec says that RestrictedGlobalProperty can't be shadowed.
+            if (hasRestrictedGlobalProperty(exec, globalObject, entry.key.get()))
+                return createSyntaxError(exec, makeString(&quot;Can't create duplicate variable that shadows a global property: '&quot;, String(entry.key.get()), &quot;'&quot;));
</ins><span class="cx"> 
</span><del>-            hasProperty = globalLexicalEnvironment-&gt;hasProperty(exec, entry.key.get());
</del><ins>+            bool hasProperty = globalLexicalEnvironment-&gt;hasProperty(exec, entry.key.get());
</ins><span class="cx">             RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
</span><span class="cx">             if (hasProperty) {
</span><span class="cx">                 if (UNLIKELY(entry.value.isConst() &amp;&amp; !vm.globalConstRedeclarationShouldThrow() &amp;&amp; !isStrictMode())) {
</span></span></pre>
</div>
</div>

</body>
</html>