Skip to content

closure: make Block_descriptor_1 conform to the ABI #1614

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

Merged
merged 1 commit into from
Jun 27, 2018

Conversation

compnerd
Copy link
Member

The Blocks ABI v1 used unsigned long int for the size and reserved
fields. On LLP64 targets (e.g. Windows x86_64), uintptr_t is larger
than unsigned long int. Adjust the types to make the definition
conform to the ABI specification.

The Blocks ABI v1 used `unsigned long int` for the `size` and `reserved`
fields.  On LLP64 targets (e.g. Windows x86_64), `uintptr_t` is larger
than `unsigned long int`.  Adjust the types to make the definition
conform to the ABI specification.
@compnerd
Copy link
Member Author

CC: @parkera @phausler

@compnerd
Copy link
Member Author

@swift-ci please test

@parkera
Copy link
Contributor

parkera commented Jun 22, 2018

I assume clang is the one emitting this on Windows then? What definition for the struct does it use?

@compnerd
Copy link
Member Author

compnerd commented Jun 22, 2018

@parkera: correct. It uses unsigned long int (which is going to be 32-bits on LLP64).

struct Block_descriptor {
  unsigned long int reserved;
  unsigned long int size;
  void (*copy_helper)(void *, void *);
  void (*dispose_helper)(void *);
  const char *signature;
  void *layout;
};

Also, note that this change will be ABI compatible on all non-LLP64 targets

@compnerd
Copy link
Member Author

@parkera seems like a pretty simple case?

@parkera
Copy link
Contributor

parkera commented Jun 26, 2018

The root of the question is me wondering if the first two values should be 64 bits on LLP64, like they would be on LP64. I suppose that would require an update to clang when targeting Windows. However, when looking at the rest of the source here it doesn't appear to be actually used by the runtime so I guess this is ok.

@compnerd
Copy link
Member Author

Sure, we could look at altering the definition in LLP64 since we don't expect there to be many users right now. I think that is beyond the scope of this change and we should discuss that with @rjmccall first.

@compnerd compnerd merged commit f013516 into swiftlang:master Jun 27, 2018
@compnerd compnerd deleted the llp64 branch June 27, 2018 15:37
@rjmccall
Copy link
Contributor

rjmccall commented Jun 27, 2018

That's an interesting question. I think the intent of the specification is probably to always get a pointer-sized integer, yes; that is, the reserved field should allow it to be used for a pointer, and the size field should not impose artificial restrictions on the size (even though a > 4GB block literal is pretty clearly impossible given that all block literals with an extended size need to be allocated on the stack).

I think that is a change we can reasonably make, but yeah, it's really up to the libclosure mantainers (CC @gparker42), as well as needing changes to clang and (I think) gcc.

@gparker42
Copy link

gparker42 commented Jun 27, 2018

Yes, the intent is uintptr_t. The original author of this code was a classic C89 / LP64 / Unix guy so unsigned long int is how he would have spelled that intent.

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

Successfully merging this pull request may close these issues.

4 participants