Skip to content

Commit

Permalink
vm: support self-executing image file
Browse files Browse the repository at this point in the history
  • Loading branch information
jckarter committed Nov 27, 2011
1 parent 7838538 commit 8b75193
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 2 deletions.
11 changes: 10 additions & 1 deletion vm/factor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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();
Expand Down
43 changes: 42 additions & 1 deletion vm/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

}
6 changes: 6 additions & 0 deletions vm/image.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions vm/vm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 8b75193

Please sign in to comment.