Skip to content

Commit

Permalink
Merge pull request #2812 from bakaq/attr_vars_arity_fix
Browse files Browse the repository at this point in the history
Fix bug in finding arity for verify attributes
  • Loading branch information
mthom authored Feb 13, 2025
2 parents c548b14 + 6d80c84 commit e5cca9d
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 14 deletions.
60 changes: 46 additions & 14 deletions src/machine/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,30 +563,62 @@ impl Machine {
self.machine_st.cp = self.machine_st.attr_var_init.cp;
}

let mut p = self.machine_st.p;
let mut arity = 0;
let p = self.machine_st.p;

while self.code[p].is_head_instr() {
for r in self.code[p].registers() {
if let RegType::Temp(t) = r {
arity = std::cmp::max(arity, t);
}
}
// Find the boundaries of the current predicate
self.indices.code_dir.sort_by(|_, a, _, b| a.cmp(b));

p += 1;
}
let predicate_idx = self
.indices
.code_dir
.binary_search_by_key(&p, |_, x| x.get().p() as usize)
.unwrap_or_else(|x| x - 1);

let current_pred_start = self
.indices
.code_dir
.get_index(predicate_idx)
.map(|x| x.1.p() as usize)
.unwrap();

debug_assert!(current_pred_start <= p);

let current_pred_end = self
.indices
.code_dir
.get_index(predicate_idx + 1)
.map(|x| x.1.p() as usize)
.unwrap_or(self.code.len());

debug_assert!(current_pred_end >= p);
debug_assert!(current_pred_end <= self.code.len());

// Find point to insert the interrupt
let p_interrupt = p + self.code[p..current_pred_end]
.iter()
.position(|x| !x.is_head_instr())
.unwrap();

// Scan registers of all instructions to find out how many to save
let arity = self.code[current_pred_start..current_pred_end]
.iter()
.flat_map(Instruction::registers)
.flat_map(|r| match r {
RegType::Temp(t) => Some(t),
_ => None,
})
.max()
.unwrap_or(0);

let instr = std::mem::replace(
&mut self.code[p],
&mut self.code[p_interrupt],
Instruction::VerifyAttrInterrupt(arity),
);

self.code[VERIFY_ATTR_INTERRUPT_LOC] = instr;
self.machine_st.attr_var_init.cp = p;
self.machine_st.attr_var_init.cp = p_interrupt;
}
&Instruction::VerifyAttrInterrupt(arity) => {
// let (_, arity) = self.code[VERIFY_ATTR_INTERRUPT_LOC].to_name_and_arity();
// let arity = std::cmp::max(arity, self.machine_st.num_of_args);
self.run_verify_attr_interrupt(arity);
}
&Instruction::Add(ref a1, ref a2, t) => {
Expand Down
17 changes: 17 additions & 0 deletions tests/scryer/cli/issues/compilation_bug.in/a.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
% Issue 2706
:- use_module(library(atts)).
:- use_module(library(lists)).
:- use_module(library(iso_ext)).

:- attribute a/1.

verify_attributes(_,_, []).

asdf([_|Xs], N) :-
true,
N1 is N - 1,
asdf(Xs, N1).

test_a :-
put_atts(A, a(1)),
call_with_inference_limit(asdf(A, 1), 1000, _).
30 changes: 30 additions & 0 deletions tests/scryer/cli/issues/compilation_bug.in/b.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
% Issue 2632

% Repro for cycle detection crash
:- use_module(library(lists)).
:- use_module(library(clpz)).
:- use_module(library(error)).
:- use_module(library(lambda)).
:- use_module(library(debug)).

clpz:monotonic.

q_r(T/N, T:U) :- 0 #=< #T, 0 #=< #U, #N #= T + U.

qs_Ts_Us(Qs, ΣTs, ΣUs) :-
maplist(\Q^T^U^(q_r(Q, T:U)), Qs, Ts, Us),
intlist_partsums(Ts, ΣTs),
intlist_partsums(Us, ΣUs).

%% Utility predicates used above:

intlist_partsums([X|Xs], [X|Ss]) :-
intlist_partsums_acc(Xs, Ss, X).

intlist_partsums_acc([], [], _).
intlist_partsums_acc([X|Xs], [S|Ss], A) :-
#S #= #X + #A,
intlist_partsums_acc(Xs, Ss, S).

test_b :-
once(qs_Ts_Us(_, [1,3], [5,9])).
19 changes: 19 additions & 0 deletions tests/scryer/cli/issues/compilation_bug.in/c.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
% Issue 2809

:- use_module(library(freeze)).

main1 :-
freeze(Minor,true),
cbor_minor_value1(Minor, []).

main2 :-
freeze(Minor,true),
cbor_minor_value2(Minor, []).

cbor_minor_value1(24, S0) :- numbytes_number(1, S0).

cbor_minor_value2(24, S0) :- S0=S1, numbytes_number(1, S1).

numbytes_number(_, []).

test_c :- main1.
2 changes: 2 additions & 0 deletions tests/scryer/cli/issues/compilation_bug.stdin
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
use_module(a), use_module(b), use_module(c).
\+ \+ (test_a, test_b, test_c).
2 changes: 2 additions & 0 deletions tests/scryer/cli/issues/compilation_bug.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
true.
true.
2 changes: 2 additions & 0 deletions tests/scryer/cli/issues/compilation_bug.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# issue 2706
args = ["-f", "--no-add-history"]

0 comments on commit e5cca9d

Please sign in to comment.