@@ -369,6 +369,38 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
369
369
) -> InterpResult < ' tcx , EmulateByNameResult < ' mir , ' tcx > > {
370
370
let this = self . eval_context_mut ( ) ;
371
371
372
+ // When adding a new shim, you should follow the following pattern:
373
+ // ```
374
+ // "shim_name" => {
375
+ // let [arg1, arg2, arg3] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
376
+ // let result = this.shim_name(arg1, arg2, arg3)?;
377
+ // this.write_scalar(result, dest)?;
378
+ // }
379
+ // ```
380
+ // and then define `shim_name` as a helper function in an extension trait in a suitable file
381
+ // (see e.g. `unix/fs.rs`):
382
+ // ```
383
+ // fn shim_name(
384
+ // &mut self,
385
+ // arg1: &OpTy<'tcx, Provenance>,
386
+ // arg2: &OpTy<'tcx, Provenance>,
387
+ // arg3: &OpTy<'tcx, Provenance>)
388
+ // -> InterpResult<'tcx, Scalar<Provenance>> {
389
+ // let this = self.eval_context_mut();
390
+ //
391
+ // // First thing: load all the arguments. Details depend on the shim.
392
+ // let arg1 = this.read_scalar(arg1)?.to_u32()?;
393
+ // let arg2 = this.read_pointer(arg2)?; // when you need to work with the pointer directly
394
+ // let arg3 = this.deref_operand(arg3)?; // when you want to load/store through the pointer at its declared type
395
+ //
396
+ // // ...
397
+ //
398
+ // Ok(Scalar::from_u32(42))
399
+ // }
400
+ // ```
401
+ // You might find existing shims not following this pattern, most
402
+ // likely because they predate it or because for some reason they cannot be made to fit.
403
+
372
404
// Here we dispatch all the shims for foreign functions. If you have a platform specific
373
405
// shim, add it to the corresponding submodule.
374
406
match link_name. as_str ( ) {
0 commit comments