Skip to content

Commit 4771879

Browse files
committed
rename deref_operand → deref_pointer and some Miri helper functions
1 parent ff1e280 commit 4771879

File tree

18 files changed

+73
-73
lines changed

18 files changed

+73
-73
lines changed

src/concurrency/sync.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ pub(super) trait EvalContextExtPriv<'mir, 'tcx: 'mir>:
206206
) -> InterpResult<'tcx, Option<Id>> {
207207
let this = self.eval_context_mut();
208208
let value_place =
209-
this.deref_operand_and_offset(lock_op, offset, lock_layout, this.machine.layouts.u32)?;
209+
this.deref_pointer_and_offset(lock_op, offset, lock_layout, this.machine.layouts.u32)?;
210210

211211
// Since we are lazy, this update has to be atomic.
212212
let (old, success) = this

src/helpers.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -715,9 +715,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
715715
}
716716

717717
/// Dereference a pointer operand to a place using `layout` instead of the pointer's declared type
718-
fn deref_operand_as(
718+
fn deref_pointer_as(
719719
&self,
720-
op: &OpTy<'tcx, Provenance>,
720+
op: &impl Readable<'tcx, Provenance>,
721721
layout: TyAndLayout<'tcx>,
722722
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> {
723723
let this = self.eval_context_ref();
@@ -746,15 +746,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
746746
}
747747

748748
/// Calculates the MPlaceTy given the offset and layout of an access on an operand
749-
fn deref_operand_and_offset(
749+
fn deref_pointer_and_offset(
750750
&self,
751-
op: &OpTy<'tcx, Provenance>,
751+
op: &impl Readable<'tcx, Provenance>,
752752
offset: u64,
753753
base_layout: TyAndLayout<'tcx>,
754754
value_layout: TyAndLayout<'tcx>,
755755
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> {
756756
let this = self.eval_context_ref();
757-
let op_place = this.deref_operand_as(op, base_layout)?;
757+
let op_place = this.deref_pointer_as(op, base_layout)?;
758758
let offset = Size::from_bytes(offset);
759759

760760
// Ensure that the access is within bounds.
@@ -763,28 +763,28 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
763763
Ok(value_place)
764764
}
765765

766-
fn read_scalar_at_offset(
766+
fn deref_pointer_and_read(
767767
&self,
768-
op: &OpTy<'tcx, Provenance>,
768+
op: &impl Readable<'tcx, Provenance>,
769769
offset: u64,
770770
base_layout: TyAndLayout<'tcx>,
771771
value_layout: TyAndLayout<'tcx>,
772772
) -> InterpResult<'tcx, Scalar<Provenance>> {
773773
let this = self.eval_context_ref();
774-
let value_place = this.deref_operand_and_offset(op, offset, base_layout, value_layout)?;
774+
let value_place = this.deref_pointer_and_offset(op, offset, base_layout, value_layout)?;
775775
this.read_scalar(&value_place)
776776
}
777777

778-
fn write_scalar_at_offset(
778+
fn deref_pointer_and_write(
779779
&mut self,
780-
op: &OpTy<'tcx, Provenance>,
780+
op: &impl Readable<'tcx, Provenance>,
781781
offset: u64,
782782
value: impl Into<Scalar<Provenance>>,
783783
base_layout: TyAndLayout<'tcx>,
784784
value_layout: TyAndLayout<'tcx>,
785785
) -> InterpResult<'tcx, ()> {
786786
let this = self.eval_context_mut();
787-
let value_place = this.deref_operand_and_offset(op, offset, base_layout, value_layout)?;
787+
let value_place = this.deref_pointer_and_offset(op, offset, base_layout, value_layout)?;
788788
this.write_scalar(value, &value_place)
789789
}
790790

src/shims/backtrace.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
9797
1 => {
9898
let [_flags, buf] = this.check_shim(abi, Abi::Rust, link_name, args)?;
9999

100-
let buf_place = this.deref_operand(buf)?;
100+
let buf_place = this.deref_pointer(buf)?;
101101

102102
let ptr_layout = this.layout_of(ptr_ty)?;
103103

src/shims/foreign_items.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -418,9 +418,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
418418
// // First thing: load all the arguments. Details depend on the shim.
419419
// let arg1 = this.read_scalar(arg1)?.to_u32()?;
420420
// let arg2 = this.read_pointer(arg2)?; // when you need to work with the pointer directly
421-
// let arg3 = this.deref_operand_as(arg3, this.libc_ty_layout("some_libc_struct"))?; // when you want to load/store
421+
// let arg3 = this.deref_pointer_as(arg3, this.libc_ty_layout("some_libc_struct"))?; // when you want to load/store
422422
// // through the pointer and supply the type information yourself
423-
// let arg4 = this.deref_operand(arg4)?; // when you want to load/store through the pointer and trust
423+
// let arg4 = this.deref_pointer(arg4)?; // when you want to load/store through the pointer and trust
424424
// // the user-given type (which you shouldn't usually do)
425425
//
426426
// // ...

src/shims/intrinsics/atomic.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
130130
let this = self.eval_context_mut();
131131

132132
let [place] = check_arg_count(args)?;
133-
let place = this.deref_operand(place)?;
133+
let place = this.deref_pointer(place)?;
134134

135135
// Perform atomic load.
136136
let val = this.read_scalar_atomic(&place, atomic)?;
@@ -147,7 +147,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
147147
let this = self.eval_context_mut();
148148

149149
let [place, val] = check_arg_count(args)?;
150-
let place = this.deref_operand(place)?;
150+
let place = this.deref_pointer(place)?;
151151

152152
// Perform regular load.
153153
let val = this.read_scalar(val)?;
@@ -188,7 +188,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
188188
let this = self.eval_context_mut();
189189

190190
let [place, rhs] = check_arg_count(args)?;
191-
let place = this.deref_operand(place)?;
191+
let place = this.deref_pointer(place)?;
192192
let rhs = this.read_immediate(rhs)?;
193193

194194
if !place.layout.ty.is_integral() && !place.layout.ty.is_unsafe_ptr() {
@@ -229,7 +229,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
229229
let this = self.eval_context_mut();
230230

231231
let [place, new] = check_arg_count(args)?;
232-
let place = this.deref_operand(place)?;
232+
let place = this.deref_pointer(place)?;
233233
let new = this.read_scalar(new)?;
234234

235235
let old = this.atomic_exchange_scalar(&place, new, atomic)?;
@@ -248,7 +248,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
248248
let this = self.eval_context_mut();
249249

250250
let [place, expect_old, new] = check_arg_count(args)?;
251-
let place = this.deref_operand(place)?;
251+
let place = this.deref_pointer(place)?;
252252
let expect_old = this.read_immediate(expect_old)?; // read as immediate for the sake of `binary_op()`
253253
let new = this.read_scalar(new)?;
254254

src/shims/intrinsics/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
9696
// Raw memory accesses
9797
"volatile_load" => {
9898
let [place] = check_arg_count(args)?;
99-
let place = this.deref_operand(place)?;
99+
let place = this.deref_pointer(place)?;
100100
this.copy_op(&place, dest, /*allow_transmute*/ false)?;
101101
}
102102
"volatile_store" => {
103103
let [place, dest] = check_arg_count(args)?;
104-
let place = this.deref_operand(place)?;
104+
let place = this.deref_pointer(place)?;
105105
this.copy_op(dest, &place, /*allow_transmute*/ false)?;
106106
}
107107

src/shims/intrinsics/simd.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
534534
let dest = this.project_index(&dest, i)?;
535535

536536
let val = if simd_element_to_bool(mask)? {
537-
let place = this.deref_operand(&ptr)?;
537+
let place = this.deref_pointer(&ptr)?;
538538
this.read_immediate(&place)?
539539
} else {
540540
passthru
@@ -557,7 +557,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
557557
let mask = this.read_immediate(&this.project_index(&mask, i)?)?;
558558

559559
if simd_element_to_bool(mask)? {
560-
let place = this.deref_operand(&ptr)?;
560+
let place = this.deref_pointer(&ptr)?;
561561
this.write_immediate(*value, &place)?;
562562
}
563563
}

src/shims/time.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
2525
this.assert_target_os_is_unix("clock_gettime");
2626

2727
let clk_id = this.read_scalar(clk_id_op)?.to_i32()?;
28-
let tp = this.deref_operand_as(tp_op, this.libc_ty_layout("timespec"))?;
28+
let tp = this.deref_pointer_as(tp_op, this.libc_ty_layout("timespec"))?;
2929

3030
let absolute_clocks;
3131
let mut relative_clocks;
@@ -92,7 +92,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
9292
this.assert_target_os_is_unix("gettimeofday");
9393
this.check_no_isolation("`gettimeofday`")?;
9494

95-
let tv = this.deref_operand_as(tv_op, this.libc_ty_layout("timeval"))?;
95+
let tv = this.deref_pointer_as(tv_op, this.libc_ty_layout("timeval"))?;
9696

9797
// Using tz is obsolete and should always be null
9898
let tz = this.read_pointer(tz_op)?;
@@ -121,7 +121,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
121121
this.assert_target_os("windows", "GetSystemTimeAsFileTime");
122122
this.check_no_isolation("`GetSystemTimeAsFileTime`")?;
123123

124-
let filetime = this.deref_operand_as(LPFILETIME_op, this.windows_ty_layout("FILETIME"))?;
124+
let filetime = this.deref_pointer_as(LPFILETIME_op, this.windows_ty_layout("FILETIME"))?;
125125

126126
let NANOS_PER_SEC = this.eval_windows_u64("time", "NANOS_PER_SEC");
127127
let INTERVALS_PER_SEC = this.eval_windows_u64("time", "INTERVALS_PER_SEC");
@@ -156,7 +156,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
156156
let qpc = i64::try_from(duration.as_nanos()).map_err(|_| {
157157
err_unsup_format!("programs running longer than 2^63 nanoseconds are not supported")
158158
})?;
159-
this.write_scalar(Scalar::from_i64(qpc), &this.deref_operand(lpPerformanceCount_op)?)?;
159+
this.write_scalar(Scalar::from_i64(qpc), &this.deref_pointer(lpPerformanceCount_op)?)?;
160160
Ok(Scalar::from_i32(-1)) // return non-zero on success
161161
}
162162

@@ -176,7 +176,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
176176
// and thus 10^9 counts per second.
177177
this.write_scalar(
178178
Scalar::from_i64(1_000_000_000),
179-
&this.deref_operand_as(lpFrequency_op, this.machine.layouts.u64)?,
179+
&this.deref_pointer_as(lpFrequency_op, this.machine.layouts.u64)?,
180180
)?;
181181
Ok(Scalar::from_i32(-1)) // Return non-zero on success
182182
}
@@ -203,7 +203,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
203203

204204
this.assert_target_os("macos", "mach_timebase_info");
205205

206-
let info = this.deref_operand_as(info_op, this.libc_ty_layout("mach_timebase_info"))?;
206+
let info = this.deref_pointer_as(info_op, this.libc_ty_layout("mach_timebase_info"))?;
207207

208208
// Since our emulated ticks in `mach_absolute_time` *are* nanoseconds,
209209
// no scaling needs to happen.
@@ -222,7 +222,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
222222

223223
this.assert_target_os_is_unix("nanosleep");
224224

225-
let req = this.deref_operand_as(req_op, this.libc_ty_layout("timespec"))?;
225+
let req = this.deref_pointer_as(req_op, this.libc_ty_layout("timespec"))?;
226226

227227
let duration = match this.read_timespec(&req)? {
228228
Some(duration) => duration,

src/shims/unix/foreign_items.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
191191
// Allocation
192192
"posix_memalign" => {
193193
let [ret, align, size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
194-
let ret = this.deref_operand(ret)?;
194+
let ret = this.deref_pointer(ret)?;
195195
let align = this.read_target_usize(align)?;
196196
let size = this.read_target_usize(size)?;
197197
// Align must be power of 2, and also at least ptr-sized (POSIX rules).
@@ -271,7 +271,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
271271
// Thread-local storage
272272
"pthread_key_create" => {
273273
let [key, dtor] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
274-
let key_place = this.deref_operand_as(key, this.libc_ty_layout("pthread_key_t"))?;
274+
let key_place = this.deref_pointer_as(key, this.libc_ty_layout("pthread_key_t"))?;
275275
let dtor = this.read_pointer(dtor)?;
276276

277277
// Extract the function type out of the signature (that seems easier than constructing it ourselves).
@@ -506,7 +506,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
506506
"pthread_attr_getguardsize"
507507
if this.frame_in_std() => {
508508
let [_attr, guard_size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
509-
let guard_size = this.deref_operand(guard_size)?;
509+
let guard_size = this.deref_pointer(guard_size)?;
510510
let guard_size_layout = this.libc_ty_layout("size_t");
511511
this.write_scalar(Scalar::from_uint(this.machine.page_size, guard_size_layout.size), &guard_size)?;
512512

@@ -532,9 +532,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
532532
// Hence we can mostly ignore the input `attr_place`.
533533
let [attr_place, addr_place, size_place] =
534534
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
535-
let _attr_place = this.deref_operand_as(attr_place, this.libc_ty_layout("pthread_attr_t"))?;
536-
let addr_place = this.deref_operand(addr_place)?;
537-
let size_place = this.deref_operand(size_place)?;
535+
let _attr_place = this.deref_pointer_as(attr_place, this.libc_ty_layout("pthread_attr_t"))?;
536+
let addr_place = this.deref_pointer(addr_place)?;
537+
let size_place = this.deref_pointer(size_place)?;
538538

539539
this.write_scalar(
540540
Scalar::from_uint(this.machine.stack_addr, this.pointer_size()),
@@ -575,10 +575,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
575575
this.check_no_isolation("`getpwuid_r`")?;
576576

577577
let uid = this.read_scalar(uid)?.to_u32()?;
578-
let pwd = this.deref_operand_as(pwd, this.libc_ty_layout("passwd"))?;
578+
let pwd = this.deref_pointer_as(pwd, this.libc_ty_layout("passwd"))?;
579579
let buf = this.read_pointer(buf)?;
580580
let buflen = this.read_target_usize(buflen)?;
581-
let result = this.deref_operand(result)?;
581+
let result = this.deref_pointer(result)?;
582582

583583
// Must be for "us".
584584
if uid != crate::shims::unix::UID {

src/shims/unix/fs.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ trait EvalContextExtPrivate<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx
344344
let (created_sec, created_nsec) = metadata.created.unwrap_or((0, 0));
345345
let (modified_sec, modified_nsec) = metadata.modified.unwrap_or((0, 0));
346346

347-
let buf = this.deref_operand_as(buf_op, this.libc_ty_layout("stat"))?;
347+
let buf = this.deref_pointer_as(buf_op, this.libc_ty_layout("stat"))?;
348348

349349
this.write_int_fields_named(
350350
&[
@@ -1014,7 +1014,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
10141014
return Ok(-1);
10151015
}
10161016

1017-
let statxbuf = this.deref_operand_as(statxbuf_op, this.libc_ty_layout("statx"))?;
1017+
let statxbuf = this.deref_pointer_as(statxbuf_op, this.libc_ty_layout("statx"))?;
10181018

10191019
let path = this.read_path_from_c_str(pathname_ptr)?.into_owned();
10201020
// See <https://github.com/rust-lang/rust/pull/79196> for a discussion of argument sizes.
@@ -1420,7 +1420,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
14201420
// pub d_name: [c_char; 1024],
14211421
// }
14221422

1423-
let entry_place = this.deref_operand_as(entry_op, this.libc_ty_layout("dirent"))?;
1423+
let entry_place = this.deref_pointer_as(entry_op, this.libc_ty_layout("dirent"))?;
14241424
let name_place = this.project_field(&entry_place, 5)?;
14251425

14261426
let file_name = dir_entry.file_name(); // not a Path as there are no separators!
@@ -1456,14 +1456,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
14561456
&entry_place,
14571457
)?;
14581458

1459-
let result_place = this.deref_operand(result_op)?;
1459+
let result_place = this.deref_pointer(result_op)?;
14601460
this.write_scalar(this.read_scalar(entry_op)?, &result_place)?;
14611461

14621462
0
14631463
}
14641464
None => {
14651465
// end of stream: return 0, assign *result=NULL
1466-
this.write_null(&this.deref_operand(result_op)?)?;
1466+
this.write_null(&this.deref_pointer(result_op)?)?;
14671467
0
14681468
}
14691469
Some(Err(e)) =>

src/shims/unix/linux/fd.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
7171
let epoll_ctl_del = this.eval_libc_i32("EPOLL_CTL_DEL");
7272

7373
if op == epoll_ctl_add || op == epoll_ctl_mod {
74-
let event = this.deref_operand_as(event, this.libc_ty_layout("epoll_event"))?;
74+
let event = this.deref_pointer_as(event, this.libc_ty_layout("epoll_event"))?;
7575

7676
let events = this.project_field(&event, 0)?;
7777
let events = this.read_scalar(&events)?.to_u32()?;
@@ -240,7 +240,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
240240
let _domain = this.read_scalar(domain)?.to_i32()?;
241241
let _type_ = this.read_scalar(type_)?.to_i32()?;
242242
let _protocol = this.read_scalar(protocol)?.to_i32()?;
243-
let sv = this.deref_operand(sv)?;
243+
let sv = this.deref_pointer(sv)?;
244244

245245
let fh = &mut this.machine.file_handler;
246246
let sv0 = fh.insert_fd(Box::new(SocketPair));

src/shims/unix/linux/foreign_items.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
198198
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
199199
this.read_scalar(pid)?.to_i32()?;
200200
this.read_target_usize(cpusetsize)?;
201-
this.deref_operand_as(mask, this.libc_ty_layout("cpu_set_t"))?;
201+
this.deref_pointer_as(mask, this.libc_ty_layout("cpu_set_t"))?;
202202
// FIXME: we just return an error; `num_cpus` then falls back to `sysconf`.
203203
let einval = this.eval_libc("EINVAL");
204204
this.set_last_error(einval)?;

src/shims/unix/macos/foreign_items.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
130130
this.check_no_isolation("`_NSGetExecutablePath`")?;
131131

132132
let buf_ptr = this.read_pointer(buf)?;
133-
let bufsize = this.deref_operand(bufsize)?;
133+
let bufsize = this.deref_pointer(bufsize)?;
134134

135135
// Using the host current_exe is a bit off, but consistent with Linux
136136
// (where stdlib reads /proc/self/exe).

0 commit comments

Comments
 (0)