Skip to content
This repository has been archived by the owner on Aug 22, 2019. It is now read-only.

Polyglot docs missing some detail #867

Open
mikehearn opened this issue Aug 21, 2018 · 4 comments
Open

Polyglot docs missing some detail #867

mikehearn opened this issue Aug 21, 2018 · 4 comments
Assignees

Comments

@mikehearn
Copy link
Contributor

  1. It's not clear to me if the "convert polyglot value to a struct" trick can handle function pointers inside the struct to emulate OO method calls. The header file says accessing members is equivalent to get/put member, so perhaps not, but it seems an obvious feature to have? Then you can map objects to structs (or perhaps even to C++ classes which would be neat)

  2. The docs go into a lot more detail than the website does and it's annoying to figure out how to get to polyglot.h from the tiny example on graalvm.org - it'd be great to have more thorough examples on the website.

@rschatz
Copy link
Member

rschatz commented Aug 22, 2018

Hi Mike!

It's not clear to me if the "convert polyglot value to a struct" trick can handle function pointers inside the struct to emulate OO method calls. The header file says accessing members is equivalent to get/put member, so perhaps not, but it seems an obvious feature to have? Then you can map objects to structs...

Having function pointers inside the struct currently doesn't work, but we definitely want to support that in the future. It shouldn't be very hard to get this working.

... (or perhaps even to C++ classes which would be neat)

That's a bit more complex. First there is the question of semantics. I guess a foreign object that is cast to a C++ class should appear as a "subclass" of the C++ class. In terms of implementation, that means we'd need to emulate a vtable. I'm sure it's doable, but it's a bit more work.

See also oracle/graal#609 for a discussion about the reverse feature, exporting C++ classes to other languages.

The docs go into a lot more detail than the website does and it's annoying to figure out how to get to polyglot.h from the tiny example on graalvm.org - it'd be great to have more thorough examples on the website.

I agree.

The inline documentation in polyglot.h is quite detailed. A good first step would be to put that on the webpage. Unfortunately our API doc infrastructure for the rest of the project is built on JavaDoc, we currently don't have a way to publish C API documentation (e.g. via Doxigen). I'll see what I can do to fix this.

@rschatz rschatz self-assigned this Aug 22, 2018
@rschatz
Copy link
Member

rschatz commented Aug 22, 2018

Having function pointers inside the struct currently doesn't work, but we definitely want to support that in the future.

Actually, I was a bit too fast: I just tested it, and it does indeed work, but only one level:

struct Point {
   double (*length)();
   struct Point *(*normalize)();
};

POLYGLOT_DECLARE_STRUCT(Point)

struct Point *pt = polyglot_as_Point(...);
printf("%f\n", pt->length()); // will work fine, but note that this is C, not C++, so no implicit "this" argument
struct Point *n1 = pt->normalize(); // will not quite do what you expect, the result is a "naked" polyglot value
struct Point *n2 = polyglot_as_Point(n1); // you need to do this

The missing feature is to pick up the types from the function pointer signature, and recursively apply them to arguments and return values, like we already do for read and written values.

@mikehearn
Copy link
Contributor Author

You know you're doing well when your software turns out to have useful features you didn't know were there ;)

We're so close! With knowledge of return types and this, we'd be able to call Java/Ruby/Python/etc objects from C++ in a vaguely OOPified way, with compiler optimisations across the boundaries. That'd be stellar!

@rschatz
Copy link
Member

rschatz commented Aug 23, 2018

With b24f57a function pointer types should now be fully supported, including recursively on argument and return types.

For example:

C:

#include <stdio.h>
#include <polyglot.h>

struct Point {
   double x;
   double y;
   struct Point *(*add)(struct Point *);
};

POLYGLOT_DECLARE_STRUCT(Point)

void access(void *value) {
   struct Point *p1 = polyglot_as_Point(value);
   struct Point p2 = {3, 5};
   struct Point *sum = p1->add(&p2);
   printf("%f %f\n", sum->x, sum->y);
}

JS:

function createPoint(x, y) {
   var self = {x: x, y: y};
   self.add = function(other) {
      return createPoint(self.x + other.x, self.y + other.y);
   };
   return self;
}

var llvm = Polyglot.evalFile("llvm", "point.bc");
var p = createPoint(1, 2);
llvm.access(p);

Note that this is still C, not C++. There is no implicit this argument, you have to capture self yourself on the JS side. Of course you can now write a C++ wrapper for the C function pointer table.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants