fix handling of backtrackable C-code in longjmp and other long range cuts.

This commit is contained in:
Vitor Santos Costa 2011-07-09 07:56:11 -04:00
parent 15f5277ca4
commit 6863a43e76
4 changed files with 63 additions and 21 deletions

View File

@ -1139,11 +1139,21 @@ YAP_cut_up(void)
choiceptr cut_pt; choiceptr cut_pt;
cut_pt = B->cp_b; cut_pt = B->cp_b;
/* make sure we prune C-choicepoints */
if (POP_CHOICE_POINT(B->cp_b))
{
POP_EXECUTE();
}
CUT_prune_to(cut_pt); CUT_prune_to(cut_pt);
Yap_TrimTrail(); Yap_TrimTrail();
B = cut_pt; B = cut_pt;
} }
#else #else
/* make sure we prune C-choicepoints */
if (POP_CHOICE_POINT(B->cp_b))
{
POP_EXECUTE();
}
Yap_TrimTrail(); Yap_TrimTrail();
B = B->cp_b; /* cut_fail */ B = B->cp_b; /* cut_fail */
#endif #endif
@ -2260,6 +2270,11 @@ YAP_LeaveGoal(int backtrack, YAP_dogoalinfo *dgi)
} }
/* recover local stack */ /* recover local stack */
ASP = (CELL *)(B+1); ASP = (CELL *)(B+1);
/* make sure we prune C-choicepoints */
if (POP_CHOICE_POINT(B->cp_b))
{
POP_EXECUTE();
}
B = B->cp_b; B = B->cp_b;
HB = B->cp_h; HB = B->cp_h;
P = dgi->p; P = dgi->p;
@ -2310,6 +2325,11 @@ YAP_RunGoalOnce(Term t)
cut_pt = B; cut_pt = B;
while (cut_pt-> cp_ap != NOCODE) { while (cut_pt-> cp_ap != NOCODE) {
/* make sure we prune C-choicepoints */
if (POP_CHOICE_POINT(cut_pt->cp_b))
{
POP_EXECUTE();
}
cut_pt = cut_pt->cp_b; cut_pt = cut_pt->cp_b;
} }
#ifdef YAPOR #ifdef YAPOR
@ -2367,6 +2387,11 @@ YAP_ShutdownGoal(int backtrack)
cut_pt = B; cut_pt = B;
while (cut_pt-> cp_ap != NOCODE) { while (cut_pt-> cp_ap != NOCODE) {
/* make sure we prune C-choicepoints */
if (POP_CHOICE_POINT(cut_pt->cp_b))
{
POP_EXECUTE();
}
cut_pt = cut_pt->cp_b; cut_pt = cut_pt->cp_b;
} }
#ifdef YAPOR #ifdef YAPOR
@ -2417,6 +2442,11 @@ YAP_PruneGoal(void)
BACKUP_B(); BACKUP_B();
while (B->cp_ap != NOCODE) { while (B->cp_ap != NOCODE) {
/* make sure we prune C-choicepoints */
if (POP_CHOICE_POINT(B->cp_b))
{
POP_EXECUTE();
}
B = B->cp_b; B = B->cp_b;
} }
Yap_TrimTrail(); Yap_TrimTrail();

View File

@ -1157,7 +1157,9 @@ Yap_execute_goal(Term t, int nargs, Term mod)
while (B->cp_b < cut_B) { while (B->cp_b < cut_B) {
B = B->cp_b; B = B->cp_b;
} }
#ifdef TABLING
abolish_incomplete_subgoals(B); abolish_incomplete_subgoals(B);
#endif
} }
#endif /* TABLING */ #endif /* TABLING */
B = cut_B; B = cut_B;
@ -1346,29 +1348,25 @@ p_restore_regs2( USES_REGS1 )
#else #else
pt0 = (choiceptr)(LCL0-IntOfTerm(d0)); pt0 = (choiceptr)(LCL0-IntOfTerm(d0));
#endif #endif
#ifdef CUT_C
{
while (POP_CHOICE_POINT(pt0))
{
POP_EXECUTE();
}
}
#endif /* CUT_C */
#ifdef YAPOR
CUT_prune_to(pt0);
#endif /* YAPOR */
/* find where to cut to */ /* find where to cut to */
if (pt0 > B) { if (pt0 > B) {
/* Wow, we're gonna cut!!! */ /* Wow, we're gonna cut!!! */
#ifdef TABLING
while (B->cp_b < pt0) { while (B->cp_b < pt0) {
while (POP_CHOICE_POINT(B->cp_b))
{
POP_EXECUTE();
}
HB = B->cp_h;
Yap_TrimTrail();
B = B->cp_b; B = B->cp_b;
} }
#ifdef TABLING
abolish_incomplete_subgoals(B); abolish_incomplete_subgoals(B);
#endif /* TABLING */ #endif
#ifdef YAPOR
CUT_prune_to(pt0);
#endif /* YAPOR */
B = pt0; B = pt0;
HB = B->cp_h;
Yap_TrimTrail();
} }
return(TRUE); return(TRUE);
} }
@ -1395,6 +1393,10 @@ p_clean_ifcp( USES_REGS1 ) {
/* this should never happen */ /* this should never happen */
return TRUE; return TRUE;
} else if (pt0 == B) { } else if (pt0 == B) {
while (POP_CHOICE_POINT(B->cp_b))
{
POP_EXECUTE();
}
B = B->cp_b; B = B->cp_b;
HB = B->cp_h; HB = B->cp_h;
} else { } else {
@ -1491,10 +1493,11 @@ JumpToEnv(Term t USES_REGS) {
/* we have a cleanup handler in the middle */ /* we have a cleanup handler in the middle */
if (is_cleanup_cp(handler)) { if (is_cleanup_cp(handler)) {
/* keep it around */ /* keep it around */
if (previous == NULL) if (previous == NULL) {
B = handler; B = handler;
else } else {
previous->cp_b = handler; previous->cp_b = handler;
}
previous = handler; previous = handler;
#ifdef TABLING #ifdef TABLING
} else { } else {
@ -1521,6 +1524,11 @@ JumpToEnv(Term t USES_REGS) {
HB = B->cp_h; HB = B->cp_h;
return TRUE; return TRUE;
} }
/* make sure we prune C-choicepoints */
while (POP_CHOICE_POINT(handler->cp_b))
{
POP_EXECUTE();
}
handler = handler->cp_b; handler = handler->cp_b;
} }
/* uncaught throw */ /* uncaught throw */
@ -1552,6 +1560,7 @@ JumpToEnv(Term t USES_REGS) {
// EX = t; // EX = t;
previous->cp_b = handler; previous->cp_b = handler;
} }
/* make sure we get rid of trash in the trail */
handler->cp_cp = (yamop *)env[E_CP]; handler->cp_cp = (yamop *)env[E_CP];
handler->cp_env = (CELL *)env[E_E]; handler->cp_env = (CELL *)env[E_E];
handler->cp_ap = catchpos; handler->cp_ap = catchpos;

View File

@ -163,6 +163,9 @@ 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 < 12000)
return;
jmp_deb(1);
#ifdef THREADS #ifdef THREADS
LOCAL_ThreadHandle.thread_inst_count++; LOCAL_ThreadHandle.thread_inst_count++;
#endif #endif

View File

@ -1276,23 +1276,23 @@ throw(Ball) :-
'$handle_throw'(C, A, _Ball) :- '$handle_throw'(C, A, _Ball) :-
'$reset_exception'(Ball), '$reset_exception'(Ball),
% reset info % reset info
('catch_ball'(Ball, C) -> (catch_ball(Ball, C) ->
'$execute'(A) '$execute'(A)
; ;
throw(Ball) throw(Ball)
). ).
'catch_ball'(Abort, _) :- Abort == '$abort', !, fail. catch_ball(Abort, _) :- Abort == '$abort', !, fail.
% system defined throws should be ignored by used, unless the % system defined throws should be ignored by used, unless the
% user is hacking away. % user is hacking away.
'catch_ball'(Ball, V) :- catch_ball(Ball, V) :-
var(V), var(V),
nonvar(Ball), nonvar(Ball),
Ball = error(Type,_), % internal error ?? Ball = error(Type,_), % internal error ??
functor(Type, Name, _), functor(Type, Name, _),
atom_codes(Name, [0'$|_]), %'0 atom_codes(Name, [0'$|_]), %'0
!, fail. !, fail.
'catch_ball'(C, C). catch_ball(C, C).
'$run_toplevel_hooks' :- '$run_toplevel_hooks' :-
nb_getval('$break',0), nb_getval('$break',0),