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.
- fid_t PL_open_foreign_frame()
-
Create a foreign frame, holding a mark that allows the system to undo
bindings and destroy data created after it, as well as providing the
environment for creating term references. This function is called by the
kernel before calling a foreign predicate. 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.227Such
a callback would deadlock if the callback creates new atoms or
requires stack shifts or garbage collection.
- void PL_close_foreign_frame(fid_t
id)
- Discard all term references created after the frame was opened. All
other Prolog data is retained. This function is called by the kernel
whenever a foreign function returns control back to Prolog.
- void PL_discard_foreign_frame(fid_t
id)
- Same as PL_close_foreign_frame(),
but also undo all bindings made since the open and destroy all Prolog
data.
- void PL_rewind_foreign_frame(fid_t
id)
- Undo all bindings and discard all term references created since the
frame was created, but do not pop the frame. That is, the same frame can
be rewound multiple times, and must eventually be closed or discarded.
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;
}
Figure 7 : Calling Prolog