Ajla 0.1.0
[ajla.git] / stdlib / ffi.ajla
blobe068da079e80e230b86f6489ae31240e14e529f6
1 {*
2  * Copyright (C) 2024 Mikulas Patocka
3  *
4  * This file is part of Ajla.
5  *
6  * Ajla is free software: you can redistribute it and/or modify it under the
7  * terms of the GNU General Public License as published by the Free Software
8  * Foundation, either version 3 of the License, or (at your option) any later
9  * version.
10  *
11  * Ajla is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13  * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * Ajla. If not, see <https://www.gnu.org/licenses/>.
17  *}
19 unit ffi;
21 uses io;
23 type ffi_structure;
25 option ffi_type [
26         t_void;
27         t_uint8;
28         t_sint8;
29         t_uint16;
30         t_sint16;
31         t_uint32;
32         t_sint32;
33         t_uint64;
34         t_sint64;
35         t_float;
36         t_double;
37         t_longdouble;
38         t_pointer;
39         t_uchar;
40         t_schar;
41         t_ushort;
42         t_sshort;
43         t_uint;
44         t_sint;
45         t_ulong;
46         t_slong;
47         t_usize;
48         t_ssize;
49         t_bool;
50         t_structure : ffi_structure;
53 option ffi_error [
54         e_none;
55         e_errno;
56         e_get_last_error;
57         e_get_last_socket_error;
60 type ffi_function;
62 fn ffi_unsafe_get_world : world;
64 fn ffi_get_size(ft : ffi_type) : int;
65 fn ffi_get_alignment(ft : ffi_type) : int;
67 fn ffi_create_structure(elements : list(ffi_type)) : (ffi_structure, list(int));
68 fn ffi_get_structure_offset(str : ffi_structure, element : int) : int;
70 fn ffi_poke(w : world, ptr : int, ft : ffi_type, val : int) : world;
71 fn ffi_peek(w : world, ptr : int, ft : ffi_type) : (world, int);
73 fn ffi_poke_array(t : type, w : world, ptr : int, a : list(t)) : world;
74 fn ffi_peek_array(w : world, ptr : int, l : int, ft : ffi_type, t : type) : (world, list(t));
76 fn ffi_handle_to_number(w : world, h : handle) : (world, int);
77 fn ffi_number_to_handle(w : world, n : int, sckt : bool) : (world, handle);
79 fn ffi_create_function(filename : bytes, funcname : bytes, err_type : ffi_error, nvarargs : int, rtype : ffi_type, args : list(ffi_type)) : ffi_function;
80 fn ffi_call_function(w : world, func : ffi_function, args : list(int)) : (world, int, int);
81 fn ffi_call_function_pure(func : ffi_function, args : list(int)) : (int, int);
83 fn ffi_encode_float(f : real32) : int;
84 fn ffi_encode_double(f : real64) : int;
85 fn ffi_encode_longdouble(f : real80) : int;
86 fn ffi_decode_float(i : int) : real32;
87 fn ffi_decode_double(i : int) : real64;
88 fn ffi_decode_longdouble(i : int) : real80;
90 type ffi_destructor;
92 fn ffi_destructor_new(w : world) : (world, ffi_destructor);
93 fn ffi_destructor_allocate(w : world, fd : ffi_destructor, size align : int, zero : bool) : (world, int);
94 fn ffi_destructor_free(w : world, fd : ffi_destructor, ptr : int) : world;
95 fn ffi_destructor_call(w : world, fd : ffi_destructor, func : ffi_function, args : list(int)) : world;
97 implementation
99 type ffi_structure := internal_type;
100 type ffi_function := internal_type;
102 fn ffi_unsafe_get_world : world
104         return unsafe_get_world;
107 fn ffi_get_size(ft : ffi_type) : int
109         var r : int;
110         pcode IO IO_FFI_Get_Size_Alignment 1 1 1 =r ft 0;
111         return r;
114 fn ffi_get_alignment(ft : ffi_type) : int
116         var r : int;
117         pcode IO IO_FFI_Get_Size_Alignment 1 1 1 =r ft 1;
118         return r;
121 fn ffi_create_structure(elements : list(ffi_type)) : (ffi_structure, list(int))
123         var r : ffi_structure;
124         var offs : list(int);
125         pcode IO IO_FFI_Create_Structure 2 1 0 =r =offs elements;
126         return r, offs;
129 fn ffi_get_structure_offset(str : ffi_structure, element : int) : int
131         var r : int;
132         pcode IO IO_FFI_Structure_Offset 1 2 0 =r str element;
133         return r;
136 fn ffi_poke(w : world, ptr : int, ft : ffi_type, val : int) : world
138         var w2 : world;
139         pcode IO IO_FFI_Poke 1 4 0 =w2 w ptr ft val;
140         return w2;
143 fn ffi_peek(w : world, ptr : int, ft : ffi_type) : (world, int)
145         var r : int;
146         var w2 : world;
147         pcode IO IO_FFI_Peek 2 3 0 =w2 =r w ptr ft;
148         return w2, r;
151 fn ffi_poke_array(t : type, w : world, ptr : int, a : list(t)) : world
153         var w2 : world;
154         pcode IO IO_FFI_Poke_Array 1 3 0 =w2 w ptr a;
155         return w2;
158 fn ffi_peek_array(w : world, ptr : int, l : int, ft : ffi_type, t : type) : (world, list(t))
160         var r : list(t);
161         var w2 : world;
162         pcode IO IO_FFI_Peek_Array 2 4 0 =w2 =r w ptr l ft;
163         return w2, r;
166 fn ffi_handle_to_number(w : world, h : handle) : (world, int)
168         var n : int;
169         var w2 : world;
170         pcode IO IO_FFI_Handle_To_Number 2 2 0 =w2 =n w h;
171         return w2, n;
174 fn ffi_number_to_handle(w : world, n : int, sckt : bool) : (world, handle)
176         var h : handle;
177         var w2 : world;
178         pcode IO IO_FFI_Number_To_Handle 2 3 0 =w2 =h w n sckt;
179         return w2, h;
182 fn ffi_create_function(filename : bytes, funcname : bytes, err_type : ffi_error, nvarargs : int, rtype : ffi_type, args : list(ffi_type)) : ffi_function
184         var r : ffi_function;
185         pcode IO IO_FFI_Create_Function 1 6 0 =r filename funcname err_type nvarargs rtype args;
186         return r;
189 fn ffi_call_function(w : world, func : ffi_function, args : list(int)) : (world, int, int)
191         var r e : int;
192         var w2 : world;
193         pcode IO IO_FFI_Call_Function 3 3 0 =w2 =r =e w func args;
194         return w2, r, e;
197 fn ffi_call_function_pure(func : ffi_function, args : list(int)) : (int, int)
199         var r e : int;
200         var w := unsafe_get_world;
201         var w2 : world;
202         pcode IO IO_FFI_Call_Function 3 3 0 =w2 =r =e w func args;
203         return r, e;
206 fn ffi_encode_float(f : real32) : int
208         var r : int;
209         pcode IO IO_FFI_Encode_Real 1 1 0 =r f;
210         return r;
213 fn ffi_encode_double(f : real64) : int
215         var r : int;
216         pcode IO IO_FFI_Encode_Real 1 1 0 =r f;
217         return r;
220 fn ffi_encode_longdouble(f : real80) : int
222         var r : int;
223         pcode IO IO_FFI_Encode_Real 1 1 0 =r f;
224         return r;
227 fn ffi_decode_float(i : int) : real32
229         var r : real32;
230         pcode IO IO_FFI_Decode_Real 1 1 0 =r i;
231         return r;
234 fn ffi_decode_double(i : int) : real64
236         var r : real64;
237         pcode IO IO_FFI_Decode_Real 1 1 0 =r i;
238         return r;
241 fn ffi_decode_longdouble(i : int) : real80
243         var r : real80;
244         pcode IO IO_FFI_Decode_Real 1 1 0 =r i;
245         return r;
248 type ffi_destructor := internal_type;
250 fn ffi_destructor_new(w : world) : (world, ffi_destructor)
252         var r : ffi_destructor;
253         var w2 : world;
254         pcode IO IO_FFI_Destructor_New 2 1 0 =w2 =r w;
255         return w2, r;
258 fn ffi_destructor_allocate(w : world, fd : ffi_destructor, size align : int, zero : bool) : (world, int)
260         var r : int;
261         var w2 : world;
262         pcode IO IO_FFI_Destructor_Allocate 2 5 0 =w2 =r w fd size align zero;
263         return w2, r;
266 fn ffi_destructor_free(w : world, fd : ffi_destructor, ptr : int) : world
268         var w2 : world;
269         pcode IO IO_FFI_Destructor_Free 1 3 0 =w2 w fd ptr;
270         return w2;
273 fn ffi_destructor_call(w : world, fd : ffi_destructor, func : ffi_function, args : list(int)) : world
275         var w2 : world;
276         pcode IO IO_FFI_Destructor_Call 1 4 0 =w2 w fd func args;
277         return w2;