Skip to content
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

Passing struct by value to a foreign function does not work properly #342

Open
Apis035 opened this issue May 18, 2024 · 1 comment
Open

Comments

@Apis035
Copy link
Contributor

Apis035 commented May 18, 2024

...And may crash the program. But passing by reference does work properly.

While passing struct by value:

  • With 1 field -> Ok
  • With 2 field -> Second field is zero
  • With 3 field -> Crash

Example C library:

typedef struct {int a, b, c} i3;

void checkByRef(i3 *s) { printf("%d, %d, %d\n", s->a, s->b, s->c); }
void checkByVal(i3 s)  { printf("%d, %d, %d\n", s.a, s.b, s.c); }

Adept:

record i3(a, b, c int)

foreign checkByRef(s *i3) void
foreign checkByVal(s i3) void

func main {
    v i3 = i3(1, 2, 3)
    checkByRef(&v) // Ok
    checkByVal(v)  // Crash
}

Test case

Related issue to discussion #337. Luckily, that problem can be resolved because the 4 ubyte struct is packed into a single int.

@IsaacShelton
Copy link
Collaborator

Yes, apparently clang has around 12,000+ lines of gymnastics to get around this problem.

https://github.com/llvm/llvm-project/blob/5e691a1c9b0ad22689d4a434ddf4fed940e58dec/clang/lib/CodeGen/TargetInfo.cpp#L5816-L5823

The structs are passed differently for each architecture and os. Sometimes, values are passed in vector registers, sometimes in integer registers (even if the value is a float), sometimes combining multiple floats into a single integer register, sometimes breaking structs into multiple "args" which are passed as registers, sometimes returning structures by out pointers, sometimes passing some fields in one way and others in another, and lots more. And all of this is architecture and os dependent.

I've been looking at different ways to handle this, but it might be awhile as you can probably understand, given that it will require thousands of lines of nonsensical magic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants