jextract C++ support
Rel
enatai at proton.me
Sun Sep 24 18:10:26 UTC 2023
Hi all,
Currently my main focus is to support:
std::string helloWorld();
I managed to generate "some" layout for std::string but I encountered problems of a different level :)
Let's take more simple examples where function will return object and do it for C first:
struct B returnStruct(); // C
My test looks like:
var alloc = SegmentAllocator.slicingAllocator(Arena.ofAuto().allocate(B.sizeof()));
assertEquals(10, A.a$get(B.a$slice(Libcexperiments.returnStruct(alloc))));
It passes.
Now C++ test:
Point2d createPoint2d(); // C++
The way C++ returns objects (struct/class) is not very similar to C. It highly depends on C++ RVO (https://sigcpp.github.io/2020/06/08/return-value-optimization). Currently I try to disable it by compiling libcppexperiments with -fno-elide-constructors and call copy ctors which is generated by the compiler
My test looks like:
var mem = Arena.global().allocate(Point2d.sizeof());
printDump(mem.asByteBuffer());
var pointAlloc = SegmentAllocator.slicingAllocator(mem);
var pointPtr2 = Happy.createPoint2d(pointAlloc);
printDump(mem.asByteBuffer());
The result is:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
happy::Point::Point(this = 0x7fbc2c533f70)
happy::Point2d::Point2d(20, 22)
7fbc2c533f70
30 cd 04 30 bc 7f 00 00 14 00 00 00 16 00 00 00
[x=20,y=22]
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
happy::createPoint2d
happy::Point::Point(this = 0x7fbc33dbddd0)
happy::Point2d::Point2d(2, 3)
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007fbc30049bf9, pid=2704200, tid=2704208
#
# JRE version: OpenJDK Runtime Environment (22.0+12) (build 22-ea+12-877)
# Java VM: OpenJDK 64-Bit Server VM (22-ea+12-877, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# C [libcppexperiments.so+0x2bf9] happy::Point::Point(happy::Point const&)+0x1f
I have two questions:
1.
Am I doing something wrong in C++ test so that it crashes?
2.
It seems that C++ tries to copy data to memory which suppose to be provided by pointAlloc
When jextract (prod version) generates code for such example in C, it expects users to define SegmentAllocator and it passes it to MethodHandle::invokeExact. The documentation of invokeExact is vague and it says that:
> args - the signature-polymorphic parameter list, statically represented using varargs
and does not cover usecase that args may contain SegmentAllocator (I guess it is to allocate memory where returned object will we saved?). Is it done in purpose or I am looking at a wrong documentation and usage of SegmentAllocator in invokeExact described somewhere else?
3.
Any ideas on how rust-bindgen deals with RVO?
Regards,
------- Original Message -------
On Wednesday, September 6th, 2023 at 12:34 AM, Rel <enatai at proton.me> wrote:
> Short updates from me.
>
> I continue working on generating layout for std::string and found that it is failing on cxx branch:
>
> Scoped: TOPLEVEL <toplevel>
> Scoped: STRUCT __mbstate_t layout = [i32(__count)[i32(__wch)|[4:b8](__wchb)](__value)](__mbstate_t)
> Attr: LINK -> []
> Variable: FIELD __count type = Int(layout = i32)
> Variable: FIELD __value type = Declared([i32(__wch)|[4:b8](__wchb)](union (unnamed at enum.h:28:3)))
>
> java.lang.IllegalArgumentException: Invalid member name: union (unnamed at enum.h:28:3)
> at java.base/java.lang.constant.ConstantUtils.validateMemberName(ConstantUtils.java:152)
> at java.base/java.lang.constant.ClassDesc.of(ClassDesc.java:129)
> at org.openjdk.jextract at 21/org.openjdk.jextract.impl.ClassSourceBuilder.<init>(ClassSourceBuilder.java:70)
> at org.openjdk.jextract at 21/org.openjdk.jextract.impl.StructBuilder.<init>(StructBuilder.java:67)
> at org.openjdk.jextract at 21/org.openjdk.jextract.impl.StructBuilder.<init>(StructBuilder.java:62)
> at org.openjdk.jextract at 21/org.openjdk.jextract.impl.StructBuilder.addStruct(StructBuilder.java:136)
> at org.openjdk.jextract at 21/org.openjdk.jextract.impl.OutputFactory.visitScoped(OutputFactory.java:187)
> at org.openjdk.jextract at 21/org.openjdk.jextract.impl.OutputFactory.visitScoped(OutputFactory.java:54)
> at org.openjdk.jextract at 21/org.openjdk.jextract.impl.DeclarationImpl$ScopedImpl.accept(DeclarationImpl.java:333)
> at org.openjdk.jextract at 21/org.openjdk.jextract.impl.OutputFactory.visitVariable(OutputFactory.java:354)
> at org.openjdk.jextract at 21/org.openjdk.jextract.impl.OutputFactory.visitVariable(OutputFactory.java:54)
> at org.openjdk.jextract at 21/org.openjdk.jextract.impl.DeclarationImpl$VariableImpl.accept(DeclarationImpl.java:172)
> at org.openjdk.jextract at 21/org.openjdk.jextract.impl.OutputFactory.lambda$visitScoped$0(OutputFactory.java:201)
>
> But same worked with latest changes in panama branch.
>
> In order to update cxx branch to panama branch I decided to use rebase instead of merge (I see Maurizio was merging them instead). The reason why I did rebase is that way our cpp changes will be always on top of whatever changes were done in panama branch (and not spread across the branch) so it will be easy to track them.
>
> Initially we had following branch:
> cxx - Maurizio initial cpp support
>
> Now I added cxx2 branch which is rebase on latest panama branch with Maurizio changes.
>
> Now, if you remember previously we did mangle only for member functions, and for ordinary functions we had define wrapper manually like:
>
> https://github.com/enatai/panamaexperiments/blob/ec76f9c2d25734a8c9f93f6b4200161b353c81f0/cppexperiments/src/main/java/libcppexperiments/CalcDistance.java
>
> I fixed it so jextract mangles, in case of C++, non member functions too:
>
> https://github.com/enatai/jextractcpp/commit/f1f64e31702b06aa9325546013758ce912f36363
>
> I plan to continue to do my changes in cxx2 branch and keep rebasing it to panama branch once in a while
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/jextract-dev/attachments/20230924/996fca4a/attachment-0001.htm>
More information about the jextract-dev
mailing list