]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: support self-executing image file
authorJoe Groff <arcata@gmail.com>
Sat, 19 Nov 2011 02:05:23 +0000 (18:05 -0800)
committerJoe Groff <arcata@gmail.com>
Sun, 27 Nov 2011 20:37:54 +0000 (12:37 -0800)
vm/factor.cpp
vm/image.cpp
vm/image.hpp
vm/vm.hpp

index bcb102b6e2b000632d718d00141b3d386efea1c3..dd9be27774b0474fc3dc521da412bd288d803cdd 100755 (executable)
@@ -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();
index d1851d6b3277afdf09e25fa0894cf846c590d832..d8c9f9f4701c987054019cd670473693518426a6 100755 (executable)
@@ -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;
+}
+
 }
index 40ffa28d114c4e70b0f248ef2afe127f5a3ee788..21cf8944d1282f6827ce2fa4bccdde62b5c4cdb9 100755 (executable)
@@ -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;
index 7193d50e2f9ef9427e03e61b0e7b94f339d3f0e7..f3bf5a06eff86c8aaad3fd1a764db5575843ddfa 100755 (executable)
--- a/vm/vm.hpp
+++ b/vm/vm.hpp
@@ -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);