diff --git a/C/c_interface.c b/C/c_interface.c index ac7599127..ee86569f9 100755 --- a/C/c_interface.c +++ b/C/c_interface.c @@ -1738,6 +1738,8 @@ X_API bool YAP_EnterGoal(YAP_PredEntryPtr ape, CELL *ptr, YAP_dogoalinfo *dgi) { // slot=%d", pe, pe->CodeOfPred->opc, FAILCODE, Deref(ARG1), Deref(ARG2), // LOCAL_CurSlot); dgi->b = dgi->b0 = LCL0 - (CELL *)B; + dgi->h = HR-H0; + dgi->tr = (CELL*)TR-LCL0; fprintf(stderr,"PrepGoal: H=%d ENV=%p B=%d TR=%d P=%p CP=%p Slots=%d\n", HR-H0,LCL0-ENV,LCL0-(CELL*)B,(CELL*)TR-LCL0, P, CP, LOCAL_CurSlot); out = Yap_exec_absmi(true, false); diff --git a/C/exec.c b/C/exec.c index b3fb5a456..948e3e44f 100755 --- a/C/exec.c +++ b/C/exec.c @@ -1512,8 +1512,7 @@ static bool exec_absmi(bool top, yap_reset_t reset_mode USES_REGS) { /* set stack */ Yap_JumpToEnv(); Yap_CloseTemporaryStreams(); - Yap_CloseSlots(sls); - pop_text_stack(i); + Yap_CloseSlots(sls); ASP = (CELL *) PROTECT_FROZEN_B(B); if (B == NULL || B->cp_b == NULL || (CELL*)(B->cp_b) > LCL0 - LOCAL_CBorder) { @@ -2092,7 +2091,6 @@ static Int JumpToEnv(USES_REGS1) { handler->cp_ap = TRUSTFAILCODE; handler = handler->cp_b; } - pop_text_stack(1); if (LOCAL_PrologMode & AsyncIntMode) { Yap_signal(YAP_FAIL_SIGNAL); } diff --git a/CXX/yapi.cpp b/CXX/yapi.cpp index 06a285308..55394b6f8 100644 --- a/CXX/yapi.cpp +++ b/CXX/yapi.cpp @@ -477,7 +477,9 @@ const char *YAPAtom::getName(void) { return Yap_AtomToUTF8Text(a); } void YAPQuery::openQuery() { CACHE_REGS - if (ap == NULL || ap->OpcodeOfPred == UNDEF_OPCODE) { + lvl = AllocLevel(); + + if (ap == NULL || ap->OpcodeOfPred == UNDEF_OPCODE) { ap = rewriteUndefQuery(); } setNext(); @@ -492,13 +494,13 @@ bool YAPEngine::call(YAPPredicate ap, YAPTerm ts[]) { bool result; YAP_dogoalinfo q; - for (arity_t i = 0; i < arity; i++) - XREGS[i + 1] = ts[i].term(); - q.CurSlot = Yap_StartSlots(); q.p = P; q.cp = CP; + for (arity_t i = 0; i < arity; i++) + XREGS[i + 1] = ts[i].term(); + // allow Prolog style exceotion handling // don't forget, on success these bindings will still be there); result = YAP_LeaveGoal(true, &q); @@ -506,6 +508,7 @@ bool YAPEngine::call(YAPPredicate ap, YAPTerm ts[]) { YAPCatchError(); Yap_CloseHandles(q.CurSlot); + pop_text_stack(q.lvl+1); RECOVER_MACHINE_REGS(); return result; } @@ -519,6 +522,9 @@ bool YAPEngine::mgoal(Term t, Term tmod, bool release) { CACHE_REGS BACKUP_MACHINE_REGS(); Term *ts = nullptr; + q.CurSlot = Yap_StartSlots(); + q.p = P; + q.cp = CP; try { if (IsStringTerm(tmod)) tmod = MkAtomTerm(Yap_LookupAtom(StringOfTerm(tmod))); @@ -540,9 +546,6 @@ bool YAPEngine::mgoal(Term t, Term tmod, bool release) { } ts = nullptr; bool result; - 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 __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "exec "); @@ -1041,21 +1044,19 @@ std::stringstream s; void YAPEngine::reSet() { /* ignore flags for now */ BACKUP_MACHINE_REGS(); - Yap_RebootHandles(worker_id); - while (B && B->cp_b) - B = B->cp_b; - if (B) { - P = FAILCODE; - Yap_exec_absmi(true, YAP_EXEC_ABSMI); - /* recover stack space */ - HR = B->cp_h; - TR = B->cp_tr; -#ifdef DEPTH_LIMIT - DEPTH = B->cp_depth; -#endif /* DEPTH_LIMIT */ - YENV = ENV = B->cp_env; - } - RECOVER_MACHINE_REGS(); + + choiceptr b = (choiceptr)(LCL0-q.b); + if (b > B) B = b; + P = FAILCODE; + Yap_exec_absmi(true, YAP_EXEC_ABSMI); + /* recover stack space */ + LOCAL_ActiveError->errorNo = YAP_NO_ERROR; + if (H0+q.h < HR) + HR = H0+q.h; + if (LCL0+q.tr < (CELL*)TR) + TR = (tr_fr_ptr)(LCL0+q.tr); + Yap_CloseHandles( q.CurSlot ); +RECOVER_MACHINE_REGS(); } Term YAPEngine::top_level(std::string s) { diff --git a/CXX/yapq.hh b/CXX/yapq.hh index 62f944454..408985ba8 100644 --- a/CXX/yapq.hh +++ b/CXX/yapq.hh @@ -45,7 +45,8 @@ class X_API YAPQuery : public YAPPredicate { YAPPairTerm names; YAPTerm goal; // temporaries - YAPError *e; + int lvl; + YAPError *e; inline void setNext() { // oq = LOCAL_execution; // LOCAL_execution = this; @@ -291,7 +292,7 @@ private: YAPError yerror; void doInit(YAP_file_type_t BootMode, YAPEngineArgs *cargs); YAP_dogoalinfo q; - YAPError e; + YAPError e; PredEntry *rewriteUndefEngineQuery(PredEntry *ap, Term &t, Term tmod); public: @@ -338,7 +339,7 @@ public: /// current directory for the engine bool call(YAPPredicate ap, YAPTerm ts[]); /// current directory for the engine - bool goal(YAPTerm Yt, YAPModule module) { return mgoal(Yt.term(),module.term()); }; + bool goal(YAPTerm Yt, YAPModule module, bool release=false) { return mgoal(Yt.term(),module.term(), release); }; /// ru1n a goal in a module. /// /// By default, memory will only be fully diff --git a/H/YapText.h b/H/YapText.h index 02c517f3a..c11b39f79 100644 --- a/H/YapText.h +++ b/H/YapText.h @@ -52,20 +52,20 @@ extern const void *MallocExportAsRO(const void *blk); extern int AllocLevel(void); #define push_text_stack() \ - (/* fprintf(stderr, "^ %*c %s:%s:%d\n", AllocLevel(), AllocLevel()+'0', \ - __FILE__, __FUNCTION__, __LINE__), */ \ + (/* fprintf(stderr, " + *** %d %s:%s:%d\n", AllocLevel(),*/ \ + /* __FILE__, __FUNCTION__, __LINE__), */ \ push_text_stack__(PASS_REGS1)) extern int push_text_stack__(USES_REGS1); #define pop_text_stack(lvl) \ - (/*fprintf(stderr, "v %*c %s:%s:%d\n", AllocLevel(), ' ', __FILE__, \ - __FUNCTION__, __LINE__),*/ \ + (/* fprintf(stderr, " - *** %d %s:%s:%d\n", AllocLevel(), __FILE__,*/ \ + /* __FUNCTION__, __LINE__), */ \ pop_text_stack__(lvl)) extern int pop_text_stack__(int lvl USES_REGS); #define pop_output_text_stack(lvl,p) \ - (/*fprintf(stderr, "v %*c %s:%s:%d\n", AllocLevel(), ' ', __FILE__, \ - __FUNCTION__, __LINE__),*/ \ + (/*fprintf(stderr, "-- *** %d %s:%s:%d\n", AllocLevel(), __FILE__,*/ \ + /* __FUNCTION__, __LINE__),*/ \ pop_output_text_stack__(lvl,p)) extern void *pop_output_text_stack__(int lvl, const void *ox USES_REGS); diff --git a/include/YapDefs.h b/include/YapDefs.h index d7e848eda..fac25cc84 100755 --- a/include/YapDefs.h +++ b/include/YapDefs.h @@ -297,6 +297,8 @@ typedef struct { YAP_handle_t EndSlot; //> variables at successful execution struct yami *p; //> Program Counter at entry struct yami *cp; //> Continuation PC at entry + int lvl; + unsigned long tr, h; } YAP_dogoalinfo; // query manipulation support diff --git a/os/iopreds.c b/os/iopreds.c index b17c8d25f..21ff012de 100644 --- a/os/iopreds.c +++ b/os/iopreds.c @@ -1583,9 +1583,18 @@ int Yap_OpenStream(Term tin, const char *io_mode, Term user_name, UNLOCK(st->streamlock); } else { st->file = fopen(fname, io_mode); + if (st->file == NULL) { + UNLOCK(st->streamlock); + if (errno == ENOENT && !strchr(io_mode, 'r')) { + PlIOError(EXISTENCE_ERROR_SOURCE_SINK, tin, "%s: %s", fname, + strerror(errno)); + } else { + PlIOError(PERMISSION_ERROR_OPEN_SOURCE_SINK, tin, "%s: %s", fname, + strerror(errno)); + } + } } - if (!st->file) { - fprintf(stderr, "trying %s\n", fname); + if (!st->file && !st->vfs) { PlIOError(EXISTENCE_ERROR_SOURCE_SINK, tin, "%s", fname); /* extract BACK info passed through the stream descriptor */ return -1; @@ -1629,19 +1638,9 @@ int Yap_OpenStream(Term tin, const char *io_mode, Term user_name, pop_text_stack(i); } } - if (st->file == NULL) { 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, - strerror(errno)); - } else { - PlIOError(PERMISSION_ERROR_OPEN_SOURCE_SINK, tin, "%s: %s", fname, - strerror(errno)); - } + flags |= Binary_Stream_f; } - return -1; - } Yap_initStream(sno, st->file, fname, io_mode, user_name, LOCAL_encoding, flags, vfsp); __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "exists %s <%d>", fname, diff --git a/packages/python/pyio.c b/packages/python/pyio.c index 84497d637..33e8f337b 100644 --- a/packages/python/pyio.c +++ b/packages/python/pyio.c @@ -69,6 +69,7 @@ static void *py_open(VFS_t *me, const char *name, const char *io_mode, } st->u.private_data = pystream; st->vfs = me; + st->file = NULL; python_release_GIL(ctk); return st; } diff --git a/packages/python/swig/yap4py/yapi.py b/packages/python/swig/yap4py/yapi.py index 702490f3b..fa49a9980 100644 --- a/packages/python/swig/yap4py/yapi.py +++ b/packages/python/swig/yap4py/yapi.py @@ -30,15 +30,15 @@ class Engine( YAPEngine ): args.setYapPLDIR(yap_lib_path) args.setSavedState(join(yap_lib_path, "startup.yss")) YAPEngine.__init__(self, args) - self.goal(set_prolog_flag('verbose', 'silent'), recover=True) - self.goal(compile(library('yapi')), recover=True) - self.goal(set_prolog_flag('verbose', 'normal'), release=True) + self.goal(set_prolog_flag('verbose', 'silent'),True) + self.goal(compile(library('yapi')), True) + self.goal(set_prolog_flag('verbose', 'normal'), True) def run(self, g, m=None, release=False): if m: - self.mgoal(g, m, release=release) + self.mgoal(g, m, release) else: - self.goal(release=release) + self.goal(release) class EngineArgs( YAPEngineArgs ): @@ -56,6 +56,7 @@ class Predicate( YAPPredicate ): class Query: """Goal is a predicate instantiated under a specific environment """ def __init__(self, engine, g): + engine.reSet(); self.q = engine.query(g) if self.q: self.port = "call" @@ -79,8 +80,10 @@ class Query: raise StopIteration() def close( self ): - self.q.close() - self.q = None + engine.reSet() + if self.q: + self.q.close() + self.q = None def name( name, arity): @@ -108,7 +111,7 @@ class YAPShell: def numbervars( self ): Dict = {} - self.engine.goal(show_answer( self, Dict)) + self.engine.goal(show_answer( self, Dict), True) return Dict # rc = self.q.namedVarsVector() # self.q.r = self.q.goal().numbervars() diff --git a/packages/python/yap_kernel/yap_ipython/yapi.py b/packages/python/yap_kernel/yap_ipython/yapi.py index 4dcea19b3..80554efe4 100644 --- a/packages/python/yap_kernel/yap_ipython/yapi.py +++ b/packages/python/yap_kernel/yap_ipython/yapi.py @@ -112,7 +112,7 @@ class YAPInputSplitter(InputSplitter): if not line: line = text.rstrip() self.errors = [] - engine.mgoal(errors(self, line),"user") + engine.mgoal(errors(self, line),"user",True) return self.errors != [] @@ -494,7 +494,7 @@ class YAPCompleter(Completer): ensure that each completion object will only be present once. """ self.matches = [] - prolog_res = self.shell.yapeng.mgoal(completions(text, self), "user") + prolog_res = self.shell.yapeng.mgoal(completions(text, self), "user",True) if self.matches: return text, self.matches magic_res = self.magic_matches(text) @@ -511,7 +511,7 @@ class YAPRun: self.yapeng = Engine() global engine engine = self.yapeng - self.yapeng.goal(use_module(library("jupyter"))) + self.yapeng.goal(use_module(library("jupyter")),True) self.query = None self.os = None self.it = None @@ -527,7 +527,7 @@ class YAPRun: return self.errors self.errors=[] (text,_,_,_) = self.clean_end(text) - self.yapeng.mgoal(errors(self,text),"user") + self.yapeng.mgoal(errors(self,text),"user",True) return self.errors def jupyter_query(self, s): @@ -724,10 +724,10 @@ class YAPRun: # run the new command using the given tracer # try: - self.yapeng.mgoal(streams(True),"user") + self.yapeng.mgoal(streams(True),"user", True) #state = tracer.runfunc(f,self,cell) state = self.jupyter_query( cell ) - self.yapeng.mgoal(streams(False),"user") + self.yapeng.mgoal(streams(False),"user", True) except Exception as e: has_raised = True self.yapeng.mgoal(streams("off"),"user")