[graalvm-users] [External] : Re: c++ bytecode from java

Roland Schatz roland.schatz at oracle.com
Mon Feb 1 05:33:10 PST 2021


"--llvm.C++Interop" is an option for the GraalVM LLVM Runtime, not for 
compiler.

You need to pass it to the GraalVM launcher (e.g. lli):
lli --llvm.C++Interop <bitcode file>

Or if you're embedding it in a Java application, you can pass the option 
to the ContextBuilder:

|Context polyglot = Context.newBuilder() .allowExperimentalOptions(true) 
.option("llvm.C++Interop", "true") .allowAllAccess(true).build(); |

- Roland

On 1/29/21 7:29 PM, Darrell Schiebel wrote:
> Thanks very much for your reply. It was very useful information, but I 
> haven't been able to get the "--llvm.C++Interop" flag to be accepted:
>
>     bash$ type clang++
>
>     clang++ is hashed
>     (/Library/Java/JavaVirtualMachines/graalvm-ee-java8-21.0.0/Contents/Home/jre/languages/llvm/native/bin/clang++)
>
>     bash$ clang++ -g --llvm.C++Interop -std=c++11 -shared -o
>     methodsTest.so methodsTest.cpp -lgraalvm-llvm
>
>     clang-10: *error: *unsupported option '--llvm.C++Interop'
>
>     clang-10: *error: *unsupported option '--llvm.C++Interop'
>
>     bash$
>
>
> So I'm not sure if this is a new flag that has not made it into 
> production or if it is an old flag that has been retired.
>
> I appreciate the work that's gone into GraalVM. It will be great if it 
> provides a way to integrate legacy systems into a modern ecosystem.
>
> Darrell
>
>
> On Tue, Jan 26, 2021 at 12:50 PM Roland Schatz 
> <roland.schatz at oracle.com <mailto:roland.schatz at oracle.com>> wrote:
>
>     Hi,
>
>     The interop support for C++ is currently work in progress, some
>     things work already, others not yet.
>     Some of the C++ interop features are behind a flag, try passing
>     "--llvm.C++Interop".
>
>     Calling constructors and non-virtual methods should work already.
>     There is a WIP PR for virtual method calls:
>     https://github.com/oracle/graal/pull/2932
>     <https://urldefense.com/v3/__https://github.com/oracle/graal/pull/2932__;!!GqivPVa7Brio!IwKBSALxE-CiB-oAQ46lEv4ZRCdDpz5VCpAQi9MxhHvSiPMwOx9W02hUi2cQ_AQuCwg$>
>
>     C++ interop is a very recent feature and doesn't have many users
>     yet, so there might be bugs.
>
>     Some more comments inline below...
>
>     On 1/25/21 10:48 PM, Darrell Schiebel wrote:
>>     Hello,
>>
>>     I'm trying to understand the capabilities and limitations of
>>     using C++ libraries from Java. One of the more complete examples
>>     I could find was the:
>>
>>      *
>>
>>         CxxMethodsTest.java/methodsTest.cpp
>>
>>     test from the GraalVM distribution. I removed the unit test
>>     framework, but I find that there are some operations which fail
>>     (in Java):
>>
>>      1. retrieving a class: testLibrary.getMember("Point")
>>
>     That should already work. You should be able to use to create
>     instances of "Point" (with `point.newInstance(...)`).
>     It might be that this needs the "--llvm.C++Interop" flag though.
>
>>      1. retrieving a class method: squaredEuclideanDistance =
>>         testLibrary.getMember("squaredEuclideanDistance")
>>
>     That doesn't work since "squaredEuclideanDistance" is not a global
>     function. If you have an instance of "Point", you should be able
>     to `point.getMember("squaredEuclideanDistance")` and execute the
>     result, or just use
>     `point.invokeMember("squaredEuclideanDistance", ...)` to directly
>     invoke methods.
>
>>      1. invoking a class member: testLibrary.invokeMember("setY",
>>         point2, 8)
>>
>     Same thing. This needs to be `point2.invokeMember("setY", 8)`.
>
>>     I am using GraalVM 21.0.0, and I compiled the C++ like:
>>
>>      *
>>
>>         clang++ -std=c++11 -shared -o methodsTest.so methodsTest.cpp
>>         -lgraalvm-llvm
>>
>>     I suppose maybe the testing framework may compile the C++ source
>>     code differently. Any idea where I've gone astray?
>
>     Is that "clang++" from the toolchain we ship with GraalVM? If yes,
>     then that's the correct way to build.
>
>     If no: If you want to use interop (both C++ or C), you need to
>     compile with debug info enabled. Also note that we currently only
>     support libc++ (the one from the LLVM project), not libstdc++ (the
>     one from GCC, which is the default on most Linux systems).
>
>     You can get the path to our toolchain using "lli
>     --print-toolchain-path" (you might have to install it using "gu
>     install llvm-toolchain", it's an optional component since you
>     don't need it at runtime). The "clang++" from there automatically
>     sets the correct flags. You can use "-v" to see what exactly it does.
>
>
>
>>     I think they may compile without name mangling or perhaps they
>>     compile the cpp file on the fly... I don't know exactly what
>>     happens behind the scenes with:
>>
>>      *
>>
>>         testLibrary = loadTestBitcodeValue("methodsTest.cpp")
>>
>     That's just some path manipulation to locate .so file for that
>     test, which is somewhere under mxbuild in a directory called
>     "methodsTest.cpp.dir". It doesn't do any compilation, that is done
>     using mx and make.
>
>>     My modified methodsTest.cpp file is down below.
>>
>>     It seems like these are the key points:
>>
>>       * pointers should be used to pass/return objects (no mapping
>>         from List<T> to std::list<T> for example)
>>
>     Correct, currently we don't support by-value arguments in interop
>     (except primitives of course). Everything must be pointers. Not
>     sure about C++ references, they should work in principle, since in
>     bitcode they are also just pointers. But I've never tried to be
>     honest.
>
>>       * mangled names do not work (unless the mangled name is used
>>         for lookup, of course)
>>
>     With the "--llvm.C++Interop" flag that should work. We read the
>     unmangled names from the debug info.
>     This probably only works if there is no name conflict with the
>     unmangled name, i.e. no overloading.
>
>>       * class based inherited methods work (using an object pointer)
>>       * looking up methods and supplying the object and args does not
>>         work (e.g. squareEuclideanDistance above)
>>       * retrieving object constructor as a function (e.g.
>>         getMember("Point") above)
>>
>>     Does this seem right? I've looked at the examples I could find on
>>     the GraalVM.org website but are there any bigger examples of
>>     Java/C++ integration via GraalVM?
>     Since this is a work in progress feature, we don't have any
>     published examples for C++ yet.
>
>     Most of our users are only using C-based interfaces, even if the
>     actual implementation behind the interface is in C++. That is of
>     course a workaround you can use right now, but not a nice one.
>     We'll probably publish more examples once we reach a more complete
>     state of our C++ interop implementation.
>
>
>     As I wrote in the beginning, all of this is pretty new, so not
>     everything might work out of the box. You're welcome to play
>     around with it, and if you get stuck, feel free to ask questions
>     or report issues!
>
>
>     - Roland
>
>>
>>     thanks for any advice,
>>     Darrell
>>
>>     /*
>>      * Copyright (c) 2020, Oracle and/or its affiliates.
>>      *
>>      * All rights reserved.
>>      *
>>      * Redistribution and use in source and binary forms, with or
>>     without modification, are
>>      * permitted provided that the following conditions are met:
>>      *
>>      * 1. Redistributions of source code must retain the above
>>     copyright notice, this list of
>>      * conditions and the following disclaimer.
>>      *
>>      * 2. Redistributions in binary form must reproduce the above
>>     copyright notice, this list of
>>      * conditions and the following disclaimer in the documentation
>>     and/or other materials provided
>>      * with the distribution.
>>      *
>>      * 3. Neither the name of the copyright holder nor the names of
>>     its contributors may be used to
>>      * endorse or promote products derived from this software without
>>     specific prior written
>>      * permission.
>>      *
>>      * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
>>     CONTRIBUTORS "AS IS" AND ANY EXPRESS
>>      * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
>>     IMPLIED WARRANTIES OF
>>      * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>>     DISCLAIMED. IN NO EVENT SHALL THE
>>      * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
>>     INDIRECT, INCIDENTAL, SPECIAL,
>>      * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>>     LIMITED TO, PROCUREMENT OF SUBSTITUTE
>>      * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
>>     INTERRUPTION) HOWEVER CAUSED
>>      * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
>>     LIABILITY, OR TORT (INCLUDING
>>      * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
>>     THIS SOFTWARE, EVEN IF ADVISED
>>      * OF THE POSSIBILITY OF SUCH DAMAGE.
>>      */
>>     #include <graalvm/llvm/polyglot.h>
>>     #include <stdlib.h>
>>     #include <math.h>
>>
>>     #define EXTERN extern "C"
>>
>>     class Point {
>>     protected:
>>         int x;
>>         int y;
>>
>>     public:
>>         Point();
>>         int getX();
>>         int getY();
>>         void setX(int val);
>>         void setY(int val);
>>         double squaredEuclideanDistance(Point *other);
>>     };
>>
>>     POLYGLOT_DECLARE_TYPE(Point)
>>
>>     class XtendPoint : public Point {
>>     private:
>>         int z;
>>
>>     public:
>>         XtendPoint();
>>         int getZ();
>>         void setZ(int val);
>>         int getZ(int constant);
>>         int getX();
>>     };
>>
>>     POLYGLOT_DECLARE_TYPE(XtendPoint)
>>
>>     //class methods
>>
>>     Point::Point() {
>>         x = 0;
>>         y = 0;
>>     }
>>
>>     int Point::getX() {
>>         return x;
>>     }
>>
>>     int Point::getY() {
>>         return y;
>>     }
>>
>>     void Point::setX(int val) {
>>         x = val;
>>     }
>>
>>     void Point::setY(int val) {
>>         y = val;
>>     }
>>
>>     double Point::squaredEuclideanDistance(Point *other) {
>>         double dX = (double) (x - other->x);
>>         double dY = (double) (y - other->y);
>>         return dX * dX + dY * dY;
>>     }
>>
>>     XtendPoint::XtendPoint() {
>>         z = 0;
>>     }
>>
>>     int XtendPoint::getZ() {
>>         return z;
>>     }
>>
>>     void XtendPoint::setZ(int dZ) {
>>         z = dZ;
>>     }
>>
>>     int XtendPoint::getZ(int constantOffset) {
>>         return z + constantOffset;
>>     }
>>
>>     int XtendPoint::getX() {
>>         return x * 2;
>>     }
>>
>>     //functions
>>     EXTERN void *allocNativePoint() {
>>         Point *ret = (Point *) malloc(sizeof(*ret));
>>         return polyglot_from_Point(ret);
>>     }
>>
>>     EXTERN void *allocNativeXtendPoint() {
>>         XtendPoint *ret = (XtendPoint *) malloc(sizeof(*ret));
>>         return polyglot_from_XtendPoint(ret);
>>     }
>>
>>     EXTERN void swap(Point *p, Point *q) {
>>         Point tmp = *q;
>>         *q = *p;
>>         *p = tmp;
>>     }
>>
>>     EXTERN void freeNativePoint(Point *p) {
>>         free(p);
>>     }
>>
>>     EXTERN void freeNativeXtendPoint(XtendPoint *p) {
>>         free(p);
>>     }
>>
>>
>>     _______________________________________________
>>     GraalVM-Users mailing list
>>     GraalVM-Users at oss.oracle.com  <mailto:GraalVM-Users at oss.oracle.com>
>>     https://oss.oracle.com/mailman/listinfo/graalvm-users  <https://oss.oracle.com/mailman/listinfo/graalvm-users>
>
>
>     _______________________________________________
>     GraalVM-Users mailing list
>     GraalVM-Users at oss.oracle.com <mailto:GraalVM-Users at oss.oracle.com>
>     https://oss.oracle.com/mailman/listinfo/graalvm-users
>     <https://oss.oracle.com/mailman/listinfo/graalvm-users>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://oss.oracle.com/pipermail/graalvm-users/attachments/20210201/cf153787/attachment-0001.html 


More information about the GraalVM-Users mailing list