make module code entries immutable (re: issue #27)

This commit is contained in:
Mark Thom
2018-04-18 19:24:32 -06:00
parent a4789a73ef
commit 989d44d702
7 changed files with 73 additions and 59 deletions

View File

@@ -24,19 +24,17 @@ impl<'a> CodeDirs<'a> {
CodeDirs { code_dir, modules }
}
fn get_current_code_dir(&self, p: &CodePtr) -> &CodeDir {
let module_name = p.module_name();
match module_name {
ClauseName::BuiltIn("user") | ClauseName::BuiltIn("builtin") => self.code_dir,
_ => &self.modules.get(&module_name).unwrap().code_dir
pub(super) fn get(&self, name: ClauseName, arity: usize, in_mod: ClauseName) -> Option<CodeIndex>
{
match in_mod.as_str() {
"user" | "builtin" => self.code_dir.get(&(name, arity)).cloned(),
_ => match self.modules.get(&in_mod) {
Some(&Module { ref code_dir, .. }) =>
code_dir.get(&(name, arity)).cloned().map(CodeIndex::from),
None => None
}
}
}
pub(super) fn get(&self, name: ClauseName, arity: usize, p: &CodePtr) -> Option<CodeIndex> {
let code_dir = self.get_current_code_dir(p);
code_dir.get(&(name, arity)).cloned()
}
}
pub(super) struct DuplicateTerm<'a> {
@@ -428,7 +426,8 @@ pub(crate) trait CallPolicy: Any {
},
&ClauseType::CallN =>
if let Some((name, arity)) = machine_st.setup_call_n(arity) {
if let Some(idx) = code_dirs.get(name.clone(), arity, &machine_st.p.clone()) {
if let Some(idx) = code_dirs.get(name.clone(), arity, machine_st.p.module_name())
{
self.context_call(machine_st, name, arity, idx, lco)
} else {
Err(predicate_existence_error(name, arity, machine_st.heap.h))

View File

@@ -909,7 +909,7 @@ impl MachineState {
self.registers[arity - 1] = pred;
if let Some((name, arity)) = self.setup_call_n(arity - 1) {
if let Some(idx) = code_dirs.get(name.clone(), arity, &self.p.clone()) {
if let Some(idx) = code_dirs.get(name.clone(), arity, self.p.module_name()) {
try_or_fail!(self, call_policy.try_execute(self, name, arity, idx));
return;
}

View File

@@ -53,8 +53,17 @@ impl<'a> SubModuleUser for MachineCodeIndex<'a> {
self.op_dir
}
fn code_dir(&mut self) -> &mut CodeDir {
self.code_dir
fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: ModuleCodeIndex) {
if let Some(ref mut code_idx) = self.code_dir.get_mut(&(name.clone(), arity)) {
println!("warning: overwriting {}/{}", &name, arity);
code_idx.0.set(idx.0);
code_idx.1 = idx.1;
return;
}
self.code_dir.insert((name, arity), CodeIndex::from(idx));
}
}
@@ -132,8 +141,8 @@ impl Machine {
{
self.remove_module(name.clone());
match self.modules.get(&name) {
Some(ref module) => {
match self.modules.get_mut(&name) {
Some(ref mut module) => {
let mut indices = MachineCodeIndex { code_dir: &mut self.code_dir,
op_dir: &mut self.op_dir };
@@ -146,8 +155,8 @@ impl Machine {
pub fn use_module_in_toplevel(&mut self, name: ClauseName) -> EvalSession {
self.remove_module(name.clone());
match self.modules.get(&name) {
Some(ref module) => {
match self.modules.get_mut(&name) {
Some(ref mut module) => {
let mut indices = MachineCodeIndex { code_dir: &mut self.code_dir,
op_dir: &mut self.op_dir };
@@ -196,7 +205,7 @@ impl Machine {
entry.0.set(IndexPtr::Index(offset));
entry.1 = clause_name!("user");
EvalSession::EntrySuccess
}
@@ -312,8 +321,8 @@ impl Machine {
let e = self.ms.e;
let r = var_data.as_reg_type().reg_num();
let addr = self.ms.and_stack[e][r].clone();
heap_locs.insert(var.clone(), addr);
heap_locs.insert(var.clone(), addr);
},
&VarData::Temp(cn, _, _) if cn == chunk_num => {
let r = var_data.as_reg_type();