-
Notifications
You must be signed in to change notification settings - Fork 700
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
Rework how bitfields are handled. #512
Conversation
r? @fitzgen |
Also @flier may want to take a look to ensure I didn't mess badly ;) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Taking this one on faith...
@@ -732,89 +732,96 @@ impl<'a> Bitfield<'a> { | |||
fn codegen_fields(self, | |||
ctx: &BindgenContext, | |||
fields: &mut Vec<ast::StructField>, | |||
methods: &mut Vec<ast::ImplItem>) | |||
_methods: &mut Vec<ast::ImplItem>) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't a trait implementation, so we can change the set of parameters. Let's remove this if it isn't used anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^ this comment is still not addressed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was assuming that given #519 is assigned, it'll be used soon :)
I think we need the accessors to make this usable. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some compatibility issues
// bitfield, and whether we have to index in it. Thus, we don't know | ||
// which integer type do we need. | ||
// | ||
// We could push them to a Vec or something, but given how buggy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO: We need some unit tests to verify accessor use the right offset same to LLVM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, this is why I didn't want to deep-dive into accessors ;)
src/codegen/mod.rs
Outdated
fields.push(field); | ||
} | ||
|
||
Layout::new(bytes_from_bits(total_size_in_bits), max_align) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need padding some bits to the latest bitfield base on its type instead of size
consider the example
struct Date {
unsigned short nWeekDay : 3; // 0..7 (3 bits)
unsigned short nMonthDay : 6; // 0..31 (6 bits)
unsigned short nMonth : 5; // 0..12 (5 bits)
unsigned short nYear : 8; // 0..100 (8 bits)
};
nYear
should be aligned to offset 16bits with 16bits size, not a 8bit bit field
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct Date {
pub _bitfield_1: [u8; 2usize],
pub _bitfield_2: u8,
pub __bindgen_align: [u16; 0usize],
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hrm, you're right about this, but this needs to only happen when this is the last field in the struct. Otherwise, we'd generate wrong code for this one (reusing your example here):
struct Date {
unsigned short nWeekDay : 3; // 0..7 (3 bits)
unsigned short nMonthDay : 6; // 0..31 (6 bits)
unsigned short nMonth : 5; // 0..12 (5 bits)
unsigned short nYear : 8; // 0..100 (8 bits)
unsigned char byte;
};
Where the size should still be 4 bytes.
I'll special-case this.
total_size_in_bits += width as usize; | ||
|
||
|
||
let data_size = align_to(field_size_in_bits, field_align * 8); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO: When we implement accessor, the data_size
must limited by its type, C++ allow bitfields exceeds its type limites
If the specified size of the bit field is greater than the size of its type, the value is limited by the type: a std::uint8_t b : 1000; would still hold values between 0 and 255. the extra bits become unused padding.
struct foo
{
unsigned char bar : 1000;
};
will generated data size, but only 8 bits should be accessible
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct foo {
pub _bitfield_1: [u8; 128usize],
pub __bindgen_align: [u64; 0usize],
}
In the C programming language, the width of a bit field cannot exceed the width of the underlying type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I had already a note about packed and wide bitfields :)
So I pushed another wip that manages to get rid of the calc layout code, at the expense of failing the That test generates an array of unaligned structs and previous to this commit, padded it. I'd argue that's pretty wrong, and it's wrong to not fail that test, since it's pretty unsafe (the structs in the array don't start where it should). @flier, wdyt? |
I fixed that test (if in a much hacky way). |
Ok, so current commit passess all the layout and field offset tests here and gecko. As I said, adding the getters and setters again is probably not too hard, but this has already went out of scope of what I initially intended. @fitzgen mind taking a look again since a few things have changed? |
@@ -13,7 +13,7 @@ name = "bindgen" | |||
readme = "README.md" | |||
repository = "https://github.com/servo/rust-bindgen" | |||
documentation = "https://docs.rs/bindgen" | |||
version = "0.21.3" | |||
version = "0.22.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We've almost caught up with emacs!
@@ -11,6 +11,7 @@ mod codegen { | |||
quasi_codegen::expand(&src, &dst).unwrap(); | |||
println!("cargo:rerun-if-changed=src/codegen/mod.rs"); | |||
println!("cargo:rerun-if-changed=src/codegen/helpers.rs"); | |||
println!("cargo:rerun-if-changed=src/codegen/struct_layout.rs"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do these things support wildcards? If so, is there a reason we shouldn't do this
println!("cargo:rerun-if-changed=src/codegen/*");
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, it's not supported I think, we'd need to walkdir or something.
@@ -732,89 +732,96 @@ impl<'a> Bitfield<'a> { | |||
fn codegen_fields(self, | |||
ctx: &BindgenContext, | |||
fields: &mut Vec<ast::StructField>, | |||
methods: &mut Vec<ast::ImplItem>) | |||
_methods: &mut Vec<ast::ImplItem>) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^ this comment is still not addressed
@bors-servo r=fitzgen |
📌 Commit b14adc3 has been approved by |
Rework how bitfields are handled. This fixes #111, and unblocks stylo. The problem with this as of right now is that it drops the accessors (though before that this code was buggy so I'm not sure it's a loss). I can probably try to re-implement those (though it'd be more complex). WDYT @fitzgen? Also, note that I changed the max_align_nonce because it was incorrect (we shouldn't generate padding, because `long double` was `128` bits).
@bors-servo r=fitzgen
|
📌 Commit 08d4b8e has been approved by |
☔ The latest upstream changes (presumably #518) made this pull request unmergeable. Please resolve the merge conflicts. |
🔒 Merge conflict |
@bors-servo r=fitzgen
|
📌 Commit 98f43d0 has been approved by |
Rework how bitfields are handled. This fixes #111, and unblocks stylo. The problem with this as of right now is that it drops the accessors (though before that this code was buggy so I'm not sure it's a loss). I can probably try to re-implement those (though it'd be more complex). WDYT @fitzgen? Also, note that I changed the max_align_nonce because it was incorrect (we shouldn't generate padding, because `long double` was `128` bits).
☀️ Test successful - status-travis |
This fixes #111, and unblocks stylo.
The problem with this as of right now is that it drops the accessors (though before that this code was buggy so I'm not sure it's a loss).
I can probably try to re-implement those (though it'd be more complex). WDYT @fitzgen?
Also, note that I changed the max_align_nonce because it was incorrect (we shouldn't generate padding, because
long double
was128
bits).