external term support.

This commit is contained in:
Vitor Santos Costa 2011-07-21 06:32:49 -07:00
parent 6b6276a4d3
commit a1d903e3e9
5 changed files with 93 additions and 12 deletions

View File

@ -60,7 +60,7 @@ Yap_MkBigIntTerm(MP_INT *big)
} }
Term Term
Yap_AllocDynamicData(size_t bytes) Yap_AllocExternalDataInStack(size_t bytes)
{ {
CACHE_REGS CACHE_REGS
Int nlimbs; Int nlimbs;

View File

@ -390,6 +390,7 @@ X_API Bool STD_PROTO(YAP_IsDbRefTerm,(Term));
X_API Bool STD_PROTO(YAP_IsAtomTerm,(Term)); X_API Bool STD_PROTO(YAP_IsAtomTerm,(Term));
X_API Bool STD_PROTO(YAP_IsPairTerm,(Term)); X_API Bool STD_PROTO(YAP_IsPairTerm,(Term));
X_API Bool STD_PROTO(YAP_IsApplTerm,(Term)); X_API Bool STD_PROTO(YAP_IsApplTerm,(Term));
X_API Bool STD_PROTO(YAP_IsExternalDataInStackTerm,(Term));
X_API Term STD_PROTO(YAP_MkIntTerm,(Int)); X_API Term STD_PROTO(YAP_MkIntTerm,(Int));
X_API Term STD_PROTO(YAP_MkBigNumTerm,(void *)); X_API Term STD_PROTO(YAP_MkBigNumTerm,(void *));
X_API Term STD_PROTO(YAP_MkRationalTerm,(void *)); X_API Term STD_PROTO(YAP_MkRationalTerm,(void *));
@ -536,6 +537,8 @@ X_API Term STD_PROTO(YAP_ModuleUser,(void));
X_API Int STD_PROTO(YAP_NumberOfClausesForPredicate,(PredEntry *)); X_API Int STD_PROTO(YAP_NumberOfClausesForPredicate,(PredEntry *));
X_API int STD_PROTO(YAP_MaxOpPriority,(Atom, Term)); X_API int STD_PROTO(YAP_MaxOpPriority,(Atom, Term));
X_API int STD_PROTO(YAP_OpInfo,(Atom, Term, int, int *, int *)); X_API int STD_PROTO(YAP_OpInfo,(Atom, Term, int, int *, int *));
X_API Term STD_PROTO(YAP_AllocExternalDataInStack,(size_t));
X_API void *STD_PROTO(YAP_ExternalDataInStackFromTerm,(Term));
static int (*do_putcf)(wchar_t); static int (*do_putcf)(wchar_t);
@ -2314,6 +2317,27 @@ YAP_RunGoal(Term t)
return(out); return(out);
} }
X_API Term
YAP_AllocExternalDataInStack(size_t bytes)
{
Term t = Yap_AllocExternalDataInStack(bytes);
if (t == TermNil)
return 0L;
return t;
}
X_API Bool
YAP_IsExternalDataInStackTerm(Term t)
{
return IsExternalBlobTerm(t);
}
X_API void *
YAP_ExternalDataInStackFromTerm(Term t)
{
return ExternalBlobFromTerm (t);
}
X_API Term X_API Term
YAP_RunGoalOnce(Term t) YAP_RunGoalOnce(Term t)
{ {

View File

@ -120,7 +120,7 @@ int STD_PROTO(Yap_IsStringTerm, (Term));
int STD_PROTO(Yap_IsWideStringTerm, (Term)); int STD_PROTO(Yap_IsWideStringTerm, (Term));
Term STD_PROTO(Yap_RatTermToApplTerm, (Term)); Term STD_PROTO(Yap_RatTermToApplTerm, (Term));
void STD_PROTO(Yap_InitBigNums, (void)); void STD_PROTO(Yap_InitBigNums, (void));
Term STD_PROTO(Yap_AllocDynamicData, (size_t)); Term STD_PROTO(Yap_AllocExternalDataInStack, (size_t));
/* c_interface.c */ /* c_interface.c */
Int STD_PROTO(YAP_Execute,(struct pred_entry *, CPredicate)); Int STD_PROTO(YAP_Execute,(struct pred_entry *, CPredicate));

View File

@ -16811,13 +16811,29 @@ only two boolean flags are accepted: @code{YAPC_ENABLE_GC} and
@code{YAPC_ENABLE_AGC}. The first enables/disables the standard garbage @code{YAPC_ENABLE_AGC}. The first enables/disables the standard garbage
collector, the second does the same for the atom garbage collector.` collector, the second does the same for the atom garbage collector.`
@item @code{YAP_TERM} YAP_AllocExternalDataInStack(@code{size_t bytes})
@item @code{void *} YAP_ExternalDataInStackFromTerm(@code{YAP_Term t})
@item @code{YAP_Bool} YAP_IsExternalDataInStackTerm(@code{YAP_Term t})
@findex YAP_AllocExternalDataInStack (C-Interface function)
The next routines allow one to store external data in the Prolog
execution stack. The first routine reserves space for @var{sz} bytes
and returns an opaque handle. The second routines receives the handle
and returns a pointer to the data. The last routine checks if a term
is an opaque handle.
Data will be automatically reclaimed during
backtracking. Also, this storage is opaque to the Prolog garbage compiler,
so it should not be used to store Prolog terms. On the other hand, it
may be useful to store arrays in a compact way, or pointers to external objects.
@item @code{int} YAP_HaltRegisterHook(@code{YAP_halt_hook f, void *closure}) @item @code{int} YAP_HaltRegisterHook(@code{YAP_halt_hook f, void *closure})
@findex YAP_HaltRegisterHook (C-Interface function) @findex YAP_HaltRegisterHook (C-Interface function)
Register the function @var{f} to be called if YAP is halted. The Register the function @var{f} to be called if YAP is halted. The
function is called with two arguments: the exit code of the process (@code{0} function is called with two arguments: the exit code of the process
if this cannot be determined on your operating system) and the closure (@code{0} if this cannot be determined on your operating system) and
argument @var{closure}. the closure argument @var{closure}.
@c See also @code{at_halt/1}. @c See also @code{at_halt/1}.
@end table @end table
@ -16850,6 +16866,7 @@ implementing the predicate and @var{arity} is its arity.
@findex YAP_UserBackCutCPredicate (C-Interface function) @findex YAP_UserBackCutCPredicate (C-Interface function)
@findex YAP_PRESERVE_DATA (C-Interface function) @findex YAP_PRESERVE_DATA (C-Interface function)
@findex YAP_PRESERVED_DATA (C-Interface function) @findex YAP_PRESERVED_DATA (C-Interface function)
@findex YAP_PRESERVED_DATA_CUT (C-Interface function)
@findex YAP_cutsucceed (C-Interface function) @findex YAP_cutsucceed (C-Interface function)
@findex YAP_cutfail (C-Interface function) @findex YAP_cutfail (C-Interface function)
For the second kind of predicates we need three C functions. The first one For the second kind of predicates we need three C functions. The first one
@ -16915,11 +16932,15 @@ static int start_n100(void)
@end example @end example
The routine starts by getting the dereference value of the argument. The routine starts by getting the dereference value of the argument.
The call to @code{YAP_PRESERVE_DATA} is used to initialize the memory which will The call to @code{YAP_PRESERVE_DATA} is used to initialize the memory
hold the information to be preserved across backtracking. The first which will hold the information to be preserved across
argument is the variable we shall use, and the second its type. Note backtracking. The first argument is the variable we shall use, and the
that we can only use @code{YAP_PRESERVE_DATA} once, so often we will second its type. Note that we can only use @code{YAP_PRESERVE_DATA}
want the variable to be a structure. once, so often we will want the variable to be a structure. This data
is visible to the garbage collector, so it should consist of Prolog
terms, as in the example. It is also correct to store pointers to
objects external to YAP stacks, as the garbage collector will ignore
such references.
If the argument of the predicate is a variable, the routine initializes the If the argument of the predicate is a variable, the routine initializes the
structure to be preserved across backtracking with the information structure to be preserved across backtracking with the information
@ -16988,6 +17009,34 @@ when pruning the execution of the predicate, @var{arity} is the
predicate arity, and @var{sizeof} is the size of the data to be predicate arity, and @var{sizeof} is the size of the data to be
preserved in the stack. In this example, we would have something like preserved in the stack. In this example, we would have something like
@example
void
init_n100(void)
@{
YAP_UserBackCutCPredicate("n100", start_n100, continue_n100, cut_n100, 1, 1);
@}
@end example
The argument before last is the predicate's arity. Notice again the
last argument to the call. function argument gives the extra space we
want to use for @code{PRESERVED_DATA}. Space is given in cells, where
a cell is the same size as a pointer. The garbage collector has access
to this space, hence users should use it either to store terms or to
store pointers to objects outside the stacks.
The code for @code{cut_n100} could be:
@example
static int cut_n100(void)
@{
YAP_PRESERVED_DATA_CUT(n100_data,n100_data_type*);
fprintf("n100 cut with counter %ld\n", YAP_IntOfTerm(n100_data->next_solution));
return TRUE;
@}
@end example
Notice that we have to use @code{YAP_PRESERVED_DATA_CUT}: this is
because the Prolog engine is at a different state during cut.
If no work is required at cut, we can use:
@example @example
void void
init_n100(void) init_n100(void)
@ -16995,8 +17044,7 @@ init_n100(void)
YAP_UserBackCutCPredicate("n100", start_n100, continue_n100, NULL, 1, 1); YAP_UserBackCutCPredicate("n100", start_n100, continue_n100, NULL, 1, 1);
@} @}
@end example @end example
Notice that we do not actually need to do anything on receiving a cut in in this case no code is executed at cut time.
this case.
@node Loading Objects, Save&Rest, Writing C, C-Interface @node Loading Objects, Save&Rest, Writing C, C-Interface
@section Loading Object Files @section Loading Object Files

View File

@ -555,6 +555,15 @@ extern X_API int PROTO(YAP_MaxOpPriority,(YAP_Atom, YAP_Term));
/* int YAP_OpInfo(Atom, Term, int, int *, int *) */ /* int YAP_OpInfo(Atom, Term, int, int *, int *) */
extern X_API int PROTO(YAP_OpInfo,(YAP_Atom, YAP_Term, int, int *, int *)); extern X_API int PROTO(YAP_OpInfo,(YAP_Atom, YAP_Term, int, int *, int *));
/* YAP_Bool YAP_IsExternalDataInStackTerm(YAP_Term) */
extern X_API YAP_Bool PROTO(YAP_IsExternalDataInStackTerm,(YAP_Term));
/* Term YAP_AllocExternalDataInStack(size_t) */
extern X_API YAP_Term PROTO(YAP_AllocExternalDataInStack,(size_t));
/* void *YAP_ExternalDataInStackFromTerm(YAP_Term) */
extern X_API void *PROTO(YAP_ExternalDataInStackFromTerm,(YAP_Term));
#define YAP_InitCPred(N,A,F) YAP_UserCPredicate(N,F,A) #define YAP_InitCPred(N,A,F) YAP_UserCPredicate(N,F,A)
__END_DECLS __END_DECLS