forked from Mirrors/wine-wine
msvcrt: Partially implement type_info::name_internal_method().
parent
8a7f817dea
commit
8723149037
|
@ -260,8 +260,8 @@
|
||||||
@ cdecl -arch=win64 ?_invalid_parameter@@YAXPEBG00I_K@Z(wstr wstr wstr long long) msvcrt._invalid_parameter
|
@ cdecl -arch=win64 ?_invalid_parameter@@YAXPEBG00I_K@Z(wstr wstr wstr long long) msvcrt._invalid_parameter
|
||||||
@ stub -arch=win32 ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z # int __cdecl _is_exception_typeof(class type_info const &,struct _EXCEPTION_POINTERS *)
|
@ stub -arch=win32 ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z # int __cdecl _is_exception_typeof(class type_info const &,struct _EXCEPTION_POINTERS *)
|
||||||
@ stub -arch=win64 ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z # int __cdecl _is_exception_typeof(class type_info const & __ptr64,struct _EXCEPTION_POINTERS * __ptr64)
|
@ stub -arch=win64 ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z # int __cdecl _is_exception_typeof(class type_info const & __ptr64,struct _EXCEPTION_POINTERS * __ptr64)
|
||||||
@ stub -arch=win32 ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z # public: char const * __thiscall type_info::_name_internal_method(struct __type_info_node *)const
|
@ thiscall -arch=win32 ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z(ptr ptr) msvcr90.?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z
|
||||||
@ stub -arch=win64 ?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z # public: char const * __ptr64 __cdecl type_info::_name_internal_method(struct __type_info_node * __ptr64)const __ptr64
|
@ cdecl -arch=win64 ?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z(ptr ptr) msvcr90.?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z
|
||||||
@ varargs -arch=win32 ?_open@@YAHPBDHH@Z(str long) msvcrt._open
|
@ varargs -arch=win32 ?_open@@YAHPBDHH@Z(str long) msvcrt._open
|
||||||
@ varargs -arch=win64 ?_open@@YAHPEBDHH@Z(str long) msvcrt._open
|
@ varargs -arch=win64 ?_open@@YAHPEBDHH@Z(str long) msvcrt._open
|
||||||
@ cdecl -arch=win32 ?_query_new_handler@@YAP6AHI@ZXZ() msvcrt.?_query_new_handler@@YAP6AHI@ZXZ
|
@ cdecl -arch=win32 ?_query_new_handler@@YAP6AHI@ZXZ() msvcrt.?_query_new_handler@@YAP6AHI@ZXZ
|
||||||
|
|
|
@ -83,8 +83,8 @@
|
||||||
@ cdecl -arch=win64 ?_invalid_parameter@@YAXPEBG00I_K@Z(wstr wstr wstr long long) msvcrt._invalid_parameter
|
@ cdecl -arch=win64 ?_invalid_parameter@@YAXPEBG00I_K@Z(wstr wstr wstr long long) msvcrt._invalid_parameter
|
||||||
@ stub -arch=win32 ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z # int __cdecl _is_exception_typeof(class type_info const &,struct _EXCEPTION_POINTERS *)
|
@ stub -arch=win32 ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z # int __cdecl _is_exception_typeof(class type_info const &,struct _EXCEPTION_POINTERS *)
|
||||||
@ stub -arch=win64 ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z # int __cdecl _is_exception_typeof(class type_info const & __ptr64,struct _EXCEPTION_POINTERS * __ptr64)
|
@ stub -arch=win64 ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z # int __cdecl _is_exception_typeof(class type_info const & __ptr64,struct _EXCEPTION_POINTERS * __ptr64)
|
||||||
@ stub -arch=win32 ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z # public: char const * __thiscall type_info::_name_internal_method(struct __type_info_node *)const
|
@ thiscall -arch=win32 ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z(ptr ptr) msvcr90.?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z
|
||||||
@ stub -arch=win64 ?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z # public: char const * __ptr64 __cdecl type_info::_name_internal_method(struct __type_info_node * __ptr64)const __ptr64
|
@ cdecl -arch=win64 ?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z(ptr ptr) msvcr90.?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z
|
||||||
@ varargs -arch=win32 ?_open@@YAHPBDHH@Z(str long) msvcrt._open
|
@ varargs -arch=win32 ?_open@@YAHPBDHH@Z(str long) msvcrt._open
|
||||||
@ varargs -arch=win64 ?_open@@YAHPEBDHH@Z(str long) msvcrt._open
|
@ varargs -arch=win64 ?_open@@YAHPEBDHH@Z(str long) msvcrt._open
|
||||||
@ cdecl -arch=win32 ?_query_new_handler@@YAP6AHI@ZXZ() msvcrt.?_query_new_handler@@YAP6AHI@ZXZ
|
@ cdecl -arch=win32 ?_query_new_handler@@YAP6AHI@ZXZ() msvcrt.?_query_new_handler@@YAP6AHI@ZXZ
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
|
@ -30,6 +31,46 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(msvcr90);
|
WINE_DEFAULT_DEBUG_CHANNEL(msvcr90);
|
||||||
|
|
||||||
|
#ifdef __i386__ /* thiscall functions are i386-specific */
|
||||||
|
|
||||||
|
#define THISCALL(func) __thiscall_ ## func
|
||||||
|
#define THISCALL_NAME(func) __ASM_NAME("__thiscall_" #func)
|
||||||
|
#define __thiscall __stdcall
|
||||||
|
#define DEFINE_THISCALL_WRAPPER(func,args) \
|
||||||
|
extern void THISCALL(func)(void); \
|
||||||
|
__ASM_GLOBAL_FUNC(__thiscall_ ## func, \
|
||||||
|
"popl %eax\n\t" \
|
||||||
|
"pushl %ecx\n\t" \
|
||||||
|
"pushl %eax\n\t" \
|
||||||
|
"jmp " __ASM_NAME(#func) __ASM_STDCALL(args) )
|
||||||
|
|
||||||
|
#else /* __i386__ */
|
||||||
|
|
||||||
|
#define THISCALL(func) func
|
||||||
|
#define THISCALL_NAME(func) __ASM_NAME(#func)
|
||||||
|
#define __thiscall __cdecl
|
||||||
|
#define DEFINE_THISCALL_WRAPPER(func,args) /* nothing */
|
||||||
|
|
||||||
|
#endif /* __i386__ */
|
||||||
|
|
||||||
|
struct __type_info_node
|
||||||
|
{
|
||||||
|
void *memPtr;
|
||||||
|
struct __type_info_node* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct __type_info
|
||||||
|
{
|
||||||
|
const void *vtable;
|
||||||
|
char *name; /* Unmangled name, allocated lazily */
|
||||||
|
char mangled[32]; /* Variable length, but we declare it large enough for static RTTI */
|
||||||
|
} type_info;
|
||||||
|
|
||||||
|
typedef void* (*__cdecl malloc_func_t)(size_t);
|
||||||
|
typedef void (*__cdecl free_func_t)(void*);
|
||||||
|
|
||||||
|
extern char* __cdecl __unDName(char *,const char*,int,malloc_func_t,free_func_t,unsigned short int);
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* msvcr90_stat64_to_stat32 [internal]
|
* msvcr90_stat64_to_stat32 [internal]
|
||||||
*/
|
*/
|
||||||
|
@ -260,3 +301,40 @@ int CDECL _atoflt( _CRT_FLOAT *value, char *str )
|
||||||
{
|
{
|
||||||
return _atoflt_l( value, str, NULL );
|
return _atoflt_l( value, str, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z (MSVCR90.@)
|
||||||
|
*/
|
||||||
|
DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_name_internal_method,8)
|
||||||
|
const char * __thiscall MSVCRT_type_info_name_internal_method(type_info * _this, struct __type_info_node *node)
|
||||||
|
{
|
||||||
|
static int once;
|
||||||
|
|
||||||
|
if (node && !once++) FIXME("type_info_node parameter ignored\n");
|
||||||
|
|
||||||
|
if (!_this->name)
|
||||||
|
{
|
||||||
|
/* Create and set the demangled name */
|
||||||
|
/* Nota: mangled name in type_info struct always start with a '.', while
|
||||||
|
* it isn't valid for mangled name.
|
||||||
|
* Is this '.' really part of the mangled name, or has it some other meaning ?
|
||||||
|
*/
|
||||||
|
char* name = __unDName(0, _this->mangled + 1, 0, malloc, free, 0x2800);
|
||||||
|
if (name)
|
||||||
|
{
|
||||||
|
unsigned int len = strlen(name);
|
||||||
|
|
||||||
|
/* It seems _unDName may leave blanks at the end of the demangled name */
|
||||||
|
while (len && name[--len] == ' ')
|
||||||
|
name[len] = '\0';
|
||||||
|
|
||||||
|
if (InterlockedCompareExchangePointer((void**)&_this->name, name, NULL))
|
||||||
|
{
|
||||||
|
/* Another thread set this member since we checked above - use it */
|
||||||
|
free(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TRACE("(%p) returning %s\n", _this, _this->name);
|
||||||
|
return _this->name;
|
||||||
|
}
|
||||||
|
|
|
@ -83,8 +83,8 @@
|
||||||
@ cdecl -arch=win64 ?_invalid_parameter@@YAXPEBG00I_K@Z(wstr wstr wstr long long) msvcrt._invalid_parameter
|
@ cdecl -arch=win64 ?_invalid_parameter@@YAXPEBG00I_K@Z(wstr wstr wstr long long) msvcrt._invalid_parameter
|
||||||
@ stub -arch=win32 ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z # int __cdecl _is_exception_typeof(class type_info const &,struct _EXCEPTION_POINTERS *)
|
@ stub -arch=win32 ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z # int __cdecl _is_exception_typeof(class type_info const &,struct _EXCEPTION_POINTERS *)
|
||||||
@ stub -arch=win64 ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z # int __cdecl _is_exception_typeof(class type_info const & __ptr64,struct _EXCEPTION_POINTERS * __ptr64)
|
@ stub -arch=win64 ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z # int __cdecl _is_exception_typeof(class type_info const & __ptr64,struct _EXCEPTION_POINTERS * __ptr64)
|
||||||
@ stub -arch=win32 ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z # public: char const * __thiscall type_info::_name_internal_method(struct __type_info_node *)const
|
@ thiscall -arch=win32 ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z(ptr ptr) MSVCRT_type_info_name_internal_method
|
||||||
@ stub -arch=win64 ?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z # public: char const * __ptr64 __cdecl type_info::_name_internal_method(struct __type_info_node * __ptr64)const __ptr64
|
@ cdecl -arch=win64 ?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z(ptr ptr) MSVCRT_type_info_name_internal_method
|
||||||
@ varargs -arch=win32 ?_open@@YAHPBDHH@Z(str long) msvcrt._open
|
@ varargs -arch=win32 ?_open@@YAHPBDHH@Z(str long) msvcrt._open
|
||||||
@ varargs -arch=win64 ?_open@@YAHPEBDHH@Z(str long) msvcrt._open
|
@ varargs -arch=win64 ?_open@@YAHPEBDHH@Z(str long) msvcrt._open
|
||||||
@ cdecl -arch=win32 ?_query_new_handler@@YAP6AHI@ZXZ() msvcrt.?_query_new_handler@@YAP6AHI@ZXZ
|
@ cdecl -arch=win32 ?_query_new_handler@@YAP6AHI@ZXZ() msvcrt.?_query_new_handler@@YAP6AHI@ZXZ
|
||||||
|
|
|
@ -79,6 +79,17 @@ static void* (__cdecl *p_realloc_crt)(void*, size_t);
|
||||||
static void* (__cdecl *p_malloc)(size_t);
|
static void* (__cdecl *p_malloc)(size_t);
|
||||||
static void (__cdecl *p_free)(void*);
|
static void (__cdecl *p_free)(void*);
|
||||||
|
|
||||||
|
/* type info */
|
||||||
|
typedef struct __type_info
|
||||||
|
{
|
||||||
|
void *vtable;
|
||||||
|
char *name;
|
||||||
|
char mangled[16];
|
||||||
|
} type_info;
|
||||||
|
|
||||||
|
static char* (WINAPI *p_type_info_name_internal_method)(type_info*);
|
||||||
|
static void (WINAPI *ptype_info_dtor)(type_info*);
|
||||||
|
|
||||||
static void* (WINAPI *pEncodePointer)(void *);
|
static void* (WINAPI *pEncodePointer)(void *);
|
||||||
|
|
||||||
static int cb_called[4];
|
static int cb_called[4];
|
||||||
|
@ -91,6 +102,62 @@ static inline int almost_equal_f(float f1, float f2)
|
||||||
|
|
||||||
/* ########## */
|
/* ########## */
|
||||||
|
|
||||||
|
/* thiscall emulation */
|
||||||
|
/* Emulate a __thiscall */
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
static inline void* do_call_func1(void *func, void *_this)
|
||||||
|
{
|
||||||
|
volatile void* retval = 0;
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
push ecx
|
||||||
|
mov ecx, _this
|
||||||
|
call func
|
||||||
|
mov retval, eax
|
||||||
|
pop ecx
|
||||||
|
}
|
||||||
|
return (void*)retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void* do_call_func2(void *func, void *_this, const void* arg)
|
||||||
|
{
|
||||||
|
volatile void* retval = 0;
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
push ecx
|
||||||
|
push arg
|
||||||
|
mov ecx, _this
|
||||||
|
call func
|
||||||
|
mov retval, eax
|
||||||
|
pop ecx
|
||||||
|
}
|
||||||
|
return (void*)retval;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void* do_call_func1(void *func, void *_this)
|
||||||
|
{
|
||||||
|
void *ret, *dummy;
|
||||||
|
__asm__ __volatile__ ("call *%2"
|
||||||
|
: "=a" (ret), "=c" (dummy)
|
||||||
|
: "g" (func), "1" (_this)
|
||||||
|
: "edx", "memory" );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* do_call_func2(void *func, void *_this, const void* arg)
|
||||||
|
{
|
||||||
|
void *ret, *dummy;
|
||||||
|
__asm__ __volatile__ ("pushl %3\n\tcall *%2"
|
||||||
|
: "=a" (ret), "=c" (dummy)
|
||||||
|
: "r" (func), "r" (arg), "1" (_this)
|
||||||
|
: "edx", "memory" );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define call_func1(x,y) do_call_func1((void*)x,(void*)y)
|
||||||
|
#define call_func2(x,y,z) do_call_func2((void*)x,(void*)y,(void*)z)
|
||||||
|
|
||||||
static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
|
static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
|
||||||
const wchar_t *function, const wchar_t *file,
|
const wchar_t *function, const wchar_t *file,
|
||||||
unsigned line, uintptr_t arg)
|
unsigned line, uintptr_t arg)
|
||||||
|
@ -796,6 +863,43 @@ if (0)
|
||||||
p_free(mem);
|
p_free(mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __i386__
|
||||||
|
|
||||||
|
struct __type_info_node {
|
||||||
|
void *memPtr;
|
||||||
|
struct __type_info_node* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void test_typeinfo(void)
|
||||||
|
{
|
||||||
|
static type_info t1 = { NULL, NULL,{'.','?','A','V','t','e','s','t','1','@','@',0,0,0,0,0 } };
|
||||||
|
struct __type_info_node node;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
if (!p_type_info_name_internal_method)
|
||||||
|
{
|
||||||
|
win_skip("public: char const * __thiscall type_info::_name_internal_method(struct \
|
||||||
|
__type_info_node *)const not supported\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* name */
|
||||||
|
t1.name = NULL;
|
||||||
|
node.memPtr = NULL;
|
||||||
|
node.next = NULL;
|
||||||
|
name = call_func2(p_type_info_name_internal_method, &t1, &node);
|
||||||
|
ok(name != NULL, "got %p\n", name);
|
||||||
|
ok(name && t1.name && !strcmp(name, t1.name), "bad name '%s' for t1\n", name);
|
||||||
|
|
||||||
|
ok(t1.name && !strcmp(t1.name, "class test1"), "demangled to '%s' for t1\n", t1.name);
|
||||||
|
call_func1(ptype_info_dtor, &t1);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void test_typeinfo(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
START_TEST(msvcr90)
|
START_TEST(msvcr90)
|
||||||
{
|
{
|
||||||
HMODULE hcrt;
|
HMODULE hcrt;
|
||||||
|
@ -834,6 +938,9 @@ START_TEST(msvcr90)
|
||||||
p_realloc_crt = (void*) GetProcAddress(hcrt, "_realloc_crt");
|
p_realloc_crt = (void*) GetProcAddress(hcrt, "_realloc_crt");
|
||||||
p_malloc = (void*) GetProcAddress(hcrt, "malloc");
|
p_malloc = (void*) GetProcAddress(hcrt, "malloc");
|
||||||
p_free = (void*)GetProcAddress(hcrt, "free");
|
p_free = (void*)GetProcAddress(hcrt, "free");
|
||||||
|
p_type_info_name_internal_method = (void*)GetProcAddress(hcrt,
|
||||||
|
"?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z");
|
||||||
|
ptype_info_dtor = (void*)GetProcAddress(hcrt, "??1type_info@@UAE@XZ");
|
||||||
|
|
||||||
hkernel32 = GetModuleHandleA("kernel32.dll");
|
hkernel32 = GetModuleHandleA("kernel32.dll");
|
||||||
pEncodePointer = (void *) GetProcAddress(hkernel32, "EncodePointer");
|
pEncodePointer = (void *) GetProcAddress(hkernel32, "EncodePointer");
|
||||||
|
@ -851,4 +958,5 @@ START_TEST(msvcr90)
|
||||||
test__sopen_s();
|
test__sopen_s();
|
||||||
test__wsopen_s();
|
test__wsopen_s();
|
||||||
test__realloc_crt();
|
test__realloc_crt();
|
||||||
|
test_typeinfo();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue