From 51a55fc9e2a59a4f702ceb9528f84abdbc2e2648 Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Wed, 18 Aug 2010 10:36:29 +0200 Subject: [PATCH] msvcp90/tests: Added allocator tests. --- dlls/msvcp90/tests/misc.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) diff --git a/dlls/msvcp90/tests/misc.c b/dlls/msvcp90/tests/misc.c index a3f7401c92e..d05222532b0 100644 --- a/dlls/msvcp90/tests/misc.c +++ b/dlls/msvcp90/tests/misc.c @@ -34,6 +34,22 @@ static BYTE (__cdecl *p_short_eq)(const void*, const void*); static char* (__cdecl *p_Copy_s)(char*, size_t, const char*, size_t); +#ifdef __i386__ +static char* (WINAPI *p_char_address)(char*); +static void* (WINAPI *p_char_ctor)(void); +static void (WINAPI *p_char_deallocate)(char*, size_t); +static char* (WINAPI *p_char_allocate)(size_t); +static void (WINAPI *p_char_construct)(char*, const char*); +static size_t (WINAPI *p_char_max_size)(void); +#else +static char* (__cdecl *p_char_address)(void*, char*); +static void* (__cdecl *p_char_ctor)(void*); +static void (__cdecl *p_char_deallocate)(void*, char*, size_t); +static char* (__cdecl *p_char_allocate)(void*, size_t); +static void (__cdecl *p_char_construct)(void*, char*, const char*); +static size_t (__cdecl *p_char_max_size)(void*); +#endif + static int invalid_parameter = 0; static void __cdecl test_invalid_parameter_handler(const wchar_t *expression, const wchar_t *function, const wchar_t *file, @@ -47,6 +63,105 @@ static void __cdecl test_invalid_parameter_handler(const wchar_t *expression, invalid_parameter++; } +/* Emulate a __thiscall */ +#ifdef __i386__ +#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; +} + +static inline void* do_call_func3(void *func, void *_this, + const void *arg1, const void *arg2) +{ + volatile void* retval = 0; + __asm + { + push ecx + push arg1 + push arg2 + 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; +} + +static void* do_call_func3(void *func, void *_this, + const void *arg1, const void *arg2) +{ + void *ret, *dummy; + __asm__ __volatile__ ( + "pushl %4\n\tpushl %3\n\tcall *%2" + : "=a" (ret), "=c" (dummy) + : "r" (func), "r" (arg1), "r" (arg2), "1" (_this) + : "edx", "memory" + ); + return ret; +} +#endif + +#define call_func1(func,_this) do_call_func1(func,_this) +#define call_func2(func,_this,a) do_call_func2(func,_this,(const void*)a) +#define call_func3(func,_this,a,b) do_call_func3(func,_this,(const void*)a,(const void*)b) + +#else + +#define call_func1(func,_this) func(_this) +#define call_func2(func,_this,a) func(_this,a) +#define call_func3(func,_this,a,b) func(_this,a,b) + +#endif /* __i386__ */ + static BOOL init(void) { HMODULE msvcr = LoadLibraryA("msvcr90.dll"); @@ -74,6 +189,13 @@ static BOOL init(void) p_short_eq = (void*)GetProcAddress(msvcp, "?eq@?$char_traits@G@std@@SA_NAEBG0@Z"); p_Copy_s = (void*)GetProcAddress(msvcp, "?_Copy_s@?$char_traits@D@std@@SAPEADPEAD_KPEBD1@Z"); + + p_char_address = (void*)GetProcAddress(msvcp, "?address@?$allocator@D@std@@QEBAPEADAEAD@Z"); + p_char_ctor = (void*)GetProcAddress(msvcp, "??0?$allocator@D@std@@QEAA@XZ"); + p_char_deallocate = (void*)GetProcAddress(msvcp, "?deallocate@?$allocator@D@std@@QEAAXPEAD_K@Z"); + p_char_allocate = (void*)GetProcAddress(msvcp, "?allocate@?$allocator@D@std@@QEAAPEAD_K@Z"); + p_char_construct = (void*)GetProcAddress(msvcp, "?construct@?$allocator@D@std@@QEAAXPEADAEBD@Z"); + p_char_max_size = (void*)GetProcAddress(msvcp, "?max_size@?$allocator@D@std@@QEBA_KXZ"); } else { p_char_assign = (void*)GetProcAddress(msvcp, "?assign@?$char_traits@D@std@@SAXAADABD@Z"); p_wchar_assign = (void*)GetProcAddress(msvcp, "?assign@?$char_traits@_W@std@@SAXAA_WAB_W@Z"); @@ -84,6 +206,13 @@ static BOOL init(void) p_short_eq = (void*)GetProcAddress(msvcp, "?eq@?$char_traits@G@std@@SA_NABG0@Z"); p_Copy_s = (void*)GetProcAddress(msvcp, "?_Copy_s@?$char_traits@D@std@@SAPADPADIPBDI@Z"); + + p_char_address = (void*)GetProcAddress(msvcp, "?address@?$allocator@D@std@@QBEPADAAD@Z"); + p_char_ctor = (void*)GetProcAddress(msvcp, "??0?$allocator@D@std@@QAE@XZ"); + p_char_deallocate = (void*)GetProcAddress(msvcp, "?deallocate@?$allocator@D@std@@QAEXPADI@Z"); + p_char_allocate = (void*)GetProcAddress(msvcp, "?allocate@?$allocator@D@std@@QAEPADI@Z"); + p_char_construct = (void*)GetProcAddress(msvcp, "?construct@?$allocator@D@std@@QAEXPADABD@Z"); + p_char_max_size = (void*)GetProcAddress(msvcp, "?max_size@?$allocator@D@std@@QBEIXZ"); } return TRUE; @@ -199,6 +328,43 @@ static void test_Copy_s(void) ok(errno == 0xdeadbeef, "errno = %d\n", errno); } +static void test_allocator_char(void) +{ + void *allocator = (void*)0xdeadbeef; + char *ptr; + char val; + unsigned int size; + + if(!p_char_address || !p_char_ctor || !p_char_deallocate || !p_char_allocate + || !p_char_construct || !p_char_max_size) { + win_skip("allocator class not available\n"); + return; + } + + allocator = call_func1(p_char_ctor, allocator); + ok(allocator == (void*)0xdeadbeef, "allocator = %p\n", allocator); + + ptr = call_func2(p_char_address, NULL, (void*)0xdeadbeef); + ok(ptr == (void*)0xdeadbeef, "incorrect address (%p)\n", ptr); + + ptr = NULL; + ptr = call_func2(p_char_allocate, allocator, 10); + ok(ptr != NULL, "Memory allocation failed\n"); + + ptr[0] = ptr[1] = '#'; + val = 'a'; + call_func3(p_char_construct, allocator, ptr, &val); + val = 'b'; + call_func3(p_char_construct, allocator, (ptr+1), &val); + ok(ptr[0] == 'a', "ptr[0] = %c\n", ptr[0]); + ok(ptr[1] == 'b', "ptr[1] = %c\n", ptr[1]); + + call_func3(p_char_deallocate, allocator, ptr, -1); + + size = (unsigned int)call_func1(p_char_max_size, allocator); + ok(size == (unsigned int)0xffffffff, "size = %x\n", size); +} + START_TEST(misc) { if(!init()) @@ -208,5 +374,7 @@ START_TEST(misc) test_equal(); test_Copy_s(); + test_allocator_char(); + ok(!invalid_parameter, "invalid_parameter_handler was invoked too many times\n"); } -- 2.11.4.GIT