Open beef331 opened 2 years ago
Well importing int128
now works but there is another related issue
typedef struct WasmEdge_Value {
uint128_t Value;
enum WasmEdge_ValType Type;
} WasmEdge_Value;
sizeof(WasmEdge_Value)
on C is 32
but inside Nim it's 24
.
The following type definitions resolve the issue.
type
uInt128t* {.importc: "unsigned __int128".} = object
do_not_use1, do_not_use2: uint64
int128t* {.importc: "__int128".} = object
do_not_use1, do_not_use2: uint64
Hmm, this is a bit weird. So the uint128t
and uint128t
should be the same size as what Futhark spits out for those, 16 bytes. I believe the issue might be with alignment and padding. Probably the C-compiler does something different for int128t
than for a struct of the same size.
That does indeed seem to be the issue. The following test C code:
#include <stdint.h>
#include <stdio.h>
typedef struct {
int64_t a;
int64_t b;
} fake;
typedef struct {
__int128 f1;
int64_t f2;
} withreal;
typedef struct {
fake f1;
int64_t f2;
} withfake;
int main() {
printf("__int128 %d\n", sizeof(__int128));
printf("struct %d\n", sizeof(fake));
printf("withreal %d\n", sizeof(withreal));
printf("withfake %d\n", sizeof(withfake));
}
outputs this:
__int128 16
struct 16
withreal 32
withfake 24
Not entirely sure how to fix that, or if it is even fixable in a trivial way. But as you say Futhark allows you to define you own type definitions for edge cases like this.
Attempting to wrap wasmedge for instance fails due to hitting
__int128
. The following is what I'm using if it helps. In this API one does not directly touch the data at__int128
so any allocation that matches the size should result in usable code.