view saveload.c @ 168:d2b941f82d74

Fix type of list constants in inference pass and return type of some Array related workers
author Mike Pavone <pavone@retrodev.com>
date Sun, 01 May 2011 18:41:17 -0700
parents 76568becd6d6
children
line wrap: on
line source

#include "interp.h"
#include "structs.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/*
void save_program(char * filename)
{
	worker * aworkerlist;
	wire * awirelist;
	FILE * savefile;
	int def_num, version = 1;
	savefile = fopen(filename, "wb");
	if(!savefile)
		return;
	//deflist[current_def].num_workers = num_workers;
	//deflist[current_def].num_wires = num_wires;
	fwrite(&version, 4, 1, savefile);
	fwrite(&num_defs, 4, 1, savefile);
	fwrite(deflist, sizeof(worker_def), num_defs, savefile);
	for(def_num = 0; def_num < num_defs; ++def_num)
	{
		if(deflist[def_num].workerlist)
		{
			fwrite(&def_num, 4, 1, savefile);
			//fwrite(&(deflist[def_num].num_workers), 4, 1, savefile);
			fwrite(deflist[def_num].workerlist, sizeof(worker), deflist[def_num].num_workers, savefile);
			//fwrite(&(deflist[def_num].num_wires), 4, 1, savefile);
			fwrite(deflist[def_num].wirelist, sizeof(wire), deflist[def_num].num_wires, savefile);
		}
	}
	def_num = -1;
	fwrite(&def_num, 4, 1, savefile);
	fclose(savefile);
}*/

program * new_program(int def_storage, int comp_storage)
{
	defchunk * defs = malloc(sizeof(defchunk) + (def_storage - 1) * sizeof(worker_def));
	program * prog = malloc(sizeof(program));
	defs->num_defs = 0;
	defs->deflist[0].name = NULL;
	defs->defs_storage = def_storage;
	defs->next = NULL;
	prog->current = prog->defs = defs;
	//prog->deflist = malloc(sizeof(worker_def) * def_storage);
	//prog->num_defs = 0;
	//prog->defs_storage = def_storage;
	prog->companylist = malloc(sizeof(company) * comp_storage);
	prog->num_companies = 0;
	prog->companies_storage = comp_storage;
	prog->refcount = 1;
	VIS_InitializeCriticalSection(prog->lock);
	return prog;
}

int count_defs(defchunk * chunk)
{
	int total = 0;
	while(chunk)
	{
		total += chunk->num_defs;
		chunk = chunk->next;
	}
	return total;
}

void save_program(program * prog, char * filename)
{
	int version = 2;
	int total_bytes = 0;
	int zero = 0;
	int i;
	int num_defs;
	unsigned char size;
	custom_worker * aworker;
	//worker_def * deflist = prog->deflist;
	defchunk * defs = prog->defs;
	defchunk * current = defs;
	worker_def * deflist;
	FILE * savefile;
	savefile = fopen(filename, "wb");
	fwrite(&version, 4, 1, savefile);
	num_defs = count_defs(defs);
	fwrite(&(num_defs), 4, 1, savefile);
	while(current)
	{
		deflist = current->deflist;
		for(i = 0; i < current->num_defs; ++i)
		{
			size = strlen(deflist[i].name);
			fwrite(&size, 1, 1, savefile);
			fwrite(deflist[i].name, 1, size, savefile);
			total_bytes += (int)size + 1;
		}
		current = current->next;
	}
	if(total_bytes % 4 != 0)// pad to a 4 byte boundary
		fwrite(&zero, 1, 4-(total_bytes % 4), savefile);
	current = defs;
	while(current)
	{
		deflist = current->deflist;
		for(i = 0; i < current->num_defs; ++i)
		{
			if(deflist[i].type & USER_FLAG)
			{
				fwrite(&i, sizeof(int), 1, savefile);
				fwrite(&(deflist[i].num_inputs), sizeof(short), 1, savefile);
				fwrite(&(deflist[i].num_outputs), sizeof(short), 1, savefile);
				fwrite(&(deflist[i].type), sizeof(short), 1, savefile);
				fwrite(deflist[i].input_types, sizeof(short), deflist[i].num_inputs, savefile);
				fwrite(deflist[i].output_types, sizeof(short), deflist[i].num_outputs, savefile);
				total_bytes += sizeof(int) + (sizeof(short) * (3+deflist[i].num_inputs+deflist[i].num_outputs));
				if(total_bytes % 4 != 0)// pad to a 4 byte boundary
					fwrite(&zero, 1, 4-(total_bytes % 4), savefile);
				if((deflist[i].type & TYPE_MASK) == WORKER_TYPE)
				{
					aworker = deflist[i].implement_func;
					fwrite(&(aworker->num_workers), sizeof(int), 1, savefile);
					fwrite(aworker->workerlist, sizeof(worker), aworker->num_workers, savefile);
					fwrite(&(aworker->num_wires), sizeof(int), 1, savefile);
					fwrite(aworker->wirelist, sizeof(wire), aworker->num_wires, savefile);
				}
			}
		}
		current = current->next;
	}
	i = -1;
	fwrite(&i, sizeof(int), 1, savefile);
	fclose(savefile);
}

program * load_program(char * filename)
{
	custom_worker * aworker;
	int version;
	int i,j;
	int * def_lookup;
	char name[256];
	int total_bytes;
	int file_defs;
	unsigned char name_size;
	FILE * loadfile;
	char * code;
	int size;
	program * prog;
	loadfile = fopen(filename, "rb");
	if(!loadfile)
	{
		puts("Error: Could not open file");
		fflush(stdout);
		return NULL;
	}
	if(!strcmp(strrchr(filename,'.')+1, "vis"))
	{
		//TODO: Fixme
		/*fread(&version, 4, 1, loadfile);
		if(version != 2)
		{
			puts("Error: Can't read files of this version.");
			return NULL;
		}
		
		fread(&file_defs, 4, 1, loadfile);
		def_lookup = malloc(sizeof(int) * file_defs);
		total_bytes = 0;
		prog = new_program(file_defs, START_COMP_STORAGE);
		initworkers(prog);
		for(i = 0; i < file_defs; ++i)
		{
			fread(&name_size, 1, 1, loadfile);
			fread(name, 1, name_size, loadfile);
			name[name_size] = '\0';
			total_bytes += (int)name_size + 1;
			for(j = 0; j < prog->num_defs; ++j)
			{
				if(!strcmp(name, prog->deflist[j].name))
				{
					def_lookup[i] = j;
					break;
				}
			}
			if(j >= prog->num_defs) //couldn't find it in the list
			{
				def_lookup[i] = prog->num_defs;
				prog->deflist[prog->num_defs].name = malloc(name_size+1);
				strcpy(prog->deflist[prog->num_defs].name, name);
				++prog->num_defs;
			}
		}
		if(total_bytes % 4 != 0)// pad to a 4 byte boundary
			fread(&i, 1, 4-(total_bytes % 4), loadfile);
		do
		{
			fread(&i, sizeof(int), 1, loadfile);
			if(i >= 0)
			{
				i = def_lookup[i];
				fread(&(prog->deflist[i].num_inputs), sizeof(short), 1, loadfile);
				fread(&(prog->deflist[i].num_outputs), sizeof(short), 1, loadfile);
				fread(&(prog->deflist[i].type), sizeof(short), 1, loadfile);
				prog->deflist[i].input_types = malloc(sizeof(short) * (prog->deflist[i].num_inputs + prog->deflist[i].num_outputs));
				prog->deflist[i].output_types = prog->deflist[i].input_types + prog->deflist[i].num_inputs;
				fread(prog->deflist[i].input_types, sizeof(short), prog->deflist[i].num_inputs, loadfile);
				fread(prog->deflist[i].output_types, sizeof(short), prog->deflist[i].num_outputs, loadfile);
				total_bytes += sizeof(int) + (sizeof(short) * (3+prog->deflist[i].num_inputs+prog->deflist[i].num_outputs));
				if(total_bytes % 4 != 0)// pad to a 4 byte boundary
					fread(&j, 1, 4-(total_bytes % 4), loadfile);
				if((prog->deflist[i].type & TYPE_MASK) == WORKER_TYPE)
				{
					aworker = malloc(sizeof(custom_worker));
					prog->deflist[i].implement_func = aworker;
					fread(&(aworker->num_workers), sizeof(int), 1, loadfile);
					aworker->workerlist = malloc(sizeof(worker) * (aworker->num_workers + 512));
					fread(aworker->workerlist, sizeof(worker), aworker->num_workers, loadfile);
					fread(&(aworker->num_wires), sizeof(int), 1, loadfile);
					aworker->wirelist = malloc(sizeof(wire) * (aworker->num_wires + 1024));
					fread(aworker->wirelist, sizeof(wire), aworker->num_wires, loadfile);
					aworker->workers_to_wires_down = malloc(sizeof(int) * (aworker->num_wires + 1024));
					aworker->workers_to_wires_up = malloc(sizeof(int) * (aworker->num_wires + 1024));
					for(j = 0; j < aworker->num_workers; ++j)
						if(aworker->workerlist[j].type == 2)
							aworker->workerlist[j].value_index = def_lookup[aworker->workerlist[j].value_index];
				}
			}
		}while(i >= 0);*/
	}
	else
	{
		//Read text program
		fflush(stdout);
		fseek(loadfile, 0, SEEK_END);
		size = ftell(loadfile);
		fseek(loadfile, 0, SEEK_SET);
		fflush(stdout);
		code = malloc(size+1);
		fread(code, 1, size, loadfile);
		fclose(loadfile);
//		num_defs = 0;
		fflush(stdout);
		prog = new_program(START_DEF_STORAGE, START_COMP_STORAGE);
		initpredefworkers(prog);
		fflush(stdout);	
		parse(code, size, prog);
		free(code);
		
//		num_workers = deflist[0].num_workers;
//		num_wires = deflist[0].num_wires;
	}
	return prog;
}

/*
void load_program(char * filename)
{
	worker * aworkerlist;
	wire * awirelist;
	FILE * loadfile;
	char * code;
	int size;
	int def_num, version;
	loadfile = fopen(filename, "rb");
	if(!loadfile)
	{
		puts("Error: Could not open file");
		return;
	}
	if(!strcmp(strrchr(filename,'.')+1, "vis"))
	{
		//Read binary program
		fread(&version, 4, 1, loadfile);
		if(version != 1)
		{
			puts("Error: Can't read files of this version.");
			return;
		}
		//program * new_program = malloc(sizeof(program));
	//	strcpy(program->filename, filename);
		fread(&num_defs, 4, 1, loadfile);
		//program->defs_storage = program->num_defs + 512;
		//new_program->deflist = malloc(sizeof(worker_def) * (program->defs_storaage));
		fread(deflist, sizeof(worker_def), num_defs, loadfile);
		fread(&def_num, 4, 1, loadfile);
		while(def_num >= 0 && !feof(loadfile))
		{
			deflist[def_num].workerlist = malloc((deflist[def_num].num_workers+512)*sizeof(worker));
			fread(deflist[def_num].workerlist, sizeof(worker), deflist[def_num].num_workers, loadfile);
			deflist[def_num].wirelist = malloc((deflist[def_num].num_wires+1024)*sizeof(wire));
			fread(deflist[def_num].wirelist, sizeof(wire), deflist[def_num].num_wires, loadfile);
			deflist[def_num].workers_to_wires_up = malloc((deflist[def_num].num_wires+1024)*sizeof(int));
			deflist[def_num].workers_to_wires_down = malloc((deflist[def_num].num_wires+1024)*sizeof(int));
			fread(&def_num, 4, 1, loadfile);
		}
		fclose(loadfile);
		num_workers = deflist[0].num_workers;
		num_wires = deflist[0].num_wires;
		initpredefworkers();
	}
	else
	{
		//Read text program
		fseek(loadfile, 0, SEEK_END);
		size = ftell(loadfile);
		fseek(loadfile, 0, SEEK_SET);
		code = malloc(size+1);
		fread(code, 1, size, loadfile);
		num_defs = 0;
		initpredefworkers();
		parse(code, size);
		num_workers = deflist[0].num_workers;
		num_wires = deflist[0].num_wires;
	}
}*/