Changeset 180564 in webkit


Ignore:
Timestamp:
Feb 24, 2015, 9:08:06 AM (11 years ago)
Author:
fpizlo@apple.com
Message:

Our bizarre behavior on Arguments::defineOwnProperty should be deliberate rather than a spaghetti incident
https://bugs.webkit.org/show_bug.cgi?id=141951

Reviewed by Benjamin Poulain.

This patch has no behavioral change, but it simplifies a bunch of wrong code. The code is
still wrong in exactly the same way, but at least it's obvious what's going on. The wrongness
is covered by this bug: https://bugs.webkit.org/show_bug.cgi?id=141952.

  • runtime/Arguments.cpp:

(JSC::Arguments::copyBackingStore): We should only see the arguments token; assert otherwise. This works because if the GC sees the butterfly token it calls the JSObject::copyBackingStore method directly.
(JSC::Arguments::defineOwnProperty): Make our bizarre behavior deliberate rather than an accident of a decade of patches.

  • tests/stress/arguments-bizarre-behavior.js: Added.

(foo):

  • tests/stress/arguments-bizarre-behaviour-disable-enumerability.js: Added. My choice of spellings of the word "behavio[u]r" is almost as consistent as our implementation of arguments.

(foo):

  • tests/stress/arguments-custom-properties-gc.js: Added. I added this test because at first I was unsure if we GCd arguments correctly.

(makeBaseArguments):
(makeArray):
(cons):

Location:
trunk/Source/JavaScriptCore
Files:
3 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r180551 r180564  
     12015-02-23  Filip Pizlo  <fpizlo@apple.com>
     2
     3        Our bizarre behavior on Arguments::defineOwnProperty should be deliberate rather than a spaghetti incident
     4        https://bugs.webkit.org/show_bug.cgi?id=141951
     5
     6        Reviewed by Benjamin Poulain.
     7       
     8        This patch has no behavioral change, but it simplifies a bunch of wrong code. The code is
     9        still wrong in exactly the same way, but at least it's obvious what's going on. The wrongness
     10        is covered by this bug: https://bugs.webkit.org/show_bug.cgi?id=141952.
     11
     12        * runtime/Arguments.cpp:
     13        (JSC::Arguments::copyBackingStore): We should only see the arguments token; assert otherwise. This works because if the GC sees the butterfly token it calls the JSObject::copyBackingStore method directly.
     14        (JSC::Arguments::defineOwnProperty): Make our bizarre behavior deliberate rather than an accident of a decade of patches.
     15        * tests/stress/arguments-bizarre-behavior.js: Added.
     16        (foo):
     17        * tests/stress/arguments-bizarre-behaviour-disable-enumerability.js: Added. My choice of spellings of the word "behavio[u]r" is almost as consistent as our implementation of arguments.
     18        (foo):
     19        * tests/stress/arguments-custom-properties-gc.js: Added. I added this test because at first I was unsure if we GCd arguments correctly.
     20        (makeBaseArguments):
     21        (makeArray):
     22        (cons):
     23
    1242015-02-23  Commit Queue  <commit-queue@webkit.org>
    225
  • trunk/Source/JavaScriptCore/runtime/Arguments.cpp

    r179887 r180564  
    8282
    8383    default:
    84         return;
     84        RELEASE_ASSERT_NOT_REACHED();
    8585    }
    8686}
     
    296296    if (i < thisObject->m_numArguments) {
    297297        RELEASE_ASSERT(i < PropertyName::NotAnIndex);
    298         // If the property is not yet present on the object, and is not yet marked as deleted, then add it now.
    299         PropertySlot slot(thisObject);
    300         if (!thisObject->isDeletedArgument(i) && !JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot)) {
     298       
     299        if (thisObject->isArgument(i)) {
     300            if (!descriptor.isAccessorDescriptor()) {
     301                // If the property is not deleted and we are using a non-accessor descriptor, then
     302                // make sure that the aliased argument sees the value.
     303                if (descriptor.value())
     304                    thisObject->trySetArgument(exec->vm(), i, descriptor.value());
     305           
     306                // If the property is not deleted and we are using a non-accessor, writable
     307                // descriptor, then we are done. The argument continues to be aliased. Note that we
     308                // ignore the request to change enumerability. We appear to have always done so, in
     309                // cases where the argument was still aliased.
     310                // FIXME: https://bugs.webkit.org/show_bug.cgi?id=141952
     311                if (descriptor.writable())
     312                    return true;
     313            }
     314           
     315            // If the property is a non-deleted argument, then move it into the base object and then
     316            // delete it.
    301317            JSValue value = thisObject->tryGetArgument(i);
    302318            ASSERT(value);
    303319            object->putDirectMayBeIndex(exec, propertyName, value);
    304         }
    305         if (!Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow))
    306             return false;
    307 
    308         // From ES 5.1, 10.6 Arguments Object
    309         // 5. If the value of isMapped is not undefined, then
    310         if (thisObject->isArgument(i)) {
    311             // a. If IsAccessorDescriptor(Desc) is true, then
    312             if (descriptor.isAccessorDescriptor()) {
    313                 // i. Call the [[Delete]] internal method of map passing P, and false as the arguments.
    314                 thisObject->tryDeleteArgument(exec->vm(), i);
    315             } else { // b. Else
    316                 // i. If Desc.[[Value]] is present, then
    317                 // 1. Call the [[Put]] internal method of map passing P, Desc.[[Value]], and Throw as the arguments.
    318                 if (descriptor.value())
    319                     thisObject->trySetArgument(exec->vm(), i, descriptor.value());
    320                 // ii. If Desc.[[Writable]] is present and its value is false, then
    321                 // 1. Call the [[Delete]] internal method of map passing P and false as arguments.
    322                 if (descriptor.writablePresent() && !descriptor.writable())
    323                     thisObject->tryDeleteArgument(exec->vm(), i);
    324             }
    325         }
    326         return true;
     320            thisObject->tryDeleteArgument(exec->vm(), i);
     321        }
     322       
     323        // Now just let the normal object machinery do its thing.
     324        return Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow);
    327325    }
    328326
Note: See TracChangeset for help on using the changeset viewer.