@@ -22,21 +22,9 @@ impl EnvVars {
22
22
}
23
23
}
24
24
}
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
- }
37
25
}
38
26
39
- pub ( crate ) fn alloc_env_value < ' mir , ' tcx > (
27
+ fn alloc_env_value < ' mir , ' tcx > (
40
28
bytes : & [ u8 ] ,
41
29
memory : & mut Memory < ' mir , ' tcx , Evaluator < ' tcx > > ,
42
30
) -> Pointer < Tag > {
@@ -58,3 +46,81 @@ pub(crate) fn alloc_env_value<'mir, 'tcx>(
58
46
alloc. write_bytes ( & tcx, trailing_zero_ptr, & [ 0 ] ) . unwrap ( ) ;
59
47
ptr
60
48
}
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