Example #1
0
File: cpp.c Project: Barrell/wine
void* CDECL MSVCRT___RTDynamicCast(void *cppobj, int unknown,
        type_info *src, type_info *dst,
        int do_throw)
{
    void *ret;

    if (!cppobj) return NULL;

    TRACE("obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)\n",
            cppobj, unknown, src, dbgstr_type_info(src), dst, dbgstr_type_info(dst), do_throw);

    __TRY
    {
        int i;
        const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
        const rtti_object_hierarchy *obj_bases;
        const rtti_base_array *base_array;
        char *base;

        if (TRACE_ON(msvcrt)) dump_obj_locator(obj_locator);

        if(obj_locator->signature == 0)
            base = RtlPcToFileHeader((void*)obj_locator, (void**)&base);
        else
            base = (char*)obj_locator - obj_locator->object_locator;

        obj_bases = (const rtti_object_hierarchy*)(base + obj_locator->type_hierarchy);
        base_array = (const rtti_base_array*)(base + obj_bases->base_classes);

        ret = NULL;
        for (i = 0; i < obj_bases->array_len; i++)
        {
            const rtti_base_descriptor *base_desc = (const rtti_base_descriptor*)(base + base_array->bases[i]);
            const type_info *typ = (const type_info*)(base + base_desc->type_descriptor);

            if (!strcmp(typ->mangled, dst->mangled))
            {
                void *this_ptr = (char *)cppobj - obj_locator->base_class_offset;
                ret = get_this_pointer( &base_desc->offsets, this_ptr );
                break;
            }
        }
        if (!ret && do_throw)
        {
            const char *msg = "Bad dynamic_cast!";
            bad_cast e;
            MSVCRT_bad_cast_ctor( &e, &msg );
            _CxxThrowException( &e, &bad_cast_exception_type );
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        __non_rtti_object e;
        MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" );
        _CxxThrowException( &e, &bad_typeid_exception_type );
        return NULL;
    }
    __ENDTRY
    return ret;
}
Example #2
0
File: cpp.c Project: Barrell/wine
const type_info* CDECL MSVCRT___RTtypeid(void *cppobj)
{
    const type_info *ret;

    if (!cppobj)
    {
        bad_typeid e;
        MSVCRT_bad_typeid_ctor( &e, "Attempted a typeid of NULL pointer!" );
        _CxxThrowException( &e, &bad_typeid_exception_type );
        return NULL;
    }

    __TRY
    {
        const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
        char *base;

        if(obj_locator->signature == 0)
            base = RtlPcToFileHeader((void*)obj_locator, (void**)&base);
        else
            base = (char*)obj_locator - obj_locator->object_locator;

        ret = (type_info*)(base + obj_locator->type_descriptor);
    }
    __EXCEPT_PAGE_FAULT
    {
        __non_rtti_object e;
        MSVCRT___non_rtti_object_ctor( &e, "Bad read pointer - no RTTI data!" );
        _CxxThrowException( &e, &bad_typeid_exception_type );
        return NULL;
    }
    __ENDTRY
    return ret;
}
Example #3
0
File: cpp.c Project: Barrell/wine
const type_info* CDECL MSVCRT___RTtypeid(void *cppobj)
{
    const type_info *ret;

    if (!cppobj)
    {
        bad_typeid e;
        MSVCRT_bad_typeid_ctor( &e, "Attempted a typeid of NULL pointer!" );
        _CxxThrowException( &e, &bad_typeid_exception_type );
        return NULL;
    }

    __TRY
    {
        const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
        ret = obj_locator->type_descriptor;
    }
    __EXCEPT_PAGE_FAULT
    {
        __non_rtti_object e;
        MSVCRT___non_rtti_object_ctor( &e, "Bad read pointer - no RTTI data!" );
        _CxxThrowException( &e, &bad_typeid_exception_type );
        return NULL;
    }
    __ENDTRY
    return ret;
}
Example #4
0
extern "C" __declspec(dllexport) void objc_exception_throw(void *exception)
{
    int typeCount = 0;

    //  Get count of all types in exception
    Class curType = object_getClass((id) exception);
    while (curType != nil) {
        typeCount++;

        curType = class_getSuperclass(curType);
    }

    typeCount++; //  For id

    __ObjC_CatchableTypeArray *exceptTypes = (__ObjC_CatchableTypeArray *)_alloca(sizeof(__ObjC_CatchableTypeArray) + sizeof(__ObjC_CatchableType *) * typeCount);

	//  Add exception type and all base types to throw information
    typeCount = 0;
    curType = object_getClass((id)exception);
    while (curType != nil) {
        exceptTypes->types[typeCount] = (__ObjC_CatchableType *)_alloca(sizeof(__ObjC_CatchableType));
        memset(exceptTypes->types[typeCount], 0, sizeof(__ObjC_CatchableType));
        exceptTypes->types[typeCount]->flags = 1;
        exceptTypes->types[typeCount]->mdisp = 0;
        exceptTypes->types[typeCount]->pdisp = -1;
        exceptTypes->types[typeCount]->vdisp = 0;
        exceptTypes->types[typeCount]->type = (const char *) alloca(32);
        memset((void *) exceptTypes->types[typeCount]->type, 0, 32);
        memcpy((char *)exceptTypes->types[typeCount]->type, class_getName(curType), strlen(class_getName(curType)));
        exceptTypes->types[typeCount]->size = 4;
        typeCount++;

        curType = class_getSuperclass(curType);
    }

    //  Add id
    exceptTypes->types[typeCount] = (__ObjC_CatchableType *)_alloca(sizeof(__ObjC_CatchableType));
    memset(exceptTypes->types[typeCount], 0, sizeof(__ObjC_CatchableType));
    exceptTypes->types[typeCount]->flags = 1;
    exceptTypes->types[typeCount]->mdisp = 0;
    exceptTypes->types[typeCount]->pdisp = -1;
    exceptTypes->types[typeCount]->vdisp = 0;
    exceptTypes->types[typeCount]->type = (const char *)alloca(32);
    memset((void *)exceptTypes->types[typeCount]->type, 0, 32);
    exceptTypes->types[typeCount]->size = 4;
    typeCount++;

    exceptTypes->count = typeCount;

    _ThrowInfo ti = 
    {
     0,
     NULL,
     NULL,
     (_CatchableTypeArray *) exceptTypes
    };

    _CxxThrowException(&exception, &ti);
}
Example #5
0
File: cpp.c Project: Barrell/wine
/******************************************************************
 *		__RTCastToVoid (MSVCRT.@)
 *
 * Dynamically cast a C++ object to a void*.
 *
 * PARAMS
 *  cppobj [I] The C++ object to cast
 *
 * RETURNS
 *  Success: The base address of the object as a void*.
 *  Failure: NULL, if cppobj is NULL or has no RTTI.
 *
 * NOTES
 *  This function is usually called by compiler generated code as a result
 *  of using one of the C++ dynamic cast statements.
 */
void* CDECL MSVCRT___RTCastToVoid(void *cppobj)
{
    void *ret;

    if (!cppobj) return NULL;

    __TRY
    {
        const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
        ret = (char *)cppobj - obj_locator->base_class_offset;
    }
    __EXCEPT_PAGE_FAULT
    {
        __non_rtti_object e;
        MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" );
        _CxxThrowException( &e, &bad_typeid_exception_type );
        return NULL;
    }
    __ENDTRY
    return ret;
}
Example #6
0
File: cpp.c Project: Barrell/wine
void* CDECL MSVCRT___RTDynamicCast(void *cppobj, int unknown,
                                   type_info *src, type_info *dst,
                                   int do_throw)
{
    void *ret;

    if (!cppobj) return NULL;

    TRACE("obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)\n",
          cppobj, unknown, src, dbgstr_type_info(src), dst, dbgstr_type_info(dst), do_throw);

    /* To cast an object at runtime:
     * 1.Find out the true type of the object from the typeinfo at vtable[-1]
     * 2.Search for the destination type in the class hierarchy
     * 3.If destination type is found, return base object address + dest offset
     *   Otherwise, fail the cast
     *
     * FIXME: the unknown parameter doesn't seem to be used for anything
     */
    __TRY
    {
        int i;
        const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
        const rtti_object_hierarchy *obj_bases = obj_locator->type_hierarchy;
        const rtti_base_descriptor * const* base_desc = obj_bases->base_classes->bases;

        if (TRACE_ON(msvcrt)) dump_obj_locator(obj_locator);

        ret = NULL;
        for (i = 0; i < obj_bases->array_len; i++)
        {
            const type_info *typ = base_desc[i]->type_descriptor;

            if (!strcmp(typ->mangled, dst->mangled))
            {
                /* compute the correct this pointer for that base class */
                void *this_ptr = (char *)cppobj - obj_locator->base_class_offset;
                ret = get_this_pointer( &base_desc[i]->offsets, this_ptr );
                break;
            }
        }
        /* VC++ sets do_throw to 1 when the result of a dynamic_cast is assigned
         * to a reference, since references cannot be NULL.
         */
        if (!ret && do_throw)
        {
            const char *msg = "Bad dynamic_cast!";
            bad_cast e;
            MSVCRT_bad_cast_ctor( &e, &msg );
            _CxxThrowException( &e, &bad_cast_exception_type );
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        __non_rtti_object e;
        MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" );
        _CxxThrowException( &e, &bad_typeid_exception_type );
        return NULL;
    }
    __ENDTRY
    return ret;
}