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:
parent
f868298acf
commit
08422c967a
@ -10,8 +10,12 @@
|
||||
* File: c_interface.c *
|
||||
* 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 $
|
||||
* 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
|
||||
* *** 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 void STD_PROTO(YAP_Error,(int, Term, char *, ...));
|
||||
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_ShutdownGoal,(int));
|
||||
X_API int STD_PROTO(YAP_EnterGoal,(PredEntry *, Term *, YAP_dogoalinfo *));
|
||||
@ -1429,7 +1434,7 @@ YAP_RunGoal(Term t)
|
||||
CP = old_CP;
|
||||
Yap_AllowRestart = TRUE;
|
||||
} else {
|
||||
if (B != NULL) /* restore might have destroyed B */
|
||||
ASP = B->cp_env;
|
||||
B = B->cp_b;
|
||||
Yap_AllowRestart = FALSE;
|
||||
}
|
||||
@ -1438,6 +1443,41 @@ YAP_RunGoal(Term t)
|
||||
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
|
||||
YAP_RestartGoal(void)
|
||||
{
|
||||
@ -1469,7 +1509,6 @@ YAP_ShutdownGoal(int backtrack)
|
||||
|
||||
if (Yap_AllowRestart) {
|
||||
choiceptr cut_pt;
|
||||
yamop *my_p = P;
|
||||
|
||||
cut_pt = B;
|
||||
while (cut_pt-> cp_ap != NOCODE) {
|
||||
@ -1488,10 +1527,7 @@ YAP_ShutdownGoal(int backtrack)
|
||||
TR = cut_pt->cp_tr;
|
||||
}
|
||||
/* we can always recover the stack */
|
||||
ENV = cut_pt->cp_env;
|
||||
ASP = (CELL *)(cut_pt+1);
|
||||
ASP += EnvSizeInCells;
|
||||
P = my_p;
|
||||
ASP = cut_pt->cp_env;
|
||||
ENV = (CELL *)ASP[E_E];
|
||||
B = (choiceptr)ASP[E_CB];
|
||||
#ifdef DEPTH_LIMIT
|
||||
|
@ -3456,15 +3456,15 @@ marking_phase(tr_fr_ptr old_TR, CELL *current_env, yamop *curp, CELL *max)
|
||||
cont_top0 = (cont *)db_vec;
|
||||
#endif
|
||||
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
|
||||
values */
|
||||
mark_regs(old_TR); /* active registers & trail */
|
||||
/* active environments */
|
||||
mark_environments(current_env, EnvSize(curp), EnvBMap((CELL *)curp));
|
||||
mark_choicepoints(B, old_TR, is_gc_very_verbose()); /* choicepoints, and environs */
|
||||
#ifdef COROUTINING
|
||||
mark_delays(max);
|
||||
#endif
|
||||
#ifdef EASY_SHUNTING
|
||||
set_conditionals(sTR);
|
||||
#endif
|
||||
|
@ -26,6 +26,7 @@ YAP_EXTRAS=@YAP_EXTRAS@
|
||||
|
||||
PROGRAMS= $(srcdir)/debug.pl \
|
||||
$(srcdir)/maplist.pl \
|
||||
$(srcdir)/nb_rbtrees.yap \
|
||||
$(srcdir)/operators.pl \
|
||||
$(srcdir)/option.pl \
|
||||
$(srcdir)/prolog_source.pl \
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
<h2>Yap-5.1.3:</h2>
|
||||
<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
|
||||
Angelopoulos).</li>
|
||||
<li> FIXED: cygiwn should ignore SWI console (obs from A N Saravanaraj).</li>
|
||||
|
@ -139,7 +139,7 @@ do_top_goal (YAP_Term Goal)
|
||||
fprintf(stderr,"Entering absmi\n");
|
||||
#endif
|
||||
/* PlPutc(0,'a'); PlPutc(0,'\n'); */
|
||||
YAP_RunGoal(Goal);
|
||||
YAP_RunGoalOnce(Goal);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
goal = YAP_MkApplTerm(fgoal, 1, as);
|
||||
/* launch consult */
|
||||
YAP_RunGoal(goal);
|
||||
YAP_RunGoalOnce(goal);
|
||||
/* set default module to user */
|
||||
as[0] = YAP_MkAtomTerm(YAP_LookupAtom("user"));
|
||||
fgoal = YAP_MkFunctor(YAP_FullLookupAtom("module"), 1);
|
||||
goal = YAP_MkApplTerm(fgoal, 1, as);
|
||||
YAP_RunGoal(goal);
|
||||
YAP_RunGoalOnce(goal);
|
||||
}
|
||||
YAP_PutValue(livegoal, YAP_MkAtomTerm (YAP_FullLookupAtom("$true")));
|
||||
|
||||
@ -712,14 +712,14 @@ main (int argc, char **argv)
|
||||
// load the module
|
||||
YAP_Term mod_arg[1];
|
||||
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
|
||||
for(i=0;i<def_c;++i) {
|
||||
YAP_Term t_args[2],t_goal;
|
||||
t_args[0] = YAP_MkAtomTerm(YAP_LookupAtom(def_var[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);
|
||||
YAP_RunGoal(t_goal);
|
||||
YAP_RunGoalOnce(t_goal);
|
||||
}
|
||||
}
|
||||
YAP_ClearExceptions();
|
||||
|
32
docs/yap.tex
32
docs/yap.tex
@ -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
|
||||
an @var{YAP_Term}.
|
||||
|
||||
One problem is that @var{YAP_Term} may change due to garbage
|
||||
collection. To make sure you have access to the current value, it may be
|
||||
a good idea to reload the term, as next example shows:
|
||||
Quite often, one wants to run a query once. In this case you should use
|
||||
@var{Goal}:
|
||||
@example
|
||||
val = YAP_RunGoal(YAP_ARG1);
|
||||
if (val == 0) return FALSE;
|
||||
else t = YAP_ARG1;
|
||||
YAP_RunGoalOnce(YAP_Term Goal)
|
||||
@end example
|
||||
Note that even if execution failed, garbage collection might still have
|
||||
been called and moved the term. In this case, this is not a problem:
|
||||
The @code{YAP_RunGoal()} function makes sure to recover stack space at
|
||||
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:
|
||||
|
||||
@example
|
||||
@ -14113,12 +14114,13 @@ An alternative that ensures correct access to arguments is to use
|
||||
YAP_RecoverSlots(1);
|
||||
if (out == 0) return FALSE;
|
||||
@end example
|
||||
Slots are safe houses in the stack, preserved by the garbage collector
|
||||
and the stack shifter. In this case, we use a slot to preserve @var{t}
|
||||
during the execution of @code{YAP_RunGoal}. When the execution of
|
||||
@var{t} is over we read the (possibly changed) value of @var{t} back
|
||||
from the slot @var{sl} and tell YAP that the slot @var{sl} is not needed
|
||||
and can be given back to the system. The slot functions are as follows:
|
||||
Slots are safe houses in the stack, the garbage collector and the stack
|
||||
shifter know about them and make sure they have correct values. In this
|
||||
case, we use a slot to preserve @var{t} during the execution of
|
||||
@code{YAP_RunGoal}. When the execution of @var{t} is over we read the
|
||||
(possibly changed) value of @var{t} back from the slot @var{sl} and tell
|
||||
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
|
||||
@item long int YAP_NewSlots(int @var{NumberOfSlots})
|
||||
|
@ -238,6 +238,9 @@ extern X_API void PROTO(YAP_FreeSpaceFromYap,(void *));
|
||||
/* int 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) */
|
||||
extern X_API YAP_Bool PROTO(YAP_RestartGoal,(void));
|
||||
|
||||
|
Reference in New Issue
Block a user