<!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>[201834] trunk/Source</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/201834">201834</a></dd>
<dt>Author</dt> <dd>barraclough@apple.com</dd>
<dt>Date</dt> <dd>2016-06-08 14:49:32 -0700 (Wed, 08 Jun 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Remove removeDirect
https://bugs.webkit.org/show_bug.cgi?id=158516

Reviewed by Ryosuke Niwa.

removeDirect is typically used as a subroutine of deleteProperty, but is also available to
call directly. Having this functionality factored out to a separate routine is a bad idea
on a couple of fronts:

- for the main use within deleteProperty there is redundancy (presence of the property
  was being checked twice) and inconsistency (the two functions returned different results
  in the case of a nonexistent property; the result from removeDirect was never observed).

- all uses of removeDirect are in practical terms incorrect. removeDirect had the
  advantage of ignoring the configurable (DontDelete) attributes, but this is achievable
  using the DeletePropertyMode setting - and the disadvantage of failing delete static
  table properties. Last uses were one that was removed in bug #158295 (where failure to
  delete static properties was a problem), and as addressed in this patch removeDirect is
  being used to implement runtime enabled features. This only works because we currently
  force reification of all properties on the DOM prototype objects, so in effect there are
  no static properties. In order to make the code robust such that runtime enabled
  features would still work even if we were not reifying static properties (a change we
  may want to make) we should be calling deleteProperty in this case too.

Source/JavaScriptCore:

* runtime/JSObject.cpp:
(JSC::JSObject::deleteProperty):
    - incorporated removeDirect functionality, added comments &amp; ASSERT.
(JSC::JSObject::removeDirect): Deleted.
    - removed.
* runtime/JSObject.h:
    - removed removeDirect.

Source/WebCore:

* bindings/scripts/CodeGeneratorJS.pm:
(GenerateImplementation):
    - changed to call deleteProperty instead of removeDirect.
* bindings/scripts/test/JS/JSTestObj.cpp:
(WebCore::JSTestObjPrototype::finishCreation):
    - updated bindings test results.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSObjectcpp">trunk/Source/JavaScriptCore/runtime/JSObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSObjecth">trunk/Source/JavaScriptCore/runtime/JSObject.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptsCodeGeneratorJSpm">trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestJSJSTestObjcpp">trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (201833 => 201834)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-06-08 21:17:54 UTC (rev 201833)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-06-08 21:49:32 UTC (rev 201834)
</span><span class="lines">@@ -1,3 +1,37 @@
</span><ins>+2016-06-08  Gavin Barraclough  &lt;barraclough@apple.com&gt;
+
+        Remove removeDirect
+        https://bugs.webkit.org/show_bug.cgi?id=158516
+
+        Reviewed by Ryosuke Niwa.
+
+        removeDirect is typically used as a subroutine of deleteProperty, but is also available to
+        call directly. Having this functionality factored out to a separate routine is a bad idea
+        on a couple of fronts:
+
+        - for the main use within deleteProperty there is redundancy (presence of the property
+          was being checked twice) and inconsistency (the two functions returned different results
+          in the case of a nonexistent property; the result from removeDirect was never observed).
+
+        - all uses of removeDirect are in practical terms incorrect. removeDirect had the
+          advantage of ignoring the configurable (DontDelete) attributes, but this is achievable
+          using the DeletePropertyMode setting - and the disadvantage of failing delete static
+          table properties. Last uses were one that was removed in bug #158295 (where failure to
+          delete static properties was a problem), and as addressed in this patch removeDirect is
+          being used to implement runtime enabled features. This only works because we currently
+          force reification of all properties on the DOM prototype objects, so in effect there are
+          no static properties. In order to make the code robust such that runtime enabled
+          features would still work even if we were not reifying static properties (a change we
+          may want to make) we should be calling deleteProperty in this case too.
+
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::deleteProperty):
+            - incorporated removeDirect functionality, added comments &amp; ASSERT.
+        (JSC::JSObject::removeDirect): Deleted.
+            - removed.
+        * runtime/JSObject.h:
+            - removed removeDirect.
+
</ins><span class="cx"> 2016-06-08  Mark Lam  &lt;mark.lam@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Simplify Interpreter::StackFrame.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSObject.cpp (201833 => 201834)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSObject.cpp        2016-06-08 21:17:54 UTC (rev 201833)
+++ trunk/Source/JavaScriptCore/runtime/JSObject.cpp        2016-06-08 21:49:32 UTC (rev 201834)
</span><span class="lines">@@ -1496,19 +1496,36 @@
</span><span class="cx">     if (Optional&lt;uint32_t&gt; index = parseIndex(propertyName))
</span><span class="cx">         return thisObject-&gt;methodTable(vm)-&gt;deletePropertyByIndex(thisObject, exec, index.value());
</span><span class="cx"> 
</span><ins>+    unsigned attributes;
+
</ins><span class="cx">     if (!thisObject-&gt;staticFunctionsReified()) {
</span><span class="cx">         if (auto* entry = thisObject-&gt;findPropertyHashEntry(propertyName)) {
</span><del>-            if (entry-&gt;attributes() &amp; DontDelete &amp;&amp; vm.deletePropertyMode() != VM::DeletePropertyMode::IgnoreConfigurable)
</del><ins>+            // If the static table contains a non-configurable (DontDelete) property then we can return early;
+            // if there is a property in the storage array it too must be non-configurable (the language does
+            // not allow repacement of a non-configurable property with a configurable one).
+            if (entry-&gt;attributes() &amp; DontDelete &amp;&amp; vm.deletePropertyMode() != VM::DeletePropertyMode::IgnoreConfigurable) {
+                ASSERT(!isValidOffset(thisObject-&gt;structure(vm)-&gt;get(vm, propertyName, attributes)) || attributes &amp; DontDelete);
</ins><span class="cx">                 return false;
</span><ins>+            }
</ins><span class="cx">             thisObject-&gt;reifyAllStaticProperties(exec);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    unsigned attributes;
-    if (isValidOffset(thisObject-&gt;structure(vm)-&gt;get(vm, propertyName, attributes))) {
</del><ins>+    Structure* structure = thisObject-&gt;structure(vm);
+
+    bool propertyIsPresent = isValidOffset(structure-&gt;get(vm, propertyName, attributes));
+    if (propertyIsPresent) {
</ins><span class="cx">         if (attributes &amp; DontDelete &amp;&amp; vm.deletePropertyMode() != VM::DeletePropertyMode::IgnoreConfigurable)
</span><span class="cx">             return false;
</span><del>-        thisObject-&gt;removeDirect(vm, propertyName);
</del><ins>+
+        PropertyOffset offset;
+        if (structure-&gt;isUncacheableDictionary())
+            offset = structure-&gt;removePropertyWithoutTransition(vm, propertyName);
+        else
+            thisObject-&gt;setStructure(vm, Structure::removePropertyTransition(vm, structure, propertyName, offset));
+
+        if (offset != invalidOffset)
+            thisObject-&gt;putDirectUndefined(offset);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return true;
</span><span class="lines">@@ -1978,28 +1995,6 @@
</span><span class="cx">     structure(vm)-&gt;setStaticFunctionsReified(true);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool JSObject::removeDirect(VM&amp; vm, PropertyName propertyName)
-{
-    Structure* structure = this-&gt;structure(vm);
-    if (!isValidOffset(structure-&gt;get(vm, propertyName)))
-        return false;
-
-    PropertyOffset offset;
-    if (structure-&gt;isUncacheableDictionary()) {
-        offset = structure-&gt;removePropertyWithoutTransition(vm, propertyName);
-        if (offset == invalidOffset)
-            return false;
-        putDirectUndefined(offset);
-        return true;
-    }
-
-    setStructure(vm, Structure::removePropertyTransition(vm, structure, propertyName, offset));
-    if (offset == invalidOffset)
-        return false;
-    putDirectUndefined(offset);
-    return true;
-}
-
</del><span class="cx"> NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot&amp; slot, JSValue getterSetter, unsigned attributes, PropertyOffset offset)
</span><span class="cx"> {
</span><span class="cx">     if (structure()-&gt;isUncacheableDictionary()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSObject.h (201833 => 201834)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSObject.h        2016-06-08 21:17:54 UTC (rev 201833)
+++ trunk/Source/JavaScriptCore/runtime/JSObject.h        2016-06-08 21:49:32 UTC (rev 201834)
</span><span class="lines">@@ -622,7 +622,6 @@
</span><span class="cx"> 
</span><span class="cx">     void transitionTo(VM&amp;, Structure*);
</span><span class="cx"> 
</span><del>-    JS_EXPORT_PRIVATE bool removeDirect(VM&amp;, PropertyName); // Return true if anything is removed.
</del><span class="cx">     bool hasCustomProperties() { return structure()-&gt;didTransition(); }
</span><span class="cx">     bool hasGetterSetterProperties() { return structure()-&gt;hasGetterSetterProperties(); }
</span><span class="cx">     bool hasCustomGetterSetterProperties() { return structure()-&gt;hasCustomGetterSetterProperties(); }
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (201833 => 201834)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-06-08 21:17:54 UTC (rev 201833)
+++ trunk/Source/WebCore/ChangeLog        2016-06-08 21:49:32 UTC (rev 201834)
</span><span class="lines">@@ -1,3 +1,36 @@
</span><ins>+2016-06-08  Gavin Barraclough  &lt;barraclough@apple.com&gt;
+
+        Remove removeDirect
+        https://bugs.webkit.org/show_bug.cgi?id=158516
+
+        Reviewed by Ryosuke Niwa.
+
+        removeDirect is typically used as a subroutine of deleteProperty, but is also available to
+        call directly. Having this functionality factored out to a separate routine is a bad idea
+        on a couple of fronts:
+
+        - for the main use within deleteProperty there is redundancy (presence of the property
+          was being checked twice) and inconsistency (the two functions returned different results
+          in the case of a nonexistent property; the result from removeDirect was never observed).
+
+        - all uses of removeDirect are in practical terms incorrect. removeDirect had the
+          advantage of ignoring the configurable (DontDelete) attributes, but this is achievable
+          using the DeletePropertyMode setting - and the disadvantage of failing delete static
+          table properties. Last uses were one that was removed in bug #158295 (where failure to
+          delete static properties was a problem), and as addressed in this patch removeDirect is
+          being used to implement runtime enabled features. This only works because we currently
+          force reification of all properties on the DOM prototype objects, so in effect there are
+          no static properties. In order to make the code robust such that runtime enabled
+          features would still work even if we were not reifying static properties (a change we
+          may want to make) we should be calling deleteProperty in this case too.
+
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateImplementation):
+            - changed to call deleteProperty instead of removeDirect.
+        * bindings/scripts/test/JS/JSTestObj.cpp:
+        (WebCore::JSTestObjPrototype::finishCreation):
+            - updated bindings test results.
+
</ins><span class="cx"> 2016-06-08  Nan Wang  &lt;n_wang@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         For keyboard users, activating a fragment URL should transfer focus and caret to the destination
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptsCodeGeneratorJSpm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (201833 => 201834)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm        2016-06-08 21:17:54 UTC (rev 201833)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm        2016-06-08 21:49:32 UTC (rev 201834)
</span><span class="lines">@@ -2282,7 +2282,8 @@
</span><span class="cx">             my $name = $signature-&gt;name;
</span><span class="cx">             push(@implContent, &quot;    if (!${enable_function}()) {\n&quot;);
</span><span class="cx">             push(@implContent, &quot;        Identifier propertyName = Identifier::fromString(&amp;vm, reinterpret_cast&lt;const LChar*&gt;(\&quot;$name\&quot;), strlen(\&quot;$name\&quot;));\n&quot;);
</span><del>-            push(@implContent, &quot;        removeDirect(vm, propertyName);\n&quot;);
</del><ins>+            push(@implContent, &quot;        VM::DeletePropertyModeScope scope(vm, VM::DeletePropertyMode::IgnoreConfigurable);\n&quot;);
+            push(@implContent, &quot;        JSObject::deleteProperty(this, globalObject()-&gt;globalExec(), propertyName);\n&quot;);
</ins><span class="cx">             push(@implContent, &quot;    }\n&quot;);
</span><span class="cx">             push(@implContent, &quot;#endif\n&quot;) if $conditionalString;
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestJSJSTestObjcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp (201833 => 201834)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp        2016-06-08 21:17:54 UTC (rev 201833)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp        2016-06-08 21:49:32 UTC (rev 201834)
</span><span class="lines">@@ -1310,13 +1310,15 @@
</span><span class="cx"> #if ENABLE(TEST_FEATURE)
</span><span class="cx">     if (!RuntimeEnabledFeatures::sharedFeatures().testFeatureEnabled()) {
</span><span class="cx">         Identifier propertyName = Identifier::fromString(&amp;vm, reinterpret_cast&lt;const LChar*&gt;(&quot;enabledAtRuntimeOperation&quot;), strlen(&quot;enabledAtRuntimeOperation&quot;));
</span><del>-        removeDirect(vm, propertyName);
</del><ins>+        VM::DeletePropertyModeScope scope(vm, VM::DeletePropertyMode::IgnoreConfigurable);
+        JSObject::deleteProperty(this, globalObject()-&gt;globalExec(), propertyName);
</ins><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="cx"> #if ENABLE(TEST_FEATURE)
</span><span class="cx">     if (!RuntimeEnabledFeatures::sharedFeatures().testFeatureEnabled()) {
</span><span class="cx">         Identifier propertyName = Identifier::fromString(&amp;vm, reinterpret_cast&lt;const LChar*&gt;(&quot;enabledAtRuntimeAttribute&quot;), strlen(&quot;enabledAtRuntimeAttribute&quot;));
</span><del>-        removeDirect(vm, propertyName);
</del><ins>+        VM::DeletePropertyModeScope scope(vm, VM::DeletePropertyMode::IgnoreConfigurable);
+        JSObject::deleteProperty(this, globalObject()-&gt;globalExec(), propertyName);
</ins><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="cx">     JSVMClientData&amp; clientData = *static_cast&lt;JSVMClientData*&gt;(vm.clientData);
</span></span></pre>
</div>
</div>

</body>
</html>