1
Fork 0

Contracts core intrinsics.

These are hooks to:

  1. control whether contract checks are run
  2. allow 3rd party tools to intercept and reintepret the results of running contracts.
This commit is contained in:
Felix S. Klock II 2024-12-02 20:35:13 +00:00 committed by Celina G. Val
parent 534d79adf9
commit bcb8565f30
30 changed files with 183 additions and 6 deletions

View file

@ -675,7 +675,11 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
Rvalue::Cast(_, _, _) => {}
Rvalue::NullaryOp(
NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) | NullOp::UbChecks,
NullOp::SizeOf
| NullOp::AlignOf
| NullOp::OffsetOf(_)
| NullOp::UbChecks
| NullOp::ContractChecks,
_,
) => {}
Rvalue::ShallowInitBox(_, _) => {}

View file

@ -293,6 +293,9 @@ pub trait Machine<'tcx>: Sized {
/// Determines the result of a `NullaryOp::UbChecks` invocation.
fn ub_checks(_ecx: &InterpCx<'tcx, Self>) -> InterpResult<'tcx, bool>;
/// Determines the result of a `NullaryOp::ContractChecks` invocation.
fn contract_checks(_ecx: &InterpCx<'tcx, Self>) -> InterpResult<'tcx, bool>;
/// Called when the interpreter encounters a `StatementKind::ConstEvalCounter` instruction.
/// You can use this to detect long or endlessly running programs.
#[inline]
@ -679,6 +682,13 @@ pub macro compile_time_machine(<$tcx: lifetime>) {
interp_ok(true)
}
#[inline(always)]
fn contract_checks(_ecx: &InterpCx<$tcx, Self>) -> InterpResult<$tcx, bool> {
// We can't look at `tcx.sess` here as that can differ across crates, which can lead to
// unsound differences in evaluating the same constant at different instantiation sites.
interp_ok(true)
}
#[inline(always)]
fn adjust_global_allocation<'b>(
_ecx: &InterpCx<$tcx, Self>,

View file

@ -537,6 +537,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
ImmTy::from_uint(val, usize_layout())
}
UbChecks => ImmTy::from_bool(M::ub_checks(self)?, *self.tcx),
ContractChecks => ImmTy::from_bool(M::contract_checks(self)?, *self.tcx),
})
}
}