Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
743b61e6
Commit
743b61e6
authored
Aug 19, 2003
by
Jon Griffiths
Committed by
Alexandre Julliard
Aug 19, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use exception as the base for all exception derived classes.
Implement type_info methods correctly. Add static RTTI for exported objects. Throw exceptions when run time casts fail.
parent
5ac945c0
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
661 additions
and
143 deletions
+661
-143
cpp.c
dlls/msvcrt/cpp.c
+661
-143
No files found.
dlls/msvcrt/cpp.c
View file @
743b61e6
...
...
@@ -22,45 +22,38 @@
#include "config.h"
#include "wine/port.h"
#include "msvcrt.h"
#include "msvcrt/eh.h"
#include "winternl.h"
#include "wine/exception.h"
#include "excpt.h"
#include "wine/debug.h"
#include "msvcrt/malloc.h"
#include "msvcrt/stdlib.h"
#include "wine/debug.h"
#include "msvcrt.h"
#include "cppexcept.h"
#include "mtdll.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
msvcrt
);
typedef
void
(
*
v_table_ptr
)();
/*
* 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
{
v_table_ptr
*
vtable
;
char
*
name
;
int
do_free
;
/* take string copy with char* ctor?
*/
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
struct
__bad_typeid
{
exception
base
;
}
bad_typeid
;
typedef
struct
____non_rtti_object
{
bad_typeid
base
;
}
__non_rtti_object
;
typedef
struct
__bad_cast
{
exception
base
;
}
bad_cast
;
typedef
struct
__type_info
{
v_table_ptr
*
vtable
;
void
*
data
;
char
name
[
1
];
}
type_info
;
typedef
exception
bad_cast
;
typedef
exception
bad_typeid
;
typedef
exception
__non_rtti_object
;
typedef
struct
_rtti_base_descriptor
{
...
...
@@ -68,11 +61,13 @@ typedef struct _rtti_base_descriptor
int
num_base_classes
;
int
base_class_offset
;
unsigned
int
flags
;
int
unknown1
;
int
unknown2
;
}
rtti_base_descriptor
;
typedef
struct
_rtti_base_array
{
rtti_base_descriptor
*
bases
[
1
];
/* First element is the class itself */
const
rtti_base_descriptor
*
bases
[
3
];
/* First element is the class itself */
}
rtti_base_array
;
typedef
struct
_rtti_object_hierachy
...
...
@@ -80,7 +75,7 @@ typedef struct _rtti_object_hierachy
int
unknown1
;
int
unknown2
;
int
array_len
;
/* Size of the array pointed to by 'base_classes' */
rtti_base_array
*
base_classes
;
const
rtti_base_array
*
base_classes
;
}
rtti_object_hierachy
;
typedef
struct
_rtti_object_locator
...
...
@@ -89,7 +84,7 @@ typedef struct _rtti_object_locator
int
base_class_offset
;
unsigned
int
flags
;
type_info
*
type_descriptor
;
rtti_object_hierachy
*
type_hierachy
;
const
rtti_object_hierachy
*
type_hierachy
;
}
rtti_object_locator
;
...
...
@@ -103,10 +98,29 @@ typedef struct _rtti_object_locator
"pushl %eax\n\t" \
"jmp " __ASM_NAME(#func) )
v_table_ptr
MSVCRT_exception_vtable
[];
v_table_ptr
MSVCRT_bad_typeid_vtable
[];
v_table_ptr
MSVCRT_bad_cast_vtable
[];
v_table_ptr
MSVCRT___non_rtti_object_vtable
[];
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.@)
...
...
@@ -114,11 +128,8 @@ v_table_ptr MSVCRT___non_rtti_object_vtable[];
DEFINE_THISCALL_WRAPPER
(
MSVCRT_exception_ctor
);
exception
*
__stdcall
MSVCRT_exception_ctor
(
exception
*
_this
,
const
char
**
name
)
{
TRACE
(
"(%p %s)
\n
"
,
_this
,
*
name
);
_this
->
vtable
=
MSVCRT_exception_vtable
;
_this
->
name
=
MSVCRT_operator_new
(
strlen
(
*
name
)
+
1
);
if
(
_this
->
name
)
strcpy
(
_this
->
name
,
*
name
);
_this
->
do_free
=
TRUE
;
TRACE
(
"(%p,%s)
\n
"
,
_this
,
*
name
);
EXCEPTION_ctor
(
_this
,
name
);
return
_this
;
}
...
...
@@ -128,16 +139,17 @@ exception * __stdcall MSVCRT_exception_ctor(exception * _this, const char ** nam
DEFINE_THISCALL_WRAPPER
(
MSVCRT_exception_copy_ctor
);
exception
*
__stdcall
MSVCRT_exception_copy_ctor
(
exception
*
_this
,
const
exception
*
rhs
)
{
TRACE
(
"(%p %p)
\n
"
,
_this
,
rhs
);
_this
->
vtable
=
MSVCRT_exception_vtable
;
_this
->
do_free
=
rhs
->
do_free
;
if
(
!
_this
->
do_free
)
_this
->
name
=
rhs
->
name
;
else
TRACE
(
"(%p,%p)
\n
"
,
_this
,
rhs
);
if
(
!
rhs
->
do_free
)
{
_this
->
name
=
MSVCRT_operator_new
(
strlen
(
rhs
->
name
)
+
1
);
if
(
_this
->
name
)
strcpy
(
_this
->
name
,
rhs
->
name
);
_this
->
vtable
=
&
MSVCRT_exception_vtable
;
_this
->
name
=
rhs
->
name
;
_this
->
do_free
=
FALSE
;
}
TRACE
(
"name = %s
\n
"
,
_this
->
name
);
else
EXCEPTION_ctor
(
_this
,
(
const
char
**
)
&
rhs
->
name
);
TRACE
(
"name = %s
\n
"
,
_this
->
name
);
return
_this
;
}
...
...
@@ -147,10 +159,10 @@ exception * __stdcall MSVCRT_exception_copy_ctor(exception * _this, const except
DEFINE_THISCALL_WRAPPER
(
MSVCRT_exception_default_ctor
);
exception
*
__stdcall
MSVCRT_exception_default_ctor
(
exception
*
_this
)
{
TRACE
(
"(%p)
\n
"
,
_this
)
;
_this
->
vtable
=
MSVCRT_exception_vtable
;
_this
->
name
=
NULL
;
_this
->
do_free
=
FALSE
;
static
const
char
*
empty
=
NULL
;
TRACE
(
"(%p)
\n
"
,
_this
)
;
EXCEPTION_ctor
(
_this
,
&
empty
)
;
return
_this
;
}
...
...
@@ -160,9 +172,9 @@ exception * __stdcall MSVCRT_exception_default_ctor(exception * _this)
DEFINE_THISCALL_WRAPPER
(
MSVCRT_exception_dtor
);
void
__stdcall
MSVCRT_exception_dtor
(
exception
*
_this
)
{
TRACE
(
"(%p)
\n
"
,
_this
);
_this
->
vtable
=
MSVCRT_exception_vtable
;
if
(
_this
->
do_free
)
MSVCRT_
operator_delet
e
(
_this
->
name
);
TRACE
(
"(%p)
\n
"
,
_this
);
_this
->
vtable
=
&
MSVCRT_exception_vtable
;
if
(
_this
->
do_free
)
MSVCRT_
fre
e
(
_this
->
name
);
}
/******************************************************************
...
...
@@ -171,13 +183,13 @@ void __stdcall MSVCRT_exception_dtor(exception * _this)
DEFINE_THISCALL_WRAPPER
(
MSVCRT_exception_opequals
);
exception
*
__stdcall
MSVCRT_exception_opequals
(
exception
*
_this
,
const
exception
*
rhs
)
{
TRACE
(
"(%p %p)
\n
"
,
_this
,
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
);
TRACE
(
"name = %s
\n
"
,
_this
->
name
);
return
_this
;
}
...
...
@@ -187,7 +199,7 @@ exception * __stdcall MSVCRT_exception_opequals(exception * _this, const excepti
DEFINE_THISCALL_WRAPPER
(
MSVCRT_exception_vector_dtor
);
void
*
__stdcall
MSVCRT_exception_vector_dtor
(
exception
*
_this
,
unsigned
int
flags
)
{
TRACE
(
"(%p %x)
\n
"
,
_this
,
flags
);
TRACE
(
"(%p %x)
\n
"
,
_this
,
flags
);
if
(
flags
&
2
)
{
/* we have an array, with the number of elements stored before the first object */
...
...
@@ -210,7 +222,7 @@ void * __stdcall MSVCRT_exception_vector_dtor(exception * _this, unsigned int fl
DEFINE_THISCALL_WRAPPER
(
MSVCRT_exception_scalar_dtor
);
void
*
__stdcall
MSVCRT_exception_scalar_dtor
(
exception
*
_this
,
unsigned
int
flags
)
{
TRACE
(
"(%p %x)
\n
"
,
_this
,
flags
);
TRACE
(
"(%p %x)
\n
"
,
_this
,
flags
);
MSVCRT_exception_dtor
(
_this
);
if
(
flags
&
1
)
MSVCRT_operator_delete
(
_this
);
return
_this
;
...
...
@@ -222,7 +234,7 @@ void * __stdcall MSVCRT_exception_scalar_dtor(exception * _this, unsigned int fl
DEFINE_THISCALL_WRAPPER
(
MSVCRT_what_exception
);
const
char
*
__stdcall
MSVCRT_what_exception
(
exception
*
_this
)
{
TRACE
(
"(%p) returning %s
\n
"
,
_this
,
_this
->
name
);
TRACE
(
"(%p) returning %s
\n
"
,
_this
,
_this
->
name
);
return
_this
->
name
?
_this
->
name
:
"Unknown exception"
;
}
...
...
@@ -232,9 +244,9 @@ const char * __stdcall MSVCRT_what_exception(exception * _this)
DEFINE_THISCALL_WRAPPER
(
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
->
base
,
&
rhs
->
base
);
_this
->
base
.
vtable
=
MSVCRT_bad_typeid_vtable
;
TRACE
(
"(%p %p)
\n
"
,
_this
,
rhs
);
MSVCRT_exception_copy_ctor
(
_this
,
rhs
);
_this
->
vtable
=
&
MSVCRT_bad_typeid_vtable
;
return
_this
;
}
...
...
@@ -244,9 +256,9 @@ bad_typeid * __stdcall MSVCRT_bad_typeid_copy_ctor(bad_typeid * _this, const bad
DEFINE_THISCALL_WRAPPER
(
MSVCRT_bad_typeid_ctor
);
bad_typeid
*
__stdcall
MSVCRT_bad_typeid_ctor
(
bad_typeid
*
_this
,
const
char
*
name
)
{
TRACE
(
"(%p %s)
\n
"
,
_this
,
name
);
MSVCRT_exception_ctor
(
&
_this
->
base
,
&
name
);
_this
->
base
.
vtable
=
MSVCRT_bad_typeid_vtable
;
TRACE
(
"(%p %s)
\n
"
,
_this
,
name
);
EXCEPTION_ctor
(
_this
,
&
name
);
_this
->
vtable
=
&
MSVCRT_bad_typeid_vtable
;
return
_this
;
}
...
...
@@ -256,8 +268,8 @@ bad_typeid * __stdcall MSVCRT_bad_typeid_ctor(bad_typeid * _this, const char * n
DEFINE_THISCALL_WRAPPER
(
MSVCRT_bad_typeid_dtor
);
void
__stdcall
MSVCRT_bad_typeid_dtor
(
bad_typeid
*
_this
)
{
TRACE
(
"(%p)
\n
"
,
_this
);
MSVCRT_exception_dtor
(
&
_this
->
base
);
TRACE
(
"(%p)
\n
"
,
_this
);
MSVCRT_exception_dtor
(
_this
);
}
/******************************************************************
...
...
@@ -266,8 +278,8 @@ void __stdcall MSVCRT_bad_typeid_dtor(bad_typeid * _this)
DEFINE_THISCALL_WRAPPER
(
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
->
base
,
&
rhs
->
base
);
TRACE
(
"(%p %p)
\n
"
,
_this
,
rhs
);
MSVCRT_exception_opequals
(
_this
,
rhs
);
return
_this
;
}
...
...
@@ -277,7 +289,7 @@ bad_typeid * __stdcall MSVCRT_bad_typeid_opequals(bad_typeid * _this, const bad_
DEFINE_THISCALL_WRAPPER
(
MSVCRT_bad_typeid_vector_dtor
);
void
*
__stdcall
MSVCRT_bad_typeid_vector_dtor
(
bad_typeid
*
_this
,
unsigned
int
flags
)
{
TRACE
(
"(%p %x)
\n
"
,
_this
,
flags
);
TRACE
(
"(%p %x)
\n
"
,
_this
,
flags
);
if
(
flags
&
2
)
{
/* we have an array, with the number of elements stored before the first object */
...
...
@@ -300,7 +312,7 @@ void * __stdcall MSVCRT_bad_typeid_vector_dtor(bad_typeid * _this, unsigned int
DEFINE_THISCALL_WRAPPER
(
MSVCRT_bad_typeid_scalar_dtor
);
void
*
__stdcall
MSVCRT_bad_typeid_scalar_dtor
(
bad_typeid
*
_this
,
unsigned
int
flags
)
{
TRACE
(
"(%p %x)
\n
"
,
_this
,
flags
);
TRACE
(
"(%p %x)
\n
"
,
_this
,
flags
);
MSVCRT_bad_typeid_dtor
(
_this
);
if
(
flags
&
1
)
MSVCRT_operator_delete
(
_this
);
return
_this
;
...
...
@@ -313,9 +325,9 @@ DEFINE_THISCALL_WRAPPER(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
->
base
,
&
rhs
->
base
);
_this
->
base
.
base
.
vtable
=
MSVCRT___non_rtti_object_vtable
;
TRACE
(
"(%p %p)
\n
"
,
_this
,
rhs
);
MSVCRT_bad_typeid_copy_ctor
(
_this
,
rhs
);
_this
->
vtable
=
&
MSVCRT___non_rtti_object_vtable
;
return
_this
;
}
...
...
@@ -326,9 +338,9 @@ DEFINE_THISCALL_WRAPPER(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
);
MSVCRT_bad_typeid_ctor
(
&
_this
->
base
,
name
);
_this
->
base
.
base
.
vtable
=
MSVCRT___non_rtti_object_vtable
;
TRACE
(
"(%p %s)
\n
"
,
_this
,
name
);
EXCEPTION_ctor
(
_this
,
&
name
);
_this
->
vtable
=
&
MSVCRT___non_rtti_object_vtable
;
return
_this
;
}
...
...
@@ -338,8 +350,8 @@ __non_rtti_object * __stdcall MSVCRT___non_rtti_object_ctor(__non_rtti_object *
DEFINE_THISCALL_WRAPPER
(
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
->
base
);
TRACE
(
"(%p)
\n
"
,
_this
);
MSVCRT_bad_typeid_dtor
(
_this
);
}
/******************************************************************
...
...
@@ -349,8 +361,8 @@ DEFINE_THISCALL_WRAPPER(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
->
base
,
&
rhs
->
base
);
TRACE
(
"(%p %p)
\n
"
,
_this
,
rhs
);
MSVCRT_bad_typeid_opequals
(
_this
,
rhs
);
return
_this
;
}
...
...
@@ -360,7 +372,7 @@ __non_rtti_object * __stdcall MSVCRT___non_rtti_object_opequals(__non_rtti_objec
DEFINE_THISCALL_WRAPPER
(
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
);
TRACE
(
"(%p %x)
\n
"
,
_this
,
flags
);
if
(
flags
&
2
)
{
/* we have an array, with the number of elements stored before the first object */
...
...
@@ -383,7 +395,7 @@ void * __stdcall MSVCRT___non_rtti_object_vector_dtor(__non_rtti_object * _this,
DEFINE_THISCALL_WRAPPER
(
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
);
TRACE
(
"(%p %x)
\n
"
,
_this
,
flags
);
MSVCRT___non_rtti_object_dtor
(
_this
);
if
(
flags
&
1
)
MSVCRT_operator_delete
(
_this
);
return
_this
;
...
...
@@ -395,9 +407,9 @@ void * __stdcall MSVCRT___non_rtti_object_scalar_dtor(__non_rtti_object * _this,
DEFINE_THISCALL_WRAPPER
(
MSVCRT_bad_cast_ctor
);
bad_cast
*
__stdcall
MSVCRT_bad_cast_ctor
(
bad_cast
*
_this
,
const
char
**
name
)
{
TRACE
(
"(%p %s)
\n
"
,
_this
,
*
name
);
MSVCRT_exception_ctor
(
&
_this
->
base
,
name
);
_this
->
base
.
vtable
=
MSVCRT_bad_cast_vtable
;
TRACE
(
"(%p %s)
\n
"
,
_this
,
*
name
);
EXCEPTION_ctor
(
_this
,
name
);
_this
->
vtable
=
&
MSVCRT_bad_cast_vtable
;
return
_this
;
}
...
...
@@ -407,9 +419,9 @@ bad_cast * __stdcall MSVCRT_bad_cast_ctor(bad_cast * _this, const char ** name)
DEFINE_THISCALL_WRAPPER
(
MSVCRT_bad_cast_copy_ctor
);
bad_cast
*
__stdcall
MSVCRT_bad_cast_copy_ctor
(
bad_cast
*
_this
,
const
bad_cast
*
rhs
)
{
TRACE
(
"(%p %p)
\n
"
,
_this
,
rhs
);
MSVCRT_exception_copy_ctor
(
&
_this
->
base
,
&
rhs
->
base
);
_this
->
base
.
vtable
=
MSVCRT_bad_cast_vtable
;
TRACE
(
"(%p %p)
\n
"
,
_this
,
rhs
);
MSVCRT_exception_copy_ctor
(
_this
,
rhs
);
_this
->
vtable
=
&
MSVCRT_bad_cast_vtable
;
return
_this
;
}
...
...
@@ -419,8 +431,8 @@ bad_cast * __stdcall MSVCRT_bad_cast_copy_ctor(bad_cast * _this, const bad_cast
DEFINE_THISCALL_WRAPPER
(
MSVCRT_bad_cast_dtor
);
void
__stdcall
MSVCRT_bad_cast_dtor
(
bad_cast
*
_this
)
{
TRACE
(
"(%p)
\n
"
,
_this
);
MSVCRT_exception_dtor
(
&
_this
->
base
);
TRACE
(
"(%p)
\n
"
,
_this
);
MSVCRT_exception_dtor
(
_this
);
}
/******************************************************************
...
...
@@ -429,8 +441,8 @@ void __stdcall MSVCRT_bad_cast_dtor(bad_cast * _this)
DEFINE_THISCALL_WRAPPER
(
MSVCRT_bad_cast_opequals
);
bad_cast
*
__stdcall
MSVCRT_bad_cast_opequals
(
bad_cast
*
_this
,
const
bad_cast
*
rhs
)
{
TRACE
(
"(%p %p)
\n
"
,
_this
,
rhs
);
MSVCRT_exception_opequals
(
&
_this
->
base
,
&
rhs
->
base
);
TRACE
(
"(%p %p)
\n
"
,
_this
,
rhs
);
MSVCRT_exception_opequals
(
_this
,
rhs
);
return
_this
;
}
...
...
@@ -440,7 +452,7 @@ bad_cast * __stdcall MSVCRT_bad_cast_opequals(bad_cast * _this, const bad_cast *
DEFINE_THISCALL_WRAPPER
(
MSVCRT_bad_cast_vector_dtor
);
void
*
__stdcall
MSVCRT_bad_cast_vector_dtor
(
bad_cast
*
_this
,
unsigned
int
flags
)
{
TRACE
(
"(%p %x)
\n
"
,
_this
,
flags
);
TRACE
(
"(%p %x)
\n
"
,
_this
,
flags
);
if
(
flags
&
2
)
{
/* we have an array, with the number of elements stored before the first object */
...
...
@@ -463,7 +475,7 @@ void * __stdcall MSVCRT_bad_cast_vector_dtor(bad_cast * _this, unsigned int flag
DEFINE_THISCALL_WRAPPER
(
MSVCRT_bad_cast_scalar_dtor
);
void
*
__stdcall
MSVCRT_bad_cast_scalar_dtor
(
bad_cast
*
_this
,
unsigned
int
flags
)
{
TRACE
(
"(%p %x)
\n
"
,
_this
,
flags
);
TRACE
(
"(%p %x)
\n
"
,
_this
,
flags
);
MSVCRT_bad_cast_dtor
(
_this
);
if
(
flags
&
1
)
MSVCRT_operator_delete
(
_this
);
return
_this
;
...
...
@@ -475,8 +487,8 @@ void * __stdcall MSVCRT_bad_cast_scalar_dtor(bad_cast * _this, unsigned int flag
DEFINE_THISCALL_WRAPPER
(
MSVCRT_type_info_opequals_equals
);
int
__stdcall
MSVCRT_type_info_opequals_equals
(
type_info
*
_this
,
const
type_info
*
rhs
)
{
int
ret
=
!
strcmp
(
_this
->
name
,
rhs
->
name
);
TRACE
(
"(%p %p) returning %d
\n
"
,
_this
,
rhs
,
ret
);
int
ret
=
!
strcmp
(
_this
->
mangled
+
1
,
rhs
->
mangled
+
1
);
TRACE
(
"(%p %p) returning %d
\n
"
,
_this
,
rhs
,
ret
);
return
ret
;
}
...
...
@@ -486,8 +498,8 @@ int __stdcall MSVCRT_type_info_opequals_equals(type_info * _this, const type_inf
DEFINE_THISCALL_WRAPPER
(
MSVCRT_type_info_opnot_equals
);
int
__stdcall
MSVCRT_type_info_opnot_equals
(
type_info
*
_this
,
const
type_info
*
rhs
)
{
int
ret
=
!!
strcmp
(
_this
->
name
,
rhs
->
name
);
TRACE
(
"(%p %p) returning %d
\n
"
,
_this
,
rhs
,
ret
);
int
ret
=
!!
strcmp
(
_this
->
mangled
+
1
,
rhs
->
mangled
+
1
);
TRACE
(
"(%p %p) returning %d
\n
"
,
_this
,
rhs
,
ret
);
return
ret
;
}
...
...
@@ -497,8 +509,8 @@ int __stdcall MSVCRT_type_info_opnot_equals(type_info * _this, const type_info *
DEFINE_THISCALL_WRAPPER
(
MSVCRT_type_info_before
);
int
__stdcall
MSVCRT_type_info_before
(
type_info
*
_this
,
const
type_info
*
rhs
)
{
int
ret
=
strcmp
(
_this
->
name
,
rhs
->
name
)
<
0
;
TRACE
(
"(%p %p) returning %d
\n
"
,
_this
,
rhs
,
ret
);
int
ret
=
strcmp
(
_this
->
mangled
+
1
,
rhs
->
mangled
+
1
)
<
0
;
TRACE
(
"(%p %p) returning %d
\n
"
,
_this
,
rhs
,
ret
);
return
ret
;
}
...
...
@@ -508,9 +520,9 @@ int __stdcall MSVCRT_type_info_before(type_info * _this, const type_info * rhs)
DEFINE_THISCALL_WRAPPER
(
MSVCRT_type_info_dtor
);
void
__stdcall
MSVCRT_type_info_dtor
(
type_info
*
_this
)
{
TRACE
(
"(%p)
\n
"
,
_this
);
if
(
_this
->
data
)
MSVCRT_free
(
_this
->
data
);
TRACE
(
"(%p)
\n
"
,
_this
);
if
(
_this
->
name
)
MSVCRT_free
(
_this
->
name
);
}
/******************************************************************
...
...
@@ -519,7 +531,35 @@ void __stdcall MSVCRT_type_info_dtor(type_info * _this)
DEFINE_THISCALL_WRAPPER
(
MSVCRT_type_info_name
);
const
char
*
__stdcall
MSVCRT_type_info_name
(
type_info
*
_this
)
{
TRACE
(
"(%p) returning %s
\n
"
,
_this
,
_this
->
name
);
if
(
!
_this
->
name
)
{
/* Create and set the demangled name */
char
*
name
=
MSVCRT___unDName
(
0
,
_this
->
mangled
,
0
,
(
MSVCRT_malloc_func
)
MSVCRT_malloc
,
(
MSVCRT_free_func
)
MSVCRT_free
,
0x2800
);
if
(
name
)
{
unsigned
int
len
=
strlen
(
name
);
/* It seems _unDName may leave blanks at the end of the demangled name */
if
(
name
[
len
]
==
' '
)
name
[
len
]
=
'\0'
;
_mlock
(
_EXIT_LOCK2
);
if
(
_this
->
name
)
{
/* Another thread set this member since we checked above - use it */
MSVCRT_free
(
name
);
}
else
_this
->
name
=
name
;
_munlock
(
_EXIT_LOCK2
);
}
}
TRACE
(
"(%p) returning %s
\n
"
,
_this
,
_this
->
name
);
return
_this
->
name
;
}
...
...
@@ -529,41 +569,384 @@ const char * __stdcall MSVCRT_type_info_name(type_info * _this)
DEFINE_THISCALL_WRAPPER
(
MSVCRT_type_info_raw_name
);
const
char
*
__stdcall
MSVCRT_type_info_raw_name
(
type_info
*
_this
)
{
TRACE
(
"(%p) returning %s
\n
"
,
_this
,
_this
->
name
);
return
_this
->
name
;
TRACE
(
"(%p) returning %s
\n
"
,
_this
,
_this
->
mangled
);
return
_this
->
mangled
;
}
/* Unexported */
DEFINE_THISCALL_WRAPPER
(
MSVCRT_type_info_vector_dtor
);
void
*
__stdcall
MSVCRT_type_info_vector_dtor
(
type_info
*
_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_type_info_dtor
(
_this
+
i
);
MSVCRT_operator_delete
(
ptr
);
}
else
{
MSVCRT_type_info_dtor
(
_this
);
if
(
flags
&
1
)
MSVCRT_operator_delete
(
_this
);
}
return
_this
;
}
/* vtables */
v_table_ptr
MSVCRT_exception_vtable
[
2
]
=
const
exception_vtable
MSVCRT_exception_vtable
=
{
__thiscall_MSVCRT_exception_vector_dtor
,
__thiscall_MSVCRT_what_exception
};
v_table_ptr
MSVCRT_bad_typeid_vtable
[
2
]
=
const
exception_vtable
MSVCRT_bad_typeid_vtable
=
{
__thiscall_MSVCRT_bad_typeid_vector_dtor
,
__thiscall_MSVCRT_what_exception
};
v_table_ptr
MSVCRT_bad_cast_vtable
[
2
]
=
const
exception_vtable
MSVCRT_bad_cast_vtable
=
{
__thiscall_MSVCRT_bad_cast_vector_dtor
,
__thiscall_MSVCRT_what_exception
};
v_table_ptr
MSVCRT___non_rtti_object_vtable
[
2
]
=
const
exception_vtable
MSVCRT___non_rtti_object_vtable
=
{
__thiscall_MSVCRT___non_rtti_object_vector_dtor
,
__thiscall_MSVCRT_what_exception
};
static
const
exception_vtable
MSVCRT_type_info_vtable
=
{
__thiscall_MSVCRT_type_info_vector_dtor
,
NULL
};
/* Static RTTI for exported objects */
static
type_info
exception_type_info
=
{
(
void
*
)
&
MSVCRT_type_info_vtable
,
NULL
,
".?AVexception@@"
};
static
const
rtti_base_descriptor
exception_rtti_base_descriptor
=
{
&
exception_type_info
,
0
,
0
,
0
,
0
,
0
};
static
const
rtti_base_array
exception_rtti_base_array
=
{
{
&
exception_rtti_base_descriptor
,
NULL
,
NULL
}
};
static
const
rtti_object_hierachy
exception_type_hierachy
=
{
0
,
0
,
1
,
&
exception_rtti_base_array
};
static
const
rtti_object_locator
exception_rtti
=
{
0
,
0
,
0
,
&
exception_type_info
,
&
exception_type_hierachy
};
static
const
cxx_type_info
exception_cxx_type_info
=
{
0
,
&
exception_type_info
,
0
,
-
1
,
0
,
sizeof
(
exception
),
(
cxx_copy_ctor
)
__thiscall_MSVCRT_exception_copy_ctor
};
static
type_info
bad_typeid_type_info
=
{
(
void
*
)
&
MSVCRT_type_info_vtable
,
NULL
,
".?AVbad_typeid@@"
};
static
const
rtti_base_descriptor
bad_typeid_rtti_base_descriptor
=
{
&
bad_typeid_type_info
,
1
,
0
,
0xffffffff
,
0
,
0
};
static
const
rtti_base_array
bad_typeid_rtti_base_array
=
{
{
&
bad_typeid_rtti_base_descriptor
,
&
exception_rtti_base_descriptor
,
NULL
}
};
static
const
rtti_object_hierachy
bad_typeid_type_hierachy
=
{
0
,
0
,
2
,
&
bad_typeid_rtti_base_array
};
static
const
rtti_object_locator
bad_typeid_rtti
=
{
0
,
0
,
0
,
&
bad_typeid_type_info
,
&
bad_typeid_type_hierachy
};
static
const
cxx_type_info
bad_typeid_cxx_type_info
=
{
0
,
&
bad_typeid_type_info
,
0
,
-
1
,
0
,
sizeof
(
exception
),
(
cxx_copy_ctor
)
__thiscall_MSVCRT_bad_typeid_copy_ctor
};
static
type_info
bad_cast_type_info
=
{
(
void
*
)
&
MSVCRT_type_info_vtable
,
NULL
,
".?AVbad_cast@@"
};
static
const
rtti_base_descriptor
bad_cast_rtti_base_descriptor
=
{
&
bad_cast_type_info
,
1
,
0
,
0xffffffff
,
0
,
0
};
static
const
rtti_base_array
bad_cast_rtti_base_array
=
{
{
&
bad_cast_rtti_base_descriptor
,
&
exception_rtti_base_descriptor
,
NULL
}
};
static
const
rtti_object_hierachy
bad_cast_type_hierachy
=
{
0
,
0
,
2
,
&
bad_cast_rtti_base_array
};
static
const
rtti_object_locator
bad_cast_rtti
=
{
0
,
0
,
0
,
&
bad_cast_type_info
,
&
bad_cast_type_hierachy
};
static
const
cxx_type_info
bad_cast_cxx_type_info
=
{
0
,
&
bad_cast_type_info
,
0
,
-
1
,
0
,
sizeof
(
exception
),
(
cxx_copy_ctor
)
__thiscall_MSVCRT_bad_cast_copy_ctor
};
static
type_info
__non_rtti_object_type_info
=
{
(
void
*
)
&
MSVCRT_type_info_vtable
,
NULL
,
".?AV__non_rtti_object@@"
};
static
const
rtti_base_descriptor
__non_rtti_object_rtti_base_descriptor
=
{
&
__non_rtti_object_type_info
,
2
,
0
,
0xffffffff
,
0
,
0
};
static
const
rtti_base_array
__non_rtti_object_rtti_base_array
=
{
{
&
__non_rtti_object_rtti_base_descriptor
,
&
bad_typeid_rtti_base_descriptor
,
&
exception_rtti_base_descriptor
}
};
static
const
rtti_object_hierachy
__non_rtti_object_type_hierachy
=
{
0
,
0
,
3
,
&
__non_rtti_object_rtti_base_array
};
static
const
rtti_object_locator
__non_rtti_object_rtti
=
{
0
,
0
,
0
,
&
__non_rtti_object_type_info
,
&
__non_rtti_object_type_hierachy
};
static
const
cxx_type_info
__non_rtti_object_cxx_type_info
=
{
0
,
&
__non_rtti_object_type_info
,
0
,
-
1
,
0
,
sizeof
(
exception
),
(
cxx_copy_ctor
)
__thiscall_MSVCRT___non_rtti_object_copy_ctor
};
static
type_info
type_info_type_info
=
{
(
void
*
)
&
MSVCRT_type_info_vtable
,
NULL
,
".?AVtype_info@@"
};
static
const
rtti_base_descriptor
type_info_rtti_base_descriptor
=
{
&
type_info_type_info
,
0
,
0
,
0xffffffff
,
0
,
0
};
static
const
rtti_base_array
type_info_rtti_base_array
=
{
{
&
type_info_rtti_base_descriptor
,
NULL
,
NULL
}
};
static
const
rtti_object_hierachy
type_info_type_hierachy
=
{
0
,
0
,
1
,
&
type_info_rtti_base_array
};
static
const
rtti_object_locator
type_info_rtti
=
{
0
,
0
,
0
,
&
type_info_type_info
,
&
type_info_type_hierachy
};
/*
* Exception RTTI for cpp objects
*/
static
const
cxx_type_info_table
bad_cast_type_info_table
=
{
3
,
{
&
__non_rtti_object_cxx_type_info
,
&
bad_typeid_cxx_type_info
,
&
exception_cxx_type_info
}
};
static
const
cxx_exception_type
bad_cast_exception_type
=
{
0
,
(
void
*
)
__thiscall_MSVCRT_bad_cast_dtor
,
NULL
,
&
bad_cast_type_info_table
};
static
const
cxx_type_info_table
bad_typeid_type_info_table
=
{
2
,
{
&
bad_cast_cxx_type_info
,
&
exception_cxx_type_info
,
NULL
}
};
static
const
cxx_exception_type
bad_typeid_exception_type
=
{
0
,
(
void
*
)
__thiscall_MSVCRT_bad_typeid_dtor
,
NULL
,
&
bad_cast_type_info_table
};
static
const
cxx_exception_type
__non_rtti_object_exception_type
=
{
0
,
(
void
*
)
__thiscall_MSVCRT___non_rtti_object_dtor
,
NULL
,
&
bad_typeid_type_info_table
};
#endif
/* __i386__ */
/******************************************************************
* ?set_terminate@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
*
* Install a handler to be called when terminate() is called.
*
* PARAMS
* func [I] Handler function to install
*
* RETURNS
* The previously installed handler function, if any.
*/
terminate_function
MSVCRT_set_terminate
(
terminate_function
func
)
{
...
...
@@ -576,6 +959,14 @@ terminate_function MSVCRT_set_terminate(terminate_function func)
/******************************************************************
* ?set_unexpected@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
*
* Install a handler to be called when unexpected() is called.
*
* PARAMS
* func [I] Handler function to install
*
* RETURNS
* The previously installed handler function, if any.
*/
unexpected_function
MSVCRT_set_unexpected
(
unexpected_function
func
)
{
...
...
@@ -600,6 +991,16 @@ _se_translator_function MSVCRT__set_se_translator(_se_translator_function func)
/******************************************************************
* ?terminate@@YAXXZ (MSVCRT.@)
*
* Default handler for an unhandled exception.
*
* PARAMS
* None.
*
* RETURNS
* This function does not return. Either control resumes from any
* handler installed by calling set_terminate(), or (by default) abort()
* is called.
*/
void
MSVCRT_terminate
(
void
)
{
...
...
@@ -618,38 +1019,139 @@ void MSVCRT_unexpected(void)
MSVCRT_terminate
();
}
/* Get type info from an object (internal) */
static
const
rtti_object_locator
*
RTTI_GetObjectLocator
(
type_info
*
cppobj
)
{
const
rtti_object_locator
*
obj_locator
=
NULL
;
#ifdef __i386__
const
exception_vtable
*
vtable
=
(
const
exception_vtable
*
)
cppobj
->
vtable
;
/* Perhaps this is one of classes we export? */
if
(
vtable
==
&
MSVCRT_exception_vtable
)
{
TRACE
(
"returning exception_rtti
\n
"
);
return
&
exception_rtti
;
}
else
if
(
vtable
==
&
MSVCRT_bad_typeid_vtable
)
{
TRACE
(
"returning bad_typeid_rtti
\n
"
);
return
&
bad_typeid_rtti
;
}
else
if
(
vtable
==
&
MSVCRT_bad_cast_vtable
)
{
TRACE
(
"returning bad_cast_rtti
\n
"
);
return
&
bad_cast_rtti
;
}
else
if
(
vtable
==
&
MSVCRT___non_rtti_object_vtable
)
{
TRACE
(
"returning __non_rtti_object_rtti
\n
"
);
return
&
__non_rtti_object_rtti
;
}
else
if
(
vtable
==
&
MSVCRT_type_info_vtable
)
{
TRACE
(
"returning type_info_rtti
\n
"
);
return
&
type_info_rtti
;
}
#endif
if
(
!
IsBadReadPtr
(
cppobj
,
sizeof
(
void
*
))
&&
!
IsBadReadPtr
(
cppobj
->
vtable
-
1
,
sizeof
(
void
*
))
&&
!
IsBadReadPtr
((
void
*
)
cppobj
->
vtable
[
-
1
],
sizeof
(
rtti_object_locator
)))
{
obj_locator
=
(
rtti_object_locator
*
)
cppobj
->
vtable
[
-
1
];
TRACE
(
"returning type_info from vtable (%p)
\n
"
,
obj_locator
);
}
return
obj_locator
;
}
/******************************************************************
* __RTtypeid (MSVCRT.@)
*
* Retrieve the Run Time Type Information (RTTI) for a C++ object.
*
* PARAMS
* cppobj [I] C++ object to get type information for.
*
* RETURNS
* Success: A type_info object describing cppobj.
* Failure: If the object to be cast has no RTTI, a __non_rtti_object
* exception is thrown. If cppobj is NULL, a bad_typeid exception
* is thrown. In either case, this function does not return.
*
* NOTES
* This function is usually called by compiler generated code as a result
* of using one of the C++ dynamic cast statements.
*/
type_info
*
MSVCRT___RTtypeid
(
type_info
*
cppobj
)
{
/* Note: cppobj _isn't_ a type_info, we use that struct for its vtable ptr */
TRACE
(
"(%p)
\n
"
,
cppobj
);
const
rtti_object_locator
*
obj_locator
=
RTTI_GetObjectLocator
(
cppobj
);
if
(
!
IsBadReadPtr
(
cppobj
,
sizeof
(
void
*
))
&&
!
IsBadReadPtr
(
cppobj
->
vtable
-
1
,
sizeof
(
void
*
))
&&
!
IsBadReadPtr
((
void
*
)
cppobj
->
vtable
[
-
1
],
sizeof
(
rtti_object_locator
)))
#ifdef __i386__
if
(
!
obj_locator
)
{
rtti_object_locator
*
obj_locator
=
(
rtti_object_locator
*
)
cppobj
->
vtable
[
-
1
];
return
obj_locator
->
type_descriptor
;
static
const
char
*
szNullPtr
=
"Attempted a typeid of NULL pointer!"
;
static
const
char
*
szBadPtr
=
"Bad read pointer - no RTTI data!"
;
const
cxx_exception_type
*
e_type
;
exception
e
;
/* Throw a bad_typeid or __non_rtti_object exception */
if
(
!
cppobj
)
{
EXCEPTION_ctor
(
&
e
,
&
szNullPtr
);
e
.
vtable
=
&
MSVCRT_bad_typeid_vtable
;
e_type
=
&
bad_typeid_exception_type
;
}
else
{
EXCEPTION_ctor
(
&
e
,
&
szBadPtr
);
e
.
vtable
=
&
MSVCRT___non_rtti_object_vtable
;
e_type
=
&
__non_rtti_object_exception_type
;
}
/* FIXME: throw a C++ exception */
FIXME
(
"Should throw(bad_typeid). Creating NULL reference, expect crash!
\n
"
);
_CxxThrowException
(
&
e
,
e_type
);
DebugBreak
();
}
return
obj_locator
->
type_descriptor
;
#else
return
NULL
;
#endif
}
/******************************************************************
* __RTDynamicCast (MSVCRT.@)
*
* Dynamically cast a C++ object to one of its base classes.
*
* PARAMS
* cppobj [I] Any C++ object to cast
* unknown [I] Reserved, set to 0
* src [I] type_info object describing cppobj
* dst [I] type_info object describing the base class to cast to
* do_throw [I] TRUE = throw an exception if the cast fails, FALSE = don't
*
* RETURNS
* Success: The address of cppobj, cast to the object described by dst.
* Failure: NULL, If the object to be cast has no RTTI, or dst is not a
* valid cast for cppobj. If do_throw is TRUE, a bad_cast exception
* is thrown and this function does not return.
*
* NOTES
* This function is usually called by compiler generated code as a result
* of using one of the C++ dynamic cast statements.
*/
void
*
MSVCRT___RTDynamicCast
(
type_info
*
cppobj
,
int
unknown
,
type_info
*
src
,
type_info
*
dst
,
int
do_throw
)
{
const
rtti_object_locator
*
obj_locator
=
RTTI_GetObjectLocator
(
cppobj
);
/* Note: cppobj _isn't_ a type_info, we use that struct for its vtable ptr */
TRACE
(
"(%p,%d,%p,%p,%d)
\n
"
,
cppobj
,
unknown
,
src
,
dst
,
do_throw
);
TRACE
(
"(%p,%d,%p,%p,%d)
\n
"
,
cppobj
,
unknown
,
src
,
dst
,
do_throw
);
if
(
unknown
)
FIXME
(
"Unknown prameter is non-zero: please report
\n
"
);
FIXME
(
"Unknown p
a
rameter is non-zero: please report
\n
"
);
/* To cast an object at runtime:
* 1.Find out the true type of the object from the typeinfo at vtable[-1]
...
...
@@ -657,21 +1159,18 @@ void* MSVCRT___RTDynamicCast(type_info *cppobj, int unknown,
* 3.If destination type is found, return base object address + dest offset
* Otherwise, fail the cast
*/
if
(
!
IsBadReadPtr
(
cppobj
,
sizeof
(
void
*
))
&&
!
IsBadReadPtr
(
cppobj
->
vtable
-
1
,
sizeof
(
void
*
))
&&
!
IsBadReadPtr
((
void
*
)
cppobj
->
vtable
[
-
1
],
sizeof
(
rtti_object_locator
)))
if
(
obj_locator
)
{
int
count
=
0
;
rtti_object_locator
*
obj_locator
=
(
rtti_object_locator
*
)
cppobj
->
vtable
[
-
1
];
rtti_object_hierachy
*
obj_bases
=
obj_locator
->
type_hierachy
;
rtti_base_descriptor
**
base_desc
=
obj_bases
->
base_classes
->
bases
;
const
rtti_object_hierachy
*
obj_bases
=
obj_locator
->
type_hierachy
;
const
rtti_base_descriptor
**
base_desc
=
obj_bases
->
base_classes
->
bases
;
int
src_offset
=
obj_locator
->
base_class_offset
,
dst_offset
=
-
1
;
while
(
count
<
obj_bases
->
array_len
)
{
type_info
*
typ
=
(
*
base_desc
)
->
type_descriptor
;
const
type_info
*
typ
=
(
*
base_desc
)
->
type_descriptor
;
if
(
!
strcmp
(
typ
->
name
,
dst
->
name
))
if
(
!
strcmp
(
typ
->
mangled
,
dst
->
mangled
))
{
dst_offset
=
(
*
base_desc
)
->
base_class_offset
;
break
;
...
...
@@ -683,32 +1182,51 @@ void* MSVCRT___RTDynamicCast(type_info *cppobj, int unknown,
return
(
void
*
)((
unsigned
long
)
cppobj
-
src_offset
+
dst_offset
);
}
#ifdef __i386__
/* VC++ sets do_throw to 1 when the result of a dynamic_cast is assigned
* to a reference, since references cannot be NULL.
*/
if
(
do_throw
)
FIXME
(
"Should throw(bad_cast). Creating NULL reference, expect crash!
\n
"
);
{
static
const
char
*
exception_text
=
"Bad dynamic_cast!"
;
exception
e
;
/* Throw a bad_cast exception */
EXCEPTION_ctor
(
&
e
,
&
exception_text
);
e
.
vtable
=
&
MSVCRT_bad_cast_vtable
;
_CxxThrowException
(
&
e
,
&
bad_cast_exception_type
);
DebugBreak
();
}
#endif
return
NULL
;
}
/******************************************************************
* __RTCastToVoid (MSVCRT.@)
*
* Dynamically cast a C++ object to a void*.
*
* PARAMS
* cppobj [I] The C++ object to cast
*
* RETURNS
* Success: The base address of the object as a void*.
* Failure: NULL, if cppobj is NULL or has no RTTI.
*
* NOTES
* This function is usually called by compiler generated code as a result
* of using one of the C++ dynamic cast statements.
*/
void
*
MSVCRT___RTCastToVoid
(
type_info
*
cppobj
)
{
const
rtti_object_locator
*
obj_locator
=
RTTI_GetObjectLocator
(
cppobj
);
/* Note: cppobj _isn't_ a type_info, we use that struct for its vtable ptr */
TRACE
(
"(%p)
\n
"
,
cppobj
);
TRACE
(
"(%p)
\n
"
,
cppobj
);
/* Casts to void* simply cast to the base object */
if
(
!
IsBadReadPtr
(
cppobj
,
sizeof
(
void
*
))
&&
!
IsBadReadPtr
(
cppobj
->
vtable
-
1
,
sizeof
(
void
*
))
&&
!
IsBadReadPtr
((
void
*
)
cppobj
->
vtable
[
-
1
],
sizeof
(
rtti_object_locator
)))
{
rtti_object_locator
*
obj_locator
=
(
rtti_object_locator
*
)
cppobj
->
vtable
[
-
1
];
int
src_offset
=
obj_locator
->
base_class_offset
;
return
(
void
*
)((
unsigned
long
)
cppobj
-
src_offset
);
}
if
(
obj_locator
)
return
(
void
*
)((
unsigned
long
)
cppobj
-
obj_locator
->
base_class_offset
);
return
NULL
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment