finalize the module resolution operator.
This commit is contained in:
@@ -35,6 +35,22 @@ impl MachineError {
|
||||
MachineError { stub, from: ErrorProvenance::Received }
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn module_resolution_error(h: usize, mod_name: ClauseName, name: ClauseName, arity: usize) -> Self
|
||||
{
|
||||
let mod_name = HeapCellValue::Addr(Addr::Con(Constant::Atom(mod_name)));
|
||||
let name = HeapCellValue::Addr(Addr::Con(Constant::Atom(name)));
|
||||
|
||||
let mut stub = functor!("evaluation_error", 1, [HeapCellValue::Addr(Addr::HeapCell(h + 2))]);
|
||||
|
||||
stub.append(&mut functor!("/", 2, [HeapCellValue::Addr(Addr::HeapCell(h + 2 + 3)),
|
||||
heap_integer!(arity)],
|
||||
Fixity::In));
|
||||
stub.append(&mut functor!(":", 2, [mod_name, name], Fixity::In));
|
||||
|
||||
MachineError { stub, from: ErrorProvenance::Constructed }
|
||||
}
|
||||
|
||||
pub(super) fn existence_error(h: usize, name: ClauseName, arity: usize) -> Self {
|
||||
let mut stub = functor!("existence_error", 2, [heap_atom!("procedure"), heap_str!(3 + h)]);
|
||||
stub.append(&mut Self::functor_stub(name, arity));
|
||||
|
||||
@@ -33,7 +33,7 @@ impl Ball {
|
||||
|
||||
pub(crate) struct CodeDirs<'a> {
|
||||
code_dir: &'a CodeDir,
|
||||
modules: &'a HashMap<ClauseName, Module>
|
||||
modules: &'a ModuleDir
|
||||
}
|
||||
|
||||
impl<'a> CodeDirs<'a> {
|
||||
@@ -225,6 +225,21 @@ pub struct MachineState {
|
||||
pub(super) last_call: bool
|
||||
}
|
||||
|
||||
fn call_at_index(machine_st: &mut MachineState, module_name: ClauseName, arity: usize, idx: usize)
|
||||
{
|
||||
machine_st.cp.assign_if_local(machine_st.p.clone() + 1);
|
||||
machine_st.num_of_args = arity;
|
||||
machine_st.b0 = machine_st.b;
|
||||
machine_st.p = dir_entry!(idx, module_name);
|
||||
}
|
||||
|
||||
fn execute_at_index(machine_st: &mut MachineState, module_name: ClauseName, arity: usize, idx: usize)
|
||||
{
|
||||
machine_st.num_of_args = arity;
|
||||
machine_st.b0 = machine_st.b;
|
||||
machine_st.p = dir_entry!(idx, module_name);
|
||||
}
|
||||
|
||||
pub(crate) type CallResult = Result<(), Vec<HeapCellValue>>;
|
||||
|
||||
pub(crate) trait CallPolicy: Any {
|
||||
@@ -352,35 +367,46 @@ pub(crate) trait CallPolicy: Any {
|
||||
}
|
||||
|
||||
fn context_call(&mut self, machine_st: &mut MachineState, name: ClauseName, arity: usize,
|
||||
idx: CodeIndex)
|
||||
idx: CodeIndex, code_dirs: CodeDirs)
|
||||
-> CallResult
|
||||
{
|
||||
if machine_st.last_call {
|
||||
self.try_execute(machine_st, name, arity, idx)
|
||||
self.try_execute(machine_st, name, arity, idx, code_dirs)
|
||||
} else {
|
||||
self.try_call(machine_st, name, arity, idx)
|
||||
self.try_call(machine_st, name, arity, idx, code_dirs)
|
||||
}
|
||||
}
|
||||
|
||||
fn try_call(&mut self, machine_st: &mut MachineState, name: ClauseName,
|
||||
arity: usize, idx: CodeIndex)
|
||||
fn try_call(&mut self, machine_st: &mut MachineState, name: ClauseName, arity: usize,
|
||||
idx: CodeIndex, code_dirs: CodeDirs)
|
||||
-> CallResult
|
||||
{
|
||||
{
|
||||
match idx.0.borrow().0 {
|
||||
IndexPtr::Module => {
|
||||
let stub = MachineError::functor_stub(name.clone(), arity);
|
||||
let module_name = idx.0.borrow().1.clone();
|
||||
let h = machine_st.heap.h;
|
||||
|
||||
if let Some(ref idx) = code_dirs.get(name.clone(), arity, module_name.clone()) {
|
||||
if let IndexPtr::Index(compiled_tl_index) = idx.0.borrow().0 {
|
||||
call_at_index(machine_st, module_name, arity, compiled_tl_index);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
let err = MachineError::module_resolution_error(h, module_name, name, arity);
|
||||
return Err(machine_st.error_form(err, stub));
|
||||
},
|
||||
IndexPtr::Undefined => {
|
||||
let stub = MachineError::functor_stub(name.clone(), arity);
|
||||
let h = machine_st.heap.h;
|
||||
|
||||
|
||||
return Err(machine_st.error_form(MachineError::existence_error(h, name, arity),
|
||||
stub));
|
||||
},
|
||||
IndexPtr::Index(compiled_tl_index) => {
|
||||
let module_name = idx.0.borrow().1.clone();
|
||||
|
||||
machine_st.cp.assign_if_local(machine_st.p.clone() + 1);
|
||||
machine_st.num_of_args = arity;
|
||||
machine_st.b0 = machine_st.b;
|
||||
machine_st.p = dir_entry!(compiled_tl_index, module_name);
|
||||
call_at_index(machine_st, module_name, arity, compiled_tl_index)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,23 +414,35 @@ pub(crate) trait CallPolicy: Any {
|
||||
}
|
||||
|
||||
fn try_execute<'a>(&mut self, machine_st: &mut MachineState, name: ClauseName,
|
||||
arity: usize, idx: CodeIndex)
|
||||
arity: usize, idx: CodeIndex, code_dirs: CodeDirs)
|
||||
-> CallResult
|
||||
{
|
||||
match idx.0.borrow().0 {
|
||||
IndexPtr::Module => {
|
||||
let stub = MachineError::functor_stub(name.clone(), arity);
|
||||
let module_name = idx.0.borrow().1.clone();
|
||||
let h = machine_st.heap.h;
|
||||
|
||||
if let Some(ref idx) = code_dirs.get(name.clone(), arity, module_name.clone()) {
|
||||
if let IndexPtr::Index(compiled_tl_index) = idx.0.borrow().0 {
|
||||
execute_at_index(machine_st, module_name, arity, compiled_tl_index);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
let err = MachineError::module_resolution_error(h, module_name, name, arity);
|
||||
return Err(machine_st.error_form(err, stub));
|
||||
},
|
||||
IndexPtr::Undefined => {
|
||||
let stub = MachineError::functor_stub(name.clone(), arity);
|
||||
let h = machine_st.heap.h;
|
||||
|
||||
|
||||
return Err(machine_st.error_form(MachineError::existence_error(h, name, arity),
|
||||
stub));
|
||||
},
|
||||
IndexPtr::Index(compiled_tl_index) => {
|
||||
let module_name = idx.0.borrow().1.clone();
|
||||
|
||||
machine_st.num_of_args = arity;
|
||||
machine_st.b0 = machine_st.b;
|
||||
machine_st.p = dir_entry!(compiled_tl_index, module_name);
|
||||
execute_at_index(machine_st, module_name, arity, compiled_tl_index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -552,7 +590,7 @@ pub(crate) trait CallPolicy: Any {
|
||||
machine_st.execute_inlined(&inlined),
|
||||
ClauseType::Op(..) | ClauseType::Named(..) =>
|
||||
if let Some(idx) = code_dirs.get(name.clone(), arity, user) {
|
||||
self.context_call(machine_st, name, arity, idx)?;
|
||||
self.context_call(machine_st, name, arity, idx, code_dirs)?;
|
||||
} else {
|
||||
let h = machine_st.heap.h;
|
||||
let stub = MachineError::functor_stub(clause_name!("call"), arity + 1);
|
||||
@@ -562,7 +600,7 @@ pub(crate) trait CallPolicy: Any {
|
||||
ClauseType::System(_) => {
|
||||
let name = Addr::Con(Constant::Atom(name));
|
||||
let stub = MachineError::functor_stub(clause_name!("call"), arity + 1);
|
||||
|
||||
|
||||
return Err(machine_st.error_form(MachineError::type_error(ValidType::Callable,
|
||||
name),
|
||||
stub));
|
||||
@@ -576,10 +614,10 @@ pub(crate) trait CallPolicy: Any {
|
||||
|
||||
impl CallPolicy for CallWithInferenceLimitCallPolicy {
|
||||
fn context_call(&mut self, machine_st: &mut MachineState, name: ClauseName,
|
||||
arity: usize, idx: CodeIndex)
|
||||
arity: usize, idx: CodeIndex, code_dirs: CodeDirs)
|
||||
-> CallResult
|
||||
{
|
||||
self.prev_policy.context_call(machine_st, name, arity, idx)?;
|
||||
self.prev_policy.context_call(machine_st, name, arity, idx, code_dirs)?;
|
||||
self.increment()
|
||||
}
|
||||
|
||||
@@ -747,7 +785,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);
|
||||
@@ -755,8 +793,8 @@ impl CutPolicy for SCCCutPolicy {
|
||||
} else {
|
||||
machine_st.fail = true;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if let Some(&(_, b_cutoff, prev_block)) = self.cont_pts.last() {
|
||||
if machine_st.b < b_cutoff {
|
||||
machine_st.block = prev_block;
|
||||
|
||||
@@ -1832,7 +1832,8 @@ impl MachineState {
|
||||
&ControlInstruction::CallClause(ClauseType::Named(ref name, ref idx), arity, _, lco)
|
||||
| &ControlInstruction::CallClause(ClauseType::Op(ref name, _, ref idx), arity, _, lco) => {
|
||||
self.last_call = lco;
|
||||
try_or_fail!(self, call_policy.context_call(self, name.clone(), arity, idx.clone()));
|
||||
try_or_fail!(self, call_policy.context_call(self, name.clone(), arity, idx.clone(),
|
||||
code_dirs));
|
||||
},
|
||||
&ControlInstruction::CallClause(ClauseType::System(ref ct), _, _, lco) => {
|
||||
self.last_call = lco;
|
||||
|
||||
@@ -17,13 +17,12 @@ use std::mem::swap;
|
||||
use std::ops::Index;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct MachineCodeIndex<'a> {
|
||||
pub code_dir: &'a mut CodeDir,
|
||||
pub op_dir: &'a mut OpDir,
|
||||
// pub modules: &'a ModuleDir
|
||||
pub struct MachineCodeIndices<'a> {
|
||||
pub(super) code_dir: &'a mut CodeDir,
|
||||
pub(super) op_dir: &'a mut OpDir,
|
||||
}
|
||||
|
||||
impl<'a> MachineCodeIndex<'a> {
|
||||
impl<'a> MachineCodeIndices<'a> {
|
||||
pub(super)
|
||||
fn lookup(&mut self, name: ClauseName, arity: usize, fixity: Option<Fixity>) -> ClauseType
|
||||
{
|
||||
@@ -73,7 +72,7 @@ impl Index<LocalCodePtr> for Machine {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SubModuleUser for MachineCodeIndex<'a> {
|
||||
impl<'a> SubModuleUser for MachineCodeIndices<'a> {
|
||||
fn op_dir(&mut self) -> &mut OpDir {
|
||||
self.op_dir
|
||||
}
|
||||
@@ -111,7 +110,7 @@ impl Machine {
|
||||
cached_query: None
|
||||
};
|
||||
|
||||
let indices = machine_code_index!(&mut CodeDir::new(), &mut default_op_dir());
|
||||
let indices = machine_code_indices!(&mut CodeDir::new(), &mut default_op_dir());
|
||||
compile_listing(&mut wam, BUILTINS, indices);
|
||||
|
||||
compile_user_module(&mut wam, LISTS);
|
||||
@@ -178,14 +177,14 @@ impl Machine {
|
||||
self.ms.atom_tbl.clone()
|
||||
}
|
||||
|
||||
pub fn use_qualified_module_in_toplevel(&mut self, name: ClauseName, exports: Vec<PredicateKey>) -> EvalSession
|
||||
pub fn use_qualified_module_in_toplevel(&mut self, name: ClauseName, exports: Vec<PredicateKey>)
|
||||
-> EvalSession
|
||||
{
|
||||
self.remove_module(name.clone());
|
||||
|
||||
if let Some(mut module) = self.modules.remove(&name) {
|
||||
let result = {
|
||||
let mut indices = machine_code_index!(&mut self.code_dir, &mut self.op_dir);
|
||||
//&self.modules);
|
||||
let mut indices = machine_code_indices!(&mut self.code_dir, &mut self.op_dir);
|
||||
indices.use_qualified_module(&mut module, &exports)
|
||||
};
|
||||
|
||||
@@ -202,8 +201,7 @@ impl Machine {
|
||||
|
||||
if let Some(mut module) = self.modules.remove(&name) {
|
||||
let result = {
|
||||
let mut indices = machine_code_index!(&mut self.code_dir, &mut self.op_dir);
|
||||
//&self.modules);
|
||||
let mut indices = machine_code_indices!(&mut self.code_dir, &mut self.op_dir);
|
||||
indices.use_module(&mut module)
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user