Auto merge of #907 - christianpoveda:env-vars-shim, r=RalfJung
Move env shims to its own module r? @RalfJung
This commit is contained in:
commit
868da2a139
4 changed files with 76 additions and 63 deletions
|
|
@ -39,7 +39,6 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
|
|||
Evaluator::new(config.communicate),
|
||||
MemoryExtra::new(StdRng::seed_from_u64(config.seed.unwrap_or(0)), config.validate),
|
||||
);
|
||||
|
||||
// Complete initialization.
|
||||
EnvVars::init(&mut ecx, config.communicate);
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ pub use crate::shims::foreign_items::EvalContextExt as ForeignItemsEvalContextEx
|
|||
pub use crate::shims::intrinsics::EvalContextExt as IntrinsicsEvalContextExt;
|
||||
pub use crate::shims::tls::{EvalContextExt as TlsEvalContextExt, TlsData};
|
||||
pub use crate::shims::dlsym::{Dlsym, EvalContextExt as DlsymEvalContextExt};
|
||||
pub use crate::shims::env::EnvVars;
|
||||
pub use crate::shims::env::{EnvVars, EvalContextExt as EnvEvalContextExt};
|
||||
pub use crate::operator::EvalContextExt as OperatorEvalContextExt;
|
||||
pub use crate::range_map::RangeMap;
|
||||
pub use crate::helpers::{EvalContextExt as HelpersEvalContextExt};
|
||||
|
|
|
|||
|
|
@ -22,21 +22,9 @@ impl EnvVars {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get(&self, name: &[u8]) -> Option<&Pointer<Tag>> {
|
||||
self.map.get(name)
|
||||
}
|
||||
|
||||
pub(crate) fn unset(&mut self, name: &[u8]) -> Option<Pointer<Tag>> {
|
||||
self.map.remove(name)
|
||||
}
|
||||
|
||||
pub(crate) fn set(&mut self, name: Vec<u8>, ptr: Pointer<Tag>) -> Option<Pointer<Tag>>{
|
||||
self.map.insert(name, ptr)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn alloc_env_value<'mir, 'tcx>(
|
||||
fn alloc_env_value<'mir, 'tcx>(
|
||||
bytes: &[u8],
|
||||
memory: &mut Memory<'mir, 'tcx, Evaluator<'tcx>>,
|
||||
) -> Pointer<Tag> {
|
||||
|
|
@ -58,3 +46,72 @@ pub(crate) fn alloc_env_value<'mir, 'tcx>(
|
|||
alloc.write_bytes(&tcx, trailing_zero_ptr, &[0]).unwrap();
|
||||
ptr
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
|
||||
fn getenv(
|
||||
&mut self,
|
||||
name_op: OpTy<'tcx, Tag>,
|
||||
) -> InterpResult<'tcx, Scalar<Tag>> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let name_ptr = this.read_scalar(name_op)?.not_undef()?;
|
||||
let name = this.memory().read_c_str(name_ptr)?;
|
||||
Ok(match this.machine.env_vars.map.get(name) {
|
||||
Some(&var) => Scalar::Ptr(var),
|
||||
None => Scalar::ptr_null(&*this.tcx),
|
||||
})
|
||||
}
|
||||
|
||||
fn setenv(
|
||||
&mut self,
|
||||
name_op: OpTy<'tcx, Tag>,
|
||||
value_op: OpTy<'tcx, Tag>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let name_ptr = this.read_scalar(name_op)?.not_undef()?;
|
||||
let value_ptr = this.read_scalar(value_op)?.not_undef()?;
|
||||
let value = this.memory().read_c_str(value_ptr)?;
|
||||
let mut new = None;
|
||||
if !this.is_null(name_ptr)? {
|
||||
let name = this.memory().read_c_str(name_ptr)?;
|
||||
if !name.is_empty() && !name.contains(&b'=') {
|
||||
new = Some((name.to_owned(), value.to_owned()));
|
||||
}
|
||||
}
|
||||
if let Some((name, value)) = new {
|
||||
let value_copy = alloc_env_value(&value, this.memory_mut());
|
||||
if let Some(var) = this.machine.env_vars.map.insert(name.to_owned(), value_copy) {
|
||||
this.memory_mut().deallocate(var, None, MiriMemoryKind::Env.into())?;
|
||||
}
|
||||
Ok(0)
|
||||
} else {
|
||||
Ok(-1)
|
||||
}
|
||||
}
|
||||
|
||||
fn unsetenv(
|
||||
&mut self,
|
||||
name_op: OpTy<'tcx, Tag>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let name_ptr = this.read_scalar(name_op)?.not_undef()?;
|
||||
let mut success = None;
|
||||
if !this.is_null(name_ptr)? {
|
||||
let name = this.memory().read_c_str(name_ptr)?.to_owned();
|
||||
if !name.is_empty() && !name.contains(&b'=') {
|
||||
success = Some(this.machine.env_vars.map.remove(&name));
|
||||
}
|
||||
}
|
||||
if let Some(old) = success {
|
||||
if let Some(var) = old {
|
||||
this.memory_mut().deallocate(var, None, MiriMemoryKind::Env.into())?;
|
||||
}
|
||||
Ok(0)
|
||||
} else {
|
||||
Ok(-1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ use syntax::attr;
|
|||
use syntax::symbol::sym;
|
||||
|
||||
use crate::*;
|
||||
use crate::shims::env::alloc_env_value;
|
||||
|
||||
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
|
||||
|
|
@ -423,60 +422,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
}
|
||||
|
||||
"getenv" => {
|
||||
let result = {
|
||||
let name_ptr = this.read_scalar(args[0])?.not_undef()?;
|
||||
let name = this.memory().read_c_str(name_ptr)?;
|
||||
match this.machine.env_vars.get(name) {
|
||||
Some(&var) => Scalar::Ptr(var),
|
||||
None => Scalar::ptr_null(&*this.tcx),
|
||||
}
|
||||
};
|
||||
let result = this.getenv(args[0])?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
||||
"unsetenv" => {
|
||||
let mut success = None;
|
||||
{
|
||||
let name_ptr = this.read_scalar(args[0])?.not_undef()?;
|
||||
if !this.is_null(name_ptr)? {
|
||||
let name = this.memory().read_c_str(name_ptr)?.to_owned();
|
||||
if !name.is_empty() && !name.contains(&b'=') {
|
||||
success = Some(this.machine.env_vars.unset(&name));
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(old) = success {
|
||||
if let Some(var) = old {
|
||||
this.memory_mut().deallocate(var, None, MiriMemoryKind::Env.into())?;
|
||||
}
|
||||
this.write_null(dest)?;
|
||||
} else {
|
||||
this.write_scalar(Scalar::from_int(-1, dest.layout.size), dest)?;
|
||||
}
|
||||
let result = this.unsetenv(args[0])?;
|
||||
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
|
||||
}
|
||||
|
||||
"setenv" => {
|
||||
let mut new = None;
|
||||
{
|
||||
let name_ptr = this.read_scalar(args[0])?.not_undef()?;
|
||||
let value_ptr = this.read_scalar(args[1])?.not_undef()?;
|
||||
let value = this.memory().read_c_str(value_ptr)?;
|
||||
if !this.is_null(name_ptr)? {
|
||||
let name = this.memory().read_c_str(name_ptr)?;
|
||||
if !name.is_empty() && !name.contains(&b'=') {
|
||||
new = Some((name.to_owned(), value.to_owned()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some((name, value)) = new {
|
||||
let value_copy = alloc_env_value(&value, this.memory_mut());
|
||||
if let Some(var) = this.machine.env_vars.set(name.to_owned(), value_copy) {
|
||||
this.memory_mut().deallocate(var, None, MiriMemoryKind::Env.into())?;
|
||||
}
|
||||
this.write_null(dest)?;
|
||||
} else {
|
||||
this.write_scalar(Scalar::from_int(-1, dest.layout.size), dest)?;
|
||||
}
|
||||
let result = this.setenv(args[0], args[1])?;
|
||||
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
|
||||
}
|
||||
|
||||
"write" => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue