This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/C/qlyw.c

933 lines
24 KiB
C
Raw Permalink Normal View History

2011-08-09 12:11:23 +01:00
/*************************************************************************
2017-11-11 02:15:59 +00:00
* *
* YAP Prolog *
* *
* Yap Prolog was developed at NCCUP - Universidade do Porto *
* *
* Copyright L.Damas, V. Santos Costa and Universidade do Porto 1985-- *
* *
**************************************************************************
* *
* File: qlyw.c *
* comments: quick saver/loader *
* *
* Last rev: $Date: 2011-08-29$,$Author: vsc $ *
* $Log: not supported by cvs2svn $ *
* *
*************************************************************************/
2011-08-09 12:11:23 +01:00
2017-04-07 23:10:59 +01:00
/**
*
* @file qlyr.c
*
* @addtogroup SaveRestoreSupport
* @{
*
*/
2011-08-16 14:34:44 +01:00
#include "Foreign.h"
2017-11-11 02:15:59 +00:00
#include "absmi.h"
2011-08-16 14:34:44 +01:00
#include "alloc.h"
#include "attvar.h"
2017-11-11 02:15:59 +00:00
#include "iopreds.h"
#include "yapio.h"
2011-08-09 12:11:23 +01:00
#if HAVE_STRING_H
#include <string.h>
#endif
2011-08-24 04:11:54 +01:00
#include "qly.h"
2011-08-09 12:11:23 +01:00
2017-11-11 02:15:59 +00:00
static void RestoreEntries(PropEntry *, int USES_REGS);
static void CleanCode(PredEntry *USES_REGS);
2011-08-09 12:11:23 +01:00
2017-11-11 02:15:59 +00:00
static void GrowAtomTable(void) {
2012-08-23 15:04:58 +01:00
CACHE_REGS
2016-07-31 10:34:22 +01:00
UInt size = LOCAL_ExportAtomHashTableSize;
2012-08-23 15:04:58 +01:00
export_atom_hash_entry_t *p, *newt, *oldt = LOCAL_ExportAtomHashChain;
UInt new_size = size + (size > 1024 ? size : 1024);
UInt i;
2017-11-11 02:15:59 +00:00
newt = (export_atom_hash_entry_t *)calloc(new_size,
sizeof(export_atom_hash_entry_t));
2012-08-23 15:04:58 +01:00
if (!newt) {
return;
}
p = oldt;
2017-11-11 02:15:59 +00:00
for (i = 0; i < size; p++, i++) {
2012-08-23 15:04:58 +01:00
Atom a = p->val;
export_atom_hash_entry_t *newp;
CELL hash;
2015-09-21 23:05:36 +01:00
const unsigned char *apt;
2016-07-31 10:34:22 +01:00
2017-11-11 02:15:59 +00:00
if (!a)
continue;
2015-09-21 23:05:36 +01:00
apt = RepAtom(a)->UStrOfAE;
2017-11-11 02:15:59 +00:00
hash = HashFunction(apt) / (2 * sizeof(CELL)) % new_size;
newp = newt + hash;
2012-08-23 15:04:58 +01:00
while (newp->val) {
newp++;
2017-11-11 02:15:59 +00:00
if (newp == newt + new_size)
newp = newt;
2012-08-23 15:04:58 +01:00
}
newp->val = a;
}
LOCAL_ExportAtomHashChain = newt;
LOCAL_ExportAtomHashTableSize = new_size;
free(oldt);
}
2017-11-11 02:15:59 +00:00
static void LookupAtom(Atom at) {
2011-09-21 15:30:29 +01:00
CACHE_REGS
2015-09-21 23:05:36 +01:00
const unsigned char *p = RepAtom(at)->UStrOfAE;
2015-07-23 01:27:29 +01:00
CELL hash = HashFunction(p) % LOCAL_ExportAtomHashTableSize;
2011-08-16 14:34:44 +01:00
export_atom_hash_entry_t *a;
2011-08-09 12:11:23 +01:00
2017-11-11 02:15:59 +00:00
a = LOCAL_ExportAtomHashChain + hash;
2012-08-23 15:04:58 +01:00
while (a->val) {
2011-08-16 14:34:44 +01:00
if (a->val == at) {
return;
}
2012-08-23 15:04:58 +01:00
a++;
2017-11-11 02:15:59 +00:00
if (a == LOCAL_ExportAtomHashChain + LOCAL_ExportAtomHashTableSize)
2012-08-23 15:04:58 +01:00
a = LOCAL_ExportAtomHashChain;
2011-08-09 12:11:23 +01:00
}
2011-08-16 14:34:44 +01:00
a->val = at;
LOCAL_ExportAtomHashTableNum++;
2017-11-11 02:15:59 +00:00
if (LOCAL_ExportAtomHashTableNum > LOCAL_ExportAtomHashTableSize / 2) {
2012-08-23 15:04:58 +01:00
GrowAtomTable();
if (!LOCAL_ExportAtomHashChain) {
return;
}
}
}
2017-11-11 02:15:59 +00:00
static void GrowFunctorTable(void) {
2012-08-23 15:04:58 +01:00
CACHE_REGS
2016-07-31 10:34:22 +01:00
UInt size = LOCAL_ExportFunctorHashTableSize;
2012-08-23 15:04:58 +01:00
export_functor_hash_entry_t *p, *newt, *oldt = LOCAL_ExportFunctorHashChain;
UInt new_size = size + (size > 1024 ? size : 1024);
UInt i;
2017-11-11 02:15:59 +00:00
newt = (export_functor_hash_entry_t *)calloc(
new_size, sizeof(export_functor_hash_entry_t));
2012-08-23 15:04:58 +01:00
if (!newt) {
return;
}
p = oldt;
2017-11-11 02:15:59 +00:00
for (i = 0; i < size; p++, i++) {
2012-08-23 15:04:58 +01:00
Functor f = p->val;
export_functor_hash_entry_t *newp;
CELL hash;
2017-11-11 02:15:59 +00:00
if (!f)
continue;
hash = ((CELL)(f)) / (2 * sizeof(CELL)) % new_size;
newp = newt + hash;
2012-08-23 15:04:58 +01:00
while (newp->val) {
newp++;
2017-11-11 02:15:59 +00:00
if (newp == newt + new_size)
newp = newt;
2012-08-23 15:04:58 +01:00
}
newp->val = p->val;
newp->arity = p->arity;
newp->name = p->name;
}
LOCAL_ExportFunctorHashChain = newt;
LOCAL_ExportFunctorHashTableSize = new_size;
free(oldt);
2011-08-16 14:34:44 +01:00
}
2017-11-11 02:15:59 +00:00
static void LookupFunctor(Functor fun) {
2011-09-21 15:30:29 +01:00
CACHE_REGS
2017-11-11 02:15:59 +00:00
CELL hash =
((CELL)(fun)) / (2 * sizeof(CELL)) % LOCAL_ExportFunctorHashTableSize;
2011-08-16 14:34:44 +01:00
export_functor_hash_entry_t *f;
Atom name = NameOfFunctor(fun);
2017-11-11 02:15:59 +00:00
UInt arity = ArityOfFunctor(fun);
2011-08-16 14:34:44 +01:00
2017-11-11 02:15:59 +00:00
f = LOCAL_ExportFunctorHashChain + hash;
2012-08-23 15:04:58 +01:00
while (f->val) {
if (f->val == fun) {
2011-08-16 14:34:44 +01:00
return;
}
2012-08-23 15:04:58 +01:00
f++;
2017-11-11 02:15:59 +00:00
if (f == LOCAL_ExportFunctorHashChain + LOCAL_ExportFunctorHashTableSize)
2012-08-23 15:04:58 +01:00
f = LOCAL_ExportFunctorHashChain;
2011-08-16 14:34:44 +01:00
}
LookupAtom(name);
2011-08-24 04:11:54 +01:00
f->val = fun;
2011-08-16 14:34:44 +01:00
f->name = name;
f->arity = arity;
LOCAL_ExportFunctorHashTableNum++;
2017-11-11 02:15:59 +00:00
if (LOCAL_ExportFunctorHashTableNum > LOCAL_ExportFunctorHashTableSize / 2) {
2012-08-23 15:04:58 +01:00
GrowFunctorTable();
if (!LOCAL_ExportFunctorHashChain) {
return;
}
}
2011-08-09 12:11:23 +01:00
}
2017-11-11 02:15:59 +00:00
static void GrowPredTable(void) {
2012-08-23 15:04:58 +01:00
CACHE_REGS
2016-07-31 10:34:22 +01:00
UInt size = LOCAL_ExportPredEntryHashTableSize;
2017-11-11 02:15:59 +00:00
export_pred_entry_hash_entry_t *p, *newt,
*oldt = LOCAL_ExportPredEntryHashChain;
2012-08-23 00:57:13 +01:00
UInt new_size = size + (size > 1024 ? size : 1024);
UInt i;
2017-11-11 02:15:59 +00:00
newt = (export_pred_entry_hash_entry_t *)calloc(
new_size, sizeof(export_pred_entry_hash_entry_t));
2012-08-23 00:57:13 +01:00
if (!newt) {
return;
}
p = oldt;
2017-11-11 02:15:59 +00:00
for (i = 0; i < size; p++, i++) {
2012-08-23 00:57:13 +01:00
PredEntry *pe = p->val;
export_pred_entry_hash_entry_t *newp;
CELL hash;
2017-11-11 02:15:59 +00:00
if (!pe)
continue;
hash = ((CELL)(pe)) / (2 * sizeof(CELL)) % new_size;
newp = newt + hash;
2012-08-23 00:57:13 +01:00
while (newp->val) {
newp++;
2017-11-11 02:15:59 +00:00
if (newp == newt + new_size)
newp = newt;
2012-08-23 00:57:13 +01:00
}
newp->val = p->val;
newp->arity = p->arity;
newp->u_af.f = p->u_af.f;
2012-08-23 00:57:13 +01:00
newp->module = p->module;
}
LOCAL_ExportPredEntryHashChain = newt;
LOCAL_ExportPredEntryHashTableSize = new_size;
free(oldt);
}
2017-11-11 02:15:59 +00:00
static void LookupPredEntry(PredEntry *pe) {
2011-09-21 15:30:29 +01:00
CACHE_REGS
2017-11-11 02:15:59 +00:00
CELL hash =
(((CELL)(pe)) / (2 * sizeof(CELL))) % LOCAL_ExportPredEntryHashTableSize;
2011-08-24 04:11:54 +01:00
export_pred_entry_hash_entry_t *p;
2017-11-11 02:15:59 +00:00
UInt arity = pe->ArityOfPE;
2011-08-24 04:11:54 +01:00
2017-11-11 02:15:59 +00:00
p = LOCAL_ExportPredEntryHashChain + hash;
2012-08-23 00:57:13 +01:00
while (p->val) {
2011-08-24 04:11:54 +01:00
if (p->val == pe) {
return;
}
2012-08-23 00:57:13 +01:00
p++;
2017-11-11 02:15:59 +00:00
if (p ==
LOCAL_ExportPredEntryHashChain + LOCAL_ExportPredEntryHashTableSize)
2012-08-23 00:57:13 +01:00
p = LOCAL_ExportPredEntryHashChain;
2011-08-24 04:11:54 +01:00
}
p->arity = arity;
2011-08-24 12:40:06 +01:00
p->val = pe;
2011-08-28 01:23:14 +01:00
if (pe->ModuleOfPred != IDB_MODULE) {
if (arity) {
p->u_af.f = pe->FunctorOfPred;
2011-08-28 01:23:14 +01:00
LookupFunctor(pe->FunctorOfPred);
} else {
p->u_af.a = (Atom)(pe->FunctorOfPred);
2011-08-28 01:23:14 +01:00
LookupAtom((Atom)(pe->FunctorOfPred));
}
2011-08-24 04:11:54 +01:00
} else {
2011-08-28 01:23:14 +01:00
if (pe->PredFlags & AtomDBPredFlag) {
p->u_af.a = (Atom)(pe->FunctorOfPred);
2011-08-28 01:23:14 +01:00
p->arity = (CELL)(-2);
LookupAtom((Atom)(pe->FunctorOfPred));
} else if (!(pe->PredFlags & NumberDBPredFlag)) {
p->u_af.f = pe->FunctorOfPred;
2011-08-28 01:23:14 +01:00
p->arity = (CELL)(-1);
LookupFunctor(pe->FunctorOfPred);
} else {
p->u_af.f = pe->FunctorOfPred;
2011-08-28 01:23:14 +01:00
}
2011-08-24 04:11:54 +01:00
}
if (pe->ModuleOfPred) {
p->module = AtomOfTerm(pe->ModuleOfPred);
} else {
p->module = AtomProlog;
}
2011-08-24 12:40:06 +01:00
LookupAtom(p->module);
2011-08-24 04:11:54 +01:00
LOCAL_ExportPredEntryHashTableNum++;
2016-07-31 10:34:22 +01:00
if (LOCAL_ExportPredEntryHashTableNum >
2017-11-11 02:15:59 +00:00
LOCAL_ExportPredEntryHashTableSize / 2) {
2012-08-23 00:57:13 +01:00
GrowPredTable();
if (!LOCAL_ExportPredEntryHashChain) {
return;
}
}
2011-08-24 04:11:54 +01:00
}
2017-11-11 02:15:59 +00:00
static void GrowDBRefTable(void) {
2012-08-23 15:04:58 +01:00
CACHE_REGS
2016-07-31 10:34:22 +01:00
UInt size = LOCAL_ExportDBRefHashTableSize;
2012-08-23 15:04:58 +01:00
export_dbref_hash_entry_t *p, *newt, *oldt = LOCAL_ExportDBRefHashChain;
UInt new_size = size + (size > 1024 ? size : 1024);
UInt i;
2017-11-11 02:15:59 +00:00
newt = (export_dbref_hash_entry_t *)calloc(new_size,
sizeof(export_dbref_hash_entry_t));
2012-08-23 15:04:58 +01:00
if (!newt) {
return;
}
p = oldt;
2017-11-11 02:15:59 +00:00
for (i = 0; i < size; p++, i++) {
2012-08-23 15:04:58 +01:00
DBRef dbr = p->val;
export_dbref_hash_entry_t *newp;
CELL hash;
2017-11-11 02:15:59 +00:00
if (!dbr)
continue;
hash = ((CELL)(dbr)) / (2 * sizeof(CELL)) % new_size;
newp = newt + hash;
2012-08-23 15:04:58 +01:00
while (newp->val) {
newp++;
2017-11-11 02:15:59 +00:00
if (newp == newt + new_size)
newp = newt;
2012-08-23 15:04:58 +01:00
}
newp->val = p->val;
newp->sz = p->sz;
newp->refs = p->refs;
}
LOCAL_ExportDBRefHashChain = newt;
LOCAL_ExportDBRefHashTableSize = new_size;
free(oldt);
}
2017-11-11 02:15:59 +00:00
static void LookupDBRef(DBRef ref) {
2011-09-21 15:30:29 +01:00
CACHE_REGS
2017-11-11 02:15:59 +00:00
CELL hash =
((CELL)(ref)) / (2 * sizeof(CELL)) % LOCAL_ExportDBRefHashTableSize;
2011-08-31 21:59:30 +01:00
export_dbref_hash_entry_t *a;
2017-11-11 02:15:59 +00:00
a = LOCAL_ExportDBRefHashChain + hash;
2012-08-23 15:04:58 +01:00
while (a->val) {
2011-08-31 21:59:30 +01:00
if (a->val == ref) {
a->refs++;
return;
}
2012-08-23 15:04:58 +01:00
a++;
2017-11-11 02:15:59 +00:00
if (a == LOCAL_ExportDBRefHashChain + LOCAL_ExportDBRefHashTableSize)
2012-08-23 15:04:58 +01:00
a = LOCAL_ExportDBRefHashChain;
2011-08-31 21:59:30 +01:00
}
a->val = ref;
a->sz = ((LogUpdClause *)ref)->ClSize;
a->refs = 1;
LOCAL_ExportDBRefHashTableNum++;
2017-11-11 02:15:59 +00:00
if (LOCAL_ExportDBRefHashTableNum > LOCAL_ExportDBRefHashTableSize / 2) {
2012-08-23 15:04:58 +01:00
GrowDBRefTable();
if (!LOCAL_ExportDBRefHashChain) {
return;
}
}
2011-08-31 21:59:30 +01:00
}
2017-11-11 02:15:59 +00:00
static void InitHash(void) {
2011-09-21 15:30:29 +01:00
CACHE_REGS
2011-08-24 12:40:06 +01:00
LOCAL_ExportFunctorHashTableNum = 0;
2011-08-16 14:34:44 +01:00
LOCAL_ExportFunctorHashTableSize = EXPORT_FUNCTOR_TABLE_SIZE;
2017-11-11 02:15:59 +00:00
LOCAL_ExportFunctorHashChain = (export_functor_hash_entry_t *)calloc(
LOCAL_ExportFunctorHashTableSize, sizeof(export_functor_hash_entry_t));
2011-08-24 12:40:06 +01:00
LOCAL_ExportAtomHashTableNum = 0;
2011-08-16 14:34:44 +01:00
LOCAL_ExportAtomHashTableSize = EXPORT_ATOM_TABLE_SIZE;
2017-11-11 02:15:59 +00:00
LOCAL_ExportAtomHashChain = (export_atom_hash_entry_t *)calloc(
LOCAL_ExportAtomHashTableSize, sizeof(export_atom_hash_entry_t));
2011-08-24 12:40:06 +01:00
LOCAL_ExportPredEntryHashTableNum = 0;
2011-08-24 04:11:54 +01:00
LOCAL_ExportPredEntryHashTableSize = EXPORT_PRED_ENTRY_TABLE_SIZE;
2017-11-11 02:15:59 +00:00
LOCAL_ExportPredEntryHashChain = (export_pred_entry_hash_entry_t *)calloc(
LOCAL_ExportPredEntryHashTableSize,
sizeof(export_pred_entry_hash_entry_t));
2011-08-31 21:59:30 +01:00
LOCAL_ExportDBRefHashTableNum = 0;
LOCAL_ExportDBRefHashTableSize = EXPORT_DBREF_TABLE_SIZE;
2017-11-11 02:15:59 +00:00
LOCAL_ExportDBRefHashChain = (export_dbref_hash_entry_t *)calloc(
EXPORT_DBREF_TABLE_SIZE, sizeof(export_dbref_hash_entry_t));
2011-08-24 04:11:54 +01:00
}
2017-11-11 02:15:59 +00:00
static void CloseHash(void) {
2011-09-21 15:30:29 +01:00
CACHE_REGS
2011-08-24 12:40:06 +01:00
LOCAL_ExportFunctorHashTableNum = 0;
2011-08-24 04:11:54 +01:00
LOCAL_ExportFunctorHashTableSize = 0L;
free(LOCAL_ExportFunctorHashChain);
2011-08-24 12:40:06 +01:00
LOCAL_ExportAtomHashTableNum = 0;
2011-08-24 04:11:54 +01:00
LOCAL_ExportAtomHashTableSize = 0L;
free(LOCAL_ExportAtomHashChain);
2011-08-24 12:40:06 +01:00
LOCAL_ExportPredEntryHashTableNum = 0;
2011-08-24 04:11:54 +01:00
LOCAL_ExportPredEntryHashTableSize = 0L;
free(LOCAL_ExportPredEntryHashChain);
2011-08-31 21:59:30 +01:00
LOCAL_ExportDBRefHashTableNum = 0;
LOCAL_ExportDBRefHashTableSize = 0L;
free(LOCAL_ExportDBRefHashChain);
2011-08-09 12:11:23 +01:00
}
2017-11-11 02:15:59 +00:00
static inline Atom AtomAdjust(Atom a) {
2011-08-16 14:34:44 +01:00
LookupAtom(a);
return a;
2011-08-09 12:11:23 +01:00
}
2017-11-11 02:15:59 +00:00
static inline Functor FuncAdjust(Functor f) {
2011-08-16 14:34:44 +01:00
LookupFunctor(f);
return f;
2011-08-09 12:11:23 +01:00
}
2017-11-11 02:15:59 +00:00
static inline Term AtomTermAdjust(Term t) {
2011-08-16 14:34:44 +01:00
LookupAtom(AtomOfTerm(t));
2016-07-31 10:34:22 +01:00
return t;
2011-08-09 12:11:23 +01:00
}
2017-11-11 02:15:59 +00:00
static inline Term TermToGlobalOrAtomAdjust(Term t) {
2011-08-16 14:34:44 +01:00
if (t && IsAtomTerm(t))
return AtomTermAdjust(t);
return t;
2011-08-09 12:11:23 +01:00
}
2011-08-16 14:34:44 +01:00
#define IsOldCode(P) FALSE
#define IsOldCodeCellPtr(P) FALSE
#define IsOldDelay(P) FALSE
#define IsOldDelayPtr(P) FALSE
#define IsOldLocalInTR(P) FALSE
#define IsOldLocalInTRPtr(P) FALSE
#define IsOldGlobal(P) FALSE
#define IsOldGlobalPtr(P) FALSE
#define IsOldTrail(P) FALSE
#define IsOldTrailPtr(P) FALSE
#define CharP(X) ((char *)(X))
2016-07-31 10:34:22 +01:00
#define REINIT_LOCK(P)
#define REINIT_RWLOCK(P)
2011-08-16 14:34:44 +01:00
#define BlobTypeAdjust(P) (P)
#define NoAGCAtomAdjust(P) (P)
2016-07-31 10:34:22 +01:00
#define OrArgAdjust(P)
#define TabEntryAdjust(P)
2017-11-11 02:15:59 +00:00
#define IntegerAdjust(D) (D)
2011-08-16 14:34:44 +01:00
#define AddrAdjust(P) (P)
#define MFileAdjust(P) (P)
#define CodeVarAdjust(P) (P)
#define ConstantAdjust(P) (P)
#define ArityAdjust(P) (P)
2016-07-31 10:34:22 +01:00
#define DoubleInCodeAdjust(P)
#define IntegerInCodeAdjust(P)
2011-08-16 14:34:44 +01:00
#define OpcodeAdjust(P) (P)
2011-08-24 04:11:54 +01:00
2017-11-11 02:15:59 +00:00
static inline Term ModuleAdjust(Term t) {
if (!t)
return t;
2011-08-24 04:11:54 +01:00
return AtomTermAdjust(t);
}
2017-11-11 02:15:59 +00:00
static inline PredEntry *PredEntryAdjust(PredEntry *pe) {
2011-08-24 04:11:54 +01:00
LookupPredEntry(pe);
return pe;
}
2017-11-11 02:15:59 +00:00
static inline PredEntry *PtoPredAdjust(PredEntry *pe) {
2011-08-24 12:40:06 +01:00
LookupPredEntry(pe);
return pe;
}
2011-08-16 14:34:44 +01:00
#define ExternalFunctionAdjust(P) (P)
#define DBRecordAdjust(P) (P)
#define ModEntryPtrAdjust(P) (P)
#define AtomEntryAdjust(P) (P)
#define GlobalEntryAdjust(P) (P)
#define BlobTermInCodeAdjust(P) (P)
#define CellPtoHeapAdjust(P) (P)
#define PtoAtomHashEntryAdjust(P) (P)
#define CellPtoHeapCellAdjust(P) (P)
#define CellPtoTRAdjust(P) (P)
#define CodeAddrAdjust(P) (P)
#define ConsultObjAdjust(P) (P)
#define DelayAddrAdjust(P) (P)
#define DelayAdjust(P) (P)
#define GlobalAdjust(P) (P)
2011-08-31 21:59:30 +01:00
2017-11-11 02:15:59 +00:00
#define DBRefAdjust(P, DoRef) DBRefAdjust__(P PASS_REGS)
static inline DBRef DBRefAdjust__(DBRef dbt USES_REGS) {
2011-08-31 21:59:30 +01:00
LookupDBRef(dbt);
return dbt;
}
2011-08-16 14:34:44 +01:00
#define DBRefPAdjust(P) (P)
#define DBTermAdjust(P) (P)
#define LUIndexAdjust(P) (P)
#define SIndexAdjust(P) (P)
#define LocalAddrAdjust(P) (P)
#define GlobalAddrAdjust(P) (P)
#define OpListAdjust(P) (P)
#define PtoLUCAdjust(P) (P)
#define PtoStCAdjust(P) (P)
#define PtoArrayEAdjust(P) (P)
#define PtoArraySAdjust(P) (P)
#define PtoGlobalEAdjust(P) (P)
#define PtoDelayAdjust(P) (P)
#define PtoGloAdjust(P) (P)
#define PtoLocAdjust(P) (P)
#define PtoHeapCellAdjust(P) (P)
#define TermToGlobalAdjust(P) (P)
#define PtoOpAdjust(P) (P)
#define PtoLUClauseAdjust(P) (P)
#define PtoLUIndexAdjust(P) (P)
#define PtoDBTLAdjust(P) (P)
#define PtoPtoPredAdjust(P) (P)
#define OpRTableAdjust(P) (P)
#define OpEntryAdjust(P) (P)
#define PropAdjust(P) (P)
#define TrailAddrAdjust(P) (P)
#define XAdjust(P) (P)
#define YAdjust(P) (P)
#define HoldEntryAdjust(P) (P)
#define CodeCharPAdjust(P) (P)
2014-12-14 11:52:07 +00:00
#define CodeConstCharPAdjust(P) (P)
2011-08-16 14:34:44 +01:00
#define CodeVoidPAdjust(P) (P)
#define HaltHookAdjust(P) (P)
#define recompute_mask(dbr)
#define rehash(oldcode, NOfE, KindOfEntries)
2017-11-11 02:15:59 +00:00
static void RestoreFlags(UInt NFlags) {}
2015-08-07 22:57:53 +01:00
2011-08-16 14:34:44 +01:00
#include "rheap.h"
2017-11-11 02:15:59 +00:00
static void RestoreHashPreds(USES_REGS1) {}
2011-08-16 14:34:44 +01:00
2017-11-11 02:15:59 +00:00
static void RestoreAtomList(Atom atm USES_REGS) {}
2011-08-16 14:34:44 +01:00
2017-11-11 02:15:59 +00:00
static size_t save_bytes(FILE *stream, void *ptr, size_t sz) {
2015-06-19 00:34:14 +01:00
return fwrite(ptr, sz, 1, stream);
2011-08-09 12:11:23 +01:00
}
2017-11-11 02:15:59 +00:00
static size_t save_byte(FILE *stream, int byte) {
2015-06-19 00:34:14 +01:00
fputc(byte, stream);
2011-08-24 04:11:54 +01:00
return 1;
2011-08-09 12:11:23 +01:00
}
2017-11-11 02:15:59 +00:00
static size_t save_bits16(FILE *stream, BITS16 val) {
2011-08-28 01:23:14 +01:00
BITS16 v = val;
return save_bytes(stream, &v, sizeof(BITS16));
}
2017-11-11 02:15:59 +00:00
static size_t save_UInt(FILE *stream, UInt val) {
2011-08-16 14:34:44 +01:00
UInt v = val;
return save_bytes(stream, &v, sizeof(UInt));
2011-08-09 12:11:23 +01:00
}
2017-11-11 02:15:59 +00:00
static size_t save_Int(FILE *stream, Int val) {
Int v = val;
return save_bytes(stream, &v, sizeof(Int));
2011-08-24 04:11:54 +01:00
}
2017-11-11 02:15:59 +00:00
static size_t save_tag(FILE *stream, qlf_tag_t tag) {
2011-08-16 14:34:44 +01:00
return save_byte(stream, tag);
2011-08-09 12:11:23 +01:00
}
2017-11-11 02:15:59 +00:00
static size_t save_predFlags(FILE *stream, pred_flags_t predFlags) {
pred_flags_t v = predFlags;
return save_bytes(stream, &v, sizeof(pred_flags_t));
}
2017-11-11 02:15:59 +00:00
static int SaveHash(FILE *stream) {
2011-09-21 15:30:29 +01:00
CACHE_REGS
2011-08-09 12:11:23 +01:00
UInt i;
2011-08-24 04:11:54 +01:00
/* first, current opcodes */
CHECK(save_tag(stream, QLY_START_X));
save_UInt(stream, (UInt)&ARG1);
2011-08-24 04:11:54 +01:00
CHECK(save_tag(stream, QLY_START_OPCODES));
save_Int(stream, _std_top);
2017-11-11 02:15:59 +00:00
for (i = 0; i <= _std_top; i++) {
save_UInt(stream, (UInt)Yap_opcode(i));
2011-08-24 04:11:54 +01:00
}
CHECK(save_tag(stream, QLY_START_ATOMS));
CHECK(save_UInt(stream, LOCAL_ExportAtomHashTableNum));
2011-08-16 14:34:44 +01:00
for (i = 0; i < LOCAL_ExportAtomHashTableSize; i++) {
2017-11-11 02:15:59 +00:00
export_atom_hash_entry_t *a = LOCAL_ExportAtomHashChain + i;
2012-08-23 15:04:58 +01:00
if (a->val) {
2011-08-16 14:34:44 +01:00
Atom at = a->val;
CHECK(save_UInt(stream, (UInt)at));
2017-11-11 02:15:59 +00:00
CHECK(save_tag(stream, QLY_ATOM));
CHECK(save_UInt(stream, strlen((char *)RepAtom(at)->StrOfAE)));
CHECK(save_bytes(stream, (char *)at->StrOfAE,
(strlen((char *)at->StrOfAE) + 1) * sizeof(char)));
2011-08-16 14:34:44 +01:00
}
}
2011-08-24 04:11:54 +01:00
save_tag(stream, QLY_START_FUNCTORS);
save_UInt(stream, LOCAL_ExportFunctorHashTableNum);
2011-08-16 14:34:44 +01:00
for (i = 0; i < LOCAL_ExportFunctorHashTableSize; i++) {
2017-11-11 02:15:59 +00:00
export_functor_hash_entry_t *f = LOCAL_ExportFunctorHashChain + i;
2012-08-23 15:04:58 +01:00
if (!(f->val))
continue;
CHECK(save_UInt(stream, (UInt)(f->val)));
CHECK(save_UInt(stream, f->arity));
CHECK(save_UInt(stream, (CELL)(f->name)));
2011-08-09 12:11:23 +01:00
}
2011-08-24 04:11:54 +01:00
save_tag(stream, QLY_START_PRED_ENTRIES);
save_UInt(stream, LOCAL_ExportPredEntryHashTableNum);
2011-08-24 04:11:54 +01:00
for (i = 0; i < LOCAL_ExportPredEntryHashTableSize; i++) {
2017-11-11 02:15:59 +00:00
export_pred_entry_hash_entry_t *p = LOCAL_ExportPredEntryHashChain + i;
2012-08-23 00:57:13 +01:00
if (!(p->val))
continue;
CHECK(save_UInt(stream, (UInt)(p->val)));
CHECK(save_UInt(stream, p->arity));
CHECK(save_UInt(stream, (UInt)p->module));
CHECK(save_UInt(stream, (UInt)p->u_af.f));
2011-08-24 04:11:54 +01:00
}
2011-08-31 21:59:30 +01:00
save_tag(stream, QLY_START_DBREFS);
save_UInt(stream, LOCAL_ExportDBRefHashTableNum);
2011-08-31 21:59:30 +01:00
for (i = 0; i < LOCAL_ExportDBRefHashTableSize; i++) {
2017-11-11 02:15:59 +00:00
export_dbref_hash_entry_t *p = LOCAL_ExportDBRefHashChain + i;
2012-08-23 15:04:58 +01:00
if (p->val) {
CHECK(save_UInt(stream, (UInt)(p->val)));
CHECK(save_UInt(stream, p->sz));
CHECK(save_UInt(stream, p->refs));
2011-08-31 21:59:30 +01:00
}
}
save_tag(stream, QLY_FAILCODE);
save_UInt(stream, (UInt)FAILCODE);
2011-08-24 04:11:54 +01:00
return 1;
2011-08-09 12:11:23 +01:00
}
2017-11-11 02:15:59 +00:00
static size_t save_clauses(FILE *stream, PredEntry *pp) {
yamop *FirstC, *LastC;
2011-08-09 12:11:23 +01:00
FirstC = pp->cs.p_code.FirstClause;
LastC = pp->cs.p_code.LastClause;
if (FirstC == NULL && LastC == NULL) {
2011-08-24 04:11:54 +01:00
return 1;
2011-08-09 12:11:23 +01:00
}
if (pp->PredFlags & LogUpdatePredFlag) {
LogUpdClause *cl = ClauseCodeToLogUpdClause(FirstC);
while (cl != NULL) {
if (IN_BETWEEN(cl->ClTimeStart, pp->TimeStampOfPred, cl->ClTimeEnd)) {
2017-11-11 02:15:59 +00:00
UInt size = cl->ClSize;
CHECK(save_tag(stream, QLY_START_LU_CLAUSE));
CHECK(save_UInt(stream, (UInt)cl));
CHECK(save_UInt(stream, size));
CHECK(save_bytes(stream, cl, size));
2011-08-28 01:23:14 +01:00
}
2011-08-09 12:11:23 +01:00
cl = cl->ClNext;
}
2011-08-31 21:59:30 +01:00
CHECK(save_tag(stream, QLY_END_LU_CLAUSES));
2011-08-09 12:11:23 +01:00
} else if (pp->PredFlags & MegaClausePredFlag) {
MegaClause *cl = ClauseCodeToMegaClause(FirstC);
2011-08-16 14:34:44 +01:00
UInt size = cl->ClSize;
2011-08-09 12:11:23 +01:00
CHECK(save_UInt(stream, (UInt)cl));
CHECK(save_UInt(stream, (UInt)(cl->ClFlags)));
CHECK(save_UInt(stream, size));
2011-08-16 14:34:44 +01:00
CHECK(save_bytes(stream, cl, size));
2011-08-09 12:11:23 +01:00
} else if (pp->PredFlags & DynamicPredFlag) {
yamop *cl = FirstC;
do {
2011-08-16 14:34:44 +01:00
DynamicClause *dcl = ClauseCodeToDynamicClause(cl);
UInt size = dcl->ClSize;
CHECK(save_UInt(stream, (UInt)cl));
CHECK(save_UInt(stream, size));
2011-08-16 14:34:44 +01:00
CHECK(save_bytes(stream, dcl, size));
2017-11-11 02:15:59 +00:00
if (cl == LastC)
return 1;
2011-08-09 12:11:23 +01:00
cl = NextDynamicClause(cl);
} while (TRUE);
} else {
StaticClause *cl = ClauseCodeToStaticClause(FirstC);
2011-08-31 21:59:30 +01:00
if (pp->PredFlags & SYSTEM_PRED_FLAGS) {
return 1;
}
2011-08-09 12:11:23 +01:00
do {
2011-08-16 14:34:44 +01:00
UInt size = cl->ClSize;
CHECK(save_UInt(stream, (UInt)cl));
CHECK(save_UInt(stream, size));
2011-08-16 14:34:44 +01:00
CHECK(save_bytes(stream, cl, size));
2017-11-11 02:15:59 +00:00
if (cl->ClCode == LastC)
return 1;
2011-08-09 12:11:23 +01:00
cl = cl->ClNext;
} while (TRUE);
}
2011-08-24 04:11:54 +01:00
return 1;
2011-08-09 12:11:23 +01:00
}
2017-11-11 02:15:59 +00:00
static size_t save_pred(FILE *stream, PredEntry *ap) {
CHECK(save_UInt(stream, (UInt)ap));
CHECK(save_predFlags(stream, ap->PredFlags));
2016-01-03 02:06:09 +00:00
if (ap->PredFlags & ForeignPredFlags)
return 1;
CHECK(save_UInt(stream, ap->cs.p_code.NOfClauses));
CHECK(save_UInt(stream, ap->src.IndxId));
CHECK(save_UInt(stream, ap->TimeStampOfPred));
2011-08-09 12:11:23 +01:00
return save_clauses(stream, ap);
}
2017-11-11 02:15:59 +00:00
static int clean_pred(PredEntry *pp USES_REGS) {
2016-01-03 02:06:09 +00:00
if (pp->PredFlags & ForeignPredFlags) {
return true;
2011-08-16 14:34:44 +01:00
} else {
2017-11-11 02:15:59 +00:00
CleanClauses(pp->cs.p_code.FirstClause, pp->cs.p_code.LastClause,
pp PASS_REGS);
2011-08-16 14:34:44 +01:00
}
2016-07-31 10:34:22 +01:00
return true;
2011-08-16 14:34:44 +01:00
}
2017-11-11 02:15:59 +00:00
static size_t mark_pred(PredEntry *ap) {
2011-09-21 15:30:29 +01:00
CACHE_REGS
2011-08-28 01:23:14 +01:00
if (ap->ModuleOfPred != IDB_MODULE) {
if (ap->ArityOfPE) {
FuncAdjust(ap->FunctorOfPred);
} else {
AtomAdjust((Atom)(ap->FunctorOfPred));
}
} else {
if (ap->PredFlags & AtomDBPredFlag) {
AtomAdjust((Atom)(ap->FunctorOfPred));
} else if (!(ap->PredFlags & NumberDBPredFlag)) {
FuncAdjust(ap->FunctorOfPred);
}
}
2017-11-11 02:15:59 +00:00
if (!(ap->PredFlags & (MultiFileFlag | NumberDBPredFlag)) &&
2011-08-28 01:23:14 +01:00
ap->src.OwnerFile) {
AtomAdjust(ap->src.OwnerFile);
}
CHECK(clean_pred(ap PASS_REGS));
return 1;
}
2017-11-11 02:15:59 +00:00
static size_t mark_ops(FILE *stream, Term mod) {
2011-08-28 01:23:14 +01:00
OpEntry *op = OpList;
while (op) {
if (!mod || op->OpModule == mod) {
AtomAdjust(op->OpName);
if (op->OpModule)
2017-11-11 02:15:59 +00:00
AtomTermAdjust(op->OpModule);
2011-08-28 01:23:14 +01:00
}
op = op->OpNext;
}
return 1;
}
2017-11-11 02:15:59 +00:00
static size_t save_ops(FILE *stream, Term mod) {
2011-08-28 01:23:14 +01:00
OpEntry *op = OpList;
while (op) {
if (!mod || op->OpModule == mod) {
CHECK(save_tag(stream, QLY_NEW_OP));
save_UInt(stream, (UInt)op->OpName);
save_UInt(stream, (UInt)op->OpModule);
2011-08-28 01:23:14 +01:00
save_bits16(stream, op->Prefix);
save_bits16(stream, op->Infix);
save_bits16(stream, op->Posfix);
}
op = op->OpNext;
}
CHECK(save_tag(stream, QLY_END_OPS));
return 1;
}
2017-11-15 12:18:19 +00:00
static size_t save_header(FILE *stream, char type[]) {
char msg[2048];
2014-09-22 18:13:35 +01:00
2017-11-15 12:18:19 +00:00
memset(msg, 0, 2048);
2017-11-11 02:15:59 +00:00
sprintf(msg,
"#!/bin/sh\nexec_dir=${YAPBINDIR:-%s}\nexec $exec_dir/yap $0 "
"\"$@\"\n%s %s\n",
YAP_BINDIR, type, YAP_FULL_VERSION);
2017-11-15 12:18:19 +00:00
return save_bytes(stream, msg, 2048);
2014-09-22 18:13:35 +01:00
}
2017-11-11 02:15:59 +00:00
static size_t save_module(FILE *stream, Term mod) {
2011-08-09 12:11:23 +01:00
PredEntry *ap = Yap_ModulePred(mod);
2017-11-11 02:15:59 +00:00
save_header(stream, "saved module,");
2011-08-16 14:34:44 +01:00
InitHash();
2011-08-24 12:40:06 +01:00
ModuleAdjust(mod);
2011-08-16 14:34:44 +01:00
while (ap) {
ap = PredEntryAdjust(ap);
2011-08-28 01:23:14 +01:00
CHECK(mark_pred(ap));
2011-08-16 14:34:44 +01:00
ap = ap->NextPredOfModule;
}
2011-08-28 01:23:14 +01:00
/* just to make sure */
mark_ops(stream, mod);
2011-08-16 14:34:44 +01:00
SaveHash(stream);
2011-08-24 04:11:54 +01:00
CHECK(save_tag(stream, QLY_START_MODULE));
CHECK(save_UInt(stream, (UInt)mod));
2011-08-16 14:34:44 +01:00
ap = Yap_ModulePred(mod);
2011-08-09 12:11:23 +01:00
while (ap) {
2011-08-24 04:11:54 +01:00
CHECK(save_tag(stream, QLY_START_PREDICATE));
2011-08-09 12:11:23 +01:00
CHECK(save_pred(stream, ap));
ap = ap->NextPredOfModule;
}
2011-08-24 04:11:54 +01:00
CHECK(save_tag(stream, QLY_END_PREDICATES));
2011-08-28 01:23:14 +01:00
CHECK(save_tag(stream, QLY_END_MODULES));
save_ops(stream, mod);
CloseHash();
return 1;
}
2017-11-11 02:15:59 +00:00
static size_t save_program(FILE *stream) {
2014-09-22 18:13:35 +01:00
ModEntry *me = CurrentModules;
2011-08-31 21:59:30 +01:00
2014-09-22 18:13:35 +01:00
InitHash();
2017-11-11 02:15:59 +00:00
save_header(stream, "saved state,");
2014-09-22 18:13:35 +01:00
/* should we allow the user to see hidden predicates? */
while (me) {
PredEntry *pp;
pp = me->PredForME;
AtomAdjust(me->AtomOfME);
while (pp != NULL) {
2015-06-19 00:34:14 +01:00
#if DEBUG
2017-11-11 02:15:59 +00:00
// Yap_PrintPredName( pp );
2015-06-19 00:34:14 +01:00
#endif
2014-09-22 18:13:35 +01:00
pp = PredEntryAdjust(pp);
CHECK(mark_pred(pp));
pp = pp->NextPredOfModule;
}
me = me->NextME;
}
/* just to make sure */
mark_ops(stream, 0);
SaveHash(stream);
me = CurrentModules;
while (me) {
PredEntry *pp;
pp = me->PredForME;
CHECK(save_tag(stream, QLY_START_MODULE));
CHECK(save_UInt(stream, (UInt)MkAtomTerm(me->AtomOfME)));
while (pp != NULL) {
CHECK(save_tag(stream, QLY_START_PREDICATE));
CHECK(save_pred(stream, pp));
pp = pp->NextPredOfModule;
}
CHECK(save_tag(stream, QLY_END_PREDICATES));
me = me->NextME;
}
CHECK(save_tag(stream, QLY_END_MODULES));
save_ops(stream, 0);
CloseHash();
return 1;
2011-08-31 21:59:30 +01:00
}
2017-11-11 02:15:59 +00:00
static size_t save_file(FILE *stream, Atom FileName) {
2011-08-28 01:23:14 +01:00
ModEntry *me = CurrentModules;
InitHash();
2017-11-11 02:15:59 +00:00
save_header(stream, "saved file,");
2011-08-28 01:23:14 +01:00
/* should we allow the user to see hidden predicates? */
while (me) {
PredEntry *pp;
pp = me->PredForME;
AtomAdjust(me->AtomOfME);
2011-08-28 01:23:14 +01:00
while (pp != NULL) {
pp = PredEntryAdjust(pp);
2014-09-22 18:13:35 +01:00
if (pp &&
2017-11-11 02:15:59 +00:00
!(pp->PredFlags & (MultiFileFlag | NumberDBPredFlag | AtomDBPredFlag |
CPredFlag | AsmPredFlag | UserCPredFlag)) &&
pp->ModuleOfPred != IDB_MODULE && pp->src.OwnerFile == FileName) {
CHECK(mark_pred(pp));
2014-09-22 18:13:35 +01:00
}
2011-08-28 01:23:14 +01:00
pp = pp->NextPredOfModule;
}
me = me->NextME;
}
/* just to make sure */
mark_ops(stream, 0);
SaveHash(stream);
me = CurrentModules;
while (me) {
PredEntry *pp;
pp = me->PredForME;
CHECK(save_tag(stream, QLY_START_MODULE));
CHECK(save_UInt(stream, (UInt)MkAtomTerm(me->AtomOfME)));
2011-08-28 01:23:14 +01:00
while (pp != NULL) {
2014-10-02 14:57:50 +01:00
if (pp &&
2017-11-11 02:15:59 +00:00
!(pp->PredFlags & (MultiFileFlag | NumberDBPredFlag | AtomDBPredFlag |
CPredFlag | AsmPredFlag | UserCPredFlag)) &&
pp->src.OwnerFile == FileName) {
CHECK(save_tag(stream, QLY_START_PREDICATE));
CHECK(save_pred(stream, pp));
2014-10-02 14:57:50 +01:00
}
2011-08-28 01:23:14 +01:00
pp = pp->NextPredOfModule;
}
CHECK(save_tag(stream, QLY_END_PREDICATES));
me = me->NextME;
}
CHECK(save_tag(stream, QLY_END_MODULES));
save_ops(stream, 0);
2011-08-24 04:11:54 +01:00
CloseHash();
2011-08-09 12:11:23 +01:00
return 1;
}
2017-11-11 02:15:59 +00:00
static Int qsave_module_preds(USES_REGS1) {
2015-06-19 00:34:14 +01:00
FILE *stream;
2011-08-09 12:11:23 +01:00
Term tmod = Deref(ARG2);
Term t1 = Deref(ARG1);
2011-08-09 12:11:23 +01:00
if (IsVarTerm(t1)) {
2017-11-11 02:15:59 +00:00
Yap_Error(INSTANTIATION_ERROR, t1, "save_module/3");
return FALSE;
}
if (!IsAtomTerm(t1)) {
2017-11-11 02:15:59 +00:00
Yap_Error(TYPE_ERROR_ATOM, t1, "save_module/3");
return (FALSE);
}
2017-11-11 02:15:59 +00:00
if (!(stream = Yap_GetOutputStream(t1, "save_module"))) {
2011-08-09 12:11:23 +01:00
return FALSE;
}
if (IsVarTerm(tmod)) {
2017-11-11 02:15:59 +00:00
Yap_Error(INSTANTIATION_ERROR, tmod, "save_module/2");
2011-08-09 12:11:23 +01:00
return FALSE;
}
if (!IsAtomTerm(tmod)) {
2017-11-11 02:15:59 +00:00
Yap_Error(TYPE_ERROR_ATOM, tmod, "save_module/2");
2011-08-09 12:11:23 +01:00
return FALSE;
}
return save_module(stream, tmod) != 0;
}
2017-11-11 02:15:59 +00:00
static Int qsave_program(USES_REGS1) {
2015-06-19 00:34:14 +01:00
FILE *stream;
Term t1 = Deref(ARG1);
2011-08-28 01:23:14 +01:00
2017-11-11 02:15:59 +00:00
if (!(stream = Yap_GetOutputStream(t1, "save_program"))) {
2012-06-11 09:22:53 +01:00
return FALSE;
}
2011-08-28 01:23:14 +01:00
return save_program(stream) != 0;
}
2017-11-11 02:15:59 +00:00
static Int qsave_file(USES_REGS1) {
2015-06-19 00:34:14 +01:00
FILE *stream;
2014-09-22 18:13:35 +01:00
Term t1 = Deref(ARG1);
Term tfile = Deref(ARG2);
2017-11-11 02:15:59 +00:00
if (!(stream = Yap_GetOutputStream(t1, "save_file/2"))) {
2014-09-22 18:13:35 +01:00
return FALSE;
}
if (IsVarTerm(tfile)) {
2017-11-11 02:15:59 +00:00
Yap_Error(INSTANTIATION_ERROR, tfile, "save_file/2");
2014-09-22 18:13:35 +01:00
return FALSE;
}
if (!IsAtomTerm(tfile)) {
2017-11-11 02:15:59 +00:00
Yap_Error(TYPE_ERROR_ATOM, tfile, "save_file/2");
2014-09-22 18:13:35 +01:00
return FALSE;
}
2017-11-11 02:15:59 +00:00
return save_file(stream, AtomOfTerm(tfile)) != 0;
2014-09-22 18:13:35 +01:00
}
2017-11-11 02:15:59 +00:00
void Yap_InitQLY(void) {
Yap_InitCPred("$qsave_module_preds", 2, qsave_module_preds,
SyncPredFlag | UserCPredFlag);
Yap_InitCPred("$qsave_program", 1, qsave_program,
SyncPredFlag | UserCPredFlag);
Yap_InitCPred("$qsave_file_preds", 2, qsave_file,
SyncPredFlag | UserCPredFlag);
2011-09-01 14:20:21 +01:00
if (FALSE) {
restore_codes();
}
2011-08-09 12:11:23 +01:00
}
2017-04-07 23:10:59 +01:00
/// @}