Changeset 270664 in webkit


Ignore:
Timestamp:
Dec 10, 2020 8:14:18 PM (20 months ago)
Author:
Alexey Shvayka
Message:

Align DefineOwnProperty? method of mapped arguments object with the spec
https://bugs.webkit.org/show_bug.cgi?id=219750

Reviewed by Yusuke Suzuki.

JSTests:

  • test262/expectations.yaml: Mark 5 test cases as passing.

Source/JavaScriptCore:

This patch reimplements DefineOwnProperty? method to resemble the spec [1] as
closely as possible, aligning JSC with V8 and SpiderMonkey on remaining test262 cases.

Unlike the spec [2], JSC doesn't materialize mapped indices with initial values,
so putDirectIndex() is performed on the first call to handle incomplete descriptors.

Even though there is a possibility to avoid JSObject storage puts for a handful of
super rare descriptors, it's not worth the increased complexity.

[1]: https://tc39.es/ecma262/#sec-arguments-exotic-objects-defineownproperty-p-desc
[2]: https://tc39.es/ecma262/#sec-createmappedargumentsobject (step 15.b)

  • runtime/GenericArgumentsInlines.h:

(JSC::GenericArguments<Type>::defineOwnProperty):

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r270608 r270664  
     12020-12-10  Alexey Shvayka  <shvaikalesh@gmail.com>
     2
     3        Align [[DefineOwnProperty]] method of mapped arguments object with the spec
     4        https://bugs.webkit.org/show_bug.cgi?id=219750
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        * test262/expectations.yaml: Mark 5 test cases as passing.
     9
    1102020-12-09  Michael Catanzaro  <mcatanzaro@gnome.org>
    211
  • trunk/JSTests/test262/expectations.yaml

    r270552 r270664  
    908908  default: 'Test262Error: "und".minimize() should be "en" Expected SameValue(«en-u-va-posix», «en») to be true'
    909909  strict mode: 'Test262Error: "und".minimize() should be "en" Expected SameValue(«en-u-va-posix», «en») to be true'
    910 test/language/arguments-object/mapped/nonconfigurable-nonenumerable-nonwritable-descriptors-set-by-arguments.js:
    911   default: 'Test262Error: Expected obj[0] to have enumerable:false.'
    912 test/language/arguments-object/mapped/nonconfigurable-nonenumerable-nonwritable-descriptors-set-by-param.js:
    913   default: 'Test262Error: Expected obj[0] to have enumerable:false.'
    914 test/language/arguments-object/mapped/nonconfigurable-nonwritable-descriptors-define-property-consecutive.js:
    915   default: 'Test262Error: Expected obj[0] to have configurable:false.'
    916 test/language/arguments-object/mapped/nonconfigurable-nonwritable-descriptors-set-by-arguments.js:
    917   default: 'Test262Error: Expected obj[0] to have configurable:false.'
    918 test/language/arguments-object/mapped/nonconfigurable-nonwritable-descriptors-set-by-param.js:
    919   default: 'Test262Error: Expected obj[0] to have configurable:false.'
    920910test/language/block-scope/syntax/redeclaration/async-function-name-redeclaration-attempt-with-async-function.js:
    921911  default: 'Test262: This statement should not be evaluated.'
  • trunk/Source/JavaScriptCore/ChangeLog

    r270659 r270664  
     12020-12-10  Alexey Shvayka  <shvaikalesh@gmail.com>
     2
     3        Align [[DefineOwnProperty]] method of mapped arguments object with the spec
     4        https://bugs.webkit.org/show_bug.cgi?id=219750
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        This patch reimplements [[DefineOwnProperty]] method to resemble the spec [1] as
     9        closely as possible, aligning JSC with V8 and SpiderMonkey on remaining test262 cases.
     10
     11        Unlike the spec [2], JSC doesn't materialize mapped indices with initial values,
     12        so putDirectIndex() is performed on the first call to handle incomplete descriptors.
     13
     14        Even though there is a possibility to avoid JSObject storage puts for a handful of
     15        super rare descriptors, it's not worth the increased complexity.
     16
     17        [1]: https://tc39.es/ecma262/#sec-arguments-exotic-objects-defineownproperty-p-desc
     18        [2]: https://tc39.es/ecma262/#sec-createmappedargumentsobject (step 15.b)
     19
     20        * runtime/GenericArgumentsInlines.h:
     21        (JSC::GenericArguments<Type>::defineOwnProperty):
     22
    1232020-12-10  Tadeu Zagallo  <tzagallo@apple.com>
    224
  • trunk/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h

    r257399 r270664  
    210210}
    211211
     212// https://tc39.es/ecma262/#sec-arguments-exotic-objects-defineownproperty-p-desc
    212213template<typename Type>
    213214bool GenericArguments<Type>::defineOwnProperty(JSObject* object, JSGlobalObject* globalObject, PropertyName ident, const PropertyDescriptor& descriptor, bool shouldThrow)
     
    222223        thisObject->overrideThingsIfNecessary(globalObject);
    223224        RETURN_IF_EXCEPTION(scope, false);
    224     } else {
    225         Optional<uint32_t> optionalIndex = parseIndex(ident);
    226         if (optionalIndex) {
    227             uint32_t index = optionalIndex.value();
    228             if (!descriptor.isAccessorDescriptor() && thisObject->isMappedArgument(optionalIndex.value())) {
    229                 // If the property is not deleted and we are using a non-accessor descriptor, then
    230                 // make sure that the aliased argument sees the value.
     225    } else if (Optional<uint32_t> optionalIndex = parseIndex(ident)) {
     226        uint32_t index = optionalIndex.value();
     227        bool isMapped = thisObject->isMappedArgument(index);
     228        PropertyDescriptor newDescriptor = descriptor;
     229
     230        if (isMapped) {
     231            if (thisObject->isModifiedArgumentDescriptor(index)) {
     232                if (!descriptor.value() && descriptor.writablePresent() && !descriptor.writable())
     233                    newDescriptor.setValue(thisObject->getIndexQuickly(index));
     234            } else
     235                thisObject->putDirectIndex(globalObject, index, thisObject->getIndexQuickly(index));
     236
     237            scope.assertNoException();
     238        }
     239
     240        bool status = thisObject->defineOwnIndexedProperty(globalObject, index, newDescriptor, shouldThrow);
     241        if (!status) {
     242            ASSERT(!isMapped || thisObject->isModifiedArgumentDescriptor(index));
     243            RELEASE_AND_RETURN(scope, false);
     244        }
     245
     246        scope.assertNoException();
     247        thisObject->setModifiedArgumentDescriptor(globalObject, index);
     248        RETURN_IF_EXCEPTION(scope, false);
     249
     250        if (isMapped) {
     251            if (descriptor.isAccessorDescriptor())
     252                thisObject->unmapArgument(globalObject, index);
     253            else {
    231254                if (descriptor.value())
    232255                    thisObject->setIndexQuickly(vm, index, descriptor.value());
    233            
    234                 // If the property is not deleted and we are using a non-accessor, writable,
    235                 // configurable and enumerable descriptor and isn't modified, then we are done.
    236                 // The argument continues to be aliased.
    237                 if (descriptor.writable() && descriptor.configurable() && descriptor.enumerable() && !thisObject->isModifiedArgumentDescriptor(index))
    238                     return true;
    239                
    240                 if (!thisObject->isModifiedArgumentDescriptor(index)) {
    241                     // If it is a new entry, we need to put direct to initialize argument[i] descriptor properly
    242                     JSValue value = thisObject->getIndexQuickly(index);
    243                     ASSERT(value);
    244                     object->putDirectMayBeIndex(globalObject, ident, value);
    245                     scope.assertNoException();
    246 
    247                     thisObject->setModifiedArgumentDescriptor(globalObject, index);
    248                     RETURN_IF_EXCEPTION(scope, false);
    249                 }
     256                if (descriptor.writablePresent() && !descriptor.writable())
     257                    thisObject->unmapArgument(globalObject, index);
    250258            }
    251            
    252             if (thisObject->isMappedArgument(index)) {
    253                 // Just unmap arguments if its descriptor contains {writable: false}.
    254                 // Check https://tc39.github.io/ecma262/#sec-createunmappedargumentsobject
    255                 // and https://tc39.github.io/ecma262/#sec-createmappedargumentsobject to verify that all data
    256                 // property from arguments object are {writable: true, configurable: true, enumerable: true} by default
    257                 if ((descriptor.writablePresent() && !descriptor.writable()) || descriptor.isAccessorDescriptor()) {
    258                     if (!descriptor.isAccessorDescriptor()) {
    259                         JSValue value = thisObject->getIndexQuickly(index);
    260                         ASSERT(value);
    261                         object->putDirectMayBeIndex(globalObject, ident, value);
    262                         scope.assertNoException();
    263                     }
    264                     thisObject->unmapArgument(globalObject, index);
    265                     RETURN_IF_EXCEPTION(scope, false);
    266                     thisObject->setModifiedArgumentDescriptor(globalObject, index);
    267                     RETURN_IF_EXCEPTION(scope, false);
    268                 }
    269             }
    270         }
    271     }
    272 
    273     // Now just let the normal object machinery do its thing.
     259
     260            RETURN_IF_EXCEPTION(scope, false);
     261        }
     262
     263        return true;
     264    }
     265
    274266    RELEASE_AND_RETURN(scope, Base::defineOwnProperty(object, globalObject, ident, descriptor, shouldThrow));
    275267}
Note: See TracChangeset for help on using the changeset viewer.