closure api: always extend integers to full word size #456
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This will fix #441 and related problems on nearly all ARM and MIPS platforms (x86 doesn't seem to be affected because of different calling conventions).
The problems are return results of closures. If integers smaller than word-size are returned, they must be extended to full word-size. But they are currently always zero-extended, never sign-extended (https://github.com/ocamllabs/ocaml-ctypes/blob/0d0c62f5b2432a49c3d0c965b8fa9d0dd50ea857/src/ctypes-foreign-base/ffi_call_stubs.c#L489 ).
The first commit contains test code to demonstrate the issue:
callback_returns_int8_t (fun () -> -128)
will sometimes return+128
.If one byte is set to
-128
and the higher bits are set to zero, the whole word will be read as128
. It's not a problem for the (exclusive) foreign interface, because it's hard-coded that the higher bits are ignored. But if stub code is generated,128
is the more likely result (it depends on the compiler and its optimization settings).