Skip to content

Commit

Permalink
Merge #576
Browse files Browse the repository at this point in the history
576: fix Drop of uninit Ctx; use MaybeUninit r=MarkMcCaskey a=MarkMcCaskey

I'm somewhat concerned that we need to call
`intrinsics::panic_if_uninhabited::<T>();` or something to tell the compiler that we know it's safe.

We just reinterpret the pointer later as initialized which is safe in theory due to `repr(transparent)`

this should unblock #561

Co-authored-by: Mark McCaskey <mark@wasmer.io>
  • Loading branch information
bors[bot] and Mark McCaskey committed Jul 24, 2019
2 parents dbfd1c6 + 3c952f3 commit e3bb365
Showing 1 changed file with 17 additions and 17 deletions.
34 changes: 17 additions & 17 deletions lib/runtime-core/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
vm::{self, InternalField},
};
use smallvec::{smallvec, SmallVec};
use std::{mem, ptr::NonNull, sync::Arc};
use std::{mem, pin::Pin, ptr::NonNull, sync::Arc};

pub(crate) struct InstanceInner {
#[allow(dead_code)]
Expand All @@ -41,7 +41,7 @@ impl Drop for InstanceInner {
/// [`ImportObject`]: struct.ImportObject.html
pub struct Instance {
pub module: Arc<ModuleInner>,
inner: Box<InstanceInner>,
inner: Pin<Box<InstanceInner>>,
#[allow(dead_code)]
import_object: ImportObject,
}
Expand All @@ -51,32 +51,32 @@ impl Instance {
// We need the backing and import_backing to create a vm::Ctx, but we need
// a vm::Ctx to create a backing and an import_backing. The solution is to create an
// uninitialized vm::Ctx and then initialize it in-place.
let mut vmctx = unsafe { Box::new(mem::uninitialized()) };
let mut vmctx: Box<mem::MaybeUninit<vm::Ctx>> =
Box::new(mem::MaybeUninit::<vm::Ctx>::zeroed());

let import_backing = ImportBacking::new(&module, &imports, &mut *vmctx)?;
let backing = LocalBacking::new(&module, &import_backing, &mut *vmctx);
let import_backing = ImportBacking::new(&module, &imports, vmctx.as_mut_ptr())?;
let backing = LocalBacking::new(&module, &import_backing, vmctx.as_mut_ptr());

// When Pin is stablized, this will use `Box::pinned` instead of `Box::new`.
let mut inner = Box::new(InstanceInner {
let mut inner = Box::pin(InstanceInner {
backing,
import_backing,
vmctx: Box::leak(vmctx),
vmctx: vmctx.as_mut_ptr(),
});

// Initialize the vm::Ctx in-place after the backing
// has been boxed.
unsafe {
*inner.vmctx = match imports.call_state_creator() {
Some((data, dtor)) => vm::Ctx::new_with_data(
&mut inner.backing,
&mut inner.import_backing,
&module,
data,
dtor,
),
None => vm::Ctx::new(&mut inner.backing, &mut inner.import_backing, &module),
let backing = &mut *(&mut inner.backing as *mut _);
let import_backing = &mut *(&mut inner.import_backing as *mut _);
let real_ctx = match imports.call_state_creator() {
Some((data, dtor)) => {
vm::Ctx::new_with_data(backing, import_backing, &module, data, dtor)
}
None => vm::Ctx::new(backing, import_backing, &module),
};
vmctx.as_mut_ptr().write(real_ctx);
};
Box::leak(vmctx);

let instance = Instance {
module,
Expand Down

0 comments on commit e3bb365

Please sign in to comment.