[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