more fixes to C-interface

git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@2257 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
vsc 2008-06-04 13:58:42 +00:00
parent f868298acf
commit 08422c967a
7 changed files with 75 additions and 31 deletions

View File

@ -10,8 +10,12 @@
* File: c_interface.c * * File: c_interface.c *
* comments: c_interface primitives definition * * comments: c_interface primitives definition *
* * * *
* Last rev: $Date: 2008-04-28 23:02:32 $,$Author: vsc $ * * Last rev: $Date: 2008-06-04 13:58:36 $,$Author: vsc $ *
* $Log: not supported by cvs2svn $ * $Log: not supported by cvs2svn $
* Revision 1.116 2008/04/28 23:02:32 vsc
* fix bug in current_predicate/2
* fix bug in c_interface.
*
* Revision 1.115 2008/04/11 16:30:27 ricroc * Revision 1.115 2008/04/11 16:30:27 ricroc
* *** empty log message *** * *** empty log message ***
* *
@ -399,6 +403,7 @@ X_API Term STD_PROTO(YAP_BufferToString, (char *));
X_API Term STD_PROTO(YAP_BufferToAtomList, (char *)); X_API Term STD_PROTO(YAP_BufferToAtomList, (char *));
X_API void STD_PROTO(YAP_Error,(int, Term, char *, ...)); X_API void STD_PROTO(YAP_Error,(int, Term, char *, ...));
X_API Term STD_PROTO(YAP_RunGoal,(Term)); X_API Term STD_PROTO(YAP_RunGoal,(Term));
X_API Term STD_PROTO(YAP_RunGoalOnce,(Term));
X_API int STD_PROTO(YAP_RestartGoal,(void)); X_API int STD_PROTO(YAP_RestartGoal,(void));
X_API int STD_PROTO(YAP_ShutdownGoal,(int)); X_API int STD_PROTO(YAP_ShutdownGoal,(int));
X_API int STD_PROTO(YAP_EnterGoal,(PredEntry *, Term *, YAP_dogoalinfo *)); X_API int STD_PROTO(YAP_EnterGoal,(PredEntry *, Term *, YAP_dogoalinfo *));
@ -1429,8 +1434,8 @@ YAP_RunGoal(Term t)
CP = old_CP; CP = old_CP;
Yap_AllowRestart = TRUE; Yap_AllowRestart = TRUE;
} else { } else {
if (B != NULL) /* restore might have destroyed B */ ASP = B->cp_env;
B = B->cp_b; B = B->cp_b;
Yap_AllowRestart = FALSE; Yap_AllowRestart = FALSE;
} }
@ -1438,6 +1443,41 @@ YAP_RunGoal(Term t)
return(out); return(out);
} }
X_API Term
YAP_RunGoalOnce(Term t)
{
Term out;
yamop *old_CP = CP;
BACKUP_MACHINE_REGS();
Yap_PrologMode = UserMode;
out = Yap_RunTopGoal(t);
Yap_PrologMode = UserCCallMode;
if (out) {
choiceptr cut_pt;
cut_pt = B;
while (cut_pt-> cp_ap != NOCODE) {
cut_pt = cut_pt->cp_b;
}
#ifdef YAPOR
CUT_prune_to(cut_pt);
#endif
B = cut_pt;
}
ASP = B->cp_env;
ENV = (CELL *)ASP[E_E];
B = (choiceptr)ASP[E_CB];
#ifdef DEPTH_LIMIT
DEPTH = ASP[E_DEPTH];
#endif
P = (yamop *)ASP[E_CP];
CP = old_CP;
Yap_AllowRestart = FALSE;
RECOVER_MACHINE_REGS();
return(out);
}
X_API int X_API int
YAP_RestartGoal(void) YAP_RestartGoal(void)
{ {
@ -1469,7 +1509,6 @@ YAP_ShutdownGoal(int backtrack)
if (Yap_AllowRestart) { if (Yap_AllowRestart) {
choiceptr cut_pt; choiceptr cut_pt;
yamop *my_p = P;
cut_pt = B; cut_pt = B;
while (cut_pt-> cp_ap != NOCODE) { while (cut_pt-> cp_ap != NOCODE) {
@ -1488,10 +1527,7 @@ YAP_ShutdownGoal(int backtrack)
TR = cut_pt->cp_tr; TR = cut_pt->cp_tr;
} }
/* we can always recover the stack */ /* we can always recover the stack */
ENV = cut_pt->cp_env; ASP = cut_pt->cp_env;
ASP = (CELL *)(cut_pt+1);
ASP += EnvSizeInCells;
P = my_p;
ENV = (CELL *)ASP[E_E]; ENV = (CELL *)ASP[E_E];
B = (choiceptr)ASP[E_CB]; B = (choiceptr)ASP[E_CB];
#ifdef DEPTH_LIMIT #ifdef DEPTH_LIMIT

View File

@ -3456,15 +3456,15 @@ marking_phase(tr_fr_ptr old_TR, CELL *current_env, yamop *curp, CELL *max)
cont_top0 = (cont *)db_vec; cont_top0 = (cont *)db_vec;
#endif #endif
cont_top = (cont *)db_vec; cont_top = (cont *)db_vec;
#ifdef COROUTINING
mark_delays(max);
#endif
/* These two must be marked first so that our trail optimisation won't lose /* These two must be marked first so that our trail optimisation won't lose
values */ values */
mark_regs(old_TR); /* active registers & trail */ mark_regs(old_TR); /* active registers & trail */
/* active environments */ /* active environments */
mark_environments(current_env, EnvSize(curp), EnvBMap((CELL *)curp)); mark_environments(current_env, EnvSize(curp), EnvBMap((CELL *)curp));
mark_choicepoints(B, old_TR, is_gc_very_verbose()); /* choicepoints, and environs */ mark_choicepoints(B, old_TR, is_gc_very_verbose()); /* choicepoints, and environs */
#ifdef COROUTINING
mark_delays(max);
#endif
#ifdef EASY_SHUNTING #ifdef EASY_SHUNTING
set_conditionals(sTR); set_conditionals(sTR);
#endif #endif

View File

@ -26,6 +26,7 @@ YAP_EXTRAS=@YAP_EXTRAS@
PROGRAMS= $(srcdir)/debug.pl \ PROGRAMS= $(srcdir)/debug.pl \
$(srcdir)/maplist.pl \ $(srcdir)/maplist.pl \
$(srcdir)/nb_rbtrees.yap \
$(srcdir)/operators.pl \ $(srcdir)/operators.pl \
$(srcdir)/option.pl \ $(srcdir)/option.pl \
$(srcdir)/prolog_source.pl \ $(srcdir)/prolog_source.pl \

View File

@ -17,6 +17,8 @@
<h2>Yap-5.1.3:</h2> <h2>Yap-5.1.3:</h2>
<ul> <ul>
<li> FIXED: Introduce YAP_RunGoalOnce and make sure we actually
reover as much ASP as possible (obs from Jean Mehat).</li>
<li> FIXED: abolish_dynamic should drop FAIL_OP (obs from N <li> FIXED: abolish_dynamic should drop FAIL_OP (obs from N
Angelopoulos).</li> Angelopoulos).</li>
<li> FIXED: cygiwn should ignore SWI console (obs from A N Saravanaraj).</li> <li> FIXED: cygiwn should ignore SWI console (obs from A N Saravanaraj).</li>

View File

@ -139,7 +139,7 @@ do_top_goal (YAP_Term Goal)
fprintf(stderr,"Entering absmi\n"); fprintf(stderr,"Entering absmi\n");
#endif #endif
/* PlPutc(0,'a'); PlPutc(0,'\n'); */ /* PlPutc(0,'a'); PlPutc(0,'\n'); */
YAP_RunGoal(Goal); YAP_RunGoalOnce(Goal);
} }
/* do initial boot by consulting the file boot.yap */ /* do initial boot by consulting the file boot.yap */
@ -665,12 +665,12 @@ exec_top_level(int BootMode, YAP_init_args *iap)
fgoal = YAP_MkFunctor(YAP_FullLookupAtom("$silent_bootstrap"), 1); fgoal = YAP_MkFunctor(YAP_FullLookupAtom("$silent_bootstrap"), 1);
goal = YAP_MkApplTerm(fgoal, 1, as); goal = YAP_MkApplTerm(fgoal, 1, as);
/* launch consult */ /* launch consult */
YAP_RunGoal(goal); YAP_RunGoalOnce(goal);
/* set default module to user */ /* set default module to user */
as[0] = YAP_MkAtomTerm(YAP_LookupAtom("user")); as[0] = YAP_MkAtomTerm(YAP_LookupAtom("user"));
fgoal = YAP_MkFunctor(YAP_FullLookupAtom("module"), 1); fgoal = YAP_MkFunctor(YAP_FullLookupAtom("module"), 1);
goal = YAP_MkApplTerm(fgoal, 1, as); goal = YAP_MkApplTerm(fgoal, 1, as);
YAP_RunGoal(goal); YAP_RunGoalOnce(goal);
} }
YAP_PutValue(livegoal, YAP_MkAtomTerm (YAP_FullLookupAtom("$true"))); YAP_PutValue(livegoal, YAP_MkAtomTerm (YAP_FullLookupAtom("$true")));
@ -712,14 +712,14 @@ main (int argc, char **argv)
// load the module // load the module
YAP_Term mod_arg[1]; YAP_Term mod_arg[1];
mod_arg[0] = YAP_MkAtomTerm(YAP_LookupAtom("ypp")); mod_arg[0] = YAP_MkAtomTerm(YAP_LookupAtom("ypp"));
YAP_RunGoal(YAP_MkApplTerm(YAP_MkFunctor(YAP_LookupAtom("use_module"),1), 1, mod_arg)); YAP_RunGoalOnce(YAP_MkApplTerm(YAP_MkFunctor(YAP_LookupAtom("use_module"),1), 1, mod_arg));
// process the definitions // process the definitions
for(i=0;i<def_c;++i) { for(i=0;i<def_c;++i) {
YAP_Term t_args[2],t_goal; YAP_Term t_args[2],t_goal;
t_args[0] = YAP_MkAtomTerm(YAP_LookupAtom(def_var[i])); t_args[0] = YAP_MkAtomTerm(YAP_LookupAtom(def_var[i]));
t_args[1] = YAP_MkAtomTerm(YAP_LookupAtom(def_value[i])); t_args[1] = YAP_MkAtomTerm(YAP_LookupAtom(def_value[i]));
t_goal = YAP_MkApplTerm(YAP_MkFunctor(YAP_LookupAtom("ypp_define"),2), 2, t_args); t_goal = YAP_MkApplTerm(YAP_MkFunctor(YAP_LookupAtom("ypp_define"),2), 2, t_args);
YAP_RunGoal(t_goal); YAP_RunGoalOnce(t_goal);
} }
} }
YAP_ClearExceptions(); YAP_ClearExceptions();

View File

@ -14091,18 +14091,19 @@ Execute query @var{Goal} and return 1 if the query succeeds, and 0
otherwise. The predicate returns 0 if failure, otherwise it will return otherwise. The predicate returns 0 if failure, otherwise it will return
an @var{YAP_Term}. an @var{YAP_Term}.
One problem is that @var{YAP_Term} may change due to garbage Quite often, one wants to run a query once. In this case you should use
collection. To make sure you have access to the current value, it may be @var{Goal}:
a good idea to reload the term, as next example shows:
@example @example
val = YAP_RunGoal(YAP_ARG1); YAP_RunGoalOnce(YAP_Term Goal)
if (val == 0) return FALSE;
else t = YAP_ARG1;
@end example @end example
Note that even if execution failed, garbage collection might still have The @code{YAP_RunGoal()} function makes sure to recover stack space at
been called and moved the term. In this case, this is not a problem: the end of execution.
An alternative that ensures correct access to arguments is to use Prolog terms are pointers: a problem users often find is that the term
@var{Goal} may actually @emph{be moved around} during the execution of
@code{YAP_RunGoal()}, due to garbage collection or stack shifting. If
this is possible, @var{Goal} will become invalid after executing
@code{YAP_RunGoal()}. In this case, it is a good idea to save @var{Goal}
@emph{slots}, as shown next: @emph{slots}, as shown next:
@example @example
@ -14113,12 +14114,13 @@ An alternative that ensures correct access to arguments is to use
YAP_RecoverSlots(1); YAP_RecoverSlots(1);
if (out == 0) return FALSE; if (out == 0) return FALSE;
@end example @end example
Slots are safe houses in the stack, preserved by the garbage collector Slots are safe houses in the stack, the garbage collector and the stack
and the stack shifter. In this case, we use a slot to preserve @var{t} shifter know about them and make sure they have correct values. In this
during the execution of @code{YAP_RunGoal}. When the execution of case, we use a slot to preserve @var{t} during the execution of
@var{t} is over we read the (possibly changed) value of @var{t} back @code{YAP_RunGoal}. When the execution of @var{t} is over we read the
from the slot @var{sl} and tell YAP that the slot @var{sl} is not needed (possibly changed) value of @var{t} back from the slot @var{sl} and tell
and can be given back to the system. The slot functions are as follows: YAP that the slot @var{sl} is not needed and can be given back to the
system. The slot functions are as follows:
@table @code @table @code
@item long int YAP_NewSlots(int @var{NumberOfSlots}) @item long int YAP_NewSlots(int @var{NumberOfSlots})

View File

@ -238,6 +238,9 @@ extern X_API void PROTO(YAP_FreeSpaceFromYap,(void *));
/* int YAP_RunGoal(YAP_Term) */ /* int YAP_RunGoal(YAP_Term) */
extern X_API YAP_Term PROTO(YAP_RunGoal,(YAP_Term)); extern X_API YAP_Term PROTO(YAP_RunGoal,(YAP_Term));
/* int YAP_RunGoalOnce(YAP_Term) */
extern X_API YAP_Term PROTO(YAP_RunGoalOnce,(YAP_Term));
/* int YAP_RestartGoal(void) */ /* int YAP_RestartGoal(void) */
extern X_API YAP_Bool PROTO(YAP_RestartGoal,(void)); extern X_API YAP_Bool PROTO(YAP_RestartGoal,(void));