#[derive(Copy, Clone, PartialEq)]
pub enum SystemClauseType {
- InstallCleaner,
+ CheckCutPoint,
+ GetSCCCleaner,
+ InstallSCCCleaner,
InstallInferenceCounter,
RemoveCallPolicyCheck,
RemoveInferenceCounter,
pub fn name(&self) -> ClauseName {
match self {
- &SystemClauseType::InstallCleaner => clause_name!("$install_cleaner"),
+ &SystemClauseType::CheckCutPoint => clause_name!("$check_cp"),
+ &SystemClauseType::GetSCCCleaner => clause_name!("$get_scc_cleaner"),
+ &SystemClauseType::InstallSCCCleaner => clause_name!("$install_scc_cleaner"),
&SystemClauseType::InstallInferenceCounter =>
clause_name!("$install_inference_counter"),
&SystemClauseType::RemoveCallPolicyCheck =>
pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
match (name, arity) {
- ("$install_cleaner", 1) =>
- Some(SystemClauseType::InstallCleaner),
+ ("$check_cp", 1) => Some(SystemClauseType::CheckCutPoint),
+ ("$get_scc_cleaner", 1) => Some(SystemClauseType::GetSCCCleaner),
+ ("$install_scc_cleaner", 1) =>
+ Some(SystemClauseType::InstallSCCCleaner),
("$install_inference_counter", 3) =>
Some(SystemClauseType::InstallInferenceCounter),
("$remove_call_policy_check", 1) =>
Neg(ArithmeticTerm, usize)
}
-// call and cut policy exempt instructions.
-#[derive(Clone)]
-pub enum PEInstruction {
-}
-
#[derive(Clone)]
pub enum ControlInstruction {
Allocate(usize), // num_frames.
CallClause(ClauseType, usize, usize, bool), // name, arity, perm_vars after threshold, last call.
- CheckCpExecute,
- Deallocate,
- GetCleanerCall,
+ Deallocate,
JmpBy(usize, usize, usize, bool), // arity, global_offset, perm_vars after threshold, last call.
Proceed
}
pub fn is_jump_instr(&self) -> bool {
match self {
&ControlInstruction::CallClause(..) => true,
- &ControlInstruction::GetCleanerCall => true,
&ControlInstruction::JmpBy(..) => true,
_ => false
}
write!(f, "execute {}/{}, {}", ct, arity, pvs),
&ControlInstruction::CallClause(ref ct, arity, pvs, false) =>
write!(f, "call {}/{}, {}", ct, arity, pvs),
- &ControlInstruction::CheckCpExecute =>
- write!(f, "check_cp_execute"),
&ControlInstruction::Deallocate =>
write!(f, "deallocate"),
- &ControlInstruction::GetCleanerCall =>
- write!(f, "get_cleaner_call"),
&ControlInstruction::JmpBy(arity, offset, pvs, false) =>
write!(f, "jmp_by_call {}/{}, {}", offset, arity, pvs),
&ControlInstruction::JmpBy(arity, offset, pvs, true) =>
}
}
-pub(crate) struct SetupCallCleanupCutPolicy {
+pub(crate) struct SCCCutPolicy {
// locations of cleaners, cut points, the previous block
cont_pts: Vec<(Addr, usize, usize)>
}
-impl SetupCallCleanupCutPolicy {
+impl SCCCutPolicy {
pub(crate) fn new() -> Self {
- SetupCallCleanupCutPolicy { cont_pts: vec![] }
+ SCCCutPolicy { cont_pts: vec![] }
}
pub(crate) fn out_of_cont_pts(&self) -> bool {
}
}
-impl CutPolicy for SetupCallCleanupCutPolicy {
+impl CutPolicy for SCCCutPolicy {
fn cut(&mut self, machine_st: &mut MachineState, r: RegType) {
let b = machine_st.b;
self.p += 1;
}
},
- &ControlInstruction::CheckCpExecute => {
- let a = self.store(self.deref(self[temp_v!(2)].clone()));
-
- match a {
- Addr::Con(Constant::Usize(old_b)) if self.b > old_b + 1 => {
- self.p = CodePtr::Local(self.cp.clone());
- },
- _ => {
- self.num_of_args = 2;
- self.b0 = self.b;
- // goto sgc_on_success/2, 382.
- self.p = dir_entry!(382, clause_name!("builtin"));
- }
- };
- },
&ControlInstruction::Deallocate => self.deallocate(),
- &ControlInstruction::GetCleanerCall => {
- let dest = self[temp_v!(1)].clone();
-
- match cut_policy.downcast_mut::<SetupCallCleanupCutPolicy>().ok() {
- Some(sgc_policy) =>
- if let Some((addr, b_cutoff, prev_block)) = sgc_policy.pop_cont_pt()
- {
- self.p += 1;
-
- if self.b <= b_cutoff + 1 {
- self.block = prev_block;
-
- if let Some(r) = dest.as_var() {
- self.bind(r, addr);
- return;
- }
- } else {
- sgc_policy.push_cont_pt(addr, b_cutoff, prev_block);
- }
- },
- None => panic!("expected SetupCallCleanupCutPolicy trait object.")
- };
-
- self.fail = true;
- },
&ControlInstruction::JmpBy(arity, offset, _, lco) => {
if !lco {
self.cp.assign_if_local(self.p.clone() + 1);
-> CallResult
{
match ct {
- &SystemClauseType::InstallCleaner => {
+ &SystemClauseType::CheckCutPoint => {},
+ &SystemClauseType::GetSCCCleaner => {
+ let dest = self[temp_v!(1)].clone();
+
+ match cut_policy.downcast_mut::<SCCCutPolicy>().ok() {
+ Some(sgc_policy) =>
+ if let Some((addr, b_cutoff, prev_block)) = sgc_policy.pop_cont_pt() {
+ if self.b <= b_cutoff + 1 {
+ self.block = prev_block;
+
+ if let Some(r) = dest.as_var() {
+ self.bind(r, addr);
+ return Ok(());
+ }
+ } else {
+ sgc_policy.push_cont_pt(addr, b_cutoff, prev_block);
+ }
+ },
+ None => panic!("expected SCCCutPolicy trait object.")
+ };
+
+ self.fail = true;
+ },
+ &SystemClauseType::InstallSCCCleaner => {
let addr = self[temp_v!(1)].clone();
let b = self.b;
let block = self.block;
- if cut_policy.downcast_ref::<SetupCallCleanupCutPolicy>().is_err() {
- *cut_policy = Box::new(SetupCallCleanupCutPolicy::new());
+ if cut_policy.downcast_ref::<SCCCutPolicy>().is_err() {
+ *cut_policy = Box::new(SCCCutPolicy::new());
}
- match cut_policy.downcast_mut::<SetupCallCleanupCutPolicy>().ok()
+ match cut_policy.downcast_mut::<SCCCutPolicy>().ok()
{
Some(cut_policy) => cut_policy.push_cont_pt(addr, b, block),
None => panic!("install_cleaner: should have installed \\
- SetupCallCleanupCutPolicy.")
+ SCCCutPolicy.")
};
},
&SystemClauseType::InstallInferenceCounter => { // A1 = B, A2 = L
},
&SystemClauseType::RestoreCutPolicy => {
let restore_default =
- if let Ok(cut_policy) = cut_policy.downcast_ref::<SetupCallCleanupCutPolicy>() {
+ if let Ok(cut_policy) = cut_policy.downcast_ref::<SCCCutPolicy>() {
cut_policy.out_of_cont_pts()
} else {
false