YAP 7.1.0
qlyw.c
1/*************************************************************************
2 * *
3 * YAP Prolog *
4 * *
5 * Yap Prolog was developed at NCCUP - Universidade do Porto *
6 * *
7 * Copyright L.Damas, V. Santos Costa and Universidade do Porto 1985-- *
8 * *
9 **************************************************************************
10 * *
11 * File: qlyw.c *
12 * comments: quick saver/loader *
13 * *
14 * Last rev: $Date: 2011-08-29$,$Author: vsc $ *
15 * $Log: not supported by cvs2svn $ *
16 * *
17 *************************************************************************/
18
28#include "Foreign.h"
29#include "absmi.h"
30#include "alloc.h"
31#include "attvar.h"
32#include "iopreds.h"
33#include "yapio.h"
34#if HAVE_STRING_H
35#include <string.h>
36#endif
37
38#include "qly.h"
39
40static void RestoreEntries(PropEntry *, int USES_REGS);
41static void CleanCode(PredEntry *USES_REGS);
42
43static void GrowAtomTable(void) {
44 CACHE_REGS
45 UInt size = LOCAL_ExportAtomHashTableSize;
46 export_atom_hash_entry_t *p, *newt, *oldt = LOCAL_ExportAtomHashChain;
47 UInt new_size = size + (size > 1024 ? size : 1024);
48 UInt i;
49
50 newt = (export_atom_hash_entry_t *)calloc(new_size,
52 if (!newt) {
53 return;
54 }
55 p = oldt;
56 for (i = 0; i < size; p++, i++) {
57 Atom a = p->val;
59 CELL hash;
60 const unsigned char *apt;
61
62 if (!a)
63 continue;
64 apt = RepAtom(a)->UStrOfAE;
65 hash = HashFunction(apt) / (2 * sizeof(CELL)) % new_size;
66 newp = newt + hash;
67 while (newp->val) {
68 newp++;
69 if (newp == newt + new_size)
70 newp = newt;
71 }
72 newp->val = a;
73 }
74 LOCAL_ExportAtomHashChain = newt;
75 LOCAL_ExportAtomHashTableSize = new_size;
76 free(oldt);
77}
78
79static void LookupAtom(Atom at) {
80 CACHE_REGS
81 const unsigned char *p = RepAtom(at)->UStrOfAE;
82 CELL hash = HashFunction(p) % LOCAL_ExportAtomHashTableSize;
84
85 a = LOCAL_ExportAtomHashChain + hash;
86 while (a->val) {
87 if (a->val == at) {
88 return;
89 }
90 a++;
91 if (a == LOCAL_ExportAtomHashChain + LOCAL_ExportAtomHashTableSize)
92 a = LOCAL_ExportAtomHashChain;
93 }
94 a->val = at;
95 LOCAL_ExportAtomHashTableNum++;
96 if (LOCAL_ExportAtomHashTableNum > LOCAL_ExportAtomHashTableSize / 2) {
97 GrowAtomTable();
98 if (!LOCAL_ExportAtomHashChain) {
99 return;
100 }
101 }
102}
103
104static void GrowFunctorTable(void) {
105 CACHE_REGS
106 UInt size = LOCAL_ExportFunctorHashTableSize;
107 export_functor_hash_entry_t *p, *newt, *oldt = LOCAL_ExportFunctorHashChain;
108 UInt new_size = size + (size > 1024 ? size : 1024);
109 UInt i;
110
111 newt = (export_functor_hash_entry_t *)calloc(
112 new_size, sizeof(export_functor_hash_entry_t));
113 if (!newt) {
114 return;
115 }
116 p = oldt;
117 for (i = 0; i < size; p++, i++) {
118 Functor f = p->val;
120 CELL hash;
121
122 if (!f)
123 continue;
124 hash = ((CELL)(f)) / (2 * sizeof(CELL)) % new_size;
125 newp = newt + hash;
126 while (newp->val) {
127 newp++;
128 if (newp == newt + new_size)
129 newp = newt;
130 }
131 newp->val = p->val;
132 newp->arity = p->arity;
133 newp->name = p->name;
134 }
135 LOCAL_ExportFunctorHashChain = newt;
136 LOCAL_ExportFunctorHashTableSize = new_size;
137 free(oldt);
138}
139
140static void LookupFunctor(Functor fun) {
141 CACHE_REGS
142 CELL hash =
143 ((CELL)(fun)) / (2 * sizeof(CELL)) % LOCAL_ExportFunctorHashTableSize;
145 Atom name = NameOfFunctor(fun);
146 UInt arity = ArityOfFunctor(fun);
147
148 f = LOCAL_ExportFunctorHashChain + hash;
149 while (f->val) {
150 if (f->val == fun) {
151 return;
152 }
153 f++;
154 if (f == LOCAL_ExportFunctorHashChain + LOCAL_ExportFunctorHashTableSize)
155 f = LOCAL_ExportFunctorHashChain;
156 }
157 LookupAtom(name);
158 f->val = fun;
159 f->name = name;
160 f->arity = arity;
161 LOCAL_ExportFunctorHashTableNum++;
162 if (LOCAL_ExportFunctorHashTableNum > LOCAL_ExportFunctorHashTableSize / 2) {
163 GrowFunctorTable();
164 if (!LOCAL_ExportFunctorHashChain) {
165 return;
166 }
167 }
168}
169
170static void GrowPredTable(void) {
171 CACHE_REGS
172 UInt size = LOCAL_ExportPredEntryHashTableSize;
174 *oldt = LOCAL_ExportPredEntryHashChain;
175 UInt new_size = size + (size > 1024 ? size : 1024);
176 UInt i;
177
178 newt = (export_pred_entry_hash_entry_t *)calloc(
179 new_size, sizeof(export_pred_entry_hash_entry_t));
180 if (!newt) {
181 return;
182 }
183 p = oldt;
184 for (i = 0; i < size; p++, i++) {
185 PredEntry *pe = p->val;
187 CELL hash;
188
189 if (!pe)
190 continue;
191 hash = ((CELL)(pe)) / (2 * sizeof(CELL)) % new_size;
192 newp = newt + hash;
193 while (newp->val) {
194 newp++;
195 if (newp == newt + new_size)
196 newp = newt;
197 }
198 newp->val = p->val;
199 newp->arity = p->arity;
200 newp->u_af.f = p->u_af.f;
201 newp->module = p->module;
202 }
203 LOCAL_ExportPredEntryHashChain = newt;
204 LOCAL_ExportPredEntryHashTableSize = new_size;
205 free(oldt);
206}
207
208static void LookupPredEntry(PredEntry *pe) {
209 CACHE_REGS
210 CELL hash =
211 (((CELL)(pe)) / (2 * sizeof(CELL))) % LOCAL_ExportPredEntryHashTableSize;
213 UInt arity = pe->ArityOfPE;
214
215 p = LOCAL_ExportPredEntryHashChain + hash;
216 while (p->val) {
217 if (p->val == pe) {
218 return;
219 }
220 p++;
221 if (p ==
222 LOCAL_ExportPredEntryHashChain + LOCAL_ExportPredEntryHashTableSize)
223 p = LOCAL_ExportPredEntryHashChain;
224 }
225 p->arity = arity;
226 p->val = pe;
227 if (pe->ModuleOfPred != IDB_MODULE) {
228 if (arity) {
229 p->u_af.f = pe->FunctorOfPred;
230 LookupFunctor(pe->FunctorOfPred);
231 } else {
232 p->u_af.a = (Atom)(pe->FunctorOfPred);
233 LookupAtom((Atom)(pe->FunctorOfPred));
234 }
235 } else {
236 if (pe->PredFlags & AtomDBPredFlag) {
237 p->u_af.a = (Atom)(pe->FunctorOfPred);
238 p->arity = (CELL)(-2);
239 LookupAtom((Atom)(pe->FunctorOfPred));
240 } else if (!(pe->PredFlags & NumberDBPredFlag)) {
241 p->u_af.f = pe->FunctorOfPred;
242 p->arity = (CELL)(-1);
243 LookupFunctor(pe->FunctorOfPred);
244 } else {
245 p->u_af.f = pe->FunctorOfPred;
246 }
247 }
248 if (pe->ModuleOfPred) {
249 p->module = AtomOfTerm(pe->ModuleOfPred);
250 } else {
251 p->module = AtomProlog;
252 }
253 LookupAtom(p->module);
254 LOCAL_ExportPredEntryHashTableNum++;
255 if (LOCAL_ExportPredEntryHashTableNum >
256 LOCAL_ExportPredEntryHashTableSize / 2) {
257 GrowPredTable();
258 if (!LOCAL_ExportPredEntryHashChain) {
259 return;
260 }
261 }
262}
263
264static void GrowDBRefTable(void) {
265 CACHE_REGS
266 UInt size = LOCAL_ExportDBRefHashTableSize;
267 export_dbref_hash_entry_t *p, *newt, *oldt = LOCAL_ExportDBRefHashChain;
268 UInt new_size = size + (size > 1024 ? size : 1024);
269 UInt i;
270
271 newt = (export_dbref_hash_entry_t *)calloc(new_size,
273 if (!newt) {
274 return;
275 }
276 p = oldt;
277 for (i = 0; i < size; p++, i++) {
278 DBRef dbr = p->val;
280 CELL hash;
281
282 if (!dbr)
283 continue;
284 hash = ((CELL)(dbr)) / (2 * sizeof(CELL)) % new_size;
285 newp = newt + hash;
286 while (newp->val) {
287 newp++;
288 if (newp == newt + new_size)
289 newp = newt;
290 }
291 newp->val = p->val;
292 newp->sz = p->sz;
293 newp->refs = p->refs;
294 }
295 LOCAL_ExportDBRefHashChain = newt;
296 LOCAL_ExportDBRefHashTableSize = new_size;
297 free(oldt);
298}
299
300static void LookupDBRef(DBRef ref) {
301 CACHE_REGS
302 CELL hash =
303 ((CELL)(ref)) / (2 * sizeof(CELL)) % LOCAL_ExportDBRefHashTableSize;
305
306 a = LOCAL_ExportDBRefHashChain + hash;
307 while (a->val) {
308 if (a->val == ref) {
309 a->refs++;
310 return;
311 }
312 a++;
313 if (a == LOCAL_ExportDBRefHashChain + LOCAL_ExportDBRefHashTableSize)
314 a = LOCAL_ExportDBRefHashChain;
315 }
316 a->val = ref;
317 a->sz = ((LogUpdClause *)ref)->ClSize;
318 a->refs = 1;
319 LOCAL_ExportDBRefHashTableNum++;
320 if (LOCAL_ExportDBRefHashTableNum > LOCAL_ExportDBRefHashTableSize / 2) {
321 GrowDBRefTable();
322 if (!LOCAL_ExportDBRefHashChain) {
323 return;
324 }
325 }
326}
327
328static void InitHash(void) {
329 CACHE_REGS
330 LOCAL_ExportFunctorHashTableNum = 0;
331 LOCAL_ExportFunctorHashTableSize = EXPORT_FUNCTOR_TABLE_SIZE;
332 LOCAL_ExportFunctorHashChain = (export_functor_hash_entry_t *)calloc(
333 LOCAL_ExportFunctorHashTableSize, sizeof(export_functor_hash_entry_t));
334 LOCAL_ExportAtomHashTableNum = 0;
335 LOCAL_ExportAtomHashTableSize = EXPORT_ATOM_TABLE_SIZE;
336 LOCAL_ExportAtomHashChain = (export_atom_hash_entry_t *)calloc(
337 LOCAL_ExportAtomHashTableSize, sizeof(export_atom_hash_entry_t));
338 LOCAL_ExportPredEntryHashTableNum = 0;
339 LOCAL_ExportPredEntryHashTableSize = EXPORT_PRED_ENTRY_TABLE_SIZE;
340 LOCAL_ExportPredEntryHashChain = (export_pred_entry_hash_entry_t *)calloc(
341 LOCAL_ExportPredEntryHashTableSize,
343 LOCAL_ExportDBRefHashTableNum = 0;
344 LOCAL_ExportDBRefHashTableSize = EXPORT_DBREF_TABLE_SIZE;
345 LOCAL_ExportDBRefHashChain = (export_dbref_hash_entry_t *)calloc(
346 EXPORT_DBREF_TABLE_SIZE, sizeof(export_dbref_hash_entry_t));
347}
348
349static void CloseHash(void) {
350 CACHE_REGS
351 LOCAL_ExportFunctorHashTableNum = 0;
352 LOCAL_ExportFunctorHashTableSize = 0L;
353 free(LOCAL_ExportFunctorHashChain);
354 LOCAL_ExportAtomHashTableNum = 0;
355 LOCAL_ExportAtomHashTableSize = 0L;
356 free(LOCAL_ExportAtomHashChain);
357 LOCAL_ExportPredEntryHashTableNum = 0;
358 LOCAL_ExportPredEntryHashTableSize = 0L;
359 free(LOCAL_ExportPredEntryHashChain);
360 LOCAL_ExportDBRefHashTableNum = 0;
361 LOCAL_ExportDBRefHashTableSize = 0L;
362 free(LOCAL_ExportDBRefHashChain);
363}
364
365static inline Atom AtomAdjust(Atom a) {
366 LookupAtom(a);
367 return a;
368}
369
370static inline Functor FuncAdjust(Functor f) {
371 LookupFunctor(f);
372 return f;
373}
374
375static inline Term AtomTermAdjust(Term t) {
376 LookupAtom(AtomOfTerm(t));
377 return t;
378}
379
380static inline Term TermToGlobalOrAtomAdjust(Term t) {
381 if (t && IsAtomTerm(t))
382 return AtomTermAdjust(t);
383 return t;
384}
385
386#define IsOldCode(P) FALSE
387#define IsOldCodeCellPtr(P) FALSE
388#define IsOldDelay(P) FALSE
389#define IsOldDelayPtr(P) FALSE
390#define IsOldLocalInTR(P) FALSE
391#define IsOldLocalInTRPtr(P) FALSE
392#define IsOldGlobal(P) FALSE
393#define IsOldGlobalPtr(P) FALSE
394#define IsOldTrail(P) FALSE
395#define IsOldTrailPtr(P) FALSE
396
397#define CharP(X) ((char *)(X))
398
399#define REINIT_LOCK(P)
400#define REINIT_RWLOCK(P)
401#define BlobTypeAdjust(P) (P)
402#define NoAGCAtomAdjust(P) (P)
403#define OrArgAdjust(P)
404#define TabEntryAdjust(P)
405#define IntegerAdjust(D) (D)
406#define AddrAdjust(P) (P)
407#define MFileAdjust(P) (P)
408#define CodeVarAdjust(P) (P)
409#define ConstantAdjust(P) (P)
410#define ArityAdjust(P) (P)
411#define DoubleInCodeAdjust(P)
412#define IntegerInCodeAdjust(P)
413#define OpcodeAdjust(P) (P)
414
415static inline Term ModuleAdjust(Term t) {
416 if (!t)
417 return t;
418 return AtomTermAdjust(t);
419}
420
421static inline PredEntry *PredEntryAdjust(PredEntry *pe) {
422 LookupPredEntry(pe);
423 return pe;
424}
425
426static inline PredEntry *PtoPredAdjust(PredEntry *pe) {
427 LookupPredEntry(pe);
428 return pe;
429}
430
431#define ExternalFunctionAdjust(P) (P)
432#define DBRecordAdjust(P) (P)
433#define ModEntryPtrAdjust(P) (P)
434#define AtomEntryAdjust(P) (P)
435#define GlobalEntryAdjust(P) (P)
436#define BlobTermInCodeAdjust(P) (P)
437#define CellPtoHeapAdjust(P) (P)
438#define PtoAtomHashEntryAdjust(P) (P)
439#define CellPtoHeapCellAdjust(P) (P)
440#define CellPtoTRAdjust(P) (P)
441#define CodeAddrAdjust(P) (P)
442#define ConsultObjAdjust(P) (P)
443#define DelayAddrAdjust(P) (P)
444#define DelayAdjust(P) (P)
445#define GlobalAdjust(P) (P)
446
447#define DBRefAdjust(P, DoRef) DBRefAdjust__(P PASS_REGS)
448static inline DBRef DBRefAdjust__(DBRef dbt USES_REGS) {
449 LookupDBRef(dbt);
450 return dbt;
451}
452
453#define DBRefPAdjust(P) (P)
454#define DBTermAdjust(P) (P)
455#define LUIndexAdjust(P) (P)
456#define SIndexAdjust(P) (P)
457#define LocalAddrAdjust(P) (P)
458#define GlobalAddrAdjust(P) (P)
459#define OpListAdjust(P) (P)
460#define PtoLUCAdjust(P) (P)
461#define PtoStCAdjust(P) (P)
462#define PtoArrayEAdjust(P) (P)
463#define PtoArraySAdjust(P) (P)
464#define PtoGlobalEAdjust(P) (P)
465#define PtoDelayAdjust(P) (P)
466#define PtoGloAdjust(P) (P)
467#define PtoLocAdjust(P) (P)
468#define PtoHeapCellAdjust(P) (P)
469#define TermToGlobalAdjust(P) (P)
470#define PtoOpAdjust(P) (P)
471#define PtoLUClauseAdjust(P) (P)
472#define PtoLUIndexAdjust(P) (P)
473#define PtoDBTLAdjust(P) (P)
474#define PtoPtoPredAdjust(P) (P)
475#define OpRTableAdjust(P) (P)
476#define OpEntryAdjust(P) (P)
477#define PropAdjust(P) (P)
478#define TrailAddrAdjust(P) (P)
479#define XAdjust(P) (P)
480#define YAdjust(P) (P)
481#define HoldEntryAdjust(P) (P)
482#define CodeCharPAdjust(P) (P)
483#define CodeConstCharPAdjust(P) (P)
484#define CodeVoidPAdjust(P) (P)
485#define HaltHookAdjust(P) (P)
486
487#define recompute_mask(dbr)
488
489#define rehash(oldcode, NOfE, KindOfEntries)
490
491static void RestoreFlags(UInt NFlags) {}
492
493#include "rheap.h"
494
495static void RestoreHashPreds(USES_REGS1) {}
496
497static void RestoreAtomList(Atom atm USES_REGS) {}
498
499static size_t save_bytes(FILE *stream, void *ptr, size_t sz) {
500 return fwrite(ptr, sz, 1, stream);
501}
502
503static size_t save_byte(FILE *stream, int byte) {
504 fputc(byte, stream);
505 return 1;
506}
507
508static size_t save_bits16(FILE *stream, BITS16 val) {
509 BITS16 v = val;
510 return save_bytes(stream, &v, sizeof(BITS16));
511}
512
513static size_t save_UInt(FILE *stream, UInt val) {
514 UInt v = val;
515 return save_bytes(stream, &v, sizeof(UInt));
516}
517
518static size_t save_Int(FILE *stream, Int val) {
519 Int v = val;
520 return save_bytes(stream, &v, sizeof(Int));
521}
522
523static size_t save_tag(FILE *stream, qlf_tag_t tag) {
524 return save_byte(stream, tag);
525}
526
527static size_t save_predFlags(FILE *stream, pred_flags_t predFlags) {
528 pred_flags_t v = predFlags;
529 return save_bytes(stream, &v, sizeof(pred_flags_t));
530}
531
532static int SaveHash(FILE *stream) {
533 CACHE_REGS
534 UInt i;
535 /* first, current opcodes */
536 CHECK(save_tag(stream, QLY_START_X));
537 save_UInt(stream, (UInt)&ARG1);
538 CHECK(save_tag(stream, QLY_START_OPCODES));
539 save_Int(stream, _std_top);
540 for (i = 0; i <= _std_top; i++) {
541 save_UInt(stream, (UInt)Yap_opcode(i));
542 }
543 CHECK(save_tag(stream, QLY_START_ATOMS));
544 CHECK(save_UInt(stream, LOCAL_ExportAtomHashTableNum));
545 for (i = 0; i < LOCAL_ExportAtomHashTableSize; i++) {
546 export_atom_hash_entry_t *a = LOCAL_ExportAtomHashChain + i;
547 if (a->val) {
548 Atom at = a->val;
549 CHECK(save_UInt(stream, (UInt)at));
550 CHECK(save_tag(stream, QLY_ATOM));
551 CHECK(save_UInt(stream, strlen((char *)RepAtom(at)->StrOfAE)));
552 CHECK(save_bytes(stream, (char *)at->StrOfAE,
553 (strlen((char *)at->StrOfAE) + 1) * sizeof(char)));
554 }
555 }
556 save_tag(stream, QLY_START_FUNCTORS);
557 save_UInt(stream, LOCAL_ExportFunctorHashTableNum);
558 for (i = 0; i < LOCAL_ExportFunctorHashTableSize; i++) {
559 export_functor_hash_entry_t *f = LOCAL_ExportFunctorHashChain + i;
560 if (!(f->val))
561 continue;
562 CHECK(save_UInt(stream, (UInt)(f->val)));
563 CHECK(save_UInt(stream, f->arity));
564 CHECK(save_UInt(stream, (CELL)(f->name)));
565 }
566 save_tag(stream, QLY_START_PRED_ENTRIES);
567 save_UInt(stream, LOCAL_ExportPredEntryHashTableNum);
568 for (i = 0; i < LOCAL_ExportPredEntryHashTableSize; i++) {
569 export_pred_entry_hash_entry_t *p = LOCAL_ExportPredEntryHashChain + i;
570 if (!(p->val))
571 continue;
572 CHECK(save_UInt(stream, (UInt)(p->val)));
573 CHECK(save_UInt(stream, p->arity));
574 CHECK(save_UInt(stream, (UInt)p->module));
575 CHECK(save_UInt(stream, (UInt)p->u_af.f));
576 }
577 save_tag(stream, QLY_START_DBREFS);
578 save_UInt(stream, LOCAL_ExportDBRefHashTableNum);
579 for (i = 0; i < LOCAL_ExportDBRefHashTableSize; i++) {
580 export_dbref_hash_entry_t *p = LOCAL_ExportDBRefHashChain + i;
581 if (p->val) {
582 CHECK(save_UInt(stream, (UInt)(p->val)));
583 CHECK(save_UInt(stream, p->sz));
584 CHECK(save_UInt(stream, p->refs));
585 }
586 }
587 save_tag(stream, QLY_FAILCODE);
588 save_UInt(stream, (UInt)FAILCODE);
589 return 1;
590}
591
592static size_t save_clauses(FILE *stream, PredEntry *pp) {
593 yamop *FirstC, *LastC;
594
595 FirstC = pp->cs.p_code.FirstClause;
596 LastC = pp->cs.p_code.LastClause;
597 if (FirstC == NULL && LastC == NULL) {
598 return 1;
599 }
600 if (pp->PredFlags & LogUpdatePredFlag) {
601 LogUpdClause *cl = ClauseCodeToLogUpdClause(FirstC);
602
603 while (cl != NULL) {
604 if (IN_BETWEEN(cl->ClTimeStart, pp->TimeStampOfPred, cl->ClTimeEnd)) {
605 UInt size = cl->ClSize;
606 CHECK(save_tag(stream, QLY_START_LU_CLAUSE));
607 CHECK(save_UInt(stream, (UInt)cl));
608 CHECK(save_UInt(stream, size));
609 CHECK(save_bytes(stream, cl, size));
610 }
611 cl = cl->ClNext;
612 }
613 CHECK(save_tag(stream, QLY_END_LU_CLAUSES));
614 } else if (pp->PredFlags & MegaClausePredFlag) {
615 MegaClause *cl = ClauseCodeToMegaClause(FirstC);
616 UInt size = cl->ClSize;
617
618 CHECK(save_UInt(stream, (UInt)cl));
619 CHECK(save_UInt(stream, (UInt)(cl->ClFlags)));
620 CHECK(save_UInt(stream, size));
621 CHECK(save_bytes(stream, cl, size));
622 } else if (pp->PredFlags & DynamicPredFlag) {
623 yamop *cl = FirstC;
624
625 do {
626 DynamicClause *dcl = ClauseCodeToDynamicClause(cl);
627 UInt size = dcl->ClSize;
628
629 CHECK(save_UInt(stream, (UInt)cl));
630 CHECK(save_UInt(stream, size));
631 CHECK(save_bytes(stream, dcl, size));
632 if (cl == LastC)
633 return 1;
634 cl = NextDynamicClause(cl);
635 } while (TRUE);
636 } else {
637 StaticClause *cl = ClauseCodeToStaticClause(FirstC);
638
639 if (pp->PredFlags & SYSTEM_PRED_FLAGS) {
640 return 1;
641 }
642 do {
643 UInt size = cl->ClSize;
644
645 CHECK(save_UInt(stream, (UInt)cl));
646 CHECK(save_UInt(stream, size));
647 CHECK(save_bytes(stream, cl, size));
648 if (cl->ClCode == LastC)
649 return 1;
650 cl = cl->ClNext;
651 } while (TRUE);
652 }
653 return 1;
654}
655
656static size_t save_pred(FILE *stream, PredEntry *ap) {
657 CHECK(save_UInt(stream, (UInt)ap));
658 CHECK(save_predFlags(stream, ap->PredFlags));
659 if (ap->PredFlags & ForeignPredFlags)
660 return 1;
661 CHECK(save_UInt(stream, ap->cs.p_code.NOfClauses));
662 CHECK(save_UInt(stream, ap->src.IndxId));
663 CHECK(save_UInt(stream, ap->TimeStampOfPred));
664 return save_clauses(stream, ap);
665}
666
667static int clean_pred(PredEntry *pp USES_REGS) {
668 if (pp->PredFlags & ForeignPredFlags) {
669 return true;
670 } else {
671 CleanClauses(pp->cs.p_code.FirstClause, pp->cs.p_code.LastClause,
672 pp PASS_REGS);
673 }
674 return true;
675}
676
677static size_t mark_pred(PredEntry *ap) {
678 CACHE_REGS
679 if (ap->ModuleOfPred != IDB_MODULE) {
680 if (ap->ArityOfPE) {
681 FuncAdjust(ap->FunctorOfPred);
682 } else {
683 AtomAdjust((Atom)(ap->FunctorOfPred));
684 }
685 } else {
686 if (ap->PredFlags & AtomDBPredFlag) {
687 AtomAdjust((Atom)(ap->FunctorOfPred));
688 } else if (!(ap->PredFlags & NumberDBPredFlag)) {
689 FuncAdjust(ap->FunctorOfPred);
690 }
691 }
692 if (!(ap->PredFlags & (MultiFileFlag | NumberDBPredFlag)) &&
693 ap->src.OwnerFile) {
694 AtomAdjust(ap->src.OwnerFile);
695 }
696 // fprintf(stderr, "> %lx %lx: ", ap->PredFlags, ap->PredFlags & ForeignPredFlags); (Yap_DebugWriteIndicator(ap));
697 CHECK(clean_pred(ap PASS_REGS));
698 return 1;
699}
700
701static size_t mark_ops(FILE *stream, Term mod) {
702 OpEntry *op = OpList;
703 while (op) {
704 if (!mod || op->OpModule == mod) {
705 AtomAdjust(op->OpName);
706 if (op->OpModule)
707 AtomTermAdjust(op->OpModule);
708 }
709 op = op->OpNext;
710 }
711 return 1;
712}
713
714static size_t save_ops(FILE *stream, Term mod) {
715 OpEntry *op = OpList;
716 while (op) {
717 if (!mod || op->OpModule == mod) {
718 CHECK(save_tag(stream, QLY_NEW_OP));
719 save_UInt(stream, (UInt)op->OpName);
720 save_UInt(stream, (UInt)op->OpModule);
721 save_bits16(stream, op->Prefix);
722 save_bits16(stream, op->Infix);
723 save_bits16(stream, op->Posfix);
724 }
725 op = op->OpNext;
726 }
727 CHECK(save_tag(stream, QLY_END_OPS));
728 return 1;
729}
730
731static size_t save_header(FILE *stream, char type[]) {
732 char msg[2048];
733
734 memset(msg, 0, 2048);
735 sprintf(msg,
736 "#!/bin/sh\nexec_dir=${YAPBINDIR:-%s}\nexec $exec_dir/yap $0 "
737 "\"$@\"\n%s %s\n",
738 YAP_BINDIR, type, YAP_FULL_VERSION);
739 return save_bytes(stream, msg, 2048);
740}
741
742static size_t save_module(FILE *stream, Term mod) {
743 PredEntry *ap = Yap_ModulePred(mod);
744 save_header(stream, "saved module,");
745 InitHash();
746 ModuleAdjust(mod);
747 while (ap) {
748 ap = PredEntryAdjust(ap);
749 CHECK(mark_pred(ap));
750 ap = ap->NextPredOfModule;
751 }
752 /* just to make sure */
753 mark_ops(stream, mod);
754 SaveHash(stream);
755 CHECK(save_tag(stream, QLY_START_MODULE));
756 CHECK(save_UInt(stream, (UInt)mod));
757 ap = Yap_ModulePred(mod);
758 while (ap) {
759 CHECK(save_tag(stream, QLY_START_PREDICATE));
760 CHECK(save_pred(stream, ap));
761 ap = ap->NextPredOfModule;
762 }
763 CHECK(save_tag(stream, QLY_END_PREDICATES));
764 CHECK(save_tag(stream, QLY_END_MODULES));
765 save_ops(stream, mod);
766 CloseHash();
767 return 1;
768}
769
770static size_t save_program(FILE *stream) {
771 ModEntry *me = CurrentModules;
772
773 InitHash();
774 save_header(stream, "saved state,");
775 /* should we allow the user to see hidden predicates? */
776 while (me) {
777 PredEntry *pp;
778 pp = me->PredForME;
779 AtomAdjust(me->AtomOfME);
780 while (pp != NULL) {
781#if DEBUG
782// Yap_PrintPredName( pp );
783#endif
784 pp = PredEntryAdjust(pp);
785 CHECK(mark_pred(pp));
786 pp = pp->NextPredOfModule;
787 }
788 me = me->NextME;
789 }
790
791 /* just to make sure */
792 mark_ops(stream, 0);
793 SaveHash(stream);
794 me = CurrentModules;
795 while (me) {
796 PredEntry *pp;
797 pp = me->PredForME;
798 CHECK(save_tag(stream, QLY_START_MODULE));
799 CHECK(save_UInt(stream, (UInt)MkAtomTerm(me->AtomOfME)));
800 while (pp != NULL) {
801 CHECK(save_tag(stream, QLY_START_PREDICATE));
802 CHECK(save_pred(stream, pp));
803 pp = pp->NextPredOfModule;
804 }
805 CHECK(save_tag(stream, QLY_END_PREDICATES));
806 me = me->NextME;
807 }
808 CHECK(save_tag(stream, QLY_END_MODULES));
809 save_ops(stream, 0);
810 CloseHash();
811 return 1;
812}
813
814static size_t save_file(FILE *stream, Atom FileName) {
815 ModEntry *me = CurrentModules;
816
817 InitHash();
818 save_header(stream, "saved file,");
819 /* should we allow the user to see hidden predicates? */
820 while (me) {
821 PredEntry *pp;
822 pp = me->PredForME;
823 AtomAdjust(me->AtomOfME);
824 while (pp != NULL) {
825 pp = PredEntryAdjust(pp);
826 if (pp &&
827 !(pp->PredFlags & (MultiFileFlag | NumberDBPredFlag | AtomDBPredFlag |
828 CPredFlag | AsmPredFlag | UserCPredFlag)) &&
829 pp->ModuleOfPred != IDB_MODULE && pp->src.OwnerFile == FileName) {
830 CHECK(mark_pred(pp));
831 }
832 pp = pp->NextPredOfModule;
833 }
834 me = me->NextME;
835 }
836
837 /* just to make sure */
838 mark_ops(stream, 0);
839 SaveHash(stream);
840 me = CurrentModules;
841 while (me) {
842 PredEntry *pp;
843 pp = me->PredForME;
844 CHECK(save_tag(stream, QLY_START_MODULE));
845 CHECK(save_UInt(stream, (UInt)MkAtomTerm(me->AtomOfME)));
846 while (pp != NULL) {
847 if (pp &&
848 !(pp->PredFlags & (MultiFileFlag | NumberDBPredFlag | AtomDBPredFlag |
849 CPredFlag | AsmPredFlag | UserCPredFlag)) &&
850 pp->src.OwnerFile == FileName) {
851 CHECK(save_tag(stream, QLY_START_PREDICATE));
852 CHECK(save_pred(stream, pp));
853 }
854 pp = pp->NextPredOfModule;
855 }
856 CHECK(save_tag(stream, QLY_END_PREDICATES));
857 me = me->NextME;
858 }
859 CHECK(save_tag(stream, QLY_END_MODULES));
860 save_ops(stream, 0);
861 CloseHash();
862 return 1;
863}
864
865static Int qsave_module_preds(USES_REGS1) {
866 FILE *stream;
867 Term tmod = Deref(ARG2);
868 Term t1 = Deref(ARG1);
869
870 if (IsVarTerm(t1)) {
871 Yap_Error(INSTANTIATION_ERROR, t1, "save_module/3");
872 return FALSE;
873 }
874 if (!IsAtomTerm(t1)) {
875 Yap_Error(TYPE_ERROR_ATOM, t1, "save_module/3");
876 return (FALSE);
877 }
878 if (!(stream = Yap_GetOutputStream(t1, "save_module"))) {
879 return FALSE;
880 }
881 if (IsVarTerm(tmod)) {
882 Yap_Error(INSTANTIATION_ERROR, tmod, "save_module/2");
883 return FALSE;
884 }
885 if (!IsAtomTerm(tmod)) {
886 Yap_Error(TYPE_ERROR_ATOM, tmod, "save_module/2");
887 return FALSE;
888 }
889 return save_module(stream, tmod) != 0;
890}
891
892static Int qsave_program(USES_REGS1) {
893 FILE *stream;
894 Term t1 = Deref(ARG1);
895
896 if (!(stream = Yap_GetOutputStream(t1, "save_program"))) {
897 return FALSE;
898 }
899 return save_program(stream) != 0;
900}
901
902static Int qsave_file(USES_REGS1) {
903 FILE *stream;
904 Term t1 = Deref(ARG1);
905 Term tfile = Deref(ARG2);
906
907 if (!(stream = Yap_GetOutputStream(t1, "save_file/2"))) {
908 return FALSE;
909 }
910 if (IsVarTerm(tfile)) {
911 Yap_Error(INSTANTIATION_ERROR, tfile, "save_file/2");
912 return FALSE;
913 }
914 if (!IsAtomTerm(tfile)) {
915 Yap_Error(TYPE_ERROR_ATOM, tfile, "save_file/2");
916 return FALSE;
917 }
918 return save_file(stream, AtomOfTerm(tfile)) != 0;
919}
920
921void Yap_InitQLY(void) {
922 Yap_InitCPred("$qsave_module_preds", 2, qsave_module_preds,
923 SyncPredFlag | UserCPredFlag);
924 Yap_InitCPred("$qsave_program", 1, qsave_program,
925 SyncPredFlag | UserCPredFlag);
926 Yap_InitCPred("$qsave_file_preds", 2, qsave_file,
927 SyncPredFlag | UserCPredFlag);
928 if (FALSE) {
929 restore_codes();
930 }
931}
932
load_foreign_files/3 has works for the following configurations:
Definition: qly.h:37
Definition: qly.h:82
Definition: qly.h:47
Definition: qly.h:66
Module property: low-level data used to manage modes.
Definition: Yatom.h:209
struct mod_entry * NextME
Module local flags (from SWI compat)
Definition: Yatom.h:220
Atom AtomOfME
index in operator table
Definition: Yatom.h:214
struct pred_entry * PredForME
kind of property
Definition: Yatom.h:212
Definition: Yatom.h:295
Definition: Yatom.h:544
Definition: amidefs.h:264