factor/native/image.c

139 lines
3.1 KiB
C
Raw Normal View History

2004-07-16 02:26:21 -04:00
#include "factor.h"
2005-05-10 22:30:58 -04:00
void init_objects(HEADER *h)
{
int i;
for(i = 0; i < USER_ENV; i++)
userenv[i] = F;
executing = F;
userenv[GLOBAL_ENV] = h->global;
userenv[BOOT_ENV] = h->boot;
T = h->t;
bignum_zero = h->bignum_zero;
bignum_pos_one = h->bignum_pos_one;
bignum_neg_one = h->bignum_neg_one;
}
2005-05-09 22:34:47 -04:00
void load_image(char* filename, int literal_table)
2004-07-16 02:26:21 -04:00
{
FILE* file;
HEADER h;
2004-12-25 02:55:03 -05:00
HEADER_2 ext_h;
printf("Loading %s...",filename);
2004-08-20 18:48:08 -04:00
2004-07-16 02:26:21 -04:00
file = fopen(filename,"rb");
if(file == NULL)
2004-08-20 18:48:08 -04:00
fatal_error("Cannot open image for reading",errno);
2004-07-16 02:26:21 -04:00
2004-12-25 02:55:03 -05:00
/* read header */
{
/* read it in native byte order */
fread(&h,sizeof(HEADER)/sizeof(CELL),sizeof(CELL),file);
if(h.magic != IMAGE_MAGIC)
fatal_error("Bad magic number",h.magic);
if(h.version == IMAGE_VERSION)
fread(&ext_h,sizeof(HEADER_2)/sizeof(CELL),sizeof(CELL),file);
else if(h.version == IMAGE_VERSION_0)
{
2005-05-09 22:34:47 -04:00
ext_h.size = literal_table;
2004-12-25 02:55:03 -05:00
ext_h.literal_top = 0;
2005-05-09 22:34:47 -04:00
ext_h.literal_max = literal_table;
2004-12-25 02:55:03 -05:00
ext_h.relocation_base = compiling.base;
}
else
fatal_error("Bad version number",h.version);
}
/* read data heap */
{
CELL size = h.size / CELLS;
allot(h.size);
2005-05-11 00:43:52 -04:00
if(size != fread((void*)tenured.base,sizeof(CELL),size,file))
2004-12-25 02:55:03 -05:00
fatal_error("Wrong data heap length",h.size);
2005-05-11 00:43:52 -04:00
tenured.here = tenured.base + h.size;
2004-12-25 02:55:03 -05:00
data_relocation_base = h.relocation_base;
}
/* read code heap */
{
CELL size = ext_h.size;
if(size + compiling.base >= compiling.limit)
fatal_error("Code heap too large",ext_h.size);
if(h.version == IMAGE_VERSION
&& size != fread((void*)compiling.base,1,size,file))
fatal_error("Wrong code heap length",ext_h.size);
compiling.here = compiling.base + ext_h.size;
literal_top = compiling.base + ext_h.literal_top;
literal_max = compiling.base + ext_h.literal_max;
compiling.here = compiling.base + ext_h.size;
code_relocation_base = ext_h.relocation_base;
}
2004-07-16 02:26:21 -04:00
fclose(file);
printf(" relocating...");
fflush(stdout);
2005-05-10 22:30:58 -04:00
init_objects(&h);
2004-12-25 02:55:03 -05:00
relocate_data();
relocate_code();
printf(" done\n");
fflush(stdout);
2004-07-16 02:26:21 -04:00
}
bool save_image(char* filename)
{
FILE* file;
HEADER h;
2004-12-25 02:55:03 -05:00
HEADER_2 ext_h;
2004-07-16 02:26:21 -04:00
2004-08-20 18:48:08 -04:00
fprintf(stderr,"Saving %s...\n",filename);
2004-12-25 02:55:03 -05:00
2004-07-16 02:26:21 -04:00
file = fopen(filename,"wb");
if(file == NULL)
2004-08-20 18:48:08 -04:00
fatal_error("Cannot open image for writing",errno);
2004-07-16 02:26:21 -04:00
h.magic = IMAGE_MAGIC;
h.version = IMAGE_VERSION;
2005-05-11 00:43:52 -04:00
h.relocation_base = tenured.base;
2004-08-20 18:48:08 -04:00
h.boot = userenv[BOOT_ENV];
2005-05-11 00:43:52 -04:00
h.size = tenured.here - tenured.base;
2004-08-20 18:48:08 -04:00
h.global = userenv[GLOBAL_ENV];
2005-05-10 22:30:58 -04:00
h.t = T;
h.bignum_zero = bignum_zero;
h.bignum_pos_one = bignum_pos_one;
h.bignum_neg_one = bignum_neg_one;
2004-07-16 02:26:21 -04:00
fwrite(&h,sizeof(HEADER),1,file);
2004-12-25 02:55:03 -05:00
ext_h.size = compiling.here - compiling.base;
ext_h.literal_top = literal_top - compiling.base;
ext_h.literal_max = literal_max - compiling.base;
ext_h.relocation_base = compiling.base;
fwrite(&ext_h,sizeof(HEADER_2),1,file);
2005-05-11 00:43:52 -04:00
fwrite((void*)tenured.base,h.size,1,file);
2004-12-25 02:55:03 -05:00
fwrite((void*)compiling.base,ext_h.size,1,file);
2004-07-16 02:26:21 -04:00
fclose(file);
return true;
}
void primitive_save_image(void)
{
F_STRING* filename;
2005-05-11 00:43:52 -04:00
/* do a full GC to push everything into tenured space */
garbage_collection(TENURED);
filename = untag_string(dpop());
save_image(to_c_string(filename,true));
2004-07-16 02:26:21 -04:00
}