-
Notifications
You must be signed in to change notification settings - Fork 530
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
fix(bindings/c): use ManuallyDrop
instead of forget
to make sure pointer is valid
#5166
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,25 +34,37 @@ pub struct opendal_bytes { | |
pub data: *const u8, | ||
/// The length of the byte array | ||
pub len: usize, | ||
/// The capacity of the byte array | ||
pub capacity: usize, | ||
} | ||
|
||
impl opendal_bytes { | ||
/// Construct a [`opendal_bytes`] from the Rust [`Vec`] of bytes | ||
pub(crate) fn new(buf: Buffer) -> Self { | ||
let vec = buf.to_vec(); | ||
let data = vec.as_ptr(); | ||
let len = vec.len(); | ||
std::mem::forget(vec); | ||
Self { data, len } | ||
let mut buf = std::mem::ManuallyDrop::new(vec); | ||
let data = buf.as_mut_ptr(); | ||
let len = buf.len(); | ||
let capacity = buf.capacity(); | ||
Self { | ||
data, | ||
len, | ||
capacity, | ||
} | ||
} | ||
|
||
/// \brief Frees the heap memory used by the opendal_bytes | ||
#[no_mangle] | ||
pub unsafe extern "C" fn opendal_bytes_free(ptr: *mut opendal_bytes) { | ||
if !ptr.is_null() { | ||
let data_mut = (*ptr).data as *mut u8; | ||
drop(Vec::from_raw_parts(data_mut, (*ptr).len, (*ptr).len)); | ||
drop(Box::from_raw(ptr)); | ||
// transmuting `*const u8` to `*mut u8` is undefined behavior in any cases | ||
// however, fields type of `opendal_bytes` is already related to the zig binding | ||
// it should be fixed later | ||
let _ = Vec::from_raw_parts((*ptr).data as *mut u8, (*ptr).len, (*ptr).capacity); | ||
// it is too weird that call `Box::new` outside `opendal_bytes::new` but dealloc it here | ||
// also, boxing `opendal_bytes` might not be necessary | ||
// `data` points to heap, so `opendal_bytes` could be passed as a stack value | ||
Comment on lines
+64
to
+66
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reasonable. But IIRC other bindings rely on this interface also. We can update them all in a follow-up. Then the free method is guarded by There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Try in #5171 |
||
let _ = Box::from_raw(ptr); | ||
} | ||
} | ||
} | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this is the real reason my previous patch failed, lol. This can be a hidden knowledge that Go binding's struct should be synced with C binding's .. |
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 you mean that the Zig binding should use non-const pointer also?
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.
Yes, I think so