Exemple #1
0
bool TiValueIsNull(TiContextRef ctx, TiValueRef value)
{
    TiExcState* exec = toJS(ctx);
    APIEntryShim entryShim(exec);

    TiValue jsValue = toJS(exec, value);
    return jsValue.isNull();
}
Exemple #2
0
::TiType TiValueGetType(TiContextRef ctx, TiValueRef value)
{
    TiExcState* exec = toJS(ctx);
    APIEntryShim entryShim(exec);

    TiValue jsValue = toJS(exec, value);

    if (jsValue.isUndefined())
        return kTITypeUndefined;
    if (jsValue.isNull())
        return kTITypeNull;
    if (jsValue.isBoolean())
        return kTITypeBoolean;
    if (jsValue.isNumber())
        return kTITypeNumber;
    if (jsValue.isString())
        return kTITypeString;
    ASSERT(jsValue.isObject());
    return kTITypeObject;
}
Exemple #3
0
void TiObject::getPropertyNames(TiExcState* exec, PropertyNameArray& propertyNames)
{
    getOwnPropertyNames(exec, propertyNames);

    if (prototype().isNull())
        return;

    TiObject* prototype = asObject(this->prototype());
    while(1) {
        if (prototype->structure()->typeInfo().overridesGetPropertyNames()) {
            prototype->getPropertyNames(exec, propertyNames);
            break;
        }
        prototype->getOwnPropertyNames(exec, propertyNames);
        TiValue nextProto = prototype->prototype();
        if (nextProto.isNull())
            break;
        prototype = asObject(nextProto);
    }
}
Exemple #4
0
bool TiString::getOwnPropertySlot(TiExcState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    // The semantics here are really getPropertySlot, not getOwnPropertySlot.
    // This function should only be called by TiValue::get.
    if (getStringPropertySlot(exec, propertyName, slot))
        return true;
    if (propertyName == exec->propertyNames().underscoreProto) {
        slot.setValue(exec->lexicalGlobalObject()->stringPrototype());
        return true;
    }
    slot.setBase(this);
    TiObject* object;
    for (TiValue prototype = exec->lexicalGlobalObject()->stringPrototype(); !prototype.isNull(); prototype = object->prototype()) {
        object = asObject(prototype);
        if (object->getOwnPropertySlot(exec, propertyName, slot))
            return true;
    }
    slot.setUndefined();
    return true;
}
Exemple #5
0
// ECMA 8.6.2.2
void TiObject::put(TiExcState* exec, const Identifier& propertyName, TiValue value, PutPropertySlot& slot)
{
    ASSERT(value);
    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));

    if (propertyName == exec->propertyNames().underscoreProto) {
        // Setting __proto__ to a non-object, non-null value is silently ignored to match Mozilla.
        if (!value.isObject() && !value.isNull())
            return;

        TiValue nextPrototypeValue = value;
        while (nextPrototypeValue && nextPrototypeValue.isObject()) {
            TiObject* nextPrototype = asObject(nextPrototypeValue)->unwrappedObject();
            if (nextPrototype == this) {
                throwError(exec, GeneralError, "cyclic __proto__ value");
                return;
            }
            nextPrototypeValue = nextPrototype->prototype();
        }

        setPrototype(value);
        return;
    }

    // Check if there are any setters or getters in the prototype chain
    TiValue prototype;
    for (TiObject* obj = this; !obj->structure()->hasGetterSetterProperties(); obj = asObject(prototype)) {
        prototype = obj->prototype();
        if (prototype.isNull()) {
            putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot);
            return;
        }
    }
    
    unsigned attributes;
    TiCell* specificValue;
    if ((m_structure->get(propertyName, attributes, specificValue) != WTI::notFound) && attributes & ReadOnly)
        return;

    for (TiObject* obj = this; ; obj = asObject(prototype)) {
        if (TiValue gs = obj->getDirect(propertyName)) {
            if (gs.isGetterSetter()) {
                TiObject* setterFunc = asGetterSetter(gs)->setter();        
                if (!setterFunc) {
                    throwSetterError(exec);
                    return;
                }
                
                CallData callData;
                CallType callType = setterFunc->getCallData(callData);
                MarkedArgumentBuffer args;
                args.append(value);
                call(exec, setterFunc, callType, callData, this, args);
                return;
            }

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

        prototype = obj->prototype();
        if (prototype.isNull())
            break;
    }

    putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot);
    return;
}