Exemplo n.º 1
0
void uAutoRelease(uObject* object)
{
    if (object)
    {
        uThreadData* thread = uGetThreadData();
        thread->AutoReleaseList.Add(object);
        U_ASSERT(thread->AutoReleasePtr >= thread->AutoReleaseStack);
#ifdef DEBUG_ARC
        int releaseCount = 0;
        for (size_t i = 0; i < thread->AutoReleaseList.Length(); i++)
            if (thread->AutoReleaseList[i] == object)
                releaseCount++;

        int retainCount = object->__retains - releaseCount;
        if (retainCount < 0)
        {
            Xli::Error->WriteFormat("*** BAD AUTORELEASE: %s #%d (%d bytes, %d retains) ***%s\n", object->__type->FullName, object->__id, object->__size, retainCount, uGetCaller().Ptr());
            U_FATAL();
        }
#endif
#if DEBUG_ARC >= 4
        Xli::Error->WriteFormat("autorelease %s #%d (%d bytes, %d retains)%s\n", object->__type->FullName, object->__id, object->__size, object->__retains, uGetCaller().Ptr());
#endif
    }
}
Exemplo n.º 2
0
uType* uType::GetBase(uType* def)
{
    for (uType* type = this; type; type = type->Base)
        if (type->Definition == def)
            return type;
    U_FATAL();
}
Exemplo n.º 3
0
void uWeakStateIntercept::SetCallback(uWeakObject* weak, uWeakStateIntercept::Callback cb)
{
    if (!weak || !cb || weak->ZombieState != uWeakObject::Healthy)
        U_FATAL();

    weak->ZombieState = uWeakObject::Infected;
    weak->ZombieStateIntercept = cb;
}
Exemplo n.º 4
0
uObject* uDelegate::Invoke(uArray* array)
{
    uDelegateType* type = (uDelegateType*)GetType();
    size_t count = type->ParameterCount;
    uType** params = type->ParameterTypes;
    void** args = NULL;

    if (array)
    {
        if (!U_IS_OBJECT(((uArrayType*)array->GetType())->ElementType))
            U_THROW_ICE();
        if (count != array->Length())
            U_THROW_IOORE();

        uObject** objects = (uObject**)array->Ptr();
        void** ptr = args = count > 0
            ? (void**)U_ALLOCA(count * sizeof(void*))
            : NULL;

        for (size_t i = 0; i < count; i++)
        {
            uType* param = *params++;
            uObject* object = *objects++;

            switch (param->Type)
            {
            case uTypeTypeEnum:
            case uTypeTypeStruct:
                *ptr++ = (uint8_t*)object + sizeof(uObject);
                break;
            case uTypeTypeByRef:
                *ptr++ = U_IS_VALUE(((uByRefType*)param)->ValueType)
                        ? (uint8_t*)object + sizeof(uObject)
                        : (void*)&object;
                break;
            case uTypeTypeClass:
            case uTypeTypeDelegate:
            case uTypeTypeInterface:
            case uTypeTypeArray:
                *ptr++ = object;
                break;
            default:
                U_FATAL();
            }
        }
    }

    uType* returnType = type->ReturnType;
    void* retval = !U_IS_VOID(returnType)
        ? U_ALLOCA(returnType->ValueSize)
        : NULL;

    Invoke(retval, args, count);
    return uBoxPtr(returnType, retval, NULL, true);
}
Exemplo n.º 5
0
void uType::Build()
{
    switch (State)
    {
    default:
        return;
    case uTypeStateBuilding:
        U_FATAL();
    case uTypeStateUninitialized:
        State = uTypeStateBuilding;
        uBuildParameterization(this);
        uBuildMemory(this);
//#if #(REFLECTION:Defined)
        uBuildReflection(this);
//#endif
        uVerifyBuild(this);
        State = uTypeStateBuilt;
        break;
    }
}
Exemplo n.º 6
0
void uCopy(uType* type, const void* src, void* dst, uint8_t flags)
{
    U_ASSERT(type && dst && (
        U_IS_OBJECT(type) &&
            flags & uCopyFlagsValue ||
        src
    ));

    if (U_IS_OBJECT(type))
    {
        switch (flags)
        {
        case 0:
            *(uObject**)dst = *(uObject**)src;
            break;
        case uCopyFlagsValue:
            *(uObject**)dst = (uObject*)src;
            break;
        case uCopyFlagsStrong:
            *(uStrong<uObject*>*)dst = *(uObject**)src;
            break;
        case uCopyFlagsStrongValue:
            *(uStrong<uObject*>*)dst = (uObject*)src;
            break;
        default:
            U_FATAL();
        }

        U_ASSERT(!*(uObject**)dst || uIs(*(uObject**)dst, type));
    }
    else if (type->Flags & uTypeFlagsRetainStruct)
    {
        uAutoReleaseStruct(type, dst);
        memcpy(dst, src, type->ValueSize);
        uRetainStruct(type, dst);
    }
    else
        INLINE_MEMCPY(dst, src, type->ValueSize);
}
Exemplo n.º 7
0
void uReverseBytes(uint8_t* ptr, size_t size)
{
    uint8_t tmp;

    switch (size)
    {
    case 2:
        tmp = ptr[0];
        ptr[0] = ptr[1];
        ptr[1] = tmp;
        break;
    case 4:
        tmp = ptr[0];
        ptr[0] = ptr[3];
        ptr[3] = tmp;
        tmp = ptr[1];
        ptr[1] = ptr[2];
        ptr[2] = tmp;
        break;
    case 8:
        tmp = ptr[0];
        ptr[0] = ptr[7];
        ptr[7] = tmp;
        tmp = ptr[1];
        ptr[1] = ptr[6];
        ptr[6] = tmp;
        tmp = ptr[2];
        ptr[2] = ptr[5];
        ptr[5] = tmp;
        tmp = ptr[3];
        ptr[3] = ptr[4];
        ptr[4] = tmp;
        break;
    default:
        U_FATAL();
    }
}
Exemplo n.º 8
0
static int64_t uLoadEnum(uEnumType* type, void* value)
{
    // See if value is unsigned (Uno.Byte|Uno.U*)
    uChar fifth = type->Base->FullName[4];
    bool isUnsigned = fifth == 'B' || fifth == 'U';

    switch (type->ValueSize)
    {
    case 1: return isUnsigned
        ? (int64_t)*(uint8_t*)value
        : (int64_t)*(int8_t*)value;
    case 2: return isUnsigned
        ? (int64_t)*(uint16_t*)value
        : (int64_t)*(int16_t*)value;
    case 4: return isUnsigned
        ? (int64_t)*(uint32_t*)value
        : (int64_t)*(int32_t*)value;
    case 8: return isUnsigned
        ? (int64_t)*(uint64_t*)value
        : *(int64_t*)value;
    default:
        U_FATAL();
    }
}
Exemplo n.º 9
0
const void* uType::InterfacePtr(const uObject* object)
{
    uType* type = object->__type;
    do
    {
        intptr_t left = 0,
                 right = (intptr_t)type->InterfaceCount - 1;

        while (left <= right)
        {
            intptr_t mid = (left + right) >> 1;
            ptrdiff_t diff = (uint8_t*)this - (uint8_t*)type->Interfaces[mid].Type;

            if (diff > 0)
                left = mid + 1;
            else if (diff < 0)
                right = mid - 1;
            else
                return (const uint8_t*)type + type->Interfaces[mid].Offset;
        }
    }
    while ((type = type->Base));
    U_FATAL();
}
Exemplo n.º 10
0
uObject* uFunction::Invoke(uObject* object, uArray* args)
{
    size_t count = ParameterTypes->Length();
    void* retval = !U_IS_VOID(ReturnType)
        ? U_ALLOCA(ReturnType->ValueSize)
        : NULL;

    if (!(Flags & uFunctionFlagsStatic))
        count++;
    if (Generic)
        count++;
    if (retval)
        count++;

    void** stack;
    void** ptr = stack = count > 0
            ? (void**)U_ALLOCA(count * sizeof(void*))
            : NULL;

    if (!(Flags & uFunctionFlagsStatic))
        *ptr++ = !(Flags & uFunctionFlagsVirtual) && U_IS_VALUE(DeclaringType)
            ? (uint8_t*)uPtr(object) + sizeof(uObject)
            : (void*)uPtr(object);
    if (Generic)
        *ptr++ = Generic;

    if (args)
    {
        if (args->Length() != ParameterTypes->Length())
            U_THROW_IOORE();
        if (U_IS_VALUE(((uArrayType*)args->GetType())->ElementType))
            U_THROW_ICE();

        uType** params = (uType**)ParameterTypes->Ptr();
        uObject** objects = (uObject**)args->Ptr();

        for (int i = 0; i < args->Length(); i++)
        {
            uType*& param = *params++;
            uObject*& arg = *objects++;

            switch (param->Type)
            {
            case uTypeTypeEnum:
            case uTypeTypeStruct:
                *ptr++ = (uint8_t*)arg + sizeof(uObject);
                break;
            case uTypeTypeByRef:
                *ptr++ = U_IS_VALUE(((uByRefType*)param)->ValueType)
                        ? (uint8_t*)arg + sizeof(uObject)
                        : (void*)&arg;
                break;
            case uTypeTypeClass:
            case uTypeTypeDelegate:
            case uTypeTypeInterface:
            case uTypeTypeArray:
                *ptr++ = arg;
                break;
            default:
                U_FATAL();
            }
        }
    }
    else if (ParameterTypes->Length() != 0)
        U_THROW_IOORE();

    if (retval)
        *ptr++ = retval;

    U_ASSERT(DeclaringType);
    DeclaringType->Init();
    uInvoke(Flags & uFunctionFlagsVirtual
            ? *(void**)((uint8_t*)object->GetType() + _offset)
            : _func,
        stack,
        count);
    return uBoxPtr(ReturnType, retval, NULL, true);
}
Exemplo n.º 11
0
void uRelease(uObject* object)
{
    if (object)
    {
        if (Xli::AtomicDecrement(&object->__retains) == 0)
        {
            if (!uTryClearWeak(object))
                return;
#ifdef DEBUG_ARC
            uThreadData* thread = uGetThreadData();

            if (thread->AutoReleasePtr >= thread->AutoReleaseStack)
            {
                uAutoReleaseFrame* frame = thread->AutoReleasePtr;
                if (frame->AllocCount > 0)
                {
                    frame->FreeCount++;
                    frame->FreeSize += object->__size;
                }
            }
#endif
            uType* type = object->__type;

            switch (type->Type)
            {
            case uTypeTypeClass:
            {
                uType* baseType = type;
                do
                {
                    if (baseType->fp_Finalize)
                    {
                        try { (*baseType->fp_Finalize)(object); }
                        catch (...) { Xli::Error->WriteFormat("Runtime Error: Unhandled exception in finalizer for %s\n", baseType->FullName); }
                    }
                } while ((baseType = baseType->Base));
                uReleaseStruct(type, object);
                break;
            }

            case uTypeTypeStruct:
                // This must be a boxed value, so append size of object header
                uReleaseStruct(type, (uint8_t*)object + sizeof(uObject));
                break;

            case uTypeTypeDelegate:
                uRelease(((uDelegate*)object)->_object);
                uRelease(((uDelegate*)object)->_prev);
                break;

            case uTypeTypeArray:
            {
                uArray* array = (uArray*)object;
                uArrayType* arrayType = (uArrayType*)type;
                uType* elmType = arrayType->ElementType;

                switch (elmType->Type)
                {
                case uTypeTypeClass:
                case uTypeTypeInterface:
                case uTypeTypeDelegate:
                case uTypeTypeArray:
                    for (uObject** objAddr = (uObject**)array->_ptr;
                         array->_length--;
                         objAddr++)
                        uRelease(*objAddr);
                    break;

                case uTypeTypeStruct:
                    for (uint8_t* address = (uint8_t*)array->_ptr;
                         array->_length--;
                         address += elmType->ValueSize)
                        uReleaseStruct(elmType, address);
                    break;

                default:
                    break;
                }
                break;
            }
            default:
                break;
            }
#if DEBUG_ARC >= 2
            Xli::Error->WriteFormat("free %s #%d (%d bytes)%s\n", object->__type->FullName, object->__id, object->__size, uGetCaller().Ptr());
#endif
#ifdef DEBUG_DUMPS
            uEnterCritical();
            _HeapObjects->Remove(object);
            uExitCritical();
#endif
            U_ASSERT(object->__type != ::g::Uno::Type_typeof());
            U_FREE_OBJECT(object);
            return;
        }

        if (object->__retains < 0)
        {
#if DEBUG_ARC >= 4
            Xli::Error->WriteFormat("*** BAD OBJECT: %s #%d (%d retains) ***%s\n", object->__type->FullName, object->__id, object->__retains, uGetCaller().Ptr());
#else
            Xli::Error->WriteFormat("*** BAD OBJECT: 0x%llx ***\n", (uintptr_t)object);
#endif
            U_FATAL();
        }
        else
        {
#if DEBUG_ARC >= 3
            Xli::Error->WriteFormat("release %s #%d (%d bytes, %d retains)%s\n", object->__type->FullName, object->__id, object->__size, object->__retains, uGetCaller().Ptr());
#endif
        }
    }
}
Exemplo n.º 12
0
static void uDumpObjectAndStrongRefs(FILE* fp, uObject* object)
{
    uType* type = object->GetType();
    uDumpObject(fp, object, type->FullName);

    switch (type->Type)
    {
    case uTypeTypeClass:
        do
            uDumpAllStrongRefs(fp, object, object, type);
        while ((type = type->Base));
        break;

    case uTypeTypeEnum:
        break;

    case uTypeTypeStruct:
    {
        uint8_t* address = (uint8_t*)object + sizeof(uObject);
        uDumpAllStrongRefs(fp, object, address, type);
        break;
    }
    case uTypeTypeDelegate:
    {
        uDelegate* delegate = (uDelegate*)object;
        uDumpStrongRef(fp, object, delegate->_object);
        uDumpStrongRef(fp, object, delegate->_prev);
        break;
    }
    case uTypeTypeArray:
    {
        uArray* array = (uArray*)object;
        uArrayType* arrayType = (uArrayType*)type;
        uType* elmType = arrayType->ElementType;

        switch (elmType->Type)
        {
        case uTypeTypeClass:
        case uTypeTypeInterface:
        case uTypeTypeDelegate:
        case uTypeTypeArray:
            for (int i = 0; i < array->Length(); ++i)
            {
                uObject* target = ((uObject**)array->Ptr())[i];
                uDumpStrongRef(fp, object, target);
            }
            break;

        case uTypeTypeEnum:
            break;

        case uTypeTypeStruct:
            for (int i = 0; i < array->Length(); ++i)
            {
                uint8_t* address = (uint8_t*)array->Ptr() + i * elmType->ValueSize;
                uDumpAllStrongRefs(fp, object, address, elmType);
            }
            break;

        default:
            U_FATAL();
        }
        break;
    }

    default:
        U_FATAL();
    }
}