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

View File

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

View File

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