From 8f72db3b56d43c90ff6a7deb24ea749bc083e36c Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Wed, 19 Oct 2016 22:38:17 -0500 Subject: [PATCH] fixes --- C/c_interface.c | 14 +- C/init.c | 2 + C/text.c | 138 +++++++----- CXX/yapi.cpp | 2 + CXX/yapq.hh | 4 +- H/LOCALS | 2 + H/Yap.h | 2 + H/YapText.h | 1 + H/generated/dlocals.h | 2 + H/generated/hlocals.h | 1 + H/generated/ilocals.h | 1 + H/generated/rlocals.h | 1 + include/YapDefs.h | 2 + library/dialect/swi/fli/swi.c | 4 +- os/iopreds.c | 2 +- os/readline.c | 3 + os/sig.c | 3 + packages/python/py2pl.c | 4 +- packages/python/pypreds.c | 399 ++++++++++++++++++++++++---------- packages/python/python.c | 2 + packages/python/python.pl | 2 + 21 files changed, 414 insertions(+), 177 deletions(-) diff --git a/C/c_interface.c b/C/c_interface.c index bacc297ce..833b35905 100755 --- a/C/c_interface.c +++ b/C/c_interface.c @@ -2260,6 +2260,9 @@ static void start_modules(void) { CurrentModule = cm; } +/// whether Yap is under control of some other system +bool Yap_embedded; + /* this routine is supposed to be called from an external program that wants to control Yap */ @@ -2268,7 +2271,6 @@ YAP_file_type_t YAP_Init(YAP_init_args *yap_init) { bool do_bootstrap = (restore_result & YAP_CONSULT_MODE); CELL Trail = 0, Stack = 0, Heap = 0, Atts = 0; char boot_file[YAP_FILENAME_MAX + 1]; - Int rc; const char *yroot; @@ -2277,6 +2279,7 @@ YAP_file_type_t YAP_Init(YAP_init_args *yap_init) { return YAP_FOUND_BOOT_ERROR; initialized = true; + Yap_embedded = yap_init->Embedded; Yap_page_size = Yap_InitPageSize(); /* init memory page size, required by later functions */ #if defined(YAPOR_COPY) || defined(YAPOR_COW) || defined(YAPOR_SBA) @@ -2285,7 +2288,7 @@ YAP_file_type_t YAP_Init(YAP_init_args *yap_init) { GLOBAL_PrologShouldHandleInterrupts = yap_init->PrologShouldHandleInterrupts; Yap_InitSysbits(0); /* init signal handling and time, required by later functions */ - GLOBAL_argv = yap_init->Argv; + GLOBAL_argv = yap_init->Argv; GLOBAL_argc = yap_init->Argc; if (0 && ((YAP_QLY && yap_init->SavedState) || (YAP_BOOT_PL && (yap_init->YapPrologBootFile)))) { @@ -2346,9 +2349,10 @@ YAP_file_type_t YAP_Init(YAP_init_args *yap_init) { // CACHE_REGS - if (yap_init->QuietMode) { - setVerbosity(TermSilent); - } + if (Yap_embedded) + if (yap_init->QuietMode) { + setVerbosity(TermSilent); + } { if (yap_init->YapPrologRCFile != NULL) { /* diff --git a/C/init.c b/C/init.c index 49bac3efa..c15664cce 100755 --- a/C/init.c +++ b/C/init.c @@ -98,6 +98,8 @@ int Yap_Portray_delays = FALSE; #endif #endif +void *YAP_save; + /** @defgroup Operators Summary of YAP Predefined Operators diff --git a/C/text.c b/C/text.c index dce99663f..08e523b03 100644 --- a/C/text.c +++ b/C/text.c @@ -35,46 +35,77 @@ inline static size_t min_size(size_t i, size_t j) { return (i < j ? i : j); } #define NAN (0.0 / 0.0) #endif -void *buf__, *cur__; +#define MAX_PATHNAME 2048 -#define init_alloc(I) \ - void *ov__ = TR, *ocur__ = LOCAL_ScannerStack; \ - if (!LOCAL_ScannerStack) \ - LOCAL_ScannerStack = (char *)TR -#define mark_stack() \ - void *otr__ = TR; \ - void *ost__ = LOCAL_ScannerStack; \ - TR = (tr_fr_ptr)LOCAL_ScannerStack +typedef struct TextBuffer_manager { + void *buf, *ptr; + size_t sz; + struct TextBuffer_manager *prev; + int lvl; +} text_buffer_t; -#define restore_stack() \ - TR = otr__; \ - LOCAL_ScannerStack = ost__ +int lvl; -#define export_buf(s) \ - {} - -#define unprotect_stack(s) TR = ov__, LOCAL_ScannerStack = ocur__ -// LOCAL_ScannerStack = ov__, TR = ot__ - -static bool alloc_ovfl(size_t sz) { - return (char *)+(sz + 4096) > (char *)LOCAL_TrailTop; +/** + * TextBuffer is allocated as a chain of blocks, They area + * recovered at the end if the translation. + */ +INLINE_ONLY inline int init_alloc(int line) { + // printf("l=%d\n",lvl); + if (lvl ) + return; + while (LOCAL_TextBuffer->prev ) { + struct TextBuffer_manager *old = LOCAL_TextBuffer; + LOCAL_TextBuffer = LOCAL_TextBuffer->prev; + free(old); + } + LOCAL_TextBuffer->sz = (YAP_FILENAME_MAX + 1); + LOCAL_TextBuffer->buf = LOCAL_TextBuffer->ptr = (void *)(LOCAL_TextBuffer + 1 ); + return lvl++; } + +INLINE_ONLY inline int mark_stack(void) { +return lvl; } + +INLINE_ONLY inline void restore_stack(int i ) {lvl = i;} \ +INLINE_ONLY inline void unprotect_stack(int i) { +lvl = i;} static void *Malloc(size_t sz USES_REGS) { sz = ALIGN_BY_TYPE(sz, CELL); - if (alloc_ovfl(sz)) - return NULL; - void *o = LOCAL_ScannerStack; - LOCAL_ScannerStack = (void *)((char *)LOCAL_ScannerStack + sz); - return o; + void *o = LOCAL_TextBuffer->ptr; + if ((char*)LOCAL_TextBuffer->ptr+sz>(char*)LOCAL_TextBuffer->buf + LOCAL_TextBuffer->sz) { + size_t nsz = max(sz*4/3,YAP_FILENAME_MAX + 1); + struct TextBuffer_manager *new = malloc(sizeof(struct TextBuffer_manager)+nsz); + new->prev = LOCAL_TextBuffer; + new->buf = (struct TextBuffer_manager *)new+1; + new->ptr = new->buf + sz; + new->sz = nsz; + LOCAL_TextBuffer= new; + return new->buf; + } + LOCAL_TextBuffer->ptr += sz; + return o; } + void *Yap_InitTextAllocator( void ) +{ + struct TextBuffer_manager *new = malloc(sizeof(struct TextBuffer_manager)\ + +MAX_PATHNAME*2 ); + new->prev = NULL; + new->ptr = new->buf = (struct TextBuffer_manager *)new+1; + new->sz = MAX_PATHNAME*2; + LOCAL_TextBuffer = new; + new->lvl = 0; + return new; +} + + + static size_t MaxTmp(USES_REGS1) { - if (LOCAL_ScannerStack) { - return (char *)LOCAL_TrailTop - (char *)LOCAL_ScannerStack; - } - return 0; + + return ((char*)LOCAL_TextBuffer->buf + LOCAL_TextBuffer->sz) - (char*)LOCAL_TextBuffer->ptr; } static Term Globalize(Term v USES_REGS) { @@ -682,18 +713,18 @@ static size_t write_length(const unsigned char *s0, seq_tv_t *out, static Term write_number(unsigned char *s, seq_tv_t *out, int size USES_REGS) { Term t; - mark_stack(); + int i = mark_stack(); t = Yap_StringToNumberTerm((char *)s, &out->enc); - restore_stack(); + restore_stack(i); return t; } static Term string_to_term(void *s, seq_tv_t *out, size_t leng USES_REGS) { Term o; - mark_stack(); + int i = mark_stack(); o = out->val.t = Yap_StringToTerm(s, strlen(s) + 1, &out->enc, GLOBAL_MaxPriority, NULL); - restore_stack(); + restore_stack(i); return o; } @@ -794,7 +825,7 @@ bool Yap_CVT_Text(seq_tv_t *inp, seq_tv_t *out USES_REGS) { bool rc; size_t leng; - init_alloc(__LINE__); + int l = init_alloc(__LINE__); /* f//printf(stderr, "[ %d ", n++) ; if (inp->type & (YAP_STRING_TERM|YAP_STRING_ATOM|YAP_STRING_ATOMS_CODES @@ -819,26 +850,26 @@ bool Yap_CVT_Text(seq_tv_t *inp, seq_tv_t *out USES_REGS) { } if (!buf) { - unprotect_stack(NULL); + unprotect_stack(0); return 0L; } if (out->type & (YAP_STRING_UPCASE | YAP_STRING_DOWNCASE)) { if (out->type & YAP_STRING_UPCASE) { if (!upcase(buf, out)) { - unprotect_stack(NULL); + unprotect_stack(0); return false; } } if (out->type & YAP_STRING_DOWNCASE) { if (!downcase(buf, out)) { - unprotect_stack(NULL); + unprotect_stack(0); return false; } } } rc = write_Text(buf, out, leng PASS_REGS); - unprotect_stack(out); + unprotect_stack(l); /* fprintf(stderr, " -> "); if (!rc) fprintf(stderr, "NULL"); else if (out->type & @@ -908,10 +939,10 @@ bool Yap_Concat_Text(int tot, seq_tv_t inp[], seq_tv_t *out USES_REGS) { unsigned char *buf; size_t leng; int i; - init_alloc(__LINE__); + int l = init_alloc(__LINE__); bufv = Malloc(tot * sizeof(unsigned char *)); if (!bufv) { - unprotect_stack(NULL); + unprotect_stack(0); return NULL; } for (i = 0; i < tot; i++) { @@ -919,14 +950,14 @@ bool Yap_Concat_Text(int tot, seq_tv_t inp[], seq_tv_t *out USES_REGS) { unsigned char *nbuf = Yap_readText(inp + i, &leng PASS_REGS); if (!nbuf) { - unprotect_stack(NULL); + unprotect_stack(0); return NULL; } bufv[i] = nbuf; } buf = concat(tot, bufv PASS_REGS); bool rc = write_Text(buf, out, leng PASS_REGS); - unprotect_stack(out); + unprotect_stack(l); return rc; } @@ -934,12 +965,11 @@ bool Yap_Concat_Text(int tot, seq_tv_t inp[], seq_tv_t *out USES_REGS) { bool Yap_Splice_Text(int n, size_t cuts[], seq_tv_t *inp, seq_tv_t outv[] USES_REGS) { unsigned char *buf; - size_t l; - init_alloc(__LINE__); + int l = init_alloc(__LINE__); inp->type |= YAP_STRING_IN_TMP; buf = Yap_readText(inp, &l PASS_REGS); if (!buf) { - unprotect_stack(NULL); + unprotect_stack(0); return false; } @@ -951,11 +981,11 @@ bool Yap_Splice_Text(int n, size_t cuts[], seq_tv_t *inp, if (outv[0].val.t) { buf0 = Yap_readText(outv, &l0 PASS_REGS); if (!buf0) { - unprotect_stack(NULL); + unprotect_stack(0); return false; } if (cmp_Text(buf, buf0, l0) != 0) { - unprotect_stack(NULL); + unprotect_stack(0); return false; } l1 = l - l0; @@ -963,26 +993,26 @@ bool Yap_Splice_Text(int n, size_t cuts[], seq_tv_t *inp, buf1 = slice(l0, l, buf PASS_REGS); bool rc = write_Text(buf1, outv + 1, l1 PASS_REGS); if (!rc) { - unprotect_stack(NULL); + unprotect_stack(0); return false; } - unprotect_stack((outv + 1)); + unprotect_stack(l); return rc; } else /* if (outv[1].val.t) */ { buf1 = Yap_readText(outv + 1, &l1 PASS_REGS); if (!buf1) { - unprotect_stack(NULL); + unprotect_stack(0); return false; } l0 = l - l1; if (cmp_Text(skip_utf8((const unsigned char *)buf, l0), buf1, l1) != 0) { - unprotect_stack(NULL); + unprotect_stack(0); return false; } buf0 = slice(0, l0, buf PASS_REGS); bool rc = write_Text(buf0, outv, l0 PASS_REGS); - unprotect_stack((rc ? NULL : outv + 0)); + unprotect_stack((rc ? 0 : l + 0)); return rc; } } @@ -995,11 +1025,11 @@ bool Yap_Splice_Text(int n, size_t cuts[], seq_tv_t *inp, next = cuts[i - 1]; void *bufi = slice(next, cuts[i], buf PASS_REGS); if (!write_Text(bufi, outv + i, cuts[i] - next PASS_REGS)) { - unprotect_stack(NULL); + unprotect_stack(0); return false; } } - unprotect_stack(outv); + unprotect_stack(l); return true; } diff --git a/CXX/yapi.cpp b/CXX/yapi.cpp index 96ad0815f..5b0ed2072 100644 --- a/CXX/yapi.cpp +++ b/CXX/yapi.cpp @@ -872,6 +872,7 @@ YAPEngine::YAPEngine(char *savedState, char *bootFile, size_t stackSize, size_t trailSize, size_t maxStackSize, size_t maxTrailSize, char *libDir, char *goal, char *topLevel, bool script, bool fastBoot, + bool embedded, YAPCallback *cb) : _callback(0) { // a single engine can be active @@ -904,6 +905,7 @@ YAPEngine::YAPEngine(char *savedState, char *bootFile, size_t stackSize, init_args.YapPrologTopLevelGoal = topLevel; init_args.HaltAfterConsult = script; init_args.FastBoot = fastBoot; + init_args.Embedded = embedded; doInit(BootMode); } diff --git a/CXX/yapq.hh b/CXX/yapq.hh index 3304e82c5..fc9ee6fed 100644 --- a/CXX/yapq.hh +++ b/CXX/yapq.hh @@ -145,6 +145,7 @@ public: size_t maxTrailSize = 0, char *libDir = (char *)NULL, char *goal = (char *)NULL, char *topLevel = (char *)NULL, bool script = FALSE, bool fastBoot = FALSE, + bool embedded = true, YAPCallback *callback = (YAPCallback *) NULL); /// construct a new engine, including aaccess to callbacks /// construct a new engine using argc/argv list of arguments @@ -183,9 +184,6 @@ public: bool goalt(YAPTerm t); /// current directory for the engine bool goal(Term t); -#if SWIGPYTHON - bool unlockedGoal(Term t) {bool rc;Py_BEGIN_ALLOW_THREADS; rc = goal(t);Py_END_ALLOW_THREADS; return rc; } -#endif /// reset Prolog state void reSet(); /// release: assune that there are no stack pointers, just release memory diff --git a/H/LOCALS b/H/LOCALS index 7a4af0fdf..f4ced4a9e 100755 --- a/H/LOCALS +++ b/H/LOCALS @@ -217,6 +217,8 @@ sigjmp_buf RestartEnv void char FileNameBuf[YAP_FILENAME_MAX+1] void char FileNameBuf2[YAP_FILENAME_MAX+1] void +struct TextBuffer_manager* TextBuffer =Yap_InitTextAllocator() + // Prolog State UInt BreakLevel =0 Int PrologMode =BootMode diff --git a/H/Yap.h b/H/Yap.h index b612399ac..442ed9603 100755 --- a/H/Yap.h +++ b/H/Yap.h @@ -850,4 +850,6 @@ inline static void LOG0(const char *f, int l, const char *fmt, ...) { #include "GitSHA1.h" +extern bool Yap_embedded, Yap_Server; + #endif /* YAP_H */ diff --git a/H/YapText.h b/H/YapText.h index 7c8d2140f..436e0690e 100644 --- a/H/YapText.h +++ b/H/YapText.h @@ -31,6 +31,7 @@ #include "../utf8proc/utf8proc.h" #include "Yap.h" + /* Character types for tokenizer and write.c */ /****************** character definition table **************************/ diff --git a/H/generated/dlocals.h b/H/generated/dlocals.h index 9f9ac0a5d..50ec4e7a1 100644 --- a/H/generated/dlocals.h +++ b/H/generated/dlocals.h @@ -326,6 +326,8 @@ #define REMOTE_FileNameBuf(wid) REMOTE(wid)->FileNameBuf_ #define LOCAL_FileNameBuf2 LOCAL->FileNameBuf2_ #define REMOTE_FileNameBuf2(wid) REMOTE(wid)->FileNameBuf2_ +#define LOCAL_TextBuffer LOCAL->TextBuffer_ +#define REMOTE_TextBuffer(wid) REMOTE(wid)->TextBuffer_ #define LOCAL_BreakLevel LOCAL->BreakLevel_ #define REMOTE_BreakLevel(wid) REMOTE(wid)->BreakLevel_ diff --git a/H/generated/hlocals.h b/H/generated/hlocals.h index 9e0474a25..0dbbdc4e0 100644 --- a/H/generated/hlocals.h +++ b/H/generated/hlocals.h @@ -184,6 +184,7 @@ typedef struct worker_local { sigjmp_buf RestartEnv_; char FileNameBuf_[YAP_FILENAME_MAX+1]; char FileNameBuf2_[YAP_FILENAME_MAX+1]; + struct TextBuffer_manager* TextBuffer_; // Prolog State UInt BreakLevel_; Int PrologMode_; diff --git a/H/generated/ilocals.h b/H/generated/ilocals.h index 8dcf95218..b290c118d 100755 --- a/H/generated/ilocals.h +++ b/H/generated/ilocals.h @@ -184,6 +184,7 @@ static void InitWorker(int wid) { + REMOTE_TextBuffer(wid) = Yap_InitTextAllocator(); REMOTE_BreakLevel(wid) = 0; REMOTE_PrologMode(wid) = BootMode; diff --git a/H/generated/rlocals.h b/H/generated/rlocals.h index cbdfa2b80..d376d9bde 100644 --- a/H/generated/rlocals.h +++ b/H/generated/rlocals.h @@ -191,6 +191,7 @@ static void RestoreWorker(int wid USES_REGS) { + #ifdef ANALYST diff --git a/include/YapDefs.h b/include/YapDefs.h index de41bbe05..ce863ace5 100755 --- a/include/YapDefs.h +++ b/include/YapDefs.h @@ -284,6 +284,8 @@ typedef struct yap_boot_params { int Argc; /* array of arguments as seen by Prolog */ char **Argv; + /* embedded in some other system: no signals, readline, etc */ + bool Embedded; /* QuietMode */ int QuietMode; diff --git a/library/dialect/swi/fli/swi.c b/library/dialect/swi/fli/swi.c index 5dda192de..1854a1ee0 100755 --- a/library/dialect/swi/fli/swi.c +++ b/library/dialect/swi/fli/swi.c @@ -892,9 +892,9 @@ X_API atom_t PL_new_atom(const char *c) { Atom at; atom_t sat; - while ((at = Yap_CharsToAtom(c, ENC_ISO_LATIN1 PASS_REGS)) == 0L) { + while ((at = Yap_LookupAtom(c)) == 0L) { if (LOCAL_Error_TYPE && !Yap_SWIHandleError("PL_new_atom")) - return FALSE; + return false; } Yap_AtomIncreaseHold(at); sat = AtomToSWIAtom(at); diff --git a/os/iopreds.c b/os/iopreds.c index 09d0473b4..3f4ab88a2 100644 --- a/os/iopreds.c +++ b/os/iopreds.c @@ -1870,7 +1870,7 @@ void Yap_InitIOPreds(void) { Yap_InitReadTPreds(); Yap_InitFormat(); Yap_InitRandomPreds(); -#if USE_READLINE + #if USE_READLINE Yap_InitReadlinePreds(); #endif Yap_InitSockets(); diff --git a/os/readline.c b/os/readline.c index 7565e5608..5f2aa2f90 100644 --- a/os/readline.c +++ b/os/readline.c @@ -450,7 +450,10 @@ int Yap_ReadlineForSIGINT(void) { static Int has_readline(USES_REGS1) { #if USE_READLINE + if (!Yap_embedded) { return true; + } + return false; #else return false; #endif diff --git a/os/sig.c b/os/sig.c index 9c63cf009..513b40e9a 100644 --- a/os/sig.c +++ b/os/sig.c @@ -834,6 +834,9 @@ static Int fpe_error(USES_REGS1) { /* SIGINT can cause problems, if caught before full initialization */ void Yap_InitOSSignals(int wid) { + if (Yap_embedded) { + return; + } if (GLOBAL_PrologShouldHandleInterrupts) { #if !defined(LIGHT) && !_MSC_VER && !defined(__MINGW32__) && !defined(LIGHT) my_signal(SIGQUIT, ReceiveSignal); diff --git a/packages/python/py2pl.c b/packages/python/py2pl.c index 691b16a3e..4b8c3078f 100644 --- a/packages/python/py2pl.c +++ b/packages/python/py2pl.c @@ -185,9 +185,9 @@ foreign_t python_to_term(PyObject *pVal, term_t t) { Py_ssize_t i, sz = PyTuple_Size(pVal); functor_t f; const char *s; - if ((s = (Py_TYPE(pVal)->tp_name))) + if ((s = (Py_TYPE(pVal)->tp_name))) { f = PL_new_functor(PL_new_atom(s), sz); - else + } else f = PL_new_functor(ATOM_t, sz); if (!PL_unify_functor(t, f)) return FALSE; diff --git a/packages/python/pypreds.c b/packages/python/pypreds.c index ea63443bb..b778400e4 100644 --- a/packages/python/pypreds.c +++ b/packages/python/pypreds.c @@ -28,7 +28,7 @@ static foreign_t python_f(term_t tmod, term_t fname, term_t tf) { char *s; size_t len; PyObject *pF, *pModule; - + /* if an atom, fetch again */ if (PL_is_atom(tmod)) { PyObject *pName; @@ -42,40 +42,59 @@ static foreign_t python_f(term_t tmod, term_t fname, term_t tf) { pName = PyUnicode_FromString(s); #endif if (pName == NULL) { - return FALSE; + { + return false; + } } pModule = PyImport_Import(pName); PyErr_Clear(); } else if (!(pModule = term_to_python(tmod, true))) { PyErr_Clear(); - return FALSE; + { + return false; + } } if (!PL_get_nchars(fname, &len, &s, CVT_ALL | CVT_EXCEPTION)) { - return FALSE; + { + return false; + } } pF = PyObject_GetAttrString(pModule, s); PyErr_Print(); Py_DECREF(pModule); if (pF == NULL || !PyCallable_Check(pF)) { - return FALSE; + { + return false; + } + } + { + foreign_t rc = python_to_ptr(pF, tf); + return rc; } - return python_to_ptr(pF, tf); } static foreign_t python_o(term_t tmod, term_t fname, term_t tf) { char *s; size_t len; PyObject *pO, *pModule; - + pModule = term_to_python(tmod, true); if (!PL_get_nchars(fname, &len, &s, CVT_ALL | CVT_EXCEPTION)) { - return FALSE; + { + return false; + } } pO = PyObject_GetAttrString(pModule, s); if (pO == NULL) { - return FALSE; + { + return false; + } + } + { + foreign_t rc = python_to_ptr(pO, tf); + ; + return rc; } - return python_to_ptr(pO, tf); } static foreign_t python_len(term_t tobj, term_t tf) { @@ -83,8 +102,9 @@ static foreign_t python_len(term_t tobj, term_t tf) { PyObject *o; o = term_to_python(tobj, true); - if (o == NULL) - return FALSE; + if (o == NULL) { + return false; + } len = PyObject_Length(o); return PL_unify_int64(tf, len); } @@ -94,40 +114,54 @@ static foreign_t python_dir(term_t tobj, term_t tf) { PyObject *o; o = term_to_python(tobj, true); - if (o == NULL) - return FALSE; + if (o == NULL) { + return false; + } dir = PyObject_Dir(o); - return python_to_ptr(dir, tf); + { + foreign_t rc = python_to_ptr(dir, tf); + ; + return rc; + } } static foreign_t python_index(term_t tobj, term_t tindex, term_t val) { PyObject *i; PyObject *o; PyObject *f; + o = term_to_python(tobj, true); - if (o == NULL) - return false; - if (!PySequence_Check(o)) + if (o == NULL) { return false; + } + if (!PySequence_Check(o)) { + return false; + } i = term_to_python(tindex, true); - if (i == NULL) + if (i == NULL) { return false; + } #if PY_MAJOR_VERSION < 3 f = PyObject_CallMethodObjArgs(o, PyString_FromString("getitem"), i); #else f = PyObject_CallMethodObjArgs(o, PyUnicode_FromString("getitem"), i); #endif - return python_to_ptr(f, val); + { + foreign_t rc = python_to_ptr(f, val); + ; + return rc; + } } static foreign_t python_is(term_t tobj, term_t tf) { PyObject *o; o = term_to_python(tobj, true); - if (!o) - return FALSE; - - return python_to_ptr(o, tf); + if (!o) { + return false; + } + foreign_t rc = python_to_ptr(o, tf); + return rc; } static foreign_t python_assign_item(term_t parent, term_t indx, term_t tobj) { @@ -145,23 +179,31 @@ static foreign_t python_assign_item(term_t parent, term_t indx, term_t tobj) { pF = term_to_python(parent, true); // Exp if (!pI || !p) { - return false; + { + return false; + } } else if (PyObject_SetItem(p, pI, pF)) { PyErr_Print(); - return FALSE; + { + return false; + } } Py_DecRef(pI); Py_DecRef(p); - return true; + { + return true; + } } /** assign a tuple to something: */ static foreign_t python_assign_tuple(term_t t_lhs, term_t t_rhs) { - PyObject *e = term_to_python(t_rhs, true); + PyObject *e; Py_ssize_t sz; functor_t f; + + e = term_to_python(t_rhs, true); if (!e || !PyTuple_Check(e)) { return -1; } @@ -224,12 +266,18 @@ static foreign_t python_item(term_t parent, term_t indx, term_t tobj) { return false; } else if ((pF = PyObject_GetItem(p, pI)) == NULL) { PyErr_Print(); - return FALSE; + { + return false; + } } Py_DecRef(pI); Py_DecRef(p); - return address_to_term(pF, tobj); + { + foreign_t rc; + rc = address_to_term(pF, tobj); + return rc; + } } static foreign_t python_slice(term_t parent, term_t indx, term_t tobj) { @@ -244,15 +292,23 @@ static foreign_t python_slice(term_t parent, term_t indx, term_t tobj) { p = term_to_python(parent, true); // Exp if (!pI || !p) { - return false; + { + return false; + } } else if ((pF = PySequence_GetSlice(p, 0, 0)) == NULL) { PyErr_Print(); - return FALSE; + { + return false; + } } Py_DecRef(pI); Py_DecRef(p); - return address_to_term(pF, tobj); + { + foreign_t rc; + rc = address_to_term(pF, tobj); + return rc; + } } static foreign_t python_apply(term_t tin, term_t targs, term_t keywds, @@ -268,14 +324,18 @@ static foreign_t python_apply(term_t tin, term_t targs, term_t keywds, pF = term_to_python(tin, true); PyErr_Clear(); if (pF == NULL) { - return false; + { + return false; + } } if (PL_is_atom(targs)) { pArgs = NULL; } else { if (!PL_get_name_arity(targs, &aname, &arity)) { - return FALSE; + { + return false; + } } if (arity == 1 && PL_get_arg(1, targs, targ) && PL_is_variable(targ)) { /* ignore (_) */ @@ -283,15 +343,18 @@ static foreign_t python_apply(term_t tin, term_t targs, term_t keywds, } else { pArgs = PyTuple_New(arity); - if (!pArgs) - return FALSE; + if (!pArgs) { + return false; + } for (i = 0; i < arity; i++) { PyObject *pArg; - if (!PL_get_arg(i + 1, targs, targ)) - return FALSE; + if (!PL_get_arg(i + 1, targs, targ)) { + return false; + } pArg = term_to_python(targ, true); - if (pArg == NULL) - return FALSE; + if (pArg == NULL) { + return false; + } /* pArg reference stolen here: */ PyTuple_SetItem(pArgs, i, pArg); } @@ -319,13 +382,16 @@ static foreign_t python_apply(term_t tin, term_t targs, term_t keywds, } } else { PyErr_Print(); - return FALSE; + { + return false; + } } if (pArgs) Py_DECREF(pArgs); Py_DECREF(pF); - if (pValue == NULL) - return FALSE; + if (pValue == NULL) { + return false; + } out = python_to_ptr(pValue, tf); return out; } @@ -333,21 +399,23 @@ static foreign_t python_apply(term_t tin, term_t targs, term_t keywds, static foreign_t python_assign(term_t name, term_t exp) { PyObject *e = term_to_python(exp, true); - if (e == NULL) - return FALSE; + if (e == NULL) { + return false; + } return assign_python(py_Main, name, e) >= 0; } static foreign_t python_assign_field(term_t source, term_t name, term_t exp) { PyObject *e = term_to_python(exp, true), *root = term_to_python(source, true); - if (e == NULL) - return FALSE; + if (e == NULL) { + return false; + } return assign_python(root, name, e) >= 0; } static foreign_t python_builtin_eval(term_t caller, term_t dict, term_t out) { - PyObject *pI, *pArgs, *pOut; + PyObject *pI, *pArgs, *pOut; PyObject *env; atom_t name; char *s; @@ -356,36 +424,47 @@ static foreign_t python_builtin_eval(term_t caller, term_t dict, term_t out) { if ((env = py_Builtin) == NULL) { // no point in even trying - return false; + { + return false; + } } if (PL_get_name_arity(caller, &name, &arity)) { - if (!(s = PL_atom_chars(name))) + if (!(s = PL_atom_chars(name))) { return false; + } if ((pI = PyObject_GetAttrString(env, s)) == NULL) { PyErr_Print(); - return false; + { + return false; + } } } else { // Prolog should make sure this never happens. - return false; + { + return false; + } } pArgs = PyTuple_New(arity); for (i = 0; i < arity; i++) { PyObject *pArg; - if (!PL_get_arg(i + 1, caller, targ)) - return FALSE; + if (!PL_get_arg(i + 1, caller, targ)) { + return false; + } /* ignore (_) */ if (i == 0 && PL_is_variable(targ)) { pArg = Py_None; } else { pArg = term_to_python(targ, true); - if (pArg == NULL) - return FALSE; + if (pArg == NULL) { + return false; + } } /* pArg reference stolen here: */ if (PyTuple_SetItem(pArgs, i, pArg)) { PyErr_Print(); - return false; + { + return false; + } } } pOut = PyObject_CallObject(pI, pArgs); @@ -393,9 +472,15 @@ static foreign_t python_builtin_eval(term_t caller, term_t dict, term_t out) { Py_DECREF(pI); if (pOut == NULL) { PyErr_Print(); - return false; + { + return false; + } + } + { + foreign_t rc = python_to_ptr(pOut, out); + ; + return rc; } - return python_to_ptr(pOut, out); } static foreign_t python_access(term_t obj, term_t f, term_t out) { @@ -405,57 +490,76 @@ static foreign_t python_access(term_t obj, term_t f, term_t out) { int i, arity; term_t targ = PL_new_term_ref(); - if (o == NULL) - return FALSE; + if (o == NULL) { + return false; + } if (PL_is_atom(f)) { - if (!PL_get_atom_chars(f, &s)) - return FALSE; + if (!PL_get_atom_chars(f, &s)) { + return false; + } if ((pValue = PyObject_GetAttrString(o, s)) == NULL) { PyErr_Print(); - return FALSE; + { + return false; + } + } + { + return python_to_term(pValue, out); } - return python_to_term(pValue, out); } if (!PL_get_name_arity(f, &name, &arity)) { - return FALSE; + { + return false; + } } /* follow chains of the form a.b.c.d.e() */ while (name == ATOM_dot && arity == 2) { term_t tleft = PL_new_term_ref(); PyObject *lhs; - if (!PL_get_arg(1, f, tleft)) - return FALSE; + if (!PL_get_arg(1, f, tleft)) { + return false; + } lhs = term_to_python(tleft, true); if ((o = PyObject_GetAttr(o, lhs)) == NULL) { PyErr_Print(); - return FALSE; + { + return false; + } + } + if (!PL_get_arg(2, f, f)) { + return false; } - if (!PL_get_arg(2, f, f)) - return FALSE; if (!PL_get_name_arity(f, &name, &arity)) { - return FALSE; + { + return false; + } } } s = PL_atom_chars(name); - if (!s) + if (!s) { return false; + } if ((pF = PyObject_GetAttrString(o, s)) == NULL) { PyErr_Print(); - return FALSE; + { + return false; + } } pArgs = PyTuple_New(arity); for (i = 0; i < arity; i++) { PyObject *pArg; - if (!PL_get_arg(i + 1, f, targ)) - return FALSE; + if (!PL_get_arg(i + 1, f, targ)) { + return false; + } /* ignore (_) */ if (i == 0 && PL_is_variable(targ)) { pArgs = Py_None; } pArg = term_to_python(targ, true); - if (pArg == NULL) - return FALSE; + if (pArg == NULL) { + return false; + } /* pArg reference stolen here: */ PyTuple_SetItem(pArgs, i, pArg); } @@ -463,9 +567,13 @@ static foreign_t python_access(term_t obj, term_t f, term_t out) { Py_DECREF(pArgs); Py_DECREF(pF); if (pValue == NULL) { - return FALSE; + { + return false; + } + } + { + return python_to_term(pValue, out); } - return python_to_term(pValue, out); } static foreign_t python_field(term_t parent, term_t att, term_t tobj) { @@ -475,7 +583,9 @@ static foreign_t python_field(term_t parent, term_t att, term_t tobj) { int arity; if (!PL_get_name_arity(att, &name, &arity)) { - return false; + { + return false; + } } else { PyObject *p; @@ -484,39 +594,61 @@ static foreign_t python_field(term_t parent, term_t att, term_t tobj) { p = term_to_python(parent, true); // Exp if (!PL_get_name_arity(att, &name, &arity)) { - return false; + { + return false; + } } s = PL_atom_chars(name); if (arity == 1 && !strcmp(s, "()")) { - if (!PL_get_arg(1, att, att)) + if (!PL_get_arg(1, att, att)) { return false; + } if (!PL_get_name_arity(att, &name, &arity)) { - return false; + { + return false; + } } s = PL_atom_chars(name); } if (!s || !p) { - return false; + { + return false; + } } else if ((pF = PyObject_GetAttrString(p, s)) == NULL) { PyErr_Clear(); - return FALSE; + { + return false; + } } } - return address_to_term(pF, tobj); + { + foreign_t rc; + rc = address_to_term(pF, tobj); + return rc; + } } static foreign_t python_main_module(term_t mod) { - return address_to_term(py_Main, mod); + { + foreign_t rc; + rc = address_to_term(py_Main, mod); + return rc; + } } static foreign_t python_function(term_t tobj) { PyObject *obj = term_to_python(tobj, true); + foreign_t rc = PyFunction_Check(obj); - return PyFunction_Check(obj); + return rc; } foreign_t python_builtin(term_t out) { - return address_to_term(py_Builtin, out); + { + foreign_t rc; + rc = address_to_term(py_Builtin, out); + return rc; + } } static foreign_t python_run_file(term_t file) { @@ -530,24 +662,37 @@ static foreign_t python_run_file(term_t file) { PyRun_SimpleFileEx(PyFile_AsFile(PyFileObject), "test.py", 1); #else FILE *f = fopen(s, "r"); - if (f == NULL) + if (f == NULL) { return false; + } PyRun_SimpleFileEx(f, s, 1); #endif - return TRUE; + { + { + return true; + } + } + } + { + return false; } - return false; } +extern PyThreadState *YAP_save; + + static foreign_t python_run_command(term_t cmd) { char *s; + bool rc = false; size_t len; char si[256]; + s = si; if (PL_get_nchars(cmd, &len, &s, CVT_ALL | CVT_EXCEPTION)) { PyRun_SimpleString(s); + rc = true; } - return TRUE; + return rc; } static foreign_t python_run_script(term_t cmd, term_t fun) { @@ -587,7 +732,9 @@ static foreign_t python_run_script(term_t cmd, term_t fun) { Py_DECREF(pModule); PyErr_Print(); fprintf(stderr, "Call failed\n"); - return false; + { + return false; + } } } else { if (PyErr_Occurred()) @@ -598,11 +745,17 @@ static foreign_t python_run_script(term_t cmd, term_t fun) { Py_DECREF(pModule); } else { PyErr_Print(); - return false; + { + return false; + } + } + { + return true; } - return true; } - return false; + { + return false; + } } static foreign_t python_export(term_t t, term_t pl) { @@ -611,10 +764,12 @@ static foreign_t python_export(term_t t, term_t pl) { void *ptr; term_t targ = PL_new_term_ref(); - if (!PL_get_arg(1, t, targ)) + if (!PL_get_arg(1, t, targ)) { return false; - if (!PL_get_pointer(targ, &ptr)) + } + if (!PL_get_pointer(targ, &ptr)) { return false; + } Py_INCREF((PyObject *)ptr); /* return __main__,s */ rc = python_to_term((PyObject *)ptr, pl); @@ -622,9 +777,7 @@ static foreign_t python_export(term_t t, term_t pl) { return rc; } -static foreign_t p_python_within_python(void) { - return python_in_python; -} +static foreign_t p_python_within_python(void) { return python_in_python; } static int python_import(term_t mname, term_t mod) { PyObject *pName, *pModule; @@ -638,14 +791,17 @@ static int python_import(term_t mname, term_t mod) { if (PL_is_pair(mname)) { char *sa; if (!PL_get_arg(1, mname, arg) || !PL_get_atom_chars(arg, &sa) || - !PL_get_arg(2, mname, mname)) + !PL_get_arg(2, mname, mname)) { return false; + } s = stpcpy(s, sa); *s++ = '.'; s[0] = '\0'; } else if (!PL_get_nchars(mname, &len, &s, CVT_ALL | CVT_EXCEPTION | REP_UTF8)) { - return false; + { + return false; + } } else { break; } @@ -656,7 +812,9 @@ static int python_import(term_t mname, term_t mod) { pName = PyUnicode_FromString(s0); #endif if (pName == NULL) { - return false; + { + return false; + } } pModule = PyImport_Import(pName); PyErr_Clear(); @@ -667,12 +825,32 @@ static int python_import(term_t mname, term_t mod) { PyErr_Print(); PyErr_Clear(); #endif - return FALSE; + { + return false; + } } ActiveModules[active_modules++] = pModule; - return python_to_ptr(pModule, mod); + { foreign_t rc = python_to_ptr(pModule, mod); + return rc; + } } + static PyThreadState *_saveP; + +static YAP_Int + p_python_get_GIL(void) + { + PyEval_AcquireThread(_saveP); + return true; + } + +static YAP_Int + p_python_release_GIL(void) + { + _saveP = PyEval_SaveThread(); + return true; + } + install_t install_pypreds(void) { PL_register_foreign("python_builtin_eval", 3, python_builtin_eval, 0); PL_register_foreign("python_builtin", 1, python_builtin, 0); @@ -699,5 +877,6 @@ install_t install_pypreds(void) { PL_register_foreign("python_main_module", 1, python_main_module, 0); PL_register_foreign("python_import", 2, python_import, 0); PL_register_foreign("python_access", 3, python_access, 0); - PL_register_foreign("python_within_python", 0, p_python_within_python, 0); + PL_register_foreign("release_GIL", 0, p_python_release_GIL, 0); + PL_register_foreign("acquire_GIL", 0, p_python_get_GIL, 0); } diff --git a/packages/python/python.c b/packages/python/python.c index 53ec1b99c..cdc8efe86 100644 --- a/packages/python/python.c +++ b/packages/python/python.c @@ -93,6 +93,7 @@ X_API bool init_python(void) { // wait for YAP_Init return false; } + PyGILState_STATE gstate = PyGILState_Ensure(); term_t t = PL_new_term_ref(); if (!Py_IsInitialized()) { python_in_python = true; @@ -111,5 +112,6 @@ X_API bool init_python(void) { PL_reset_term_refs(t); install_pypreds(); install_pl2pl(); + PyGILState_Release(gstate); return !python_in_python; } diff --git a/packages/python/python.pl b/packages/python/python.pl index 997f0a194..42e266d09 100644 --- a/packages/python/python.pl +++ b/packages/python/python.pl @@ -27,6 +27,8 @@ array_to_python_tuple/4, array_to_python_view/5, python/2, + acquire_GIL/0, + release_GIL/0, (:=)/2, (:=)/1, % (<-)/2,