<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>Hi Rel,<span><br>
      </span></p>
    <p><span>> 1. Am I doing something wrong in C++ test so that it
        crashes?</span></p>
    <p>I can't say for sure without seeing the struct's definition.<br>
      <br>
      Note though that, there are many cases in which the C and C++ ABIs
      differ. At least for the moment, the FFM linker only supports
      linking using the C ABI, so in order to  reliably call C++, you
      would have to define the C++ functions with C linkage (using
      `extern "C"`).</p>
    <p>> <span>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></p>
    <p><span>The documentation of invokeExact is very general, and
        doesn't cover the FFM's use of method handles in particular. You
        can find a description of the additional SegmentAllocator
        parameter in the documentation of Linker::downcallHandle [1].
        E.g. "</span>... if the function descriptor's return layout is a
      group layout, the resulting downcall method handle accepts an
      additional leading parameter of type SegmentAllocator, which is
      used by the linker runtime to allocate the memory region
      associated with the struct returned by the downcall method handle.
      "</p>
    <p>> 3. Any ideas on how rust-bindgen deals with <span>RVO</span>?</p>
    <p>As far as I know, rust-bindgen only generations functions with C
      linkage, so RVO is not in the picture.<br>
    </p>
    <p><span></span></p>
    <p>Jorn</p>
    <p>[1]:
<a class="moz-txt-link-freetext" href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/foreign/Linker.html#downcallHandle(java.lang.foreign.FunctionDescriptor,java.lang.foreign.Linker.Option...)">https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/foreign/Linker.html#downcallHandle(java.lang.foreign.FunctionDescriptor,java.lang.foreign.Linker.Option...)</a><br>
    </p>
    <div class="moz-cite-prefix">On 24/09/2023 20:10, Rel wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:T0fMEeQsA-CkOmbwFCKU4_llTHmz9pDWM4Pvo7xK8xw2EBAyAPzK5-BbFISuYWyKN9zd6uWjJLLRzpdMMsuZKEkDmvydrmBG_K46LHv6svE=@proton.me">
      
      <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" moz-do-not-send="true" class="moz-txt-link-freetext">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
        <a class="moz-txt-link-rfc2396E" href="mailto:enatai@proton.me"><enatai@proton.me></a> 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
<a class="moz-txt-link-abbreviated" href="mailto:org.openjdk.jextract@21/org.openjdk.jextract.impl.ClassSourceBuilder">org.openjdk.jextract@21/org.openjdk.jextract.impl.ClassSourceBuilder</a>.<init>(ClassSourceBuilder.java:70)</span></div>
            <div><span> at
<a class="moz-txt-link-abbreviated" href="mailto:org.openjdk.jextract@21/org.openjdk.jextract.impl.StructBuilder">org.openjdk.jextract@21/org.openjdk.jextract.impl.StructBuilder</a>.<init>(StructBuilder.java:67)</span></div>
            <div><span> at
<a class="moz-txt-link-abbreviated" href="mailto:org.openjdk.jextract@21/org.openjdk.jextract.impl.StructBuilder">org.openjdk.jextract@21/org.openjdk.jextract.impl.StructBuilder</a>.<init>(StructBuilder.java:62)</span></div>
            <div><span> at
<a class="moz-txt-link-abbreviated" href="mailto:org.openjdk.jextract@21/org.openjdk.jextract.impl.StructBuilder.addStruct">org.openjdk.jextract@21/org.openjdk.jextract.impl.StructBuilder.addStruct</a>(StructBuilder.java:136)</span></div>
            <div><span> at
<a class="moz-txt-link-abbreviated" href="mailto:org.openjdk.jextract@21/org.openjdk.jextract.impl.OutputFactory.visitScoped">org.openjdk.jextract@21/org.openjdk.jextract.impl.OutputFactory.visitScoped</a>(OutputFactory.java:187)</span></div>
            <div><span> at
<a class="moz-txt-link-abbreviated" href="mailto:org.openjdk.jextract@21/org.openjdk.jextract.impl.OutputFactory.visitScoped">org.openjdk.jextract@21/org.openjdk.jextract.impl.OutputFactory.visitScoped</a>(OutputFactory.java:54)</span></div>
            <div><span> at
<a class="moz-txt-link-abbreviated" href="mailto:org.openjdk.jextract@21/org.openjdk.jextract.impl.DeclarationImpl$ScopedImpl.accept">org.openjdk.jextract@21/org.openjdk.jextract.impl.DeclarationImpl$ScopedImpl.accept</a>(DeclarationImpl.java:333)</span></div>
            <div><span> at
<a class="moz-txt-link-abbreviated" href="mailto:org.openjdk.jextract@21/org.openjdk.jextract.impl.OutputFactory.visitVariable">org.openjdk.jextract@21/org.openjdk.jextract.impl.OutputFactory.visitVariable</a>(OutputFactory.java:354)</span></div>
            <div><span> at
<a class="moz-txt-link-abbreviated" href="mailto:org.openjdk.jextract@21/org.openjdk.jextract.impl.OutputFactory.visitVariable">org.openjdk.jextract@21/org.openjdk.jextract.impl.OutputFactory.visitVariable</a>(OutputFactory.java:54)</span></div>
            <div><span> at
<a class="moz-txt-link-abbreviated" href="mailto:org.openjdk.jextract@21/org.openjdk.jextract.impl.DeclarationImpl$VariableImpl.accept">org.openjdk.jextract@21/org.openjdk.jextract.impl.DeclarationImpl$VariableImpl.accept</a>(DeclarationImpl.java:172)</span></div>
            <div><span> at
<a class="moz-txt-link-abbreviated" href="mailto:org.openjdk.jextract@21/org.openjdk.jextract.impl.OutputFactory.lambda$visitScoped$0">org.openjdk.jextract@21/org.openjdk.jextract.impl.OutputFactory.lambda$visitScoped$0</a>(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" moz-do-not-send="true" class="moz-txt-link-freetext">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" moz-do-not-send="true" class="moz-txt-link-freetext">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>
    </blockquote>
  </body>
</html>