void factor_vm::default_parameters(vm_parameters *p)
{
+ p->embedded_image = false;
p->image_path = NULL;
p->datastack_size = 32 * sizeof(cell);
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();
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;
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;
+}
+
}
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;
};
struct vm_parameters {
+ bool embedded_image;
const vm_char *image_path;
const vm_char *executable_path;
cell datastack_size, retainstack_size, callstack_size;
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);