mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-13 22:08:45 +00:00
feat(c-api) Implement Drop for wasm_exporttype_t.
`wasm_exporttype_t` has 2 fields: `name` and `extern_type`. Both are of kind `NonNull`. When `wasm_exporttype_t` is dropped, nor `name` nor `extern_type` are going to be dropped. To avoid leaking data, this patch adds a new field: `owns_fields`: * When `wasm_exporttype_t` is built from `wasm_exportype_new`, this field is set to `false` because `name` and `extern_type` are received by pointer, and its the responsibility of the caller to free them, * When `wasm_exporttype_t` is built from the `From<&ExportType>` implementation, _we_ create `name` and `extern_type` to then leak them. In this case, it is safe to reconstruct proper `Box`es to finally drop them.
This commit is contained in:
@@ -6,6 +6,7 @@ use wasmer::ExportType;
|
||||
pub struct wasm_exporttype_t {
|
||||
name: NonNull<wasm_name_t>,
|
||||
extern_type: NonNull<wasm_externtype_t>,
|
||||
owns_fields: bool,
|
||||
}
|
||||
|
||||
wasm_declare_boxed_vec!(exporttype);
|
||||
@@ -15,7 +16,11 @@ pub extern "C" fn wasm_exporttype_new(
|
||||
name: NonNull<wasm_name_t>,
|
||||
extern_type: NonNull<wasm_externtype_t>,
|
||||
) -> Box<wasm_exporttype_t> {
|
||||
Box::new(wasm_exporttype_t { name, extern_type })
|
||||
Box::new(wasm_exporttype_t {
|
||||
name,
|
||||
extern_type,
|
||||
owns_fields: false,
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -33,6 +38,20 @@ pub extern "C" fn wasm_exporttype_type(
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wasm_exporttype_delete(_exporttype: Option<Box<wasm_exporttype_t>>) {}
|
||||
|
||||
impl Drop for wasm_exporttype_t {
|
||||
fn drop(&mut self) {
|
||||
if self.owns_fields {
|
||||
// SAFETY: `owns_fields` is set to `true` only in
|
||||
// `wasm_exporttype_t.from(&ExportType)`, where the data
|
||||
// are leaked properly and won't be freed somewhere else.
|
||||
unsafe {
|
||||
let _ = Box::from_raw(self.name.as_ptr());
|
||||
let _ = Box::from_raw(self.extern_type.as_ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ExportType> for wasm_exporttype_t {
|
||||
fn from(other: ExportType) -> Self {
|
||||
(&other).into()
|
||||
@@ -59,6 +78,10 @@ impl From<&ExportType> for wasm_exporttype_t {
|
||||
unsafe { NonNull::new_unchecked(Box::into_raw(Box::new(extern_type))) }
|
||||
};
|
||||
|
||||
wasm_exporttype_t { name, extern_type }
|
||||
wasm_exporttype_t {
|
||||
name,
|
||||
extern_type,
|
||||
owns_fields: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user