don't always allocate during init
intrinsic processing
This commit is contained in:
parent
b3bf730513
commit
bf73e7581e
1 changed files with 48 additions and 5 deletions
|
@ -6,7 +6,7 @@ use rustc::ty::{self, Ty};
|
||||||
|
|
||||||
use error::{EvalError, EvalResult};
|
use error::{EvalError, EvalResult};
|
||||||
use interpreter::value::Value;
|
use interpreter::value::Value;
|
||||||
use interpreter::{EvalContext, Lvalue};
|
use interpreter::{EvalContext, Lvalue, LvalueExtra};
|
||||||
use primval::{self, PrimVal, PrimValKind};
|
use primval::{self, PrimVal, PrimValKind};
|
||||||
|
|
||||||
impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||||
|
@ -126,11 +126,54 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||||
"forget" => {}
|
"forget" => {}
|
||||||
|
|
||||||
"init" => {
|
"init" => {
|
||||||
// FIXME(solson)
|
|
||||||
let dest = self.force_allocation(dest)?.to_ptr();
|
|
||||||
|
|
||||||
let size = dest_layout.size(&self.tcx.data_layout).bytes() as usize;
|
let size = dest_layout.size(&self.tcx.data_layout).bytes() as usize;
|
||||||
self.memory.write_repeat(dest, 0, size)?;
|
match dest {
|
||||||
|
Lvalue::Local { frame, local } => {
|
||||||
|
match self.stack[frame].get_local(local) {
|
||||||
|
Some(Value::ByRef(ptr)) => self.memory.write_repeat(ptr, 0, size)?,
|
||||||
|
None => match self.ty_to_primval_kind(dest_ty) {
|
||||||
|
Ok(kind) => self.stack[frame].set_local(local, Value::ByVal(PrimVal::new(0, kind))),
|
||||||
|
Err(_) => {
|
||||||
|
let ptr = self.alloc_ptr_with_substs(dest_ty, substs)?;
|
||||||
|
self.memory.write_repeat(ptr, 0, size)?;
|
||||||
|
self.stack[frame].set_local(local, Value::ByRef(ptr));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Some(Value::ByVal(val)) => self.stack[frame].set_local(local, Value::ByVal(PrimVal::new(0, val.kind))),
|
||||||
|
Some(Value::ByValPair(a, b)) => self.stack[frame].set_local(local, Value::ByValPair(
|
||||||
|
PrimVal::new(0, a.kind),
|
||||||
|
PrimVal::new(0, b.kind),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Lvalue::Ptr { ptr, extra: LvalueExtra::None } => self.memory.write_repeat(ptr, 0, size)?,
|
||||||
|
Lvalue::Ptr { .. } => bug!("init intrinsic tried to write to fat ptr target"),
|
||||||
|
Lvalue::Global(cid) => {
|
||||||
|
let global_val = *self.globals.get(&cid).expect("global not cached");
|
||||||
|
if !global_val.mutable {
|
||||||
|
return Err(EvalError::ModifiedConstantMemory);
|
||||||
|
}
|
||||||
|
match global_val.data {
|
||||||
|
Some(Value::ByRef(ptr)) => self.memory.write_repeat(ptr, 0, size)?,
|
||||||
|
None => match self.ty_to_primval_kind(dest_ty) {
|
||||||
|
Ok(kind) => self.globals
|
||||||
|
.get_mut(&cid)
|
||||||
|
.expect("already checked")
|
||||||
|
.data = Some(Value::ByVal(PrimVal::new(0, kind))),
|
||||||
|
Err(_) => {
|
||||||
|
let ptr = self.alloc_ptr_with_substs(dest_ty, substs)?;
|
||||||
|
self.memory.write_repeat(ptr, 0, size)?;
|
||||||
|
self.globals.get_mut(&cid).expect("already checked").data = Some(Value::ByRef(ptr));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Some(Value::ByVal(val)) => self.globals.get_mut(&cid).expect("already checked").data = Some(Value::ByVal(PrimVal::new(0, val.kind))),
|
||||||
|
Some(Value::ByValPair(a, b)) => self.globals.get_mut(&cid).expect("already checked").data = Some(Value::ByValPair(
|
||||||
|
PrimVal::new(0, a.kind),
|
||||||
|
PrimVal::new(0, b.kind),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"min_align_of" => {
|
"min_align_of" => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue