1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
// license:BSD-3-Clause
// copyright-holders:Aaron Giles,Vas Crabb
/***************************************************************************
delegate.cpp
Templates and classes to enable delegates for callbacks.
***************************************************************************/
#include "delegate.h"
#include "mfpresolve.h"
#include <cstdio>
#include <sstream>
//**************************************************************************
// MACROS
//**************************************************************************
#if defined(MAME_DELEGATE_LOG_ADJ)
#define LOG(...) printf(__VA_ARGS__)
#else
#define LOG(...) do { if (false) printf(__VA_ARGS__); } while (false)
#endif
//**************************************************************************
// LATE BINDING EXCEPTION
//**************************************************************************
binding_type_exception::binding_type_exception(std::type_info const &target_type, std::type_info const &actual_type)
: m_target_type(&target_type)
, m_actual_type(&actual_type)
{
std::ostringstream os;
os << "Error performing late bind of function expecting type " << target_type.name() << " to instance of type " << actual_type.name();
m_what = os.str();
}
char const *binding_type_exception::what() const noexcept
{
return m_what.c_str();
}
namespace util::detail {
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
const delegate_mfp_compatible::raw_mfp_data delegate_mfp_compatible::s_null_mfp = { { 0 } };
//**************************************************************************
// INTERNAL DELEGATE HELPERS
//**************************************************************************
//-------------------------------------------------
// delegate_mfp_itanium::convert_to_generic -
// given an object pointer and member function
// pointer, apply the displacement and get the
// actual function pointer
//-------------------------------------------------
delegate_generic_function delegate_mfp_itanium::convert_to_generic(delegate_generic_class *&object) const
{
auto const [entrypoint, adjusted] = detail::resolve_member_function_itanium(m_function, m_this_delta, object);
object = reinterpret_cast<delegate_generic_class *>(adjusted);
return reinterpret_cast<delegate_generic_function>(entrypoint);
}
//-------------------------------------------------
// delegate_mfp_msvc::adjust_this_pointer - given
// an object pointer and member function pointer,
// apply the displacement, and walk past
// recognisable thunks
//-------------------------------------------------
delegate_generic_function delegate_mfp_msvc::adjust_this_pointer(delegate_generic_class *&object) const
{
auto const [entrypoint, adjusted] = detail::resolve_member_function_msvc(&m_function, m_size, object);
object = reinterpret_cast<delegate_generic_class *>(adjusted);
return reinterpret_cast<delegate_generic_function>(entrypoint);
}
} // namespace util::detail
|