/* Save the current image to disk. We don't throw any exceptions here because if the 'then-die' argument is t it is not safe to do so. Instead we signal failure by returning false. */ bool factor_vm::save_image(const vm_char* saving_filename, const vm_char* filename) { image_header h; h.magic = image_magic; h.version = image_version; h.data_relocation_base = data->tenured->start; h.data_size = data->tenured->occupied_space(); h.code_relocation_base = code->allocator->start; h.code_size = code->allocator->occupied_space(); for (cell i = 0; i < special_object_count; i++) h.special_objects[i] = (save_special_p(i) ? special_objects[i] : false_object); FILE* file = OPEN_WRITE(saving_filename); if (file == NULL) return false; if (safe_fwrite(&h, sizeof(image_header), 1, file) != 1) return false; if (safe_fwrite((void*)data->tenured->start, h.data_size, 1, file) != 1) return false; if (safe_fwrite((void*)code->allocator->start, h.code_size, 1, file) != 1) return false; if (raw_fclose(file) == -1) return false; if (!move_file(saving_filename, filename)) return false; return true; }
/* This function also initializes the data and code heaps */ void factor_vm::load_image(vm_parameters* p) { FILE* file = open_image(p); if (file == NULL) { std::cout << "Cannot open image file: " << p->image_path << std::endl; char *msg = threadsafe_strerror(errno); std::cout << "strerror:2: " << msg << std::endl; free(msg); exit(1); } image_header h; if (raw_fread(&h, sizeof(image_header), 1, file) != 1) fatal_error("Cannot read image header", 0); if (h.magic != image_magic) fatal_error("Bad image: magic number check failed", h.magic); if (h.version != image_version) fatal_error("Bad image: version number check failed", h.version); load_data_heap(file, &h, p); load_code_heap(file, &h, p); raw_fclose(file); /* Certain special objects in the image are known to the runtime */ memcpy(special_objects, h.special_objects, sizeof(special_objects)); cell data_offset = data->tenured->start - h.data_relocation_base; cell code_offset = code->allocator->start - h.code_relocation_base; fixup_heaps(data_offset, code_offset); /* Store image path name */ special_objects[OBJ_IMAGE] = allot_alien(false_object, (cell)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); if (file == NULL) { std::cout << "Cannot open image file: " << p->image_path << std::endl; char *msg = threadsafe_strerror(errno); std::cout << "strerror:2: " << msg << std::endl; free(msg); exit(1); } if (p->embedded_image) { embedded_image_footer footer; if (!read_embedded_image_footer(file, &footer)) { std::cout << "No embedded image" << std::endl; exit(1); } safe_fseek(file, (off_t)footer.image_offset, SEEK_SET); } image_header h; if (raw_fread(&h, sizeof(image_header), 1, file) != 1) fatal_error("Cannot read image header", 0); if (h.magic != image_magic) fatal_error("Bad image: magic number check failed", h.magic); if (h.version != image_version) fatal_error("Bad image: version number check failed", h.version); load_data_heap(file, &h, p); load_code_heap(file, &h, p); raw_fclose(file); // Certain special objects in the image are known to the runtime memcpy(special_objects, h.special_objects, sizeof(special_objects)); cell data_offset = data->tenured->start - h.data_relocation_base; cell code_offset = code->allocator->start - h.code_relocation_base; fixup_heaps(data_offset, code_offset); }
void factor_vm::primitive_fclose() { FILE* file = pop_file_handle(); if (raw_fclose(file) == -1) io_error_if_not_EINTR(); }