Skip to content

[interop] Make the cling work with -fmodules - #157

Open
keremsahn wants to merge 2 commits into
compiler-research:mainfrom
keremsahn:cling-modules
Open

keremsahn wants to merge 2 commits into
compiler-research:mainfrom
keremsahn:cling-modules

Conversation

@keremsahn

Copy link
Copy Markdown
Contributor

Built upon #114, just look at the second commit
@vgvassilev @Vipul-Cariappa

…ing memory

Added an AllocType field on CPPMethod, cached from Cpp::IsAllocator, that now
decides the ownership of a returned object. The overloads of a group share
fMethodInfo, so the answer of the called overload stays in a local instead of
going into the shared kIsCreator flag, which nothing ever clears. The analyzer
is not called; this is the attribute-checker path only.

AllocType was collapsed into kIsCreator and never reached op_dealloc_nofree, so
malloc'd, new[]'d and raw operator-new'd memory were all freed with a scalar
delete. It now rides on the instance as kIsArrayAlloc, kIsNoConstruct and
kIsMalloc; op_dealloc_nofree branches on them to delete[], free,
::operator delete or ::operator delete[], with no destructor for the raw cases.
All flags clear keeps the old delete path. bind_object carries those flags to
the new proxy along with the ownership, as BindCppObjectNoCast() masks them out,
so a cast object frees its memory the way it was allocated.

Mirrored that with Cpp::IsDeallocator, cached the same way, and passed the call
arguments to HandleReturn: handing a Python-owned instance to an
ownership-taking function now gives ownership back to C++ instead of leaving it
to be freed twice.

IsDeallocator reports one DeallocType per parameter, so every argument of a call
is matched to the parameter that the attribute labels. A positional argument
finds its slot from its place in the args array, and a keyword argument from its
name in the signature. Two shifts turn either number into a slot, because an
implicit object parameter and the shape of the call each move it:
GetDeallocArgShift() answers for the args array and GetDeallocParamShift() for
the declaration. CPPMethod, CPPFunction and CPPClassMethod answer both for their
own kind of callee, and the defaults on PyCallable keep every other callable out
of this path.

The interop layer carries what the above needs. interop::AllocType and
interop::DeallocType name the CppInterOp enums, and IsAllocator() and
IsDeallocator() join their neighbours in the wrapper, each holding the
interpreter mutex. interop::Destruct() takes an object count, which it used to
pin to 0; a count other than 0 makes the CppInterOp destructor wrapper run
delete[] in place of delete, which is what the array path wants.
CPPINTEROP_GIT_TAG moves to the CppInterOp commit that carries those two entry
points, and test/Makefile builds the memory_analysis dictionary.

Ownership is only released, never nullified: the instance keeps a stale pointer
after the callee frees the memory.

GetAllocBehaviour is restricted to raw-pointer returns.

Exposed read-only __is_array_alloc__ / __is_no_construct__ / __is_malloc__ and
added tests for the deallocation paths and for ownership release via free, via
an ownership_takes function, and the negative case. An attribute reaches the
tests three ways: a clang::annotate on the declaration, a redeclaration that
carries it, and APINotes behind a module map. The release tests cover the bound,
unbound and stored-bound forms of a member method, a static method and a free
function, each in a positional and a keyword shape, a keyword shape with the
names reversed, an argument that is no object at all, a cppDeallocNone
parameter, a Python overload that carries no attribute, and a cast through
bind_object.
Cling looks for its module maps next to RuntimeUniverse.h, which it finds
through argv[0]. That is the host python, so collectModuleMaps asserts. Pass
cling's own include directory as -I.

Preload stdint.h and cstdlib first, so Dispatch.h does not redefine what
cling's libc module already declared.

test00_driver now runs on linux with cling.

@vgvassilev vgvassilev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does that work in clang-repl too?

@keremsahn

Copy link
Copy Markdown
Contributor Author

Does that work in clang-repl too?

Yes it only effects cling builds, basically pushes a necessary dir to interpreter_args if found

@vgvassilev

Copy link
Copy Markdown
Contributor

Does that work in clang-repl too?

Yes it only effects cling builds, basically pushes a necessary dir to interpreter_args if found

I meant to ask whether the same feature will work under clang-repl powered CppInterOp.

@keremsahn

Copy link
Copy Markdown
Contributor Author

Does that work in clang-repl too?

Yes it only effects cling builds, basically pushes a necessary dir to interpreter_args if found

I meant to ask whether the same feature will work under clang-repl powered CppInterOp.

What feature? This commit solves a problem of cling, does not add any feature

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants