Partially implement reallocation (e.g. for growing Vecs).
This commit is contained in:
parent
8d3d8af67a
commit
f472018fbb
@ -530,6 +530,17 @@ impl<'a, 'tcx: 'a, 'arena> Interpreter<'a, 'tcx, 'arena> {
|
||||
try!(self.memory.write_ptr(dest, ptr));
|
||||
}
|
||||
|
||||
"__rust_reallocate" => {
|
||||
let ptr_arg = try!(self.eval_operand(&args[0]));
|
||||
let _old_size_arg = try!(self.eval_operand(&args[1]));
|
||||
let size_arg = try!(self.eval_operand(&args[2]));
|
||||
let _align_arg = try!(self.eval_operand(&args[3]));
|
||||
let ptr = try!(self.memory.read_ptr(ptr_arg));
|
||||
let size = try!(self.memory.read_usize(size_arg));
|
||||
try!(self.memory.reallocate(ptr, size as usize));
|
||||
try!(self.memory.write_ptr(dest, ptr));
|
||||
}
|
||||
|
||||
_ => panic!("can't call C ABI function: {}", link_name),
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ pub struct AllocId(u64);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Allocation {
|
||||
pub bytes: Box<[u8]>,
|
||||
pub bytes: Vec<u8>,
|
||||
pub relocations: BTreeMap<usize, AllocId>,
|
||||
pub undef_mask: UndefMask,
|
||||
}
|
||||
@ -104,7 +104,7 @@ impl Memory {
|
||||
pub fn allocate(&mut self, size: usize) -> Pointer {
|
||||
let id = AllocId(self.next_id);
|
||||
let alloc = Allocation {
|
||||
bytes: vec![0; size].into_boxed_slice(),
|
||||
bytes: vec![0; size],
|
||||
relocations: BTreeMap::new(),
|
||||
undef_mask: UndefMask::new(size),
|
||||
};
|
||||
@ -116,6 +116,30 @@ impl Memory {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(tsion): Track which allocations were returned from __rust_allocate and report an error
|
||||
// when reallocating/deallocating any others.
|
||||
pub fn reallocate(&mut self, ptr: Pointer, new_size: usize) -> EvalResult<()> {
|
||||
if ptr.offset != 0 {
|
||||
// TODO(tsion): Report error about non-__rust_allocate'd pointer.
|
||||
panic!()
|
||||
}
|
||||
|
||||
let alloc = try!(self.get_mut(ptr.alloc_id));
|
||||
let size = alloc.bytes.len();
|
||||
if new_size > size {
|
||||
let amount = new_size - size;
|
||||
alloc.bytes.extend(iter::repeat(0).take(amount));
|
||||
alloc.undef_mask.grow(amount, false);
|
||||
} else if size > new_size {
|
||||
unimplemented!()
|
||||
// alloc.bytes.truncate(new_size);
|
||||
// alloc.undef_mask.len = new_size;
|
||||
// TODO: potentially remove relocations
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Allocation accessors
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
13
test/vecs.rs
13
test/vecs.rs
@ -2,7 +2,7 @@
|
||||
#![allow(dead_code, unused_attributes)]
|
||||
|
||||
#[miri_run]
|
||||
fn make_vec() -> Vec<i32> {
|
||||
fn make_vec() -> Vec<u8> {
|
||||
let mut v = Vec::with_capacity(4);
|
||||
v.push(1);
|
||||
v.push(2);
|
||||
@ -10,7 +10,7 @@ fn make_vec() -> Vec<i32> {
|
||||
}
|
||||
|
||||
#[miri_run]
|
||||
fn make_vec_macro() -> Vec<i32> {
|
||||
fn make_vec_macro() -> Vec<u8> {
|
||||
vec![1, 2]
|
||||
}
|
||||
|
||||
@ -23,3 +23,12 @@ fn make_vec_macro_repeat() -> Vec<u8> {
|
||||
fn vec_into_iter() -> i32 {
|
||||
vec![1, 2, 3, 4].into_iter().fold(0, |x, y| x + y)
|
||||
}
|
||||
|
||||
#[miri_run]
|
||||
fn vec_reallocate() -> Vec<u8> {
|
||||
let mut v = vec![1, 2];
|
||||
v.push(3);
|
||||
v.push(4);
|
||||
v.push(5);
|
||||
v
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user