major refactor
This commit is contained in:
@@ -715,8 +715,8 @@ impl SCCCutPolicy {
|
||||
self.cont_pts.is_empty()
|
||||
}
|
||||
|
||||
pub(crate) fn push_cont_pt(&mut self, addr: Addr, b: usize, block: usize) {
|
||||
self.cont_pts.push((addr, b, block));
|
||||
pub(crate) fn push_cont_pt(&mut self, addr: Addr, b: usize, prev_b: usize) {
|
||||
self.cont_pts.push((addr, b, prev_b));
|
||||
}
|
||||
|
||||
pub(crate) fn pop_cont_pt(&mut self) -> Option<(Addr, usize, usize)> {
|
||||
@@ -729,7 +729,7 @@ impl CutPolicy for SCCCutPolicy {
|
||||
let b = machine_st.b;
|
||||
|
||||
if let Addr::Con(Constant::Usize(b0)) = machine_st[r].clone() {
|
||||
if b > b0 {
|
||||
if b > b0 {
|
||||
machine_st.b = b0;
|
||||
machine_st.tidy_trail();
|
||||
machine_st.or_stack.truncate(machine_st.b);
|
||||
@@ -737,14 +737,13 @@ impl CutPolicy for SCCCutPolicy {
|
||||
} else {
|
||||
machine_st.fail = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if !self.out_of_cont_pts() {
|
||||
machine_st.cp.assign_if_local(machine_st.p.clone());
|
||||
machine_st.num_of_args = 0;
|
||||
machine_st.b0 = machine_st.b;
|
||||
// goto_call run_cleaners_without_handling/0, 370.
|
||||
machine_st.p = dir_entry!(370, clause_name!("builtin"));
|
||||
}
|
||||
|
||||
if let Some(&(_, b_cutoff, prev_block)) = self.cont_pts.last() {
|
||||
if machine_st.b < b_cutoff {
|
||||
machine_st.block = prev_block;
|
||||
machine_st.unwind_stack();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1065,13 +1065,6 @@ impl MachineState {
|
||||
duplicator.duplicate_term(addr);
|
||||
}
|
||||
|
||||
pub(super) fn unwind_stack(&mut self) {
|
||||
self.b = self.block;
|
||||
self.or_stack.truncate(self.b);
|
||||
|
||||
self.fail = true;
|
||||
}
|
||||
|
||||
pub(super) fn setup_call_n(&mut self, arity: usize) -> Option<PredicateKey>
|
||||
{
|
||||
let stub = self.functor_stub(clause_name!("call"), arity + 1);
|
||||
@@ -1121,7 +1114,14 @@ impl MachineState {
|
||||
|
||||
Some((name, arity + narity - 1))
|
||||
}
|
||||
|
||||
pub(super) fn unwind_stack(&mut self) {
|
||||
self.b = self.block;
|
||||
self.or_stack.truncate(self.b);
|
||||
|
||||
self.fail = true;
|
||||
}
|
||||
|
||||
fn heap_ball_boundary_diff(&self) -> usize {
|
||||
if self.ball.boundary > self.heap.h {
|
||||
self.ball.boundary - self.heap.h
|
||||
@@ -1945,6 +1945,13 @@ impl MachineState {
|
||||
self[r] = Addr::Con(Constant::Usize(b0));
|
||||
self.p += 1;
|
||||
},
|
||||
&CutInstruction::GetLevelAndUnify(r) => {
|
||||
let b0 = Addr::Con(Constant::Usize(self.b0));
|
||||
let a = self[r].clone();
|
||||
|
||||
self.unify(a, b0);
|
||||
self.p += 1;
|
||||
},
|
||||
&CutInstruction::Cut(r) => {
|
||||
cut_policy.cut(self, r);
|
||||
self.p += 1;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use prolog::ast::*;
|
||||
use prolog::builtins::*;
|
||||
use prolog::compile::*;
|
||||
use prolog::heap_print::*;
|
||||
use prolog::tabled_rc::*;
|
||||
|
||||
@@ -17,9 +17,9 @@ use std::mem::swap;
|
||||
use std::ops::Index;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub(super) struct MachineCodeIndex<'a> {
|
||||
pub(super) code_dir: &'a mut CodeDir,
|
||||
pub(super) op_dir: &'a mut OpDir,
|
||||
pub struct MachineCodeIndex<'a> {
|
||||
pub code_dir: &'a mut CodeDir,
|
||||
pub op_dir: &'a mut OpDir,
|
||||
}
|
||||
|
||||
pub struct Machine {
|
||||
@@ -66,24 +66,33 @@ impl<'a> SubModuleUser for MachineCodeIndex<'a> {
|
||||
self.code_dir.insert((name, arity), CodeIndex::from(idx));
|
||||
}
|
||||
}
|
||||
|
||||
static LISTS: &str = include_str!("../lib/lists.pl");
|
||||
static CONTROL: &str = include_str!("../lib/control.pl");
|
||||
static QUEUES: &str = include_str!("../lib/queues.pl");
|
||||
|
||||
impl Machine {
|
||||
pub fn new() -> Self {
|
||||
let atom_tbl = Rc::new(RefCell::new(HashSet::new()));
|
||||
let op_dir = default_op_dir(); //TODO: change to the builtins module once it's done.
|
||||
//let (code, code_dir, op_dir) = default_build();
|
||||
|
||||
Machine {
|
||||
ms: MachineState::new(atom_tbl),
|
||||
let mut wam = Machine {
|
||||
ms: MachineState::new(Rc::new(RefCell::new(HashSet::new()))),
|
||||
call_policy: Box::new(DefaultCallPolicy {}),
|
||||
cut_policy: Box::new(DefaultCutPolicy {}),
|
||||
code: Code::new(),
|
||||
code_dir: CodeDir::new(),
|
||||
term_dir: TermDir::new(),
|
||||
op_dir,
|
||||
op_dir: default_op_dir(),
|
||||
modules: HashMap::new(),
|
||||
cached_query: None
|
||||
}
|
||||
};
|
||||
|
||||
compile_listing(&mut wam, BUILTINS);
|
||||
wam.use_module_in_toplevel(clause_name!("builtins"));
|
||||
|
||||
compile_listing(&mut wam, LISTS);
|
||||
compile_listing(&mut wam, CONTROL);
|
||||
compile_listing(&mut wam, QUEUES);
|
||||
|
||||
wam
|
||||
}
|
||||
|
||||
fn remove_module(&mut self, module_name: ClauseName) {
|
||||
|
||||
@@ -151,39 +151,57 @@ impl MachineState {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn system_call(&mut self, ct: &SystemClauseType, call_policy: &mut Box<CallPolicy>,
|
||||
|
||||
fn install_new_block(&mut self, r: RegType) -> usize {
|
||||
self.block = self.b;
|
||||
|
||||
let c = Constant::Usize(self.block);
|
||||
let addr = self[r].clone();
|
||||
|
||||
self.write_constant_to_var(addr, c);
|
||||
self.block
|
||||
}
|
||||
|
||||
pub(super) fn system_call(&mut self, ct: &SystemClauseType,
|
||||
call_policy: &mut Box<CallPolicy>,
|
||||
cut_policy: &mut Box<CutPolicy>,)
|
||||
-> CallResult
|
||||
{
|
||||
match ct {
|
||||
&SystemClauseType::CheckCutPoint => {},
|
||||
&SystemClauseType::CheckCutPoint => {
|
||||
let addr = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||
|
||||
match addr {
|
||||
Addr::Con(Constant::Usize(old_b)) if self.b <= old_b + 2 => {},
|
||||
_ => self.fail = true
|
||||
};
|
||||
},
|
||||
&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 let Some((addr, b_cutoff, prev_b)) = sgc_policy.pop_cont_pt() {
|
||||
if self.b <= b_cutoff + 1 {
|
||||
self.block = prev_block;
|
||||
self.block = prev_b;
|
||||
|
||||
if let Some(r) = dest.as_var() {
|
||||
self.bind(r, addr);
|
||||
self.bind(r, addr.clone());
|
||||
return Ok(());
|
||||
}
|
||||
} else {
|
||||
sgc_policy.push_cont_pt(addr, b_cutoff, prev_block);
|
||||
sgc_policy.push_cont_pt(addr, b_cutoff, prev_b);
|
||||
}
|
||||
},
|
||||
None => panic!("expected SCCCutPolicy trait object.")
|
||||
};
|
||||
|
||||
self.fail = true;
|
||||
self.fail = true;
|
||||
},
|
||||
&SystemClauseType::InstallSCCCleaner => {
|
||||
let addr = self[temp_v!(1)].clone();
|
||||
let b = self.b;
|
||||
let block = self.block;
|
||||
let prev_block = self.block;
|
||||
|
||||
if cut_policy.downcast_ref::<SCCCutPolicy>().is_err() {
|
||||
*cut_policy = Box::new(SCCCutPolicy::new());
|
||||
@@ -191,7 +209,10 @@ impl MachineState {
|
||||
|
||||
match cut_policy.downcast_mut::<SCCCutPolicy>().ok()
|
||||
{
|
||||
Some(cut_policy) => cut_policy.push_cont_pt(addr, b, block),
|
||||
Some(cut_policy) => {
|
||||
self.install_new_block(temp_v!(2));
|
||||
cut_policy.push_cont_pt(addr, b, prev_block);
|
||||
},
|
||||
None => panic!("install_cleaner: should have installed \\
|
||||
SCCCutPolicy.")
|
||||
};
|
||||
@@ -292,7 +313,7 @@ impl MachineState {
|
||||
},
|
||||
_ => self.fail = true
|
||||
};
|
||||
},
|
||||
},
|
||||
&SystemClauseType::CleanUpBlock => {
|
||||
let nb = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||
|
||||
@@ -337,16 +358,11 @@ impl MachineState {
|
||||
&SystemClauseType::GetCutPoint => {
|
||||
let a1 = self[temp_v!(1)].clone();
|
||||
let a2 = Addr::Con(Constant::Usize(self.b));
|
||||
|
||||
|
||||
self.unify(a1, a2);
|
||||
},
|
||||
&SystemClauseType::InstallNewBlock => {
|
||||
self.block = self.b;
|
||||
|
||||
let c = Constant::Usize(self.block);
|
||||
let addr = self[temp_v!(1)].clone();
|
||||
|
||||
self.write_constant_to_var(addr, c);
|
||||
self.install_new_block(temp_v!(1));
|
||||
},
|
||||
&SystemClauseType::ResetBlock => {
|
||||
let addr = self.deref(self[temp_v!(1)].clone());
|
||||
|
||||
Reference in New Issue
Block a user