コード例 #1
0
ファイル: JSCJSValue.cpp プロジェクト: endlessm/WebKit
// ECMA 8.7.2
bool JSValue::putToPrimitive(ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
{
    VM& vm = exec->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    if (Optional<uint32_t> index = parseIndex(propertyName))
        return putToPrimitiveByIndex(exec, index.value(), value, slot.isStrictMode());

    // Check if there are any setters or getters in the prototype chain
    JSObject* obj = synthesizePrototype(exec);
    if (UNLIKELY(!obj))
        return false;
    JSValue prototype;
    if (propertyName != exec->propertyNames().underscoreProto) {
        for (; !obj->structure()->hasReadOnlyOrGetterSetterPropertiesExcludingProto(); obj = asObject(prototype)) {
            prototype = obj->getPrototypeDirect();
            if (prototype.isNull()) {
                if (slot.isStrictMode())
                    throwTypeError(exec, scope, StrictModeReadonlyPropertyWriteError);
                return false;
            }
        }
    }

    for (; ; obj = asObject(prototype)) {
        unsigned attributes;
        PropertyOffset offset = obj->structure()->get(vm, propertyName, attributes);
        if (offset != invalidOffset) {
            if (attributes & ReadOnly) {
                if (slot.isStrictMode())
                    throwTypeError(exec, scope, StrictModeReadonlyPropertyWriteError);
                return false;
            }

            JSValue gs = obj->getDirect(offset);
            if (gs.isGetterSetter())
                return callSetter(exec, *this, gs, value, slot.isStrictMode() ? StrictMode : NotStrictMode);

            if (gs.isCustomGetterSetter())
                return callCustomSetter(exec, gs, attributes & CustomAccessor, obj, slot.thisValue(), value);

            // If there's an existing property on the object or one of its 
            // prototypes it should be replaced, so break here.
            break;
        }

        prototype = obj->getPrototype(vm, exec);
        if (vm.exception())
            return false;
        if (prototype.isNull())
            break;
    }
    
    if (slot.isStrictMode())
        throwTypeError(exec, scope, StrictModeReadonlyPropertyWriteError);
    return false;
}
コード例 #2
0
ファイル: JSCJSValue.cpp プロジェクト: eocanha/webkit
bool JSValue::putToPrimitiveByIndex(ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)
{
    VM& vm = exec->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    if (propertyName > MAX_ARRAY_INDEX) {
        PutPropertySlot slot(*this, shouldThrow);
        return putToPrimitive(exec, Identifier::from(exec, propertyName), value, slot);
    }

    JSObject* prototype = synthesizePrototype(exec);
    if (UNLIKELY(!prototype)) {
        ASSERT(scope.exception());
        return false;
    }
    bool putResult = false;
    if (prototype->attemptToInterceptPutByIndexOnHoleForPrototype(exec, *this, propertyName, value, shouldThrow, putResult))
        return putResult;

    return typeError(exec, scope, shouldThrow, ASCIILiteral(ReadonlyPropertyWriteError));
}