📄 cpp.c
字号:
/*
* msvcrt.dll C++ objects
*
* Copyright 2000 Jon Griffiths
* Copyright 2003 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "wine/config.h"
#include "wine/port.h"
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winternl.h"
#include "wine/exception.h"
#include "winnt.h"
#include "excpt.h"
#include "wine/debug.h"
#include <malloc.h>
#include <stdlib.h>
#include <internal/wine/msvcrt.h>
#include <internal/wine/cppexcept.h>
#include <internal/mtdll.h>
WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
/*
* exception object: base for exception, bad_cast, bad_typeid, __non_rtti_object
*/
typedef struct
{
void* pfn_vector_dtor;
void* pfn_what;
} exception_vtable;
typedef struct __exception
{
const exception_vtable *vtable;
char *name; /* Name of this exception, always a new copy for each object */
int do_free; /* Whether to free 'name' in our dtor */
} exception;
typedef exception bad_cast;
typedef exception bad_typeid;
typedef exception __non_rtti_object;
typedef struct _rtti_base_descriptor
{
type_info *type_descriptor;
int num_base_classes;
int base_class_offset;
unsigned int flags;
int unknown1;
int unknown2;
} rtti_base_descriptor;
typedef struct _rtti_base_array
{
const rtti_base_descriptor *bases[3]; /* First element is the class itself */
} rtti_base_array;
typedef struct _rtti_object_hierachy
{
int unknown1;
int unknown2;
int array_len; /* Size of the array pointed to by 'base_classes' */
const rtti_base_array *base_classes;
} rtti_object_hierachy;
typedef struct _rtti_object_locator
{
int unknown1;
int base_class_offset;
unsigned int flags;
type_info *type_descriptor;
const rtti_object_hierachy *type_hierachy;
} rtti_object_locator;
#ifdef __i386__ /* thiscall functions are i386-specific */
#define DEFINE_THISCALL_WRAPPER0(func) \
extern void __thiscall_ ## func(); \
__ASM_GLOBAL_FUNC(__thiscall_ ## func, \
"popl %eax\n\t" \
"pushl %ecx\n\t" \
"pushl %eax\n\t" \
"jmp " __ASM_NAME(#func) "@4" )
#define DEFINE_THISCALL_WRAPPER1(func) \
extern void __thiscall_ ## func(); \
__ASM_GLOBAL_FUNC(__thiscall_ ## func, \
"popl %eax\n\t" \
"pushl %ecx\n\t" \
"pushl %eax\n\t" \
"jmp " __ASM_NAME(#func) "@8" )
const exception_vtable MSVCRT_exception_vtable;
const exception_vtable MSVCRT_bad_typeid_vtable;
const exception_vtable MSVCRT_bad_cast_vtable;
const exception_vtable MSVCRT___non_rtti_object_vtable;
static const exception_vtable MSVCRT_type_info_vtable;
/* Internal common ctor for exception */
static void WINAPI EXCEPTION_ctor(exception *_this, const char** name)
{
_this->vtable = &MSVCRT_exception_vtable;
if (*name)
{
size_t name_len = strlen(*name) + 1;
_this->name = MSVCRT_malloc(name_len);
memcpy(_this->name, *name, name_len);
_this->do_free = TRUE;
}
else
{
_this->name = NULL;
_this->do_free = FALSE;
}
}
/******************************************************************
* ??0exception@@QAE@ABQBD@Z (MSVCRT.@)
*/
DEFINE_THISCALL_WRAPPER1(MSVCRT_exception_ctor);
exception * __stdcall MSVCRT_exception_ctor(exception * _this, const char ** name)
{
TRACE("(%p,%s)\n", _this, *name);
EXCEPTION_ctor(_this, name);
return _this;
}
/******************************************************************
* ??0exception@@QAE@ABV0@@Z (MSVCRT.@)
*/
DEFINE_THISCALL_WRAPPER1(MSVCRT_exception_copy_ctor);
exception * __stdcall MSVCRT_exception_copy_ctor(exception * _this, const exception * rhs)
{
TRACE("(%p,%p)\n", _this, rhs);
if (!rhs->do_free)
{
_this->vtable = &MSVCRT_exception_vtable;
_this->name = rhs->name;
_this->do_free = FALSE;
}
else
EXCEPTION_ctor(_this, (const char**)&rhs->name);
TRACE("name = %s\n", _this->name);
return _this;
}
/******************************************************************
* ??0exception@@QAE@XZ (MSVCRT.@)
*/
DEFINE_THISCALL_WRAPPER0(MSVCRT_exception_default_ctor);
exception * __stdcall MSVCRT_exception_default_ctor(exception * _this)
{
static const char* empty = NULL;
TRACE("(%p)\n", _this);
EXCEPTION_ctor(_this, &empty);
return _this;
}
/******************************************************************
* ??1exception@@UAE@XZ (MSVCRT.@)
*/
DEFINE_THISCALL_WRAPPER0(MSVCRT_exception_dtor);
void __stdcall MSVCRT_exception_dtor(exception * _this)
{
TRACE("(%p)\n", _this);
_this->vtable = &MSVCRT_exception_vtable;
if (_this->do_free) MSVCRT_free(_this->name);
}
/******************************************************************
* ??4exception@@QAEAAV0@ABV0@@Z (MSVCRT.@)
*/
DEFINE_THISCALL_WRAPPER1(MSVCRT_exception_opequals);
exception * __stdcall MSVCRT_exception_opequals(exception * _this, const exception * rhs)
{
TRACE("(%p %p)\n", _this, rhs);
if (_this != rhs)
{
MSVCRT_exception_dtor(_this);
MSVCRT_exception_copy_ctor(_this, rhs);
}
TRACE("name = %s\n", _this->name);
return _this;
}
/******************************************************************
* ??_Eexception@@UAEPAXI@Z (MSVCRT.@)
*/
DEFINE_THISCALL_WRAPPER1(MSVCRT_exception_vector_dtor);
void * __stdcall MSVCRT_exception_vector_dtor(exception * _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 i, *ptr = (int *)_this - 1;
for (i = *ptr - 1; i >= 0; i--) MSVCRT_exception_dtor(_this + i);
MSVCRT_operator_delete(ptr);
}
else
{
MSVCRT_exception_dtor(_this);
if (flags & 1) MSVCRT_operator_delete(_this);
}
return _this;
}
/******************************************************************
* ??_Gexception@@UAEPAXI@Z (MSVCRT.@)
*/
DEFINE_THISCALL_WRAPPER1(MSVCRT_exception_scalar_dtor);
void * __stdcall MSVCRT_exception_scalar_dtor(exception * _this, unsigned int flags)
{
TRACE("(%p %x)\n", _this, flags);
MSVCRT_exception_dtor(_this);
if (flags & 1) MSVCRT_operator_delete(_this);
return _this;
}
/******************************************************************
* ?what@exception@@UBEPBDXZ (MSVCRT.@)
*/
DEFINE_THISCALL_WRAPPER0(MSVCRT_what_exception);
const char * __stdcall MSVCRT_what_exception(exception * _this)
{
TRACE("(%p) returning %s\n", _this, _this->name);
return _this->name ? _this->name : "Unknown exception";
}
/******************************************************************
* ??0bad_typeid@@QAE@ABV0@@Z (MSVCRT.@)
*/
DEFINE_THISCALL_WRAPPER1(MSVCRT_bad_typeid_copy_ctor);
bad_typeid * __stdcall MSVCRT_bad_typeid_copy_ctor(bad_typeid * _this, const bad_typeid * rhs)
{
TRACE("(%p %p)\n", _this, rhs);
MSVCRT_exception_copy_ctor(_this, rhs);
_this->vtable = &MSVCRT_bad_typeid_vtable;
return _this;
}
/******************************************************************
* ??0bad_typeid@@QAE@PBD@Z (MSVCRT.@)
*/
DEFINE_THISCALL_WRAPPER1(MSVCRT_bad_typeid_ctor);
bad_typeid * __stdcall MSVCRT_bad_typeid_ctor(bad_typeid * _this, const char * name)
{
TRACE("(%p %s)\n", _this, name);
EXCEPTION_ctor(_this, &name);
_this->vtable = &MSVCRT_bad_typeid_vtable;
return _this;
}
/******************************************************************
* ??1bad_typeid@@UAE@XZ (MSVCRT.@)
*/
DEFINE_THISCALL_WRAPPER0(MSVCRT_bad_typeid_dtor);
void __stdcall MSVCRT_bad_typeid_dtor(bad_typeid * _this)
{
TRACE("(%p)\n", _this);
MSVCRT_exception_dtor(_this);
}
/******************************************************************
* ??4bad_typeid@@QAEAAV0@ABV0@@Z (MSVCRT.@)
*/
DEFINE_THISCALL_WRAPPER1(MSVCRT_bad_typeid_opequals);
bad_typeid * __stdcall MSVCRT_bad_typeid_opequals(bad_typeid * _this, const bad_typeid * rhs)
{
TRACE("(%p %p)\n", _this, rhs);
MSVCRT_exception_opequals(_this, rhs);
return _this;
}
/******************************************************************
* ??_Ebad_typeid@@UAEPAXI@Z (MSVCRT.@)
*/
DEFINE_THISCALL_WRAPPER1(MSVCRT_bad_typeid_vector_dtor);
void * __stdcall MSVCRT_bad_typeid_vector_dtor(bad_typeid * _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 i, *ptr = (int *)_this - 1;
for (i = *ptr - 1; i >= 0; i--) MSVCRT_bad_typeid_dtor(_this + i);
MSVCRT_operator_delete(ptr);
}
else
{
MSVCRT_bad_typeid_dtor(_this);
if (flags & 1) MSVCRT_operator_delete(_this);
}
return _this;
}
/******************************************************************
* ??_Gbad_typeid@@UAEPAXI@Z (MSVCRT.@)
*/
DEFINE_THISCALL_WRAPPER1(MSVCRT_bad_typeid_scalar_dtor);
void * __stdcall MSVCRT_bad_typeid_scalar_dtor(bad_typeid * _this, unsigned int flags)
{
TRACE("(%p %x)\n", _this, flags);
MSVCRT_bad_typeid_dtor(_this);
if (flags & 1) MSVCRT_operator_delete(_this);
return _this;
}
/******************************************************************
* ??0__non_rtti_object@@QAE@ABV0@@Z (MSVCRT.@)
*/
DEFINE_THISCALL_WRAPPER1(MSVCRT___non_rtti_object_copy_ctor);
__non_rtti_object * __stdcall MSVCRT___non_rtti_object_copy_ctor(__non_rtti_object * _this,
const __non_rtti_object * rhs)
{
TRACE("(%p %p)\n", _this, rhs);
MSVCRT_bad_typeid_copy_ctor(_this, rhs);
_this->vtable = &MSVCRT___non_rtti_object_vtable;
return _this;
}
/******************************************************************
* ??0__non_rtti_object@@QAE@PBD@Z (MSVCRT.@)
*/
DEFINE_THISCALL_WRAPPER1(MSVCRT___non_rtti_object_ctor);
__non_rtti_object * __stdcall MSVCRT___non_rtti_object_ctor(__non_rtti_object * _this,
const char * name)
{
TRACE("(%p %s)\n", _this, name);
EXCEPTION_ctor(_this, &name);
_this->vtable = &MSVCRT___non_rtti_object_vtable;
return _this;
}
/******************************************************************
* ??1__non_rtti_object@@UAE@XZ (MSVCRT.@)
*/
DEFINE_THISCALL_WRAPPER0(MSVCRT___non_rtti_object_dtor);
void __stdcall MSVCRT___non_rtti_object_dtor(__non_rtti_object * _this)
{
TRACE("(%p)\n", _this);
MSVCRT_bad_typeid_dtor(_this);
}
/******************************************************************
* ??4__non_rtti_object@@QAEAAV0@ABV0@@Z (MSVCRT.@)
*/
DEFINE_THISCALL_WRAPPER1(MSVCRT___non_rtti_object_opequals);
__non_rtti_object * __stdcall MSVCRT___non_rtti_object_opequals(__non_rtti_object * _this,
const __non_rtti_object *rhs)
{
TRACE("(%p %p)\n", _this, rhs);
MSVCRT_bad_typeid_opequals(_this, rhs);
return _this;
}
/******************************************************************
* ??_E__non_rtti_object@@UAEPAXI@Z (MSVCRT.@)
*/
DEFINE_THISCALL_WRAPPER1(MSVCRT___non_rtti_object_vector_dtor);
void * __stdcall MSVCRT___non_rtti_object_vector_dtor(__non_rtti_object * _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 i, *ptr = (int *)_this - 1;
for (i = *ptr - 1; i >= 0; i--) MSVCRT___non_rtti_object_dtor(_this + i);
MSVCRT_operator_delete(ptr);
}
else
{
MSVCRT___non_rtti_object_dtor(_this);
if (flags & 1) MSVCRT_operator_delete(_this);
}
return _this;
}
/******************************************************************
* ??_G__non_rtti_object@@UAEPAXI@Z (MSVCRT.@)
*/
DEFINE_THISCALL_WRAPPER1(MSVCRT___non_rtti_object_scalar_dtor);
void * __stdcall MSVCRT___non_rtti_object_scalar_dtor(__non_rtti_object * _this, unsigned int flags)
{
TRACE("(%p %x)\n", _this, flags);
MSVCRT___non_rtti_object_dtor(_this);
if (flags & 1) MSVCRT_operator_delete(_this);
return _this;
}
/******************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -