From 92089074f17a22e499e676d209d90e6a4a3a43f0 Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Thu, 24 Jan 2019 13:27:23 +0000 Subject: [PATCH] write_loops --- C/utilpreds.c | 145 +++++++++++++++++++++++++++++++++---------------- C/write.c | 52 +++++++++++------- os/writeterm.c | 4 ++ 3 files changed, 134 insertions(+), 67 deletions(-) diff --git a/C/utilpreds.c b/C/utilpreds.c index cdf66b7d5..0a0d18c68 100644 --- a/C/utilpreds.c +++ b/C/utilpreds.c @@ -176,6 +176,42 @@ clean_dirty_tr(tr_fr_ptr TR0 USES_REGS) { TR = TR0; } +/// @brief recover original term while fixing direct refs. +/// +/// @param USES_REGS +/// +static inline void +clean_complex_tr(tr_fr_ptr TR0 USES_REGS) { + tr_fr_ptr pt0 = TR; + while (pt0 != TR0) { + Term p = TrailTerm(--pt0); + if (IsApplTerm(p)) { + /// pt: points to the address of the new term we may want to fix. + CELL *pt = RepAppl(p); + if (pt >= HB && pt < HR) { /// is it new? + Term v = pt[0]; + if (IsApplTerm(v)) { + /// yes, more than a single ref + *pt = (CELL)RepAppl(v); + } +#ifndef FROZEN_STACKS + pt0 --; +#endif /* FROZEN_STACKS */ + continue; + } +#ifdef FROZEN_STACKS + pt[0] = TrailVal(pt0); +#else + pt[0] = TrailTerm(pt0 - 1); + pt0 --; +#endif /* FROZEN_STACKS */ + } else { + RESET_VARIABLE(p); + } + } + TR = TR0; +} + #define expand_stack(S0,SP,SF,TYPE) \ { size_t sz = SF-S0, used = SP-S0; \ S0 = Realloc(S0, (1024+sz)*sizeof(TYPE) PASS_REGS); \ @@ -214,69 +250,79 @@ int Yap_copy_complex_term(register CELL *pt0, register CELL *pt0_end, copy_term_nvar : { if (IsPairTerm(d0)) { CELL *headp = RepPair(d0); - if (IsPairTerm(*headp) && RepPair(*headp) >= HB && RepPair(*headp) < HR) { + Term head = *headp; + if (IsPairTerm(head) && RepPair(head) >= HB && RepPair(head) < HR) { if (split) { Term v = Yap_MkNewApplTerm(FunctorEq, 2); - RepAppl(v)[1] = *headp; + RepAppl(v)[1] = AbsPair(ptf); *headp = *ptf++ = RepAppl(v)[0]; o = MkPairTerm( v, o ); } else { - /* If this is newer than the current term, just reuse */ - *ptf++ = (CELL)RepAppl(*headp); + *ptf++ = head; } - } - else if (IsApplTerm(*headp) && RepAppl(*headp) >= HB && RepAppl(*headp) < HR) { + continue; + } else if (IsApplTerm(*headp) && RepAppl(*headp) >= HB && RepAppl(*headp) < HR) { *ptf++ = AbsPair(RepAppl(*headp)); - continue; - } - if (to_visit >= to_visit_max-32) { - expand_stack(to_visit0, to_visit, to_visit_max, struct cp_frame); - } - *ptf = AbsPair(HR); - ptf++; - to_visit->start_cp = pt0; - to_visit->end_cp = pt0_end; - to_visit->to = ptf; - to_visit->curp = headp; - d0 = *headp; - to_visit->oldv = d0; - to_visit->ground = ground; - to_visit++; - // move to new list - if (share) { - TrailedMaBind(headp,AbsPair(HR)); - } else { - *headp = AbsPair(HR); - } - pt0 = headp; - pt0_end = headp + 1; - ptf = HR; - ground = true; - HR += 2; - if (HR > ASP - MIN_ARENA_SIZE) { - goto overflow; - } - ptd0 = pt0; - goto deref; - } else if (IsApplTerm(d0)) { + continue; + } + if (to_visit >= to_visit_max-32) { + expand_stack(to_visit0, to_visit, to_visit_max, struct cp_frame); + } + *ptf = AbsPair(HR); + ptf++; + to_visit->start_cp = pt0; + to_visit->end_cp = pt0_end; + to_visit->to = ptf; + to_visit->curp = headp; + to_visit->oldv = head; + to_visit->ground = ground; + to_visit++; + // move to new list + if (share) { + TrailedMaBind(headp,AbsPair(HR)); + } else { + /* If this is newer than the current term, just reuse */ + *headp = AbsPair(HR); + } + if (split) { + TrailedMaBind(ptf,AbsPair(HR)); + } + pt0 = headp; + pt0_end = headp + 1; + ptf = HR; + ground = true; + HR += 2; + if (HR > ASP - MIN_ARENA_SIZE) { + goto overflow; + } + ptd0 = pt0; + goto deref; + } else if (IsApplTerm(d0)) { register Functor f; - register CELL *headp; + register CELL *headp, head; /* store the terms to visit */ headp = RepAppl(d0); - if (IsPairTerm(*headp)//(share && headp < HB) || + head = *headp; + + if (IsPairTerm(head)//(share && headp < HB) || ) { if (split) { Term v = Yap_MkNewApplTerm(FunctorEq, 2); - RepAppl(v)[1] = *headp; + RepAppl(v)[1] = head; *headp = *ptf++ = RepAppl(v)[0]; o = MkPairTerm( v, o ); } else { /* If this is newer than the current term, just reuse */ - *ptf++ = AbsPair(RepAppl(*headp)); + *ptf++ = AbsAppl(RepPair(head)); } continue; } - f = (Functor)(*headp); + if (IsApplTerm(head)//(share && headp < HB) || + ) { + *ptf++ = head; + continue; + } + f = (Functor)(head); if (IsExtensionFunctor(f)) { if (share) { @@ -365,6 +411,11 @@ int Yap_copy_complex_term(register CELL *pt0, register CELL *pt0_end, } else { *headp = AbsPair(HR); } + if (split) { + // must be after trailing source term, so that we can check the source + // term and confirm it is still ok. + TrailedMaBind(ptf,AbsAppl(HR)); + } ptf = HR; ptf[-1] = (CELL)f; ground = true; @@ -435,10 +486,10 @@ if (to_visit > to_visit0) { } /* restore our nice, friendly, term to its original state */ -clean_dirty_tr(TR0 PASS_REGS); -/* follow chain of multi-assigned variables */ -pop_text_stack(lvl); -return 0; + clean_complex_tr(TR0 PASS_REGS); + /* follow chain of multi-assigned variables */ + pop_text_stack(lvl); + return 0; overflow: diff --git a/C/write.c b/C/write.c index 95df7a945..aec28c6df 100644 --- a/C/write.c +++ b/C/write.c @@ -77,6 +77,7 @@ typedef struct write_globs { int last_atom_minus; UInt MaxDepth, MaxArgs; wtype lw; + int sl0; } wglbs; #define lastw wglb->lw @@ -100,11 +101,20 @@ static bool callPortray(Term t, int sno USES_REGS) { return false; } -#define PROTECT(t, F) \ - { \ - yhandle_t yt = Yap_InitHandle(t); \ - F; \ - t = Yap_PopHandle(yt); \ +#define PROTECT(t, F) \ + { \ + yhandle_t yt = Yap_InitHandle(t); \ + if (wglb->Write_Loops) { \ + yhandle_t i; \ + for (i=wglb->sl0;istream ); return; \ + } \ + } \ + } \ + F; \ + t = Yap_PopHandle(yt);\ } static void wrputn(Int, struct write_globs *); static void wrputf(Float, struct write_globs *); @@ -267,7 +277,7 @@ static void writebig(Term t, int p, int depth, int rinfixarg, return; } else if (big_tag == BIG_RATIONAL) { Term trat = Yap_RatTermToApplTerm(t); - writeTerm(trat, p, depth, rinfixarg, wglb, rwt); + PROTECT(t,writeTerm(trat, p, depth, rinfixarg, wglb, rwt)); return; #endif } else if (big_tag >= USER_BLOB_START && big_tag < USER_BLOB_END) { @@ -701,11 +711,11 @@ static void write_var(CELL *t, struct write_globs *wglb, wrputs("$AT(", wglb->stream); write_var(t, wglb, rwt); wrputc(',', wglb->stream); - PROTECT(*t, writeTerm(*l, 999, 1, FALSE, wglb, &nrwt)); + PROTECT(t, writeTerm(*l, 999, 1, FALSE, wglb, &nrwt)); attv = RepAttVar(t); wrputc(',', wglb->stream); l++; - writeTerm(*l, 999, 1, FALSE, wglb, &nrwt); + PROTECT(t, writeTerm(*l, 999, 1, FALSE, wglb, &nrwt)); wrclose_bracket(wglb, TRUE); } wglb->Portray_delays = TRUE; @@ -767,14 +777,14 @@ static void write_list(Term t, int direction, int depth, /* we found an infinite loop */ /* keep going on the list */ wrputc(',', wglb->stream); - write_list(ti, direction, depth, wglb, &nrwt); + PROTECT(t,write_list(ti, direction, depth, wglb, &nrwt)); } else if (ti != MkAtomTerm(AtomNil)) { if (lastw == symbol || lastw == separator) { wrputc(' ', wglb->stream); } wrputc('|', wglb->stream); lastw = separator; - writeTerm(ti, 999, depth, FALSE, wglb, &nrwt); + PROTECT(ti,writeTerm(ti, 999, depth, FALSE, wglb, &nrwt)); } } @@ -807,7 +817,7 @@ static void writeTerm(Term t, int p, int depth, int rinfixarg, PROTECT(t, writeTerm(HeadOfTerm(t), 999, depth + 1, FALSE, wglb, &nrwt)); wrputs(",", wglb->stream); - writeTerm(TailOfTerm(t), 999, depth + 1, FALSE, wglb, &nrwt); + PROTECT(t, writeTerm(TailOfTerm(t), 999, depth + 1, FALSE, wglb, &nrwt)); wrclose_bracket(wglb, TRUE); return; } @@ -901,7 +911,7 @@ static void writeTerm(Term t, int p, int depth, int rinfixarg, } else if (atom == AtomMinus) { last_minus = TRUE; } - writeTerm(tright, rp, depth + 1, TRUE, wglb, &nrwt); + PROTECT(t,writeTerm(tright, rp, depth + 1, TRUE, wglb, &nrwt)); if (bracket_right) { wrclose_bracket(wglb, TRUE); } @@ -934,7 +944,7 @@ static void writeTerm(Term t, int p, int depth, int rinfixarg, if (bracket_left) { wropen_bracket(wglb, TRUE); } - writeTerm(ArgOfTerm(offset, t), lp, depth + 1, rinfixarg, wglb, &nrwt); + PROTECT(t,writeTerm(ArgOfTerm(offset, t), lp, depth + 1, rinfixarg, wglb, &nrwt)); if (bracket_left) { wrclose_bracket(wglb, TRUE); } @@ -999,7 +1009,7 @@ static void writeTerm(Term t, int p, int depth, int rinfixarg, if (bracket_right) { wropen_bracket(wglb, TRUE); } - writeTerm(ArgOfTerm(2, t), rp, depth + 1, TRUE, wglb, &nrwt); + PROTECT(t,writeTerm(ArgOfTerm(2, t), rp, depth + 1, TRUE, wglb, &nrwt)); if (bracket_right) { wrclose_bracket(wglb, TRUE); } @@ -1039,14 +1049,14 @@ static void writeTerm(Term t, int p, int depth, int rinfixarg, } else { wrputs("'$VAR'(", wglb->stream); lastw = separator; - writeTerm(ArgOfTerm(1, t), 999, depth + 1, FALSE, wglb, &nrwt); + PROTECT(t,writeTerm(ArgOfTerm(1, t), 999, depth + 1, FALSE, wglb, &nrwt)); wrclose_bracket(wglb, TRUE); } } else if (!wglb->Ignore_ops && functor == FunctorBraces) { wrputc('{', wglb->stream); lastw = separator; - writeTerm(ArgOfTerm(1, t), GLOBAL_MaxPriority, depth + 1, FALSE, wglb, - &nrwt); + PROTECT(t,writeTerm(ArgOfTerm(1, t), GLOBAL_MaxPriority, depth + 1, FALSE, wglb, + &nrwt)); wrputc('}', wglb->stream); lastw = separator; } else if (atom == AtomArray) { @@ -1057,7 +1067,7 @@ static void writeTerm(Term t, int p, int depth, int rinfixarg, wrputs("...", wglb->stream); break; } - writeTerm(ArgOfTerm(op, t), 999, depth + 1, FALSE, wglb, &nrwt); + PROTECT(t,writeTerm(ArgOfTerm(op, t), 999, depth + 1, FALSE, wglb, &nrwt)); if (op != Arity) { PROTECT(t, writeTerm(ArgOfTerm(op, t), 999, depth + 1, FALSE, wglb, &nrwt)); @@ -1065,7 +1075,7 @@ static void writeTerm(Term t, int p, int depth, int rinfixarg, lastw = separator; } } - writeTerm(ArgOfTerm(op, t), 999, depth + 1, FALSE, wglb, &nrwt); + PROTECT(t,writeTerm(ArgOfTerm(op, t), 999, depth + 1, FALSE, wglb, &nrwt)); wrputc('}', wglb->stream); lastw = separator; } else { @@ -1084,7 +1094,7 @@ static void writeTerm(Term t, int p, int depth, int rinfixarg, wrputc(',', wglb->stream); lastw = separator; } - writeTerm(ArgOfTerm(op, t), 999, depth + 1, FALSE, wglb, &nrwt); + PROTECT(t,writeTerm(ArgOfTerm(op, t), 999, depth + 1, FALSE, wglb, &nrwt)); wrclose_bracket(wglb, TRUE); } } @@ -1102,6 +1112,7 @@ void Yap_plwrite(Term t, StreamDesc *mywrite, int max_depth, int flags, yhandle_t sls = Yap_CurrentSlot(); int lvl = push_text_stack(); + wglb.sl0 = sls; if (t == 0) return; if (!mywrite) { @@ -1124,6 +1135,7 @@ void Yap_plwrite(Term t, StreamDesc *mywrite, int max_depth, int flags, rwt.parent = NULL; wglb.Ignore_ops = flags & Ignore_ops_f; wglb.Write_strings = flags & BackQuote_String_f; + wglb.Write_Loops = !(flags &Ignore_cyclics_f); if (!(flags & Ignore_cyclics_f) && false) { Term ts[2]; ts[0] = Yap_BreakRational(t, 0, ts + 1, TermNil PASS_REGS); diff --git a/os/writeterm.c b/os/writeterm.c index 715d84e3c..b55b96c63 100644 --- a/os/writeterm.c +++ b/os/writeterm.c @@ -573,6 +573,8 @@ static Int writeln1(USES_REGS1) { args[WRITE_NL].tvalue = TermTrue; args[WRITE_NUMBERVARS].used = true; args[WRITE_NUMBERVARS].tvalue = TermTrue; + args[WRITE_CYCLES].used = true; + args[WRITE_CYCLES].tvalue = TermTrue; LOCK(GLOBAL_Stream[output_stream].streamlock); write_term(output_stream, ARG1, args PASS_REGS); UNLOCK(GLOBAL_Stream[output_stream].streamlock); @@ -603,6 +605,8 @@ static Int writeln(USES_REGS1) { args[WRITE_NL].tvalue = TermTrue; args[WRITE_NUMBERVARS].used = true; args[WRITE_NUMBERVARS].tvalue = TermTrue; + args[WRITE_CYCLES].used = true; + args[WRITE_CYCLES].tvalue = TermTrue; write_term(output_stream, ARG2, args PASS_REGS); UNLOCK(GLOBAL_Stream[output_stream].streamlock); free(args);