msvcrt: Fixed get_this_pointer implementation.

This commit is contained in:
Piotr Caban 2012-12-10 16:13:50 +01:00 committed by Alexandre Julliard
parent d3ecfe0599
commit b9c71ffd42
2 changed files with 21 additions and 8 deletions

View File

@ -133,20 +133,21 @@ static inline const char *dbgstr_type_info( const type_info *info )
/* compute the this pointer for a base class of a given type */
static inline void *get_this_pointer( const this_ptr_offsets *off, void *object )
{
void *this_ptr;
int *offset_ptr;
if (!object) return NULL;
this_ptr = (char *)object + off->this_offset;
if (off->vbase_descr >= 0)
{
int *offset_ptr;
/* move this ptr to vbase descriptor */
this_ptr = (char *)this_ptr + off->vbase_descr;
object = (char *)object + off->vbase_descr;
/* and fetch additional offset from vbase descriptor */
offset_ptr = (int *)(*(char **)this_ptr + off->vbase_offset);
this_ptr = (char *)this_ptr + *offset_ptr;
offset_ptr = (int *)(*(char **)object + off->vbase_offset);
object = (char *)object + *offset_ptr;
}
return this_ptr;
object = (char *)object + off->this_offset;
return object;
}
#ifndef __x86_64__

View File

@ -901,6 +901,12 @@ static void test_rtti(void)
{ {RTTI_REF(child_class_rtti, base_descriptor[0]), RTTI_REF(child_class_rtti, base_descriptor[1])} },
{0, 0, 2, RTTI_REF(child_class_rtti, base_array)},
{1, 0, 0, RTTI_REF(child_class_rtti, type_info[1]), RTTI_REF(child_class_rtti, object_hierarchy), RTTI_REF(child_class_rtti, object_locator)}
}, virtual_base_class_rtti = {
{ {NULL, NULL, "simple_class"}, {NULL, NULL, "child_class"} },
{ {RTTI_REF(virtual_base_class_rtti, type_info[1]), 0, {0x10, sizeof(void*), sizeof(int)}, 0}, {RTTI_REF(virtual_base_class_rtti, type_info[0]), 0, {8, -1, 0}, 0} },
{ {RTTI_REF(virtual_base_class_rtti, base_descriptor[0]), RTTI_REF(virtual_base_class_rtti, base_descriptor[1])} },
{0, 0, 2, RTTI_REF(virtual_base_class_rtti, base_array)},
{1, 0, 0, RTTI_REF(virtual_base_class_rtti, type_info[1]), RTTI_REF(virtual_base_class_rtti, object_hierarchy), RTTI_REF(virtual_base_class_rtti, object_locator)}
};
static struct rtti_data simple_class_sig0_rtti, child_class_sig0_rtti;
@ -912,6 +918,9 @@ static void test_rtti(void)
void *simple_class_sig0 = &simple_class_sig0_vtbl[1];
void *child_class_sig0_vtbl[2] = {&child_class_sig0_rtti.object_locator};
void *child_class_sig0 = &child_class_sig0_vtbl[1];
void *virtual_base_class_vtbl[2] = {&virtual_base_class_rtti.object_locator};
int virtual_base_class_vbtbl[2] = {0, 0x100};
void *virtual_base_class[2] = {&virtual_base_class_vtbl[1], virtual_base_class_vbtbl};
static const char* e_name = "name";
type_info *ti,*bti;
@ -1026,6 +1035,9 @@ static void test_rtti(void)
casted = p__RTDynamicCast(&child_class, 0, &child_class_rtti.type_info[0], &child_class_rtti.type_info[1], 0);
ok(casted == (char*)&child_class+4, "failed cast to child class (%p %p)\n", casted, &child_class);
casted = p__RTDynamicCast(&virtual_base_class, 0, &virtual_base_class_rtti.type_info[0], &virtual_base_class_rtti.type_info[1], 0);
ok(casted == (char*)&virtual_base_class+0x110+sizeof(void*), "failed cast to child class (%p %p)\n", casted, &virtual_base_class);
}
struct _demangle {