parent
101065e74f
commit
c6d1bd6b25
|
@ -532,7 +532,6 @@ tuple
|
|||
{ "dll-valid?" "alien" }
|
||||
{ "unimplemented" "kernel.private" }
|
||||
{ "gc-reset" "memory" }
|
||||
{ "(save-image*)" "memory" }
|
||||
}
|
||||
[ >r first2 r> make-primitive ] each-index
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ ARTICLE: "images" "Images"
|
|||
"The current image can be saved; the image contains a complete dump of all data and code in the current Factor instance:"
|
||||
{ $subsection save }
|
||||
{ $subsection save-image }
|
||||
{ $subsection save-image* }
|
||||
{ $subsection save-image-and-exit }
|
||||
"To start Factor with a custom image, use the " { $snippet "-i=" { $emphasis "image" } } " command line switch; see " { $link "runtime-cli-args" } "."
|
||||
{ $see-also "tools.memory" } ;
|
||||
|
@ -57,10 +56,6 @@ HELP: save-image ( path -- )
|
|||
{ $values { "path" "a pathname string" } }
|
||||
{ $description "Saves a snapshot of the heap to the given file, overwriting the file if it already exists." } ;
|
||||
|
||||
HELP: save-image* ( path arguments -- )
|
||||
{ $values { "path" "a pathname string" } { "arguments" "a commandline string" } }
|
||||
{ $description "Saves a snapshot of the heap to the given file, overwriting the file if it already exists. The image is formatted so that Unix systems can execute the image directly using the shellscript #! syntax. The saved image will start the current VM with the given commandline arguments when executed." } ;
|
||||
|
||||
HELP: save-image-and-exit ( path -- )
|
||||
{ $values { "path" "a pathname string" } }
|
||||
{ $description "Saves a snapshot of the heap to the given file, overwriting the file if it already exists. This word compacts the code heap and immediately exits Factor, since the Factor VM cannot continue executing after compiled code blocks have been moved around." } ;
|
||||
|
|
|
@ -13,7 +13,3 @@ IN: memory
|
|||
pusher [ each-object ] dip >array ; inline
|
||||
|
||||
: save ( -- ) image save-image ;
|
||||
|
||||
: save-image* ( path args -- )
|
||||
"#!" vm append swap "-shebang\n" 3array " " join
|
||||
(save-image*) ; inline
|
||||
|
|
13
vm/factor.c
13
vm/factor.c
|
@ -140,8 +140,13 @@ void init_factor_from_args(F_CHAR *image, int argc, F_CHAR **argv, bool embedded
|
|||
|
||||
CELL i;
|
||||
|
||||
posix_argc = argc;
|
||||
posix_argv = safe_malloc(argc * sizeof(F_CHAR*));
|
||||
posix_argv[0] = safe_strdup(argv[0]);
|
||||
|
||||
for(i = 1; i < argc; i++)
|
||||
{
|
||||
posix_argv[i] = safe_strdup(argv[i]);
|
||||
if(factor_arg(argv[i],STR_FORMAT("-datastack=%d"),&p.ds_size));
|
||||
else if(factor_arg(argv[i],STR_FORMAT("-retainstack=%d"),&p.rs_size));
|
||||
else if(factor_arg(argv[i],STR_FORMAT("-generations=%d"),&p.gen_count));
|
||||
|
@ -155,10 +160,6 @@ void init_factor_from_args(F_CHAR *image, int argc, F_CHAR **argv, bool embedded
|
|||
p.fep = true;
|
||||
else if(STRNCMP(argv[i],STR_FORMAT("-i="),3) == 0)
|
||||
p.image = argv[i] + 3;
|
||||
else if(STRCMP(argv[i],STR_FORMAT("-shebang")) == 0 && i < argc)
|
||||
{
|
||||
p.image = argv[--argc];
|
||||
}
|
||||
else if(STRCMP(argv[i],STR_FORMAT("-console")) == 0)
|
||||
p.console = true;
|
||||
else if(STRCMP(argv[i],STR_FORMAT("-no-stack-traces")) == 0)
|
||||
|
@ -193,6 +194,10 @@ void init_factor_from_args(F_CHAR *image, int argc, F_CHAR **argv, bool embedded
|
|||
|
||||
c_to_factor_toplevel(userenv[BOOT_ENV]);
|
||||
unnest_stacks();
|
||||
|
||||
for(i = 0; i < argc; i++)
|
||||
free(posix_argv[i]);
|
||||
free(posix_argv);
|
||||
}
|
||||
|
||||
char *factor_eval_string(char *string)
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
int posix_argc;
|
||||
F_CHAR **posix_argv;
|
||||
|
||||
DLLEXPORT void init_factor_from_args(F_CHAR *image, int argc, F_CHAR **argv, bool embedded);
|
||||
DLLEXPORT char *factor_eval_string(char *string);
|
||||
DLLEXPORT void factor_eval_free(char *result);
|
||||
|
|
75
vm/image.c
75
vm/image.c
|
@ -80,12 +80,6 @@ void load_image(F_PARAMETERS *p)
|
|||
F_HEADER h;
|
||||
fread(&h,sizeof(F_HEADER),1,file);
|
||||
|
||||
if(h.magic_bytes[0] == '#' && h.magic_bytes[1] == '!')
|
||||
{
|
||||
fseek(file,IMAGE_SHEBANG_BLOCK_SIZE,SEEK_SET);
|
||||
fread(&h,sizeof(F_HEADER),1,file);
|
||||
}
|
||||
|
||||
if(h.magic != IMAGE_MAGIC)
|
||||
fatal_error("Bad image: magic number check failed",h.magic);
|
||||
|
||||
|
@ -107,11 +101,22 @@ void load_image(F_PARAMETERS *p)
|
|||
}
|
||||
|
||||
/* Save the current image to disk */
|
||||
static bool save_image_to_file(FILE *file)
|
||||
bool save_image(const F_CHAR *filename)
|
||||
{
|
||||
F_ZONE *tenured = &data_heap->generations[TENURED];
|
||||
FILE* file;
|
||||
F_HEADER h;
|
||||
|
||||
FPRINTF(stderr,"*** Saving %s...\n",filename);
|
||||
|
||||
file = OPEN_WRITE(filename);
|
||||
if(file == NULL)
|
||||
{
|
||||
fprintf(stderr,"Cannot open image file: %s\n",strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
F_ZONE *tenured = &data_heap->generations[TENURED];
|
||||
|
||||
h.magic = IMAGE_MAGIC;
|
||||
h.version = IMAGE_VERSION;
|
||||
h.data_relocation_base = tenured->start;
|
||||
|
@ -156,49 +161,6 @@ static bool save_image_to_file(FILE *file)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool save_image(const F_CHAR *filename)
|
||||
{
|
||||
FILE* file;
|
||||
|
||||
FPRINTF(stderr,"*** Saving %s...\n",filename);
|
||||
|
||||
file = OPEN_WRITE(filename);
|
||||
if(file == NULL)
|
||||
{
|
||||
fprintf(stderr,"Cannot open image file: %s\n",strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return save_image_to_file(file);
|
||||
}
|
||||
|
||||
bool save_image_shebang(const F_CHAR *filename, const char *shebang)
|
||||
{
|
||||
FILE* file;
|
||||
|
||||
FPRINTF(stderr,"*** Saving %s...\n",filename);
|
||||
|
||||
file = OPEN_WRITE(filename);
|
||||
if(file == NULL)
|
||||
{
|
||||
fprintf(stderr,"Cannot open image file: %s\n",strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char shebang_block[IMAGE_SHEBANG_BLOCK_SIZE];
|
||||
strncpy(shebang_block,shebang,IMAGE_SHEBANG_BLOCK_SIZE-1);
|
||||
shebang_block[IMAGE_SHEBANG_BLOCK_SIZE-1] = 0;
|
||||
|
||||
if(fwrite(shebang_block,IMAGE_SHEBANG_BLOCK_SIZE,1,file) != 1)
|
||||
{
|
||||
fprintf(stderr,"Save #! block failed: %s\n",strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
return save_image_to_file(file);
|
||||
}
|
||||
|
||||
DEFINE_PRIMITIVE(save_image)
|
||||
{
|
||||
/* do a full GC to push everything into tenured space */
|
||||
|
@ -207,17 +169,6 @@ DEFINE_PRIMITIVE(save_image)
|
|||
save_image(unbox_native_string());
|
||||
}
|
||||
|
||||
DEFINE_PRIMITIVE(save_image_shebang)
|
||||
{
|
||||
/* do a full GC to push everything into tenured space */
|
||||
gc();
|
||||
|
||||
char *shebang = unbox_char_string();
|
||||
F_CHAR *path = unbox_native_string();
|
||||
|
||||
save_image_shebang(path, shebang);
|
||||
}
|
||||
|
||||
DEFINE_PRIMITIVE(save_image_and_exit)
|
||||
{
|
||||
F_CHAR *path = unbox_native_string();
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
#define IMAGE_MAGIC 0x0f0e0d0c
|
||||
#define IMAGE_VERSION 4
|
||||
|
||||
#define IMAGE_SHEBANG_BLOCK_SIZE 512
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
CELL magic;
|
||||
char magic_bytes[sizeof(CELL)];
|
||||
};
|
||||
CELL magic;
|
||||
CELL version;
|
||||
/* all pointers in the image file are relocated from
|
||||
relocation_base to here when the image is loaded */
|
||||
|
@ -44,10 +39,8 @@ typedef struct {
|
|||
void load_image(F_PARAMETERS *p);
|
||||
void init_objects(F_HEADER *h);
|
||||
bool save_image(const F_CHAR *file);
|
||||
bool save_image_shebang(const F_CHAR *file, const char *shebang);
|
||||
|
||||
DECLARE_PRIMITIVE(save_image);
|
||||
DECLARE_PRIMITIVE(save_image_shebang);
|
||||
DECLARE_PRIMITIVE(save_image_and_exit);
|
||||
|
||||
/* relocation base of currently loaded image's data heap */
|
||||
|
|
|
@ -149,5 +149,4 @@ void *primitives[] = {
|
|||
primitive_dll_validp,
|
||||
primitive_unimplemented,
|
||||
primitive_gc_reset,
|
||||
primitive_save_image_shebang,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue