@@ -22,21 +22,9 @@ impl EnvVars {
2222 }
2323 }
2424 }
25-
26- pub ( crate ) fn get ( & self , name : & [ u8 ] ) -> Option < & Pointer < Tag > > {
27- self . map . get ( name)
28- }
29-
30- pub ( crate ) fn unset ( & mut self , name : & [ u8 ] ) -> Option < Pointer < Tag > > {
31- self . map . remove ( name)
32- }
33-
34- pub ( crate ) fn set ( & mut self , name : Vec < u8 > , ptr : Pointer < Tag > ) -> Option < Pointer < Tag > > {
35- self . map . insert ( name, ptr)
36- }
3725}
3826
39- pub ( crate ) fn alloc_env_value < ' mir , ' tcx > (
27+ fn alloc_env_value < ' mir , ' tcx > (
4028 bytes : & [ u8 ] ,
4129 memory : & mut Memory < ' mir , ' tcx , Evaluator < ' tcx > > ,
4230) -> Pointer < Tag > {
@@ -58,3 +46,81 @@ pub(crate) fn alloc_env_value<'mir, 'tcx>(
5846 alloc. write_bytes ( & tcx, trailing_zero_ptr, & [ 0 ] ) . unwrap ( ) ;
5947 ptr
6048}
49+
50+ impl < ' mir , ' tcx > EvalContextExt < ' mir , ' tcx > for crate :: MiriEvalContext < ' mir , ' tcx > { }
51+ pub trait EvalContextExt < ' mir , ' tcx : ' mir > : crate :: MiriEvalContextExt < ' mir , ' tcx > {
52+ fn getenv (
53+ & mut self ,
54+ name_op : OpTy < ' tcx , Tag > ,
55+ dest : PlaceTy < ' tcx , Tag >
56+ ) -> InterpResult < ' tcx > {
57+ let this = self . eval_context_mut ( ) ;
58+
59+ let result = {
60+ let name_ptr = this. read_scalar ( name_op) ?. not_undef ( ) ?;
61+ let name = this. memory ( ) . read_c_str ( name_ptr) ?;
62+ match this. machine . env_vars . map . get ( name) {
63+ Some ( & var) => Scalar :: Ptr ( var) ,
64+ None => Scalar :: ptr_null ( & * this. tcx ) ,
65+ }
66+ } ;
67+ this. write_scalar ( result, dest) ?;
68+ Ok ( ( ) )
69+ }
70+
71+ fn setenv (
72+ & mut self ,
73+ name_op : OpTy < ' tcx , Tag > ,
74+ value_op : OpTy < ' tcx , Tag > ,
75+ dest : PlaceTy < ' tcx , Tag >
76+ ) -> InterpResult < ' tcx > {
77+ let this = self . eval_context_mut ( ) ;
78+
79+ let mut new = None ;
80+ let name_ptr = this. read_scalar ( name_op) ?. not_undef ( ) ?;
81+ let value_ptr = this. read_scalar ( value_op) ?. not_undef ( ) ?;
82+ let value = this. memory ( ) . read_c_str ( value_ptr) ?;
83+ if !this. is_null ( name_ptr) ? {
84+ let name = this. memory ( ) . read_c_str ( name_ptr) ?;
85+ if !name. is_empty ( ) && !name. contains ( & b'=' ) {
86+ new = Some ( ( name. to_owned ( ) , value. to_owned ( ) ) ) ;
87+ }
88+ }
89+ if let Some ( ( name, value) ) = new {
90+ let value_copy = alloc_env_value ( & value, this. memory_mut ( ) ) ;
91+ if let Some ( var) = this. machine . env_vars . map . insert ( name. to_owned ( ) , value_copy) {
92+ this. memory_mut ( ) . deallocate ( var, None , MiriMemoryKind :: Env . into ( ) ) ?;
93+ }
94+ this. write_null ( dest) ?;
95+ } else {
96+ this. write_scalar ( Scalar :: from_int ( -1 , dest. layout . size ) , dest) ?;
97+ }
98+ Ok ( ( ) )
99+ }
100+
101+ fn unsetenv (
102+ & mut self ,
103+ name_op : OpTy < ' tcx , Tag > ,
104+ dest : PlaceTy < ' tcx , Tag >
105+ ) -> InterpResult < ' tcx > {
106+ let this = self . eval_context_mut ( ) ;
107+
108+ let mut success = None ;
109+ let name_ptr = this. read_scalar ( name_op) ?. not_undef ( ) ?;
110+ if !this. is_null ( name_ptr) ? {
111+ let name = this. memory ( ) . read_c_str ( name_ptr) ?. to_owned ( ) ;
112+ if !name. is_empty ( ) && !name. contains ( & b'=' ) {
113+ success = Some ( this. machine . env_vars . map . remove ( & name) ) ;
114+ }
115+ }
116+ if let Some ( old) = success {
117+ if let Some ( var) = old {
118+ this. memory_mut ( ) . deallocate ( var, None , MiriMemoryKind :: Env . into ( ) ) ?;
119+ }
120+ this. write_null ( dest) ?;
121+ } else {
122+ this. write_scalar ( Scalar :: from_int ( -1 , dest. layout . size ) , dest) ?;
123+ }
124+ Ok ( ( ) )
125+ }
126+ }
0 commit comments