error handling

This commit is contained in:
Vitor Santos Costa 2018-05-21 14:45:24 +01:00
parent 6e9882c369
commit b7a97a5b19
5 changed files with 168 additions and 151 deletions

View File

@ -34,9 +34,10 @@ X_API bool do_init_python(void);
YAPPredicate::YAPPredicate(Term &t, Term &tmod, CELL *&ts, const char *pname) {
Term t0 = t;
ap = nullptr;
Yap_DebugPlWriteln(t);
restart:
if (IsVarTerm(t)) {
throw YAPError( SOURCE(), INSTANTIATION_ERROR, t0, pname);
throw YAPError(SOURCE(), INSTANTIATION_ERROR, t0, pname);
} else if (IsAtomTerm(t)) {
ap = RepPredProp(Yap_GetPredPropByAtom(AtomOfTerm(t), tmod));
ts = nullptr;
@ -49,15 +50,16 @@ restart:
} else if (IsApplTerm(t)) {
Functor fun = FunctorOfTerm(t);
if (IsExtensionFunctor(fun)) {
throw YAPError( SOURCE(), TYPE_ERROR_CALLABLE, Yap_PredicateIndicator(t, tmod), pname);
throw YAPError(SOURCE(), TYPE_ERROR_CALLABLE,
Yap_PredicateIndicator(t, tmod), pname);
}
if (fun == FunctorModule) {
tmod = ArgOfTerm(1, t);
if (IsVarTerm(tmod)) {
throw YAPError( SOURCE(), INSTANTIATION_ERROR, t0, pname);
throw YAPError(SOURCE(), INSTANTIATION_ERROR, t0, pname);
}
if (!IsAtomTerm(tmod)) {
throw YAPError( SOURCE(), TYPE_ERROR_ATOM, t0, pname);
throw YAPError(SOURCE(), TYPE_ERROR_ATOM, t0, pname);
}
t = ArgOfTerm(2, t);
goto restart;
@ -65,32 +67,32 @@ restart:
ap = RepPredProp(Yap_GetPredPropByFunc(fun, tmod));
ts = RepAppl(t) + 1;
} else {
throw YAPError( SOURCE(), TYPE_ERROR_CALLABLE, t0, pname);
throw YAPError(SOURCE(), TYPE_ERROR_CALLABLE, t0, pname);
}
}
Term YAPTerm::getArg(arity_t i) {
BACKUP_MACHINE_REGS();
Term tf = 0;
Term t0 = gt();
Term YAPTerm::getArg(arity_t i) {
BACKUP_MACHINE_REGS();
Term tf = 0;
Term t0 = gt();
if (IsApplTerm(t0)) {
if (i > ArityOfFunctor(FunctorOfTerm(t0)))
throw YAPError( SOURCE(), DOMAIN_ERROR_OUT_OF_RANGE, t0, "t0.getArg()");
tf = (ArgOfTerm(i, t0));
} else if (IsPairTerm(t0)) {
if (i == 1)
tf = (HeadOfTerm(t0));
else if (i == 2)
tf = (TailOfTerm(t0));
else
throw YAPError( SOURCE(), DOMAIN_ERROR_OUT_OF_RANGE, t0, "t0.getArg()");
} else {
throw YAPError( SOURCE(), TYPE_ERROR_COMPOUND, t0, "t0.getArg()");
}
RECOVER_MACHINE_REGS();
return tf;
if (IsApplTerm(t0)) {
if (i > ArityOfFunctor(FunctorOfTerm(t0)))
throw YAPError(SOURCE(), DOMAIN_ERROR_OUT_OF_RANGE, t0, "t0.getArg()");
tf = (ArgOfTerm(i, t0));
} else if (IsPairTerm(t0)) {
if (i == 1)
tf = (HeadOfTerm(t0));
else if (i == 2)
tf = (TailOfTerm(t0));
else
throw YAPError(SOURCE(), DOMAIN_ERROR_OUT_OF_RANGE, t0, "t0.getArg()");
} else {
throw YAPError(SOURCE(), TYPE_ERROR_COMPOUND, t0, "t0.getArg()");
}
RECOVER_MACHINE_REGS();
return tf;
}
YAPAtomTerm::YAPAtomTerm(char s[]) { // build string
BACKUP_H();
@ -265,7 +267,7 @@ Term &YAPTerm::operator[](arity_t i) {
tf = RepPair(t0) + 1;
RECOVER_MACHINE_REGS();
} else {
throw YAPError( SOURCE(), TYPE_ERROR_COMPOUND, t0, "");
throw YAPError(SOURCE(), TYPE_ERROR_COMPOUND, t0, "");
}
RECOVER_MACHINE_REGS();
return *tf;
@ -303,22 +305,21 @@ YAPPairTerm::YAPPairTerm() {
}
std::vector<Term> YAPPairTerm::listToArray() {
Term *tailp;
Term t1 = gt();
Int l = Yap_SkipList(&t1, &tailp);
if (l < 0) {
throw YAPError( SOURCE(), TYPE_ERROR_LIST, (t), nullptr);
}
std::vector<Term> o = std::vector<Term>(l);
int i = 0;
Term t = gt();
while (t != TermNil) {
o[i++] = HeadOfTerm(t);
t = TailOfTerm(t);
}
return o;
Term *tailp;
Term t1 = gt();
Int l = Yap_SkipList(&t1, &tailp);
if (l < 0) {
throw YAPError(SOURCE(), TYPE_ERROR_LIST, (t), nullptr);
}
std::vector<Term> o = std::vector<Term>(l);
int i = 0;
Term t = gt();
while (t != TermNil) {
o[i++] = HeadOfTerm(t);
t = TailOfTerm(t);
}
return o;
}
YAP_tag_t YAPTerm::tag() {
Term tt = gt();
@ -375,14 +376,14 @@ Term YAPTerm::deepCopy() {
}
Term YAPListTerm::cdr() {
Term to = gt();
if (IsPairTerm(to))
return (TailOfTerm(to));
else if (to == TermNil)
return TermNil;
/* error */
throw YAPError( SOURCE(), TYPE_ERROR_LIST, to, "");
}
Term to = gt();
if (IsPairTerm(to))
return (TailOfTerm(to));
else if (to == TermNil)
return TermNil;
/* error */
throw YAPError(SOURCE(), TYPE_ERROR_LIST, to, "");
}
Term YAPListTerm::dup() {
yhandle_t tn;
@ -431,7 +432,7 @@ Term YAPListTerm::car() {
if (IsPairTerm(to))
return (HeadOfTerm(to));
else {
throw YAPError( SOURCE(), TYPE_ERROR_LIST, to, "");
throw YAPError(SOURCE(), TYPE_ERROR_LIST, to, "");
return TermUnique;
}
}
@ -487,7 +488,8 @@ bool YAPEngine::call(YAPPredicate ap, YAPTerm ts[]) {
if (LOCAL_CommittedError != nullptr) {
std::cerr << "Exception received by " << __func__ << "( "
<< YAPError( LOCAL_CommittedError).text() << ").\n Forwarded...\n\n";
<< YAPError(LOCAL_CommittedError).text()
<< ").\n Forwarded...\n\n";
// Yap_PopTermFromDB(info->errorTerm);
// throw throw YAPError( SOURCE(), );
}
@ -508,8 +510,10 @@ bool YAPEngine::mgoal(Term t, Term tmod) {
try {
if (IsStringTerm(tmod))
tmod = MkAtomTerm(Yap_LookupAtom(StringOfTerm(tmod)));
PredEntry *ap = (new YAPPredicate(t, tmod, ts, "C++"))->ap;
if (ap == nullptr || ap->OpcodeOfPred == UNDEF_OPCODE) {
YAPPredicate *p = new YAPPredicate(t, tmod, ts, "C++");
PredEntry *ap = nullptr;
if (p == nullptr || (ap = p->ap) == nullptr ||
ap->OpcodeOfPred == UNDEF_OPCODE) {
ap = rewriteUndefEngineQuery(ap, t, tmod);
}
if (IsApplTerm(t))
@ -527,27 +531,37 @@ bool YAPEngine::mgoal(Term t, Term tmod) {
q.CurSlot = Yap_StartSlots();
q.p = P;
q.cp = CP;
// allow Prolog style exception handling
// don't forget, on success these guys may create slots
// allow Prolog style exception handling
// don't forget, on success these guys may create slots
__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "exec ");
result = (bool)YAP_EnterGoal(ap, nullptr, &q);
if (LOCAL_CommittedError != nullptr &&
LOCAL_CommittedError->errorNo != YAP_NO_ERROR) {
throw YAPError( LOCAL_CommittedError);
LOCAL_CommittedError->errorNo != YAP_NO_ERROR) {
throw YAPError(LOCAL_CommittedError);
}
{
YAP_LeaveGoal(result, &q);
if (LOCAL_CommittedError != nullptr &&
LOCAL_CommittedError->errorNo != YAP_NO_ERROR) {
throw YAPError(LOCAL_CommittedError);
}
// PyEval_RestoreThread(_save);
RECOVER_MACHINE_REGS();
return result;
}
} catch (...) {
if (LOCAL_CommittedError != nullptr &&
LOCAL_CommittedError->errorNo != YAP_NO_ERROR) {
std::cerr << "Exception received by " << __func__ << "( "
<< YAPError(LOCAL_CommittedError).text()
<< ").\n Forwarded...\n\n";
// free(LOCAL_CommittedError);
LOCAL_CommittedError->errorNo = YAP_NO_ERROR;
LOCAL_ActiveError->errorNo = YAP_NO_ERROR;
LOCAL_CommittedError = nullptr;
return false;
}
{
YAP_LeaveGoal(result, &q);
// PyEval_RestoreThread(_save);
RECOVER_MACHINE_REGS();
return result;
}
} catch ( ... ) {
if (LOCAL_CommittedError != nullptr &&
LOCAL_CommittedError->errorNo != YAP_NO_ERROR) {
std::cerr << "Exception received by " << __func__ << "( "
<< YAPError( LOCAL_CommittedError).text() << ").\n Forwarded...\n\n";
}
}
}
@ -585,7 +599,7 @@ Term YAPEngine::fun(Term t) {
name = AtomDot;
f = FunctorDot;
} else {
throw YAPError( SOURCE(), TYPE_ERROR_CALLABLE, t, 0);
throw YAPError(SOURCE(), TYPE_ERROR_CALLABLE, t, 0);
return 0L;
}
XREGS[arity + 1] = MkVarTerm();
@ -606,7 +620,8 @@ Term YAPEngine::fun(Term t) {
bool result = (bool)YAP_EnterGoal(ap, nullptr, &q);
if (LOCAL_CommittedError != nullptr) {
std::cerr << "Exception received by " << __func__ << "( "
<< YAPError( LOCAL_CommittedError).text() << ").\n Forwarded...\n\n";
<< YAPError(LOCAL_CommittedError).text()
<< ").\n Forwarded...\n\n";
// Yap_PopTermFromDB(info->errorTerm);
// throw throw YAPError( SOURCE(), );
}
@ -725,9 +740,9 @@ bool YAPQuery::next() {
YAP_LeaveGoal(false, &q_h);
Yap_CloseHandles(q_handles);
q_open = false;
if (LOCAL_CommittedError != nullptr) {
// Yap_PopTermFromDB(info->errorTerm);
// throw throw YAPError( );
if (LOCAL_CommittedError != nullptr) {
// Yap_PopTermFromDB(info->errorTerm);
// throw throw YAPError( );
Term es[2];
es[0] = TermError;
es[1] = MkErrorTerm(LOCAL_CommittedError);
@ -911,15 +926,15 @@ PredEntry *YAPPredicate::getPred(YAPTerm &tt, CELL *&outp) {
CACHE_REGS
Term m = Yap_CurrentModule(), t = tt.term();
t = Yap_StripModule(t, &m);
std::cerr << "Exception received by " << __func__ << "( "
<< tt.text() << ").\n Forwarded...\n\n";
std::cerr << "Exception received by " << __func__ << "( " << tt.text()
<< ").\n Forwarded...\n\n";
if (IsVarTerm(t) || IsNumTerm(t)) {
if (IsVarTerm(t))
throw YAPError( SOURCE(), INSTANTIATION_ERROR, tt.term(), 0);
throw YAPError(SOURCE(), INSTANTIATION_ERROR, tt.term(), 0);
else if (IsNumTerm(t))
throw YAPError( SOURCE(), TYPE_ERROR_CALLABLE, tt.term(), 0);
throw YAPError(SOURCE(), TYPE_ERROR_CALLABLE, tt.term(), 0);
}
tt.put(t);
if (IsAtomTerm(t)) {
@ -938,7 +953,7 @@ PredEntry *YAPPredicate::getPred(YAPTerm &tt, CELL *&outp) {
}
Functor f = FunctorOfTerm(t);
if (IsExtensionFunctor(f)) {
throw YAPError( SOURCE(), TYPE_ERROR_CALLABLE, t, 0);
throw YAPError(SOURCE(), TYPE_ERROR_CALLABLE, t, 0);
} else {
ap = RepPredProp(PredPropByFunc(f, m));
outp = RepAppl(t) + 1;
@ -1002,31 +1017,32 @@ void *YAPPrologPredicate::retractClause(YAPTerm skeleton, bool all) {
std::string YAPError::text() {
char buf[256];
std::string s = "";
return "Error";
#if 0
std::stringstream s;
s << "";
if (info->errorNo == YAP_NO_ERROR)
return 0;
if (info->errorFunction) {
if (info->errorFunction) {
s += info->errorFile;
s += ":";
sprintf(buf, "%ld", (long int)info->errorLine);
s += buf;
s += ":0 in C-code";
}
return s;
if (info->prologPredLine) {
s += "\n";
s += info->prologPredFile;
s += ":";
sprintf(buf, "%ld", (long int)info->prologPredLine);
s += buf; // std::to_string(info->prologPredLine) ;
s << info->prologPredLine;
// YAPIntegerTerm(info->prologPredLine).text();
s += ":0 ";
s += info->prologPredModule;
s += ":";
s += (info->prologPredName);
s += "/";
sprintf(buf, "%ld", (long int)info->prologPredArity);
s += // std::to_string(info->prologPredArity);
buf;
s << info->prologPredArity;
}
s += " error ";
if (info->classAsText == nullptr)
@ -1035,12 +1051,13 @@ std::string YAPError::text() {
s += info->classAsText;
s += ".";
if (info->errorAsText == nullptr)
info->errorAsText = Yap_errorName(info->errorNo);
info->errorAsText = Yap_errorName(info->errorNo);
if (info->errorAsText != nullptr)
s += info->errorAsText;
s += ".\n";
// printf("%s\n", s.c_str());
return s.c_str();
#endif
}
void YAPEngine::reSet() {
@ -1063,7 +1080,6 @@ void YAPEngine::reSet() {
RECOVER_MACHINE_REGS();
}
Term YAPEngine::top_level(std::string s) {
/// parse string s and make term with var names
/// available.
@ -1072,7 +1088,7 @@ Term YAPEngine::top_level(std::string s) {
ARG2 = tp;
ARG3 = MkVarTerm();
if (ARG1 == 0)
throw YAPError( SOURCE(), SYNTAX_ERROR, ARG1, "in input query");
throw YAPError(SOURCE(), SYNTAX_ERROR, ARG1, "in input query");
YAPPredicate p = YAPPredicate(YAP_TopGoal());
YAPQuery *Q = new YAPQuery(p, 0);
Term ts[2];

View File

@ -7,20 +7,5 @@
YAP includes a number of extensions over the original Prolog
language. Next, we discuss how to use the most important ones.
+ @ref Rational_Trees
+ @ref AttributedVariables
+ @ref DepthLimited
+ @ref Tabling
+ @ref Threads
+ @ref Profiling
+ @ref YAPArrays
+ @ref Parallelism
@}

View File

@ -28,7 +28,8 @@ static char SccsId[] = "%W% %G%";
*/
/*
* This file includes the definition of a miscellania of standard predicates *
*for yap refering to: Files and GLOBAL_Streams, Simple Input/Output,
*for yap refering to: Files and GLOBAL_1588
*ams, Simple Input/Output,
*
*/
@ -1584,7 +1585,7 @@ int Yap_OpenStream(Term tin, const char *io_mode, Term user_name,
st->file = fopen(fname, io_mode);
}
if (!st->file) {
fprintf(stderr, "trying %s\n", fname);
PlIOError(EXISTENCE_ERROR_SOURCE_SINK, tin, "%s", fname);
/* extract BACK info passed through the stream descriptor */
return -1;
@ -1632,12 +1633,10 @@ int Yap_OpenStream(Term tin, const char *io_mode, Term user_name,
if (!strchr(io_mode, 'b') && binary_file(fname)) {
UNLOCK(st->streamlock);
if (errno == ENOENT && !strchr(io_mode, 'r')) {
PlIOError(EXISTENCE_ERROR_SOURCE_SINK,
tin, "%s: %s", fname,
PlIOError(EXISTENCE_ERROR_SOURCE_SINK, tin, "%s: %s", fname,
strerror(errno));
} else {
PlIOError(PERMISSION_ERROR_OPEN_SOURCE_SINK,
tin, "%s: %s", fname,
PlIOError(PERMISSION_ERROR_OPEN_SOURCE_SINK, tin, "%s: %s", fname,
strerror(errno));
}
}

View File

@ -7,8 +7,7 @@
YAP_Term TermErrStream, TermOutStream;
static int py_put(int sno, int ch)
{
static int py_put(int sno, int ch) {
// PyObject *pyw; // buffer
// int pyw_kind;
// PyObject *pyw_data;
@ -16,13 +15,13 @@ static int py_put(int sno, int ch)
if (st->user_name == TermOutStream) {
term_t tg = python_acquire_GIL();
PySys_WriteStdout("%C", ch);
python_release_GIL(tg);
return ch;
python_release_GIL(tg);
return ch;
}
if (st->user_name == TermErrStream) {
term_t tg = python_acquire_GIL();
PySys_WriteStderr("%C", ch);
python_release_GIL(tg);
term_t tg = python_acquire_GIL();
PySys_WriteStderr("%C", ch);
python_release_GIL(tg);
return ch;
}
char s[2];
@ -33,8 +32,7 @@ static int py_put(int sno, int ch)
PyObject_CallMethodObjArgs(st->u.private_data, PyUnicode_FromString("write"),
PyUnicode_FromString(s), NULL);
python_release_GIL(g0);
if ((err = PyErr_Occurred()))
{
if ((err = PyErr_Occurred())) {
PyErr_SetString(
err,
"Error in put\n"); // %s:%s:%d!\n", __FILE__, __FUNCTION__, __LINE__);
@ -43,7 +41,8 @@ static int py_put(int sno, int ch)
}
VFS_t pystream;
static void *py_open(VFS_t *me, const char *name, const char *io_mode, int sno) {
static void *py_open(VFS_t *me, const char *name, const char *io_mode,
int sno) {
#if HAVE_STRCASESTR
if (strcasestr(name, "/python/") == name)
name += strlen("/python/");
@ -52,34 +51,36 @@ VFS_t pystream;
name += strlen("/python/");
#endif
term_t ctk = python_acquire_GIL();
PyObject *pystream = string_to_python(name, true, NULL);
if (pystream == NULL || pystream == Py_None) {
python_release_GIL(ctk);
return NULL;
}
PyObject *pystream = string_to_python(name, true, NULL);
if (pystream == NULL || pystream == Py_None) {
python_release_GIL(ctk);
return NULL;
}
StreamDesc *st = YAP_RepStreamFromId(sno);
st->name = YAP_LookupAtom(name);
if (strcmp(name,"sys.stdout") == 0) {
if (strcmp(name, "sys.stdout") == 0) {
st->user_name = TermOutStream;
} else if(strcmp(name,"sys.stderr") == 0) {
} else if (strcmp(name, "sys.stderr") == 0) {
st->user_name = TermErrStream;
} else {
st->user_name = YAP_MkAtomTerm(st->name);
}
// we assume object is already open, so there is no need to open it.
st->u.private_data = pystream;
if (PyCallable_Check(pystream))
st->u.private_data = PyObject_Call(pystream, PyTuple_New(0), NULL);
else
st->u.private_data = pystream;
st->vfs = me;
python_release_GIL(ctk);
python_release_GIL(ctk);
return st;
}
static bool py_close(int sno) {
StreamDesc *st = YAP_RepStreamFromId(sno);
if (strcmp(st->name,"sys.stdout") &&
strcmp(st->name,"sys.stderr")) {
Py_XDECREF(st->u.private_data);
if (strcmp(st->name, "sys.stdout") && strcmp(st->name, "sys.stderr")) {
Py_XDECREF(st->u.private_data);
}
st->u.private_data = NULL;
st->u.private_data = NULL;
st->vfs = NULL;
return true;
@ -87,19 +88,20 @@ static bool py_close(int sno) {
static bool getLine(int inp) {
char *myrl_line = NULL;
StreamDesc *rl_instream = YAP_RepStreamFromId(inp);
term_t ctk = python_acquire_GIL();
fprintf(stderr,"in");
PyObject*prompt = PyUnicode_FromString( "?- "),
*msg = PyUnicode_FromString(" **input** ");
StreamDesc *rl_instream = YAP_RepStreamFromId(inp);
term_t ctk = python_acquire_GIL();
fprintf(stderr, "in");
PyObject *prompt = PyUnicode_FromString("?- "),
*msg = PyUnicode_FromString(" **input** ");
/* window of vulnerability opened */
myrl_line = PyUnicode_AsUTF8(PyObject_CallFunctionObjArgs(rl_instream->u.private_data,msg,prompt,NULL));
myrl_line = PyUnicode_AsUTF8(PyObject_CallFunctionObjArgs(
rl_instream->u.private_data, msg, prompt, NULL));
python_release_GIL(ctk);
rl_instream->u.irl.ptr = rl_instream->u.irl.buf = (const unsigned char*)myrl_line;
rl_instream->u.irl.ptr = rl_instream->u.irl.buf =
(const unsigned char *)myrl_line;
myrl_line = NULL;
return true;
}
static int py_getc(int sno) {
StreamDesc *s = YAP_RepStreamFromId(sno);
@ -117,7 +119,7 @@ static int py_getc(int sno) {
} else {
return EOF;
}
return ch;
return ch;
}
/**
@ -151,23 +153,22 @@ static int py_peek(int sno) {
return ch;
}
static int64_t py_seek(int sno, int64_t where, int how) {
StreamDesc *g0 = YAP_RepStreamFromId(sno);
term_t s0 = python_acquire_GIL();
term_t s0 = python_acquire_GIL();
PyObject *fseek = PyObject_GetAttrString(g0->u.private_data, "seek");
PyObject *pyr = PyObject_CallFunctionObjArgs(fseek, PyLong_FromLong(where),
PyLong_FromLong(how), NULL);
python_release_GIL(s0);
return PyLong_AsLong(pyr);
python_release_GIL(s0);
return PyLong_AsLong(pyr);
}
static void py_flush(int sno) {
StreamDesc *s = YAP_GetStreamFromId(sno);
term_t tg = python_acquire_GIL();
term_t tg = python_acquire_GIL();
PyObject *flush = PyObject_GetAttrString(s->u.private_data, "flush");
PyObject_CallFunction(flush, NULL);
python_release_GIL(tg);
python_release_GIL(tg);
}
#if 0

View File

@ -20,7 +20,6 @@
% ]
%% ).
:- [library(hacks)].
:- reexport(library(yapi)).
:- use_module(library(lists)).
:- use_module(library(maplist)).
@ -274,4 +273,21 @@ close_events( Self ) :-
fail.
close_events( _ ).
:- if( current_prolog_flag(apple, true) ).
:- putenv( 'LC_ALL', 'en_us:UTF-8').
plot_inline :-
X := self.inline_plotting,
nb_setval(inline, X ),
X = true,
!,
:= (
import( matplotlib ),
matplotlib.use( `nbagg` )
).
:- endif.
%:- ( start_low_level_trace ).