/**************************************************************************** ** ** This file is part of GAP, a system for computational discrete algebra. ** ** Copyright of GAP belongs to its developers, whose names are too numerous ** to list here. Please refer to the COPYRIGHT file for details. ** ** SPDX-License-Identifier: GPL-2.0-or-later ** ** This file contains the functions concerned with saving and loading ** the workspace. There are support functions in gasman.c and elsewhere ** throughout the kernel
*/
/*************************************************************************** ** ** Temporary Stuff which will probably be revised to tie in with sysfiles
*/
/*************************************************************************** ** ** Find Bags -- a useful debugging tool -- scan for a bag of specified ** type and size and return it to the GAP level. Could be a problem ** if the bag is not a valid GAP object -- eg a local variables bag or ** a functions body.
*/
#ifdef USE_GASMAN
static UInt fb_minsize, fb_maxsize, fb_tnum; static Bag hit;
staticvoid ScanBag( Bag bag)
{ if (hit == (Bag)0 &&
SIZE_BAG(bag) >= fb_minsize &&
SIZE_BAG(bag) <= fb_maxsize &&
TNUM_BAG(bag) == fb_tnum)
hit = bag;
}
/*************************************************************************** ** *F SaveWorkspace( <fname> ) . . . . . save the workspace to the named file ** ** 'SaveWorkspace' is the entry point to the workspace saving. It is not ** installed as a GAP function, but instead as a keyword, so that we can be ** sure it is only being called from the top-most prompt level ** The file saveload.tex in the dev directory describes the saved format ** in more detail. Most of the work will be done from inside GASMAN, because ** we need to fiddle with Bag internals somewhat ** ** The return value is either True or Fail
*/
#ifdef USE_GASMAN
static UInt NextSaveIndex = 1;
staticvoid AddSaveIndex( Bag bag)
{
LINK_BAG(bag) = (Obj)NextSaveIndex++;
}
staticvoid RemoveSaveIndex( Bag bag)
{
LINK_BAG(bag) = bag;
}
SaveCStr("Counts and Sizes"); for (i = 0; i < GlobalBags.nr; i++) {
GAP_ASSERT(GlobalBags.cookie[i] != NULL);
}
SaveUInt(GlobalBags.nr);
SaveUInt(NextSaveIndex-1);
SaveUInt(GASMAN_USED_MEMORY());
SaveCStr("Loaded Modules");
SaveModules();
SaveCStr("Kernel to WS refs"); for (i = 0; i < GlobalBags.nr; i++)
{
GAP_ASSERT(GlobalBags.cookie[i] != NULL);
SaveCStr((constChar *)GlobalBags.cookie[i]);
SaveSubObj(*(GlobalBags.addr[i]));
}
}
if (!IsStringConv(fname))
ErrorQuit("usage: SaveWorkspace( )",0,0); // maybe expand fname starting with ~/...
fullname = Call1ArgsInNewReader(userHomeExpand, fname);
if (ModulesPreSave()) return Fail;
// Do a full garbage collection
CollectBags( 0, 1);
// Add indices in link words of all bags, for saving inter-bag references
NextSaveIndex = 1;
CallbackForAllBags( AddSaveIndex );
// Now do the work
result = Fail; if (!OpenForSave( fullname ))
{
result = True;
WriteSaveHeader();
SaveCStr("Bag data");
SortHandlers( 1 ); // Sort by address to speed up CookieOfHandler
CallbackForAllBags( SaveBagData );
CloseAfterSave();
}
// Finally, reset all the link words
CallbackForAllBags( RemoveSaveIndex );
// Restore situation by calling all post-save methods
ModulesPostSave();
return result;
}
/*************************************************************************** ** *F LoadWorkspace( <fname> ) . . . . . load the workspace to the named file ** ** 'LoadWorkspace' is the entry point to the workspace saving. It is not ** installed as a GAP function, but instead called from InitializeGap when ** the -L command-line flag is given ** ** The file saveload.tex in the dev directory describes the saved format ** in more detail. Most of the work will be done from inside GASMAN, because ** we need to fiddle with Bag internals somewhat **
*/ void LoadWorkspace( Char * fname )
{
UInt nGlobs, nBags, i, maxSize; Char buf[256];
Obj * glob;
// Open saved workspace
OpenForLoad( fname );
// Check file header
LoadCStr(buf,256); if (strncmp (buf, "GAP ", 4) != 0) {
Panic("File %s does not appear to be a GAP workspace", fname);
}
if (streq(buf, "GAP workspace")) {
LoadCStr(buf,256); if (!streq(buf, GetKernelDescription())) {
Panic("This workspace is not compatible with GAP kernel (%s, present: " "%s)", buf, GetKernelDescription());
}
LoadCStr(buf,256); #ifdef SYS_IS_64_BIT if (!streq(buf,"64 bit")) #else if (!streq(buf,"32 bit")) #endif
{
Panic("This workspace was created by a %s version of GAP", buf);
}
} else {
Panic("File %s probably isn't a GAP workspace", fname);
}
CheckEndiannessMarker();
LoadCStr(buf,256); if (!streq(buf,"Counts and Sizes"))
{
Panic("Bad divider");
}
// Make sure there is enough room, and signal GASMAN that // we are starting a restore
StartRestoringBags(nBags, maxSize);
// The restoring kernel must have at least as many compiled modules // as the saving one.
LoadCStr(buf,256); if (!streq(buf,"Loaded Modules"))
{
Panic("Bad divider");
}
LoadModules();
// Now the kernel variables that point into the workspace
LoadCStr(buf,256); if (!streq(buf,"Kernel to WS refs"))
{
Panic("Bad divider");
}
SortGlobals(); // globals by cookie for quick lookup // TODO: the goal here is to stop exporting `GlobalBags` completely... if (nGlobs != GlobalBags.nr) {
Panic("Wrong number of global bags in saved workspace %d %d",
(int)nGlobs, (int)GlobalBags.nr);
} for (i = 0; i < nGlobs; i++) {
LoadCStr(buf, 256);
glob = GlobalByCookie(buf); if (glob == (Obj *)0) {
Panic( "Global object cookie from workspace not found in kernel %s",
buf);
}
*glob = LoadSubObj(); if (SyDebugLoading)
Pr("Restored global %s\n", (Int)buf, 0);
}
LoadCStr(buf,256); if (!streq(buf,"Bag data"))
{
Panic("Bad divider");
}
SortHandlers(2); for (i = 0; i < nBags; i++)
LoadBagData();
FinishedRestoringBags();
CloseAfterLoad();
ModulesPostRestore();
}
staticvoid PrSavedObj( UInt x)
{ if ((x & 3) == 1)
Pr("Immediate integer %d\n", INT_INTOBJ((Obj)x), 0); elseif ((x & 3) == 2)
Pr("Immediate FFE %d %d\n", VAL_FFE((Obj)x), SIZE_FF(FLD_FFE((Obj)x))); else
Pr("Reference to bag number %d\n",x>>2, 0);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.