2001-04-09 20:54:03 +01:00
/*************************************************************************
* *
* YAP Prolog *
* *
* Yap Prolog was developed at NCCUP - Universidade do Porto *
* *
* Copyright L . Damas , V . S . Costa and Universidade do Porto 1985 - 1997 *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* File : save . c *
* Last rev : *
* mods : *
* comments : saving and restoring a Prolog computation *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifdef SCCS
static char SccsId [ ] = " @(#)save.c 1.3 3/15/90 " ;
# endif
2002-06-01 02:46:06 +01:00
# if _MSC_VER || defined(__MINGW32__)
# include <windows.h>
# endif
2001-04-09 20:54:03 +01:00
# include "absmi.h"
# include "alloc.h"
# include "yapio.h"
# include "sshift.h"
# include "Foreign.h"
# if HAVE_STRING_H
# include <string.h>
# endif
# if !HAVE_STRNCAT
# define strncat(X,Y,Z) strcat(X,Y)
# endif
# if !HAVE_STRNCPY
# define strncpy(X,Y,Z) strcpy(X,Y)
# endif
# if HAVE_FCNTL_H
# include <fcntl.h>
# endif
# ifdef HAVE_UNISTD_H
# include <unistd.h>
# endif
2001-05-28 20:54:53 +01:00
# ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
# endif
# ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
# endif
2002-06-01 02:46:06 +01:00
# include "iopreds.h"
2001-04-09 20:54:03 +01:00
2002-06-01 02:46:06 +01:00
/********* hack for accesing several kinds of terms. Should be cleaned **/
2001-04-09 20:54:03 +01:00
2002-10-30 17:27:19 +00:00
static char StartUpFile [ ] = " startup " ;
2001-04-09 20:54:03 +01:00
static char end_msg [ 256 ] = " *** End of YAP saved state ***** " ;
2002-05-14 19:22:42 +01:00
2001-04-09 20:54:03 +01:00
# ifdef DEBUG
/*
2002-05-28 17:26:00 +01:00
*
# FOR DEBUGGING define DEBUG_RESTORE0 to check the file stuff,
# define DEBUG_RESTORE1 to see if it is able to prepare the chain,
# define DEBUG_RESTORE2 to see how things are going,
# define DEBUG_RESTORE3 to check if the atom chain is still a working chain,
2001-04-09 20:54:03 +01:00
* define DEBUG_RESTORE4 if you want to set the output for some
* particular file ,
* define DEBUG_RESTORE5 if you want to see how the stacks are being
* cleaned up ,
* define DEBUG_RESTORE6 if you want to follow the execution in
*
* Also a file is defined where you can write things , by default stderr
*
* Good Luck
*/
# endif
STATIC_PROTO ( void myread , ( int , char * , Int ) ) ;
STATIC_PROTO ( void mywrite , ( int , char * , Int ) ) ;
STATIC_PROTO ( int open_file , ( char * , int ) ) ;
STATIC_PROTO ( void close_file , ( void ) ) ;
STATIC_PROTO ( void putout , ( CELL ) ) ;
STATIC_PROTO ( void putcellptr , ( CELL * ) ) ;
STATIC_PROTO ( CELL get_cell , ( void ) ) ;
STATIC_PROTO ( CELL * get_cellptr , ( /* CELL * */ void ) ) ;
STATIC_PROTO ( void put_info , ( int , int ) ) ;
STATIC_PROTO ( void save_regs , ( int ) ) ;
STATIC_PROTO ( void save_code_info , ( void ) ) ;
STATIC_PROTO ( void save_heap , ( void ) ) ;
STATIC_PROTO ( void save_stacks , ( int ) ) ;
STATIC_PROTO ( void save_crc , ( void ) ) ;
STATIC_PROTO ( Int do_save , ( int ) ) ;
STATIC_PROTO ( Int p_save , ( void ) ) ;
STATIC_PROTO ( Int p_save_program , ( void ) ) ;
2002-10-30 17:27:19 +00:00
STATIC_PROTO ( int check_header , ( CELL * , CELL * , CELL * , CELL * ) ) ;
2001-04-09 20:54:03 +01:00
STATIC_PROTO ( void get_heap_info , ( void ) ) ;
STATIC_PROTO ( void get_regs , ( int ) ) ;
STATIC_PROTO ( void get_insts , ( OPCODE [ ] ) ) ;
STATIC_PROTO ( void get_hash , ( void ) ) ;
STATIC_PROTO ( void CopyCode , ( void ) ) ;
STATIC_PROTO ( void CopyStacks , ( void ) ) ;
STATIC_PROTO ( int get_coded , ( int , OPCODE [ ] ) ) ;
STATIC_PROTO ( void restore_codes , ( void ) ) ;
STATIC_PROTO ( void ConvDBList , ( Term , char * , CELL ) ) ;
STATIC_PROTO ( Term AdjustDBTerm , ( Term ) ) ;
STATIC_PROTO ( void RestoreDB , ( DBEntry * ) ) ;
2002-06-04 19:21:55 +01:00
STATIC_PROTO ( void RestoreClause , ( Clause * , int ) ) ;
2001-04-09 20:54:03 +01:00
STATIC_PROTO ( void CleanClauses , ( CODEADDR , CODEADDR ) ) ;
STATIC_PROTO ( void rehash , ( CELL * , int , int ) ) ;
STATIC_PROTO ( void CleanCode , ( PredEntry * ) ) ;
STATIC_PROTO ( void RestoreEntries , ( PropEntry * ) ) ;
STATIC_PROTO ( void RestoreInvisibleAtoms , ( void ) ) ;
STATIC_PROTO ( void RestoreFreeSpace , ( void ) ) ;
STATIC_PROTO ( void restore_heap , ( void ) ) ;
# ifdef DEBUG_RESTORE3
STATIC_PROTO ( void ShowAtoms , ( void ) ) ;
STATIC_PROTO ( void ShowEntries , ( PropEntry * ) ) ;
# endif
2002-10-30 17:27:19 +00:00
STATIC_PROTO ( int OpenRestore , ( char * , char * , CELL * , CELL * , CELL * , CELL * ) ) ;
2001-04-09 20:54:03 +01:00
STATIC_PROTO ( void CloseRestore , ( void ) ) ;
STATIC_PROTO ( int check_opcodes , ( OPCODE [ ] ) ) ;
STATIC_PROTO ( void RestoreHeap , ( OPCODE [ ] , int ) ) ;
STATIC_PROTO ( Int p_restore , ( void ) ) ;
STATIC_PROTO ( void restore_heap_regs , ( void ) ) ;
STATIC_PROTO ( void restore_regs , ( int ) ) ;
STATIC_PROTO ( void ConvDBStruct , ( Term , char * , CELL ) ) ;
# ifdef MACYAP
STATIC_PROTO ( void NewFileInfo , ( long , long ) ) ;
extern int DefVol ;
# endif
2001-05-28 20:54:53 +01:00
# if HAVE_IO_H
2001-04-09 20:54:03 +01:00
# include <io.h>
# endif
# ifdef LIGHT
# include <unix.h>
# include <strings.h>
void
LightBug ( char * ) ;
static void
LightBug ( s )
char * s ;
{
}
# endif /* LIGHT */
# if SHORT_INTS
# ifdef M_WILLIAMS
# include <fcntl.h>
# endif
static void
myread ( int fd , char * buff , Int len )
{
while ( len > 16000 ) {
int nchars = read ( fd , buff , 16000 ) ;
if ( nchars < = 0 )
2002-11-18 18:18:05 +00:00
Yap_Error ( FATAL_ERROR , TermNil , " bad saved state, system corrupted " ) ;
2001-04-09 20:54:03 +01:00
len - = 16000 ;
buff + = 16000 ;
}
read ( fd , buff , ( unsigned ) len ) ;
}
static void
mywrite ( int fd , char * buff , Int len )
{
while ( len > 16000 ) {
write ( fd , buff , 16000 ) ;
len - = 16000 ;
buff + = 16000 ;
}
write ( fd , buff , ( unsigned ) len ) ;
}
# else /* SHORT_INTS */
inline static
void myread ( int fd , char * buffer , Int len ) {
int nread ;
while ( len > 0 ) {
nread = read ( fd , buffer , ( int ) len ) ;
if ( nread < 1 ) {
2002-11-18 18:18:05 +00:00
Yap_Error ( FATAL_ERROR , TermNil , " bad saved state, system corrupted " ) ;
2001-04-09 20:54:03 +01:00
}
buffer + = nread ;
len - = nread ;
}
}
inline static
void mywrite ( int fd , char * buff , Int len ) {
Int nwritten ;
while ( len > 0 ) {
nwritten = ( Int ) write ( fd , buff , ( int ) len ) ;
if ( nwritten = = - 1 ) {
2002-11-18 18:18:05 +00:00
Yap_Error ( SYSTEM_ERROR , TermNil , " write error while saving " ) ;
2001-04-09 20:54:03 +01:00
}
buff + = nwritten ;
len - = nwritten ;
}
}
# endif /* SHORT_INTS */
# define FullSaved 1
/* Where the code was before */
typedef CELL * CELLPOINTER ;
2002-11-11 17:38:10 +00:00
static int splfild = 0 ;
2001-04-09 20:54:03 +01:00
# ifdef DEBUG
# ifdef DEBUG_RESTORE4
static FILE * errout ;
# else
2002-11-18 18:18:05 +00:00
# define errout Yap_stderr
2001-04-09 20:54:03 +01:00
# endif
# endif /* DEBUG */
static Int OldHeapUsed ;
static CELL which_save ;
/* Open a file to read or to write */
static int
2002-11-11 17:38:10 +00:00
open_file ( char * my_file , int flag )
2001-04-09 20:54:03 +01:00
{
int splfild ;
# ifdef M_WILLIAMS
if ( flag & O_CREAT )
2002-11-11 17:38:10 +00:00
splfild = creat ( my_file , flag ) ;
2001-04-09 20:54:03 +01:00
else
2002-11-11 17:38:10 +00:00
splfild = open ( my_file , flag ) ;
2001-04-09 20:54:03 +01:00
if ( splfild < 0 ) {
# else
# ifdef O_BINARY
# if _MSC_VER
2002-11-11 17:38:10 +00:00
if ( ( splfild = _open ( my_file , flag | O_BINARY ) , _S_IREAD | _S_IWRITE ) < 0 )
2001-04-09 20:54:03 +01:00
# else
2002-11-11 17:38:10 +00:00
if ( ( splfild = open ( my_file , flag | O_BINARY , 0775 ) ) < 0 )
2001-04-09 20:54:03 +01:00
# endif
# else /* O_BINARY */
2002-11-11 17:38:10 +00:00
if ( ( splfild = open ( my_file , flag , 0755 ) ) < 0 )
2001-04-09 20:54:03 +01:00
# endif /* O_BINARY */
# endif /* M_WILLIAMS */
{
splfild = 0 ; /* We do not have an open file */
return ( - 1 ) ;
}
# ifdef undf0
2002-11-11 17:38:10 +00:00
fprintf ( errout , " Opened file %s \n " , my_file ) ;
2001-04-09 20:54:03 +01:00
# endif
return ( splfild ) ;
}
static void
close_file ( void )
{
2002-10-30 17:27:19 +00:00
if ( splfild = = 0 )
return ;
2001-04-09 20:54:03 +01:00
close ( splfild ) ;
splfild = 0 ;
}
/* stores a cell in a file */
static void
putout ( CELL l )
{
2002-10-30 17:27:19 +00:00
mywrite ( splfild , ( char * ) & l , sizeof ( CELL ) ) ;
2001-04-09 20:54:03 +01:00
}
/* stores a pointer to a cell in a file */
static void
putcellptr ( CELL * l )
{
2002-10-30 17:27:19 +00:00
mywrite ( splfild , ( char * ) & l , sizeof ( CELLPOINTER ) ) ;
2001-04-09 20:54:03 +01:00
}
/* gets a cell from a file */
static CELL
get_cell ( void )
{
2002-10-30 17:27:19 +00:00
CELL l ;
myread ( splfild , ( char * ) & l , Unsigned ( sizeof ( CELL ) ) ) ;
return ( l ) ;
}
/* gets a cell from a file */
static CELL
get_header_cell ( void )
{
CELL l ;
int count = 0 , n ;
while ( count < sizeof ( CELL ) ) {
if ( ( n = read ( splfild , & l , sizeof ( CELL ) - count ) ) < 0 ) {
2002-11-18 18:18:05 +00:00
Yap_ErrorMessage = " corrupt saved state " ;
2002-10-30 17:27:19 +00:00
return ( 0L ) ;
}
count + = n ;
}
return ( l ) ;
2001-04-09 20:54:03 +01:00
}
/* gets a pointer to cell from a file */
static CELL *
get_cellptr ( void )
{
2002-10-30 17:27:19 +00:00
CELL * l ;
myread ( splfild , ( char * ) & l , Unsigned ( sizeof ( CELLPOINTER ) ) ) ;
return ( l ) ;
2001-04-09 20:54:03 +01:00
}
/*
* writes the header ( at the moment YAPV * ) , info about what kind of saved
* set , the work size , and the space ocuppied
*/
static void
put_info ( int info , int mode )
{
char msg [ 256 ] ;
2002-11-11 17:38:10 +00:00
sprintf ( msg , " #!/bin/sh \n exec_dir=${YAPBINDIR:-%s} \n exec $exec_dir/yap $0 \" $@ \" \n %cYAPV%s " , BIN_DIR , 1 , YAP_VERSION ) ;
2001-04-09 20:54:03 +01:00
mywrite ( splfild , msg , strlen ( msg ) + 1 ) ;
putout ( Unsigned ( info ) ) ;
/* say whether we just saved the heap or everything */
putout ( mode ) ;
2002-10-30 17:27:19 +00:00
/* c-predicates in system */
2002-11-11 17:38:10 +00:00
putout ( NumberOfCPreds ) ;
2002-10-30 17:27:19 +00:00
/* comparison predicates in system */
2002-11-11 17:38:10 +00:00
putout ( NumberOfCmpFuncs ) ;
2001-04-09 20:54:03 +01:00
/* current state of stacks, to be used by SavedInfo */
# if defined(YAPOR) || defined(TABLING)
/* space available in heap area */
2002-11-18 18:18:05 +00:00
putout ( Unsigned ( Yap_GlobalBase ) - Unsigned ( Yap_HeapBase ) ) ;
2001-04-09 20:54:03 +01:00
/* space available for stacks */
2002-11-18 18:18:05 +00:00
putout ( Unsigned ( Yap_LocalBase ) - Unsigned ( Yap_GlobalBase ) + CellSize ) ;
2001-04-09 20:54:03 +01:00
# else
/* space available in heap area */
2002-11-18 18:18:05 +00:00
putout ( Unsigned ( Yap_GlobalBase ) - Unsigned ( Yap_HeapBase ) ) ;
2001-04-09 20:54:03 +01:00
/* space available for stacks */
2002-11-18 18:18:05 +00:00
putout ( Unsigned ( Yap_LocalBase ) - Unsigned ( Yap_GlobalBase ) ) ;
2001-04-09 20:54:03 +01:00
# endif /* YAPOR || TABLING */
/* space available for trail */
2002-11-18 18:18:05 +00:00
putout ( Unsigned ( Yap_TrailTop ) - Unsigned ( Yap_TrailBase ) ) ;
2001-04-09 20:54:03 +01:00
/* Space used in heap area */
2002-11-18 18:18:05 +00:00
putout ( Unsigned ( HeapTop ) - Unsigned ( Yap_HeapBase ) ) ;
2001-04-09 20:54:03 +01:00
/* Space used for local stack */
putout ( Unsigned ( LCL0 ) - Unsigned ( ASP ) ) ;
/* Space used for global stack */
2002-11-18 18:18:05 +00:00
putout ( Unsigned ( H ) - Unsigned ( Yap_GlobalBase ) ) ;
2001-04-09 20:54:03 +01:00
/* Space used for trail */
2002-11-18 18:18:05 +00:00
putout ( Unsigned ( TR ) - Unsigned ( Yap_TrailBase ) ) ;
2001-04-09 20:54:03 +01:00
}
static void
save_regs ( int mode )
{
/* save all registers */
putout ( ( CELL ) compile_arrays ) ;
if ( mode = = DO_EVERYTHING ) {
putcellptr ( ( CELL * ) CP ) ;
putcellptr ( ENV ) ;
putcellptr ( ASP ) ;
/* putout((CELL)N); */
putcellptr ( H0 ) ;
putcellptr ( LCL0 ) ;
putcellptr ( H ) ;
putcellptr ( HB ) ;
putcellptr ( ( CELL * ) B ) ;
putcellptr ( ( CELL * ) TR ) ;
putcellptr ( YENV ) ;
putcellptr ( S ) ;
putcellptr ( ( CELL * ) P ) ;
putcellptr ( ( CELL * ) MyTR ) ;
putout ( CreepFlag ) ;
putout ( FlipFlop ) ;
2002-05-14 19:22:42 +01:00
putout ( EX ) ;
2001-04-09 20:54:03 +01:00
# ifdef COROUTINING
putout ( DelayedVars ) ;
# endif
}
2002-05-14 19:22:42 +01:00
putout ( CurrentModule ) ;
2001-04-09 20:54:03 +01:00
putcellptr ( ( CELL * ) HeapPlus ) ;
if ( mode = = DO_EVERYTHING ) {
# ifdef COROUTINING
putout ( WokenGoals ) ;
# endif
# ifdef DEPTH_LIMIT
putout ( DEPTH ) ;
# endif
}
/* The operand base */
putcellptr ( CellPtr ( XREGS ) ) ;
putout ( which_save ) ;
/* Now start by saving the code */
/* the heap boundaries */
2002-11-18 18:18:05 +00:00
putcellptr ( CellPtr ( Yap_HeapBase ) ) ;
2001-04-09 20:54:03 +01:00
putcellptr ( CellPtr ( HeapTop ) ) ;
/* and the space it ocuppies */
putout ( Unsigned ( HeapUsed ) ) ;
/* Then the start of the free code */
putcellptr ( CellPtr ( FreeBlocks ) ) ;
if ( mode = = DO_EVERYTHING ) {
/* put the old trail base, just in case it moves again */
putout ( ARG1 ) ;
if ( which_save = = 2 ) {
putout ( ARG2 ) ;
}
2002-11-18 18:18:05 +00:00
putcellptr ( CellPtr ( Yap_TrailBase ) ) ;
2001-04-09 20:54:03 +01:00
}
}
static void
save_code_info ( void )
{
/* First the instructions */
{
op_numbers i ;
OPCODE my_ops [ _std_top + 1 ] ;
for ( i = _Ystop ; i < = _std_top ; + + i )
2002-11-18 18:18:05 +00:00
my_ops [ i ] = Yap_opcode ( i ) ;
2001-04-09 20:54:03 +01:00
mywrite ( splfild , ( char * ) my_ops , sizeof ( OPCODE ) * ( _std_top + 1 ) ) ;
}
/* Then the c-functions */
2002-11-11 17:38:10 +00:00
putout ( NumberOfCPreds ) ;
2001-04-09 20:54:03 +01:00
{
UInt i ;
2002-11-11 17:38:10 +00:00
for ( i = 0 ; i < NumberOfCPreds ; + + i )
2002-11-18 18:18:05 +00:00
putcellptr ( CellPtr ( Yap_c_predicates [ i ] ) ) ;
2001-04-09 20:54:03 +01:00
}
/* Then the cmp-functions */
2002-11-11 17:38:10 +00:00
putout ( NumberOfCmpFuncs ) ;
2001-04-09 20:54:03 +01:00
{
UInt i ;
2002-11-11 17:38:10 +00:00
for ( i = 0 ; i < NumberOfCmpFuncs ; + + i ) {
2002-11-18 18:18:05 +00:00
putcellptr ( CellPtr ( Yap_cmp_funcs [ i ] . p ) ) ;
putcellptr ( CellPtr ( Yap_cmp_funcs [ i ] . f ) ) ;
2001-04-09 20:54:03 +01:00
}
}
/* and the current character codes */
2002-11-18 18:18:05 +00:00
mywrite ( splfild , Yap_chtype , NUMBER_OF_CHARS ) ;
2001-04-09 20:54:03 +01:00
}
static void
save_heap ( void )
{
int j ;
/* Then save the whole heap */
# if defined(YAPOR) || defined(TABLING)
/* skip the local and global data structures */
2002-11-18 18:18:05 +00:00
j = Unsigned ( & GLOBAL ) - Unsigned ( Yap_HeapBase ) ;
2001-04-09 20:54:03 +01:00
putout ( j ) ;
2002-11-18 18:18:05 +00:00
mywrite ( splfild , ( char * ) Yap_HeapBase , j ) ;
2001-04-09 20:54:03 +01:00
# ifdef USE_HEAP
j = Unsigned ( HeapTop ) - Unsigned ( & HashChain ) ;
putout ( j ) ;
mywrite ( splfild , ( char * ) & HashChain , j ) ;
# else
j = Unsigned ( BaseAllocArea ) - Unsigned ( & HashChain ) ;
putout ( j ) ;
mywrite ( splfild , ( char * ) & HashChain , j ) ;
j = Unsigned ( HeapTop ) - Unsigned ( TopAllocBlockArea ) ;
putout ( j ) ;
mywrite ( splfild , ( char * ) TopAllocBlockArea , j ) ;
# endif
# else
2002-11-18 18:18:05 +00:00
j = Unsigned ( HeapTop ) - Unsigned ( Yap_HeapBase ) ;
2001-04-09 20:54:03 +01:00
/* store 10 more cells because of the memory manager */
2002-11-18 18:18:05 +00:00
mywrite ( splfild , ( char * ) Yap_HeapBase , j ) ;
2001-04-09 20:54:03 +01:00
# endif
}
static void
save_stacks ( int mode )
{
int j ;
switch ( mode ) {
case DO_EVERYTHING :
/* Now, go and save the state */
/* Save the local stack */
j = Unsigned ( LCL0 ) - Unsigned ( ASP ) ;
mywrite ( splfild , ( char * ) ASP , j ) ;
/* Save the global stack */
2002-11-18 18:18:05 +00:00
j = Unsigned ( H ) - Unsigned ( Yap_GlobalBase ) ;
mywrite ( splfild , ( char * ) Yap_GlobalBase , j ) ;
2001-04-09 20:54:03 +01:00
/* Save the trail */
2002-11-18 18:18:05 +00:00
j = Unsigned ( TR ) - Unsigned ( Yap_TrailBase ) ;
mywrite ( splfild , ( char * ) Yap_TrailBase , j ) ;
2001-04-09 20:54:03 +01:00
break ;
case DO_ONLY_CODE :
{
tr_fr_ptr tr_ptr = TR ;
2002-11-18 18:18:05 +00:00
while ( tr_ptr ! = ( tr_fr_ptr ) Yap_TrailBase ) {
2001-04-09 20:54:03 +01:00
CELL val = TrailTerm ( tr_ptr - 1 ) ;
2001-12-17 18:31:11 +00:00
if ( IsVarTerm ( val ) ) {
CELL * d1 = VarOfTerm ( val ) ;
if ( d1 < ( CELL * ) HeapTop )
putout ( val ) ;
} else if ( IsPairTerm ( val ) ) {
2001-04-09 20:54:03 +01:00
CELL * d1 = RepPair ( val ) ;
if ( d1 < ( CELL * ) HeapTop )
2001-12-17 18:31:11 +00:00
putout ( val ) ;
2001-04-09 20:54:03 +01:00
}
tr_ptr - - ;
}
}
putcellptr ( NULL ) ;
break ;
}
}
static void
save_crc ( void )
{
/* Save a CRC */
mywrite ( splfild , end_msg , 256 ) ;
# ifdef MACYAP
NewFileInfo ( ' TEXT ' , ' MYap ' ) ;
if ( DefVol )
SetVol ( 0l , DefVol ) ;
DefVol = 0 ;
# endif
}
static Int
do_save ( int mode ) {
# ifdef MACYAP
NewFileInfo ( ' YAPS ' , ' MYap ' ) ;
# endif
Term t1 = Deref ( ARG1 ) ;
2002-11-18 18:18:05 +00:00
if ( ! Yap_GetName ( Yap_FileNameBuf , YAP_FILENAME_MAX , t1 ) ) {
Yap_Error ( TYPE_ERROR_LIST , t1 , " save/1 " ) ;
2001-04-09 20:54:03 +01:00
return ( FALSE ) ;
}
2002-11-18 18:18:05 +00:00
Yap_CloseStreams ( TRUE ) ;
if ( ( splfild = open_file ( Yap_FileNameBuf , O_WRONLY | O_CREAT ) ) < 0 ) {
Yap_Error ( SYSTEM_ERROR , MkAtomTerm ( Yap_LookupAtom ( Yap_FileNameBuf ) ) ,
2001-04-09 20:54:03 +01:00
" restore/1, open(%s) " , strerror ( errno ) ) ;
return ( FALSE ) ;
}
put_info ( FullSaved , mode ) ;
save_regs ( mode ) ;
save_code_info ( ) ;
save_heap ( ) ;
save_stacks ( mode ) ;
save_crc ( ) ;
close_file ( ) ;
return ( TRUE ) ;
}
/* Saves a complete prolog environment */
static Int
p_save ( void )
{
2002-10-22 04:45:24 +01:00
# if defined(YAPOR) || defined(THREADS)
2002-10-21 23:52:36 +01:00
if ( NOfThreads ! = 1 ) {
2002-11-18 18:18:05 +00:00
Yap_Error ( SYSTEM_ERROR , TermNil , " cannot perform save: more than a worker/thread running " ) ;
2002-10-21 23:52:36 +01:00
return ( FALSE ) ;
}
2002-10-22 04:45:24 +01:00
# endif
2001-04-09 20:54:03 +01:00
which_save = 1 ;
return ( do_save ( DO_EVERYTHING ) ) ;
}
/* Saves a complete prolog environment */
static Int
p_save2 ( void )
{
2002-10-22 04:45:24 +01:00
# if defined(YAPOR) || defined(THREADS)
2002-10-21 23:52:36 +01:00
if ( NOfThreads ! = 1 ) {
2002-11-18 18:18:05 +00:00
Yap_Error ( SYSTEM_ERROR , TermNil ,
2002-11-11 17:38:10 +00:00
" cannot perform save: more than a worker/thread running " ) ;
2002-10-21 23:52:36 +01:00
return ( FALSE ) ;
}
2002-10-22 04:45:24 +01:00
# endif
2001-04-09 20:54:03 +01:00
which_save = 2 ;
2002-11-18 18:18:05 +00:00
return ( do_save ( DO_EVERYTHING ) & & Yap_unify ( ARG2 , MkIntTerm ( 1 ) ) ) ;
2001-04-09 20:54:03 +01:00
}
/* Just save the program, not the stacks */
static Int
p_save_program ( void )
{
which_save = 0 ;
return ( do_save ( DO_ONLY_CODE ) ) ;
}
/* Now, to restore the saved code */
/* First check out if we are dealing with a valid file */
static int
2002-10-30 17:27:19 +00:00
check_header ( CELL * info , CELL * ATrail , CELL * AStack , CELL * AHeap )
2001-04-09 20:54:03 +01:00
{
char pp [ 80 ] ;
char msg [ 256 ] ;
2002-10-30 17:27:19 +00:00
CELL hp_size , gb_size , lc_size , tr_size , mode , c_preds , cmp_funcs ;
2001-04-09 20:54:03 +01:00
2002-10-30 17:27:19 +00:00
/* make sure we always check if there are enough bytes */
2001-04-09 20:54:03 +01:00
/* skip the first line */
do {
2002-10-30 17:27:19 +00:00
if ( read ( splfild , pp , 1 ) < 0 ) {
2002-11-18 18:18:05 +00:00
Yap_ErrorMessage = " corrupt saved state " ;
2002-10-30 17:27:19 +00:00
return ( FAIL_RESTORE ) ;
}
2001-04-09 20:54:03 +01:00
} while ( pp [ 0 ] ! = 1 ) ;
/* now check the version */
2002-11-11 17:38:10 +00:00
sprintf ( msg , " YAPV%s " , YAP_VERSION ) ;
2002-10-30 17:27:19 +00:00
{
int count = 0 , n , to_read = Unsigned ( strlen ( msg ) + 1 ) ;
while ( count < to_read ) {
if ( ( n = read ( splfild , pp , to_read - count ) ) < 0 ) {
2002-11-18 18:18:05 +00:00
Yap_ErrorMessage = " corrupt saved state " ;
2002-10-30 17:27:19 +00:00
return ( FAIL_RESTORE ) ;
}
count + = n ;
}
}
if ( pp [ 0 ] ! = ' Y ' & & pp [ 1 ] ! = ' A ' & & pp [ 0 ] ! = ' P ' ) {
2002-11-18 18:18:05 +00:00
Yap_ErrorMessage = " corrupt saved state " ;
2002-10-30 17:27:19 +00:00
return ( FAIL_RESTORE ) ;
}
2001-04-09 20:54:03 +01:00
if ( strcmp ( pp , msg ) ! = 0 ) {
2002-11-18 18:18:05 +00:00
Yap_ErrorMessage = " saved state for different version of YAP " ;
2001-04-09 20:54:03 +01:00
return ( FAIL_RESTORE ) ;
}
/* check info on header */
/* ignore info on saved state */
2002-10-30 17:27:19 +00:00
* info = get_header_cell ( ) ;
2002-11-18 18:18:05 +00:00
if ( Yap_ErrorMessage )
2002-10-30 17:27:19 +00:00
return ( FAIL_RESTORE ) ;
2001-04-09 20:54:03 +01:00
/* check the restore mode */
2002-10-30 17:27:19 +00:00
mode = get_header_cell ( ) ;
2002-11-18 18:18:05 +00:00
if ( Yap_ErrorMessage )
2002-10-30 17:27:19 +00:00
return ( FAIL_RESTORE ) ;
/* check the number of c-predicates */
c_preds = get_header_cell ( ) ;
2002-11-18 18:18:05 +00:00
if ( Yap_ErrorMessage )
2002-10-30 17:27:19 +00:00
return ( FAIL_RESTORE ) ;
2002-11-18 18:18:05 +00:00
if ( Yap_HeapBase ! = NULL & & c_preds ! = NumberOfCPreds ) {
Yap_ErrorMessage = " saved state with different number of built-ins " ;
2002-10-30 17:27:19 +00:00
return ( FAIL_RESTORE ) ;
}
cmp_funcs = get_header_cell ( ) ;
2002-11-18 18:18:05 +00:00
if ( Yap_ErrorMessage )
2002-10-30 17:27:19 +00:00
return ( FAIL_RESTORE ) ;
2002-11-18 18:18:05 +00:00
if ( Yap_HeapBase ! = NULL & & cmp_funcs ! = NumberOfCmpFuncs ) {
Yap_ErrorMessage = " saved state with different built-ins " ;
2002-10-30 17:27:19 +00:00
return ( FAIL_RESTORE ) ;
}
if ( mode ! = DO_EVERYTHING & & mode ! = DO_ONLY_CODE ) {
2002-11-18 18:18:05 +00:00
Yap_ErrorMessage = " corrupt saved state " ;
2001-04-09 20:54:03 +01:00
return ( FAIL_RESTORE ) ;
}
/* ignore info on stacks size */
2002-10-30 17:27:19 +00:00
* AHeap = get_header_cell ( ) ;
* AStack = get_header_cell ( ) ;
* ATrail = get_header_cell ( ) ;
2002-11-18 18:18:05 +00:00
if ( Yap_ErrorMessage )
2002-10-30 17:27:19 +00:00
return ( FAIL_RESTORE ) ;
2001-04-09 20:54:03 +01:00
/* now, check whether we got enough enough space to load the
saved space */
2002-09-09 18:40:12 +01:00
hp_size = get_cell ( ) ;
2002-11-18 18:18:05 +00:00
if ( Yap_ErrorMessage )
2002-10-30 17:27:19 +00:00
return ( FAIL_RESTORE ) ;
2002-11-18 18:18:05 +00:00
while ( Yap_HeapBase ! = NULL & & hp_size > Unsigned ( AuxTop ) - Unsigned ( Yap_HeapBase ) ) {
if ( ! Yap_growheap ( FALSE ) ) {
2002-10-30 17:27:19 +00:00
return ( FAIL_RESTORE ) ;
2002-10-09 05:26:48 +01:00
}
2001-04-09 20:54:03 +01:00
}
if ( mode = = DO_EVERYTHING ) {
2002-10-30 17:27:19 +00:00
lc_size = get_cell ( ) ;
2002-11-18 18:18:05 +00:00
if ( Yap_ErrorMessage )
2002-10-30 17:27:19 +00:00
return ( FAIL_RESTORE ) ;
gb_size = get_cell ( ) ;
2002-11-18 18:18:05 +00:00
if ( Yap_ErrorMessage )
2002-10-30 17:27:19 +00:00
return ( FAIL_RESTORE ) ;
2002-11-18 18:18:05 +00:00
if ( Yap_HeapBase ! = NULL & & lc_size + gb_size > Unsigned ( Yap_LocalBase ) - Unsigned ( Yap_GlobalBase ) ) {
Yap_ErrorMessage = " not enough stack space for restore " ;
2002-10-30 17:27:19 +00:00
return ( FAIL_RESTORE ) ;
2001-04-09 20:54:03 +01:00
}
2002-11-18 18:18:05 +00:00
if ( Yap_HeapBase ! = NULL & & ( tr_size = get_cell ( ) ) > Unsigned ( Yap_TrailTop ) - Unsigned ( Yap_TrailBase ) ) {
Yap_ErrorMessage = " not enough trail space for restore " ;
2001-04-09 20:54:03 +01:00
return ( FAIL_RESTORE ) ;
}
} else {
/* skip cell size */
2002-10-30 17:27:19 +00:00
get_header_cell ( ) ;
2002-11-18 18:18:05 +00:00
if ( Yap_ErrorMessage )
2002-10-30 17:27:19 +00:00
return ( FAIL_RESTORE ) ;
get_header_cell ( ) ;
2002-11-18 18:18:05 +00:00
if ( Yap_ErrorMessage )
2002-10-30 17:27:19 +00:00
return ( FAIL_RESTORE ) ;
get_header_cell ( ) ;
2002-11-18 18:18:05 +00:00
if ( Yap_ErrorMessage )
2002-10-30 17:27:19 +00:00
return ( FAIL_RESTORE ) ;
2001-04-09 20:54:03 +01:00
}
return ( mode ) ;
}
/* Gets the state of the heap, and evaluates the related variables */
static void
get_heap_info ( void )
{
OldHeapBase = ( ADDR ) get_cellptr ( ) ;
OldHeapTop = ( ADDR ) get_cellptr ( ) ;
OldHeapUsed = ( Int ) get_cell ( ) ;
FreeBlocks = ( BlockHeader * ) get_cellptr ( ) ;
2002-11-18 18:18:05 +00:00
HDiff = Unsigned ( Yap_HeapBase ) - Unsigned ( OldHeapBase ) ;
2001-04-09 20:54:03 +01:00
}
/* Gets the register array */
/* Saves the old bases for the work areas */
/* and evaluates the difference from the old areas to the new ones */
static void
get_regs ( int flag )
{
2002-11-18 18:18:05 +00:00
CELL * NewGlobalBase = ( CELL * ) Yap_GlobalBase ;
2001-04-09 20:54:03 +01:00
CELL * NewLCL0 = LCL0 ;
CELL * OldXREGS ;
/* Get regs */
compile_arrays = ( int ) get_cell ( ) ;
if ( flag = = DO_EVERYTHING ) {
CP = ( yamop * ) get_cellptr ( ) ;
ENV = get_cellptr ( ) ;
ASP = get_cellptr ( ) ;
/* N = get_cell(); */
H0 = get_cellptr ( ) ;
LCL0 = get_cellptr ( ) ;
H = get_cellptr ( ) ;
HB = get_cellptr ( ) ;
B = ( choiceptr ) get_cellptr ( ) ;
TR = ( tr_fr_ptr ) get_cellptr ( ) ;
YENV = get_cellptr ( ) ;
S = get_cellptr ( ) ;
P = ( yamop * ) get_cellptr ( ) ;
MyTR = ( tr_fr_ptr ) get_cellptr ( ) ;
CreepFlag = get_cell ( ) ;
FlipFlop = get_cell ( ) ;
# ifdef COROUTINING
DelayedVars = get_cell ( ) ;
# endif
}
2002-05-14 19:22:42 +01:00
CurrentModule = get_cell ( ) ;
2001-04-09 20:54:03 +01:00
HeapPlus = ( ADDR ) get_cellptr ( ) ;
if ( flag = = DO_EVERYTHING ) {
# ifdef COROUTINING
WokenGoals = get_cell ( ) ;
# endif
# ifdef DEPTH_LIMIT
DEPTH = get_cell ( ) ;
# endif
}
/* Get the old bases */
OldXREGS = get_cellptr ( ) ;
which_save = get_cell ( ) ;
XDiff = ( CELL ) XREGS - ( CELL ) OldXREGS ;
get_heap_info ( ) ;
if ( flag = = DO_EVERYTHING ) {
ARG1 = get_cell ( ) ;
if ( which_save = = 2 ) {
ARG2 = get_cell ( ) ;
}
/* get old trail base */
OldTrailBase = ( ADDR ) get_cellptr ( ) ;
/* Save the old register where we can easily access them */
OldASP = ASP ;
OldLCL0 = LCL0 ;
2002-11-18 18:18:05 +00:00
OldGlobalBase = ( CELL * ) Yap_GlobalBase ;
2001-04-09 20:54:03 +01:00
OldH = H ;
OldTR = TR ;
2002-11-18 18:18:05 +00:00
GDiff = Unsigned ( NewGlobalBase ) - Unsigned ( Yap_GlobalBase ) ;
2001-04-09 20:54:03 +01:00
LDiff = Unsigned ( NewLCL0 ) - Unsigned ( LCL0 ) ;
TrDiff = LDiff ;
2002-11-18 18:18:05 +00:00
Yap_GlobalBase = ( ADDR ) NewGlobalBase ;
2001-04-09 20:54:03 +01:00
LCL0 = NewLCL0 ;
}
}
/* Get the old opcodes and place them in a hash table */
static void
get_insts ( OPCODE old_ops [ ] )
{
myread ( splfild , ( char * ) old_ops , sizeof ( OPCODE ) * ( _std_top + 1 ) ) ;
}
/* check if the old functions are the same as the new ones, or if they
have moved around . Note that we don ' t need these functions afterwards */
static int
check_funcs ( void )
{
2002-11-11 17:38:10 +00:00
UInt old_NumberOfCPreds , old_NumberOfCmpFuncs ;
2001-04-09 20:54:03 +01:00
int out = FALSE ;
2002-11-11 17:38:10 +00:00
if ( ( old_NumberOfCPreds = get_cell ( ) ) ! = NumberOfCPreds ) {
2002-11-18 18:18:05 +00:00
Yap_Error ( SYSTEM_ERROR , TermNil , " bad saved state, different number of functions (%d vs %d), system corrupted, old_NumberOfCPreds, NumberOfCPreds " ) ;
2001-04-09 20:54:03 +01:00
}
{
unsigned int i ;
2002-11-11 17:38:10 +00:00
for ( i = 0 ; i < old_NumberOfCPreds ; + + i ) {
2001-04-09 20:54:03 +01:00
CELL * old_pred = get_cellptr ( ) ;
2002-11-18 18:18:05 +00:00
out = ( out | | old_pred ! = CellPtr ( Yap_c_predicates [ i ] ) ) ;
2001-04-09 20:54:03 +01:00
}
}
2002-11-11 17:38:10 +00:00
if ( ( old_NumberOfCmpFuncs = get_cell ( ) ) ! = NumberOfCmpFuncs ) {
2002-11-18 18:18:05 +00:00
Yap_Error ( SYSTEM_ERROR , TermNil , " bad saved state, different number of comparison functions (%d vs %d), system corrupted " , old_NumberOfCmpFuncs , NumberOfCmpFuncs ) ;
2001-04-09 20:54:03 +01:00
}
{
unsigned int i ;
2002-11-11 17:38:10 +00:00
for ( i = 0 ; i < old_NumberOfCmpFuncs ; + + i ) {
2001-04-09 20:54:03 +01:00
CELL * old_p = get_cellptr ( ) ;
CELL * old_f = get_cellptr ( ) ;
/* if (AddrAdjust((ADDR)old_p) != cmp_funcs[i].p) {
2002-11-18 18:18:05 +00:00
Yap_Error ( SYSTEM_ERROR , TermNil , " bad saved state, comparison function is in wrong place (%p vs %p), system corrupted " , AddrAdjust ( ( ADDR ) old_p ) , cmp_funcs [ i ] . p ) ;
2001-04-09 20:54:03 +01:00
} */
2002-11-18 18:18:05 +00:00
Yap_cmp_funcs [ i ] . p = ( PredEntry * ) AddrAdjust ( ( ADDR ) old_p ) ;
2001-04-09 20:54:03 +01:00
out = ( out | |
2002-11-18 18:18:05 +00:00
old_f ! = CellPtr ( Yap_cmp_funcs [ i ] . f ) ) ;
2001-04-09 20:54:03 +01:00
}
}
return ( out ) ;
}
/* Get the old atoms hash table */
static void
get_hash ( void )
{
2002-11-18 18:18:05 +00:00
myread ( splfild , Yap_chtype , NUMBER_OF_CHARS ) ;
2001-04-09 20:54:03 +01:00
}
/* Copy all of the old code to the new Heap */
static void
CopyCode ( void )
{
# if defined(YAPOR) || defined(TABLING)
/* skip the local and global data structures */
CELL j = get_cell ( ) ;
2002-11-18 18:18:05 +00:00
if ( j ! = Unsigned ( & GLOBAL ) - Unsigned ( Yap_HeapBase ) ) {
Yap_Error ( FATAL_ERROR , TermNil , " bad saved state, system corrupted " ) ;
2001-04-09 20:54:03 +01:00
}
2002-11-18 18:18:05 +00:00
myread ( splfild , ( char * ) Yap_HeapBase , j ) ;
2001-04-09 20:54:03 +01:00
# ifdef USE_HEAP
j = get_cell ( ) ;
myread ( splfild , ( char * ) & HashChain , j ) ;
# else
j = get_cell ( ) ;
if ( j ! = Unsigned ( BaseAllocArea ) - Unsigned ( & HashChain ) ) {
2002-11-18 18:18:05 +00:00
Yap_Error ( FATAL_ERROR , TermNil , " bad saved state, system corrupted " ) ;
2001-04-09 20:54:03 +01:00
}
myread ( splfild , ( char * ) & HashChain , j ) ;
j = get_cell ( ) ;
myread ( splfild , ( char * ) TopAllocBlockArea , j ) ;
# endif
# else
2002-11-18 18:18:05 +00:00
myread ( splfild , ( char * ) Yap_HeapBase ,
2001-04-09 20:54:03 +01:00
( Unsigned ( OldHeapTop ) - Unsigned ( OldHeapBase ) ) ) ;
# endif
}
/* Copy the local and global stack and also the trail to their new home */
/* In REGS we still have nonadjusted values !! */
static void
CopyStacks ( void )
{
Int j ;
char * NewASP ;
j = Unsigned ( OldLCL0 ) - Unsigned ( ASP ) ;
NewASP = ( char * ) ( Unsigned ( ASP ) + ( Unsigned ( LCL0 ) - Unsigned ( OldLCL0 ) ) ) ;
myread ( splfild , ( char * ) NewASP , j ) ;
j = Unsigned ( H ) - Unsigned ( OldGlobalBase ) ;
2002-11-18 18:18:05 +00:00
myread ( splfild , ( char * ) Yap_GlobalBase , j ) ;
2001-04-09 20:54:03 +01:00
j = Unsigned ( TR ) - Unsigned ( OldTrailBase ) ;
2002-11-18 18:18:05 +00:00
myread ( splfild , Yap_TrailBase , j ) ;
2001-04-09 20:54:03 +01:00
}
/* Copy the local and global stack and also the trail to their new home */
/* In REGS we still have nonadjusted values !! */
static void
CopyTrailEntries ( void )
{
CELL entry , * Entries ;
2002-11-18 18:18:05 +00:00
Entries = ( CELL * ) Yap_TrailBase ;
2001-04-09 20:54:03 +01:00
do {
* Entries + + = entry = get_cell ( ) ;
} while ( ( CODEADDR ) entry ! = NULL ) ;
}
/* get things which are saved in the file */
static int
get_coded ( int flag , OPCODE old_ops [ ] )
{
char my_end_msg [ 256 ] ;
int funcs_moved = FALSE ;
get_regs ( flag ) ;
get_insts ( old_ops ) ;
funcs_moved = check_funcs ( ) ;
get_hash ( ) ;
CopyCode ( ) ;
switch ( flag ) {
case DO_EVERYTHING :
CopyStacks ( ) ;
break ;
case DO_ONLY_CODE :
CopyTrailEntries ( ) ;
break ;
}
/* Check CRC */
myread ( splfild , my_end_msg , 256 ) ;
if ( strcmp ( end_msg , my_end_msg ) ! = 0 )
2002-11-18 18:18:05 +00:00
Yap_Error ( FATAL_ERROR , TermNil , " bad saved state, system corrupted " ) ;
2001-04-09 20:54:03 +01:00
return ( funcs_moved ) ;
}
/* restore some heap registers */
static void
restore_heap_regs ( void )
{
HeapPlus = AddrAdjust ( HeapPlus ) ;
2002-10-09 05:26:48 +01:00
HeapTop = AddrAdjust ( HeapTop ) ;
2001-04-09 20:54:03 +01:00
* ( ( YAP_SEG_SIZE * ) HeapTop ) = InUseFlag ;
HeapMax = HeapUsed = OldHeapUsed ;
restore_codes ( ) ;
}
/* adjust abstract machine registers */
static void
restore_regs ( int flag )
{
restore_heap_regs ( ) ;
if ( flag = = DO_EVERYTHING ) {
CP = PtoOpAdjust ( CP ) ;
ENV = PtoLocAdjust ( ENV ) ;
ASP = PtoLocAdjust ( ASP ) ;
H = PtoGloAdjust ( H ) ;
B = ( choiceptr ) PtoLocAdjust ( CellPtr ( B ) ) ;
TR = PtoTRAdjust ( TR ) ;
P = PtoOpAdjust ( P ) ;
HB = PtoLocAdjust ( HB ) ;
YENV = PtoLocAdjust ( YENV ) ;
S = PtoGloAdjust ( S ) ;
HeapPlus = AddrAdjust ( HeapPlus ) ;
if ( MyTR )
MyTR = PtoTRAdjust ( MyTR ) ;
# ifdef COROUTINING
DelayedVars = AbsAppl ( PtoGloAdjust ( RepAppl ( DelayedVars ) ) ) ;
# ifdef MULTI_ASSIGNMENT_VARIABLES
WokenGoals = AbsAppl ( PtoGloAdjust ( RepAppl ( WokenGoals ) ) ) ;
# endif
# endif
}
}
static void
recompute_mask ( DBRef dbr )
{
if ( dbr - > Flags & DBNoVars ) {
2002-11-18 18:18:05 +00:00
dbr - > Mask = Yap_EvalMasks ( ( Term ) dbr - > Entry , & ( dbr - > Key ) ) ;
2001-04-09 20:54:03 +01:00
} else if ( dbr - > Flags & DBComplex ) {
/* This is quite nasty, we want to recalculate the mask but
we don ' t want to rebuild the whole term . We ' ll just build whatever we
need to recompute the mask .
*/
2002-06-04 19:21:55 +01:00
CELL * x = ( CELL * ) HeapTop , * tp ;
unsigned int Arity , i ;
Term out ;
char * tbase = CharP ( dbr - > Contents - 1 ) ;
2001-04-09 20:54:03 +01:00
2002-06-04 19:21:55 +01:00
if ( IsPairTerm ( dbr - > Entry ) ) {
2001-04-09 20:54:03 +01:00
2002-06-04 19:21:55 +01:00
out = AbsPair ( x ) ;
Arity = 2 ;
tp = ( CELL * ) ( tbase + ( CELL ) RepPair ( dbr - > Entry ) ) ;
} else {
Functor f ;
tp = ( CELL * ) ( tbase + ( CELL ) RepAppl ( dbr - > Entry ) ) ;
f = ( Functor ) ( * tp + + ) ;
out = AbsAppl ( x ) ;
Arity = ArityOfFunctor ( f ) ;
* x + + = ( CELL ) f ;
if ( Arity > 3 ) Arity = 3 ;
}
for ( i = 0 ; i < Arity ; i + + ) {
register Term tw = * tp + + ;
if ( IsVarTerm ( tw ) ) {
RESET_VARIABLE ( x ) ;
} else if ( IsApplTerm ( tw ) ) {
/* just fetch the functor from where it is in the data-base.
This guarantees we have access to references and friends . */
CELL offset = ( CELL ) RepAppl ( tw ) ;
if ( offset > dbr - > NOfCells * sizeof ( CELL ) )
* x = tw ;
else
* x = AbsAppl ( ( CELL * ) ( tbase + offset ) ) ;
} else if ( IsAtomicTerm ( tw ) ) {
* x = tw ;
} else if ( IsPairTerm ( tw ) ) {
* x = AbsPair ( x ) ;
}
x + + ;
}
2002-11-18 18:18:05 +00:00
dbr - > Mask = Yap_EvalMasks ( out , & ( dbr - > Key ) ) ;
2001-04-09 20:54:03 +01:00
}
}
# define HASH_SHIFT 6
/*
* This is used to make an hash table correct , after displacing its elements ,
* HCEnd should point to an area of free space , usually in the heap . The
* routine is very dependent on the hash function used , and it destroys the
* previous " hit " order
*/
static void
rehash ( CELL * oldcode , int NOfE , int KindOfEntries )
{
register CELL * savep , * basep ;
CELL * oldp = oldcode ;
int TableSize = NOfE - 1 , NOfEntries ;
register int i ;
int hash ;
CELL WorkTerm , failplace = 0 ;
CELL * Base = oldcode ;
if ( HDiff = = 0 )
return ;
basep = H ;
if ( H + ( NOfE * 2 ) > ASP ) {
basep = ( CELL * ) TR ;
2002-11-18 18:18:05 +00:00
if ( basep + ( NOfE * 2 ) > ( CELL * ) Yap_TrailTop ) {
if ( ! Yap_growtrail ( ( ADDR ) ( basep + ( NOfE * 2 ) ) - Yap_TrailTop ) ) {
Yap_Error ( SYSTEM_ERROR , TermNil ,
2001-04-09 20:54:03 +01:00
" not enough space to restore hash tables for indexing " ) ;
2002-11-18 18:18:05 +00:00
Yap_exit ( 1 ) ;
2001-04-09 20:54:03 +01:00
}
}
}
for ( i = 0 ; i < NOfE ; + + i ) {
if ( * oldp = = 0 ) {
failplace = oldp [ 1 ] ;
break ;
}
oldp + = 2 ;
}
savep = basep ;
oldp = oldcode ;
for ( i = 0 ; i < NOfE ; + + i ) {
if ( * oldp ! = 0 ) {
savep [ 0 ] = oldp [ 0 ] ;
savep [ 1 ] = oldp [ 1 ] ;
oldp [ 0 ] = 0 ;
oldp [ 1 ] = failplace ;
savep + = 2 ;
}
oldp + = 2 ;
}
NOfEntries = ( savep - basep ) / 2 ;
savep = basep ;
for ( i = 0 ; i < NOfEntries ; + + i ) {
register Int d ;
CELL * hentry ;
WorkTerm = savep [ i * 2 ] ;
hash = ( Unsigned ( WorkTerm ) > > HASH_SHIFT ) & TableSize ;
hentry = Base + hash * 2 ;
d = TableSize & ( Unsigned ( WorkTerm ) | 1 ) ;
while ( * hentry ) {
# ifdef DEBUG
# ifdef CLASHES
+ + clashes ;
# endif /* CLASHES */
# endif /* DEBUG */
hash = ( hash + d ) & TableSize ;
hentry = Base + hash * 2 ;
}
hentry [ 0 ] = WorkTerm ;
hentry [ 1 ] = savep [ i * 2 + 1 ] ;
}
}
static CODEADDR
2002-06-04 19:21:55 +01:00
CCodeAdjust ( PredEntry * pe , CODEADDR c )
2001-04-09 20:54:03 +01:00
{
/* add this code to a list of ccalls that must be adjusted */
2002-11-18 18:18:05 +00:00
return ( ( CODEADDR ) ( Yap_c_predicates [ pe - > StateOfPred ] ) ) ;
2001-04-09 20:54:03 +01:00
}
static CODEADDR
2002-06-04 19:21:55 +01:00
NextCCodeAdjust ( PredEntry * pe , CODEADDR c )
2001-04-09 20:54:03 +01:00
{
/* add this code to a list of ccalls that must be adjusted */
2002-11-18 18:18:05 +00:00
return ( ( CODEADDR ) ( Yap_c_predicates [ pe - > StateOfPred + 1 ] ) ) ;
2001-04-09 20:54:03 +01:00
}
static CODEADDR
2002-06-04 19:21:55 +01:00
DirectCCodeAdjust ( PredEntry * pe , CODEADDR c )
2001-04-09 20:54:03 +01:00
{
/* add this code to a list of ccalls that must be adjusted */
unsigned int i ;
2002-11-11 17:38:10 +00:00
for ( i = 0 ; i < NumberOfCmpFuncs ; i + + ) {
2002-11-18 18:18:05 +00:00
if ( Yap_cmp_funcs [ i ] . p = = pe ) {
return ( ( CODEADDR ) ( Yap_cmp_funcs [ i ] . f ) ) ;
2001-04-09 20:54:03 +01:00
}
}
2002-11-18 18:18:05 +00:00
Yap_Error ( FATAL_ERROR , TermNil , " bad saved state, ccalls corrupted " ) ;
2001-04-09 20:54:03 +01:00
return ( NULL ) ;
}
2002-06-04 19:21:55 +01:00
# include "rheap.h"
2001-04-09 20:54:03 +01:00
/* restore the atom entries which are invisible for the user */
static void
RestoreForeignCodeStructure ( void )
{
ForeignObj * f_code ;
if ( ForeignCodeLoaded ! = NULL )
ForeignCodeLoaded = ( void * ) AddrAdjust ( ( ADDR ) ForeignCodeLoaded ) ;
f_code = ForeignCodeLoaded ;
while ( f_code ! = NULL ) {
StringList objs , libs ;
if ( f_code - > objs ! = NULL )
f_code - > objs = ( StringList ) AddrAdjust ( ( ADDR ) f_code - > objs ) ;
objs = f_code - > objs ;
while ( objs ! = NULL ) {
if ( objs - > next ! = NULL )
objs - > next = ( StringList ) AddrAdjust ( ( ADDR ) objs - > next ) ;
if ( objs - > s ! = NULL )
objs - > s = ( char * ) AddrAdjust ( ( ADDR ) objs - > s ) ;
objs = objs - > next ;
}
if ( f_code - > libs ! = NULL )
f_code - > libs = ( StringList ) AddrAdjust ( ( ADDR ) f_code - > libs ) ;
libs = f_code - > libs ;
while ( libs ! = NULL ) {
if ( libs - > next ! = NULL )
libs - > next = ( StringList ) AddrAdjust ( ( ADDR ) libs - > next ) ;
if ( libs - > s ! = NULL )
libs - > s = ( char * ) AddrAdjust ( ( ADDR ) libs - > s ) ;
libs = libs - > next ;
}
if ( f_code - > f ! = NULL )
f_code - > f = ( char * ) AddrAdjust ( ( ADDR ) f_code - > f ) ;
if ( f_code - > next ! = NULL )
f_code - > next = ( ForeignObj * ) AddrAdjust ( ( ADDR ) f_code - > f ) ;
f_code = f_code - > next ;
}
}
2002-05-28 17:26:00 +01:00
/* restore the atom entries which are invisible for the user */
static void
RestoreIOStructures ( void )
{
2002-11-18 18:18:05 +00:00
Yap_InitStdStreams ( ) ;
2002-05-28 17:26:00 +01:00
}
2001-04-09 20:54:03 +01:00
/* restores the list of free space, with its curious structure */
static void
RestoreFreeSpace ( void )
{
register BlockHeader * bpt , * bsz ;
if ( FreeBlocks ! = NULL )
FreeBlocks = BlockAdjust ( FreeBlocks ) ;
bpt = FreeBlocks ;
while ( bpt ! = NULL ) {
if ( bpt - > b_next ! = NULL ) {
bsz = bpt - > b_next = BlockAdjust ( bpt - > b_next ) ;
while ( bsz ! = NULL ) {
if ( bsz - > b_next_size ! = NULL )
bsz - > b_next_size = BlockAdjust ( bsz - > b_next_size ) ;
if ( bsz - > b_next ! = NULL )
bsz - > b_next = BlockAdjust ( bsz - > b_next ) ;
bsz = bsz - > b_next ;
}
}
if ( bpt - > b_next_size ! = NULL )
bpt - > b_next_size = BlockAdjust ( bpt - > b_next_size ) ;
bpt = bpt - > b_next_size ;
}
* ( ( YAP_SEG_SIZE * ) HeapTop ) = InUseFlag ;
}
2002-06-04 19:21:55 +01:00
/* restore the atom entries which are invisible for the user */
static void
RestoreInvisibleAtoms ( void )
{
AtomEntry * at ;
Atom atm = INVISIBLECHAIN . Entry ;
INVISIBLECHAIN . Entry = atm = AtomAdjust ( atm ) ;
at = RepAtom ( atm ) ;
if ( EndOfPAEntr ( at ) )
return ;
do {
# ifdef DEBUG_RESTORE2 /* useful during debug */
2002-11-11 17:38:10 +00:00
fprintf ( errout , " Restoring %s \n " , at - > StrOfAE ) ;
2002-06-04 19:21:55 +01:00
# endif
at - > PropsOfAE = PropAdjust ( at - > PropsOfAE ) ;
RestoreEntries ( RepProp ( at - > PropsOfAE ) ) ;
atm = at - > NextOfAE ;
at - > NextOfAE = atm = AtomAdjust ( atm ) ;
at = RepAtom ( atm ) ;
}
while ( ! EndOfPAEntr ( at ) ) ;
}
2001-04-09 20:54:03 +01:00
/*
* This is the really tough part , to restore the whole of the heap
*/
static void
restore_heap ( void )
{
AtomHashEntry * HashPtr = HashChain ;
register int i ;
for ( i = 0 ; i < MaxHash ; + + i ) {
Atom atm = HashPtr - > Entry ;
if ( atm ) {
AtomEntry * at ;
HashPtr - > Entry = atm = AtomAdjust ( atm ) ;
at = RepAtom ( atm ) ;
do {
# ifdef DEBUG_RESTORE2 /* useful during debug */
2002-11-11 17:38:10 +00:00
fprintf ( errout , " Restoring %s \n " , at - > StrOfAE ) ;
2001-04-09 20:54:03 +01:00
# endif
2002-05-24 19:25:25 +01:00
at - > PropsOfAE = PropAdjust ( at - > PropsOfAE ) ;
2001-10-30 16:42:05 +00:00
RestoreEntries ( RepProp ( at - > PropsOfAE ) ) ;
2001-04-09 20:54:03 +01:00
atm = at - > NextOfAE = AtomAdjust ( at - > NextOfAE ) ;
at = RepAtom ( atm ) ;
} while ( ! EndOfPAEntr ( at ) ) ;
}
HashPtr + + ;
}
RestoreInvisibleAtoms ( ) ;
RestoreForeignCodeStructure ( ) ;
2002-05-28 17:26:00 +01:00
RestoreIOStructures ( ) ;
2001-04-09 20:54:03 +01:00
}
# ifdef DEBUG_RESTORE3
static void
ShowEntries ( pp )
PropEntry * pp ;
{
while ( ! EndOfPAEntr ( pp ) ) {
2002-11-18 18:18:05 +00:00
fprintf ( Yap_stderr , " Estou a ver a prop %x em %x \n " , pp - > KindOfPE , pp ) ;
2001-04-09 20:54:03 +01:00
pp = RepProp ( pp - > NextOfPE ) ;
}
}
static void
ShowAtoms ( )
{
AtomHashEntry * HashPtr = HashChain ;
register int i ;
for ( i = 0 ; i < MaxHash ; + + i ) {
if ( HashPtr - > Entry ! = NIL ) {
AtomEntry * at ;
at = RepAtom ( HashPtr - > Entry ) ;
do {
2002-11-18 18:18:05 +00:00
fprintf ( Yap_stderr , " Passei ao %s em %x \n " , at - > StrOfAE , at ) ;
2001-10-30 16:42:05 +00:00
ShowEntries ( RepProp ( at - > PropsOfAE ) ) ;
2001-04-09 20:54:03 +01:00
} while ( ! EndOfPAEntr ( at = RepAtom ( at - > NextOfAE ) ) ) ;
}
HashPtr + + ;
}
}
# endif /* DEBUG_RESTORE3 */
# include <stdio.h>
2002-10-30 17:27:19 +00:00
static int
commit_to_saved_state ( char * s , CELL * Astate , CELL * ATrail , CELL * AStack , CELL * AHeap ) {
2001-04-09 20:54:03 +01:00
int mode ;
2002-10-30 17:27:19 +00:00
if ( ( mode = check_header ( Astate , ATrail , AStack , AHeap ) ) = = FAIL_RESTORE )
2001-04-09 20:54:03 +01:00
return ( FAIL_RESTORE ) ;
2002-11-18 18:18:05 +00:00
Yap_PrologMode = BootMode ;
if ( Yap_HeapBase ) {
2002-10-30 17:27:19 +00:00
if ( ! yap_flags [ HALT_AFTER_CONSULT_FLAG ] ) {
2002-11-18 18:18:05 +00:00
Yap_TrueFileName ( s , Yap_FileNameBuf2 , YAP_FILENAME_MAX ) ;
fprintf ( Yap_stderr , " [ Restoring file %s ] \n " , Yap_FileNameBuf2 ) ;
2002-10-30 17:27:19 +00:00
}
2002-11-18 18:18:05 +00:00
Yap_CloseStreams ( TRUE ) ;
2001-04-09 20:54:03 +01:00
}
# ifdef DEBUG_RESTORE4
/*
* This should be another file , like the log file
*/
2002-11-18 18:18:05 +00:00
errout = Yap_stderr ;
2001-04-09 20:54:03 +01:00
# endif
return ( mode ) ;
}
2002-10-30 17:27:19 +00:00
static void
cat_file_name ( char * s , char * prefix , char * name , unsigned int max_length )
{
strncpy ( s , prefix , max_length ) ;
# if _MSC_VER || defined(__MINGW32__)
strncat ( s , " \\ " , max_length ) ;
# else
strncat ( s , " / " , max_length ) ;
# endif
strncat ( s , name , max_length ) ;
}
static int
2002-11-11 17:38:10 +00:00
OpenRestore ( char * inpf , char * YapLibDir , CELL * Astate , CELL * ATrail , CELL * AStack , CELL * AHeap )
2002-10-30 17:27:19 +00:00
{
int mode = FAIL_RESTORE ;
2002-11-18 18:18:05 +00:00
Yap_ErrorMessage = NULL ;
2002-11-11 17:38:10 +00:00
if ( inpf = = NULL )
inpf = StartUpFile ;
if ( inpf ! = NULL & & ( splfild = open_file ( inpf , O_RDONLY ) ) > 0 ) {
2002-12-10 19:08:25 +00:00
if ( ( mode = commit_to_saved_state ( inpf , Astate , ATrail , AStack , AHeap ) ) ! = FAIL_RESTORE ) {
Yap_ErrorMessage = NULL ;
2002-10-30 17:27:19 +00:00
return ( mode ) ;
2002-12-10 19:08:25 +00:00
}
2002-10-30 17:27:19 +00:00
}
2002-11-18 18:18:05 +00:00
if ( ! Yap_dir_separator ( inpf [ 0 ] ) & & ! Yap_volume_header ( inpf ) ) {
2002-10-30 17:27:19 +00:00
/*
we have a relative path for the file , try to do somewhat better
using YAPLIBDIR or friends .
*/
if ( YapLibDir ! = NULL ) {
2002-11-18 18:18:05 +00:00
cat_file_name ( Yap_FileNameBuf , Yap_LibDir , inpf , YAP_FILENAME_MAX ) ;
if ( ( splfild = open_file ( Yap_FileNameBuf , O_RDONLY ) ) > 0 ) {
2002-12-10 19:08:25 +00:00
if ( ( mode = commit_to_saved_state ( Yap_FileNameBuf , Astate , ATrail , AStack , AHeap ) ) ! = FAIL_RESTORE ) {
Yap_ErrorMessage = NULL ;
2002-10-30 17:27:19 +00:00
return ( mode ) ;
2002-12-10 19:08:25 +00:00
}
2002-10-30 17:27:19 +00:00
}
}
# if HAVE_GETENV
{
char * yap_env = getenv ( " YAPLIBDIR " ) ;
if ( yap_env ! = NULL ) {
2002-11-18 18:18:05 +00:00
cat_file_name ( Yap_FileNameBuf , yap_env , inpf , YAP_FILENAME_MAX ) ;
if ( ( splfild = open_file ( Yap_FileNameBuf , O_RDONLY ) ) > 0 ) {
2002-12-10 19:08:25 +00:00
if ( ( mode = commit_to_saved_state ( Yap_FileNameBuf , Astate , ATrail , AStack , AHeap ) ) ! = FAIL_RESTORE ) {
Yap_ErrorMessage = NULL ;
2002-10-30 17:27:19 +00:00
return ( mode ) ;
2002-12-10 19:08:25 +00:00
}
2002-10-30 17:27:19 +00:00
}
}
}
# endif
if ( LIB_DIR ! = NULL ) {
2002-11-18 18:18:05 +00:00
cat_file_name ( Yap_FileNameBuf , LIB_DIR , inpf , YAP_FILENAME_MAX ) ;
if ( ( splfild = open_file ( Yap_FileNameBuf , O_RDONLY ) ) > 0 ) {
2002-12-10 19:08:25 +00:00
if ( ( mode = commit_to_saved_state ( Yap_FileNameBuf , Astate , ATrail , AStack , AHeap ) ) ! = FAIL_RESTORE ) {
Yap_ErrorMessage = NULL ;
2002-10-30 17:27:19 +00:00
return ( mode ) ;
2002-12-10 19:08:25 +00:00
}
2002-10-30 17:27:19 +00:00
}
}
}
2002-11-18 18:18:05 +00:00
Yap_Error ( SYSTEM_ERROR , TermNil , Yap_ErrorMessage ) ;
Yap_ErrorMessage = NULL ;
2002-10-30 17:27:19 +00:00
return ( FAIL_RESTORE ) ;
}
2001-04-09 20:54:03 +01:00
static void
CloseRestore ( void )
{
# ifdef DEBUG_RESTORE3
ShowAtoms ( ) ;
# endif
close_file ( ) ;
2002-11-18 18:18:05 +00:00
Yap_PrologMode = UserMode ;
2001-04-09 20:54:03 +01:00
}
static int
check_opcodes ( OPCODE old_ops [ ] )
{
# if USE_THREADED_CODE
int have_shifted = FALSE ;
op_numbers op = _Ystop ;
for ( op = _Ystop ; op < _std_top ; op + + ) {
2002-11-18 18:18:05 +00:00
if ( Yap_opcode ( op ) ! = old_ops [ op ] ) {
2001-04-09 20:54:03 +01:00
have_shifted = TRUE ;
break ;
}
}
return ( have_shifted ) ;
# else
return ( FALSE ) ;
# endif
}
static void
RestoreHeap ( OPCODE old_ops [ ] , int functions_moved )
{
2002-11-18 18:18:05 +00:00
int heap_moved = ( OldHeapBase ! = Yap_HeapBase ) , opcodes_moved ;
2001-04-09 20:54:03 +01:00
opcodes_moved = check_opcodes ( old_ops ) ;
/* opcodes_moved has side-effects and should be tried first */
if ( heap_moved | | opcodes_moved | | functions_moved ) {
restore_heap ( ) ;
}
/* This must be done after restore_heap */
if ( heap_moved ) {
RestoreFreeSpace ( ) ;
}
2002-11-18 18:18:05 +00:00
Yap_InitAbsmi ( ) ;
if ( ! ( Yap_ReInitConstExps ( ) & & Yap_ReInitUnaryExps ( ) & & Yap_ReInitBinaryExps ( ) ) )
Yap_Error ( SYSTEM_ERROR , TermNil , " arithmetic operator not in saved state " ) ;
2001-04-09 20:54:03 +01:00
# ifdef DEBUG_RESTORE1
2002-11-11 17:38:10 +00:00
fprintf ( errout , " phase 1 done \n " ) ;
2001-04-09 20:54:03 +01:00
# endif
}
/*
* This function is called to know about the parameters of the last saved
* state
*/
int
2002-11-18 18:18:05 +00:00
Yap_SavedInfo ( char * FileName , char * YapLibDir , CELL * ATrail , CELL * AStack , CELL * AHeap )
2001-04-09 20:54:03 +01:00
{
2002-10-30 17:27:19 +00:00
CELL MyTrail , MyStack , MyHeap , MyState ;
int mode ;
2001-04-09 20:54:03 +01:00
2002-10-30 17:27:19 +00:00
mode = OpenRestore ( FileName , YapLibDir , & MyState , & MyTrail , & MyStack , & MyHeap ) ;
close_file ( ) ;
if ( mode = = FAIL_RESTORE ) {
2002-11-18 18:18:05 +00:00
Yap_ErrorMessage = NULL ;
2001-04-09 20:54:03 +01:00
return ( 0 ) ;
}
2002-10-30 17:27:19 +00:00
if ( ! * AHeap )
* AHeap = MyHeap / 1024 ;
if ( mode ! = DO_ONLY_CODE & & * AStack )
* AStack = MyStack / 1024 ;
if ( mode ! = DO_ONLY_CODE & & * ATrail )
* ATrail = MyTrail / 1024 ;
return ( MyState ) ;
2001-04-09 20:54:03 +01:00
}
static void
UnmarkTrEntries ( void )
{
CELL entry , * Entries ;
/* initialise a choice point */
B = ( choiceptr ) LCL0 ;
B - - ;
2002-05-14 19:22:42 +01:00
B - > cp_ap = NOCODE ;
2002-11-18 18:18:05 +00:00
Entries = ( CELL * ) Yap_TrailBase ;
2001-12-17 18:31:11 +00:00
while ( ( entry = * Entries + + ) ! = ( CELL ) NULL ) {
if ( IsVarTerm ( entry ) ) {
RESET_VARIABLE ( ( CELL * ) entry ) ;
} else if ( IsPairTerm ( entry ) ) {
2002-05-28 17:26:00 +01:00
CODEADDR ent = CodeAddrAdjust ( ( CODEADDR ) RepPair ( entry ) ) ;
2001-12-17 18:31:11 +00:00
register CELL flags ;
flags = Flags ( ent ) ;
ResetFlag ( InUseMask , flags ) ;
Flags ( ent ) = flags ;
if ( FlagOn ( ErasedMask , flags ) ) {
if ( FlagOn ( DBClMask , flags ) ) {
2002-11-18 18:18:05 +00:00
Yap_ErDBE ( ( DBRef ) ( ent - ( CELL ) & ( ( ( DBRef ) NIL ) - > Flags ) ) ) ;
2001-12-17 18:31:11 +00:00
} else {
2002-11-18 18:18:05 +00:00
Yap_ErCl ( ClauseFlagsToClause ( ent ) ) ;
2001-12-17 18:31:11 +00:00
}
2001-04-09 20:54:03 +01:00
}
}
}
B = NULL ;
}
int in_limbo = FALSE ;
/*
* This function is called when wanting only to restore the heap and
* associated registers
*/
2002-11-11 17:38:10 +00:00
static int
2002-10-30 17:27:19 +00:00
Restore ( char * s , char * lib_dir )
2001-04-09 20:54:03 +01:00
{
int restore_mode ;
int funcs_moved ;
OPCODE old_ops [ _std_top + 1 ] ;
2002-10-30 17:27:19 +00:00
CELL MyTrail , MyStack , MyHeap , MyState ;
if ( ( restore_mode = OpenRestore ( s , lib_dir , & MyState , & MyTrail , & MyStack , & MyHeap ) ) = = FAIL_RESTORE )
2001-04-09 20:54:03 +01:00
return ( FALSE ) ;
2002-11-18 18:18:05 +00:00
Yap_ShutdownLoadForeign ( ) ;
2001-04-09 20:54:03 +01:00
in_limbo = TRUE ;
funcs_moved = get_coded ( restore_mode , old_ops ) ;
restore_regs ( restore_mode ) ;
in_limbo = FALSE ;
/*#endif*/
RestoreHeap ( old_ops , funcs_moved ) ;
switch ( restore_mode ) {
case DO_EVERYTHING :
2002-11-18 18:18:05 +00:00
if ( OldHeapBase ! = Yap_HeapBase | |
2001-04-09 20:54:03 +01:00
OldLCL0 ! = LCL0 | |
2002-11-18 18:18:05 +00:00
OldGlobalBase ! = ( CELL * ) Yap_GlobalBase | |
OldTrailBase ! = Yap_TrailBase ) {
Yap_AdjustStacksAndTrail ( ) ;
2001-04-09 20:54:03 +01:00
if ( which_save = = 2 ) {
2002-11-18 18:18:05 +00:00
Yap_AdjustRegs ( 2 ) ;
2001-04-09 20:54:03 +01:00
} else {
2002-11-18 18:18:05 +00:00
Yap_AdjustRegs ( 1 ) ;
2001-04-09 20:54:03 +01:00
}
break ;
# ifdef DEBUG_RESTORE2
2002-11-11 17:38:10 +00:00
fprintf ( errout , " phase 2 done \n " ) ;
2001-04-09 20:54:03 +01:00
# endif
}
break ;
case DO_ONLY_CODE :
UnmarkTrEntries ( ) ;
2002-11-18 18:18:05 +00:00
Yap_InitYaamRegs ( ) ;
2001-04-09 20:54:03 +01:00
break ;
}
2002-11-18 18:18:05 +00:00
Yap_ReOpenLoadForeign ( ) ;
Yap_InitPlIO ( ) ;
2001-04-09 20:54:03 +01:00
/* reset time */
2002-11-18 18:18:05 +00:00
Yap_ReInitWallTime ( ) ;
2001-04-09 20:54:03 +01:00
CloseRestore ( ) ;
if ( which_save = = 2 ) {
2002-11-18 18:18:05 +00:00
Yap_unify ( ARG2 , MkIntTerm ( 0 ) ) ;
2001-04-09 20:54:03 +01:00
}
return ( restore_mode ) ;
}
2002-11-11 17:38:10 +00:00
int
2002-11-18 18:18:05 +00:00
Yap_Restore ( char * s , char * lib_dir )
2002-11-11 17:38:10 +00:00
{
return Restore ( s , lib_dir ) ;
}
2001-04-09 20:54:03 +01:00
static Int
p_restore ( void )
{
int mode ;
Term t1 = Deref ( ARG1 ) ;
2002-10-22 04:45:24 +01:00
# if defined(YAPOR) || defined(THREADS)
2002-10-21 23:52:36 +01:00
if ( NOfThreads ! = 1 ) {
2002-11-18 18:18:05 +00:00
Yap_Error ( SYSTEM_ERROR , TermNil , " cannot perform save: more than a worker/thread running " ) ;
2002-10-21 23:52:36 +01:00
return ( FALSE ) ;
}
2002-10-22 04:45:24 +01:00
# endif
2002-11-18 18:18:05 +00:00
if ( ! Yap_GetName ( Yap_FileNameBuf , YAP_FILENAME_MAX , t1 ) ) {
Yap_Error ( TYPE_ERROR_LIST , t1 , " restore/1 " ) ;
2001-04-09 20:54:03 +01:00
return ( FALSE ) ;
}
2002-11-18 18:18:05 +00:00
if ( ( mode = Restore ( Yap_FileNameBuf , NULL ) ) = = DO_ONLY_CODE ) {
2001-04-09 20:54:03 +01:00
# if PUSH_REGS
2002-11-18 18:18:05 +00:00
restore_absmi_regs ( & Yap_standard_regs ) ;
2001-04-09 20:54:03 +01:00
# endif
/* back to the top level we go */
2002-11-18 18:18:05 +00:00
siglongjmp ( Yap_RestartEnv , 3 ) ;
2001-04-09 20:54:03 +01:00
}
return ( mode ! = FAIL_RESTORE ) ;
}
void
2002-11-18 18:18:05 +00:00
Yap_InitSavePreds ( void )
2001-04-09 20:54:03 +01:00
{
2002-11-18 18:18:05 +00:00
Yap_InitCPred ( " $save " , 1 , p_save , SafePredFlag | SyncPredFlag ) ;
Yap_InitCPred ( " $save " , 2 , p_save2 , SafePredFlag | SyncPredFlag ) ;
Yap_InitCPred ( " $save_program " , 1 , p_save_program , SafePredFlag | SyncPredFlag ) ;
Yap_InitCPred ( " $restore " , 1 , p_restore , SyncPredFlag ) ;
2001-04-09 20:54:03 +01:00
}