Mercurial > repos > rhope
view worker.c @ 75:0083b2f7b3c7
Partially working implementation of List. Modified build scripts to allow use of other compilers. Fixed some bugs involving method implementations on different types returning different numbers of outputs. Added Fold to the 'builtins' in the comipler.
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 06 Jul 2010 07:52:59 -0400 |
parents | 914ad38f9b59 |
children |
line wrap: on
line source
#include "structs.h" #include "interp.h" #include "datum.h" #include "parser.h" #include "saveload.h" #include <stdlib.h> #include <string.h> int vis_worker_from_string(datum ** inputlist, queue_entry * worker_entry) { int i; worker_datum * work; datum * output = new_datum(BUILTIN_TYPE_WORKER, 1, sizeof(worker_datum), worker_entry->instance->def->program); work = output->c.generic.data; find_worker(inputlist[0]->c.generic.data, NULL, NULL, worker_entry->instance->def->program, &work->def); if(work->def) add_program_ref(work->def->program); for(i = 0; i < 32; ++i) work->params[i] = NULL; release_ref(inputlist[0]); inputlist[0] = output; return 0; } BOOL list_to_array(datum * list_dat, datum ** out_params, int num) { int i; datum * params[2]; list_data * list = list_dat->c.generic.data; if(num > list->num_entries) { return FALSE; } for(i = 0; i < num; ++i) out_params[i] = add_ref(list->entries[i]); release_ref(list_dat); return TRUE; } datum * array_to_list(datum ** in_params, int num, program * prog) { int i; datum * params[2]; params[0] = create_list(prog); for(i = 0; i < num; ++i) { params[1] = in_params[i]; vis_list_append(params, NULL); } return params[0]; } int worker_populate_inputs(datum * inputWorker, datum * ioList, datum ** inputlist) { int i,j=0; worker_datum * work = inputWorker->c.generic.data; list_data * list = ioList->c.generic.data; for(i = 0; i < work->def->num_inputs; ++i) if(work->params[i]) { DEBUGPRINTF("Setting input %d to %X from worker object\n", i, work->params[i]); inputlist[i] = add_ref(work->params[i]); } else { if(j < list->num_entries) { DEBUGPRINTF("Setting input %d to %X from input %d\n", i, list->entries[j], j); inputlist[i] = add_ref(list->entries[j]); ++j; } else { ERRORPRINTF("Error: List passed to Do@Worker doesn't have enough entries for worker %s\n", work->def->name); return -1; } } return 0; } int vis_worker_do(datum ** inputlist, queue_entry * worker_entry) { //int i,j; worker_datum * work; //worker_def * def; //list_data * list; datum * inputWorker = inputlist[0]; datum * ioList = inputlist[1]; int returnval; //release_ref(inputlist[0]); work = inputlist[0]->c.generic.data; //list_to_array(inputlist[1], inputlist, work->def->num_inputs); /*list = inputlist[1]->c.generic.data; j = 0; DEBUGPRINTF("vis_worker_do: def_name: %s, num_inputs = %d, list length = %d\n", work->def->name, work->def->num_inputs, list->num_entries); for(i = 0; i < work->def->num_inputs; ++i) if(work->params[i]) { DEBUGPRINTF("Setting input %d to %X from worker object\n", i, work->params[i]); inputlist[i] = add_ref(work->params[i]); } else { DEBUGPRINTF("Setting input %d to %X from input %d, company name: %s\n", i, list->entries[j], j, list->entries[j]->company->name); inputlist[i] = add_ref(list->entries[j]); ++j; }*/ returnval = worker_populate_inputs(inputWorker, ioList, inputlist); release_ref(ioList); if(returnval) { print_stack_trace(worker_entry->instance); return returnval; } if(work->def->program != worker_entry->instance->def->program) { prep_program(work->def->program ); } returnval = execute_def(work->def, *worker_entry, inputlist, pack_list_sub_callback); if(returnval == 0) { inputlist[0] = array_to_list(inputlist, work->def->num_outputs, worker_entry->instance->def->program); /*vis_list_new(params, NULL); DEBUGPRINTF("params[0] after vis_list_new: %X\n", params[0]); for(i = 0; i < work->def->num_outputs; ++i) { params[1] = inputlist[i]; vis_list_append(params, NULL); DEBUGPRINTF("params[0] after vis_list_append: %X\n", params[0]); } inputlist[0] = params[0];*/ } release_ref(inputWorker); return returnval; } int vis_worker_setinput(datum ** inputlist, queue_entry * worker_entry) { worker_datum * work; inputlist[0] = copy_datum(inputlist[0], 0); work = inputlist[0]->c.generic.data; if(inputlist[1]->c.integers.num_a < 32) work->params[inputlist[1]->c.integers.num_a] = inputlist[2]; else { puts("Error: Visuality currently only supports 32 inputs\n"); execute_active = FALSE; return -1; } release_ref(inputlist[1]); inputlist[1] = inputlist[2] = NULL; return 0; } int vis_worker_add_worker_call(datum ** inputlist, queue_entry * worker_entry) { worker_datum * add_work; worker_datum * work = inputlist[0]->c.generic.data; int index; add_work = inputlist[1]->c.generic.data; /*index = add_work->def - work->def->program->deflist; DEBUGPRINTF("work->def: %X, deflist: %X\n", work->def, worker_entry->instance->def->program->deflist); DEBUGPRINTF("work->def->name: %X\n", work->def->name);*/ index = add_worker_to_def(work->def, add_work->def, 1.0, 1.0); release_ref(inputlist[1]); inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program); inputlist[1]->c.integers.num_a = index; return 0; } int vis_worker_add_wire(datum ** inputlist, queue_entry * worker_entry) { worker_datum * work = inputlist[0]->c.generic.data; add_wire(work->def, inputlist[1]->c.integers.num_a, inputlist[2]->c.integers.num_a, inputlist[3]->c.integers.num_a, inputlist[4]->c.integers.num_a); release_ref(inputlist[1]); release_ref(inputlist[2]); release_ref(inputlist[3]); release_ref(inputlist[4]); return 0; } void list_change_program(list_data * list, program * new_prog) { int i; for(i = 0; i < list->num_entries; ++i) { if(list->entries[i] && list->entries[i]->company->type_id < USER_DEFINED_TYPES) { list->entries[i] = copy_datum(list->entries[i], 0); list->entries[i]->company = new_prog->companylist + list->entries[i]->company->type_id; if(list->entries[i]->company->type_id == BUILTIN_TYPE_LIST) list_change_program(list->entries[i]->c.generic.data, new_prog); } } } int vis_worker_add_constant(datum ** inputlist, queue_entry * worker_entry) { datum * constant = inputlist[1]; worker_datum * work = inputlist[0]->c.generic.data; int index = add_constant(work->def, "code generated", 1.0, 1.0); if(worker_entry->instance->def->program != work->def->program && constant->company->type_id < USER_DEFINED_TYPES) { constant = copy_datum(constant, 0); constant->company = work->def->program->companylist + constant->company->type_id; if(constant->company->type_id == BUILTIN_TYPE_LIST) { list_change_program(constant->c.generic.data, work->def->program); } } work->def->implement_func->workerlist[index].value_index = constant; inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program); inputlist[1]->c.integers.num_a = index; return 0; } int vis_worker_add_input(datum ** inputlist, queue_entry * worker_entry) { worker_datum * work = inputlist[0]->c.generic.data; int index = add_input_num(work->def, inputlist[1]->c.generic.data, inputlist[2]->c.integers.num_a, 1.0, 1.0); release_ref(inputlist[1]); release_ref(inputlist[2]); inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program); inputlist[1]->c.integers.num_a = index; return 0; } int vis_worker_add_output(datum ** inputlist, queue_entry * worker_entry) { worker_datum * work = inputlist[0]->c.generic.data; int index = add_output_num(work->def, inputlist[1]->c.generic.data, inputlist[2]->c.integers.num_a, 1.0, 1.0); release_ref(inputlist[1]); release_ref(inputlist[2]); inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program); inputlist[1]->c.integers.num_a = index; return 0; } int vis_worker_add_objectget(datum ** inputlist, queue_entry * worker_entry) { worker_datum * work = inputlist[0]->c.generic.data; int index = add_get_comp_room(work->def, inputlist[1]->c.generic.data, 1.0,1.0); release_ref(inputlist[1]); inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program); inputlist[1]->c.integers.num_a = index; return 0; } int vis_worker_add_objectset(datum ** inputlist, queue_entry * worker_entry) { worker_datum * work = inputlist[0]->c.generic.data; int index = add_set_comp_room(work->def, inputlist[1]->c.generic.data, 1.0,1.0); release_ref(inputlist[1]); inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program); inputlist[1]->c.integers.num_a = index; return 0; } int vis_worker_add_globalget(datum ** inputlist, queue_entry * worker_entry) { worker_datum * work = inputlist[0]->c.generic.data; int index; char * name = malloc(inputlist[1]->c.generic.len + inputlist[2]->c.generic.len + 1); memcpy(name, inputlist[1]->c.generic.data, inputlist[1]->c.generic.len); release_ref(inputlist[1]); strcat(name, "::"); strcat(name, inputlist[2]->c.generic.data); release_ref(inputlist[2]); index = add_global_get(work->def, name, 1.0,1.0); free(name); inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program); inputlist[1]->c.integers.num_a = index; return 0; } int vis_worker_add_globalset(datum ** inputlist, queue_entry * worker_entry) { worker_datum * work = inputlist[0]->c.generic.data; int index; char * name = malloc(inputlist[1]->c.generic.len + inputlist[2]->c.generic.len + 1); memcpy(name, inputlist[1]->c.generic.data, inputlist[1]->c.generic.len); release_ref(inputlist[1]); strcat(name, "::"); strcat(name, inputlist[2]->c.generic.data); release_ref(inputlist[2]); index = add_global_set(work->def, name, 1.0,1.0); free(name); inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program); inputlist[1]->c.integers.num_a = index; return 0; } int vis_worker_new(datum ** inputlist, queue_entry * worker_entry) { int i; datum * output = new_datum(BUILTIN_TYPE_WORKER, 1, sizeof(worker_datum), worker_entry->instance->def->program); worker_datum * work = output->c.generic.data; work->def = create_worker(worker_entry->instance->def->program, inputlist[0]->c.generic.data, 0, 0, USER_FLAG | WORKER_TYPE); add_program_ref(work->def->program); for(i = 0; i < 32; ++i) work->params[i] = NULL; release_ref(inputlist[0]); inputlist[0] = output; return 0; } int vis_worker_clear(datum ** inputlist, queue_entry * worker_entry) { int i; worker_datum * work = inputlist[0]->c.generic.data; VIS_EnterCriticalSection(work->def->implement_func->lock); for(i = 0; i < work->def->implement_func->num_workers; ++i) { if(work->def->implement_func->workerlist[i].type == CONSTANT) { release_ref(work->def->implement_func->workerlist[i].value_index); } } work->def->num_inputs = 0; work->def->num_outputs = 0; work->def->implement_func->num_workers = 0; work->def->implement_func->num_wires = 0; work->def->implement_func->dirty = TRUE; VIS_LeaveCriticalSection(work->def->implement_func->lock); return 0; } int vis_worker_uses(datum ** inputlist, queue_entry * worker_entry) { int i; worker_datum * work = inputlist[0]->c.generic.data; list_data * list = inputlist[1]->c.generic.data; char ** new_uses; if(list->num_entries) { new_uses = malloc(sizeof(char *) * list->num_entries); for(i = 0; i < list->num_entries; ++i) { if(list->entries[i]->company->type_id != BUILTIN_TYPE_STRING) { ERRORPUTS("List passed to Uses@Worker contains non-string value(s)\n"); execute_active = FALSE; return -1; } new_uses[i] = malloc(sizeof(char) * list->entries[i]->c.generic.len); memcpy(new_uses[i], list->entries[i]->c.generic.data, list->entries[i]->c.generic.len); } } else new_uses = NULL; if(work->def->uses_stores) free(work->def->uses_stores); work->def->uses_stores = new_uses; work->def->num_stores = list->num_entries; release_ref(inputlist[1]); return 0; } int vis_worker_setio_counts(datum ** inputlist, queue_entry * worker_entry) { int i; int new_inputs = inputlist[1]->c.integers.num_a; worker_datum * work = inputlist[0]->c.generic.data; release_ref(inputlist[1]); if(work->def->num_inputs < new_inputs) { work->def->input_types = realloc(work->def->input_types, sizeof(short)*new_inputs); for(i = work->def->num_inputs; i < new_inputs; ++i) work->def->input_types[i] = ANY_TYPE; } work->def->num_inputs = new_inputs; work->def->num_outputs = inputlist[2]->c.integers.num_a; release_ref(inputlist[2]); return 0; } int vis_program_new(datum ** inputlist, queue_entry * worker_entry) { program * prog = new_program(START_DEF_STORAGE, START_COMP_STORAGE); inputlist[0] = new_datum(BUILTIN_TYPE_PROGRAM, 2, 0, worker_entry->instance->def->program); inputlist[0]->c.generic.data = prog; inputlist[0]->c.generic.len = sizeof(program); //inputlist[0]->union_type = 1; return 0; } int vis_program_new_worker(datum ** inputlist, queue_entry * worker_entry) { int i; datum * output = new_datum(BUILTIN_TYPE_WORKER, 1, sizeof(worker_datum), worker_entry->instance->def->program); worker_datum * work = output->c.generic.data; add_program_ref(inputlist[0]->c.generic.data); work->def = create_worker(inputlist[0]->c.generic.data, inputlist[1]->c.generic.data, 0, 0, USER_FLAG | WORKER_TYPE); for(i = 0; i < 32; ++i) work->params[i] = NULL; release_ref(inputlist[1]); inputlist[1] = output; return 0; } int vis_program_add_worker(datum ** inputlist, queue_entry * worker_entry) { int i; worker_datum * work = inputlist[1]->c.generic.data; program * prog = inputlist[0]->c.generic.data; datum * output = new_datum(BUILTIN_TYPE_WORKER, 1, sizeof(worker_datum), worker_entry->instance->def->program); worker_datum * out_work = output->c.generic.data; add_program_ref(inputlist[0]->c.generic.data); out_work->def = create_worker(prog, work->def->name, work->def->num_inputs, work->def->num_outputs, WORKER_TYPE); out_work->def->implement_func = work->def->implement_func; out_work->def->type = work->def->type; if(work->def->type & USER_FLAG) out_work->def->program = work->def->program; for(i = 0; i < work->def->num_inputs; ++i) out_work->def->input_types[i] = out_work->def->input_types[i]; release_ref(inputlist[1]); inputlist[1] = output; return 0; } int vis_program_add_builtins(datum ** inputlist, queue_entry * worker_entry) { initpredefworkers((program *)inputlist[0]->c.generic.data); return 0; } int vis_program_run(datum ** inputlist, queue_entry * worker_entry) { datum * params[32]; defchunk * current; int i; program * prog = inputlist[0]->c.generic.data; params[0] = inputlist[1]; VIS_EnterCriticalSection(program_count_lock); ++program_count; VIS_LeaveCriticalSection(program_count_lock); prep_program(prog); add_program_ref(prog); init_custom_worker(-1, NULL, prog->defs->deflist, main_callback, add_ref(inputlist[0]), params); return 0; } int vis_program_find_worker(datum ** inputlist, queue_entry * worker_entry) { int i,returnval; worker_datum * work; worker_def * def; program * prog = inputlist[0]->c.generic.data; returnval = find_worker(inputlist[1]->c.generic.data, NULL, NULL, prog, &def); release_ref(inputlist[0]); if(returnval >= 0) { add_program_ref(prog); release_ref(inputlist[1]); inputlist[0] = new_datum(BUILTIN_TYPE_WORKER, 1, sizeof(worker_datum), worker_entry->instance->def->program); inputlist[1] = NULL; work = inputlist[0]->c.generic.data; work->def = def; for(i = 0; i < 32; ++i) work->params[i] = NULL; } else { inputlist[0] = NULL; } return 0; } void free_worker(worker_def * def) { int i; if(def->type & USER_FLAG && (def->type & TYPE_MASK) == WORKER_TYPE) { for(i = 0; i < def->implement_func->num_workers; ++i) if(def->implement_func->workerlist[i].type == CONSTANT) release_ref(def->implement_func->workerlist[i].value_index); free(def->implement_func->workerlist); free(def->implement_func->wirelist); free(def->implement_func->workers_to_wires_up); free(def->implement_func->workers_to_wires_down); free(def->implement_func); } free(def->name); free(def->input_types); free(def->output_types); } void free_company(company * comp) { free(comp->methodlist); free(comp->room_list); } void add_program_ref(program * prog) { VIS_EnterCriticalSection(prog->lock); ++prog->refcount; VIS_LeaveCriticalSection(prog->lock); } void release_program_ref(program * prog) { int i; defchunk * current, *temp; VIS_EnterCriticalSection(prog->lock); --prog->refcount; if(!prog->refcount) { VIS_LeaveCriticalSection(prog->lock); VIS_DeleteCriticalSection(prog->lock); current = prog->defs; while(current) { for(i = 0; i < current->num_defs; ++i) { free_worker(current->deflist + i); } current = current->next; } current = prog->defs; while(current) { temp = current; current = current->next; free(temp); } //FIXME: We can't currently free the object definitions because of issues related to global stores //for(i = 0; i < prog->num_companies; ++i) // free_company(prog->companylist + i); //free(prog->companylist); free(prog); } else { VIS_LeaveCriticalSection(prog->lock); } } /* int vis_worker_begin_transaction(datum ** inputlist, queue_entry * worker_entry) { worker_def * def; int returnval; datum * params[2]; int i; global_store * store; list_data * list = inputist[0]->c.generic.data; transaction * trans = malloc(sizeof(transaction) + list->num_entries - 1); trans->num_stores = list->num_entries; VIS_EnterCriticalSection(global_store_lock); for(i = 0; i < list->num_entries; ++i) { params[0] = global_store_dict; params[1] = add_ref(list->entries[i]); vis_dict_index(params, NULL); store = params[0]->c.generic.data; while(store->inuse) { VIS_LeaveCriticalSection(global_store_lock); #ifdef WIN32 Sleep(0); #else sleep(0); #endif VIS_EnterCriticalSection(global_store_lock); } store->inuse; trans->stores[i] = params[0]; } VIS_LeaveCriticalSection(global_store_lock; release_ref(inputlist[0]); def = deflist+inputlist[1]->c.integers.num_a; release_ref(inputlist[1]); list_to_array(inputlist[2], inputlist, def->num_inputs); returnval = execute_def_data(def, *worker_entry, inputlist, trasnaction_sub_callback, transaction); if(returnval == 0) inputlist[0] = array_to_list(inputlist, def->num_outputs); return returnval; } */