Introducing GCC-Bridge: a C/Fortran Compiler targeting the JVM

137 views
Skip to first unread message

Alexander Bertram

unread,
Feb 1, 2016, 7:09:47 AM2/1/16
to JVM Languages
Hi all,

I've finally gotten around to writing a bit about GCC-Bridge, the C/Fortran compiler used by Renjin to compile R packages with "native" code to the JVM.

The compiler's recently benefited from a near total rewrite to target Java 1.7 (including using MethodHandles for function pointers, which are a great fit) and
we are looking to support C++ code in the near future, which is a actually not such a big step as we are using GCC as a frontend.

We've been careful to keep gcc-bridge usable apart from Renjin, so would welcome collaboration with other J* languages interested in a better supporting native
extensions/gems/modules!

All the best,
Alex

Charles Oliver Nutter

unread,
Feb 1, 2016, 8:31:37 AM2/1/16
to JVM Languages

Yay! I will have to look into this. We have an interest in compiling Ruby C extensions to Java and providing a JVM-level implementation of Ruby's C API.

- Charlie (mobile)

--
You received this message because you are subscribed to the Google Groups "JVM Languages" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jvm-language...@googlegroups.com.
To post to this group, send email to jvm-la...@googlegroups.com.
Visit this group at https://groups.google.com/group/jvm-languages.
For more options, visit https://groups.google.com/d/optout.

Alexander Bertram

unread,
Feb 1, 2016, 5:55:15 PM2/1/16
to JVM Languages
That's the approach we've taken with Renjin and GNU R's C API. 

You can basically tell the compiler to map a C struct to a given java class, for example, mapping CRuby's VALUE to org.jruby.RubyBasicObject and import 

GimpleCompiler compiler = new GimpleCompiler();
compiler.addRecordClass("__VALUE", RubyBasicObject.class);
compiler.addMethod("TYPE", CRuby.class, "TYPE");

You can then define:

class CRuby {
public static int TYPE(RubyBasicObject obj) {  
  if(obj instance of RubyBoolean) return 1;
  if(obj instance of RubyHash) return 2;
  // etc...
}
}

We monkey with the GNU R header files to make replace macros with function declarations so they can mapped to JVM methods.

-Alex

Charles Oliver Nutter

unread,
Feb 1, 2016, 8:31:01 PM2/1/16
to JVM Languages
On Mon, Feb 1, 2016 at 11:55 PM, Alexander Bertram
<al...@bedatadriven.com> wrote:
> You can basically tell the compiler to map a C struct to a given java class,
> for example, mapping CRuby's VALUE to org.jruby.RubyBasicObject and import
>
> GimpleCompiler compiler = new GimpleCompiler();
> compiler.addRecordClass("__VALUE", RubyBasicObject.class);
> compiler.addMethod("TYPE", CRuby.class, "TYPE");
>
> You can then define:
>
> class CRuby {
> public static int TYPE(RubyBasicObject obj) {
> if(obj instance of RubyBoolean) return 1;
> if(obj instance of RubyHash) return 2;
> // etc...
> }
> }

Very nice! I'm eager to give this a try with a simple extension and
see how it feels.

> We monkey with the GNU R header files to make replace macros with function
> declarations so they can mapped to JVM methods.

Yeah we'd turn the weird ones into functions bound to JRuby operations too.

I have been in transit all day so I did not get to read much... how
does one get this gcc plugin installed? RubyGems are built when
installed, so we'd need to be able to hook into gcc at that point.

- Charlie

Alexander Bertram

unread,
Feb 2, 2016, 3:52:26 AM2/2/16
to JVM Languages

For the plugin itself: various builds of gcc-bridge.so are shipped with the gcc-bridge compiler jar and extracted to a temp folder as needed. We have builds for linux-x86 and linux-i686, and I know that we have contributors who have built a version for os x. Windows remains unattempted...

GCC needs to be installed, and on 64-bit system, gcc-multilib also needs to be present so we can generate code that uses 32-bit pointers, as GCC-Bridge backs pointers with JVM arrays which support only 32-bit (31-bit I guess) indexing on all platforms.

On Ubuntu, you'd need:
sudo apt-get install gcc-4.6 gfortran-4.6 gcc-4.6.multilib

For Renjin, packages are distributed as JARs so we run a build server (http://packages.renjin.org) that churns out pre-built JARs for all the R packages in the major R repositories. I don't know if would be possible to do something similar for JRuby.

-Alex
Reply all
Reply to author
Forward
0 new messages