[1/4] msvcirt: Add implementation of streambuf::allocate (try 2, resend)
Iván Matellanes
matellanesivan at gmail.com
Mon Jun 8 08:56:37 CDT 2015
Resending the whole series, I didn't send properly last time
---
dlls/msvcirt/msvcirt.c | 57 ++++++++++++++++++++++++++++++++++++++++++--
dlls/msvcirt/msvcirt.h | 1 +
dlls/msvcirt/msvcirt.spec | 4 ++--
dlls/msvcirt/tests/msvcirt.c | 23 +++++++++++++++++-
dlls/msvcrt20/msvcrt20.spec | 4 ++--
dlls/msvcrt40/msvcrt40.spec | 4 ++--
6 files changed, 84 insertions(+), 9 deletions(-)
diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c
index e0781b9..507ed11 100644
--- a/dlls/msvcirt/msvcirt.c
+++ b/dlls/msvcirt/msvcirt.c
@@ -29,6 +29,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(msvcirt);
+#define RESERVE_SIZE 512
+
/* class streambuf */
typedef struct {
const vtable_ptr *vtable;
@@ -47,6 +49,7 @@ typedef struct {
CRITICAL_SECTION lock;
} streambuf;
+void __thiscall streambuf_setb(streambuf*, char*, char*, int);
streambuf* __thiscall streambuf_setbuf(streambuf*, char*, int);
void __thiscall streambuf_setg(streambuf*, char*, char*, char*);
void __thiscall streambuf_setp(streambuf*, char*, char*);
@@ -179,10 +182,29 @@ streambuf* __thiscall streambuf_scalar_dtor(streambuf *this, unsigned int flags)
/* ?doallocate at streambuf@@MAEHXZ */
/* ?doallocate at streambuf@@MEAAHXZ */
DEFINE_THISCALL_WRAPPER(streambuf_doallocate, 4)
+#define call_streambuf_doallocate(this) CALL_VTBL_FUNC(this, 40, int, (streambuf*), (this))
int __thiscall streambuf_doallocate(streambuf *this)
{
- FIXME("(%p): stub\n", this);
- return EOF;
+ char *reserve;
+
+ TRACE("(%p)\n", this);
+ reserve = MSVCRT_operator_new(RESERVE_SIZE);
+ if (!reserve)
+ return EOF;
+
+ streambuf_setb(this, reserve, reserve + RESERVE_SIZE, 1);
+ return 1;
+}
+
+/* ?allocate at streambuf@@IAEHXZ */
+/* ?allocate at streambuf@@IEAAHXZ */
+DEFINE_THISCALL_WRAPPER(streambuf_allocate, 4)
+int __thiscall streambuf_allocate(streambuf *this)
+{
+ TRACE("(%p)\n", this);
+ if (this->base != NULL || this->unbuffered)
+ return 0;
+ return call_streambuf_doallocate(this);
}
/* Unexported */
@@ -404,6 +426,35 @@ char * __thiscall MSVCIRT_str_sl_void(class_strstreambuf * _this)
return 0;
}
+#ifdef __i386__
+
+#define DEFINE_VTBL_WRAPPER(off) \
+ __ASM_GLOBAL_FUNC(vtbl_wrapper_ ## off, \
+ "popl %eax\n\t" \
+ "popl %ecx\n\t" \
+ "pushl %eax\n\t" \
+ "movl 0(%ecx), %eax\n\t" \
+ "jmp *" #off "(%eax)\n\t")
+
+DEFINE_VTBL_WRAPPER(0);
+DEFINE_VTBL_WRAPPER(4);
+DEFINE_VTBL_WRAPPER(8);
+DEFINE_VTBL_WRAPPER(12);
+DEFINE_VTBL_WRAPPER(16);
+DEFINE_VTBL_WRAPPER(20);
+DEFINE_VTBL_WRAPPER(24);
+DEFINE_VTBL_WRAPPER(28);
+DEFINE_VTBL_WRAPPER(32);
+DEFINE_VTBL_WRAPPER(36);
+DEFINE_VTBL_WRAPPER(40);
+DEFINE_VTBL_WRAPPER(44);
+DEFINE_VTBL_WRAPPER(48);
+DEFINE_VTBL_WRAPPER(52);
+DEFINE_VTBL_WRAPPER(56);
+
+#endif
+
+void* (__cdecl *MSVCRT_operator_new)(SIZE_T);
void (__cdecl *MSVCRT_operator_delete)(void*);
static void init_cxx_funcs(void)
@@ -412,10 +463,12 @@ static void init_cxx_funcs(void)
if (sizeof(void *) > sizeof(int)) /* 64-bit has different names */
{
+ MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2 at YAPEAX_K@Z");
MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3 at YAXPEAX@Z");
}
else
{
+ MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2 at YAPAXI@Z");
MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3 at YAXPAX@Z");
}
}
diff --git a/dlls/msvcirt/msvcirt.h b/dlls/msvcirt/msvcirt.h
index bdcd7d8..5cf15de 100644
--- a/dlls/msvcirt/msvcirt.h
+++ b/dlls/msvcirt/msvcirt.h
@@ -23,6 +23,7 @@
typedef LONG streamoff;
typedef LONG streampos;
+extern void* (__cdecl *MSVCRT_operator_new)(SIZE_T);
extern void (__cdecl *MSVCRT_operator_delete)(void*);
void init_exception(void*);
diff --git a/dlls/msvcirt/msvcirt.spec b/dlls/msvcirt/msvcirt.spec
index dfb2734..f987dfd 100644
--- a/dlls/msvcirt/msvcirt.spec
+++ b/dlls/msvcirt/msvcirt.spec
@@ -400,8 +400,8 @@
@ stub -arch=win32 ??_Gstrstream@@UAEPAXI at Z # virtual void * __thiscall strstream::`scalar deleting destructor'(unsigned int)
@ stub -arch=win32 ??_Gstrstreambuf@@UAEPAXI at Z # virtual void * __thiscall strstreambuf::`scalar deleting destructor'(unsigned int)
# @ extern ?adjustfield at ios@@2JB # static long const ios::adjustfield
-@ stub -arch=win32 ?allocate at streambuf@@IAEHXZ # int __thiscall streambuf::allocate(void)
-@ stub -arch=win64 ?allocate at streambuf@@IEAAHXZ
+@ thiscall -arch=win32 ?allocate at streambuf@@IAEHXZ(ptr) streambuf_allocate
+@ cdecl -arch=win64 ?allocate at streambuf@@IEAAHXZ(ptr) streambuf_allocate
@ stub -arch=win32 ?attach at filebuf@@QAEPAV1 at H@Z # class filebuf * __thiscall filebuf::attach(int)
@ stub -arch=win64 ?attach at filebuf@@QEAAPEAV1 at H@Z
@ stub -arch=win32 ?attach at fstream@@QAEXH at Z # void __thiscall fstream::attach(int)
diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c
index 311fd97..8bf194f 100644
--- a/dlls/msvcirt/tests/msvcirt.c
+++ b/dlls/msvcirt/tests/msvcirt.c
@@ -52,6 +52,8 @@ typedef struct {
static streambuf* (*__thiscall p_streambuf_reserve_ctor)(streambuf*, char*, int);
static streambuf* (*__thiscall p_streambuf_ctor)(streambuf*);
static void (*__thiscall p_streambuf_dtor)(streambuf*);
+static int (*__thiscall p_streambuf_allocate)(streambuf*);
+static int (*__thiscall p_streambuf_doallocate)(streambuf*);
static void (*__thiscall p_streambuf_setb)(streambuf*, char*, char*, int);
static streambuf* (*__thiscall p_streambuf_setbuf)(streambuf*, char*, int);
@@ -127,12 +129,16 @@ static BOOL init(void)
SET(p_streambuf_reserve_ctor, "??0streambuf@@IEAA at PEADH@Z");
SET(p_streambuf_ctor, "??0streambuf@@IEAA at XZ");
SET(p_streambuf_dtor, "??1streambuf@@UEAA at XZ");
+ SET(p_streambuf_allocate, "?allocate at streambuf@@IEAAHXZ");
+ SET(p_streambuf_doallocate, "?doallocate at streambuf@@MEAAHXZ");
SET(p_streambuf_setb, "?setb at streambuf@@IEAAXPEAD0H at Z");
SET(p_streambuf_setbuf, "?setbuf at streambuf@@UEAAPEAV1 at PEADH@Z");
} else {
SET(p_streambuf_reserve_ctor, "??0streambuf@@IAE at PADH@Z");
SET(p_streambuf_ctor, "??0streambuf@@IAE at XZ");
SET(p_streambuf_dtor, "??1streambuf@@UAE at XZ");
+ SET(p_streambuf_allocate, "?allocate at streambuf@@IAEHXZ");
+ SET(p_streambuf_doallocate, "?doallocate at streambuf@@MAEHXZ");
SET(p_streambuf_setb, "?setb at streambuf@@IAEXPAD0H at Z");
SET(p_streambuf_setbuf, "?setbuf at streambuf@@UAEPAV1 at PADH@Z");
}
@@ -145,6 +151,7 @@ static void test_streambuf(void)
{
streambuf sb, sb2, *psb;
char reserve[16];
+ int ret;
memset(&sb, 0xab, sizeof(streambuf));
memset(&sb2, 0xab, sizeof(streambuf));
@@ -197,7 +204,21 @@ static void test_streambuf(void)
ok(sb.base == reserve, "wrong base pointer, expected %p got %p\n", reserve, sb.base);
ok(sb.ebuf == reserve+16, "wrong ebuf pointer, expected %p got %p\n", reserve+16, sb.ebuf);
- sb.allocated = 0;
+ /* allocate */
+ ret = (int) call_func1(p_streambuf_allocate, &sb);
+ ok(ret == 0, "wrong return value, expected 0 got %d\n", ret);
+ sb.base = NULL;
+ ret = (int) call_func1(p_streambuf_allocate, &sb);
+ ok(ret == 1, "wrong return value, expected 1 got %d\n", ret);
+ ok(sb.allocated == 1, "wrong allocate value, expected 1 got %d\n", sb.allocated);
+ ok(sb.ebuf - sb.base == 512 , "wrong reserve area size, expected 512 got %d\n", sb.ebuf - sb.base);
+
+ /* doallocate */
+ ret = (int) call_func1(p_streambuf_doallocate, &sb2);
+ ok(ret == 1, "doallocate failed, got %d\n", ret);
+ ok(sb2.allocated == 1, "wrong allocate value, expected 1 got %d\n", sb2.allocated);
+ ok(sb2.ebuf - sb2.base == 512 , "wrong reserve area size, expected 512 got %d\n", sb2.ebuf - sb2.base);
+
call_func1(p_streambuf_dtor, &sb);
call_func1(p_streambuf_dtor, &sb2);
}
diff --git a/dlls/msvcrt20/msvcrt20.spec b/dlls/msvcrt20/msvcrt20.spec
index 3cefd74..195cdf1 100644
--- a/dlls/msvcrt20/msvcrt20.spec
+++ b/dlls/msvcrt20/msvcrt20.spec
@@ -388,8 +388,8 @@
@ cdecl -arch=win32 ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0 at Z@Z(ptr) msvcrt.?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0 at Z@Z
@ cdecl -arch=win64 ?_set_se_translator@@YAP6AXIPEAU_EXCEPTION_POINTERS@@@ZP6AXI0 at Z@Z(ptr) msvcrt.?_set_se_translator@@YAP6AXIPEAU_EXCEPTION_POINTERS@@@ZP6AXI0 at Z@Z
# @ extern ?adjustfield at ios@@2JB
-@ stub -arch=win32 ?allocate at streambuf@@IAEHXZ
-@ stub -arch=win64 ?allocate at streambuf@@IEAAHXZ
+@ thiscall -arch=win32 ?allocate at streambuf@@IAEHXZ(ptr) msvcirt.?allocate at streambuf@@IAEHXZ
+@ cdecl -arch=win64 ?allocate at streambuf@@IEAAHXZ(ptr) msvcirt.?allocate at streambuf@@IEAAHXZ
@ stub -arch=win32 ?attach at filebuf@@QAEPAV1 at H@Z
@ stub -arch=win64 ?attach at filebuf@@QEAAPEAV1 at H@Z
@ stub -arch=win32 ?attach at fstream@@QAEXH at Z
diff --git a/dlls/msvcrt40/msvcrt40.spec b/dlls/msvcrt40/msvcrt40.spec
index 705521a..0042f17 100644
--- a/dlls/msvcrt40/msvcrt40.spec
+++ b/dlls/msvcrt40/msvcrt40.spec
@@ -451,8 +451,8 @@
@ cdecl -arch=win32 ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0 at Z@Z(ptr) msvcrt.?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0 at Z@Z
@ cdecl -arch=win64 ?_set_se_translator@@YAP6AXIPEAU_EXCEPTION_POINTERS@@@ZP6AXI0 at Z@Z(ptr) msvcrt.?_set_se_translator@@YAP6AXIPEAU_EXCEPTION_POINTERS@@@ZP6AXI0 at Z@Z
# @ extern ?adjustfield at ios@@2JB
-@ stub -arch=win32 ?allocate at streambuf@@IAEHXZ
-@ stub -arch=win64 ?allocate at streambuf@@IEAAHXZ
+@ thiscall -arch=win32 ?allocate at streambuf@@IAEHXZ(ptr) msvcirt.?allocate at streambuf@@IAEHXZ
+@ cdecl -arch=win64 ?allocate at streambuf@@IEAAHXZ(ptr) msvcirt.?allocate at streambuf@@IEAAHXZ
@ stub -arch=win32 ?attach at filebuf@@QAEPAV1 at H@Z
@ stub -arch=win64 ?attach at filebuf@@QEAAPEAV1 at H@Z
@ stub -arch=win32 ?attach at fstream@@QAEXH at Z
--
2.1.4
More information about the wine-patches
mailing list