Rename REAMDE to README.md
[nit.git] / src / ffi / ffi.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2013 Alexis Laferrière <alexis.laf@xymus.net>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # Full FFI support, independent of the compiler
18 #
19 # The full FFI support all the features of the light FFI and more:
20 #
21 # * More foreign languages: **C++, Java and Objective-C**.
22 # * **Callbacks** to Nit from foreign codes.
23 # The callbacks are declared in Nit using the `import` annotation on extern methods.
24 # They are then generated on demand for the target foreign language.
25 # * **Static Nit types** in C for precise typing and static typing errors in C.
26 # * **Propagating public code blocks** at the module level (C Header).
27 # This allows to use extern classes in foreign code in other modules
28 # without having to import the related headers.
29 # This is optional in C as it is easy to find the correct importation.
30 # However it is important in Java and other complex FFIs.
31 # * **Reference pinning** of Nit objects from foreign code.
32 # This ensure that objects referenced from foreign code are not liberated by the GC.
33 # * FFI **annotations**:
34 # * `cflags`, `ldflags` and `cppflags` pass arguments to the C and C++
35 # compilers and linker.
36 # * `pkgconfig` calls the `pkg-config` program to get the arguments
37 # to pass to the C copiler and linker.
38 # * `extra_java_files` adds Java source file to the compilation chain.
39 module ffi
40
41 import modelbuilder
42
43 import nitni
44
45 intrude import ffi_base
46 import extern_classes
47 import header_dependency
48 import pkgconfig
49 import c_compiler_options
50 import c
51 import cpp
52 import java
53 import extra_java_files
54 import objc
55 intrude import light_ffi
56
57 redef class MModule
58 # Complete the compilation of the FFI code
59 redef fun finalize_ffi_wrapper(compdir, mainmodule)
60 do
61 for language in ffi_callbacks.keys do
62 for callback in ffi_callbacks[language] do
63 language.compile_callback(callback, self, mainmodule, ffi_ccu.as(not null))
64 end
65
66 language.compile_to_files(self, compdir)
67 end
68
69 # include dependancies FFI
70 for mod in header_dependencies do
71 if mod.uses_ffi then ffi_ccu.header_custom.add("#include \"{mod.c_name}._ffi.h\"\n")
72 end
73
74 super
75 end
76 end
77
78
79 redef class VerifyNitniCallbacksPhase
80 redef fun process_npropdef(npropdef)
81 do
82 super
83
84 if not npropdef isa AMethPropdef then return
85
86 var code_block = npropdef.n_extern_code_block
87 if code_block == null then return
88
89 var lang = code_block.language
90 assert lang != null
91
92 # Associate callbacks used by an extern method to its foreign language
93 for callback in npropdef.foreign_callbacks.all do
94 var map = npropdef.mpropdef.mclassdef.mmodule.ffi_callbacks
95 if not map.keys.has(lang) then map[lang] = new HashSet[NitniCallback]
96 map[lang].add(callback)
97 end
98 end
99 end