- Documentation
- Reference manual
- Foreign Language Interface
- The Foreign Include File
- Argument Passing and Control
- Atoms and functors
- Input and output
- Analysing Terms via the Foreign Interface
- Constructing Terms
- Unifying data
- Convenient functions to generate Prolog exceptions
- Foreign language wrapper support functions
- Serializing and deserializing Prolog terms
- BLOBS: Using atoms to store arbitrary binary data
- Exchanging GMP numbers
- Calling Prolog from C
- Discarding Data
- String buffering
- Foreign Code and Modules
- Prolog exceptions in foreign code
- Catching Signals (Software Interrupts)
- Miscellaneous
- Errors and warnings
- Environment Control from Foreign Code
- Querying Prolog
- Registering Foreign Predicates
- Foreign Code Hooks
- Storing foreign data
- Embedding SWI-Prolog in other applications
- The Foreign Include File
- Foreign Language Interface
- Packages
- Reference manual
12.4.13 Discarding Data
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. Each call to a foreign
predicate is wrapped in a PL_open_foreign_frame()
and
PL_close_foreign_frame()
pair. This ensures that
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 10term_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.229Such 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. Prolog data referenced by the discarded term references is not affected.
- 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; }