Skip to content

Added mdbook entry for bitfields. #1052

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 3 commits into from
Jan 17, 2018
Merged

Conversation

ambaxter
Copy link
Contributor

@ambaxter ambaxter commented Oct 1, 2017

Fixes #818

@highfive
Copy link

highfive commented Oct 1, 2017

warning Warning warning

  • These commits modify unsafe code. Please review it carefully!

Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

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

This is a good start! Thanks @ambaxter.

I think we should have a section at the very beginning that gives an overview of bindgen's translation strategy:

  • The Rust language does not have bitfields, so they are translated into opaque fields in the Rust struct

  • We generate getter methods to access the bitfields, and the getters are named <bitfield>

  • We generate setter methods to write to bitfields, and the setters are named set_<bitfield>

  • We generate constructors for the opaque fields containing a set of bitfields. These constructors are static methods on the Rust struct, and are named new_bitfield_{1,2,...}. They have a parameter for each of the bitfields contained within the opaque physical field.

With that leading overview section in place, I think the existing detailed walkthrough will be a good follow up for people who want more.

Thanks again! Looking forward to the revised version :)

bitfield create_bitfield();

// Print a bitfield
void print_bitfield(bitfield bfield)
Copy link
Member

Choose a reason for hiding this comment

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

Nitpick: missing a semicolon at the end of this declaration.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

bitfield: a:0, b:0, c:0
```

However, Bindgen's getter provides different results:
Copy link
Member

Choose a reason for hiding this comment

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

This is a bug, that we should fix, not behavior that we should document and canonicalize.

Let's remove this section and file a new issue to fix this bug instead.

unsigned int b: 1;
unsigned int c: 2;

} bitfield;
Copy link
Member

Choose a reason for hiding this comment

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

I think naming the struct that contains bitfields "bitfield" leaves room for misinterpretation. The struct is not a bitfield, it just contains bitfields. How about ContainsBitfields or StructWithBitfields?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

bitfield: a:1, b:1, c:0
```

To create a new bitfield in Rust, use mem::zeroed.
Copy link
Member

Choose a reason for hiding this comment

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

Rather than use std::mem::zeroed, we should use the bitfield allocation unit constructors that bindgen emits: new_bitfield_{1,2,...}. About one of these is created for each set of contiguous bitfields within a struct.

let contains_bitfields = ContainsBitfields {
    _bitfield_1: ContainsBitfields::new_bitfield_1(/* a */ 1, /* b */ 2, /* c */ 3),
    ..Default::default()
};

Copy link
Contributor

@glyn glyn Nov 13, 2017

Choose a reason for hiding this comment

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

@fitgen with the currently generated code, e.g. this, the bitfield allocation unit constructor does not necessarily return a value of the same type as the bitfield allocation unit, so this way of initialising a field produces a compile error. What should the user do in this case?

Copy link
Member

Choose a reason for hiding this comment

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

For now transmute, but really we should (eventually) fix that.

The problem is transmute is not a const fn yet, and we make these bitfield constructors const fns when we can. Additionally, making transmute into a const fn requires Miri integration into rustc, and I'm not sure on the timeline for that.

We could do all kinds of things to work around this like:

  • avoid generating the ctors when we need to transmute and its a const fn
  • avoid making the ctor a const fn when we need to transmute
  • skip generating any ctor at all when we need to transmute
  • etc

Copy link
Contributor

Choose a reason for hiding this comment

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

@fitzgen Is a fix along these lines reasonable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@fitzgen During testing, I ran into an issue where Default isn't implemented for the bitfield. Is there a flag I need to set for that to be generated?

bitfield: a:1, b:1, c:3
```

Overflowing a bitfield will result in the same behavior as in C/C++: the bitfield will be set to 0.
Copy link
Member

Choose a reason for hiding this comment

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

Does it just happen to set to 0 in this case or is that really what the standard says should happen? My reading of the C++ standard doesn't come up with anything either way. Same with the C11 standard.

I think we should leave overflow unspecified as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In my googling Stackoverflow that's what the standard says: https://stackoverflow.com/questions/4908300/overflow-in-bit-fields#4908606

Copy link
Member

Choose a reason for hiding this comment

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

Great!

@fitzgen
Copy link
Member

fitzgen commented Oct 12, 2017

Hey @ambaxter, still making progress here?

@ambaxter
Copy link
Contributor Author

Yes. Work took a lot of my free time the last few weeks. Thankfully today is the last day of that.

@ambaxter
Copy link
Contributor Author

As an update, the latest crunch time is over. Combining that with the upcoming US holiday, I should have this updated this week.

@ambaxter
Copy link
Contributor Author

Ready for next review

@fitzgen
Copy link
Member

fitzgen commented Nov 27, 2017

@ambaxter this PR is a bit tough to review in its current state: there seems to be lots of unrelated commits from master mixed in (perhaps a funky merge?)

Can you rebase just your commits on top of master and squash them down to one commit? Alternatively, just check out the latest master and copy your new .md file into it and make a new commit and force push that to this PR.

Thanks!

@fitzgen
Copy link
Member

fitzgen commented Nov 27, 2017

And thanks for picking this up again!

@ambaxter
Copy link
Contributor Author

Weird. Those were from the rebase. I'll reset it.

Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

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

Looks great! A couple tiny nit picks to be addressed below and then we can finally merge this. Thanks for sticking with this PR @ambaxter!


## Bitfield Strategy Overview

As Rust does not support bitfields, Bindgen generates an opaque struct for each with the following characteristics
Copy link
Member

Choose a reason for hiding this comment

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

generates an opaque struct

Nitpick: We don't make the whole struct opaque, we emit an opaque physical field that contains one or more logical bitfields.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

As Rust does not support bitfields, Bindgen generates an opaque struct for each with the following characteristics
* Immutable getter functions for each bitfield named ```<bitfield>```
* Setter functions for each bitfield named ```set_<bitfield>```
* A static constructor ```new_bitfield_{1, 2, ...}``` with a parameter for each bitfield contained within the opaque physical field.
Copy link
Member

Choose a reason for hiding this comment

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

Nitpick: s/for each bitfield/for each contiguous block of bitfields/

There is a constructor for each of those physical, opaque fields that we end up generating, which is roughly equivalent to sets of contiguous bitfields.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

let bfield = StructWithBitfields{
_bitfield_1: StructWithBitfields::new_bitfield_1(0,0,0),
..Default::default()
}; unsafe { print_bitfield(bfield) };
Copy link
Member

Choose a reason for hiding this comment

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

Nitpick: need to insert a new line before the unsafe block.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

* Setter functions for each bitfield named ```set_<bitfield>```
* A static constructor ```new_bitfield_{1, 2, ...}``` with a parameter for each bitfield contained within the opaque physical field.

## Bitfield examples
Copy link
Member

Choose a reason for hiding this comment

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

awesome 👍

@ambaxter
Copy link
Contributor Author

Finally got some time to finish this.

Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

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

Awesome! Thanks so much for circling back on this @ambaxter! Just one typo fix needed, then we can merge this.


As Rust does not support bitfields, Bindgen generates a struct for each with the following characteristics
* Immutable getter functions for each bitfield named ```<bitfield>```
* Setter functions for each contiguous bsock of bitfields named ```set_<bitfield>```
Copy link
Member

Choose a reason for hiding this comment

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

"bsock" -> "block"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!

@fitzgen
Copy link
Member

fitzgen commented Jan 17, 2018

Thanks!

@bors-servo r+

@bors-servo
Copy link

📌 Commit b969bfb has been approved by fitzgen

@bors-servo
Copy link

⌛ Testing commit b969bfb with merge 13f2b9a...

bors-servo pushed a commit that referenced this pull request Jan 17, 2018
Added mdbook entry for bitfields.

Fixes #818
@bors-servo
Copy link

☀️ Test successful - status-travis
Approved by: fitzgen
Pushing 13f2b9a to master...

@bors-servo bors-servo merged commit b969bfb into rust-lang:master Jan 17, 2018
@ambaxter ambaxter deleted the bitfield_docs branch January 17, 2018 21:45
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.

5 participants