From 7155aa943f956489938717be1d0a8af4592800ed Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Wed, 22 Jul 2009 23:28:04 -0500 Subject: [PATCH] make sure that variables in tabled predicates are safe for backtracking: new variables should be bound carefully. --- C/amasm.c | 2 +- C/compiler.c | 17 +++++++++++++---- C/tracer.c | 4 ++++ 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/C/amasm.c b/C/amasm.c index 8059365f9..76116aeb1 100644 --- a/C/amasm.c +++ b/C/amasm.c @@ -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 */ Prop fe = (Prop) (cip->cpc->rnd1); CELL Flags = RepPredProp(fe)->PredFlags; - if (Flags & AsmPredFlag && !(cip->CurrentPred->PredFlags & TabledPredFlag)) { + if (Flags & AsmPredFlag) { op_numbers op; int is_test = FALSE; diff --git a/C/compiler.c b/C/compiler.c index c6d54d55e..f1e2ee611 100644 --- a/C/compiler.c +++ b/C/compiler.c @@ -871,7 +871,7 @@ c_eq(Term t1, Term t2, compiler_struct *cglobs) } } /* first argument is an unbound var */ - if (IsNewVar(t1)) { + if (IsNewVar(t1) && !(cglobs->cint.CurrentPred->PredFlags & TabledPredFlag)) { Int v; if (IsVarTerm(t2)) { 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(); 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)) */) { c_var(t3,f_flag,(unsigned int)Op, 0, cglobs); if (Op == _functor) { @@ -1758,7 +1767,7 @@ c_goal(Term Goal, Term mod, compiler_struct *cglobs) c_goal(ArgOfTerm(2, Goal), mod, cglobs); return; } - else if (f == FunctorEq && !(cglobs->cint.CurrentPred->PredFlags & TabledPredFlag)) { + else if (f == FunctorEq) { if (profiling) Yap_emit(enter_profiling_op, (CELL)p, Zero, &cglobs->cint); else if (call_counting) @@ -1785,7 +1794,7 @@ c_goal(Term Goal, Term mod, compiler_struct *cglobs) v->FlagsOfVE |= SafeVar; return; } - else if (p->PredFlags & AsmPredFlag && !(cglobs->cint.CurrentPred->PredFlags & TabledPredFlag)) { + else if (p->PredFlags & AsmPredFlag) { int op = p->PredFlags & 0x7f; if (profiling) @@ -1850,7 +1859,7 @@ c_goal(Term Goal, Term mod, compiler_struct *cglobs) #ifdef BEAM else if (p->PredFlags & BinaryPredFlag && !EAM) { #else - else if (p->PredFlags & BinaryPredFlag && !(cglobs->cint.CurrentPred->PredFlags & TabledPredFlag)) { + else if (p->PredFlags & BinaryPredFlag) { #endif Term a1 = ArgOfTerm(1,Goal); diff --git a/C/tracer.c b/C/tracer.c index 4b91937ed..362e6e854 100644 --- a/C/tracer.c +++ b/C/tracer.c @@ -172,6 +172,10 @@ low_level_trace(yap_low_level_port port, PredEntry *pred, CELL *args) LOCK(Yap_heap_regs->low_level_trace_lock); sc = Yap_heap_regs; vsc_count++; + if (vsc_count < 50000) + return; + if (vsc_count == 50084) + jmp_deb(1); #ifdef THREADS Yap_heap_regs->thread_handle[worker_id].thread_inst_count++; #endif