Merge: Intro the light FFI and use it in nith
authorJean Privat <jean@pryen.org>
Mon, 11 May 2015 23:22:31 +0000 (19:22 -0400)
committerJean Privat <jean@pryen.org>
Mon, 11 May 2015 23:22:31 +0000 (19:22 -0400)
commitbe7ab8cb0bef91d411f0d4c6937f2ba4dbd6985d
treef0e76d66402e4a2e2d417e9b3054214430f60ef8
parent90770bf2f054980d2c8326ff04975ff44d911732
parent707b2f8617b98926c99c09ee32758ad7c8767471
Merge: Intro the light FFI and use it in nith

The new light FFI use only features that should be easy to implement in new/alternative engines to quickly achieve a bootstrap. For this reason, core features of the Nit standard library should be limited to use the light FFI.

## Features of the light FFI

* **Extern methods** implemented in C, nested within the Nit code.
  The body of these method is copied directly to the generated C files for compilation.
  Also supports extern `new` factories.
* Module level **C code blocks**, both "C Body" (the default) and "C Header".
  They will be copied to the beginning of the generated C files.
* Automatic transformation of Nit **primitive types** from/to their equivalent in C.
* **Extern classes** to create a Nit class around a C pointer.
  Allows to specify the equivalent C type of the Nit extern class.

## Features of the full FFI

* More foreign languages: **C++, Java and Objective-C**.
* **Callbacks** to Nit from foreign codes.
  The callbacks are declared in Nit using the `import` annotation on extern methods.
  They are then generated on demand for the target foreign language.
* **Static Nit types** in C for precise typing and static typing errors in C.
* **Propagating public code blocks** at the module level (C Header).
  This allows to use extern classes in foreign code in other modules
  without having to import the related headers.
  This is optional in C as it is easy to find the correct importation.
  However it is important in Java and other complex FFIs.
* **Reference pinning** of Nit objects from foreign code.
  This ensure that objects referenced from foreign code are not liberated by the GC.
* FFI **annotations**:
    * `cflags`, `ldflags` and `cppflags` pass arguments to the C and C++
      compilers and linker.
    * `pkgconfig` calls the `pkg-config` program to get the arguments
      to pass to the C copiler and linker.
    * `extra_java_files` adds Java source file to the compilation chain.

## Light FFI only compilation

Compilers using the module `compiler_ffi::light_only` do not compile extern method with callbacks. This is a good heuristic to determine whether the method uses the full FFI of the light FFI.

The limitation of this heuristic is on 3 features: static Nit types, propagating public code blocks and reference pinning. These features do not required any declaration on the Nit side so they are not reliably detectable by the compiler. Using these features will cause GGC to raise errors on unfound types and functions.

In the case of public code block propagation, the user can fix it by importing the needed C headers in each module. In the other cases, static Nit types and reference pinning, they are used for callbacks, the method should probably declare callbacks. Still, there is some very rare situations where these features could be used correctly and the method would still be recognized as light FFI. If this is becomes a problem, we could add an annotation such as `is light_ffi` to force the heuristic.

> This PR should be read commit by commit. The first 4 commits separate modules in 2 their light/full versions. The only code modification is adding supers, redefs and tweaking the imports.

Pull-Request: #1323
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Jean Privat <jean@pryen.org>
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>