/*-------------------------------------------------------------------------* * PL_RECOVER_SOLUTIONS_2 * * * *-------------------------------------------------------------------------*/ Bool Pl_Recover_Solutions_2(WamWord stop_word, WamWord handle_key_word, WamWord list_word) { int stop; int nb_sol; WamWord *p, *q; OneSol *s; Bool handle_key; stop = Pl_Rd_Integer(stop_word); nb_sol = sol->sol_no - stop; if (nb_sol == 0) return Pl_Get_Nil(list_word); handle_key = Pl_Rd_Integer(handle_key_word); key_var_ptr = pl_glob_dico_var; /* pl_glob_dico_var: key vars */ H += 2 * nb_sol; /* Since we start from the end to the beginning, if nb_sol is very big * when the heap overflow triggers a SIGSEGV the handler will not detect * that the heap is the culprit (and emits a simple Segmentation Violation * message). To avoid this we remain just after the end of the stack. */ if (H > Global_Stack + Global_Size) H = Global_Stack + Global_Size; p = q = H; while (nb_sol--) { p--; *p = Tag_LST(p + 1); *--p = Tag_REF(H); Pl_Copy_Contiguous_Term(H, &sol->term_word); if (handle_key) Handle_Key_Variables(*H); H += sol->term_size; s = sol; sol = sol->prev; Free(s); } q[-1] = NIL_WORD; return Pl_Unify(Tag_LST(p), list_word); }
/*-------------------------------------------------------------------------* * PL_RECOVER_SOLUTIONS_2 * * * *-------------------------------------------------------------------------*/ Bool Pl_Recover_Solutions_2(WamWord stop_word, WamWord handle_key_word, WamWord list_word) { int stop; int nb_sol; WamWord *p, *q; OneSol *s; Bool handle_key; stop = Pl_Rd_Integer(stop_word); nb_sol = sol->sol_no - stop; if (nb_sol == 0) return Pl_Get_Nil(list_word); handle_key = Pl_Rd_Integer(handle_key_word); key_var_ptr = pl_glob_dico_var; /* pl_glob_dico_var: key vars */ H += 2 * nb_sol; p = q = H; while (nb_sol--) { p--; *p = Tag_LST(p + 1); *--p = Tag_REF(H); Pl_Copy_Contiguous_Term(H, &sol->term_word); if (handle_key) Handle_Key_Variables(*H); H += sol->term_size; s = sol; sol = sol->prev; Free(s); } q[-1] = NIL_WORD; return Pl_Unify(Tag_LST(p), list_word); }
/*-------------------------------------------------------------------------* * PL_COPY_CONTIGUOUS_TERM * * * * Copy a contiguous term (dereferenced), the result is a contiguous term. * *-------------------------------------------------------------------------*/ void Pl_Copy_Contiguous_Term(WamWord *dst_adr, WamWord *src_adr) #define Old_Adr_To_New_Adr(adr) ((dst_adr)+((adr)-(src_adr))) { WamWord word, *adr; WamWord *q; int i; terminal_rec: word = *src_adr; switch (Tag_Of(word)) { case REF: adr = UnTag_REF(word); q = Old_Adr_To_New_Adr(adr); *dst_adr = Tag_REF(q); if (adr > src_adr) /* only useful for Dont_Separate_Tag */ Pl_Copy_Contiguous_Term(q, adr); return; #ifndef NO_USE_FD_SOLVER case FDV: adr = UnTag_FDV(word); Fd_Copy_Variable(dst_adr, adr); return; #endif case FLT: adr = UnTag_FLT(word); q = Old_Adr_To_New_Adr(adr); q[0] = adr[0]; #if WORD_SIZE == 32 q[1] = adr[1]; #endif *dst_adr = Tag_FLT(q); return; case LST: adr = UnTag_LST(word); q = Old_Adr_To_New_Adr(adr); *dst_adr = Tag_LST(q); q = &Car(q); adr = &Car(adr); Pl_Copy_Contiguous_Term(q++, adr++); dst_adr = q; src_adr = adr; goto terminal_rec; case STC: adr = UnTag_STC(word); q = Old_Adr_To_New_Adr(adr); *dst_adr = Tag_STC(q); Functor_And_Arity(q) = Functor_And_Arity(adr); i = Arity(adr); q = &Arg(q, 0); adr = &Arg(adr, 0); while (--i) Pl_Copy_Contiguous_Term(q++, adr++); dst_adr = q; src_adr = adr; goto terminal_rec; default: *dst_adr = word; return; } }