The Prolog data created and term references needed to set up the call and/or analyse the result can in most cases be discarded right after the call. PL_close_query() allows for destroying the data, while leaving the term references. The calls below may be used to destroy term references and data. See figure 7 for an example.
term_t
handles created during the
execution of a foreign predicate are scoped to this execution. Note that
if the foreign predicate is
non-deterministic, term_t
handles are scoped to
each activation of the foreign function.
The user may create explicit foreign frames to undo (backtrack)
changes to Prolog terms. See PL_unify()
for an example. An explicit foreign frame must also be used for creating
a callback from C to Prolog (see PL_open_query())
to ensure the existence of such a frame and to scope the term_t
handles needed to setup the call to Prolog.
On success, the stack has room for at least 10 term_t
handles. This implies that foreign predicates as well as code inside an
explicitly created foreign frame may use PL_new_term_ref()
to create up to 10 term_t
handles without checking the
return status.
Returns (fid_t)0
on failure. Failure is either lack of
space on the stacks, in which case a resource exception is scheduled or
atom-gc being in progress in the current thread, in which case no
exception is scheduled. The latter is an exceptional case that prevents
doing a callback on Prolog from blob release handlers.230Such
a callback would deadlock if the callback creates new atoms or
requires stack shifts or garbage collection.
It is obligatory to call either of the two closing functions to discard a foreign frame. Foreign frames may be nested.
int count_atoms() { fid_t fid = PL_open_foreign_frame(); term_t goal = PL_new_term_ref(); term_t a1 = PL_new_term_ref(); term_t a2 = PL_new_term_ref(); functor_t s2 = PL_new_functor(PL_new_atom("statistics"), 2); int atoms; PL_put_atom_chars(a1, "atoms"); PL_cons_functor(goal, s2, a1, a2); PL_call(goal, NULL); /* call it in current module */ PL_get_integer(a2, &atoms); PL_discard_foreign_frame(fid); return atoms; }