<span>Hi all,</span><div><br></div><div><span>Currently my main focus is to support:</span></div><div><br></div><div><span>std::string helloWorld();</span></div><div><br></div><div><span>I managed to generate "some" layout for std::string but I encountered problems of a different level :)</span></div><div><br></div><div><span>Let's take more simple examples where function will return object and do it for C first:</span></div><div><br></div><div><span>struct B returnStruct(); // C</span></div><div><br></div><div><span>My test looks like:</span></div><div><br></div><div><span> var alloc = SegmentAllocator.slicingAllocator(Arena.ofAuto().allocate(B.sizeof()));</span></div><div><span> assertEquals(10, A.a$get(B.a$slice(Libcexperiments.returnStruct(alloc))));</span></div><div><br></div><div><span>It passes.</span></div><div><br></div><div><span>Now C++ test:</span></div><div><br></div><div><span>Point2d createPoint2d(); // C++</span></div><div><br></div><div><span>The way C++ returns objects (struct/class) is not very similar to C. It highly depends on C++ RVO (<a target="_blank" rel="noreferrer nofollow noopener" href="https://sigcpp.github.io/2020/06/08/return-value-optimization">https://sigcpp.github.io/2020/06/08/return-value-optimization</a>). Currently I try to disable it by compiling libcppexperiments with -fno-elide-constructors and call copy ctors which is generated by the compiler</span></div><div><br></div><div><span>My test looks like:</span></div><div><br></div><div><span> var mem = Arena.global().allocate(Point2d.sizeof());</span></div><div><span> printDump(mem.asByteBuffer());</span></div><div><span> var pointAlloc = SegmentAllocator.slicingAllocator(mem);</span></div><div><span> var pointPtr2 = Happy.createPoint2d(pointAlloc);</span></div><div><span> printDump(mem.asByteBuffer());</span></div><div><br></div><div><span>The result is:</span></div><div><br></div><div><span>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 </span></div><div><span>happy::Point::Point(this = 0x7fbc2c533f70)</span></div><div><span>happy::Point2d::Point2d(20, 22)</span></div><div><span>7fbc2c533f70</span></div><div><span>30 cd 04 30 bc 7f 00 00 14 00 00 00 16 00 00 00 </span></div><div><span>[x=20,y=22]</span></div><div><span>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 </span></div><div><span>happy::createPoint2d</span></div><div><span>happy::Point::Point(this = 0x7fbc33dbddd0)</span></div><div><span>happy::Point2d::Point2d(2, 3)</span></div><div><span>#</span></div><div><span># A fatal error has been detected by the Java Runtime Environment:</span></div><div><span>#</span></div><div><span># SIGSEGV (0xb) at pc=0x00007fbc30049bf9, pid=2704200, tid=2704208</span></div><div><span>#</span></div><div><span># JRE version: OpenJDK Runtime Environment (22.0+12) (build 22-ea+12-877)</span></div><div><span># Java VM: OpenJDK 64-Bit Server VM (22-ea+12-877, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)</span></div><div><span># Problematic frame:</span></div><div><span># C [libcppexperiments.so+0x2bf9] happy::Point::Point(happy::Point const&)+0x1f</span></div><div><br></div><div><span>I have two questions:</span></div><div><br></div><div><span>1.</span></div><div><span>Am I doing something wrong in C++ test so that it crashes?</span></div><div><br></div><div><span>2.</span></div><div><span>It seems that C++ tries to copy data to memory which suppose to be provided by pointAlloc</span></div><div><br></div><div><span>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:</span></div><div><br></div><div><span>> args - the signature-polymorphic parameter list, statically represented using varargs</span></div><div><br></div><div><span>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 <span>SegmentAllocator</span> in <span>invokeExact</span> described somewhere else?</span></div><div style="font-family: Arial, sans-serif; font-size: 14px; color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"><br></div><div style="font-family: Arial, sans-serif; font-size: 14px; color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);">3.</div><div style="font-family: Arial, sans-serif; font-size: 14px; color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);">Any ideas on how rust-bindgen deals with <span>RVO</span>?</div><div style="font-family: Arial, sans-serif; font-size: 14px; color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"><br></div><div style="font-family: Arial, sans-serif; font-size: 14px; color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);">Regards,<br></div><span></span><div class="protonmail_quote">
------- Original Message -------<br>
On Wednesday, September 6th, 2023 at 12:34 AM, Rel <enatai@proton.me> wrote:<br><br>
<blockquote class="protonmail_quote" type="cite">
<div style="font-family: Arial, sans-serif; font-size: 14px;"><span>Short updates from me.</span><div><br></div><div><span>I continue working on generating layout for std::string and found that it is failing on cxx branch:</span></div><div><br></div><div><span>Scoped: TOPLEVEL <toplevel></span></div><div><span> Scoped: STRUCT __mbstate_t layout = [i32(__count)[i32(__wch)|[4:b8](__wchb)](__value)](__mbstate_t)</span></div><div><span> Attr: LINK -> []</span></div><div><span> Variable: FIELD __count type = Int(layout = i32)</span></div><div><span> Variable: FIELD __value type = Declared([i32(__wch)|[4:b8](__wchb)](union (unnamed at enum.h:28:3)))</span></div><div><br></div><div><span>java.lang.IllegalArgumentException: Invalid member name: union (unnamed at enum.h:28:3)</span></div><div><span> at java.base/java.lang.constant.ConstantUtils.validateMemberName(ConstantUtils.java:152)</span></div><div><span> at java.base/java.lang.constant.ClassDesc.of(ClassDesc.java:129)</span></div><div><span> at org.openjdk.jextract@21/org.openjdk.jextract.impl.ClassSourceBuilder.<init>(ClassSourceBuilder.java:70)</span></div><div><span> at org.openjdk.jextract@21/org.openjdk.jextract.impl.StructBuilder.<init>(StructBuilder.java:67)</span></div><div><span> at org.openjdk.jextract@21/org.openjdk.jextract.impl.StructBuilder.<init>(StructBuilder.java:62)</span></div><div><span> at org.openjdk.jextract@21/org.openjdk.jextract.impl.StructBuilder.addStruct(StructBuilder.java:136)</span></div><div><span> at org.openjdk.jextract@21/org.openjdk.jextract.impl.OutputFactory.visitScoped(OutputFactory.java:187)</span></div><div><span> at org.openjdk.jextract@21/org.openjdk.jextract.impl.OutputFactory.visitScoped(OutputFactory.java:54)</span></div><div><span> at org.openjdk.jextract@21/org.openjdk.jextract.impl.DeclarationImpl$ScopedImpl.accept(DeclarationImpl.java:333)</span></div><div><span> at org.openjdk.jextract@21/org.openjdk.jextract.impl.OutputFactory.visitVariable(OutputFactory.java:354)</span></div><div><span> at org.openjdk.jextract@21/org.openjdk.jextract.impl.OutputFactory.visitVariable(OutputFactory.java:54)</span></div><div><span> at org.openjdk.jextract@21/org.openjdk.jextract.impl.DeclarationImpl$VariableImpl.accept(DeclarationImpl.java:172)</span></div><div><span> at org.openjdk.jextract@21/org.openjdk.jextract.impl.OutputFactory.lambda$visitScoped$0(OutputFactory.java:201)</span></div><div><br></div><div><span>But same worked with latest changes in panama branch.</span></div><div><br></div><div><span>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.</span></div><div><br></div><div><span>Initially we had following branch:</span></div><div><span>cxx - Maurizio initial cpp support</span></div><div><br></div><div><span>Now I added cxx2 branch which is rebase on latest panama branch with Maurizio changes.<br></span></div><div><br></div><div><span>Now, if
you remember previously we did mangle only for member functions, and
for ordinary functions we had define wrapper manually like:</span></div><div><br></div><div><span><a target="_blank" rel="noreferrer nofollow noopener" href="https://github.com/enatai/panamaexperiments/blob/ec76f9c2d25734a8c9f93f6b4200161b353c81f0/cppexperiments/src/main/java/libcppexperiments/CalcDistance.java">https://github.com/enatai/panamaexperiments/blob/ec76f9c2d25734a8c9f93f6b4200161b353c81f0/cppexperiments/src/main/java/libcppexperiments/CalcDistance.java</a></span></div><div><br></div><div><span>I fixed it so jextract mangles, in case of C++, non member functions too:</span></div><div><br></div><div><span><a target="_blank" rel="noreferrer nofollow noopener" href="https://github.com/enatai/jextractcpp/commit/f1f64e31702b06aa9325546013758ce912f36363">https://github.com/enatai/jextractcpp/commit/f1f64e31702b06aa9325546013758ce912f36363</a></span></div><span></span><div><br></div><div><span>I plan to continue to do my changes in cxx2 branch and keep rebasing it to panama branch once in a while</span></div><br></div>
</blockquote><br>
</div>