-
Notifications
You must be signed in to change notification settings - Fork 31
Add support for array of objects in Construct/Destruct #587
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
a6a4a15
1e81d51
1251662
eb843f2
d90fe11
4072038
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -103,6 +103,7 @@ | |
enum Kind : char { | ||
kUnknown = 0, | ||
kGenericCall, | ||
kConstructorCall, | ||
kDestructorCall, | ||
}; | ||
struct ArgList { | ||
|
@@ -115,25 +116,32 @@ | |
// FIXME: Figure out how to unify the wrapper signatures. | ||
// FIXME: Hide these implementation details by moving wrapper generation in | ||
// this class. | ||
// (self, nargs, args, result, nary) | ||
using GenericCall = void (*)(void*, size_t, void**, void*); | ||
using DestructorCall = void (*)(void*, unsigned long, int); | ||
// (result, nary, nargs, args, is_arena) | ||
using ConstructorCall = void (*)(void*, size_t, size_t, void**, void*); | ||
// (self, nary, withFree) | ||
using DestructorCall = void (*)(void*, size_t, int); | ||
|
||
private: | ||
union { | ||
GenericCall m_GenericCall; | ||
ConstructorCall m_ConstructorCall; | ||
DestructorCall m_DestructorCall; | ||
}; | ||
Kind m_Kind; | ||
TCppConstFunction_t m_FD; | ||
JitCall() : m_GenericCall(nullptr), m_Kind(kUnknown), m_FD(nullptr) {} | ||
JitCall(Kind K, GenericCall C, TCppConstFunction_t FD) | ||
: m_GenericCall(C), m_Kind(K), m_FD(FD) {} | ||
JitCall(Kind K, ConstructorCall C, TCppConstFunction_t Ctor) | ||
: m_ConstructorCall(C), m_Kind(K), m_FD(Ctor) {} | ||
JitCall(Kind K, DestructorCall C, TCppConstFunction_t Dtor) | ||
: m_DestructorCall(C), m_Kind(K), m_FD(Dtor) {} | ||
|
||
/// Checks if the passed arguments are valid for the given function. | ||
CPPINTEROP_API bool AreArgumentsValid(void* result, ArgList args, | ||
void* self) const; | ||
CPPINTEROP_API bool AreArgumentsValid(void* result, ArgList args, void* self, | ||
size_t nary) const; | ||
|
||
/// This function is used for debugging, it reports when the function was | ||
/// called. | ||
|
@@ -164,17 +172,34 @@ | |
// decide to directly. | ||
void Invoke(void* result, ArgList args = {}, void* self = nullptr) const { | ||
// NOLINTBEGIN(*-type-union-access) | ||
// Forward if we intended to call a dtor with only 1 parameter. | ||
if (m_Kind == kDestructorCall && result && !args.m_Args) { | ||
InvokeDestructor(result, /*nary=*/0UL, /*withFree=*/true); | ||
return; | ||
} | ||
// Its possible the JitCall object deals with structor decls but went | ||
// through Invoke | ||
|
||
switch (m_Kind) { | ||
case kUnknown: | ||
assert(0 && "Attempted to call an invalid function declaration"); | ||
break; | ||
|
||
case kGenericCall: | ||
#ifndef NDEBUG | ||
assert(AreArgumentsValid(result, args, self) && "Invalid args!"); | ||
ReportInvokeStart(result, args, self); | ||
// We pass 1UL to nary which is only relevant for structors | ||
assert(AreArgumentsValid(result, args, self, 1UL) && "Invalid args!"); | ||
ReportInvokeStart(result, args, self); | ||
#endif // NDEBUG | ||
m_GenericCall(self, args.m_ArgSize, args.m_Args, result); | ||
m_GenericCall(self, args.m_ArgSize, args.m_Args, result); | ||
break; | ||
|
||
case kConstructorCall: | ||
// Forward if we intended to call a constructor (nary cannot be inferred, | ||
// so we stick to constructing a single object) | ||
InvokeConstructor(result, /*nary=*/1UL, args, self); | ||
break; | ||
case kDestructorCall: | ||
// Forward if we intended to call a dtor with only 1 parameter. | ||
assert(!args.m_Args && "Destructor called with arguments"); | ||
InvokeDestructor(result, /*nary=*/0UL, /*withFree=*/true); | ||
break; | ||
} | ||
// NOLINTEND(*-type-union-access) | ||
} | ||
/// Makes a call to a destructor. | ||
|
@@ -192,6 +217,24 @@ | |
#endif // NDEBUG | ||
m_DestructorCall(object, nary, withFree); | ||
} | ||
|
||
/// Makes a call to a constructor. | ||
///\param[in] result - the memory address at which we construct the object | ||
/// (placement new). | ||
///\param[in] nary - Use array new if we have to construct an array of | ||
/// objects (nary > 1). | ||
///\param[in] args - a pointer to a argument list and argument size. | ||
// FIXME: Change the type of withFree from int to bool in the wrapper code. | ||
void InvokeConstructor(void* result, unsigned long nary = 1, | ||
ArgList args = {}, void* is_arena = nullptr) const { | ||
assert(m_Kind == kConstructorCall && "Wrong overload!"); | ||
#ifndef NDEBUG | ||
assert(AreArgumentsValid(result, args, /*self=*/nullptr, nary) && | ||
"Invalid args!"); | ||
ReportInvokeStart(result, args, nullptr); | ||
#endif // NDEBUG | ||
aaronj0 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
m_ConstructorCall(result, nary, args.m_ArgSize, args.m_Args, is_arena); | ||
aaronj0 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
}; | ||
|
||
///\returns the version string information of the library. | ||
|
@@ -791,20 +834,36 @@ | |
/// Gets the size/dimensions of a multi-dimension array. | ||
CPPINTEROP_API std::vector<long int> GetDimensions(TCppType_t type); | ||
|
||
/// Allocates memory for a given class. | ||
CPPINTEROP_API TCppObject_t Allocate(TCppScope_t scope); | ||
/// Allocates memory required by an object of a given class | ||
/// \c scope Given class for which to allocate memory for | ||
/// \c count is used to indicate the number of objects to allocate for. | ||
CPPINTEROP_API TCppObject_t Allocate(TCppScope_t scope, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: enum '(unnamed enum at /github/workspace/include/CppInterOp/CppInterOp.h:802:1)' uses a larger base type ('long', size: 8 bytes) than necessary for its value set, consider using 'std::int8_t' (1 byte) as the base type to reduce its size [performance-enum-size] enum : long int {
^ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should adjust the types to match the signature types to match the generated code types and disable the clang-tidy complaints if we have to. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This enum is unrelated to this PR or |
||
TCppIndex_t count = 1UL); | ||
|
||
/// Deallocates memory for a given class. | ||
CPPINTEROP_API void Deallocate(TCppScope_t scope, TCppObject_t address); | ||
|
||
/// Creates an object of class \c scope and calls its default constructor. If | ||
/// \c arena is set it uses placement new. | ||
CPPINTEROP_API TCppObject_t Construct(TCppScope_t scope, void* arena = nullptr); | ||
|
||
/// Calls the destructor of object of type \c type. When withFree is true it | ||
/// calls operator delete/free. | ||
/// \c scope Class to indicate size of memory to deallocate | ||
/// \c count is used to indicate the number of objects to dallocate for | ||
CPPINTEROP_API void Deallocate(TCppScope_t scope, TCppObject_t address, | ||
TCppIndex_t count = 1UL); | ||
|
||
/// Creates one or more objects of class \c scope by calling its default | ||
/// constructor. | ||
/// \param[in] scope Class to construct | ||
/// \param[in] arena If set, this API uses placement new to construct at this | ||
/// address. | ||
/// \param[in] is used to indicate the number of objects to construct. | ||
CPPINTEROP_API TCppObject_t Construct(TCppScope_t scope, void* arena = nullptr, | ||
TCppIndex_t count = 1UL); | ||
|
||
/// Destroys one or more objects of a class | ||
/// \param[in] This this pointer of the object to destruct. Can also be the | ||
/// starting address of an array of objects | ||
/// \param[in] withFree if true, we call operator delete/free, else just the | ||
/// destructor | ||
/// \param[in] count indicate the number of objects to destruct, if \c This | ||
/// points to an array of objects | ||
CPPINTEROP_API void Destruct(TCppObject_t This, TCppScope_t type, | ||
bool withFree = true); | ||
bool withFree = true, TCppIndex_t count = 0UL); | ||
aaronj0 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/// @name Stream Redirection | ||
/// | ||
|
Uh oh!
There was an error while loading. Please reload this page.