10
10
#ifndef CPPINTEROP_CPPINTEROP_H
11
11
#define CPPINTEROP_CPPINTEROP_H
12
12
13
+ #include < cassert>
13
14
#include < string>
14
15
#include < vector>
15
16
@@ -18,11 +19,98 @@ namespace Cpp {
18
19
using TCppScope_t = void *;
19
20
using TCppType_t = void *;
20
21
using TCppFunction_t = void *;
22
+ using TCppConstFunction_t = const void *;
21
23
using TCppFuncAddr_t = void *;
22
24
using TCppSema_t = void *;
23
25
using TInterp_t = void *;
24
26
using TCppObject_t = void *;
25
- typedef void (*CallFuncWrapper_t)(void *, int , void **, void *);
27
+ // / A class modeling function calls for functions produced by the interpreter
28
+ // / in compiled code. It provides an information if we are calling a standard
29
+ // / function, constructor or destructor.
30
+ class JitCall {
31
+ public:
32
+ friend JitCall MakeFunctionCallable (TInterp_t, TCppConstFunction_t);
33
+ enum Kind : char {
34
+ kUnknown = 0 ,
35
+ kGenericCall ,
36
+ kDestructorCall ,
37
+ };
38
+ struct ArgList {
39
+ void ** m_Args = nullptr ;
40
+ size_t m_ArgSize = 0 ;
41
+ // Clang struggles with =default...
42
+ ArgList () : m_Args(nullptr ), m_ArgSize(0 ) {}
43
+ ArgList (void ** Args, size_t ArgSize)
44
+ : m_Args(Args), m_ArgSize(ArgSize) {}
45
+ };
46
+ // FIXME: Figure out how to unify the wrapper signatures.
47
+ // FIXME: Hide these implementation details by moving wrapper generation in
48
+ // this class.
49
+ using GenericCall = void (*)(void *, int , void **, void *);
50
+ using DestructorCall = void (*)(void *, unsigned long , int );
51
+ private:
52
+ union {
53
+ GenericCall m_GenericCall;
54
+ DestructorCall m_DestructorCall;
55
+ };
56
+ const Kind m_Kind;
57
+ TCppConstFunction_t m_FD;
58
+ JitCall () : m_Kind(kUnknown ), m_GenericCall(nullptr ), m_FD(nullptr ) {}
59
+ JitCall (Kind K, GenericCall C, TCppConstFunction_t FD)
60
+ : m_Kind(K), m_GenericCall(C), m_FD(FD) {}
61
+ JitCall (Kind K, DestructorCall C, TCppConstFunction_t Dtor)
62
+ : m_Kind(K), m_DestructorCall(C), m_FD(Dtor) {}
63
+ bool AreArgumentsValid (void * result, ArgList args, void * self) const ;
64
+ void ReportInvokeStart (void * result, ArgList args, void * self) const ;
65
+ void ReportInvokeStart (void * object, unsigned long nary,
66
+ int withFree) const ;
67
+ void ReportInvokeEnd () const ;
68
+ public:
69
+ Kind getKind () const { return m_Kind; }
70
+ bool isValid () const { return getKind () != kUnknown ; }
71
+ bool isInvalid () const { return !isValid (); }
72
+ explicit operator bool () const { return isValid (); }
73
+
74
+ // Specialized for calling void functions.
75
+ void Invoke (ArgList args = {}, void * self = nullptr ) const {
76
+ Invoke (/* result=*/ nullptr , args, self);
77
+ }
78
+
79
+ // / Makes a call to a generic function or method.
80
+ // /\param[in] result - the location where the return result will be placed.
81
+ // /\param[in] args - a pointer to a argument list and argument size.
82
+ // /\param[in] self - the this pointer of the object.
83
+ // FIXME: Adjust the arguments and their types: args_size can be unsigned;
84
+ // self can go in the end and be nullptr by default; result can be a nullptr
85
+ // by default. These changes should be syncronized with the wrapper if we
86
+ // decide to directly.
87
+ void Invoke (void * result, ArgList args = {}, void * self = nullptr ) const {
88
+ // Forward if we intended to call a dtor with only 1 parameter.
89
+ if (m_Kind == kDestructorCall && result && !args.m_Args )
90
+ return InvokeDestructor (result, /* nary=*/ 0UL , /* withFree=*/ true );
91
+
92
+ #ifndef NDEBUG
93
+ assert (AreArgumentsValid (result, args, self) && " Invalid args!" );
94
+ ReportInvokeStart (result, args, self);
95
+ #endif // NDEBUG
96
+ m_GenericCall (self, args.m_ArgSize , args.m_Args , result);
97
+ }
98
+ // / Makes a call to a destructor.
99
+ // /\param[in] object - the pointer of the object whose destructor we call.
100
+ // /\param[in] nary - the count of the objects we destruct if we deal with an
101
+ // / array of objects.
102
+ // /\param[in] withFree - true if we should call operator delete or false if
103
+ // / we should call only the destructor.
104
+ // FIXME: Change the type of withFree from int to bool in the wrapper code.
105
+ void InvokeDestructor (void * object, unsigned long nary = 0 ,
106
+ int withFree = true ) const {
107
+ assert (m_Kind == kDestructorCall && " Wrong overload!" );
108
+ #ifndef NDEBUG
109
+ ReportInvokeStart (object, nary, withFree);
110
+ #endif // NDEBUG
111
+ m_DestructorCall (object, nary, withFree);
112
+ }
113
+ };
26
114
27
115
// / Enables or disables the debugging printouts on stderr.
28
116
void EnableDebugOutput (bool value = true );
@@ -109,9 +197,14 @@ namespace Cpp {
109
197
std::vector<TCppFunction_t> GetClassMethods (TCppSema_t sema,
110
198
TCppScope_t klass);
111
199
200
+ // /\returns if a class has a default constructor.
112
201
bool HasDefaultConstructor (TCppScope_t scope);
113
202
114
- TCppScope_t GetDestructor (TCppScope_t scope);
203
+ // /\returns the default constructor of a class if any.
204
+ TCppFunction_t GetDefaultConstructor (TCppSema_t sema, TCppScope_t scope);
205
+
206
+ // /\returns the class destructor.
207
+ TCppFunction_t GetDestructor (TCppScope_t scope);
115
208
116
209
std::vector<TCppFunction_t> GetFunctionsUsingName (TCppSema_t sema,
117
210
TCppScope_t scope,
@@ -121,7 +214,7 @@ namespace Cpp {
121
214
122
215
TCppIndex_t GetFunctionNumArgs (TCppFunction_t func);
123
216
124
- TCppIndex_t GetFunctionRequiredArgs (TCppFunction_t func);
217
+ TCppIndex_t GetFunctionRequiredArgs (TCppConstFunction_t func);
125
218
126
219
TCppType_t GetFunctionArgType (TCppFunction_t func, TCppIndex_t iarg);
127
220
@@ -134,15 +227,17 @@ namespace Cpp {
134
227
bool ExistsFunctionTemplate (TCppSema_t sema, const std::string &name,
135
228
TCppScope_t parent = 0 );
136
229
230
+ bool IsMethod (TCppConstFunction_t method);
231
+
137
232
bool IsPublicMethod (TCppFunction_t method);
138
233
139
234
bool IsProtectedMethod (TCppFunction_t method);
140
235
141
236
bool IsPrivateMethod (TCppFunction_t method);
142
237
143
- bool IsConstructor (TCppFunction_t method);
238
+ bool IsConstructor (TCppConstFunction_t method);
144
239
145
- bool IsDestructor (TCppFunction_t method);
240
+ bool IsDestructor (TCppConstFunction_t method);
146
241
147
242
bool IsStaticMethod (TCppFunction_t method);
148
243
@@ -188,8 +283,9 @@ namespace Cpp {
188
283
// / Check if a C++ type derives from another.
189
284
bool IsTypeDerivedFrom (TInterp_t interp, TCppType_t derived, TCppType_t base);
190
285
191
- CallFuncWrapper_t GetFunctionCallWrapper (TInterp_t interp,
192
- TCppFunction_t func);
286
+ // / Creates a trampoline function by using the interpreter and returns a
287
+ // / uniform interface to call it from compiled code.
288
+ JitCall MakeFunctionCallable (TInterp_t interp, TCppConstFunction_t func);
193
289
194
290
// / Checks if a function declared is of const type or not
195
291
bool IsConstMethod (TCppFunction_t method);
0 commit comments