remove need for RefCell wrapping on CodeDir
This commit is contained in:
@@ -5,7 +5,7 @@ use prolog::instructions::*;
|
||||
use prolog::and_stack::*;
|
||||
use prolog::copier::*;
|
||||
use prolog::heap_print::*;
|
||||
use prolog::machine::MachineCodeIndices;
|
||||
use prolog::machine::IndexStore;
|
||||
use prolog::machine::machine_errors::*;
|
||||
use prolog::num::{BigInt, BigUint, Zero, One};
|
||||
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> {
|
||||
state: &'a mut MachineState
|
||||
}
|
||||
@@ -431,8 +398,8 @@ pub(crate) trait CallPolicy: Any {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn context_call(&mut self, machine_st: &mut MachineState, name: ClauseName, arity: usize,
|
||||
idx: CodeIndex, indices: MachineCodeIndices)
|
||||
fn context_call(&mut self, machine_st: &mut MachineState, name: ClauseName,
|
||||
arity: usize, idx: CodeIndex, indices: &mut IndexStore)
|
||||
-> CallResult
|
||||
{
|
||||
if machine_st.last_call {
|
||||
@@ -442,9 +409,9 @@ pub(crate) trait CallPolicy: Any {
|
||||
}
|
||||
}
|
||||
|
||||
fn try_call<'a>(&mut self, machine_st: &mut MachineState, name: ClauseName, arity: usize,
|
||||
idx: CodeIndex, indices: MachineCodeIndices<'a>)
|
||||
-> CallResult
|
||||
fn try_call(&mut self, machine_st: &mut MachineState, name: ClauseName, arity: usize,
|
||||
idx: CodeIndex, indices: &IndexStore)
|
||||
-> CallResult
|
||||
{
|
||||
match idx.0.borrow().0 {
|
||||
IndexPtr::Module => {
|
||||
@@ -477,9 +444,9 @@ pub(crate) trait CallPolicy: Any {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn try_execute<'a>(&mut self, machine_st: &mut MachineState, name: ClauseName,
|
||||
arity: usize, idx: CodeIndex, indices: MachineCodeIndices<'a>)
|
||||
-> CallResult
|
||||
fn try_execute(&mut self, machine_st: &mut MachineState, name: ClauseName,
|
||||
arity: usize, idx: CodeIndex, indices: &IndexStore)
|
||||
-> CallResult
|
||||
{
|
||||
match idx.0.borrow().0 {
|
||||
IndexPtr::Module => {
|
||||
@@ -512,9 +479,9 @@ pub(crate) trait CallPolicy: Any {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType,
|
||||
indices: MachineCodeIndices<'a>) //code_dirs: CodeDirs)
|
||||
-> CallResult
|
||||
fn call_builtin(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType,
|
||||
indices: &mut IndexStore)
|
||||
-> CallResult
|
||||
{
|
||||
match ct {
|
||||
&BuiltInClauseType::AcyclicTerm => {
|
||||
@@ -682,9 +649,8 @@ pub(crate) trait CallPolicy: Any {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize,
|
||||
indices: MachineCodeIndices<'a>)
|
||||
-> CallResult
|
||||
fn call_n(&mut self, machine_st: &mut MachineState, arity: usize, indices: &mut IndexStore)
|
||||
-> CallResult
|
||||
{
|
||||
if let Some((name, arity)) = machine_st.setup_call_n(arity) {
|
||||
match ClauseType::from(name.clone(), arity, None) {
|
||||
@@ -731,9 +697,9 @@ pub(crate) trait CallPolicy: Any {
|
||||
}
|
||||
|
||||
impl CallPolicy for CWILCallPolicy {
|
||||
fn context_call<'a>(&mut self, machine_st: &mut MachineState, name: ClauseName,
|
||||
arity: usize, idx: CodeIndex, indices: MachineCodeIndices<'a>)
|
||||
-> CallResult
|
||||
fn context_call(&mut self, machine_st: &mut MachineState, name: ClauseName,
|
||||
arity: usize, idx: CodeIndex, indices: &mut IndexStore)
|
||||
-> CallResult
|
||||
{
|
||||
self.prev_policy.context_call(machine_st, name, arity, idx, indices)?;
|
||||
self.increment(machine_st)
|
||||
@@ -763,16 +729,16 @@ impl CallPolicy for CWILCallPolicy {
|
||||
self.increment(machine_st)
|
||||
}
|
||||
|
||||
fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType,
|
||||
indices: MachineCodeIndices<'a>)
|
||||
-> CallResult
|
||||
fn call_builtin(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType,
|
||||
indices: &mut IndexStore)
|
||||
-> CallResult
|
||||
{
|
||||
self.prev_policy.call_builtin(machine_st, ct, indices)?;
|
||||
self.increment(machine_st)
|
||||
}
|
||||
|
||||
fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize, indices: MachineCodeIndices<'a>)
|
||||
-> CallResult
|
||||
fn call_n(&mut self, machine_st: &mut MachineState, arity: usize, indices: &mut IndexStore)
|
||||
-> CallResult
|
||||
{
|
||||
self.prev_policy.call_n(machine_st, arity, indices)?;
|
||||
self.increment(machine_st)
|
||||
|
||||
@@ -6,7 +6,7 @@ use prolog::and_stack::*;
|
||||
use prolog::copier::*;
|
||||
use prolog::heap_iter::*;
|
||||
use prolog::heap_print::*;
|
||||
use prolog::machine::MachineCodeIndices;
|
||||
use prolog::machine::IndexStore;
|
||||
use prolog::machine::machine_errors::*;
|
||||
use prolog::machine::machine_state::*;
|
||||
use prolog::num::{Integer, Signed, ToPrimitive, Zero};
|
||||
@@ -2126,13 +2126,13 @@ impl MachineState {
|
||||
self.p += 1;
|
||||
}
|
||||
|
||||
fn handle_call_clause<'a>(&mut self, indices: MachineCodeIndices<'a>,
|
||||
call_policy: &mut Box<CallPolicy>,
|
||||
cut_policy: &mut Box<CutPolicy>,
|
||||
ct: &ClauseType,
|
||||
arity: usize,
|
||||
lco: bool,
|
||||
use_default_cp: bool)
|
||||
fn handle_call_clause(&mut self, indices: &mut IndexStore,
|
||||
call_policy: &mut Box<CallPolicy>,
|
||||
cut_policy: &mut Box<CutPolicy>,
|
||||
ct: &ClauseType,
|
||||
arity: usize,
|
||||
lco: bool,
|
||||
use_default_cp: bool)
|
||||
{
|
||||
let mut default_call_policy: Box<CallPolicy> = Box::new(DefaultCallPolicy {});
|
||||
let call_policy = if use_default_cp {
|
||||
@@ -2160,10 +2160,10 @@ impl MachineState {
|
||||
};
|
||||
}
|
||||
|
||||
pub(super) fn execute_ctrl_instr<'a>(&mut self, indices: MachineCodeIndices<'a>,
|
||||
call_policy: &mut Box<CallPolicy>,
|
||||
cut_policy: &mut Box<CutPolicy>,
|
||||
instr: &ControlInstruction)
|
||||
pub(super) fn execute_ctrl_instr(&mut self, indices: &mut IndexStore,
|
||||
call_policy: &mut Box<CallPolicy>,
|
||||
cut_policy: &mut Box<CutPolicy>,
|
||||
instr: &ControlInstruction)
|
||||
{
|
||||
match instr {
|
||||
&ControlInstruction::Allocate(num_cells) =>
|
||||
|
||||
@@ -16,37 +16,65 @@ mod system_calls;
|
||||
|
||||
use prolog::machine::machine_state::*;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::mem::swap;
|
||||
use std::mem;
|
||||
use std::ops::Index;
|
||||
use std::rc::Rc;
|
||||
|
||||
static BUILTINS: &str = include_str!("../lib/builtins.pl");
|
||||
|
||||
pub struct MachineCodeIndices<'a> {
|
||||
pub struct IndexStore {
|
||||
pub(super) atom_tbl: TabledData<Atom>,
|
||||
pub(super) code_dir: &'a mut CodeDir,
|
||||
pub(super) op_dir: &'a mut OpDir,
|
||||
pub(super) modules: &'a mut ModuleDir
|
||||
pub(super) code_dir: CodeDir,
|
||||
pub(super) op_dir: OpDir,
|
||||
pub(super) modules: ModuleDir
|
||||
}
|
||||
|
||||
impl<'a> MachineCodeIndices<'a> {
|
||||
impl IndexStore {
|
||||
#[inline]
|
||||
pub(super) fn copy_and_swap(&mut self, other: &mut MachineCodeIndices<'a>) {
|
||||
*self.code_dir = other.code_dir.clone();
|
||||
*self.op_dir = other.op_dir.clone();
|
||||
|
||||
swap(&mut self.code_dir, &mut other.code_dir);
|
||||
swap(&mut self.op_dir, &mut other.op_dir);
|
||||
swap(&mut self.modules, &mut other.modules);
|
||||
pub(super) fn new() -> Self {
|
||||
IndexStore {
|
||||
atom_tbl: TabledData::new(Rc::new("user".to_string())),
|
||||
code_dir: CodeDir::new(),
|
||||
op_dir: default_op_dir(),
|
||||
modules: ModuleDir::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn to_code_dirs(self) -> CodeDirs<'a> {
|
||||
CodeDirs { code_dir: self.code_dir,
|
||||
op_dir: self.op_dir,
|
||||
modules: self.modules }
|
||||
pub(super) fn copy_and_swap(&mut self, other: &mut IndexStore) {
|
||||
self.code_dir = other.code_dir.clone();
|
||||
self.op_dir = other.op_dir.clone();
|
||||
|
||||
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>,
|
||||
cut_policy: Box<CutPolicy>,
|
||||
code: Code,
|
||||
pub(super) atom_tbl: TabledData<Atom>,
|
||||
pub(super) code_dir: Rc<RefCell<CodeDir>>,
|
||||
pub(super) op_dir: OpDir,
|
||||
pub(super) indices: IndexStore,
|
||||
term_dir: TermDir,
|
||||
term_expanders: Code,
|
||||
pub(super) modules: ModuleDir,
|
||||
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> {
|
||||
self.atom_tbl.clone()
|
||||
}
|
||||
|
||||
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>
|
||||
@@ -132,20 +157,17 @@ impl Machine {
|
||||
call_policy: Box::new(DefaultCallPolicy {}),
|
||||
cut_policy: Box::new(DefaultCutPolicy {}),
|
||||
code: Code::new(),
|
||||
atom_tbl: TabledData::new(Rc::new("user".to_string())),
|
||||
code_dir: Rc::new(RefCell::new(CodeDir::new())),
|
||||
op_dir: default_op_dir(),
|
||||
indices: IndexStore::new(),
|
||||
term_dir: TermDir::new(),
|
||||
term_expanders: Code::new(),
|
||||
modules: HashMap::new(),
|
||||
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(),
|
||||
default_machine_code_indices!(atom_tbl.clone()),
|
||||
default_machine_code_indices!(atom_tbl));
|
||||
default_index_store!(atom_tbl.clone()),
|
||||
default_index_store!(atom_tbl));
|
||||
|
||||
compile_user_module(&mut wam, LISTS.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.
|
||||
if !existing_idx.is_undefined() && !idx.is_undefined() {
|
||||
// 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.
|
||||
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.
|
||||
// we don't need to modify anything in that case.
|
||||
if !Rc::ptr_eq(&master_idx.0, &idx.0) {
|
||||
@@ -207,7 +229,7 @@ impl Machine {
|
||||
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());
|
||||
@@ -216,31 +238,37 @@ impl Machine {
|
||||
|
||||
#[inline]
|
||||
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]
|
||||
pub fn remove_module(&mut self, module: &Module) {
|
||||
let mut indices = machine_code_indices!(self.atom_tbl.clone(),
|
||||
&mut self.code_dir.borrow_mut(),
|
||||
&mut self.op_dir,
|
||||
&mut self.modules);
|
||||
indices.remove_module(clause_name!("user"), module);
|
||||
self.indices.remove_module(clause_name!("user"), module);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
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]
|
||||
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]
|
||||
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());
|
||||
}
|
||||
|
||||
@@ -300,8 +328,6 @@ impl Machine {
|
||||
None => return
|
||||
};
|
||||
|
||||
let atom_tbl = self.atom_tbl.clone();
|
||||
|
||||
match instr {
|
||||
Line::Arithmetic(ref 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),
|
||||
Line::Cut(ref cut_instr) =>
|
||||
self.ms.execute_cut_instr(cut_instr, &mut self.cut_policy),
|
||||
Line::Control(ref control_instr) => {
|
||||
let indices = machine_code_indices!(atom_tbl,
|
||||
&mut self.code_dir.borrow_mut(),
|
||||
&mut self.op_dir,
|
||||
&mut self.modules);
|
||||
|
||||
self.ms.execute_ctrl_instr(indices, &mut self.call_policy,
|
||||
&mut self.cut_policy, control_instr)
|
||||
},
|
||||
Line::Control(ref control_instr) =>
|
||||
self.ms.execute_ctrl_instr(&mut self.indices, &mut self.call_policy,
|
||||
&mut self.cut_policy, control_instr),
|
||||
Line::Fact(ref fact) => {
|
||||
for fact_instr in fact {
|
||||
if self.failed() {
|
||||
@@ -515,7 +535,7 @@ impl Machine {
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
let mut machine = Machine::new();
|
||||
swap(self, &mut machine);
|
||||
mem::swap(self, &mut machine);
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) {
|
||||
|
||||
@@ -2,7 +2,7 @@ use prolog_parser::ast::*;
|
||||
|
||||
use prolog::heap_iter::*;
|
||||
use prolog::instructions::*;
|
||||
use prolog::machine::MachineCodeIndices;
|
||||
use prolog::machine::IndexStore;
|
||||
use prolog::machine::machine_errors::*;
|
||||
use prolog::machine::machine_state::*;
|
||||
use prolog::num::{ToPrimitive, Zero};
|
||||
@@ -187,11 +187,11 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn system_call<'a>(&mut self, ct: &SystemClauseType,
|
||||
indices: MachineCodeIndices<'a>,
|
||||
call_policy: &mut Box<CallPolicy>,
|
||||
cut_policy: &mut Box<CutPolicy>,)
|
||||
-> CallResult
|
||||
pub(super) fn system_call(&mut self, ct: &SystemClauseType,
|
||||
indices: &IndexStore,
|
||||
call_policy: &mut Box<CallPolicy>,
|
||||
cut_policy: &mut Box<CutPolicy>,)
|
||||
-> CallResult
|
||||
{
|
||||
match ct {
|
||||
&SystemClauseType::CheckCutPoint => {
|
||||
@@ -242,7 +242,7 @@ impl MachineState {
|
||||
let prev_block = self.block;
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user