msvcrt: Add ExternalContextBase class stub.
Signed-off-by: Piotr Caban <piotr@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e70265feb6
commit
3dff8b8213
|
@ -33,7 +33,7 @@ typedef struct __type_info
|
|||
{
|
||||
const vtable_ptr *vtable;
|
||||
char *name; /* Unmangled name, allocated lazily */
|
||||
char mangled[32]; /* Variable length, but we declare it large enough for static RTTI */
|
||||
char mangled[64]; /* Variable length, but we declare it large enough for static RTTI */
|
||||
} type_info;
|
||||
|
||||
/* exception object */
|
||||
|
|
|
@ -259,3 +259,18 @@ typedef struct
|
|||
} rtti_object_locator;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
#define CALL_VTBL_FUNC(this, off, ret, type, args) ((ret (WINAPI*)type)&vtbl_wrapper_##off)args
|
||||
|
||||
extern void *vtbl_wrapper_0;
|
||||
extern void *vtbl_wrapper_4;
|
||||
extern void *vtbl_wrapper_8;
|
||||
extern void *vtbl_wrapper_20;
|
||||
|
||||
#else
|
||||
|
||||
#define CALL_VTBL_FUNC(this, off, ret, type, args) ((ret (__cdecl***)type)this)[0][off/4]args
|
||||
|
||||
#endif
|
||||
|
|
|
@ -115,6 +115,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|||
msvcrt_init_console();
|
||||
msvcrt_init_args();
|
||||
msvcrt_init_signals();
|
||||
#if _MSVCR_VER >= 100 && _MSVCR_VER <= 120
|
||||
msvcrt_init_scheduler(hinstDLL);
|
||||
#endif
|
||||
#if _MSVCR_VER == 0
|
||||
/* don't allow unloading msvcrt, we can't setup file handles twice */
|
||||
LdrAddRefDll( LDR_ADDREF_DLL_PIN, hinstDLL );
|
||||
|
@ -137,11 +140,18 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|||
if (!msvcrt_free_tls())
|
||||
return FALSE;
|
||||
MSVCRT__free_locale(MSVCRT_locale);
|
||||
#if _MSVCR_VER >= 100 && _MSVCR_VER <= 120
|
||||
msvcrt_free_scheduler_thread();
|
||||
msvcrt_free_scheduler();
|
||||
#endif
|
||||
msvcrt_destroy_heap();
|
||||
TRACE("finished process free\n");
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
msvcrt_free_tls_mem();
|
||||
#if _MSVCR_VER >= 100 && _MSVCR_VER <= 120
|
||||
msvcrt_free_scheduler_thread();
|
||||
#endif
|
||||
TRACE("finished thread free\n");
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -329,6 +329,12 @@ extern void msvcrt_free_popen_data(void) DECLSPEC_HIDDEN;
|
|||
extern BOOL msvcrt_init_heap(void) DECLSPEC_HIDDEN;
|
||||
extern void msvcrt_destroy_heap(void) DECLSPEC_HIDDEN;
|
||||
|
||||
#if _MSVCR_VER >= 100
|
||||
extern void msvcrt_init_scheduler(void*) DECLSPEC_HIDDEN;
|
||||
extern void msvcrt_free_scheduler(void) DECLSPEC_HIDDEN;
|
||||
extern void msvcrt_free_scheduler_thread(void) DECLSPEC_HIDDEN;
|
||||
#endif
|
||||
|
||||
extern unsigned msvcrt_create_io_inherit_block(WORD*, BYTE**) DECLSPEC_HIDDEN;
|
||||
|
||||
extern unsigned int __cdecl _control87(unsigned int, unsigned int);
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
|
@ -31,23 +33,89 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
|
||||
|
||||
#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(20);
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
const vtable_ptr *vtable;
|
||||
} Context;
|
||||
#define call_Context_GetId(this) CALL_VTBL_FUNC(this, 0, \
|
||||
unsigned int, (const Context*), (this))
|
||||
#define call_Context_GetVirtualProcessorId(this) CALL_VTBL_FUNC(this, 4, \
|
||||
unsigned int, (const Context*), (this))
|
||||
#define call_Context_GetScheduleGroupId(this) CALL_VTBL_FUNC(this, 8, \
|
||||
unsigned int, (const Context*), (this))
|
||||
#define call_Context_dtor(this, flags) CALL_VTBL_FUNC(this, 20, \
|
||||
Context*, (Context*, unsigned int), (this, flags))
|
||||
|
||||
typedef struct {
|
||||
Context context;
|
||||
} ExternalContextBase;
|
||||
extern const vtable_ptr MSVCRT_ExternalContextBase_vtable;
|
||||
static void ExternalContextBase_ctor(ExternalContextBase*);
|
||||
|
||||
static int context_tls_index = TLS_OUT_OF_INDEXES;
|
||||
|
||||
static Context* try_get_current_context(void)
|
||||
{
|
||||
if (context_tls_index == TLS_OUT_OF_INDEXES)
|
||||
return NULL;
|
||||
return TlsGetValue(context_tls_index);
|
||||
}
|
||||
|
||||
static Context* get_current_context(void)
|
||||
{
|
||||
Context *ret;
|
||||
|
||||
if (context_tls_index == TLS_OUT_OF_INDEXES) {
|
||||
int tls_index = TlsAlloc();
|
||||
if (tls_index == TLS_OUT_OF_INDEXES) {
|
||||
/* throw scheduler_resource_allocation_error */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(InterlockedCompareExchange(&context_tls_index, tls_index, TLS_OUT_OF_INDEXES) != TLS_OUT_OF_INDEXES)
|
||||
TlsFree(tls_index);
|
||||
}
|
||||
|
||||
ret = TlsGetValue(context_tls_index);
|
||||
if (!ret) {
|
||||
ExternalContextBase *context = MSVCRT_operator_new(sizeof(ExternalContextBase));
|
||||
ExternalContextBase_ctor(context);
|
||||
TlsSetValue(context_tls_index, context);
|
||||
ret = &context->context;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ?CurrentContext@Context@Concurrency@@SAPAV12@XZ */
|
||||
/* ?CurrentContext@Context@Concurrency@@SAPEAV12@XZ */
|
||||
Context* __cdecl Context_CurrentContext(void)
|
||||
{
|
||||
FIXME("()\n");
|
||||
return NULL;
|
||||
TRACE("()\n");
|
||||
return get_current_context();
|
||||
}
|
||||
|
||||
/* ?Id@Context@Concurrency@@SAIXZ */
|
||||
unsigned int __cdecl Context_Id(void)
|
||||
{
|
||||
FIXME("()\n");
|
||||
return -1;
|
||||
Context *ctx = try_get_current_context();
|
||||
TRACE("()\n");
|
||||
return ctx ? call_Context_GetId(ctx) : -1;
|
||||
}
|
||||
|
||||
/* ?Block@Context@Concurrency@@SAXXZ */
|
||||
|
@ -84,15 +152,122 @@ void __cdecl Context_Oversubscribe(MSVCRT_bool begin)
|
|||
/* ?ScheduleGroupId@Context@Concurrency@@SAIXZ */
|
||||
unsigned int __cdecl Context_ScheduleGroupId(void)
|
||||
{
|
||||
FIXME("()\n");
|
||||
return -1;
|
||||
Context *ctx = try_get_current_context();
|
||||
TRACE("()\n");
|
||||
return ctx ? call_Context_GetScheduleGroupId(ctx) : -1;
|
||||
}
|
||||
|
||||
/* ?VirtualProcessorId@Context@Concurrency@@SAIXZ */
|
||||
unsigned int __cdecl Context_VirtualProcessorId(void)
|
||||
{
|
||||
Context *ctx = try_get_current_context();
|
||||
FIXME("()\n");
|
||||
return ctx ? call_Context_GetVirtualProcessorId(ctx) : -1;
|
||||
}
|
||||
|
||||
DEFINE_THISCALL_WRAPPER(ExternalContextBase_GetId, 4)
|
||||
unsigned int __thiscall ExternalContextBase_GetId(const ExternalContextBase *this)
|
||||
{
|
||||
FIXME("(%p)->() stub\n", this);
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEFINE_THISCALL_WRAPPER(ExternalContextBase_GetVirtualProcessorId, 4)
|
||||
unsigned int __thiscall ExternalContextBase_GetVirtualProcessorId(const ExternalContextBase *this)
|
||||
{
|
||||
FIXME("(%p)->() stub\n", this);
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEFINE_THISCALL_WRAPPER(ExternalContextBase_GetScheduleGroupId, 4)
|
||||
unsigned int __thiscall ExternalContextBase_GetScheduleGroupId(const ExternalContextBase *this)
|
||||
{
|
||||
FIXME("(%p)->() stub\n", this);
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEFINE_THISCALL_WRAPPER(ExternalContextBase_Unblock, 4)
|
||||
void __thiscall ExternalContextBase_Unblock(ExternalContextBase *this)
|
||||
{
|
||||
FIXME("(%p)->() stub\n", this);
|
||||
}
|
||||
|
||||
DEFINE_THISCALL_WRAPPER(ExternalContextBase_IsSynchronouslyBlocked, 4)
|
||||
MSVCRT_bool __thiscall ExternalContextBase_IsSynchronouslyBlocked(const ExternalContextBase *this)
|
||||
{
|
||||
FIXME("(%p)->() stub\n", this);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void ExternalContextBase_dtor(ExternalContextBase *this)
|
||||
{
|
||||
}
|
||||
|
||||
DEFINE_THISCALL_WRAPPER(ExternalContextBase_vector_dtor, 8)
|
||||
Context* __thiscall ExternalContextBase_vector_dtor(ExternalContextBase *this, unsigned int flags)
|
||||
{
|
||||
TRACE("(%p %x)\n", this, flags);
|
||||
if(flags & 2) {
|
||||
/* we have an array, with the number of elements stored before the first object */
|
||||
INT_PTR i, *ptr = (INT_PTR *)this-1;
|
||||
|
||||
for(i=*ptr-1; i>=0; i--)
|
||||
ExternalContextBase_dtor(this+i);
|
||||
MSVCRT_operator_delete(ptr);
|
||||
} else {
|
||||
ExternalContextBase_dtor(this);
|
||||
if(flags & 1)
|
||||
MSVCRT_operator_delete(this);
|
||||
}
|
||||
|
||||
return &this->context;
|
||||
}
|
||||
|
||||
static void ExternalContextBase_ctor(ExternalContextBase *this)
|
||||
{
|
||||
this->context.vtable = &MSVCRT_ExternalContextBase_vtable;
|
||||
}
|
||||
|
||||
extern const vtable_ptr MSVCRT_type_info_vtable;
|
||||
DEFINE_RTTI_DATA0(Context, 0, ".?AVContext@Concurrency@@")
|
||||
DEFINE_RTTI_DATA1(ContextBase, 0, &Context_rtti_base_descriptor, ".?AVContextBase@details@Concurrency@@")
|
||||
DEFINE_RTTI_DATA2(ExternalContextBase, 0, &ContextBase_rtti_base_descriptor,
|
||||
&Context_rtti_base_descriptor, ".?AVExternalContextBase@details@Concurrency@@")
|
||||
|
||||
#ifndef __GNUC__
|
||||
void __asm_dummy_vtables(void) {
|
||||
#endif
|
||||
__ASM_VTABLE(ExternalContextBase,
|
||||
VTABLE_ADD_FUNC(ExternalContextBase_GetId)
|
||||
VTABLE_ADD_FUNC(ExternalContextBase_GetVirtualProcessorId)
|
||||
VTABLE_ADD_FUNC(ExternalContextBase_GetScheduleGroupId)
|
||||
VTABLE_ADD_FUNC(ExternalContextBase_Unblock)
|
||||
VTABLE_ADD_FUNC(ExternalContextBase_IsSynchronouslyBlocked)
|
||||
VTABLE_ADD_FUNC(ExternalContextBase_vector_dtor));
|
||||
#ifndef __GNUC__
|
||||
}
|
||||
#endif
|
||||
|
||||
void msvcrt_init_scheduler(void *base)
|
||||
{
|
||||
#ifdef __x86_64__
|
||||
init_Context_rtti(base);
|
||||
init_ContextBase_rtti(base);
|
||||
init_ExternalContextBase_rtti(base);
|
||||
#endif
|
||||
}
|
||||
|
||||
void msvcrt_free_scheduler(void)
|
||||
{
|
||||
if (context_tls_index != TLS_OUT_OF_INDEXES)
|
||||
TlsFree(context_tls_index);
|
||||
}
|
||||
|
||||
void msvcrt_free_scheduler_thread(void)
|
||||
{
|
||||
Context *context = try_get_current_context();
|
||||
if (!context) return;
|
||||
call_Context_dtor(context, 1);
|
||||
}
|
||||
|
||||
#endif /* _MSVCR_VER >= 100 */
|
||||
|
|
Loading…
Reference in New Issue