move SGC and call inference instructions over to SystemClauseType
This commit is contained in:
@@ -702,7 +702,9 @@ pub struct Rule {
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum SystemClauseType {
|
||||
InstallCleaner,
|
||||
CheckCutPoint,
|
||||
GetSCCCleaner,
|
||||
InstallSCCCleaner,
|
||||
InstallInferenceCounter,
|
||||
RemoveCallPolicyCheck,
|
||||
RemoveInferenceCounter,
|
||||
@@ -730,7 +732,9 @@ impl SystemClauseType {
|
||||
|
||||
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 =>
|
||||
@@ -757,8 +761,10 @@ impl SystemClauseType {
|
||||
|
||||
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) =>
|
||||
@@ -1362,18 +1368,11 @@ pub enum ArithmeticInstruction {
|
||||
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
|
||||
}
|
||||
@@ -1382,7 +1381,6 @@ impl ControlInstruction {
|
||||
pub fn is_jump_instr(&self) -> bool {
|
||||
match self {
|
||||
&ControlInstruction::CallClause(..) => true,
|
||||
&ControlInstruction::GetCleanerCall => true,
|
||||
&ControlInstruction::JmpBy(..) => true,
|
||||
_ => false
|
||||
}
|
||||
|
||||
@@ -133,12 +133,8 @@ impl fmt::Display for ControlInstruction {
|
||||
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) =>
|
||||
|
||||
@@ -701,14 +701,14 @@ impl CutPolicy for DefaultCutPolicy {
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -724,7 +724,7 @@ impl SetupCallCleanupCutPolicy {
|
||||
}
|
||||
}
|
||||
|
||||
impl CutPolicy for SetupCallCleanupCutPolicy {
|
||||
impl CutPolicy for SCCCutPolicy {
|
||||
fn cut(&mut self, machine_st: &mut MachineState, r: RegType) {
|
||||
let b = machine_st.b;
|
||||
|
||||
|
||||
@@ -1838,47 +1838,7 @@ impl MachineState {
|
||||
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);
|
||||
|
||||
@@ -157,20 +157,43 @@ impl MachineState {
|
||||
-> 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
|
||||
@@ -242,7 +265,7 @@ impl MachineState {
|
||||
},
|
||||
&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
|
||||
|
||||
Reference in New Issue
Block a user