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