Opir/Futhark fails to import code that uses `__int128`
beef331 opened this issue · 3 comments
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.
import futhark
import std/strutils
proc removeWasmEdge(name, kind, partof: string): string =
const prefix = "WasmEdge_"
result =
if name.startsWith(prefix):
name[prefix.len..name.high]
else:
name
case kind
of "const", "typedef":
discard
else:
result[0] = result[0].toLowerAscii
importc:
sysPath "/usr/lib/clang/13.0.1/include"
path "/home/jason/.wasmedge/include/"
renameCallback removeWasmEdge
"wasmedge/wasmedge.h"
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.