-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New Foreign Function Interface (FFI) #25
Conversation
5984ef4
to
1e36895
Compare
Signed-off-by is missing in the 1st two commits. |
1e36895
to
f423c7f
Compare
Missing signoffs added. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
There is an unused file in the tests. And exit(1)
is missing in one place.
@@ -92,6 +92,20 @@ let split3 (xyzs : ('x * 'y * 'z) list) : ('x list * 'y list * 'z list) = | |||
xyzs | |||
([], [], []) | |||
|
|||
(** split4 [(a1, b1, c1, d1); ... (an, bn, cn, dn)] = ([a1; ... an], ... [d1; ... dn]) *) | |||
let split4 (abcds : ('a * 'b * 'c * 'd) list) : ('a list * 'b list * 'c list * 'd list) = | |||
List.fold_right |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you considered fold_left
, as it is tail-recursive?
It will require reversing the resulting lists in the tuple though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting idea. Definitely worthwhile if the lists are long.
These functions are only used with lists of arguments - which don't get longer than about 5-10 so not being tail recursive should not be a problem. So I will stick with the simple version.
A quick look at the source code for List.split shows that it is not tail recursive either. This might be more of a problem since it is used in more places and maybe some of those involve long lists. (eg a list of all functions).
tests/backends/ffi_import_01.c
Outdated
uint32_t FFI_null_bits32(uint32_t x) { return x; } | ||
uint64_t FFI_null_bits64(uint64_t x) { return x; } | ||
|
||
void FFI_null_bits17(uint64_t x[1], uint64_t r[1]) { memcpy(r, x, 1*sizeof(*r)); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
void FFI_null_bits17(uint64_t x[1], uint64_t r[1]) { memcpy(r, x, 1*sizeof(*r)); } | |
void FFI_null_bits17(uint64_t x[1], uint64_t r[1]) { memcpy(r, x, 1*sizeof(uint64_t)); } |
would be cleaner.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes - good idea
@@ -463,6 +491,11 @@ def main() -> int: | |||
if args.num_c_files != 1 and args.build: | |||
print("Error: don't specify --num-c-files if building or running") | |||
exit(1) | |||
if (args.imports or args.exports or args.extra_c) and not args.build: | |||
print("Error: don't specify --imports or --exports or --extra-c if not building or not running") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
print("Error: don't specify --imports or --exports or --extra-c if not building or not running") | |
print("Error: don't specify --imports or --exports or --extra-c if not building or not running") | |
exit(1) |
Missing exit(1)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops - fixed
// Wide bitvectors are represented as arrays of uint64_t | ||
// If returning a wide bitvector, an extra array argument is | ||
// added as the last argument | ||
void FFI_Invert128(uint64_t x[2], uint64_t y[2]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
void FFI_Invert128(uint64_t x[2], uint64_t y[2]) | |
void FFI_Invert128(uint64_t x[], uint64_t y[]) |
Strictly speaking, array sizes are not needed here. I assume you add them for readability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I want the size of the arrays to be clear since the size of the array is important for writing correct code.
I am not sure whether gcc/clang generate warnings if you are obviously writing past the end of an array - but hopefully a human code reviewer would spot a problem.
Signed-off-by: Alastair Reid <[email protected]>
This provides a way to test whether a type was generated by the :xform_tuples transformation - which is needed to support tuple-return in the foreign function interface Signed-off-by: Alastair Reid <[email protected]>
This interface makes the types of imported/exported functions independent of the particular representation choices made by the runtime system. Instead, values of arguments and results are converted between the type used for ASL code and a standard representation used for C code. The representation of types is as follows - if the ASL type is boolean then "bool" (from stdbool.h) - if the ASL type is string then "const char*" - if the ASL type is integer then "int" - if the ASL type is bits(N) then either - uint8_t, uint16_t, uint32_t, uint64_t if N IN {8, 16, 32, 64} - array uint64_t _[N'] where N' is ceiling(N / 64) - if the ASL type is an enumeration, then that enumeration provided that the enumeration type has been explicitly exported Other types cannot be used in imported/exported functions. In addition, exported functions must not raise exceptions and, for extra safety, we insert a runtime check that they do not raise an exception In addition, for each configuration variable 'v : ty', we generate a pair of getter/setter functions ASL_set_config_{v}({cty} value); {cty} ASL_get_config_{v}(); Note that (based on the ASL semantics of configuration variables) all changes to the configuration variable should be made before executing any ASL code. Signed-off-by: Alastair Reid <[email protected]>
- Add --new-ffi flag This causes the new FFI to be used instead of the old FFI where the type of imported/exported functions was determined by the data representations of a particular runtime. - Add --configuration=<json file> Specify a configuration control file typically containing import and export lists to control the FFI - Add --import=<C function name> and --export=<C function name> These specify a C function to be imported/exported. The ASL function name needs to be the same as the C function name. This is a shortcut to creating a configuration file that is mostly intended to make it easier to write tests. - Add --extra-c=<C file> flag This specifies a C file to be compiled and linked against the ASL code when using --build or --run. Mostly intended to make it easier to write tests. Signed-off-by: Alastair Reid <[email protected]>
Signed-off-by: Alastair Reid <[email protected]>
f423c7f
to
59499d3
Compare
This new interface makes the types of imported/exported
functions independent of the particular representation
choices made by the runtime system.
Instead, values of arguments and results are converted
between the type used for ASL code and a standard
representation used for C code.
The representation of types is as follows
provided that the enumeration type has been explicitly
exported
expects N extra arguments which should be pointers for
the C function to write results to.
Other types cannot be used in imported/exported functions.
In addition, exported functions must not raise exceptions
and, for extra safety, we insert a runtime check that
they do not raise an exception
In addition, for each configuration variable 'v : ty', we generate
a pair of getter/setter functions
Note that (based on the ASL semantics of configuration variables)
all changes to the configuration variable should be made
before executing any ASL code.
All the interesting (and harder to review changes) are in libASL/backend_c_new.ml - the rest is just changes to the runtime API to support the new FFI or to support testing.