let module_code =
compiler.generate_code(results.worker_results, wam, &mut indices.code_dir, 0)?;
- let mut clause_code_generator = ClauseCodeGenerator::new(module_code.len());
- clause_code_generator.generate_clause_code(results.dynamic_clause_map, wam)?;
+ let mut clause_code_generator = ClauseCodeGenerator::new(module_code.len(), module_name.clone());
+ clause_code_generator.generate_clause_code(&results.dynamic_clause_map, wam)?;
update_module_indices(wam, module_name, indices);
wam.code_repo.code.extend(module_code.into_iter());
- clause_code_generator.add_clause_code(wam);
+ clause_code_generator.add_clause_code(wam, results.dynamic_clause_map);
Ok(compiler.drop_expansions(wam.machine_flags(), &mut wam.code_repo))
}
pub struct ClauseCodeGenerator {
len_offset: usize,
code: Code,
+ module_name: ClauseName,
pi_to_loc: IndexMap<PredicateKey, usize>,
}
impl ClauseCodeGenerator {
#[inline]
- fn new(len_offset: usize) -> Self {
+ fn new(len_offset: usize, module_name: ClauseName) -> Self {
ClauseCodeGenerator {
len_offset,
code: vec![],
+ module_name,
pi_to_loc: IndexMap::new(),
}
}
fn generate_clause_code(
&mut self,
- dynamic_clause_map: DynamicClauseMap,
+ dynamic_clause_map: &DynamicClauseMap,
wam: &Machine,
) -> Result<(), SessionError> {
for ((name, arity), heads_and_tails) in dynamic_clause_map {
let predicate = Predicate(
heads_and_tails
- .into_iter()
+ .iter()
.map(|(head, tail)| {
let clause = Term::Clause(
Cell::default(),
clause_name!("clause"),
- vec![Box::new(head), Box::new(tail)],
+ vec![Box::new(head.clone()), Box::new(tail.clone())],
None,
);
PredicateClause::Fact(clause)
compile_appendix(&mut decl_code, &VecDeque::new(), false, wam.machine_flags())?;
- self.pi_to_loc.insert((name, arity), p);
+ self.pi_to_loc.insert((name.clone(), *arity), p);
self.code.extend(decl_code.into_iter());
}
Ok(())
}
- fn add_clause_code(self, wam: &mut Machine) {
+ fn add_clause_code(self, wam: &mut Machine, dynamic_code_dir: DynamicClauseMap)
+ {
wam.code_repo.code.extend(self.code.into_iter());
+ for ((name, arity), _) in dynamic_code_dir {
+ wam.indices.dynamic_code_dir.insert((name.owning_module(), name.clone(), arity),
+ DynamicPredicateInfo::default());
+ wam.indices.code_dir.entry((name, arity))
+ .or_insert(CodeIndex::dynamic_undefined(self.module_name.clone()));
+ }
+
for ((name, arity), p) in self.pi_to_loc {
let entry = wam
.indices
) -> Result<(), SessionError> {
wam.check_toplevel_code(&indices)?;
- let mut clause_code_generator = ClauseCodeGenerator::new(code.len());
- clause_code_generator.generate_clause_code(dynamic_clause_map, wam)?;
+ let mut clause_code_generator = ClauseCodeGenerator::new(code.len(), clause_name!("user"));
+ clause_code_generator.generate_clause_code(&dynamic_clause_map, wam)?;
add_toplevel_code(wam, code, indices);
- clause_code_generator.add_clause_code(wam);
+ clause_code_generator.add_clause_code(wam, dynamic_clause_map);
Ok(())
}
.dynamic_clause_map
.entry((name.clone(), arity))
.or_insert(vec![]);
+
+ indices.code_dir.insert((name.clone(), arity),
+ CodeIndex::dynamic_undefined(self.get_module_name()));
}
&Declaration::Hook(hook, _, ref queue) if self.module.is_none() => worker
.term_stream
if let Some(module) = compiler.module.take() {
let mut clause_code_generator =
- ClauseCodeGenerator::new(module_code.len() + toplvl_code.len());
+ ClauseCodeGenerator::new(module_code.len() + toplvl_code.len(),
+ module.module_decl.name.clone());
try_eval_session!(wam.check_toplevel_code(&results.toplevel_indices));
try_eval_session!(
- clause_code_generator.generate_clause_code(results.dynamic_clause_map, wam)
+ clause_code_generator.generate_clause_code(&results.dynamic_clause_map, wam)
);
add_module_code(wam, module, module_code, indices);
add_toplevel_code(wam, toplvl_code, results.toplevel_indices);
- clause_code_generator.add_clause_code(wam);
+ clause_code_generator.add_clause_code(wam, results.dynamic_clause_map);
} else {
try_eval_session!(add_non_module_code(
wam,
let (name, arity) = self.get_predicate_key(name, arity);
if let Some(idx) = self.indices.code_dir.get(&(name.clone(), arity)) {
- set_code_index!(idx, IndexPtr::Undefined, clause_name!("user"));
+ set_code_index!(idx, IndexPtr::DynamicUndefined, clause_name!("user"));
}
self.indices.remove_code_index((name.clone(), arity));
if let Some(idx) = self.indices.code_dir.get(&(name.clone(), arity)) {
if idx.module_name() == module_name {
- set_code_index!(idx, IndexPtr::Undefined, clause_name!("user"));
+ set_code_index!(idx, IndexPtr::DynamicUndefined, clause_name!("user"));
}
}
let mut addrs = VecDeque::from(addrs);
addrs.remove(index);
- if addrs.is_empty() {
- self.abolish_dynamic_clause_in_module(temp_v!(1), temp_v!(2), temp_v!(5));
- return;
- }
-
self.print_new_dynamic_clause(addrs, name.clone(), arity)
}
Err(err) => return self.machine_st.throw_exception(err),
let mut addrs = VecDeque::from(addrs);
addrs.remove(index);
- if addrs.is_empty() {
- self.abolish_dynamic_clause(temp_v!(1), temp_v!(2));
- return;
- }
-
self.print_new_dynamic_clause(addrs, name.clone(), arity)
}
Err(err) => return self.machine_st.throw_exception(err),
let (name, arity) = key;
if let Some(ref idx) = indices.get_code_index((name.clone(), arity), module_name.clone()) {
- if let IndexPtr::Index(compiled_tl_index) = idx.0.borrow().0 {
- if last_call {
- self.execute_at_index(arity, compiled_tl_index);
- } else {
- self.call_at_index(arity, compiled_tl_index);
- }
+ match idx.0.borrow().0 {
+ IndexPtr::Index(compiled_tl_index) => {
+ if last_call {
+ self.execute_at_index(arity, compiled_tl_index);
+ } else {
+ self.call_at_index(arity, compiled_tl_index);
+ }
- return Ok(());
+ return Ok(());
+ }
+ IndexPtr::DynamicUndefined => {
+ self.fail = true;
+ return Ok(());
+ }
+ _ => {}
}
}
indices: &IndexStore,
) -> CallResult {
match idx.0.borrow().0 {
- IndexPtr::Undefined => return try_in_situ(machine_st, name, arity, indices, false),
+ IndexPtr::DynamicUndefined =>
+ machine_st.fail = true,
+ IndexPtr::Undefined =>
+ return try_in_situ(machine_st, name, arity, indices, false),
IndexPtr::Index(compiled_tl_index) => {
machine_st.call_at_index(arity, compiled_tl_index)
}
indices: &IndexStore,
) -> CallResult {
match idx.0.borrow().0 {
- IndexPtr::Undefined => return try_in_situ(machine_st, name, arity, indices, true),
+ IndexPtr::DynamicUndefined =>
+ machine_st.fail = true,
+ IndexPtr::Undefined =>
+ return try_in_situ(machine_st, name, arity, indices, true),
IndexPtr::Index(compiled_tl_index) => {
machine_st.execute_at_index(arity, compiled_tl_index)
}