Changeset 216279 in webkit


Ignore:
Timestamp:
May 5, 2017 3:35:31 PM (7 years ago)
Author:
sbarati@apple.com
Message:

putDirectIndex does not properly do defineOwnProperty
https://bugs.webkit.org/show_bug.cgi?id=171591
<rdar://problem/31735695>

Reviewed by Geoffrey Garen.

JSTests:

  • stress/array-prototype-splice-making-typed-array.js:

(test):

  • stress/array-species-config-array-constructor.js:

(shouldThrow):
(test):

  • stress/put-direct-index-broken-2.js: Added.

(assert):
(test):
(makeLengthWritable):
(set get restoreOldDesc):

  • stress/put-direct-index-broken.js: Added.

(whatToTest):
(tryRunning):
(tryItOut):

  • stress/put-indexed-getter-setter.js: Added.

(foo.X.prototype.set 7):
(foo.X.prototype.get 7):
(foo.X):
(foo):

Source/JavaScriptCore:

This patch fixes putDirectIndex and its JIT implementations to be
compatible with the ES6 spec. I think our code became out of date
when we implemented ArraySpeciesCreate since ArraySpeciesCreate may
return arbitrary objects. We perform putDirectIndex on that arbitrary
object. The behavior we want is as if we performed defineProperty({configurable:true, enumerable:true, writable:true}).
However, we weren't doing this. putDirectIndex assumed it could just splat
data into any descendent of JSObject's butterfly. For example, this means
we'd just splat into the butterfly of a typed array, even though a typed
array doesn't use its butterfly to store its indexed properties in the usual
way. Also, typed array properties are non-configurable, so this operation
should throw. This also means if we saw a ProxyObject, we'd just splat
into its butterfly, but this is obviously wrong because ProxyObject should
intercept the defineProperty operation.

This patch fixes this issue by adding a whitelist of cell types that can
go down putDirectIndex's fast path. Anything not in that whitelist will
simply call into defineOwnProperty.

  • bytecode/ByValInfo.h:

(JSC::jitArrayModePermitsPutDirect):

  • dfg/DFGArrayMode.cpp:

(JSC::DFG::ArrayMode::refine):

  • jit/JITOperations.cpp:
  • runtime/ArrayPrototype.cpp:

(JSC::arrayProtoFuncSplice):

  • runtime/ClonedArguments.cpp:

(JSC::ClonedArguments::createStructure):

  • runtime/JSGenericTypedArrayViewInlines.h:

(JSC::JSGenericTypedArrayView<Adaptor>::defineOwnProperty):

  • runtime/JSObject.cpp:

(JSC::canDoFastPutDirectIndex):
(JSC::JSObject::defineOwnIndexedProperty):
(JSC::JSObject::putDirectIndexSlowOrBeyondVectorLength):
(JSC::JSObject::putDirectIndexBeyondVectorLength): Deleted.

  • runtime/JSObject.h:

(JSC::JSObject::putDirectIndex):
(JSC::JSObject::canSetIndexQuicklyForPutDirect): Deleted.

  • runtime/JSType.h:
Location:
trunk
Files:
3 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r216178 r216279  
     12017-05-05  Saam Barati  <sbarati@apple.com>
     2
     3        putDirectIndex does not properly do defineOwnProperty
     4        https://bugs.webkit.org/show_bug.cgi?id=171591
     5        <rdar://problem/31735695>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        * stress/array-prototype-splice-making-typed-array.js:
     10        (test):
     11        * stress/array-species-config-array-constructor.js:
     12        (shouldThrow):
     13        (test):
     14        * stress/put-direct-index-broken-2.js: Added.
     15        (assert):
     16        (test):
     17        (makeLengthWritable):
     18        (set get restoreOldDesc):
     19        * stress/put-direct-index-broken.js: Added.
     20        (whatToTest):
     21        (tryRunning):
     22        (tryItOut):
     23        * stress/put-indexed-getter-setter.js: Added.
     24        (foo.X.prototype.set 7):
     25        (foo.X.prototype.get 7):
     26        (foo.X):
     27        (foo):
     28
    1292017-05-04  Yusuke Suzuki  <utatane.tea@gmail.com>
    230
  • trunk/JSTests/stress/array-prototype-splice-making-typed-array.js

    r203087 r216279  
    1111test(function() {
    1212    // This should not crash.
    13 
    14     // FIXME: this might need to be updated as we make our splice implementation
    15     // more ES6 compliant: https://bugs.webkit.org/show_bug.cgi?id=159645
    1613    let x = [1,2,3,4,5];
    1714    x.constructor = Uint8Array;
    1815    delete x[2];
    1916    assert(!(2 in x));
    20     let removed = x.splice(1,3);
    21     assert(removed instanceof Uint8Array);
    22     assert(removed.length === 3);
    23     assert(removed[0] === 2);
    24     assert(removed[1] === 0);
    25     assert(removed[2] === 4);
     17    let err = null;
     18    try {
     19        let removed = x.splice(1,3);
     20        assert(removed instanceof Uint8Array);
     21        assert(removed.length === 3);
     22        assert(removed[0] === 2);
     23        assert(removed[1] === 0);
     24        assert(removed[2] === 4);
     25    } catch(e) {
     26        err = e;
     27    }
     28    assert(err.toString() === "TypeError: Attempting to configure non-configurable property on a typed array at index: 0");
    2629
    2730    assert(x instanceof Array);
    28     assert(x.length === 2);
     31    assert(x.length === 5);
    2932    assert(x[0] === 1);
    30     assert(x[1] === 5);
     33    assert(x[1] === 2);
     34    assert(x[2] === undefined);
     35    assert(x[3] === 4);
     36    assert(x[4] === 5);
    3137});
    3238
  • trunk/JSTests/stress/array-species-config-array-constructor.js

    r202125 r216279  
    2020Object.defineProperty(Int32Array.prototype, "length", { value: 0, writable: true });
    2121
    22 result = foo.concat([1]);
    23 if (!(result instanceof Int32Array))
    24     throw "concat failed";
     22function shouldThrow(f, m) {
     23    let err;
     24    try {
     25        f();
     26    } catch(e) {
     27        err = e;
     28    }
     29    if (err.toString() !== m)
     30        throw new Error("Wrong error: " + err);
     31}
    2532
    26 result = foo.splice();
    27 if (!(result instanceof Int32Array))
    28     throw "splice failed";
    29 
    30 result = foo.slice();
    31 if (!(result instanceof Int32Array))
    32     throw "slice failed";
     33function test() {
     34    const message = "TypeError: Attempting to configure non-configurable property on a typed array at index: 0";
     35    shouldThrow(() => foo.concat([1]), message);
     36    foo = [1,2,3,4];
     37    shouldThrow(() => foo.slice(0), message);
     38    foo = [1,2,3,4];
     39    let r = foo.splice();
     40    if (!(r instanceof Int32Array))
     41        throw "Bad";
     42    if (r.length !== 0)
     43        throw "Bad";
     44    foo = [1,2,3,4];
     45    shouldThrow(() => foo.splice(0), message);
     46}
     47noInline(test);
     48for (let i = 0; i < 3000; ++i)
     49    test();
  • trunk/Source/JavaScriptCore/ChangeLog

    r216264 r216279  
     12017-05-05  Saam Barati  <sbarati@apple.com>
     2
     3        putDirectIndex does not properly do defineOwnProperty
     4        https://bugs.webkit.org/show_bug.cgi?id=171591
     5        <rdar://problem/31735695>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        This patch fixes putDirectIndex and its JIT implementations to be
     10        compatible with the ES6 spec. I think our code became out of date
     11        when we implemented ArraySpeciesCreate since ArraySpeciesCreate may
     12        return arbitrary objects. We perform putDirectIndex on that arbitrary
     13        object. The behavior we want is as if we performed defineProperty({configurable:true, enumerable:true, writable:true}).
     14        However, we weren't doing this. putDirectIndex assumed it could just splat
     15        data into any descendent of JSObject's butterfly. For example, this means
     16        we'd just splat into the butterfly of a typed array, even though a typed
     17        array doesn't use its butterfly to store its indexed properties in the usual
     18        way. Also, typed array properties are non-configurable, so this operation
     19        should throw. This also means if we saw a ProxyObject, we'd just splat
     20        into its butterfly, but this is obviously wrong because ProxyObject should
     21        intercept the defineProperty operation.
     22       
     23        This patch fixes this issue by adding a whitelist of cell types that can
     24        go down putDirectIndex's fast path. Anything not in that whitelist will
     25        simply call into defineOwnProperty.
     26
     27        * bytecode/ByValInfo.h:
     28        (JSC::jitArrayModePermitsPutDirect):
     29        * dfg/DFGArrayMode.cpp:
     30        (JSC::DFG::ArrayMode::refine):
     31        * jit/JITOperations.cpp:
     32        * runtime/ArrayPrototype.cpp:
     33        (JSC::arrayProtoFuncSplice):
     34        * runtime/ClonedArguments.cpp:
     35        (JSC::ClonedArguments::createStructure):
     36        * runtime/JSGenericTypedArrayViewInlines.h:
     37        (JSC::JSGenericTypedArrayView<Adaptor>::defineOwnProperty):
     38        * runtime/JSObject.cpp:
     39        (JSC::canDoFastPutDirectIndex):
     40        (JSC::JSObject::defineOwnIndexedProperty):
     41        (JSC::JSObject::putDirectIndexSlowOrBeyondVectorLength):
     42        (JSC::JSObject::putDirectIndexBeyondVectorLength): Deleted.
     43        * runtime/JSObject.h:
     44        (JSC::JSObject::putDirectIndex):
     45        (JSC::JSObject::canSetIndexQuicklyForPutDirect): Deleted.
     46        * runtime/JSType.h:
     47
    1482017-05-05  Guillaume Emont  <guijemont@igalia.com>
    249
  • trunk/Source/JavaScriptCore/bytecode/ByValInfo.h

    r206525 r216279  
    165165}
    166166
     167inline bool jitArrayModePermitsPutDirect(JITArrayMode mode)
     168{
     169    // We don't allow typed array putDirect here since putDirect has
     170    // defineOwnProperty({configurable: true, writable:true, enumerable:true})
     171    // semantics. Typed array indexed properties are non-configurable by
     172    // default, so we can't simply store to a typed array for putDirect.
     173    //
     174    // We could model putDirect on ScopedArguments and DirectArguments, but we
     175    // haven't found any performance incentive to do it yet.
     176    switch (mode) {
     177    case JITInt32:
     178    case JITDouble:
     179    case JITContiguous:
     180    case JITArrayStorage:
     181        return true;
     182    default:
     183        return false;
     184    }
     185}
     186
    167187inline TypedArrayType typedArrayTypeForJITArrayMode(JITArrayMode mode)
    168188{
  • trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp

    r215600 r216279  
    187187    // to value profiling, but the array profile tells us something else, then we
    188188    // should just trust the array profile.
     189
     190    auto typedArrayResult = [&] (ArrayMode result) -> ArrayMode {
     191        if (node->op() == PutByValDirect) {
     192            // This is semantically identical to defineOwnProperty({configurable: true, writable:true, enumerable:true}),
     193            // which we can't model as a simple store to the typed array since typed array indexed properties
     194            // are non-configurable.
     195            return ArrayMode(Array::Generic);
     196        }
     197        return result;
     198    };
    189199   
    190200    switch (type()) {
     
    236246    case Array::Float32Array:
    237247    case Array::Float64Array:
    238         switch (node->op()) {
    239         case PutByVal:
     248        if (node->op() == PutByVal) {
    240249            if (graph.hasExitSite(node->origin.semantic, OutOfBounds) || !isInBounds())
    241                 return withSpeculation(Array::OutOfBounds);
    242             return withSpeculation(Array::InBounds);
    243         default:
    244             return withSpeculation(Array::InBounds);
    245         }
    246         return *this;
     250                return typedArrayResult(withSpeculation(Array::OutOfBounds));
     251        }
     252        return typedArrayResult(withSpeculation(Array::InBounds));
    247253    case Array::Unprofiled:
    248254    case Array::SelectUsingPredictions: {
     
    275281            break;
    276282        }
    277        
     283
    278284        if (isInt8ArraySpeculation(base))
    279             return result.withType(Array::Int8Array);
     285            return typedArrayResult(result.withType(Array::Int8Array));
    280286       
    281287        if (isInt16ArraySpeculation(base))
    282             return result.withType(Array::Int16Array);
     288            return typedArrayResult(result.withType(Array::Int16Array));
    283289       
    284290        if (isInt32ArraySpeculation(base))
    285             return result.withType(Array::Int32Array);
     291            return typedArrayResult(result.withType(Array::Int32Array));
    286292       
    287293        if (isUint8ArraySpeculation(base))
    288             return result.withType(Array::Uint8Array);
     294            return typedArrayResult(result.withType(Array::Uint8Array));
    289295       
    290296        if (isUint8ClampedArraySpeculation(base))
    291             return result.withType(Array::Uint8ClampedArray);
     297            return typedArrayResult(result.withType(Array::Uint8ClampedArray));
    292298       
    293299        if (isUint16ArraySpeculation(base))
    294             return result.withType(Array::Uint16Array);
     300            return typedArrayResult(result.withType(Array::Uint16Array));
    295301       
    296302        if (isUint32ArraySpeculation(base))
    297             return result.withType(Array::Uint32Array);
     303            return typedArrayResult(result.withType(Array::Uint32Array));
    298304       
    299305        if (isFloat32ArraySpeculation(base))
    300             return result.withType(Array::Float32Array);
     306            return typedArrayResult(result.withType(Array::Float32Array));
    301307       
    302308        if (isFloat64ArraySpeculation(base))
    303             return result.withType(Array::Float64Array);
     309            return typedArrayResult(result.withType(Array::Float64Array));
    304310
    305311        if (type() == Array::Unprofiled)
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r214979 r216279  
    585585        uint32_t index = subscript.asUInt32();
    586586        ASSERT(isIndex(index));
    587         if (baseObject->canSetIndexQuicklyForPutDirect(index)) {
    588             baseObject->setIndexQuickly(callFrame->vm(), index, value);
    589             return;
    590         }
    591 
    592         // FIXME: This will make us think that in-bounds typed array accesses are actually
    593         // out-of-bounds.
    594         // https://bugs.webkit.org/show_bug.cgi?id=149886
    595         byValInfo->arrayProfile->setOutOfBounds();
     587
     588        switch (baseObject->indexingType()) {
     589        case ALL_INT32_INDEXING_TYPES:
     590        case ALL_DOUBLE_INDEXING_TYPES:
     591        case ALL_CONTIGUOUS_INDEXING_TYPES:
     592        case ALL_ARRAY_STORAGE_INDEXING_TYPES:
     593            if (index < baseObject->butterfly()->vectorLength())
     594                break;
     595            FALLTHROUGH;
     596        default:
     597            byValInfo->arrayProfile->setOutOfBounds();
     598            break;
     599        }
     600
    596601        baseObject->putDirectIndex(callFrame, index, value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
    597602        return;
     
    733738            // Attempt to optimize.
    734739            JITArrayMode arrayMode = jitArrayModeForStructure(structure);
    735             if (jitArrayModePermitsPut(arrayMode) && arrayMode != byValInfo->arrayMode) {
     740            if (jitArrayModePermitsPutDirect(arrayMode) && arrayMode != byValInfo->arrayMode) {
    736741                CodeBlock* codeBlock = exec->codeBlock();
    737742                ConcurrentJSLocker locker(codeBlock->m_lock);
  • trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp

    r215885 r216279  
    10321032
    10331033    if (!result) {
    1034         if (speciesResult.first == SpeciesConstructResult::CreatedObject) {
     1034        if (speciesResult.first == SpeciesConstructResult::CreatedObject)
    10351035            result = speciesResult.second;
    1036            
    1037             for (unsigned k = 0; k < actualDeleteCount; ++k) {
    1038                 JSValue v = getProperty(exec, thisObj, k + actualStart);
    1039                 RETURN_IF_EXCEPTION(scope, encodedJSValue());
    1040                 if (UNLIKELY(!v))
    1041                     continue;
    1042                 result->putByIndexInline(exec, k, v, true);
    1043                 RETURN_IF_EXCEPTION(scope, encodedJSValue());
    1044             }
    1045         } else {
     1036        else {
    10461037            result = JSArray::tryCreate(vm, exec->lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), actualDeleteCount);
    10471038            if (UNLIKELY(!result)) {
     
    10491040                return encodedJSValue();
    10501041            }
    1051 
    1052             for (unsigned k = 0; k < actualDeleteCount; ++k) {
    1053                 JSValue v = getProperty(exec, thisObj, k + actualStart);
    1054                 RETURN_IF_EXCEPTION(scope, encodedJSValue());
    1055                 if (UNLIKELY(!v))
    1056                     continue;
    1057                 result->putDirectIndex(exec, k, v);
    1058                 RETURN_IF_EXCEPTION(scope, encodedJSValue());
    1059             }
     1042        }
     1043        for (unsigned k = 0; k < actualDeleteCount; ++k) {
     1044            JSValue v = getProperty(exec, thisObj, k + actualStart);
     1045            RETURN_IF_EXCEPTION(scope, encodedJSValue());
     1046            if (UNLIKELY(!v))
     1047                continue;
     1048            result->putDirectIndex(exec, k, v, 0, PutDirectIndexShouldThrow);
     1049            RETURN_IF_EXCEPTION(scope, encodedJSValue());
    10601050        }
    10611051    }
  • trunk/Source/JavaScriptCore/runtime/ClonedArguments.cpp

    r215885 r216279  
    152152Structure* ClonedArguments::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype, IndexingType indexingType)
    153153{
    154     Structure* structure = Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info(), indexingType);
     154    Structure* structure = Structure::create(vm, globalObject, prototype, TypeInfo(ClonedArgumentsType, StructureFlags), info(), indexingType);
    155155    PropertyOffset offset;
    156156    structure = structure->addPropertyTransition(vm, structure, vm.propertyNames->length, DontEnum, offset);
  • trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h

    r212535 r216279  
    395395    JSGenericTypedArrayView* thisObject = jsCast<JSGenericTypedArrayView*>(object);
    396396
    397     if (parseIndex(propertyName)) {
     397    if (std::optional<uint32_t> index = parseIndex(propertyName)) {
     398        auto throwTypeErrorIfNeeded = [&] (const char* errorMessage) -> bool {
     399            if (shouldThrow)
     400                throwTypeError(exec, scope, makeString(errorMessage, String::number(*index)));
     401            return false;
     402        };
     403
    398404        if (descriptor.isAccessorDescriptor())
    399             return typeError(exec, scope, shouldThrow, ASCIILiteral("Attempting to store accessor indexed property on a typed array."));
     405            return throwTypeErrorIfNeeded("Attempting to store accessor property on a typed array at index: ");
    400406
    401407        if (descriptor.configurable())
    402             return typeError(exec, scope, shouldThrow, ASCIILiteral("Attempting to configure non-configurable property."));
     408            return throwTypeErrorIfNeeded("Attempting to configure non-configurable property on a typed array at index: ");
    403409
    404410        if (!descriptor.enumerable() || !descriptor.writable())
    405             return typeError(exec, scope, shouldThrow, ASCIILiteral("Attempting to store non-enumerable or non-writable indexed property on a typed array."));
     411            return throwTypeErrorIfNeeded("Attempting to store non-enumerable or non-writable property on a typed array at index: ");
    406412
    407413        if (descriptor.value()) {
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r215689 r216279  
    23572357}
    23582358
     2359ALWAYS_INLINE static bool canDoFastPutDirectIndex(JSObject* object)
     2360{
     2361    return isJSArray(object)
     2362        || isJSFinalObject(object)
     2363        || object->type() == DirectArgumentsType
     2364        || object->type() == ScopedArgumentsType
     2365        || object->type() == ClonedArgumentsType;
     2366}
     2367
    23592368// Defined in ES5.1 8.12.9
    23602369bool JSObject::defineOwnIndexedProperty(ExecState* exec, unsigned index, const PropertyDescriptor& descriptor, bool throwException)
     
    23702379        // however if the property currently exists missing attributes will override from their current 'true'
    23712380        // state (i.e. defineOwnProperty could be used to set a value without needing to entering 'SparseMode').
    2372         if (!descriptor.attributes() && descriptor.value()) {
     2381        if (!descriptor.attributes() && descriptor.value() && canDoFastPutDirectIndex(this)) {
    23732382            ASSERT(!descriptor.isAccessorDescriptor());
    23742383            return putDirectIndex(exec, index, descriptor.value(), 0, throwException ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
     
    28092818}
    28102819
    2811 bool JSObject::putDirectIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue value, unsigned attributes, PutDirectIndexMode mode)
     2820bool JSObject::putDirectIndexSlowOrBeyondVectorLength(ExecState* exec, unsigned i, JSValue value, unsigned attributes, PutDirectIndexMode mode)
    28122821{
    28132822    VM& vm = exec->vm();
     2823   
     2824    if (!canDoFastPutDirectIndex(this)) {
     2825        PropertyDescriptor descriptor;
     2826        descriptor.setDescriptor(value, attributes);
     2827        return methodTable(vm)->defineOwnProperty(this, exec, Identifier::from(exec, i), descriptor, mode == PutDirectIndexShouldThrow);
     2828    }
    28142829
    28152830    // i should be a valid array index that is outside of the current vector.
     
    28552870        if (!value.isInt32()) {
    28562871            convertInt32ForValue(vm, value);
    2857             return putDirectIndexBeyondVectorLength(exec, i, value, attributes, mode);
     2872            return putDirectIndexSlowOrBeyondVectorLength(exec, i, value, attributes, mode);
    28582873        }
    28592874        putByIndexBeyondVectorLengthWithoutAttributes<Int32Shape>(exec, i, value);
     
    28692884        if (!value.isNumber()) {
    28702885            convertDoubleToContiguous(vm);
    2871             return putDirectIndexBeyondVectorLength(exec, i, value, attributes, mode);
     2886            return putDirectIndexSlowOrBeyondVectorLength(exec, i, value, attributes, mode);
    28722887        }
    28732888        double valueAsDouble = value.asNumber();
    28742889        if (valueAsDouble != valueAsDouble) {
    28752890            convertDoubleToContiguous(vm);
    2876             return putDirectIndexBeyondVectorLength(exec, i, value, attributes, mode);
     2891            return putDirectIndexSlowOrBeyondVectorLength(exec, i, value, attributes, mode);
    28772892        }
    28782893        putByIndexBeyondVectorLengthWithoutAttributes<DoubleShape>(exec, i, value);
  • trunk/Source/JavaScriptCore/runtime/JSObject.h

    r215885 r216279  
    197197    JS_EXPORT_PRIVATE static bool putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
    198198       
     199    // This performs the ECMAScript Set() operation.
    199200    ALWAYS_INLINE bool putByIndexInline(ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)
    200201    {
     
    210211    //  - accessors are not called.
    211212    //  - it will ignore extensibility and read-only properties if PutDirectIndexLikePutDirect is passed as the mode (the default).
    212     // This method creates a property with attributes writable, enumerable and configurable all set to true.
     213    // This method creates a property with attributes writable, enumerable and configurable all set to true if attributes is zero,
     214    // otherwise, it creates a property with the provided attributes. Semantically, this is performing defineOwnProperty.
    213215    bool putDirectIndex(ExecState* exec, unsigned propertyName, JSValue value, unsigned attributes, PutDirectIndexMode mode)
    214216    {
    215         if (!attributes && canSetIndexQuicklyForPutDirect(propertyName)) {
     217        auto canSetIndexQuicklyForPutDirect = [&] () -> bool {
     218            switch (indexingType()) {
     219            case ALL_BLANK_INDEXING_TYPES:
     220            case ALL_UNDECIDED_INDEXING_TYPES:
     221                return false;
     222            case ALL_INT32_INDEXING_TYPES:
     223            case ALL_DOUBLE_INDEXING_TYPES:
     224            case ALL_CONTIGUOUS_INDEXING_TYPES:
     225            case ALL_ARRAY_STORAGE_INDEXING_TYPES:
     226                return propertyName < m_butterfly.get()->vectorLength();
     227            default:
     228                RELEASE_ASSERT_NOT_REACHED();
     229                return false;
     230            }
     231        };
     232       
     233        if (!attributes && canSetIndexQuicklyForPutDirect()) {
    216234            setIndexQuickly(exec->vm(), propertyName, value);
    217235            return true;
    218236        }
    219         return putDirectIndexBeyondVectorLength(exec, propertyName, value, attributes, mode);
    220     }
     237        return putDirectIndexSlowOrBeyondVectorLength(exec, propertyName, value, attributes, mode);
     238    }
     239    // This is semantically equivalent to performing defineOwnProperty(propertyName, {configurable:true, writable:true, enumerable:true, value:value}).
    221240    bool putDirectIndex(ExecState* exec, unsigned propertyName, JSValue value)
    222241    {
     
    224243    }
    225244
    226     // A non-throwing version of putDirect and putDirectIndex.
     245    // A generally non-throwing version of putDirect and putDirectIndex.
     246    // However, it's only guaranteed to not throw based on what the receiver is.
     247    // For example, if the receiver is a ProxyObject, this is not guaranteed, since
     248    // it may call into arbitrary JS code. It's the responsibility of the user of
     249    // this API to ensure that the receiver object is a well known type if they
     250    // want to ensure that this won't throw an exception.
    227251    JS_EXPORT_PRIVATE bool putDirectMayBeIndex(ExecState*, PropertyName, JSValue);
    228252       
     
    347371            return i < butterfly->arrayStorage()->vectorLength()
    348372                && !!butterfly->arrayStorage()->m_vector[i];
    349         default:
    350             RELEASE_ASSERT_NOT_REACHED();
    351             return false;
    352         }
    353     }
    354        
    355     bool canSetIndexQuicklyForPutDirect(unsigned i)
    356     {
    357         switch (indexingType()) {
    358         case ALL_BLANK_INDEXING_TYPES:
    359         case ALL_UNDECIDED_INDEXING_TYPES:
    360             return false;
    361         case ALL_INT32_INDEXING_TYPES:
    362         case ALL_DOUBLE_INDEXING_TYPES:
    363         case ALL_CONTIGUOUS_INDEXING_TYPES:
    364         case ALL_ARRAY_STORAGE_INDEXING_TYPES:
    365             return i < m_butterfly.get()->vectorLength();
    366373        default:
    367374            RELEASE_ASSERT_NOT_REACHED();
     
    10171024    bool putByIndexBeyondVectorLength(ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
    10181025    bool putDirectIndexBeyondVectorLengthWithArrayStorage(ExecState*, unsigned propertyName, JSValue, unsigned attributes, PutDirectIndexMode, ArrayStorage*);
    1019     JS_EXPORT_PRIVATE bool putDirectIndexBeyondVectorLength(ExecState*, unsigned propertyName, JSValue, unsigned attributes, PutDirectIndexMode);
     1026    JS_EXPORT_PRIVATE bool putDirectIndexSlowOrBeyondVectorLength(ExecState*, unsigned propertyName, JSValue, unsigned attributes, PutDirectIndexMode);
    10201027       
    10211028    unsigned getNewVectorLength(unsigned indexBias, unsigned currentVectorLength, unsigned currentLength, unsigned desiredLength);
  • trunk/Source/JavaScriptCore/runtime/JSType.h

    r214498 r216279  
    100100    WebAssemblyFunctionType,
    101101
    102     LastJSCObjectType = WebAssemblyFunctionType,
     102    ClonedArgumentsType,
     103
     104    LastJSCObjectType = ClonedArgumentsType,
    103105    MaxJSType = 0b11111111,
    104106};
Note: See TracChangeset for help on using the changeset viewer.