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
Yap_AllocDynamicData(size_t bytes)
Yap_AllocExternalDataInStack(size_t bytes)
{
CACHE_REGS
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_IsPairTerm,(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_MkBigNumTerm,(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_MaxOpPriority,(Atom, Term));
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);
@ -2314,6 +2317,27 @@ YAP_RunGoal(Term t)
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
YAP_RunGoalOnce(Term t)
{

View File

@ -120,7 +120,7 @@ int STD_PROTO(Yap_IsStringTerm, (Term));
int STD_PROTO(Yap_IsWideStringTerm, (Term));
Term STD_PROTO(Yap_RatTermToApplTerm, (Term));
void STD_PROTO(Yap_InitBigNums, (void));
Term STD_PROTO(Yap_AllocDynamicData, (size_t));
Term STD_PROTO(Yap_AllocExternalDataInStack, (size_t));
/* c_interface.c */
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
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})
@findex YAP_HaltRegisterHook (C-Interface function)
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}
if this cannot be determined on your operating system) and the closure
argument @var{closure}.
function is called with two arguments: the exit code of the process
(@code{0} if this cannot be determined on your operating system) and
the closure argument @var{closure}.
@c See also @code{at_halt/1}.
@end table
@ -16850,6 +16866,7 @@ implementing the predicate and @var{arity} is its arity.
@findex YAP_UserBackCutCPredicate (C-Interface function)
@findex YAP_PRESERVE_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_cutfail (C-Interface function)
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
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
hold the information to be preserved across backtracking. The first
argument is the variable we shall use, and the second its type. Note
that we can only use @code{YAP_PRESERVE_DATA} once, so often we will
want the variable to be a structure.
The call to @code{YAP_PRESERVE_DATA} is used to initialize the memory
which will hold the information to be preserved across
backtracking. The first argument is the variable we shall use, and the
second its type. Note that we can only use @code{YAP_PRESERVE_DATA}
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
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
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
void
init_n100(void)
@ -16995,8 +17044,7 @@ init_n100(void)
YAP_UserBackCutCPredicate("n100", start_n100, continue_n100, NULL, 1, 1);
@}
@end example
Notice that we do not actually need to do anything on receiving a cut in
this case.
in this case no code is executed at cut time.
@node Loading Objects, Save&Rest, Writing C, C-Interface
@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 *) */
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)
__END_DECLS