Skip to content

[FFI] Fix #80847 - Resolve struct type for internal struct fields #6762

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

Closed
wants to merge 5 commits into from

Conversation

nawarian
Copy link
Contributor

@nawarian nawarian commented Mar 8, 2021

This is an incomplete fix for BUG #80847.

It uses recursion to resolve nested structs.

This Pull Request currently is incomplete:

  • PHP complains of memory leaks introduced and I can't really understand how to solve this
  • I need support for testing this

This GIST generates a fatal error without this Pull Request with the following message:

PHP Fatal error:  Uncaught FFI\Exception: Passing incompatible argument 1 of C function 'BeginMode2D',
expecting 'struct Camera2D', found 'struct Camera2D' in [...]/raylib.php:11

@nawarian nawarian force-pushed the BUG-80847/FFI_NESTED_STRUCTS branch from d5f1e3c to 7d7333d Compare March 8, 2021 20:43
@cmb69
Copy link
Member

cmb69 commented Mar 10, 2021

I need support for testing this

See for instance 67f9b0b. Basically, you can add the required C code to the zend_test extension, and then use it with FFI. Adding a test first may help to indentify the memory leak issues.

@nawarian
Copy link
Contributor Author

nawarian commented Mar 12, 2021

Thanks! This helped a lot with the test part! I'll keep checking the memory leaks part

@nawarian
Copy link
Contributor Author

Most builds passed; One is breaking on APT step, not sure it relates to my changes...

@@ -339,6 +340,9 @@ static ffi_type *zend_ffi_make_fake_struct_type(zend_ffi_type *type) /* {{{ */
case ZEND_FFI_TYPE_POINTER:
t->elements[i] = &ffi_type_pointer;
break;
case ZEND_FFI_TYPE_STRUCT:
t->elements[i] = &ffi_type_pointer;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not 100% sure why this works tbh. In my test's specific case this makes sure that the returned value won't be NULL. But I failed to trace back how ffi_type_pointer is actually used in the code.

I suppose ffi_type_* symbols come from libffi and given ffi_type_struct does not exist I just guessed that ffi_type_pointer would be the best way to go. Please let me know if this isn't a good idea.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I doubt this is the right thing to do here. Probably only works because in your test case the struct happens to have the same size as a pointer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix is incorrect. We can't pass/return structures by value in general. libffi doesn't support this (e.g. see libffi/libffi#33). However, we may try to pass/return structures by value if they fit into 32/64-bit word. I'll try to do this...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wrong. libffi seems support big structures. See my fix #6781

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Thanks a lot for taking care of this @dstogov. Hopefully next time I'll manage it by myself, but I'm very glad learning from your fix :)

Shall we close this pull request and follow up on #6781 ?

@nawarian nawarian changed the title [FFI] Resolve struct type for internal struct fields [FFI] Fix #80847 - Resolve struct type for internal struct fields Mar 15, 2021
@dstogov
Copy link
Member

dstogov commented Mar 17, 2021

Closed in favour of #6781

@dstogov dstogov closed this Mar 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants