make sure that variables in tabled predicates are safe for backtracking: new

variables should be bound carefully.
This commit is contained in:
Vitor Santos Costa 2009-07-22 23:28:04 -05:00
parent 4882cefa12
commit 7155aa943f
3 changed files with 18 additions and 5 deletions

View File

@ -1438,7 +1438,7 @@ a_p(op_numbers opcode, clause_info *clinfo, yamop *code_p, int pass_no, struct i
{ /* emit opcode & predicate code address */ { /* emit opcode & predicate code address */
Prop fe = (Prop) (cip->cpc->rnd1); Prop fe = (Prop) (cip->cpc->rnd1);
CELL Flags = RepPredProp(fe)->PredFlags; CELL Flags = RepPredProp(fe)->PredFlags;
if (Flags & AsmPredFlag && !(cip->CurrentPred->PredFlags & TabledPredFlag)) { if (Flags & AsmPredFlag) {
op_numbers op; op_numbers op;
int is_test = FALSE; int is_test = FALSE;

View File

@ -871,7 +871,7 @@ c_eq(Term t1, Term t2, compiler_struct *cglobs)
} }
} }
/* first argument is an unbound var */ /* first argument is an unbound var */
if (IsNewVar(t1)) { if (IsNewVar(t1) && !(cglobs->cint.CurrentPred->PredFlags & TabledPredFlag)) {
Int v; Int v;
if (IsVarTerm(t2)) { if (IsVarTerm(t2)) {
v = 0; v = 0;
@ -1268,6 +1268,15 @@ c_bifun(Int Op, Term t1, Term t2, Term t3, Term Goal, Term mod, compiler_struct
save_machine_regs(); save_machine_regs();
longjmp(cglobs->cint.CompilerBotch,1); longjmp(cglobs->cint.CompilerBotch,1);
} }
} else if (IsNewVar(t3) && cglobs->curbranch == 0 && cglobs->cint.CurrentPred->PredFlags & TabledPredFlag) {
Term nv = MkVarTerm();
c_var(nv,f_flag,(unsigned int)Op, 0, cglobs);
if (Op == _functor) {
Yap_emit(empty_call_op, Zero, Zero, &cglobs->cint);
Yap_emit(restore_tmps_and_skip_op, Zero, Zero, &cglobs->cint);
}
/* make sure that we first get the true t3, and then bind it to nv. That way it will be confitional */
c_eq(t3, nv, cglobs);
} else if (IsNewVar(t3) && cglobs->curbranch == 0 /* otherwise you may have trouble with z(X) :- ( Z is X*2 ; write(Z)) */) { } else if (IsNewVar(t3) && cglobs->curbranch == 0 /* otherwise you may have trouble with z(X) :- ( Z is X*2 ; write(Z)) */) {
c_var(t3,f_flag,(unsigned int)Op, 0, cglobs); c_var(t3,f_flag,(unsigned int)Op, 0, cglobs);
if (Op == _functor) { if (Op == _functor) {
@ -1758,7 +1767,7 @@ c_goal(Term Goal, Term mod, compiler_struct *cglobs)
c_goal(ArgOfTerm(2, Goal), mod, cglobs); c_goal(ArgOfTerm(2, Goal), mod, cglobs);
return; return;
} }
else if (f == FunctorEq && !(cglobs->cint.CurrentPred->PredFlags & TabledPredFlag)) { else if (f == FunctorEq) {
if (profiling) if (profiling)
Yap_emit(enter_profiling_op, (CELL)p, Zero, &cglobs->cint); Yap_emit(enter_profiling_op, (CELL)p, Zero, &cglobs->cint);
else if (call_counting) else if (call_counting)
@ -1785,7 +1794,7 @@ c_goal(Term Goal, Term mod, compiler_struct *cglobs)
v->FlagsOfVE |= SafeVar; v->FlagsOfVE |= SafeVar;
return; return;
} }
else if (p->PredFlags & AsmPredFlag && !(cglobs->cint.CurrentPred->PredFlags & TabledPredFlag)) { else if (p->PredFlags & AsmPredFlag) {
int op = p->PredFlags & 0x7f; int op = p->PredFlags & 0x7f;
if (profiling) if (profiling)
@ -1850,7 +1859,7 @@ c_goal(Term Goal, Term mod, compiler_struct *cglobs)
#ifdef BEAM #ifdef BEAM
else if (p->PredFlags & BinaryPredFlag && !EAM) { else if (p->PredFlags & BinaryPredFlag && !EAM) {
#else #else
else if (p->PredFlags & BinaryPredFlag && !(cglobs->cint.CurrentPred->PredFlags & TabledPredFlag)) { else if (p->PredFlags & BinaryPredFlag) {
#endif #endif
Term a1 = ArgOfTerm(1,Goal); Term a1 = ArgOfTerm(1,Goal);

View File

@ -172,6 +172,10 @@ low_level_trace(yap_low_level_port port, PredEntry *pred, CELL *args)
LOCK(Yap_heap_regs->low_level_trace_lock); LOCK(Yap_heap_regs->low_level_trace_lock);
sc = Yap_heap_regs; sc = Yap_heap_regs;
vsc_count++; vsc_count++;
if (vsc_count < 50000)
return;
if (vsc_count == 50084)
jmp_deb(1);
#ifdef THREADS #ifdef THREADS
Yap_heap_regs->thread_handle[worker_id].thread_inst_count++; Yap_heap_regs->thread_handle[worker_id].thread_inst_count++;
#endif #endif