Changeset 178894 in webkit for trunk/Source/JavaScriptCore


Ignore:
Timestamp:
Jan 22, 2015, 12:54:52 AM (10 years ago)
Author:
Yusuke Suzuki
Message:

put_by_val_direct need to check the property is index or not for using putDirect / putDirectIndex
https://bugs.webkit.org/show_bug.cgi?id=140426

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

In the put_by_val_direct operation, we use JSObject::putDirect.
However, it only accepts non-index property. For index property, we need to use JSObject::putDirectIndex.
This patch changes Identifier::asIndex() to return Optional<uint32_t>.
It forces callers to check the value is index or not explicitly.
Additionally, it checks toString-ed Identifier is index or not to choose putDirect / putDirectIndex.

  • bytecode/GetByIdStatus.cpp:

(JSC::GetByIdStatus::computeFor):

  • bytecode/PutByIdStatus.cpp:

(JSC::PutByIdStatus::computeFor):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitDirectPutById):

  • dfg/DFGOperations.cpp:

(JSC::DFG::operationPutByValInternal):

  • jit/JITOperations.cpp:
  • jit/Repatch.cpp:

(JSC::emitPutTransitionStubAndGetOldStructure):

  • jsc.cpp:
  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):

  • runtime/Arguments.cpp:

(JSC::Arguments::getOwnPropertySlot):
(JSC::Arguments::put):
(JSC::Arguments::deleteProperty):
(JSC::Arguments::defineOwnProperty):

  • runtime/ArrayPrototype.cpp:

(JSC::arrayProtoFuncSort):

  • runtime/JSArray.cpp:

(JSC::JSArray::defineOwnProperty):

  • runtime/JSCJSValue.cpp:

(JSC::JSValue::putToPrimitive):

  • runtime/JSGenericTypedArrayViewInlines.h:

(JSC::JSGenericTypedArrayView<Adaptor>::getOwnPropertySlot):
(JSC::JSGenericTypedArrayView<Adaptor>::put):
(JSC::JSGenericTypedArrayView<Adaptor>::defineOwnProperty):
(JSC::JSGenericTypedArrayView<Adaptor>::deleteProperty):

  • runtime/JSObject.cpp:

(JSC::JSObject::put):
(JSC::JSObject::putDirectAccessor):
(JSC::JSObject::putDirectCustomAccessor):
(JSC::JSObject::deleteProperty):
(JSC::JSObject::putDirectMayBeIndex):
(JSC::JSObject::defineOwnProperty):

  • runtime/JSObject.h:

(JSC::JSObject::getOwnPropertySlot):
(JSC::JSObject::getPropertySlot):
(JSC::JSObject::putDirectInternal):

  • runtime/JSString.cpp:

(JSC::JSString::getStringPropertyDescriptor):

  • runtime/JSString.h:

(JSC::JSString::getStringPropertySlot):

  • runtime/LiteralParser.cpp:

(JSC::LiteralParser<CharType>::parse):

  • runtime/PropertyName.h:

(JSC::toUInt32FromCharacters):
(JSC::toUInt32FromStringImpl):
(JSC::PropertyName::asIndex):

  • runtime/PropertyNameArray.cpp:

(JSC::PropertyNameArray::add):

  • runtime/StringObject.cpp:

(JSC::StringObject::deleteProperty):

  • runtime/Structure.cpp:

(JSC::Structure::prototypeChainMayInterceptStoreTo):

Source/WebCore:

Test: js/dfg-put-by-val-direct-with-edge-numbers.html

  • bindings/js/JSDOMWindowCustom.cpp:

(WebCore::JSDOMWindow::getOwnPropertySlot):

  • bindings/js/JSHTMLAllCollectionCustom.cpp:

(WebCore::callHTMLAllCollection):
(WebCore::JSHTMLAllCollection::item):

  • bindings/scripts/CodeGeneratorJS.pm:

(GenerateGetOwnPropertySlotBody):
(GenerateImplementation):

  • bindings/scripts/test/JS/JSFloat64Array.cpp:

(WebCore::JSFloat64Array::getOwnPropertySlot):
(WebCore::JSFloat64Array::getOwnPropertyDescriptor):
(WebCore::JSFloat64Array::put):

  • bindings/scripts/test/JS/JSTestEventTarget.cpp:

(WebCore::JSTestEventTarget::getOwnPropertySlot):

  • bridge/runtime_array.cpp:

(JSC::RuntimeArray::getOwnPropertySlot):
(JSC::RuntimeArray::put):

LayoutTests:

  • js/dfg-put-by-val-direct-with-edge-numbers-expected.txt: Added.
  • js/dfg-put-by-val-direct-with-edge-numbers.html: Added.
  • js/script-tests/dfg-put-by-val-direct-with-edge-numbers.js: Added.

(lookupWithKey):
(dfgShouldThrow):
(lookupWithKey2):
(toStringThrowsError.toString):

Location:
trunk/Source/JavaScriptCore
Files:
23 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r178888 r178894  
     12015-01-22  Yusuke Suzuki  <[email protected]>
     2
     3        put_by_val_direct need to check the property is index or not for using putDirect / putDirectIndex
     4        https://bugs.webkit.org/show_bug.cgi?id=140426
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        In the put_by_val_direct operation, we use JSObject::putDirect.
     9        However, it only accepts non-index property. For index property, we need to use JSObject::putDirectIndex.
     10        This patch changes Identifier::asIndex() to return Optional<uint32_t>.
     11        It forces callers to check the value is index or not explicitly.
     12        Additionally, it checks toString-ed Identifier is index or not to choose putDirect / putDirectIndex.
     13
     14        * bytecode/GetByIdStatus.cpp:
     15        (JSC::GetByIdStatus::computeFor):
     16        * bytecode/PutByIdStatus.cpp:
     17        (JSC::PutByIdStatus::computeFor):
     18        * bytecompiler/BytecodeGenerator.cpp:
     19        (JSC::BytecodeGenerator::emitDirectPutById):
     20        * dfg/DFGOperations.cpp:
     21        (JSC::DFG::operationPutByValInternal):
     22        * jit/JITOperations.cpp:
     23        * jit/Repatch.cpp:
     24        (JSC::emitPutTransitionStubAndGetOldStructure):
     25        * jsc.cpp:
     26        * llint/LLIntSlowPaths.cpp:
     27        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
     28        * runtime/Arguments.cpp:
     29        (JSC::Arguments::getOwnPropertySlot):
     30        (JSC::Arguments::put):
     31        (JSC::Arguments::deleteProperty):
     32        (JSC::Arguments::defineOwnProperty):
     33        * runtime/ArrayPrototype.cpp:
     34        (JSC::arrayProtoFuncSort):
     35        * runtime/JSArray.cpp:
     36        (JSC::JSArray::defineOwnProperty):
     37        * runtime/JSCJSValue.cpp:
     38        (JSC::JSValue::putToPrimitive):
     39        * runtime/JSGenericTypedArrayViewInlines.h:
     40        (JSC::JSGenericTypedArrayView<Adaptor>::getOwnPropertySlot):
     41        (JSC::JSGenericTypedArrayView<Adaptor>::put):
     42        (JSC::JSGenericTypedArrayView<Adaptor>::defineOwnProperty):
     43        (JSC::JSGenericTypedArrayView<Adaptor>::deleteProperty):
     44        * runtime/JSObject.cpp:
     45        (JSC::JSObject::put):
     46        (JSC::JSObject::putDirectAccessor):
     47        (JSC::JSObject::putDirectCustomAccessor):
     48        (JSC::JSObject::deleteProperty):
     49        (JSC::JSObject::putDirectMayBeIndex):
     50        (JSC::JSObject::defineOwnProperty):
     51        * runtime/JSObject.h:
     52        (JSC::JSObject::getOwnPropertySlot):
     53        (JSC::JSObject::getPropertySlot):
     54        (JSC::JSObject::putDirectInternal):
     55        * runtime/JSString.cpp:
     56        (JSC::JSString::getStringPropertyDescriptor):
     57        * runtime/JSString.h:
     58        (JSC::JSString::getStringPropertySlot):
     59        * runtime/LiteralParser.cpp:
     60        (JSC::LiteralParser<CharType>::parse):
     61        * runtime/PropertyName.h:
     62        (JSC::toUInt32FromCharacters):
     63        (JSC::toUInt32FromStringImpl):
     64        (JSC::PropertyName::asIndex):
     65        * runtime/PropertyNameArray.cpp:
     66        (JSC::PropertyNameArray::add):
     67        * runtime/StringObject.cpp:
     68        (JSC::StringObject::deleteProperty):
     69        * runtime/Structure.cpp:
     70        (JSC::Structure::prototypeChainMayInterceptStoreTo):
     71
    1722015-01-21  Ryosuke Niwa  <[email protected]>
    273
  • trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp

    r178756 r178894  
    271271        return GetByIdStatus();
    272272
    273     if (toUInt32FromStringImpl(uid) != PropertyName::NotAnIndex)
     273    if (toUInt32FromStringImpl(uid))
    274274        return GetByIdStatus(TakesSlowPath);
    275275   
  • trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp

    r178756 r178894  
    311311PutByIdStatus PutByIdStatus::computeFor(JSGlobalObject* globalObject, const StructureSet& set, AtomicStringImpl* uid, bool isDirect)
    312312{
    313     if (toUInt32FromStringImpl(uid) != PropertyName::NotAnIndex)
     313    if (toUInt32FromStringImpl(uid))
    314314        return PutByIdStatus(TakesSlowPath);
    315315
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r178882 r178894  
    14891489    instructions().append(0);
    14901490    instructions().append(0);
    1491     instructions().append(
    1492         property != m_vm->propertyNames->underscoreProto
    1493         && PropertyName(property).asIndex() == PropertyName::NotAnIndex);
     1491    instructions().append(property != m_vm->propertyNames->underscoreProto && !PropertyName(property).asIndex());
    14941492    return value;
    14951493}
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r178756 r178894  
    9898
    9999    if (LIKELY(property.isUInt32())) {
    100         putByVal<strict, direct>(exec, baseValue, property.asUInt32(), value);
     100        uint32_t index = property.asUInt32();
     101        ASSERT_WITH_MESSAGE(index != PropertyName::NotAnIndex, "Since JSValue::isUInt32 returns true only when the boxed value is int32_t and positive, it doesn't return true for uint32_t max value that is PropertyName::NotAnIndex.");
     102        putByVal<strict, direct>(exec, baseValue, index, value);
    101103        return;
    102104    }
     
    105107        double propertyAsDouble = property.asDouble();
    106108        uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
    107         if (propertyAsDouble == propertyAsUInt32) {
     109        if (propertyAsDouble == propertyAsUInt32 && propertyAsUInt32 != PropertyName::NotAnIndex) {
    108110            putByVal<strict, direct>(exec, baseValue, propertyAsUInt32, value);
    109111            return;
     
    123125    // Don't put to an object if toString throws an exception.
    124126    Identifier ident = property.toString(exec)->toIdentifier(exec);
    125     if (!vm->exception()) {
    126         PutPropertySlot slot(baseValue, strict);
    127         if (direct) {
    128             RELEASE_ASSERT(baseValue.isObject());
    129             asObject(baseValue)->putDirect(*vm, ident, value, slot);
    130         } else
    131             baseValue.put(exec, ident, value, slot);
    132     }
     127    if (vm->exception())
     128        return;
     129
     130    PutPropertySlot slot(baseValue, strict);
     131    if (direct) {
     132        PropertyName propertyName(ident);
     133        RELEASE_ASSERT(baseValue.isObject());
     134        if (Optional<uint32_t> index = propertyName.asIndex())
     135            asObject(baseValue)->putDirectIndex(exec, index.value(), value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
     136        else
     137            asObject(baseValue)->putDirect(*vm, propertyName, value, slot);
     138    } else
     139        baseValue.put(exec, ident, value, slot);
    133140}
    134141
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r178756 r178894  
    5252#include "LegacyProfiler.h"
    5353#include "ObjectConstructor.h"
     54#include "PropertyName.h"
    5455#include "Repatch.h"
    5556#include "RepatchBuffer.h"
     
    481482static void directPutByVal(CallFrame* callFrame, JSObject* baseObject, JSValue subscript, JSValue value)
    482483{
     484    bool isStrictMode = callFrame->codeBlock()->isStrictMode();
    483485    if (LIKELY(subscript.isUInt32())) {
    484         uint32_t i = subscript.asUInt32();
    485         baseObject->putDirectIndex(callFrame, i, value);
    486     } else if (isName(subscript)) {
    487         PutPropertySlot slot(baseObject, callFrame->codeBlock()->isStrictMode());
     486        uint32_t index = subscript.asUInt32();
     487        ASSERT_WITH_MESSAGE(index != PropertyName::NotAnIndex, "Since JSValue::isUInt32 returns true only when the boxed value is int32_t and positive, it doesn't return true for uint32_t max value that is PropertyName::NotAnIndex.");
     488        baseObject->putDirectIndex(callFrame, index, value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
     489        return;
     490    }
     491
     492    if (subscript.isDouble()) {
     493        double subscriptAsDouble = subscript.asDouble();
     494        uint32_t subscriptAsUInt32 = static_cast<uint32_t>(subscriptAsDouble);
     495        if (subscriptAsDouble == subscriptAsUInt32 && subscriptAsUInt32 != PropertyName::NotAnIndex) {
     496            baseObject->putDirectIndex(callFrame, subscriptAsUInt32, value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
     497            return;
     498        }
     499    }
     500
     501    if (isName(subscript)) {
     502        PutPropertySlot slot(baseObject, isStrictMode);
    488503        baseObject->putDirect(callFrame->vm(), jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
    489     } else {
    490         Identifier property = subscript.toString(callFrame)->toIdentifier(callFrame);
    491         if (!callFrame->vm().exception()) { // Don't put to an object if toString threw an exception.
    492             PutPropertySlot slot(baseObject, callFrame->codeBlock()->isStrictMode());
    493             baseObject->putDirect(callFrame->vm(), property, value, slot);
    494         }
     504        return;
     505    }
     506
     507    // Don't put to an object if toString throws an exception.
     508    Identifier property = subscript.toString(callFrame)->toIdentifier(callFrame);
     509    if (callFrame->vm().exception())
     510        return;
     511
     512    PropertyName propertyName(property);
     513    if (Optional<uint32_t> index = propertyName.asIndex())
     514        baseObject->putDirectIndex(callFrame, index.value(), value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
     515    else {
     516        PutPropertySlot slot(baseObject, isStrictMode);
     517        baseObject->putDirect(callFrame->vm(), propertyName, value, slot);
    495518    }
    496519}
  • trunk/Source/JavaScriptCore/jit/Repatch.cpp

    r178856 r178894  
    983983    PropertyName pname(ident);
    984984    Structure* oldStructure = structure;
    985     if (!oldStructure->isObject() || oldStructure->isDictionary() || pname.asIndex() != PropertyName::NotAnIndex)
     985    if (!oldStructure->isObject() || oldStructure->isDictionary() || pname.asIndex())
    986986        return nullptr;
    987987
  • trunk/Source/JavaScriptCore/jsc.cpp

    r178756 r178894  
    335335        }
    336336
    337         unsigned index = propertyName.asIndex();
    338         if (index < thisObject->getLength()) {
    339             ASSERT(index != PropertyName::NotAnIndex);
    340             slot.setValue(thisObject, DontDelete | DontEnum, jsNumber(thisObject->m_vector[index]));
     337        Optional<uint32_t> index = propertyName.asIndex();
     338        if (index && index.value() < thisObject->getLength()) {
     339            slot.setValue(thisObject, DontDelete | DontEnum, jsNumber(thisObject->m_vector[index.value()]));
    341340            return true;
    342341        }
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r178756 r178894  
    820820    RELEASE_ASSERT(baseValue.isObject());
    821821    JSObject* baseObject = asObject(baseValue);
     822    bool isStrictMode = exec->codeBlock()->isStrictMode();
    822823    if (LIKELY(subscript.isUInt32())) {
    823         uint32_t i = subscript.asUInt32();
    824         baseObject->putDirectIndex(exec, i, value);
    825     } else if (isName(subscript)) {
    826         PutPropertySlot slot(baseObject, exec->codeBlock()->isStrictMode());
     824        uint32_t index = subscript.asUInt32();
     825        ASSERT_WITH_MESSAGE(index != PropertyName::NotAnIndex, "Since JSValue::isUInt32 returns true only when the boxed value is int32_t and positive, it doesn't return true for uint32_t max value that is PropertyName::NotAnIndex.");
     826        baseObject->putDirectIndex(exec, index, value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
     827        LLINT_END();
     828    }
     829
     830
     831    if (subscript.isDouble()) {
     832        double subscriptAsDouble = subscript.asDouble();
     833        uint32_t subscriptAsUInt32 = static_cast<uint32_t>(subscriptAsDouble);
     834        if (subscriptAsDouble == subscriptAsUInt32 && subscriptAsUInt32 != PropertyName::NotAnIndex) {
     835            baseObject->putDirectIndex(exec, subscriptAsUInt32, value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
     836            LLINT_END();
     837        }
     838    }
     839
     840    if (isName(subscript)) {
     841        PutPropertySlot slot(baseObject, isStrictMode);
    827842        baseObject->putDirect(exec->vm(), jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
    828     } else {
    829         Identifier property = subscript.toString(exec)->toIdentifier(exec);
    830         if (!exec->vm().exception()) { // Don't put to an object if toString threw an exception.
    831             PutPropertySlot slot(baseObject, exec->codeBlock()->isStrictMode());
    832             baseObject->putDirect(exec->vm(), property, value, slot);
    833         }
     843        LLINT_END();
     844    }
     845
     846    // Don't put to an object if toString throws an exception.
     847    Identifier property = subscript.toString(exec)->toIdentifier(exec);
     848    if (exec->vm().exception())
     849        LLINT_END();
     850
     851    PropertyName propertyName(property);
     852    if (Optional<uint32_t> index = propertyName.asIndex())
     853        baseObject->putDirectIndex(exec, index.value(), value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
     854    else {
     855        PutPropertySlot slot(baseObject, isStrictMode);
     856        baseObject->putDirect(exec->vm(), propertyName, value, slot);
    834857    }
    835858    LLINT_END();
  • trunk/Source/JavaScriptCore/runtime/Arguments.cpp

    r178756 r178894  
    162162{
    163163    Arguments* thisObject = jsCast<Arguments*>(object);
    164     unsigned i = propertyName.asIndex();
    165     if (JSValue value = thisObject->tryGetArgument(i)) {
    166         RELEASE_ASSERT(i < PropertyName::NotAnIndex);
    167         slot.setValue(thisObject, None, value);
    168         return true;
     164    if (Optional<uint32_t> index = propertyName.asIndex()) {
     165        if (JSValue value = thisObject->tryGetArgument(index.value())) {
     166            slot.setValue(thisObject, None, value);
     167            return true;
     168        }
    169169    }
    170170
     
    225225{
    226226    Arguments* thisObject = jsCast<Arguments*>(cell);
    227     unsigned i = propertyName.asIndex();
    228     if (thisObject->trySetArgument(exec->vm(), i, value))
     227    Optional<uint32_t> index = propertyName.asIndex();
     228    if (index && thisObject->trySetArgument(exec->vm(), index.value(), value))
    229229        return;
    230230
     
    268268
    269269    Arguments* thisObject = jsCast<Arguments*>(cell);
    270     unsigned i = propertyName.asIndex();
    271     if (i < thisObject->m_numArguments) {
    272         RELEASE_ASSERT(i < PropertyName::NotAnIndex);
     270    Optional<uint32_t> index = propertyName.asIndex();
     271    if (index && index.value() < thisObject->m_numArguments) {
    273272        if (!Base::deleteProperty(cell, exec, propertyName))
    274273            return false;
    275         if (thisObject->tryDeleteArgument(exec->vm(), i))
     274        if (thisObject->tryDeleteArgument(exec->vm(), index.value()))
    276275            return true;
    277276    }
     
    299298{
    300299    Arguments* thisObject = jsCast<Arguments*>(object);
    301     unsigned i = propertyName.asIndex();
    302     if (i < thisObject->m_numArguments) {
    303         RELEASE_ASSERT(i < PropertyName::NotAnIndex);
     300    Optional<uint32_t> optionalIndex = propertyName.asIndex();
     301    if (optionalIndex && optionalIndex.value() < thisObject->m_numArguments) {
    304302        // If the property is not yet present on the object, and is not yet marked as deleted, then add it now.
     303        uint32_t index = optionalIndex.value();
    305304        PropertySlot slot(thisObject);
    306         if (!thisObject->isDeletedArgument(i) && !JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot)) {
    307             JSValue value = thisObject->tryGetArgument(i);
     305        if (!thisObject->isDeletedArgument(index) && !JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot)) {
     306            JSValue value = thisObject->tryGetArgument(index);
    308307            ASSERT(value);
    309308            object->putDirectMayBeIndex(exec, propertyName, value);
     
    314313        // From ES 5.1, 10.6 Arguments Object
    315314        // 5. If the value of isMapped is not undefined, then
    316         if (thisObject->isArgument(i)) {
     315        if (thisObject->isArgument(index)) {
    317316            // a. If IsAccessorDescriptor(Desc) is true, then
    318317            if (descriptor.isAccessorDescriptor()) {
    319318                // i. Call the [[Delete]] internal method of map passing P, and false as the arguments.
    320                 thisObject->tryDeleteArgument(exec->vm(), i);
     319                thisObject->tryDeleteArgument(exec->vm(), index);
    321320            } else { // b. Else
    322321                // i. If Desc.[[Value]] is present, then
    323322                // 1. Call the [[Put]] internal method of map passing P, Desc.[[Value]], and Throw as the arguments.
    324323                if (descriptor.value())
    325                     thisObject->trySetArgument(exec->vm(), i, descriptor.value());
     324                    thisObject->trySetArgument(exec->vm(), index, descriptor.value());
    326325                // ii. If Desc.[[Writable]] is present and its value is false, then
    327326                // 1. Call the [[Delete]] internal method of map passing P and false as arguments.
    328327                if (descriptor.writablePresent() && !descriptor.writable())
    329                     thisObject->tryDeleteArgument(exec->vm(), i);
     328                    thisObject->tryDeleteArgument(exec->vm(), index);
    330329            }
    331330        }
  • trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp

    r178756 r178894  
    743743    for (size_t i = 0; i < nameArray.size(); ++i) {
    744744        PropertyName name = nameArray[i];
    745         uint32_t index = name.asIndex();
    746         if (index == PropertyName::NotAnIndex)
     745        Optional<uint32_t> optionalIndex = name.asIndex();
     746        if (!optionalIndex)
    747747            continue;
    748        
     748
     749        uint32_t index = optionalIndex.value();
    749750        JSValue value = getOrHole(thisObj, exec, index);
    750751        if (exec->hadException())
  • trunk/Source/JavaScriptCore/runtime/JSArray.cpp

    r178756 r178894  
    159159    // 4. Else if P is an array index (15.4), then
    160160    // a. Let index be ToUint32(P).
    161     unsigned index = propertyName.asIndex();
    162     if (index != PropertyName::NotAnIndex) {
     161    if (Optional<uint32_t> optionalIndex = propertyName.asIndex()) {
    163162        // b. Reject if index >= oldLen and oldLenDesc.[[Writable]] is false.
     163        uint32_t index = optionalIndex.value();
    164164        if (index >= array->length() && !array->isLengthWritable())
    165165            return reject(exec, throwException, "Attempting to define numeric property on array with non-writable length property.");
  • trunk/Source/JavaScriptCore/runtime/JSCJSValue.cpp

    r178756 r178894  
    120120    VM& vm = exec->vm();
    121121
    122     unsigned index = propertyName.asIndex();
    123     if (index != PropertyName::NotAnIndex) {
    124         putToPrimitiveByIndex(exec, index, value, slot.isStrictMode());
     122    if (Optional<uint32_t> index = propertyName.asIndex()) {
     123        putToPrimitiveByIndex(exec, index.value(), value, slot.isStrictMode());
    125124        return;
    126125    }
  • trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h

    r178756 r178894  
    303303    }
    304304   
    305     unsigned index = propertyName.asIndex();
    306     if (index != PropertyName::NotAnIndex && thisObject->canGetIndexQuickly(index)) {
    307         slot.setValue(thisObject, DontDelete | ReadOnly, thisObject->getIndexQuickly(index));
     305    Optional<uint32_t> index = propertyName.asIndex();
     306    if (index && thisObject->canGetIndexQuickly(index.value())) {
     307        slot.setValue(thisObject, DontDelete | ReadOnly, thisObject->getIndexQuickly(index.value()));
    308308        return true;
    309309    }
     
    325325    }
    326326   
    327     unsigned index = propertyName.asIndex();
    328     if (index != PropertyName::NotAnIndex) {
    329         putByIndex(thisObject, exec, index, value, slot.isStrictMode());
     327    if (Optional<uint32_t> index = propertyName.asIndex()) {
     328        putByIndex(thisObject, exec, index.value(), value, slot.isStrictMode());
    330329        return;
    331330    }
     
    344343    // defineOwnProperty for indexed properties on typed arrays, even if they're out
    345344    // of bounds.
    346     if (propertyName == exec->propertyNames().length
    347         || propertyName.asIndex() != PropertyName::NotAnIndex)
     345    if (propertyName == exec->propertyNames().length || propertyName.asIndex())
    348346        return reject(exec, shouldThrow, "Attempting to write to a read-only typed array property.");
    349347   
     
    357355    JSGenericTypedArrayView* thisObject = jsCast<JSGenericTypedArrayView*>(cell);
    358356   
    359     if (propertyName == exec->propertyNames().length
    360         || propertyName.asIndex() != PropertyName::NotAnIndex)
     357    if (propertyName == exec->propertyNames().length || propertyName.asIndex())
    361358        return false;
    362359   
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r178756 r178894  
    340340    // Try indexed put first. This is required for correctness, since loads on property names that appear like
    341341    // valid indices will never look in the named property storage.
    342     unsigned i = propertyName.asIndex();
    343     if (i != PropertyName::NotAnIndex) {
    344         putByIndex(thisObject, exec, i, value, slot.isStrictMode());
     342    if (Optional<uint32_t> index = propertyName.asIndex()) {
     343        putByIndex(thisObject, exec, index.value(), value, slot.isStrictMode());
    345344        return;
    346345    }
     
    11991198    ASSERT(value.isGetterSetter() && (attributes & Accessor));
    12001199
    1201     unsigned index = propertyName.asIndex();
    1202     if (index != PropertyName::NotAnIndex) {
    1203         putDirectIndex(exec, index, value, attributes, PutDirectIndexLikePutDirect);
     1200    if (Optional<uint32_t> index = propertyName.asIndex()) {
     1201        putDirectIndex(exec, index.value(), value, attributes, PutDirectIndexLikePutDirect);
    12041202        return;
    12051203    }
     
    12101208void JSObject::putDirectCustomAccessor(VM& vm, PropertyName propertyName, JSValue value, unsigned attributes)
    12111209{
    1212     ASSERT(propertyName.asIndex() == PropertyName::NotAnIndex);
     1210    ASSERT(!propertyName.asIndex());
    12131211
    12141212    PutPropertySlot slot(this);
     
    12581256    JSObject* thisObject = jsCast<JSObject*>(cell);
    12591257   
    1260     unsigned i = propertyName.asIndex();
    1261     if (i != PropertyName::NotAnIndex)
    1262         return thisObject->methodTable(exec->vm())->deletePropertyByIndex(thisObject, exec, i);
     1258    if (Optional<uint32_t> index = propertyName.asIndex())
     1259        return thisObject->methodTable(exec->vm())->deletePropertyByIndex(thisObject, exec, index.value());
    12631260
    12641261    if (!thisObject->staticFunctionsReified())
     
    25032500void JSObject::putDirectMayBeIndex(ExecState* exec, PropertyName propertyName, JSValue value)
    25042501{
    2505     unsigned asIndex = propertyName.asIndex();
    2506     if (asIndex == PropertyName::NotAnIndex)
     2502    if (Optional<uint32_t> index = propertyName.asIndex())
     2503        putDirectIndex(exec, index.value(), value);
     2504    else
    25072505        putDirect(exec->vm(), propertyName, value);
    2508     else
    2509         putDirectIndex(exec, asIndex, value);
    25102506}
    25112507
     
    26602656{
    26612657    // If it's an array index, then use the indexed property storage.
    2662     unsigned index = propertyName.asIndex();
    2663     if (index != PropertyName::NotAnIndex) {
     2658    if (Optional<uint32_t> index = propertyName.asIndex()) {
    26642659        // c. Let succeeded be the result of calling the default [[DefineOwnProperty]] internal method (8.12.9) on A passing P, Desc, and false as arguments.
    26652660        // d. Reject if succeeded is false.
     
    26682663        // e.ii. Call the default [[DefineOwnProperty]] internal method (8.12.9) on A passing "length", oldLenDesc, and false as arguments. This call will always return true.
    26692664        // f. Return true.
    2670         return object->defineOwnIndexedProperty(exec, index, descriptor, throwException);
     2665        return object->defineOwnIndexedProperty(exec, index.value(), descriptor, throwException);
    26712666    }
    26722667   
  • trunk/Source/JavaScriptCore/runtime/JSObject.h

    r178756 r178894  
    12451245    if (object->inlineGetOwnPropertySlot(vm, structure, propertyName, slot))
    12461246        return true;
    1247     unsigned index = propertyName.asIndex();
    1248     if (index != PropertyName::NotAnIndex)
    1249         return getOwnPropertySlotByIndex(object, exec, index, slot);
     1247    if (Optional<uint32_t> index = propertyName.asIndex())
     1248        return getOwnPropertySlotByIndex(object, exec, index.value(), slot);
    12501249    return false;
    12511250}
     
    12751274    }
    12761275
    1277     unsigned index = propertyName.asIndex();
    1278     if (index != PropertyName::NotAnIndex)
    1279         return getPropertySlot(exec, index, slot);
     1276    if (Optional<uint32_t> index = propertyName.asIndex())
     1277        return getPropertySlot(exec, index.value(), slot);
    12801278    return false;
    12811279}
     
    13211319    ASSERT(value.isGetterSetter() == !!(attributes & Accessor));
    13221320    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
    1323     ASSERT(propertyName.asIndex() == PropertyName::NotAnIndex);
     1321    ASSERT(!propertyName.asIndex());
    13241322
    13251323    Structure* structure = this->structure(vm);
  • trunk/Source/JavaScriptCore/runtime/JSString.cpp

    r178756 r178894  
    426426    }
    427427   
    428     unsigned i = propertyName.asIndex();
    429     if (i < m_length) {
    430         ASSERT(i != PropertyName::NotAnIndex); // No need for an explicit check, the above test would always fail!
    431         descriptor.setDescriptor(getIndex(exec, i), DontDelete | ReadOnly);
     428    Optional<uint32_t> index = propertyName.asIndex();
     429    if (index && index.value() < m_length) {
     430        descriptor.setDescriptor(getIndex(exec, index.value()), DontDelete | ReadOnly);
    432431        return true;
    433432    }
  • trunk/Source/JavaScriptCore/runtime/JSString.h

    r178756 r178894  
    627627    }
    628628
    629     unsigned i = propertyName.asIndex();
    630     if (i < m_length) {
    631         ASSERT(i != PropertyName::NotAnIndex); // No need for an explicit check, the above test would always fail!
    632         slot.setValue(this, DontDelete | ReadOnly, getIndex(exec, i));
     629    Optional<uint32_t> index = propertyName.asIndex();
     630    if (index && index.value() < m_length) {
     631        slot.setValue(this, DontDelete | ReadOnly, getIndex(exec, index.value()));
    633632        return true;
    634633    }
  • trunk/Source/JavaScriptCore/runtime/LiteralParser.cpp

    r178756 r178894  
    650650                JSObject* object = asObject(objectStack.last());
    651651                PropertyName ident = identifierStack.last();
    652                 unsigned i = ident.asIndex();
    653                 if (i != PropertyName::NotAnIndex)
    654                     object->putDirectIndex(m_exec, i, lastValue);
     652                if (Optional<uint32_t> index = ident.asIndex())
     653                    object->putDirectIndex(m_exec, index.value(), lastValue);
    655654                else
    656655                    object->putDirect(m_exec->vm(), ident, lastValue);
  • trunk/Source/JavaScriptCore/runtime/PropertyName.h

    r178756 r178894  
    2929#include "Identifier.h"
    3030#include "PrivateName.h"
     31#include <wtf/Optional.h>
    3132
    3233namespace JSC {
    3334
    3435template <typename CharType>
    35 ALWAYS_INLINE uint32_t toUInt32FromCharacters(const CharType* characters, unsigned length)
     36ALWAYS_INLINE Optional<uint32_t> toUInt32FromCharacters(const CharType* characters, unsigned length)
    3637{
    3738    // An empty string is not a number.
    3839    if (!length)
    39         return UINT_MAX;
     40        return Nullopt;
    4041
    4142    // Get the first character, turning it into a digit.
    4243    uint32_t value = characters[0] - '0';
    4344    if (value > 9)
    44         return UINT_MAX;
     45        return Nullopt;
    4546   
    4647    // Check for leading zeros. If the first characher is 0, then the
    4748    // length of the string must be one - e.g. "042" is not equal to "42".
    4849    if (!value && length > 1)
    49         return UINT_MAX;
     50        return Nullopt;
    5051   
    5152    while (--length) {
    5253        // Multiply value by 10, checking for overflow out of 32 bits.
    5354        if (value > 0xFFFFFFFFU / 10)
    54             return UINT_MAX;
     55            return Nullopt;
    5556        value *= 10;
    5657       
     
    5859        uint32_t newValue = *(++characters) - '0';
    5960        if (newValue > 9)
    60             return UINT_MAX;
     61            return Nullopt;
    6162       
    6263        // Add in the old value, checking for overflow out of 32 bits.
    6364        newValue += value;
    6465        if (newValue < value)
    65             return UINT_MAX;
     66            return Nullopt;
    6667        value = newValue;
    6768    }
    68    
     69
     70    if (value == UINT_MAX)
     71        return Nullopt;
    6972    return value;
    7073}
    7174
    72 ALWAYS_INLINE uint32_t toUInt32FromStringImpl(StringImpl* impl)
     75ALWAYS_INLINE Optional<uint32_t> toUInt32FromStringImpl(StringImpl* impl)
    7376{
    7477    if (impl->is8Bit())
     
    110113    static const uint32_t NotAnIndex = UINT_MAX;
    111114
    112     uint32_t asIndex()
     115    Optional<uint32_t> asIndex()
    113116    {
    114         return m_impl ? toUInt32FromStringImpl(m_impl) : NotAnIndex;
     117        return m_impl ? toUInt32FromStringImpl(m_impl) : Nullopt;
    115118    }
    116    
     119
    117120    void dump(PrintStream& out) const
    118121    {
  • trunk/Source/JavaScriptCore/runtime/PropertyNameArray.cpp

    r178756 r178894  
    3434    ASSERT(!identifier || identifier == StringImpl::empty() || identifier->isAtomic());
    3535    if (!ASSERT_DISABLED) {
    36         uint32_t index = PropertyName(Identifier(m_vm, identifier)).asIndex();
    37         ASSERT_UNUSED(index, index == PropertyName::NotAnIndex || index >= m_previouslyEnumeratedLength);
     36        Optional<uint32_t> index = PropertyName(Identifier(m_vm, identifier)).asIndex();
     37        ASSERT_UNUSED(index, !index || index.value() >= m_previouslyEnumeratedLength);
    3838    }
    3939
  • trunk/Source/JavaScriptCore/runtime/StringObject.cpp

    r178756 r178894  
    129129    if (propertyName == exec->propertyNames().length)
    130130        return false;
    131     unsigned i = propertyName.asIndex();
    132     if (thisObject->internalValue()->canGetIndex(i)) {
    133         ASSERT(i != PropertyName::NotAnIndex); // No need for an explicit check, the above test would always fail!
     131    Optional<uint32_t> index = propertyName.asIndex();
     132    if (index && thisObject->internalValue()->canGetIndex(index.value())) {
    134133        return false;
    135134    }
  • trunk/Source/JavaScriptCore/runtime/Structure.cpp

    r178756 r178894  
    10111011bool Structure::prototypeChainMayInterceptStoreTo(VM& vm, PropertyName propertyName)
    10121012{
    1013     unsigned i = propertyName.asIndex();
    1014     if (i != PropertyName::NotAnIndex)
     1013    if (propertyName.asIndex())
    10151014        return anyObjectInChainMayInterceptIndexedAccesses();
    10161015   
Note: See TracChangeset for help on using the changeset viewer.