Skip to content

Commit

Permalink
Auto merge of #907 - christianpoveda:env-vars-shim, r=RalfJung
Browse files Browse the repository at this point in the history
Move env shims to its own module

r? @RalfJung
  • Loading branch information
bors committed Aug 15, 2019
2 parents 1f504ea + aee8f17 commit 868da2a
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 63 deletions.
1 change: 0 additions & 1 deletion src/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
83 changes: 70 additions & 13 deletions src/shims/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand All @@ -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)
}
}
}
53 changes: 5 additions & 48 deletions src/shims/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -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" => {
Expand Down

0 comments on commit 868da2a

Please sign in to comment.