vm: support self-executing image file
parent
14031d8794
commit
cca526df73
|
@ -10,6 +10,7 @@ void init_globals()
|
|||
|
||||
void factor_vm::default_parameters(vm_parameters *p)
|
||||
{
|
||||
p->embedded_image = false;
|
||||
p->image_path = NULL;
|
||||
|
||||
p->datastack_size = 32 * sizeof(cell);
|
||||
|
@ -118,7 +119,15 @@ void factor_vm::init_factor(vm_parameters *p)
|
|||
p->executable_path = executable_path;
|
||||
|
||||
if(p->image_path == NULL)
|
||||
p->image_path = default_image_path();
|
||||
{
|
||||
if (embedded_image_p())
|
||||
{
|
||||
p->embedded_image = true;
|
||||
p->image_path = p->executable_path;
|
||||
}
|
||||
else
|
||||
p->image_path = default_image_path();
|
||||
}
|
||||
|
||||
srand((unsigned int)nano_count());
|
||||
init_ffi();
|
||||
|
|
43
vm/image.cpp
43
vm/image.cpp
|
@ -219,11 +219,37 @@ void factor_vm::fixup_code(cell data_offset, cell code_offset)
|
|||
code->allocator->iterate(updater,fixup);
|
||||
}
|
||||
|
||||
FILE* factor_vm::open_image(vm_parameters *p)
|
||||
{
|
||||
if (p->embedded_image)
|
||||
{
|
||||
FILE *file = OPEN_READ(p->executable_path);
|
||||
if (file == NULL)
|
||||
{
|
||||
std::cout << "Cannot open embedded image" << std::endl;
|
||||
std::cout << strerror(errno) << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
safe_fseek(file, -sizeof(embedded_image_footer), SEEK_END);
|
||||
embedded_image_footer footer;
|
||||
safe_fread(&footer, sizeof(embedded_image_footer), 1, file);
|
||||
if (footer.magic != image_magic)
|
||||
{
|
||||
std::cout << "No embedded image" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
safe_fseek(file, footer.image_offset, SEEK_SET);
|
||||
return file;
|
||||
}
|
||||
else
|
||||
return OPEN_READ(p->image_path);
|
||||
}
|
||||
|
||||
/* Read an image file from disk, only done once during startup */
|
||||
/* This function also initializes the data and code heaps */
|
||||
void factor_vm::load_image(vm_parameters *p)
|
||||
{
|
||||
FILE *file = OPEN_READ(p->image_path);
|
||||
FILE *file = open_image(p);
|
||||
if(file == NULL)
|
||||
{
|
||||
std::cout << "Cannot open image file: " << p->image_path << std::endl;
|
||||
|
@ -339,4 +365,19 @@ void factor_vm::primitive_save_image_and_exit()
|
|||
exit(1);
|
||||
}
|
||||
|
||||
bool factor_vm::embedded_image_p()
|
||||
{
|
||||
const vm_char *vm_path = vm_executable_path();
|
||||
if (!vm_path)
|
||||
return false;
|
||||
FILE *file = OPEN_READ(vm_path);
|
||||
if (!file)
|
||||
return false;
|
||||
safe_fseek(file, -sizeof(embedded_image_footer), SEEK_END);
|
||||
embedded_image_footer footer;
|
||||
safe_fread(&footer, sizeof(embedded_image_footer), 1, file);
|
||||
fclose(file);
|
||||
return footer.magic == image_magic;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,11 @@ namespace factor
|
|||
static const cell image_magic = 0x0f0e0d0c;
|
||||
static const cell image_version = 4;
|
||||
|
||||
struct embedded_image_footer {
|
||||
cell magic;
|
||||
cell image_offset;
|
||||
};
|
||||
|
||||
struct image_header {
|
||||
cell magic;
|
||||
cell version;
|
||||
|
@ -28,6 +33,7 @@ struct image_header {
|
|||
};
|
||||
|
||||
struct vm_parameters {
|
||||
bool embedded_image;
|
||||
const vm_char *image_path;
|
||||
const vm_char *executable_path;
|
||||
cell datastack_size, retainstack_size, callstack_size;
|
||||
|
|
|
@ -610,7 +610,9 @@ struct factor_vm
|
|||
void primitive_save_image_and_exit();
|
||||
void fixup_data(cell data_offset, cell code_offset);
|
||||
void fixup_code(cell data_offset, cell code_offset);
|
||||
FILE *open_image(vm_parameters *p);
|
||||
void load_image(vm_parameters *p);
|
||||
bool embedded_image_p();
|
||||
|
||||
// callstack
|
||||
template<typename Iterator> void iterate_callstack_object(callstack *stack_, Iterator &iterator);
|
||||
|
|
Loading…
Reference in New Issue