next up previous contents index
Next: Foreign code and Prolog Up: The Foreign Include File Previous: Foreign Code and Modules   Contents   Index

Prolog exceptions in foreign code

This section discusses PL_exception, PL_throw and PL_raise_exception, the interface functions to detect and generate Prolog exceptions from C-code. PL_throw and PL_raise_exception from the C-interface to raise an exception from foreign code. PL_throw exploits the C-function longjmp() to return immediately to the innermost PL_next_solution. PL_raise_exception registers the exception term and returns FALSE. If a foreign predicate returns FALSE, while and exception-term is registered a Prolog exception will be raised by the virtual machine.

Calling these functions outside the context of a function implementing a foreign predicate results in undefined behaviour.

PL_exception may be used after a call to PL_next_solution fails, and returns a term reference to an exception term if an exception was raised, and 0 otherwise.

If a C-function, implementing a predicate calls Prolog and detects an exception using PL_exception, it can handle this exception, or return with the exception. Some caution is required though. It is not allowed to call PL_close_query or PL_discard_foreign_frame afterwards, as this will invalidate the exception term. Below is the code that calls a Prolog defined arithmetic function (see arithmethic_function1).

If PL_next_solution succeeds, the result is analysed and translated to a number, after which the query is closed and all Prolog data created after PL_open_foreign_frame is destroyed. On the other hand, if PL_next_solution fails and if an exception was raised, just pass it. Otherwise generate an exception (PL_error is an internal call for building the standard error terms and calling PL_raise_exception). After this, the Prolog environment should be discarded using PL_cut_query and PL_close_foreign_frame to avoid invalidating the exception term.


\begin{code}
static int
prologFunction(ArithFunction f, term_t av, Number r)
{ i...
...ta */
PL_close_foreign_frame(fid); /* same */
}
\par return rval;
}
\end{code}

intPL_raise_exceptionterm_t exception Generate an exception (as throw1) and return FALSE. Below is an example returning an exception from foreign predicate:


\begin{code}
foreign_t
pl_hello(term_t to)
{ char *s;
\par if ( PL_get_atom_char...
...''atom'',
PL_TERM, to);
\par return PL_raise_exception(except);
}
}
\end{code}

intPL_throwterm_t exception Similar to PL_raise_exception, but returns using the C longjmp() function to the innermost PL_next_solution.

term_tPL_exceptionqid_t qid If PL_next_solution fails, this can be due to normal failure of the Prolog call, or because an exception was raised using throw1. This function returns a handle to the exception term if an exception was raised, or 0 if the Prolog goal simply failed.3.4.


next up previous contents index
Next: Foreign code and Prolog Up: The Foreign Include File Previous: Foreign Code and Modules   Contents   Index
Dr. Richard Botting 2001-12-12