remove need for RefCell wrapping on CodeDir

This commit is contained in:
Mark Thom
2018-10-04 21:43:49 -06:00
parent bf0521fde6
commit 4bd805cc76
9 changed files with 171 additions and 187 deletions

View File

@@ -98,13 +98,10 @@ fn compile_query(terms: Vec<QueryTerm>, queue: Vec<TopLevel>, flags: MachineFlag
} }
fn package_term(wam: &mut Machine, term: Term) -> Result<TopLevelPacket, ParserError> { fn package_term(wam: &mut Machine, term: Term) -> Result<TopLevelPacket, ParserError> {
let code_dir = wam.code_dir.clone(); let mut code_dir = wam.take_code_dir();
let indices = machine_code_indices!(wam.atom_tbl.clone(), let packet = consume_term(&mut code_dir, term, &mut wam.indices)?;
&mut CodeDir::new(), wam.swap_code_dir(&mut code_dir);
&mut wam.op_dir, Ok(packet)
&mut wam.modules);
consume_term(code_dir, term, indices)
} }
pub fn compile_term(wam: &mut Machine, term: Term) -> EvalSession pub fn compile_term(wam: &mut Machine, term: Term) -> EvalSession
@@ -119,7 +116,7 @@ pub fn compile_term(wam: &mut Machine, term: Term) -> EvalSession
}, },
TopLevelPacket::Decl(TopLevel::Declaration(decl), _) => { TopLevelPacket::Decl(TopLevel::Declaration(decl), _) => {
let mut compiler = ListingCompiler::new(); let mut compiler = ListingCompiler::new();
let mut indices = default_machine_code_indices!(wam.atom_tbl.clone()); let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
try_eval_session!(compiler.process_decl(decl, wam, &mut indices)); try_eval_session!(compiler.process_decl(decl, wam, &mut indices));
try_eval_session!(compiler.add_code(wam, vec![], indices)); try_eval_session!(compiler.add_code(wam, vec![], indices));
@@ -143,7 +140,7 @@ impl ListingCompiler {
} }
} }
fn use_module(&mut self, submodule: Module, wam: &mut Machine, indices: &mut MachineCodeIndices) fn use_module(&mut self, submodule: Module, wam: &mut Machine, indices: &mut IndexStore)
-> Result<(), SessionError> -> Result<(), SessionError>
{ {
let mod_name = self.get_module_name(); let mod_name = self.get_module_name();
@@ -161,7 +158,7 @@ impl ListingCompiler {
} }
fn use_qualified_module(&mut self, submodule: Module, wam: &mut Machine, fn use_qualified_module(&mut self, submodule: Module, wam: &mut Machine,
exports: &Vec<PredicateKey>, indices: &mut MachineCodeIndices) exports: &Vec<PredicateKey>, indices: &mut IndexStore)
-> Result<(), SessionError> -> Result<(), SessionError>
{ {
let mod_name = self.get_module_name(); let mod_name = self.get_module_name();
@@ -213,11 +210,11 @@ impl ListingCompiler {
Ok(code) Ok(code)
} }
fn add_code(&mut self, wam: &mut Machine, code: Code, indices: MachineCodeIndices) fn add_code(&mut self, wam: &mut Machine, code: Code, mut indices: IndexStore)
-> Result<(), SessionError> -> Result<(), SessionError>
{ {
let code_dir = mem::replace(indices.code_dir, HashMap::new()); let code_dir = mem::replace(&mut indices.code_dir, CodeDir::new());
let op_dir = mem::replace(indices.op_dir, HashMap::new()); let op_dir = mem::replace(&mut indices.op_dir, OpDir::new());
if let Some(mut module) = self.module.take() { if let Some(mut module) = self.module.take() {
module.code_dir.extend(as_module_code_dir(code_dir)); module.code_dir.extend(as_module_code_dir(code_dir));
@@ -236,7 +233,7 @@ impl ListingCompiler {
self.non_counted_bt_preds.insert((name, arity)); self.non_counted_bt_preds.insert((name, arity));
} }
fn process_decl(&mut self, decl: Declaration, wam: &mut Machine, indices: &mut MachineCodeIndices) fn process_decl(&mut self, decl: Declaration, wam: &mut Machine, indices: &mut IndexStore)
-> Result<(), SessionError> -> Result<(), SessionError>
{ {
match decl { match decl {
@@ -272,13 +269,15 @@ impl ListingCompiler {
} }
pub pub
fn compile_listing<'a, R: Read>(wam: &mut Machine, src: R, mut indices: MachineCodeIndices<'a>, fn compile_listing<R: Read>(wam: &mut Machine, src: R, mut indices: IndexStore,
mut toplevel_indices: MachineCodeIndices<'a>) mut toplevel_indices: IndexStore)
-> EvalSession -> EvalSession
{ {
let mut worker = TopLevelBatchWorker::new(src, wam.atom_tbl.clone(), let code_dir = wam.take_code_dir();
let mut worker = TopLevelBatchWorker::new(src, wam.indices.atom_tbl.clone(),
wam.machine_flags(), wam.machine_flags(),
wam.code_dir.clone()); code_dir);
let mut compiler = ListingCompiler::new(); let mut compiler = ListingCompiler::new();
let mut toplevel_results = vec![]; let mut toplevel_results = vec![];
@@ -298,6 +297,8 @@ fn compile_listing<'a, R: Read>(wam: &mut Machine, src: R, mut indices: MachineC
} }
} }
wam.swap_code_dir(&mut worker.static_code_dir);
let module_code = try_eval_session!(compiler.generate_code(worker.results, wam, let module_code = try_eval_session!(compiler.generate_code(worker.results, wam,
&mut indices.code_dir)); &mut indices.code_dir));
let toplvl_code = try_eval_session!(compiler.generate_code(toplevel_results, wam, let toplvl_code = try_eval_session!(compiler.generate_code(toplevel_results, wam,
@@ -309,8 +310,8 @@ fn compile_listing<'a, R: Read>(wam: &mut Machine, src: R, mut indices: MachineC
EvalSession::EntrySuccess EvalSession::EntrySuccess
} }
fn setup_indices(wam: &Machine, indices: &mut MachineCodeIndices) -> Result<(), SessionError> { fn setup_indices(wam: &Machine, indices: &mut IndexStore) -> Result<(), SessionError> {
if let Some(ref builtins) = wam.modules.get(&clause_name!("builtins")) { if let Some(ref builtins) = wam.indices.modules.get(&clause_name!("builtins")) {
indices.use_module(builtins) indices.use_module(builtins)
} else { } else {
Err(SessionError::ModuleNotFound) Err(SessionError::ModuleNotFound)
@@ -318,10 +319,10 @@ fn setup_indices(wam: &Machine, indices: &mut MachineCodeIndices) -> Result<(),
} }
pub fn compile_user_module<R: Read>(wam: &mut Machine, src: R) -> EvalSession { pub fn compile_user_module<R: Read>(wam: &mut Machine, src: R) -> EvalSession {
let atom_tbl = wam.atom_tbl.clone(); let atom_tbl = wam.indices.atom_tbl.clone();
let mut indices = default_machine_code_indices!(atom_tbl.clone()); let mut indices = default_index_store!(atom_tbl.clone());
try_eval_session!(setup_indices(&wam, &mut indices)); try_eval_session!(setup_indices(&wam, &mut indices));
compile_listing(wam, src, indices, default_machine_code_indices!(atom_tbl)) compile_listing(wam, src, indices, default_index_store!(atom_tbl))
} }

View File

@@ -5,7 +5,7 @@ use prolog::instructions::*;
use prolog::and_stack::*; use prolog::and_stack::*;
use prolog::copier::*; use prolog::copier::*;
use prolog::heap_print::*; use prolog::heap_print::*;
use prolog::machine::MachineCodeIndices; use prolog::machine::IndexStore;
use prolog::machine::machine_errors::*; use prolog::machine::machine_errors::*;
use prolog::num::{BigInt, BigUint, Zero, One}; use prolog::num::{BigInt, BigUint, Zero, One};
use prolog::or_stack::*; use prolog::or_stack::*;
@@ -34,39 +34,6 @@ impl Ball {
} }
} }
#[derive(Clone, Copy)]
pub(crate) struct CodeDirs<'a> {
pub code_dir: &'a CodeDir,
pub op_dir: &'a OpDir,
pub modules: &'a ModuleDir
}
impl<'a> CodeDirs<'a> {
fn get_internal(&self, name: ClauseName, arity: usize, in_mod: ClauseName) -> Option<ModuleCodeIndex> {
self.modules.get(&in_mod)
.and_then(|ref module| module.code_dir.get(&(name, arity)))
.cloned()
}
pub(super) fn get_cleaner_sites(&self) -> (usize, usize) {
let r_w_h = clause_name!("run_cleaners_with_handling");
let r_wo_h = clause_name!("run_cleaners_without_handling");
let builtins = clause_name!("builtins");
let r_w_h = self.get_internal(r_w_h, 0, builtins.clone()).and_then(|item| item.local());
let r_wo_h = self.get_internal(r_wo_h, 1, builtins).and_then(|item| item.local());
if let Some(r_w_h) = r_w_h {
if let Some(r_wo_h) = r_wo_h {
return (r_w_h, r_wo_h);
}
}
return (0, 0);
}
}
pub(super) struct DuplicateTerm<'a> { pub(super) struct DuplicateTerm<'a> {
state: &'a mut MachineState state: &'a mut MachineState
} }
@@ -431,8 +398,8 @@ pub(crate) trait CallPolicy: Any {
Ok(()) Ok(())
} }
fn context_call(&mut self, machine_st: &mut MachineState, name: ClauseName, arity: usize, fn context_call(&mut self, machine_st: &mut MachineState, name: ClauseName,
idx: CodeIndex, indices: MachineCodeIndices) arity: usize, idx: CodeIndex, indices: &mut IndexStore)
-> CallResult -> CallResult
{ {
if machine_st.last_call { if machine_st.last_call {
@@ -442,8 +409,8 @@ pub(crate) trait CallPolicy: Any {
} }
} }
fn try_call<'a>(&mut self, machine_st: &mut MachineState, name: ClauseName, arity: usize, fn try_call(&mut self, machine_st: &mut MachineState, name: ClauseName, arity: usize,
idx: CodeIndex, indices: MachineCodeIndices<'a>) idx: CodeIndex, indices: &IndexStore)
-> CallResult -> CallResult
{ {
match idx.0.borrow().0 { match idx.0.borrow().0 {
@@ -477,8 +444,8 @@ pub(crate) trait CallPolicy: Any {
Ok(()) Ok(())
} }
fn try_execute<'a>(&mut self, machine_st: &mut MachineState, name: ClauseName, fn try_execute(&mut self, machine_st: &mut MachineState, name: ClauseName,
arity: usize, idx: CodeIndex, indices: MachineCodeIndices<'a>) arity: usize, idx: CodeIndex, indices: &IndexStore)
-> CallResult -> CallResult
{ {
match idx.0.borrow().0 { match idx.0.borrow().0 {
@@ -512,8 +479,8 @@ pub(crate) trait CallPolicy: Any {
Ok(()) Ok(())
} }
fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType, fn call_builtin(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType,
indices: MachineCodeIndices<'a>) //code_dirs: CodeDirs) indices: &mut IndexStore)
-> CallResult -> CallResult
{ {
match ct { match ct {
@@ -682,8 +649,7 @@ pub(crate) trait CallPolicy: Any {
Ok(()) Ok(())
} }
fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize, fn call_n(&mut self, machine_st: &mut MachineState, arity: usize, indices: &mut IndexStore)
indices: MachineCodeIndices<'a>)
-> CallResult -> CallResult
{ {
if let Some((name, arity)) = machine_st.setup_call_n(arity) { if let Some((name, arity)) = machine_st.setup_call_n(arity) {
@@ -731,8 +697,8 @@ pub(crate) trait CallPolicy: Any {
} }
impl CallPolicy for CWILCallPolicy { impl CallPolicy for CWILCallPolicy {
fn context_call<'a>(&mut self, machine_st: &mut MachineState, name: ClauseName, fn context_call(&mut self, machine_st: &mut MachineState, name: ClauseName,
arity: usize, idx: CodeIndex, indices: MachineCodeIndices<'a>) arity: usize, idx: CodeIndex, indices: &mut IndexStore)
-> CallResult -> CallResult
{ {
self.prev_policy.context_call(machine_st, name, arity, idx, indices)?; self.prev_policy.context_call(machine_st, name, arity, idx, indices)?;
@@ -763,15 +729,15 @@ impl CallPolicy for CWILCallPolicy {
self.increment(machine_st) self.increment(machine_st)
} }
fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType, fn call_builtin(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType,
indices: MachineCodeIndices<'a>) indices: &mut IndexStore)
-> CallResult -> CallResult
{ {
self.prev_policy.call_builtin(machine_st, ct, indices)?; self.prev_policy.call_builtin(machine_st, ct, indices)?;
self.increment(machine_st) self.increment(machine_st)
} }
fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize, indices: MachineCodeIndices<'a>) fn call_n(&mut self, machine_st: &mut MachineState, arity: usize, indices: &mut IndexStore)
-> CallResult -> CallResult
{ {
self.prev_policy.call_n(machine_st, arity, indices)?; self.prev_policy.call_n(machine_st, arity, indices)?;

View File

@@ -6,7 +6,7 @@ use prolog::and_stack::*;
use prolog::copier::*; use prolog::copier::*;
use prolog::heap_iter::*; use prolog::heap_iter::*;
use prolog::heap_print::*; use prolog::heap_print::*;
use prolog::machine::MachineCodeIndices; use prolog::machine::IndexStore;
use prolog::machine::machine_errors::*; use prolog::machine::machine_errors::*;
use prolog::machine::machine_state::*; use prolog::machine::machine_state::*;
use prolog::num::{Integer, Signed, ToPrimitive, Zero}; use prolog::num::{Integer, Signed, ToPrimitive, Zero};
@@ -2126,7 +2126,7 @@ impl MachineState {
self.p += 1; self.p += 1;
} }
fn handle_call_clause<'a>(&mut self, indices: MachineCodeIndices<'a>, fn handle_call_clause(&mut self, indices: &mut IndexStore,
call_policy: &mut Box<CallPolicy>, call_policy: &mut Box<CallPolicy>,
cut_policy: &mut Box<CutPolicy>, cut_policy: &mut Box<CutPolicy>,
ct: &ClauseType, ct: &ClauseType,
@@ -2160,7 +2160,7 @@ impl MachineState {
}; };
} }
pub(super) fn execute_ctrl_instr<'a>(&mut self, indices: MachineCodeIndices<'a>, pub(super) fn execute_ctrl_instr(&mut self, indices: &mut IndexStore,
call_policy: &mut Box<CallPolicy>, call_policy: &mut Box<CallPolicy>,
cut_policy: &mut Box<CutPolicy>, cut_policy: &mut Box<CutPolicy>,
instr: &ControlInstruction) instr: &ControlInstruction)

View File

@@ -16,37 +16,65 @@ mod system_calls;
use prolog::machine::machine_state::*; use prolog::machine::machine_state::*;
use std::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
use std::mem::swap; use std::mem;
use std::ops::Index; use std::ops::Index;
use std::rc::Rc; use std::rc::Rc;
static BUILTINS: &str = include_str!("../lib/builtins.pl"); static BUILTINS: &str = include_str!("../lib/builtins.pl");
pub struct MachineCodeIndices<'a> { pub struct IndexStore {
pub(super) atom_tbl: TabledData<Atom>, pub(super) atom_tbl: TabledData<Atom>,
pub(super) code_dir: &'a mut CodeDir, pub(super) code_dir: CodeDir,
pub(super) op_dir: &'a mut OpDir, pub(super) op_dir: OpDir,
pub(super) modules: &'a mut ModuleDir pub(super) modules: ModuleDir
} }
impl<'a> MachineCodeIndices<'a> { impl IndexStore {
#[inline] #[inline]
pub(super) fn copy_and_swap(&mut self, other: &mut MachineCodeIndices<'a>) { pub(super) fn new() -> Self {
*self.code_dir = other.code_dir.clone(); IndexStore {
*self.op_dir = other.op_dir.clone(); atom_tbl: TabledData::new(Rc::new("user".to_string())),
code_dir: CodeDir::new(),
swap(&mut self.code_dir, &mut other.code_dir); op_dir: default_op_dir(),
swap(&mut self.op_dir, &mut other.op_dir); modules: ModuleDir::new()
swap(&mut self.modules, &mut other.modules); }
} }
#[inline] #[inline]
pub(super) fn to_code_dirs(self) -> CodeDirs<'a> { pub(super) fn copy_and_swap(&mut self, other: &mut IndexStore) {
CodeDirs { code_dir: self.code_dir, self.code_dir = other.code_dir.clone();
op_dir: self.op_dir, self.op_dir = other.op_dir.clone();
modules: self.modules }
mem::swap(&mut self.code_dir, &mut other.code_dir);
mem::swap(&mut self.op_dir, &mut other.op_dir);
mem::swap(&mut self.modules, &mut other.modules);
}
fn get_internal(&self, name: ClauseName, arity: usize, in_mod: ClauseName)
-> Option<ModuleCodeIndex>
{
self.modules.get(&in_mod)
.and_then(|ref module| module.code_dir.get(&(name, arity)))
.cloned()
}
pub(super) fn get_cleaner_sites(&self) -> (usize, usize) {
let r_w_h = clause_name!("run_cleaners_with_handling");
let r_wo_h = clause_name!("run_cleaners_without_handling");
let builtins = clause_name!("builtins");
let r_w_h = self.get_internal(r_w_h, 0, builtins.clone()).and_then(|item| item.local());
let r_wo_h = self.get_internal(r_wo_h, 1, builtins).and_then(|item| item.local());
if let Some(r_w_h) = r_w_h {
if let Some(r_wo_h) = r_wo_h {
return (r_w_h, r_wo_h);
}
}
return (0, 0);
} }
} }
@@ -55,12 +83,9 @@ pub struct Machine {
call_policy: Box<CallPolicy>, call_policy: Box<CallPolicy>,
cut_policy: Box<CutPolicy>, cut_policy: Box<CutPolicy>,
code: Code, code: Code,
pub(super) atom_tbl: TabledData<Atom>, pub(super) indices: IndexStore,
pub(super) code_dir: Rc<RefCell<CodeDir>>,
pub(super) op_dir: OpDir,
term_dir: TermDir, term_dir: TermDir,
term_expanders: Code, term_expanders: Code,
pub(super) modules: ModuleDir,
cached_query: Option<Code> cached_query: Option<Code>
} }
@@ -81,13 +106,13 @@ impl Index<LocalCodePtr> for Machine {
} }
} }
impl<'a> SubModuleUser for MachineCodeIndices<'a> { impl SubModuleUser for IndexStore {
fn atom_tbl(&self) -> TabledData<Atom> { fn atom_tbl(&self) -> TabledData<Atom> {
self.atom_tbl.clone() self.atom_tbl.clone()
} }
fn op_dir(&mut self) -> &mut OpDir { fn op_dir(&mut self) -> &mut OpDir {
self.op_dir &mut self.op_dir
} }
fn get_code_index(&self, key: PredicateKey, module: ClauseName) -> Option<CodeIndex> fn get_code_index(&self, key: PredicateKey, module: ClauseName) -> Option<CodeIndex>
@@ -132,20 +157,17 @@ impl Machine {
call_policy: Box::new(DefaultCallPolicy {}), call_policy: Box::new(DefaultCallPolicy {}),
cut_policy: Box::new(DefaultCutPolicy {}), cut_policy: Box::new(DefaultCutPolicy {}),
code: Code::new(), code: Code::new(),
atom_tbl: TabledData::new(Rc::new("user".to_string())), indices: IndexStore::new(),
code_dir: Rc::new(RefCell::new(CodeDir::new())),
op_dir: default_op_dir(),
term_dir: TermDir::new(), term_dir: TermDir::new(),
term_expanders: Code::new(), term_expanders: Code::new(),
modules: HashMap::new(),
cached_query: None cached_query: None
}; };
let atom_tbl = wam.atom_tbl.clone(); let atom_tbl = wam.indices.atom_tbl.clone();
compile_listing(&mut wam, BUILTINS.as_bytes(), compile_listing(&mut wam, BUILTINS.as_bytes(),
default_machine_code_indices!(atom_tbl.clone()), default_index_store!(atom_tbl.clone()),
default_machine_code_indices!(atom_tbl)); default_index_store!(atom_tbl));
compile_user_module(&mut wam, LISTS.as_bytes()); compile_user_module(&mut wam, LISTS.as_bytes());
compile_user_module(&mut wam, CONTROL.as_bytes()); compile_user_module(&mut wam, CONTROL.as_bytes());
@@ -178,7 +200,7 @@ impl Machine {
} }
}; };
if let Some(ref existing_idx) = self.code_dir.borrow().get(&key) { if let Some(ref existing_idx) = self.indices.code_dir.get(&key) {
// ensure we don't try to overwrite an existing predicate from a different module. // ensure we don't try to overwrite an existing predicate from a different module.
if !existing_idx.is_undefined() && !idx.is_undefined() { if !existing_idx.is_undefined() && !idx.is_undefined() {
// allow the overwriting of user-level predicates by all other predicates. // allow the overwriting of user-level predicates by all other predicates.
@@ -197,7 +219,7 @@ impl Machine {
// error detection has finished, so update the master index of keys. // error detection has finished, so update the master index of keys.
for (key, idx) in code_dir { for (key, idx) in code_dir {
if let Some(ref mut master_idx) = self.code_dir.borrow_mut().get_mut(&key) { if let Some(ref mut master_idx) = self.indices.code_dir.get_mut(&key) {
// ensure we don't double borrow if master_idx == idx. // ensure we don't double borrow if master_idx == idx.
// we don't need to modify anything in that case. // we don't need to modify anything in that case.
if !Rc::ptr_eq(&master_idx.0, &idx.0) { if !Rc::ptr_eq(&master_idx.0, &idx.0) {
@@ -207,7 +229,7 @@ impl Machine {
continue; continue;
} }
self.code_dir.borrow_mut().insert(key.clone(), idx.clone()); self.indices.code_dir.insert(key.clone(), idx.clone());
} }
self.code.extend(code.into_iter()); self.code.extend(code.into_iter());
@@ -216,31 +238,37 @@ impl Machine {
#[inline] #[inline]
pub fn add_batched_ops(&mut self, op_dir: OpDir) { pub fn add_batched_ops(&mut self, op_dir: OpDir) {
self.op_dir.extend(op_dir.into_iter()); self.indices.op_dir.extend(op_dir.into_iter());
} }
#[inline] #[inline]
pub fn remove_module(&mut self, module: &Module) { pub fn remove_module(&mut self, module: &Module) {
let mut indices = machine_code_indices!(self.atom_tbl.clone(), self.indices.remove_module(clause_name!("user"), module);
&mut self.code_dir.borrow_mut(),
&mut self.op_dir,
&mut self.modules);
indices.remove_module(clause_name!("user"), module);
} }
#[inline] #[inline]
pub fn take_module(&mut self, name: ClauseName) -> Option<Module> { pub fn take_module(&mut self, name: ClauseName) -> Option<Module> {
self.modules.remove(&name) self.indices.modules.remove(&name)
}
#[inline]
pub fn take_code_dir(&mut self) -> CodeDir {
mem::replace(&mut self.indices.code_dir, CodeDir::new())
}
#[inline]
pub fn swap_code_dir(&mut self, code_dir: &mut CodeDir) {
mem::swap(&mut self.indices.code_dir, code_dir);
} }
#[inline] #[inline]
pub fn insert_module(&mut self, module: Module) { pub fn insert_module(&mut self, module: Module) {
self.modules.insert(module.module_decl.name.clone(), module); self.indices.modules.insert(module.module_decl.name.clone(), module);
} }
#[inline] #[inline]
pub fn add_module(&mut self, module: Module, code: Code) { pub fn add_module(&mut self, module: Module, code: Code) {
self.modules.insert(module.module_decl.name.clone(), module); self.indices.modules.insert(module.module_decl.name.clone(), module);
self.code.extend(code.into_iter()); self.code.extend(code.into_iter());
} }
@@ -300,8 +328,6 @@ impl Machine {
None => return None => return
}; };
let atom_tbl = self.atom_tbl.clone();
match instr { match instr {
Line::Arithmetic(ref arith_instr) => Line::Arithmetic(ref arith_instr) =>
self.ms.execute_arith_instr(arith_instr), self.ms.execute_arith_instr(arith_instr),
@@ -309,15 +335,9 @@ impl Machine {
self.ms.execute_choice_instr(choice_instr, &mut self.call_policy), self.ms.execute_choice_instr(choice_instr, &mut self.call_policy),
Line::Cut(ref cut_instr) => Line::Cut(ref cut_instr) =>
self.ms.execute_cut_instr(cut_instr, &mut self.cut_policy), self.ms.execute_cut_instr(cut_instr, &mut self.cut_policy),
Line::Control(ref control_instr) => { Line::Control(ref control_instr) =>
let indices = machine_code_indices!(atom_tbl, self.ms.execute_ctrl_instr(&mut self.indices, &mut self.call_policy,
&mut self.code_dir.borrow_mut(), &mut self.cut_policy, control_instr),
&mut self.op_dir,
&mut self.modules);
self.ms.execute_ctrl_instr(indices, &mut self.call_policy,
&mut self.cut_policy, control_instr)
},
Line::Fact(ref fact) => { Line::Fact(ref fact) => {
for fact_instr in fact { for fact_instr in fact {
if self.failed() { if self.failed() {
@@ -515,7 +535,7 @@ impl Machine {
pub fn clear(&mut self) { pub fn clear(&mut self) {
let mut machine = Machine::new(); let mut machine = Machine::new();
swap(self, &mut machine); mem::swap(self, &mut machine);
} }
pub fn reset(&mut self) { pub fn reset(&mut self) {

View File

@@ -2,7 +2,7 @@ use prolog_parser::ast::*;
use prolog::heap_iter::*; use prolog::heap_iter::*;
use prolog::instructions::*; use prolog::instructions::*;
use prolog::machine::MachineCodeIndices; use prolog::machine::IndexStore;
use prolog::machine::machine_errors::*; use prolog::machine::machine_errors::*;
use prolog::machine::machine_state::*; use prolog::machine::machine_state::*;
use prolog::num::{ToPrimitive, Zero}; use prolog::num::{ToPrimitive, Zero};
@@ -187,8 +187,8 @@ impl MachineState {
} }
} }
pub(super) fn system_call<'a>(&mut self, ct: &SystemClauseType, pub(super) fn system_call(&mut self, ct: &SystemClauseType,
indices: MachineCodeIndices<'a>, indices: &IndexStore,
call_policy: &mut Box<CallPolicy>, call_policy: &mut Box<CallPolicy>,
cut_policy: &mut Box<CutPolicy>,) cut_policy: &mut Box<CutPolicy>,)
-> CallResult -> CallResult
@@ -242,7 +242,7 @@ impl MachineState {
let prev_block = self.block; let prev_block = self.block;
if cut_policy.downcast_ref::<SCCCutPolicy>().is_err() { if cut_policy.downcast_ref::<SCCCutPolicy>().is_err() {
let (r_c_w_h, r_c_wo_h) = indices.to_code_dirs().get_cleaner_sites(); let (r_c_w_h, r_c_wo_h) = indices.get_cleaner_sites();
*cut_policy = Box::new(SCCCutPolicy::new(r_c_w_h, r_c_wo_h)); *cut_policy = Box::new(SCCCutPolicy::new(r_c_w_h, r_c_wo_h));
} }

View File

@@ -77,7 +77,8 @@ impl<R: Read> TermStream<R> {
}; };
} }
let term = self.parser.read_term(composite_op!(self.in_module, &wam.op_dir, op_dir))?; let term = self.parser.read_term(composite_op!(self.in_module, &wam.indices.op_dir,
op_dir))?;
self.stack.push(term); self.stack.push(term);
} }
} }

View File

@@ -209,21 +209,18 @@ macro_rules! set_code_index {
}} }}
} }
macro_rules! machine_code_indices { macro_rules! index_store {
($atom_tbl:expr, $code_dir:expr, $op_dir:expr, $modules:expr) => ( ($atom_tbl:expr, $code_dir:expr, $op_dir:expr, $modules:expr) => (
MachineCodeIndices { atom_tbl: $atom_tbl, IndexStore { atom_tbl: $atom_tbl,
code_dir: $code_dir, code_dir: $code_dir,
op_dir: $op_dir, op_dir: $op_dir,
modules: $modules } modules: $modules }
) )
} }
macro_rules! default_machine_code_indices { macro_rules! default_index_store {
($atom_tbl:expr) => ( ($atom_tbl:expr) => (
machine_code_indices!($atom_tbl, index_store!($atom_tbl, CodeDir::new(), default_op_dir(), HashMap::new())
&mut CodeDir::new(),
&mut default_op_dir(),
&mut HashMap::new())
) )
} }

View File

@@ -45,7 +45,7 @@ pub fn read_toplevel(wam: &mut Machine) -> Result<Input, ParserError> {
Ok(Input::Batch) Ok(Input::Batch)
}, },
_ => { _ => {
let mut term_stream = TermStream::new(stdin.lock(), wam.atom_tbl.clone(), let mut term_stream = TermStream::new(stdin.lock(), wam.indices.atom_tbl.clone(),
wam.machine_flags()); wam.machine_flags());
term_stream.add_to_top(buffer.as_str()); term_stream.add_to_top(buffer.as_str());

View File

@@ -13,9 +13,9 @@ use std::io::Read;
use std::mem; use std::mem;
use std::rc::Rc; use std::rc::Rc;
struct CompositeIndices<'a, 'b : 'a> { struct CompositeIndices<'a, 'b> {
local: &'a mut MachineCodeIndices<'b>, local: &'a mut IndexStore,
static_code_dir: Option<Rc<RefCell<CodeDir>>> static_code_dir: Option<&'b mut CodeDir>
} }
macro_rules! composite_indices { macro_rules! composite_indices {
@@ -32,15 +32,16 @@ macro_rules! composite_indices {
) )
} }
impl<'a, 'b : 'a> CompositeIndices<'a, 'b> impl<'a, 'b> CompositeIndices<'a, 'b>
{ {
fn get_code_index(&mut self, name: ClauseName, arity: usize) -> CodeIndex { fn get_code_index(&mut self, name: ClauseName, arity: usize) -> CodeIndex {
let idx_opt = self.local.code_dir.get(&(name.clone(), arity)).cloned() let idx_opt = self.local.code_dir.get(&(name.clone(), arity))
.or_else(|| { .or_else(|| {
self.static_code_dir.clone().and_then(|code_dir| { match &self.static_code_dir {
code_dir.borrow().get(&(name.clone(), arity)).cloned() &Some(ref code_dir) => code_dir.get(&(name.clone(), arity)),
}) _ => None
}); }
}).cloned();
if let Some(idx) = idx_opt { if let Some(idx) = idx_opt {
self.local.code_dir.insert((name, arity), idx.clone()); self.local.code_dir.insert((name, arity), idx.clone());
@@ -714,17 +715,16 @@ pub fn parse_term<R: Read>(wam: &Machine, buf: R) -> Result<Term, ParserError>
{ {
use prolog_parser::parser::*; use prolog_parser::parser::*;
let mut parser = Parser::new(buf, wam.atom_tbl.clone(), wam.machine_flags()); let mut parser = Parser::new(buf, wam.indices.atom_tbl.clone(), wam.machine_flags());
parser.read_term(composite_op!(&wam.op_dir)) parser.read_term(composite_op!(&wam.indices.op_dir))
} }
pub pub
fn consume_term<'a>(static_code_dir: Rc<RefCell<CodeDir>>, term: Term, fn consume_term(static_code_dir: &mut CodeDir, term: Term, indices: &mut IndexStore)
mut indices: MachineCodeIndices<'a>)
-> Result<TopLevelPacket, ParserError> -> Result<TopLevelPacket, ParserError>
{ {
let mut rel_worker = RelationWorker::new(); let mut rel_worker = RelationWorker::new();
let mut indices = composite_indices!(false, &mut indices, static_code_dir); let mut indices = composite_indices!(false, indices, static_code_dir);
let tl = rel_worker.try_term_to_tl(&mut indices, term, true)?; let tl = rel_worker.try_term_to_tl(&mut indices, term, true)?;
let results = rel_worker.parse_queue(&mut indices)?; let results = rel_worker.parse_queue(&mut indices)?;
@@ -735,14 +735,13 @@ fn consume_term<'a>(static_code_dir: Rc<RefCell<CodeDir>>, term: Term,
pub struct TopLevelBatchWorker<R: Read> { pub struct TopLevelBatchWorker<R: Read> {
pub(crate) term_stream: TermStream<R>, pub(crate) term_stream: TermStream<R>,
rel_worker: RelationWorker, rel_worker: RelationWorker,
static_code_dir: Rc<RefCell<CodeDir>>, pub(super) static_code_dir: CodeDir,
pub(crate) results: Vec<(Predicate, VecDeque<TopLevel>)>, pub(crate) results: Vec<(Predicate, VecDeque<TopLevel>)>,
pub(crate) in_module: bool pub(crate) in_module: bool
} }
impl<R: Read> TopLevelBatchWorker<R> { impl<R: Read> TopLevelBatchWorker<R> {
pub fn new(inner: R, atom_tbl: TabledData<Atom>, flags: MachineFlags, pub fn new(inner: R, atom_tbl: TabledData<Atom>, flags: MachineFlags, static_code_dir: CodeDir)
static_code_dir: Rc<RefCell<CodeDir>>)
-> Self -> Self
{ {
TopLevelBatchWorker { term_stream: TermStream::new(inner, atom_tbl, flags), TopLevelBatchWorker { term_stream: TermStream::new(inner, atom_tbl, flags),
@@ -753,12 +752,12 @@ impl<R: Read> TopLevelBatchWorker<R> {
} }
pub pub
fn consume<'a, 'b : 'a>(&mut self, wam: &mut Machine, indices: &'a mut MachineCodeIndices<'b>) fn consume(&mut self, wam: &mut Machine, indices: &mut IndexStore)
-> Result<Option<Declaration>, SessionError> -> Result<Option<Declaration>, SessionError>
{ {
let mut preds = vec![]; let mut preds = vec![];
let mut indices = composite_indices!(self.in_module, indices, let mut indices = composite_indices!(self.in_module, indices,
self.static_code_dir.clone()); &mut self.static_code_dir);
while !self.term_stream.eof()? { while !self.term_stream.eof()? {
self.term_stream.empty_tokens(); // empty the parser stack of token descriptions. self.term_stream.empty_tokens(); // empty the parser stack of token descriptions.