Mercurial > repos > rhope
annotate interp.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 | 6202b866d72c |
children |
rev | line source |
---|---|
0 | 1 #ifdef WIN32 |
2 #include <windows.h> | |
3 #include <winsock.h> | |
4 #include <crtdbg.h> | |
5 #else | |
6 #ifdef SYLLABLE | |
7 #include <unistd.h> | |
8 #include <atheos/threads.h> | |
9 #else | |
10 #ifdef NINTENDO_DS | |
11 #include <nds.h> | |
12 #else | |
13 #include <unistd.h> | |
14 #include <pthread.h> | |
15 #endif | |
16 #endif | |
17 #endif | |
18 #include <stdio.h> | |
19 #include <stdlib.h> | |
20 #include <string.h> | |
21 #include <time.h> | |
22 #include "mt19937ar.h" | |
23 #include "interp.h" | |
24 #include "vis_threading.h" | |
25 #include "datum.h" | |
26 #include "parser.h" | |
27 #include "saveload.h" | |
28 | |
29 #ifdef TEXT_FILE_DEBUG | |
30 FILE * debugfile; | |
31 #endif | |
32 char debugbuffer[1024]; | |
33 | |
34 //extern HWND hWnd; | |
35 extern char new_name_buf[256]; | |
36 extern int buf_size; | |
37 | |
38 int lock_fail_counter; | |
39 int lock_counter; | |
40 | |
41 VIS_CRITICAL_SECTION(data_lock) | |
42 VIS_CRITICAL_SECTION(worker_queue_lock) | |
43 VIS_CRITICAL_SECTION(randlock) | |
44 VIS_Event(queue_add_event) | |
45 | |
46 int program_count=1; | |
47 VIS_CRITICAL_SECTION(program_count_lock) | |
48 | |
49 //#define ENABLE_PROFILING 1 | |
50 | |
51 #ifdef ENABLE_PROFILING | |
52 | |
53 __int64 vis_profile_start_times[NUM_PROFS]; | |
54 __int64 vis_profile_running_total[NUM_PROFS]; | |
55 int vis_profile_counts[NUM_PROFS]; | |
56 | |
57 __declspec(naked) | |
58 unsigned __int64 __cdecl rdtsc(void) | |
59 { | |
60 __asm | |
61 { | |
62 rdtsc | |
63 ret ; return value at EDX:EAX | |
64 } | |
65 } | |
66 | |
67 | |
68 #define PROF_INIT_CUSTOM 0 | |
69 #define PROF_WORKER_THREAD 1 | |
70 #define PROF_PROCESS_WORKER 2 | |
71 #define PROF_CLEANUP_CUSTOM 3 | |
72 #define PROF_SUB_CALLBACK 4 | |
73 #define PROF_CLEANUP_RELEASE_REFS 5 | |
74 #define PROF_CLEANUP_CHECK 6 | |
75 #define PROF_CLEANUP_FREELISTS 7 | |
76 #define PROF_PROCESS_OUTPUTS 8 | |
77 #define PROF_OPT_PREP_INPUT 9 | |
78 #define PROF_RUN_OPT 10 | |
79 #define PROF_ADDQUEUE 11 | |
80 #define PROF_ADDQUEUE_MALLOC 12 | |
81 #define PROF_OPT_LOOP 13 | |
82 #define PROF_EXECUTE_WORKER 14 | |
83 #define PROF_EXECUTE_OTHER 15 | |
84 #define PROF_PREP_MAGIC 16 | |
85 #define PROF_CONVERT_INPUTS 17 | |
86 #define PROF_EXECUTE_CUSTOM 18 | |
87 #define PROF_EXECUTE_BUILTIN 19 | |
88 #define PROF_EMPTYFUNC 20 | |
89 #define PROF_NOCODE 21 | |
90 #define PROF_LESSERWHOLE 22 | |
91 #define PROF_EQUALWHOLE 23 | |
92 #define PROF_PARTIAL_EXEC 24 | |
93 #define PROF_ADDWHOLE 25 | |
94 #define PROF_FULL_EXEC 26 | |
95 #define PROF_OPT_EXEC_USER 27 | |
96 #define PROF_OPT_EXEC_BUILT 28 | |
97 #define PROF_VIRTUAL_DECODE 27 | |
98 #define PROF_VIRTUAL_EXECUTE 28 | |
99 | |
100 | |
101 /*#define VIS_PROFILE_START(index) vis_profile_start_times[index] = rdtsc() | |
102 #define VIS_PROFILE_END(index) vis_profile_running_total[index] += (rdtsc()-vis_profile_start_times[index]); ++vis_profile_counts[index] | |
103 | |
104 #else | |
105 | |
106 #define VIS_PROFILE_START(index) | |
107 #define VIS_PROFILE_END(index)*/ | |
108 | |
109 #endif | |
110 | |
111 queue_entry * worker_queue; | |
112 queue_section first_section; | |
113 queue_section * current_section; | |
114 int queue_start; | |
115 int queue_len; | |
116 | |
117 BOOL execute_active=FALSE; | |
118 | |
119 char text_buf[256]; | |
120 int text_buf_size; | |
121 VIS_CRITICAL_SECTION(text_buf_lock) | |
122 | |
123 #ifdef WIN32 | |
124 WSADATA wsa_data; | |
125 #ifdef GUI_LIB | |
126 char errorbuffer[1024]; | |
127 #endif | |
128 #endif | |
129 | |
130 | |
131 worker_instance * main_instance; | |
132 | |
133 //company companylist[40]; | |
134 //int num_companies=0; | |
135 | |
136 datum * global_store_dict; | |
137 VIS_CRITICAL_SECTION(global_store_lock); | |
138 | |
139 | |
140 int empty_func(datum ** a, queue_entry * worker_entry) | |
141 { | |
142 return 0; | |
143 } | |
144 | |
145 worker_impl empty_test = empty_func; | |
146 /* | |
147 void set_in_child(worker_def * parent, int worker_num, BOOL * in_child, BOOL value, int exclude_worker) | |
148 { | |
149 int j,i = parent->workerlist[worker_num].wire_down_lookup; | |
150 if(exclude_worker >= 0 && exclude_worker == worker_num) | |
151 return; | |
152 in_child[worker_num] = value; | |
153 while(parent->wirelist[j=parent->workers_to_wires_down[i]].start_worker == worker_num && j >= 0) | |
154 set_in_child(parent, parent->wirelist[j].end_worker, in_child, value); | |
155 } | |
156 | |
157 void build_child_worker(worker_def * parent, int worker_num, int output_num) | |
158 { | |
159 int i,j, num_child_workers, num_child_wires, child_def; | |
160 BOOL * in_child = malloc(sizeof(BOOL)* parent->num_workers); | |
161 int * child_offsets = malloc(sizeof(int) * parent->num_workers); | |
162 for(i = 0; i < parent->num_workers; ++i) | |
163 { | |
164 in_child[i] = FALSE; | |
165 child_offsets[i] = -1; | |
166 } | |
167 i = parent->workerlist[worker_num].wire_down_lookup; | |
168 while(parent->wirelist[j=parent->workers_to_wires_down[i]].start_worker == worker_num && j >= 0) | |
169 { | |
170 if(parent->wirelist[j].output_num == output_num) | |
171 set_in_child(parent, parent->wirelist[j].end_worker, in_child, TRUE,-1); | |
172 } | |
173 i = parent->workerlist[worker_num].wire_down_lookup; | |
174 while(parent->wirelist[j=parent->workers_to_wires_down[i]].start_worker == worker_num && j >= 0) | |
175 { | |
176 if(parent->wirelist[j].output_num != output_num) | |
177 set_in_child(parent, parent->wirelist[j].end_worker, in_child, FALSE,-1); | |
178 } | |
179 for(i = 0; i < parent->num_workers; ++i) | |
180 { | |
181 if(i != worker_num && (parent->workerlist[i].type == 4 || (parent->workerlist[i].type == 2 && !in_child[i]))) | |
182 set_in_child(parent, i, in_child, FALSE); | |
183 } | |
184 for(i = 0; i < parent->num_workers; ++i) | |
185 { | |
186 if(in_child[i]) | |
187 child_offests[i] = num_child_workers++; | |
188 } | |
189 for(i = 0; i < parent->num_wires; ++i) | |
190 { | |
191 if(in_child[parent->wirelist[i].start_worker] || in_child[parent->wirelist[i].end_worker]) | |
192 ++num_child_wires; | |
193 } | |
194 child_def = num_defs++;//needs lock or atomic incrememnt | |
195 deflist[child_def].workerlist = malloc(sizeof(worker)*num_child_workers); | |
196 deflist[child_def].wirelist = malloc(sizeof(wire)*num_child_wires); | |
197 for(i = 0; i < parent->num_workers; ++i) | |
198 { | |
199 if(in_child[i]) | |
200 deflist[child_def].workerlist[child_offests[i]] = parent->workerlist[i]; | |
201 } | |
202 } */ | |
203 | |
204 #define MAX_TRACE_DEPTH 40 | |
205 | |
206 void print_stack_trace(worker_instance * stack_instance) | |
207 { | |
208 int i = 0; | |
209 ERRORPUTS("Stack trace:\n"); | |
210 while(stack_instance && i < MAX_TRACE_DEPTH) | |
211 { | |
212 ERRORPRINTF("%s\n", stack_instance->def->name); | |
213 stack_instance = stack_instance->caller_instance; | |
214 ++i; | |
215 } | |
216 if(stack_instance) | |
217 { | |
218 ERRORPUTS("Stack trace aborted after 40 entries\n"); | |
219 } | |
220 } | |
221 | |
222 void check_tail(worker_def * def) | |
223 { | |
224 custom_worker * worker = def->implement_func; | |
225 int i,j,k,endworker; | |
226 BOOL can_tail, outputs_handled[32]; | |
227 for(i = 0; i < worker->num_workers; ++i) | |
228 { | |
229 if(worker->workerlist[i].type == WORKER) | |
230 { | |
231 can_tail = TRUE; | |
232 for(j = 0; j < def->num_outputs; ++j) | |
233 outputs_handled[j] = FALSE; | |
234 j = worker->workerlist[i].wire_down_lookup; | |
235 while((k=worker->workers_to_wires_down[j]) >= 0 && worker->wirelist[k].start_worker == i) | |
236 { | |
237 endworker = worker->wirelist[k].end_worker; | |
238 if(worker->workerlist[endworker].type != OUTPUT || worker->workerlist[endworker].io_num != worker->wirelist[k].output_num) | |
239 { | |
240 can_tail = FALSE; | |
241 break; | |
242 } | |
243 else | |
244 outputs_handled[worker->wirelist[k].output_num] = TRUE; | |
245 ++j; | |
246 } | |
247 if(can_tail) | |
248 { | |
249 for(j = 0; j < def->num_outputs; ++j) | |
250 if(!outputs_handled[j]) | |
251 { | |
252 can_tail = FALSE; | |
253 break; | |
254 } | |
255 if(can_tail) | |
256 if(worker->workerlist[i].value_index == def) | |
257 worker->workerlist[i].type = TAIL_RECURSE; | |
258 else if(!def->num_stores) | |
259 worker->workerlist[i].type = TAIL_CALL; | |
260 } | |
261 } | |
262 } | |
263 } | |
264 | |
265 BOOL method_match(char * name, char * method_name) | |
266 { | |
267 int i = 0; | |
268 while(name[i] != '\0' && method_name[i] != '@' && method_name[i] != '\0') | |
269 { | |
270 if(name[i] != method_name[i]) | |
271 return FALSE; | |
272 ++i; | |
273 } | |
274 if(name[i] != '\0' || method_name[i] != '@') | |
275 return FALSE; | |
276 return TRUE; | |
277 } | |
278 | |
279 worker_def * find_method(int type, char * name, int num_inputs, program * prog) | |
280 { | |
281 int i; | |
282 worker_def * output = NULL; | |
283 company * companylist = prog->companylist; | |
284 VIS_EnterCriticalSection(companylist[type].lock); | |
285 for(i = 0; i < companylist[type].num_methods; ++i) | |
286 { | |
287 //DEBUGPRINTF( "Checking method %s(%d,%d)\n", companylist[type].methodlist[i]->name, companylist[type].methodlist[i]->num_inputs, companylist[type].methodlist[i]->num_outputs); | |
288 if(companylist[type].methodlist[i]->num_inputs == num_inputs && method_match(name, companylist[type].methodlist[i]->name)) | |
289 { | |
290 DEBUGPRINTF( "Found method: %s\n", companylist[type].methodlist[i]->name); | |
291 output = companylist[type].methodlist[i]; | |
292 break; | |
293 } | |
294 } | |
295 VIS_LeaveCriticalSection(companylist[type].lock); | |
296 return output; | |
297 } | |
298 | |
299 worker_def * find_method_noinputcheck(int type, char * name, program * prog) | |
300 { | |
301 int i; | |
302 worker_def * output = NULL; | |
303 company * companylist = prog->companylist; | |
304 VIS_EnterCriticalSection(companylist[type].lock); | |
305 for(i = 0; i < companylist[type].num_methods; ++i) | |
306 { | |
307 //DEBUGPRINTF( "Checking method %s(%d,%d)\n", companylist[type].methodlist[i]->name, companylist[type].methodlist[i]->num_inputs, companylist[type].methodlist[i]->num_outputs); | |
308 if(method_match(name, companylist[type].methodlist[i]->name)) | |
309 { | |
310 DEBUGPRINTF( "Found method: %s\n", companylist[type].methodlist[i]->name); | |
311 output = companylist[type].methodlist[i]; | |
312 break; | |
313 } | |
314 } | |
315 VIS_LeaveCriticalSection(companylist[type].lock); | |
316 return output; | |
317 } | |
318 | |
319 worker_def * find_converter_method(int totype, int fromtype, program * prog) | |
320 { | |
321 int i; | |
322 company * companylist = prog->companylist; | |
323 DEBUGPRINTF( "Finding converter from %s to %s\n", companylist[fromtype].name, companylist[totype].name); | |
324 //DEBUGPRINTF( "Num methods %d\n", companylist[totype].num_methods); | |
325 for(i = 0; i < companylist[totype].num_methods; ++i) | |
326 { | |
327 //DEBUGPRINTF("methodlist[i]: %X\n", companylist[totype].methodlist[i]); | |
328 DEBUGPRINTF( "Checking method %s\n", companylist[totype].methodlist[i]->name); | |
329 | |
330 if(companylist[totype].methodlist[i]->name[0] == '<' && method_match(companylist[fromtype].name, companylist[totype].methodlist[i]->name+1)) | |
331 { | |
332 DEBUGPRINTF( "Found Method %s\n", companylist[totype].methodlist[i]->name); | |
333 | |
334 return companylist[totype].methodlist[i]; | |
335 } | |
336 } | |
337 return NULL; | |
338 } | |
339 | |
340 worker_instance * init_custom_worker_type(int aworker, worker_instance * caller, worker_def * def, instance_callback callback, void * callback_data, datum ** params, int type) | |
341 { | |
342 int i, workerlist_size, j, add_index_count=0; | |
343 int add_index[32]; | |
344 datum * work_params[32]; | |
345 datum * temp_params[3]; | |
346 global_store * store; | |
347 worker_instance * instance; | |
348 BOOL release_params = TRUE; | |
349 def_make_lookup(def); | |
350 workerlist_size = sizeof(worker_instance_data)*(def->implement_func->num_workers); | |
351 //DEBUGPRINTF("workerlist_size: %d * %d = %d, wirelist_size: %d * %d = %d.\n", sizeof(worker_instance_data), def->implement_func->num_workers, workerlist_size, sizeof(wire_instance_data), def->implement_func->num_wires, sizeof(wire_instance_data)*(def->implement_func->num_wires)); | |
352 //DEBUGPRINTF("Before malloc(%d)\n",sizeof(worker_instance) + workerlist_size + sizeof(wire_instance_data)*(def->implement_func->num_wires)); | |
353 if(type == TAIL_RECURSE || type == TAIL_CALL) | |
354 { | |
355 VIS_EnterCriticalSection(caller->counter_lock); | |
356 if(caller->in_progress_count <= 1 && !caller->in_queue_count) | |
357 { | |
358 VIS_LeaveCriticalSection(caller->counter_lock); | |
359 instance = caller; | |
360 for(i = 0; i < instance->num_workers; ++i) | |
361 { | |
362 if(instance->def->implement_func->workerlist[i].type != WORKER && instance->def->implement_func->workerlist[i].type != TAIL_RECURSE && instance->def->implement_func->workerlist[i].type != TAIL_CALL && instance->workerlist[i].value) | |
363 release_ref(instance->workerlist[i].value); | |
364 if(instance->workerlist[i].ready_count && instance->workerlist[i].ready_count < (instance->def->implement_func->workerlist[i].num_inputs + (instance->def->implement_func->workerlist[i].null_input ? 1 : 0))) | |
365 { | |
366 DEBUGPRINTF("Freeing params for worker number %d, ready_count: %d, num_inputs: %d, null_input: %d, instance: %X\n", i, instance->workerlist[i].ready_count,instance->def->implement_func->workerlist[i].num_inputs, instance->def->implement_func->workerlist[i].null_input, instance); | |
367 for(j = 0; j <= instance->def->implement_func->workerlist[i].num_inputs; ++j) | |
368 { | |
369 DEBUGPRINTF("Releasing param %d of worker %d\n", j, i); | |
370 release_ref(instance->workerlist[i].params[j]); | |
371 } | |
372 } | |
373 } | |
374 for(i = 0; i < def->num_inputs; ++i) | |
375 work_params[i] = params[i]; | |
376 params = work_params; | |
377 if(type == TAIL_RECURSE) | |
378 { | |
379 instance->in_progress_count = 0; | |
380 //TODO: adjust profile counter? | |
381 goto init_workerlist; | |
382 } | |
383 else | |
384 { | |
385 aworker = instance->worker_in_caller; | |
386 callback = instance->callback; | |
387 callback_data = instance->callback_data; | |
388 caller = instance->caller_instance; | |
389 VIS_DeleteCriticalSection(instance->counter_lock); | |
390 free(instance); | |
391 } | |
392 } | |
393 else | |
394 { | |
395 VIS_LeaveCriticalSection(caller->counter_lock); | |
396 } | |
397 } | |
398 | |
399 | |
400 instance = MALLOC(sizeof(worker_instance) + workerlist_size/* + sizeof(wire_instance_data)*(def->implement_func->num_wires) */,"instance"); | |
401 | |
402 //DEBUGPRINTF("malloc returned %X.\n", instance); | |
403 VIS_PROFILE_START(PROF_INIT_CUSTOM); | |
404 //DEBUGPRINTF("init_custom_worker, instance: %X\n", instance); | |
405 #ifdef USER_PROFILE | |
406 QueryPerformanceCounter(&(instance->start)); | |
407 #endif | |
408 instance->def = def; | |
409 instance->num_workers = def->implement_func->num_workers; | |
410 instance->workerlist = (worker_instance_data *)(((char *)instance) + sizeof(worker_instance));//malloc(sizeof(worker_instance_data)*(def->implement_func->num_workers)); | |
411 //DEBUGPRINTF("workerlist at %X\n", instance->workerlist); | |
412 | |
413 /*instance->num_wires = def->implement_func->num_wires; | |
414 instance->wirelist = (wire_instance_data *)(((char *)(instance->workerlist)) + workerlist_size);//malloc(sizeof(wire_instance_data)*(def->implement_func->num_wires)); | |
415 DEBUGPRINTF("wirelist at %X\n", instance->wirelist);*/ | |
416 | |
417 | |
418 instance->callback = callback; | |
419 instance->worker_in_caller = aworker; | |
420 instance->callback_data = callback_data; | |
421 instance->caller_instance = caller; | |
422 VIS_InitializeCriticalSection(instance->counter_lock); | |
423 instance->in_progress_count = 0; | |
424 instance->in_queue_count = 0; | |
425 | |
426 if(def->num_stores) | |
427 { | |
428 instance->trans = MALLOC(sizeof(transaction) + sizeof(global_store_use) *(def->num_stores - 1),"transaction"); | |
429 VIS_EnterCriticalSection(global_store_lock); | |
430 for(i = 0; i < def->num_stores; ++i) | |
431 { | |
432 temp_params[0] = add_ref(global_store_dict); | |
433 temp_params[1] = make_string(def->uses_stores[i], -1, def->program); | |
434 vis_dict_index(temp_params, NULL); | |
435 if(!temp_params[0]) | |
436 { | |
437 printf("Error: Global store %s is not initialized\n", def->uses_stores[i]); | |
438 DEBUGPRINTF("Error: Global store %s is not initialized\n", def->uses_stores[i]); | |
439 VIS_LeaveCriticalSection(global_store_lock); | |
440 return NULL; | |
441 } | |
442 instance->trans->stores[i].store = temp_params[0]->c.generic.data; | |
443 instance->trans->stores[i].instance_data = instance->trans->stores[i].begin_data = add_ref(instance->trans->stores[i].store->data); | |
444 VIS_InitializeCriticalSection(instance->trans->stores[i].lock); | |
445 //Is this really necessary? | |
446 release_ref(temp_params[0]); | |
447 } | |
448 VIS_LeaveCriticalSection(global_store_lock); | |
449 instance->trans->num_stores = def->num_stores; | |
450 if((def->transaction_flags & TRANSACTION_WRITE) && (def->transaction_flags & TRANSACTION_TYPE_MASK) == TRANSACTION_RETRY) | |
451 { | |
452 release_params = FALSE; | |
453 for(i = 0; i < def->num_inputs; ++i) | |
454 instance->trans->params[i] = params[i]; | |
455 } | |
456 } else { | |
457 instance->trans = NULL; | |
458 } | |
459 | |
460 | |
461 init_workerlist: | |
462 //DEBUGPUTS("init worker values\n"); | |
463 for(i = 0; i < instance->num_workers; ++i) | |
464 { | |
465 // DEBUGPRINTF("InitializeCriticalSection on workerlist[%d].worker_lock (%X)\n", i, &(instance->workerlist[i].worker_lock)); | |
466 VIS_InitializeCriticalSection(instance->workerlist[i].worker_lock); | |
467 //DEBUGPUTS("ready_count = 0\n"); | |
468 instance->workerlist[i].ready_count = 0; | |
469 if(def->implement_func->workerlist[i].type == INPUT && params) | |
470 instance->workerlist[i].value = add_ref(params[def->implement_func->workerlist[i].io_num]); | |
471 else //if(def->implement_func->workerlist[i].type != 2) | |
472 instance->workerlist[i].value = NULL; | |
473 //DEBUGPRINTF("instance->workerlist[%d].value = %X\n", i, instance->workerlist[i].value); | |
474 for(j = 0; j <= def->implement_func->workerlist[i].num_inputs; ++j) | |
475 instance->workerlist[i].params[j] = NULL; | |
476 //DEBUGPRINTF("num_inputs: %d, null_input: %d\n", def->implement_func->workerlist[i].num_inputs, def->implement_func->workerlist[i].null_input); | |
477 | |
478 //There's still a potential race condition here, but it's unlikely to occur except on a system with an insane number of cores/processors | |
479 //and only on custom workers that have more than 32 items that will be initially ready | |
480 if(!def->implement_func->workerlist[i].num_inputs && !def->implement_func->workerlist[i].null_input) | |
481 { | |
482 DEBUGPRINTF("adding worker %s(%d) to queue\n", def->implement_func->workerlist[i].name, i); | |
483 add_index[add_index_count++] = i; | |
484 if(add_index_count == 32) | |
485 { | |
486 add_multiple(add_index, add_index_count, instance); | |
487 add_index_count = 0; | |
488 } | |
489 //add_queue(i,instance); | |
490 } | |
491 } | |
492 | |
493 if(params) | |
494 { | |
495 if(release_params) | |
496 { | |
497 //DEBUGPUTS("release params\n"); | |
498 for(i = 0; i < def->num_inputs; ++i) | |
499 release_ref(params[i]); | |
500 } | |
501 } | |
502 if(add_index_count > 0) | |
503 add_multiple(add_index, add_index_count, instance); | |
504 VIS_PROFILE_END(PROF_INIT_CUSTOM); | |
505 | |
506 return instance; | |
507 } | |
508 | |
509 worker_instance * init_custom_worker(int aworker, worker_instance * caller, worker_def * def, instance_callback callback, void * callback_data, datum ** params) | |
510 { | |
511 return init_custom_worker_type(aworker, caller, def, callback, callback_data, params, WORKER); | |
512 } | |
513 | |
514 void cleanup_check(queue_entry aworker) | |
515 { | |
516 char msg[256]; | |
517 VIS_EnterCriticalSection(aworker.instance->counter_lock); | |
518 --(aworker.instance->in_progress_count); | |
519 DEBUGPRINTF( "Cleanup Check on %s<%d>:%X, in_progress: %d, in_queue: %d\n", aworker.instance->def->name, aworker.instance->worker_in_caller, aworker.instance, aworker.instance->in_progress_count,aworker.instance->in_queue_count); | |
520 | |
521 if(aworker.instance->in_progress_count == 0 && aworker.instance->in_queue_count == 0) | |
522 { | |
523 VIS_LeaveCriticalSection(aworker.instance->counter_lock); | |
524 cleanup_custom_worker(aworker.instance, aworker.worker_num); | |
525 } | |
526 else | |
527 { | |
528 VIS_LeaveCriticalSection(aworker.instance->counter_lock); | |
529 } | |
530 } | |
531 | |
532 void cleanup_custom_worker(worker_instance * instance, int worker_num) | |
533 { | |
534 BOOL do_commit = TRUE; | |
535 int i,j; | |
536 queue_entry incaller; | |
537 global_store * store; | |
538 #ifdef USER_PROFILE | |
539 LARGE_INTEGER end; | |
540 LARGE_INTEGER duration; | |
541 #endif | |
542 if(instance->trans) | |
543 { | |
544 if(instance->def->transaction_flags & TRANSACTION_WRITE) | |
545 { | |
546 VIS_EnterCriticalSection(global_store_lock); | |
547 if((instance->def->transaction_flags & TRANSACTION_TYPE_MASK) != TRANSACTION_FORCE) | |
548 { | |
549 for(i = 0; i < instance->trans->num_stores; ++i) | |
550 { | |
551 if(instance->trans->stores[i].begin_data != instance->trans->stores[i].store->data) | |
552 { | |
553 do_commit = FALSE; | |
554 break; | |
555 } | |
556 } | |
557 } | |
558 if(do_commit) | |
559 { | |
560 for(i = 0; i < instance->trans->num_stores; ++i) | |
561 { | |
562 release_ref(instance->trans->stores[i].store->data); | |
563 instance->trans->stores[i].store->data = instance->trans->stores[i].instance_data; | |
564 } | |
565 } | |
566 VIS_LeaveCriticalSection(global_store_lock); | |
567 if(!do_commit)//retry transaction | |
568 { | |
569 for(i = 0; i < instance->trans->num_stores; ++i) | |
570 release_ref(instance->trans->stores[i].instance_data); | |
571 puts("retrying transaction"); | |
572 init_custom_worker(instance->worker_in_caller, instance->caller_instance, instance->def, instance->callback, instance->callback_data, instance->trans->params); | |
573 } | |
574 else if((instance->def->transaction_flags & TRANSACTION_TYPE_MASK) == TRANSACTION_RETRY) | |
575 for(i = 0; i < instance->def->num_inputs; ++i) | |
576 release_ref(instance->trans->params[i]); | |
577 } | |
578 else | |
579 { | |
580 for(i = 0; i < instance->trans->num_stores; ++i) | |
581 release_ref(instance->trans->stores[i].instance_data); | |
582 } | |
583 VIS_FREE(instance->trans, "transaction"); | |
584 } | |
585 VIS_PROFILE_START(PROF_CLEANUP_CUSTOM); | |
586 DEBUGPRINTF("Cleaning up custom worker: %s:%X\n", instance->def->name, instance); | |
587 | |
588 VIS_PROFILE_START(PROF_SUB_CALLBACK); | |
589 if(instance->callback && do_commit) | |
590 instance->callback(instance->caller_instance, instance->worker_in_caller, instance, instance->callback_data); | |
591 //DEBUGPUTS("About to release refs\n"); | |
592 VIS_PROFILE_END(PROF_SUB_CALLBACK); | |
593 VIS_PROFILE_START(PROF_CLEANUP_RELEASE_REFS); | |
594 /*for(i = 0; i < instance->def->implement_func->num_wires; ++i) | |
595 { | |
596 if(instance->wirelist[i].data) | |
597 { | |
598 DEBUGPRINTF("release_ref on wire %d\n", i); | |
599 | |
600 release_ref(instance->wirelist[i].data); | |
601 } | |
602 }*/ | |
603 for(i = 0; i < instance->num_workers; ++i) | |
604 { | |
605 if(instance->def->implement_func->workerlist[i].type != WORKER && instance->def->implement_func->workerlist[i].type != TAIL_RECURSE && instance->def->implement_func->workerlist[i].type != TAIL_CALL && instance->workerlist[i].value) | |
606 { | |
607 DEBUGPRINTF( "release_ref on worker %d in instance %X\n", i, instance); | |
608 release_ref(instance->workerlist[i].value); | |
609 } | |
610 if(instance->workerlist[i].ready_count && instance->workerlist[i].ready_count < (instance->def->implement_func->workerlist[i].num_inputs + (instance->def->implement_func->workerlist[i].null_input ? 1 : 0))) | |
611 { | |
612 DEBUGPRINTF("Freeing params for worker number %d, ready_count: %d, num_inputs: %d, null_input: %d, instance: %X\n", i, instance->workerlist[i].ready_count,instance->def->implement_func->workerlist[i].num_inputs, instance->def->implement_func->workerlist[i].null_input, instance); | |
613 for(j = 0; j <= instance->def->implement_func->workerlist[i].num_inputs; ++j) | |
614 { | |
615 DEBUGPRINTF("Releasing param %d of worker %d\n", j, i); | |
616 release_ref(instance->workerlist[i].params[j]); | |
617 } | |
618 } | |
619 VIS_DeleteCriticalSection(instance->workerlist[i].worker_lock); | |
620 } | |
621 VIS_PROFILE_END(PROF_CLEANUP_RELEASE_REFS); | |
622 VIS_DeleteCriticalSection(instance->counter_lock); | |
623 //DEBUGPUTS("freeing lists\n"); | |
624 #ifdef USER_PROFILE | |
625 if(do_commit) | |
626 { | |
627 QueryPerformanceCounter(&end); | |
628 duration.QuadPart = end.QuadPart - instance->start.QuadPart; | |
629 VIS_EnterCriticalSection(instance->def->lock); | |
630 instance->def->total.QuadPart += duration.QuadPart; | |
631 ++instance->def->count; | |
632 if(duration.QuadPart > instance->def->worst.QuadPart) | |
633 instance->def->worst.QuadPart = duration.QuadPart; | |
634 VIS_LeaveCriticalSection(instance->def->lock); | |
635 } | |
636 #endif | |
637 /*VIS_PROFILE_START(PROF_CLEANUP_FREELISTS); | |
638 free(instance->workerlist); | |
639 free(instance->wirelist); | |
640 VIS_PROFILE_END(PROF_CLEANUP_FREELISTS);*/ | |
641 VIS_PROFILE_START(PROF_CLEANUP_CHECK); | |
642 if(instance->caller_instance && do_commit) | |
643 { | |
644 incaller.worker_num = instance->worker_in_caller; | |
645 incaller.instance = instance->caller_instance; | |
646 DEBUGPUTS("Calling cleanup_check on parent\n"); | |
647 cleanup_check(incaller); | |
648 } | |
649 if(do_commit && instance->callback == main_callback) | |
650 release_program_ref(instance->def->program); | |
651 VIS_PROFILE_END(PROF_CLEANUP_CHECK); | |
652 VIS_PROFILE_START(PROF_CLEANUP_FREELISTS); | |
653 VIS_FREE(instance, "worker instance"); | |
654 VIS_PROFILE_END(PROF_CLEANUP_FREELISTS); | |
655 VIS_PROFILE_END(PROF_CLEANUP_CUSTOM); | |
656 } | |
657 /* | |
658 void worker_complete(queue_entry aworker) | |
659 { | |
660 int i,j; | |
661 wire * wirelist; | |
662 int * workers_to_wires_down; | |
663 VIS_PROFILE_START(PROF_WORKER_COMPLETE); | |
664 DEBUGPUTS("worker_complete()\n"); | |
665 | |
666 | |
667 i = aworker.instance->def->implement_func->workerlist[aworker.worker_num].wire_down_lookup; | |
668 wirelist = aworker.instance->def->implement_func->wirelist; | |
669 workers_to_wires_down = aworker.instance->def->implement_func->workers_to_wires_down; | |
670 while(wirelist[j=workers_to_wires_down[i]].start_worker == aworker.worker_num && j >= 0) | |
671 { | |
672 if(aworker.instance->wirelist[j].data) | |
673 { | |
674 DEBUGPRINTF("end_worker: %d, wirelist[%d].data = %X\n", wirelist[j].end_worker, j, aworker.instance->wirelist[j].data); | |
675 add_if_ready(wirelist[j].end_worker, aworker.instance); | |
676 } | |
677 ++i; | |
678 } | |
679 DEBUGPUTS("worker_complete done\n"); | |
680 VIS_PROFILE_END(PROF_WORKER_COMPLETE); | |
681 }*/ | |
682 | |
683 void process_outputs(datum ** params, int aworker, worker_instance * instance) | |
684 { | |
685 BOOL flag=FALSE; | |
686 int i,j; | |
687 worker_def * def = instance->def; | |
688 //custom_worker *implement_func = def->implement_func; | |
689 wire * def_wires = def->implement_func->wirelist; | |
690 worker * def_workers = def->implement_func->workerlist; | |
691 VIS_PROFILE_START(PROF_PROCESS_OUTPUTS); | |
692 DEBUGPRINTF("Process outputs for worker %d in instance %X\n", aworker, instance); | |
693 DEBUGPRINTF("Num_inputs: %d, num_outputs: %d\n", def_workers[aworker].num_inputs, def_workers[aworker].num_outputs); | |
694 if(def_workers[aworker].num_outputs && instance->workerlist) | |
695 { | |
696 //DEBUGPRINTF("num_outputs: %d\n", def_workers[aworker].num_outputs); | |
697 i = def_workers[aworker].wire_down_lookup; | |
698 while((j=def->implement_func->workers_to_wires_down[i]) >= 0 && def_wires[j].start_worker == aworker) | |
699 { | |
700 //DEBUGPRINTF("Checking output: %d\n", def_wires[j].output_num); | |
701 DEBUGPRINTF("output[%d] = %X\n", def_wires[j].output_num, params[def_wires[j].output_num]); | |
702 DEBUGPRINTF("wire leads to worker %d, instance->workerlist: %X\n", def_wires[j].end_worker, instance->workerlist); | |
703 VIS_EnterCriticalSection(instance->workerlist[def_wires[j].end_worker].worker_lock); | |
704 if(params[def_wires[j].output_num] && !instance->workerlist[def_wires[j].end_worker].params[def_wires[j].input_num+1]) | |
705 { | |
706 //DEBUGPRINTF( "add_ref on output %d\n", def_wires[j].output_num); | |
707 instance->workerlist[def_wires[j].end_worker].params[def_wires[j].input_num+1]=add_ref(params[def_wires[j].output_num]); | |
708 //DEBUGPRINTF("Ready count was: %d, ", instance->workerlist[def_wires[j].end_worker].ready_count); | |
709 ++instance->workerlist[def_wires[j].end_worker].ready_count; | |
710 DEBUGPRINTF("Ready count is now: %d\n", instance->workerlist[def_wires[j].end_worker].ready_count); | |
711 DEBUGPRINTF("num inputs: %d, null input: %d\n", instance->def->implement_func->workerlist[def_wires[j].end_worker].num_inputs, instance->def->implement_func->workerlist[def_wires[j].end_worker].null_input); | |
712 if(instance->workerlist[def_wires[j].end_worker].ready_count >= (instance->def->implement_func->workerlist[def_wires[j].end_worker].num_inputs + (instance->def->implement_func->workerlist[def_wires[j].end_worker].null_input ? 1 : 0))) | |
713 { | |
714 //DEBUGPUTS("flag = true\n"); | |
715 flag = TRUE; | |
716 instance->workerlist[def_wires[j].end_worker].ready_count=0; | |
717 } | |
718 } | |
719 VIS_LeaveCriticalSection(instance->workerlist[def_wires[j].end_worker].worker_lock); | |
720 if(flag) | |
721 { | |
722 DEBUGPUTS("add_queue\n"); | |
723 add_queue(def_wires[j].end_worker, instance); | |
724 //add_if_ready(def_wires[j].end_worker, instance); | |
725 flag = FALSE; | |
726 } | |
727 ++i; | |
728 } | |
729 //DEBUGPUTS("releasing refs\n"); | |
730 | |
731 for(i = 0; i < def_workers[aworker].num_outputs; ++i) | |
732 release_ref(params[i]); | |
733 } | |
734 VIS_PROFILE_END(PROF_PROCESS_OUTPUTS); | |
735 } | |
736 | |
737 void main_callback(worker_instance * junkinst, int junk, worker_instance * main_instance, void * data) | |
738 { | |
739 //MessageBox(NULL, "Main Callback", "Visuality Debug", MB_OK); | |
740 VIS_EnterCriticalSection(program_count_lock); | |
741 --program_count; | |
742 if(program_count <= 0) | |
743 { | |
744 execute_active = FALSE; | |
745 VIS_SetEvent(queue_add_event); | |
746 } | |
747 VIS_LeaveCriticalSection(program_count_lock); | |
748 if(data) | |
749 release_ref((datum *)data); | |
750 } | |
751 | |
752 void sub_callback(worker_instance * caller_instance, int caller_workernum, worker_instance * done_instance, void * data) | |
753 { | |
754 int i; | |
755 queue_entry incaller; | |
756 datum * params[32]; | |
757 worker_def * def = done_instance->def; | |
758 custom_worker * implement_func = def->implement_func; | |
759 | |
760 incaller.worker_num = caller_workernum; | |
761 incaller.instance = caller_instance; | |
762 for(i = 0; i < def->num_outputs; ++i) | |
763 params[i] = NULL; | |
764 for(i = 0; i < implement_func->num_workers; ++i) | |
765 { | |
766 if(implement_func->workerlist[i].type == 4) | |
767 { | |
768 if(!params[implement_func->workerlist[i].io_num]) | |
769 { | |
770 params[implement_func->workerlist[i].io_num] = done_instance->workerlist[i].value; | |
771 DEBUGPRINTF("Output[%d] = %X\n", implement_func->workerlist[i].io_num, done_instance->workerlist[i].value); | |
772 done_instance->workerlist[i].value = NULL; | |
773 } | |
774 } | |
775 } | |
776 process_outputs(params, caller_workernum, caller_instance); | |
777 //worker_complete(incaller); | |
778 } | |
779 | |
780 void pack_list_sub_callback(worker_instance * caller_instance, int caller_workernum, worker_instance * done_instance, void * data) | |
781 { | |
782 int i; | |
783 queue_entry incaller; | |
784 datum * params[32]; | |
785 datum * workparams[2]; | |
786 | |
787 incaller.worker_num = caller_workernum; | |
788 incaller.instance = caller_instance; | |
789 for(i = 0; i < done_instance->def->num_outputs; ++i) | |
790 params[i] = NULL; | |
791 for(i = 0; i < done_instance->def->implement_func->num_workers; ++i) | |
792 { | |
793 if(done_instance->def->implement_func->workerlist[i].type == 4) | |
794 { | |
795 if(!params[done_instance->def->implement_func->workerlist[i].io_num]) | |
796 { | |
797 params[done_instance->def->implement_func->workerlist[i].io_num] = done_instance->workerlist[i].value; | |
798 done_instance->workerlist[i].value = NULL; | |
799 } | |
800 } | |
801 } | |
802 workparams[0] = create_list(done_instance->def->program); | |
803 for(i = 0; i < done_instance->def->num_outputs; ++i) | |
804 { | |
805 workparams[1] = params[i]; | |
806 vis_list_append(workparams, NULL); | |
807 } | |
808 process_outputs(workparams, caller_workernum, caller_instance); | |
809 //worker_complete(incaller); | |
810 } | |
811 | |
812 void transaction_sub_callback(worker_instance * caller_instance, int caller_workernum, worker_instance * done_instance, void * data) | |
813 { | |
814 int i; | |
815 | |
816 pack_list_sub_callback(caller_instance, caller_workernum, done_instance, NULL); | |
817 } | |
818 | |
819 int global_argc; | |
820 char ** global_argv; | |
821 int spin_counter; | |
822 | |
823 void prep_program(program * prog) | |
824 { | |
825 defchunk * current; | |
826 int i,j; | |
827 make_lookup_arrays(prog); | |
828 current = prog->defs; | |
829 while(current) | |
830 { | |
831 for(i = 0; i < current->num_defs; ++i) | |
832 { | |
833 #ifdef USER_PROFILE | |
834 current->deflist[i].count = 0; | |
835 current->deflist[i].total.QuadPart = 0; | |
836 current->deflist[i].worst.QuadPart = 0; | |
837 VIS_InitializeCriticalSection(current->deflist[i].lock); | |
838 #endif // USER_PROFILE | |
839 //DEBUGPRINTF("Checking worker %s with type %X\n", current->deflist[i].name, current->deflist[i].type); | |
840 if(current->deflist[i].type & USER_FLAG && (current->deflist[i].type & TYPE_MASK) == WORKER_TYPE) | |
841 { | |
842 //DEBUGPRINTF("Checking for constants in worker %s\n", current->deflist[i].name); | |
843 for(j = 0; j < current->deflist[i].implement_func->num_workers; ++j) | |
844 if(current->deflist[i].implement_func->workerlist[j].type == CONSTANT) | |
845 { | |
846 //current->deflist[i].implement_func->workerlist[j].value_index = (int)(get_constant(current->deflist[i].implement_func->workerlist[j].name,-1, initial_prog)); | |
847 //DEBUGPRINTF("Set value_index for constant to %X in worker %s at index %d\n", current->deflist[i].implement_func->workerlist[j].value_index, current->deflist[i].name, j); | |
848 } | |
849 else if(current->deflist[i].implement_func->workerlist[j].type == WORKER || current->deflist[i].implement_func->workerlist[j].type == TAIL_CALL || current->deflist[i].implement_func->workerlist[j].type == TAIL_RECURSE) | |
850 { | |
851 current->deflist[i].implement_func->workerlist[j].num_inputs = ((worker_def *)current->deflist[i].implement_func->workerlist[j].value_index)->num_inputs; | |
852 current->deflist[i].implement_func->workerlist[j].num_outputs = ((worker_def *)current->deflist[i].implement_func->workerlist[j].value_index)->num_outputs; | |
853 } | |
854 else | |
855 current->deflist[i].implement_func->workerlist[j].value_index = 0; | |
856 //DEBUGPRINTF("optimize %d\n", i); | |
857 #ifdef ENABLE_OPT | |
858 optimize(current->deflist + i); | |
859 #endif | |
860 } | |
861 } | |
862 current = current->next; | |
863 } | |
864 } | |
865 | |
866 void interp_start(int num_threads, BOOL use_this_thread, int argc, char ** argv, program * initial_prog) | |
867 { | |
868 defchunk * current; | |
869 datum * params[2]; | |
870 int i, junk,create_threads,j; | |
871 #ifdef USER_PROFILE | |
872 LARGE_INTEGER frequency; | |
873 #endif | |
874 lock_fail_counter = 0; | |
875 lock_counter = 0; | |
876 spin_counter = 0; | |
877 | |
878 #ifdef WIN32 | |
879 //_CrtSetDbgFlag(_CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_CHECK_CRT_DF | _CRTDBG_ALLOC_MEM_DF); | |
880 WSAStartup(MAKEWORD(1, 1), &wsa_data); | |
881 #endif | |
882 VIS_InitializeCriticalSection(randlock); | |
883 | |
884 DEBUGPUTS("interp_start\n"); | |
885 #ifdef ENABLE_PROFILING | |
886 for(i = 0; i < NUM_PROFS; ++i) | |
887 { | |
888 vis_profile_running_total[i] = 0; | |
889 vis_profile_counts[i] = 0; | |
890 } | |
891 VIS_PROFILE_START(PROF_EMPTYFUNC); | |
892 empty_test(NULL,NULL); | |
893 VIS_PROFILE_END(PROF_EMPTYFUNC); | |
894 VIS_PROFILE_START(PROF_NOCODE); | |
895 VIS_PROFILE_END(PROF_NOCODE); | |
896 #endif | |
897 global_argc = argc; | |
898 global_argv = argv; | |
899 init_sync_primitives(); | |
900 init_datum_storage(); | |
901 init_global_storage(initial_prog); | |
902 //init queue | |
903 current_section = &first_section; | |
904 DEBUGPRINTF("current_section = %X, ¤t_section = %X\n", current_section, ¤t_section); | |
905 worker_queue = current_section->entries; | |
906 current_section->last = NULL; | |
907 current_section->next = NULL; | |
908 queue_start = queue_len = 0; | |
909 // deflist[0].num_workers = num_workers; | |
910 // deflist[0].num_wires = num_wires; | |
911 prep_program(initial_prog); | |
912 //MessageBox(NULL, "Before fopen", "visdbg", MB_OK); | |
913 init_genrand(time(NULL)); | |
914 | |
915 execute_active = TRUE; | |
916 DEBUGPUTS("Before init_custom_worker on Main\n"); | |
917 params[0] = create_list(initial_prog); | |
918 for(i = 0; i < argc; ++i) | |
919 { | |
920 params[1] = make_string(argv[i], -1, initial_prog); | |
921 vis_list_append(params, NULL); | |
922 } | |
923 main_instance = init_custom_worker(-1, NULL, initial_prog->defs->deflist, main_callback, NULL, params); | |
924 | |
925 //num_datum = 0; | |
926 #if COMPILE_THREADS > 0 | |
927 create_threads = COMPILE_THREADS; | |
928 if(num_threads > 0) | |
929 create_threads = num_threads; | |
930 if(use_this_thread) | |
931 --create_threads; | |
932 | |
933 for(i = 0; i < create_threads; ++i) | |
934 { | |
935 #ifdef WIN32 | |
936 CreateThread(NULL, 0, worker_thread, NULL, 0, &junk); | |
937 #else | |
938 #ifdef SYLLABLE | |
939 resume_thread(spawn_thread("vis_worker", worker_thread, 1, 0, NULL)); | |
940 #else | |
941 pthread_t pid; | |
942 pthread_create(&pid, NULL, worker_thread, NULL); | |
943 #endif | |
944 #endif | |
945 } | |
946 if(use_this_thread) | |
947 worker_thread(NULL); | |
948 #else | |
949 worker_thread(NULL); | |
950 #endif | |
951 #ifdef ENABLE_PROFILING | |
952 for(i = 0; i < NUM_PROFS; ++i) | |
953 printf("%d:\t%f,\tcount: %d,\taverage: %f\n", i, (double)vis_profile_running_total[i], vis_profile_counts[i], ((double)vis_profile_running_total[i])/((double)vis_profile_counts[i])); | |
954 #endif | |
955 | |
956 #ifdef USER_PROFILE | |
957 printf("%-33s%12s%7s%15s%12s\n\n", "Worker", "Total", "Count", "Average", "Worst"); | |
958 current = initial_prog->defs; | |
959 while(current) | |
960 { | |
961 for(i = 0; i < current->num_defs; ++i) | |
962 { | |
963 if(current->deflist[i].count > 0) | |
964 { | |
965 printf("%-33s%12.0f%7d%15.2f%12.0f\n", current->deflist[i].name, (double)current->deflist[i].total.QuadPart, current->deflist[i].count, (double)current->deflist[i].total.QuadPart / (double)current->deflist[i].count, (double)current->deflist[i].worst.QuadPart); | |
966 } | |
967 } | |
968 current = current->next; | |
969 } | |
970 QueryPerformanceFrequency(&frequency); | |
971 printf("%.0f ticks per second\n", (double)frequency.QuadPart); | |
972 #endif | |
973 interp_stop(); | |
974 } | |
975 | |
976 void interp_stop() | |
977 { | |
978 int i; | |
979 execute_active = FALSE; | |
980 close_sync_primitives(); | |
981 // Doesn't make sense in the context of multiple programs | |
982 // cleanup_custom_worker(main_instance); | |
983 #ifdef WIN32 | |
984 WSACleanup(); | |
985 #endif | |
986 #ifdef TEXT_FILE_DEBUG | |
987 fclose(debugfile); | |
988 #endif | |
989 } | |
990 | |
991 extern | |
992 void init_sync_primitives() | |
993 { | |
994 int i; | |
995 DEBUGPUTS("Initializing data_lock\n"); | |
996 VIS_InitializeCriticalSection(data_lock); | |
997 DEBUGPUTS("Initializing worker_queue_lock\n"); | |
998 VIS_InitializeCriticalSection(worker_queue_lock); | |
999 DEBUGPUTS("Initializing text_buf_lock\n"); | |
1000 VIS_InitializeCriticalSection(text_buf_lock); | |
13 | 1001 #ifdef GUI_LIB |
0 | 1002 #ifdef SYLLABLE |
1003 DEBUGPUTS("vis_window_init\n"); | |
1004 vis_window_init(); | |
1005 #endif | |
13 | 1006 #endif //GUI_LIB |
0 | 1007 VIS_CreateEvent(queue_add_event);//No security parameter, auto reset, starts signaled, no name |
1008 | |
1009 } | |
1010 | |
1011 void close_sync_primitives() | |
1012 { | |
1013 int i; | |
1014 VIS_DeleteCriticalSection(data_lock); | |
1015 VIS_DeleteCriticalSection(worker_queue_lock); | |
1016 VIS_DestroyEvent(queue_add_event); | |
1017 | |
1018 } | |
1019 | |
1020 void init_global_storage(program * prog) | |
1021 { | |
1022 VIS_InitializeCriticalSection(global_store_lock); | |
1023 global_store_dict = create_dict(prog); | |
1024 } | |
1025 | |
1026 void add_multiple(int * data, int num, worker_instance * instance) | |
1027 { | |
1028 int i, index; | |
1029 queue_section * temp; | |
1030 DEBUGPRINTF( "Adding %d workers\n", num); | |
1031 | |
1032 VIS_EnterCriticalSection(instance->counter_lock); | |
1033 instance->in_queue_count += num; | |
1034 VIS_LeaveCriticalSection(instance->counter_lock); | |
1035 VIS_EnterCriticalSection(worker_queue_lock); | |
1036 for(i = 0; i < num; ++i) | |
1037 { | |
1038 if(queue_len >= QUEUE_SIZE) | |
1039 { | |
1040 if(current_section->next) | |
1041 { | |
1042 //DEBUGPUTS("Moving to next queue_section\n"); | |
1043 current_section = current_section->next; | |
1044 } | |
1045 else | |
1046 { | |
1047 //DEBUGPUTS("Allocating new queue_section\n"); | |
1048 VIS_PROFILE_START(PROF_ADDQUEUE_MALLOC); | |
1049 temp = MALLOC(sizeof(queue_section),"queue section"); | |
1050 VIS_PROFILE_END(PROF_ADDQUEUE_MALLOC); | |
1051 temp->last = current_section; | |
1052 temp->next = NULL; | |
1053 current_section->next = temp; | |
1054 current_section = temp; | |
1055 } | |
1056 worker_queue = current_section->entries; | |
1057 queue_start = queue_len = 0; | |
1058 } | |
1059 if(queue_start+queue_len < QUEUE_SIZE) | |
1060 index = queue_start+queue_len; | |
1061 else | |
1062 index = queue_start+queue_len-QUEUE_SIZE; | |
1063 worker_queue[index].worker_num=data[i]; | |
1064 worker_queue[index].instance = instance; | |
1065 ++queue_len; | |
1066 } | |
1067 VIS_LeaveCriticalSection(worker_queue_lock); | |
1068 //DEBUGPUTS("SetEvent\n"); | |
1069 VIS_SetEvent(queue_add_event); | |
1070 } | |
1071 | |
1072 void requeue(int data, worker_instance * instance) | |
1073 { | |
1074 add_queue(data, instance); | |
1075 VIS_EnterCriticalSection(instance->counter_lock); | |
1076 --(instance->in_progress_count); | |
1077 VIS_LeaveCriticalSection(instance->counter_lock); | |
1078 } | |
1079 | |
1080 void add_queue(int data, worker_instance * instance) | |
1081 { | |
1082 int index; | |
1083 queue_section * temp; | |
1084 VIS_PROFILE_START(PROF_ADDQUEUE); | |
1085 VIS_EnterCriticalSection(instance->counter_lock); | |
1086 ++(instance->in_queue_count); | |
1087 VIS_LeaveCriticalSection(instance->counter_lock); | |
1088 VIS_EnterCriticalSection(worker_queue_lock); | |
1089 if(queue_len >= QUEUE_SIZE) | |
1090 { | |
1091 if(current_section->next) | |
1092 { | |
1093 //DEBUGPUTS("Moving to next queue_section\n"); | |
1094 current_section = current_section->next; | |
1095 } | |
1096 else | |
1097 { | |
1098 //DEBUGPUTS("Allocating new queue_section\n"); | |
1099 VIS_PROFILE_START(PROF_ADDQUEUE_MALLOC); | |
1100 temp = MALLOC(sizeof(queue_section),"queue section"); | |
1101 VIS_PROFILE_END(PROF_ADDQUEUE_MALLOC); | |
1102 temp->last = current_section; | |
1103 temp->next = NULL; | |
1104 current_section->next = temp; | |
1105 current_section = temp; | |
1106 } | |
1107 worker_queue = current_section->entries; | |
1108 queue_start = queue_len = 0; | |
1109 } | |
1110 else if(queue_len == 0) | |
1111 { | |
1112 VIS_SetEvent(queue_add_event); | |
1113 //DEBUGPUTS("SetEvent\n"); | |
1114 } | |
1115 | |
1116 if(queue_start+queue_len < QUEUE_SIZE) | |
1117 index = queue_start+queue_len; | |
1118 else | |
1119 index = queue_start+queue_len-QUEUE_SIZE; | |
1120 worker_queue[index].worker_num=data; | |
1121 worker_queue[index].instance = instance; | |
1122 ++queue_len; | |
1123 | |
1124 VIS_LeaveCriticalSection(worker_queue_lock); | |
1125 VIS_PROFILE_END(PROF_ADDQUEUE); | |
1126 } | |
1127 | |
1128 /** | |
1129 * Retrieves a ready worker from the queue | |
1130 */ | |
1131 queue_entry get_queue() | |
1132 { | |
1133 queue_entry data; | |
1134 queue_section * temp; | |
1135 //DEBUGPUTS("Begin get_queue()\n"); | |
1136 | |
1137 VIS_EnterCriticalSection(worker_queue_lock); | |
1138 while(!queue_len && execute_active) | |
1139 { | |
1140 //DEBUGPUTS("Queue empty, resetting event\n"); | |
1141 VIS_ResetEvent(queue_add_event); | |
1142 VIS_LeaveCriticalSection(worker_queue_lock); | |
1143 //DEBUGPUTS("Waiting for queue_add_event\n"); | |
1144 VIS_WaitEvent(queue_add_event); | |
1145 #ifdef NINTENDO_DS | |
1146 //TODO make the processor sleep while waiting for IRQs | |
1147 if(irq_queue_count > 0) | |
1148 run_queued_irqs(); | |
1149 #endif | |
1150 VIS_EnterCriticalSection(worker_queue_lock); | |
1151 } | |
1152 if(queue_len > 0) | |
1153 { | |
1154 data = worker_queue[queue_start]; | |
1155 //DEBUGPRINTF( "Next worker in queue: %d\n", data.worker_num); | |
1156 //DEBUGPRINTF("data.instance: %X, data.instance->workerlist: %X\n", data.instance, data.instance->workerlist); | |
1157 /*VIS_EnterCriticalSection(data.instance->workerlist[data.worker_num].worker_lock); | |
1158 DEBUGPUTS("Adjusting ready_count"); | |
1159 data.instance->workerlist[data.worker_num].ready_count=0; | |
1160 VIS_LeaveCriticalSection(data.instance->workerlist[data.worker_num].worker_lock);*/ | |
1161 ++queue_start; | |
1162 --queue_len; | |
1163 //DEBUGPUTS("Adjusted ready count.\n"); | |
1164 //DEBUGPRINTF("current_section: %X\n", current_section); | |
1165 if(queue_len == 0 && current_section->last) | |
1166 { | |
1167 if(current_section->next != NULL) | |
1168 { | |
1169 //DEBUGPUTS("Freeing current_section->next.\n"); | |
1170 VIS_FREE(current_section->next, "ready queue node"); | |
1171 current_section->next = NULL; | |
1172 } | |
1173 current_section = current_section->last; | |
1174 worker_queue = current_section->entries; | |
1175 queue_start = 0; | |
1176 queue_len = QUEUE_SIZE; | |
1177 } | |
1178 else if(queue_start == QUEUE_SIZE) | |
1179 queue_start = 0; | |
1180 } | |
1181 else | |
1182 { | |
1183 //DEBUGPUTS("Queue empty\n"); | |
1184 data.worker_num = -2; | |
1185 } | |
1186 VIS_LeaveCriticalSection(worker_queue_lock); | |
1187 //DEBUGPUTS("Left worker_queue_lock\n"); | |
1188 //MessageBox(NULL,"AfterLeave","visdbg",MB_OK); | |
1189 if(data.worker_num >= 0) | |
1190 { | |
1191 VIS_EnterCriticalSection(data.instance->counter_lock); | |
1192 //DEBUGPUTS("Adjusting in_queue/in_progress counts.\n"); | |
1193 --(data.instance->in_queue_count); | |
1194 ++(data.instance->in_progress_count); | |
1195 DEBUGPRINTF( "Counts for %s<%d> Instance:%X after get_queue: in_queue: %d in_progress: %d\n",data.instance->def->name, data.instance->worker_in_caller, data.instance, data.instance->in_queue_count, data.instance->in_progress_count); | |
1196 | |
1197 VIS_LeaveCriticalSection(data.instance->counter_lock); | |
1198 } | |
1199 //DEBUGPUTS("End get_queue()\n"); | |
1200 | |
1201 return data; | |
1202 } | |
1203 | |
1204 void def_make_lookup(worker_def * def) | |
1205 { | |
1206 int i, j, upoffset, offset; | |
1207 VIS_EnterCriticalSection(def->implement_func->lock); | |
1208 if(def->implement_func->dirty) | |
1209 { | |
1210 upoffset = offset = 0; | |
1211 for(i = 0; i < def->implement_func->num_workers; ++i) | |
1212 { | |
1213 def->implement_func->workerlist[i].wire_down_lookup=offset; | |
1214 def->implement_func->workerlist[i].wire_up_lookup=upoffset; | |
1215 for(j = 0; j < def->implement_func->num_wires; ++j) | |
1216 { | |
1217 if(def->implement_func->wirelist[j].start_worker == i) | |
1218 def->implement_func->workers_to_wires_down[offset++]=j; | |
1219 if(def->implement_func->wirelist[j].end_worker == i) | |
1220 def->implement_func->workers_to_wires_up[upoffset++]=j; | |
1221 } | |
1222 //Clear tail call info | |
1223 if(def->implement_func->workerlist[i].type == TAIL_CALL || def->implement_func->workerlist[i].type == TAIL_RECURSE) | |
1224 def->implement_func->workerlist[i].type = WORKER; | |
1225 } | |
1226 def->implement_func->workers_to_wires_down[offset]=-1; | |
1227 def->implement_func->workers_to_wires_up[upoffset]=-1; | |
1228 check_tail(def); | |
1229 def->implement_func->dirty = FALSE; | |
1230 } | |
1231 VIS_LeaveCriticalSection(def->implement_func->lock); | |
1232 } | |
1233 | |
1234 /** | |
1235 * Generates lookup array to ease navigation between workers | |
1236 */ | |
1237 void make_lookup_arrays(program * prog) | |
1238 { | |
1239 int i,j,k, offset, upoffset; | |
1240 worker_def * deflist; | |
1241 defchunk * current = prog->defs; | |
1242 while(current) | |
1243 { | |
1244 deflist = current->deflist; | |
1245 for(k = 0; k < current->num_defs; ++k) | |
1246 { | |
1247 if(deflist[k].type & USER_FLAG && (deflist[k].type & TYPE_MASK) == WORKER_TYPE) | |
1248 def_make_lookup(deflist + k); | |
1249 } | |
1250 current = current->next; | |
1251 } | |
1252 } | |
1253 extern char _end_bss[]; | |
1254 void initpredefworkers(program * prog) | |
1255 { | |
1256 int current_def = 1; | |
1257 int current_company = 0; | |
1258 int current_method; | |
1259 int comp_room; | |
1260 company * this_comp; | |
1261 worker_def * aworker; | |
1262 create_company(prog, "Any Type", 0, 0, FALSE); | |
1263 create_company(prog, "Yes No", 0, 0, FALSE); | |
1264 | |
1265 aworker = create_worker(prog, "Print", 1, 1, WORKER_TYPE); | |
1266 aworker->implement_func = (custom_worker *)vis_print; | |
1267 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1268 | |
1269 aworker = create_worker(prog, "Random", 0, 1, WORKER_TYPE); | |
1270 aworker->implement_func = (custom_worker *)vis_random; | |
1271 | |
1272 aworker = create_worker(prog, "Build", 1, 1, WORKER_TYPE); | |
1273 aworker->implement_func = (custom_worker *)vis_build; | |
1274 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1275 | |
1276 aworker = create_worker(prog, "End", 1, 0, WORKER_TYPE); | |
1277 aworker->implement_func = (custom_worker *)vis_end; | |
1278 aworker->input_types[0] = ANY_TYPE; | |
1279 | |
1280 create_worker(prog, "Append", 2, 1, MAGIC_TYPE); | |
1281 create_worker(prog, "+", 2, 1, MAGIC_TYPE); | |
1282 create_worker(prog, "-", 2, 1, MAGIC_TYPE); | |
1283 create_worker(prog, "*", 2, 1, MAGIC_TYPE); | |
1284 create_worker(prog, "/", 2, 1, MAGIC_TYPE); | |
1285 create_worker(prog, ">", 2, 1, MAGIC_TYPE); | |
1286 create_worker(prog, "<", 2, 1, MAGIC_TYPE); | |
1287 create_worker(prog, "=", 2, 1, MAGIC_TYPE); | |
1288 | |
1289 aworker = create_worker(prog, "Get Input", 0, 1, WORKER_TYPE); | |
1290 aworker->implement_func = (custom_worker *)vis_getinput; | |
1291 | |
1292 aworker = create_worker(prog, "If",1, 2, WORKER_TYPE); | |
1293 aworker->implement_func=(custom_worker *)vis_if; | |
1294 aworker->input_types[0] = BUILTIN_TYPE_YESNO; | |
1295 | |
1296 aworker = create_worker(prog, "Type Of",1, 1, WORKER_TYPE); | |
1297 aworker->implement_func=(custom_worker *)vis_type_of; | |
1298 aworker->input_types[0] = ANY_TYPE; | |
1299 | |
1300 aworker = create_worker(prog, "Init Store",1, 0, WORKER_TYPE); | |
1301 aworker->implement_func=(custom_worker *)init_global_store; | |
1302 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1303 | |
1304 aworker = create_worker(prog, "Wait Forever", 0, 0, WORKER_TYPE); | |
1305 aworker->implement_func=(custom_worker *)vis_wait_forever; | |
1306 | |
1307 #ifdef NINTENDO_DS | |
1308 aworker = create_worker(prog, "Register Handler", 2, 1, WORKER_TYPE); | |
1309 aworker->implement_func = (custom_worker *)vis_register_handler; | |
1310 aworker->input_types[0] = BUILTIN_TYPE_WHOLE; | |
1311 aworker->input_types[1] = BUILTIN_TYPE_WORKER; | |
1312 | |
1313 aworker = create_worker(prog, "Clear Handler", 1, 1, WORKER_TYPE); | |
1314 aworker->implement_func = (custom_worker *)vis_clear_handler; | |
1315 aworker->input_types[0] = BUILTIN_TYPE_WHOLE; | |
1316 | |
1317 aworker = create_worker(prog, "Held Keys", 0, 1, WORKER_TYPE); | |
1318 aworker->implement_func = (custom_worker *)vis_held_keys; | |
1319 | |
1320 aworker = create_worker(prog, "Touch Position", 0, 2, WORKER_TYPE); | |
1321 aworker->implement_func = (custom_worker *)vis_touch_position; | |
1322 #endif | |
1323 | |
1324 current_method = 0; | |
1325 //strcpy(companylist[current_company].name, "String"); | |
1326 #ifdef SEGA | |
1327 this_comp = create_company(prog, "String", 6, 0, FALSE); | |
1328 #else | |
1329 this_comp = create_company(prog, "String", 7, 0, FALSE); | |
1330 #endif | |
1331 aworker = create_worker(prog, "<Whole Number@String",1, 1, WORKER_TYPE); | |
1332 aworker->implement_func=(custom_worker *)vis_inttostring; | |
1333 aworker->input_types[0] = BUILTIN_TYPE_WHOLE; | |
1334 //add_method(this_comp, aworker); | |
1335 | |
1336 #ifndef SEGA | |
1337 | |
1338 aworker = create_worker(prog, "<Real Number@String",1, 1, WORKER_TYPE); | |
1339 aworker->implement_func=(custom_worker *)vis_realtostring; | |
1340 aworker->input_types[0] = BUILTIN_TYPE_REAL; | |
1341 //add_method(this_comp, aworker); | |
1342 #endif | |
1343 | |
1344 aworker = create_worker(prog, "=@String",2, 1, WORKER_TYPE); | |
1345 aworker->implement_func=(custom_worker *)vis_stringequal; | |
1346 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1347 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1348 //add_method(this_comp, aworker); | |
1349 | |
1350 aworker = create_worker(prog, "<Yes No@String",1, 1, WORKER_TYPE); | |
1351 aworker->implement_func=(custom_worker *)vis_yesnotostring; | |
1352 aworker->input_types[0] = BUILTIN_TYPE_YESNO; | |
1353 //add_method(this_comp, aworker); | |
1354 | |
1355 aworker = create_worker(prog, ">@String",2, 1, WORKER_TYPE); | |
1356 aworker->implement_func=(custom_worker *)vis_greaterstring; | |
1357 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1358 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1359 //add_method(this_comp, aworker); | |
1360 | |
1361 aworker = create_worker(prog, "<@String",2, 1, WORKER_TYPE); | |
1362 aworker->implement_func=(custom_worker *)vis_lesserstring; | |
1363 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1364 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1365 //add_method(this_comp, aworker); | |
1366 | |
1367 aworker = create_worker(prog, "Append@String",2, 1, WORKER_TYPE); | |
1368 aworker->implement_func=(custom_worker *)vis_append; | |
1369 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1370 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1371 //add_method(this_comp, aworker); | |
1372 | |
1373 aworker = create_worker(prog, "Split@String",2, 1, WORKER_TYPE); | |
1374 aworker->implement_func=(custom_worker *)vis_string_split; | |
1375 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1376 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1377 | |
1378 aworker = create_worker(prog, "Get Raw@String",2, 2, WORKER_TYPE); | |
1379 aworker->implement_func=(custom_worker *)vis_string_get_raw; | |
1380 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1381 aworker->input_types[1] = ANY_TYPE; | |
1382 | |
1383 aworker = create_worker(prog, "Put Raw@String",2, 1, WORKER_TYPE); | |
1384 aworker->implement_func=(custom_worker *)vis_string_put_raw; | |
1385 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1386 aworker->input_types[1] = ANY_TYPE; | |
1387 | |
1388 aworker = create_worker(prog, "Slice@String",2, 2, WORKER_TYPE); | |
1389 aworker->implement_func=(custom_worker *)vis_string_slice; | |
1390 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1391 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1392 | |
1393 aworker = create_worker(prog, "Reverse@String",1, 1, WORKER_TYPE); | |
1394 aworker->implement_func=(custom_worker *)vis_string_reverse; | |
1395 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1396 | |
1397 aworker = create_worker(prog, "Length@String",1, 1, WORKER_TYPE); | |
1398 aworker->implement_func=(custom_worker *)vis_string_length; | |
1399 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1400 | |
1401 aworker = create_worker(prog, "Put Byte@String",2, 1, WORKER_TYPE); | |
1402 aworker->implement_func=(custom_worker *)vis_string_put_byte; | |
1403 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1404 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1405 | |
1406 aworker = create_worker(prog, "Get DString@String",2, 4, WORKER_TYPE); | |
1407 aworker->implement_func=(custom_worker *)vis_string_get_dstring; | |
1408 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1409 aworker->input_types[1] = ANY_TYPE; | |
1410 | |
1411 current_method = 0; | |
1412 this_comp = create_company(prog, "Whole Number", 6, 0, FALSE); | |
1413 aworker = create_worker(prog, "<String@Whole Number",1, 1, WORKER_TYPE); | |
1414 aworker->implement_func=(custom_worker *)vis_stringtoint; | |
1415 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1416 | |
1417 aworker = create_worker(prog, "From Hex@Whole Number",1, 1, WORKER_TYPE); | |
1418 aworker->implement_func=(custom_worker *)vis_whole_fromhex; | |
1419 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1420 //add_method(this_comp, aworker); | |
1421 | |
1422 aworker = create_worker(prog, "=@Whole Number",2, 1, WORKER_TYPE); | |
1423 aworker->implement_func=(custom_worker *)vis_wholeequal; | |
1424 aworker->input_types[0] = BUILTIN_TYPE_WHOLE; | |
1425 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1426 //add_method(this_comp, aworker); | |
1427 | |
1428 aworker = create_worker(prog, ">@Whole Number",2, 1, WORKER_TYPE); | |
1429 aworker->implement_func=(custom_worker *)vis_greaterint; | |
1430 aworker->input_types[0] = BUILTIN_TYPE_WHOLE; | |
1431 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1432 //add_method(this_comp, aworker); | |
1433 | |
1434 aworker = create_worker(prog, "<@Whole Number",2, 1, WORKER_TYPE); | |
1435 aworker->implement_func=(custom_worker *)vis_lesserint; | |
1436 aworker->input_types[0] = BUILTIN_TYPE_WHOLE; | |
1437 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1438 | |
1439 //add_method(this_comp, aworker); | |
1440 | |
1441 aworker = create_worker(prog, "+@Whole Number", 2, 1, WORKER_TYPE); | |
1442 aworker->implement_func=(custom_worker *)vis_whole_add; | |
1443 aworker->input_types[0] = BUILTIN_TYPE_WHOLE; | |
1444 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1445 | |
1446 //add_method(this_comp, aworker); | |
1447 | |
1448 aworker = create_worker(prog, "-@Whole Number", 2, 1, WORKER_TYPE); | |
1449 aworker->implement_func=(custom_worker *)vis_whole_subtract; | |
1450 aworker->input_types[0] = BUILTIN_TYPE_WHOLE; | |
1451 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1452 | |
1453 aworker = create_worker(prog, "*@Whole Number", 2, 1, WORKER_TYPE); | |
1454 aworker->implement_func=(custom_worker *)vis_whole_mult; | |
1455 aworker->input_types[0] = BUILTIN_TYPE_WHOLE; | |
1456 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1457 | |
1458 //add_method(this_comp, aworker); | |
1459 | |
1460 aworker = create_worker(prog, "/@Whole Number", 2, 1, WORKER_TYPE); | |
1461 aworker->implement_func=(custom_worker *)vis_whole_div; | |
1462 aworker->input_types[0] = BUILTIN_TYPE_WHOLE; | |
1463 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1464 | |
1465 aworker = create_worker(prog, "&@Whole Number", 2, 1, WORKER_TYPE); | |
1466 aworker->implement_func=(custom_worker *)vis_whole_and; | |
1467 aworker->input_types[0] = BUILTIN_TYPE_WHOLE; | |
1468 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1469 | |
1470 aworker = create_worker(prog, "|@Whole Number", 2, 1, WORKER_TYPE); | |
1471 aworker->implement_func=(custom_worker *)vis_whole_or; | |
1472 aworker->input_types[0] = BUILTIN_TYPE_WHOLE; | |
1473 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1474 | |
1475 aworker = create_worker(prog, "LShift@Whole Number", 2, 1, WORKER_TYPE); | |
1476 aworker->implement_func=(custom_worker *)vis_whole_lsh; | |
1477 aworker->input_types[0] = BUILTIN_TYPE_WHOLE; | |
1478 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1479 | |
1480 aworker = create_worker(prog, "RShift@Whole Number", 2, 1, WORKER_TYPE); | |
1481 aworker->implement_func=(custom_worker *)vis_whole_rsh; | |
1482 aworker->input_types[0] = BUILTIN_TYPE_WHOLE; | |
1483 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1484 | |
46 | 1485 aworker = create_worker(prog, "%@Whole Number", 2, 1, WORKER_TYPE); |
1486 aworker->implement_func=(custom_worker *)vis_whole_modulus; | |
1487 aworker->input_types[0] = BUILTIN_TYPE_WHOLE; | |
1488 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1489 | |
0 | 1490 //add_method(this_comp, aworker); |
1491 | |
1492 current_method = 0; | |
1493 this_comp = create_company(prog, "Real Number", 6, 0, FALSE);//<string, =, >, <, +, - | |
1494 aworker = create_worker(prog, "<String@Real Number", 1, 1, WORKER_TYPE); | |
1495 aworker->implement_func=(custom_worker *)vis_stringtoreal; | |
1496 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1497 //add_method(this_comp, aworker); | |
1498 | |
1499 aworker = create_worker(prog, "=@Real Number", 2, 1, WORKER_TYPE); | |
1500 aworker->implement_func=(custom_worker *)vis_realequal; | |
1501 aworker->input_types[0] = BUILTIN_TYPE_REAL; | |
1502 aworker->input_types[1] = BUILTIN_TYPE_REAL; | |
1503 | |
1504 //add_method(this_comp, aworker); | |
1505 | |
1506 aworker = create_worker(prog, ">@Real Number", 2, 1, WORKER_TYPE); | |
1507 aworker->implement_func=(custom_worker *)vis_greaterreal; | |
1508 aworker->input_types[0] = BUILTIN_TYPE_REAL; | |
1509 aworker->input_types[1] = BUILTIN_TYPE_REAL; | |
1510 | |
1511 //add_method(this_comp, aworker); | |
1512 | |
1513 aworker = create_worker(prog, "<@Real Number", 2, 1, WORKER_TYPE); | |
1514 aworker->implement_func=(custom_worker *)vis_lesserreal; | |
1515 aworker->input_types[0] = BUILTIN_TYPE_REAL; | |
1516 aworker->input_types[1] = BUILTIN_TYPE_REAL; | |
1517 | |
1518 //add_method(this_comp, aworker); | |
1519 | |
1520 aworker = create_worker(prog, "+@Real Number", 2, 1, WORKER_TYPE); | |
1521 aworker->implement_func=(custom_worker *)vis_real_add; | |
1522 aworker->input_types[0] = BUILTIN_TYPE_REAL; | |
1523 aworker->input_types[1] = BUILTIN_TYPE_REAL; | |
1524 | |
1525 //add_method(this_comp, aworker); | |
1526 | |
1527 aworker = create_worker(prog, "-@Real Number", 2, 1, WORKER_TYPE); | |
1528 aworker->implement_func=(custom_worker *)vis_real_subtract; | |
1529 aworker->input_types[0] = BUILTIN_TYPE_REAL; | |
1530 aworker->input_types[1] = BUILTIN_TYPE_REAL; | |
1531 | |
1532 aworker = create_worker(prog, "/@Real Number", 2, 1, WORKER_TYPE); | |
1533 aworker->implement_func=(custom_worker *)vis_real_div; | |
1534 aworker->input_types[0] = BUILTIN_TYPE_REAL; | |
1535 aworker->input_types[1] = BUILTIN_TYPE_REAL; | |
28
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1536 |
29
3cc5e4a42344
Missed registration for *@Real Number in previous commit
Mike Pavone <pavone@retrodev.com>
parents:
28
diff
changeset
|
1537 aworker = create_worker(prog, "*@Real Number", 2, 1, WORKER_TYPE); |
3cc5e4a42344
Missed registration for *@Real Number in previous commit
Mike Pavone <pavone@retrodev.com>
parents:
28
diff
changeset
|
1538 aworker->implement_func=(custom_worker *)vis_real_mult; |
3cc5e4a42344
Missed registration for *@Real Number in previous commit
Mike Pavone <pavone@retrodev.com>
parents:
28
diff
changeset
|
1539 aworker->input_types[0] = BUILTIN_TYPE_REAL; |
3cc5e4a42344
Missed registration for *@Real Number in previous commit
Mike Pavone <pavone@retrodev.com>
parents:
28
diff
changeset
|
1540 aworker->input_types[1] = BUILTIN_TYPE_REAL; |
3cc5e4a42344
Missed registration for *@Real Number in previous commit
Mike Pavone <pavone@retrodev.com>
parents:
28
diff
changeset
|
1541 |
28
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1542 aworker = create_worker(prog, "Cosine@Real Number", 1, 1, WORKER_TYPE); |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1543 aworker->implement_func=(custom_worker *)vis_real_cos; |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1544 aworker->input_types[0] = BUILTIN_TYPE_REAL; |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1545 |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1546 aworker = create_worker(prog, "Sine@Real Number", 1, 1, WORKER_TYPE); |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1547 aworker->implement_func=(custom_worker *)vis_real_sin; |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1548 aworker->input_types[0] = BUILTIN_TYPE_REAL; |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1549 |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1550 aworker = create_worker(prog, "Tangent@Real Number", 1, 1, WORKER_TYPE); |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1551 aworker->implement_func=(custom_worker *)vis_real_tan; |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1552 aworker->input_types[0] = BUILTIN_TYPE_REAL; |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1553 |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1554 aworker = create_worker(prog, "Arc Cosine@Real Number", 1, 1, WORKER_TYPE); |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1555 aworker->implement_func=(custom_worker *)vis_real_arccos; |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1556 aworker->input_types[0] = BUILTIN_TYPE_REAL; |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1557 |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1558 aworker = create_worker(prog, "Arc Sine@Real Number", 1, 1, WORKER_TYPE); |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1559 aworker->implement_func=(custom_worker *)vis_real_arcsin; |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1560 aworker->input_types[0] = BUILTIN_TYPE_REAL; |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1561 |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1562 aworker = create_worker(prog, "Arc Tangent@Real Number", 1, 1, WORKER_TYPE); |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1563 aworker->implement_func=(custom_worker *)vis_real_arctan; |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1564 aworker->input_types[0] = BUILTIN_TYPE_REAL; |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1565 |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1566 aworker = create_worker(prog, "^@Real Number", 2, 1, WORKER_TYPE); |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1567 aworker->implement_func=(custom_worker *)vis_real_exp; |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1568 aworker->input_types[0] = BUILTIN_TYPE_REAL; |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1569 aworker->input_types[1] = BUILTIN_TYPE_REAL; |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1570 |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1571 aworker = create_worker(prog, "Square Root@Real Number", 1, 1, WORKER_TYPE); |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1572 aworker->implement_func=(custom_worker *)vis_real_sqrt; |
d8b4d38fceb6
Merged in the worker registration code for the math functions added for ICFP 08
Mike Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
1573 aworker->input_types[0] = BUILTIN_TYPE_REAL; |
0 | 1574 |
46 | 1575 aworker = create_worker(prog, "Truncate to Whole@Real Number", 1, 1, WORKER_TYPE); |
1576 aworker->implement_func=(custom_worker *)vis_whole_fromreal; | |
1577 aworker->input_types[0] = BUILTIN_TYPE_REAL; | |
1578 | |
1579 aworker = create_worker(prog, "<Whole Number@Real Number", 1, 1, WORKER_TYPE); | |
1580 aworker->implement_func=(custom_worker *)vis_real_fromwhole; | |
1581 aworker->input_types[0] = BUILTIN_TYPE_WHOLE; | |
1582 | |
0 | 1583 //add_method(this_comp, aworker); |
1584 | |
1585 current_method = 0; | |
1586 this_comp = create_company(prog, "List", 7, 1, FALSE);//Index, Append, Swap, Insert, Remove, Set, Length, New | |
1587 comp_room = add_comp_room(this_comp, "Length", 0, 0, ROOM_NO_ACCESS, ROOM_LONG); | |
1588 | |
1589 aworker = create_worker(prog, "Index@List", 2, 2, WORKER_TYPE); | |
1590 aworker->implement_func=(custom_worker *)vis_list_index; | |
1591 aworker->input_types[0] = BUILTIN_TYPE_LIST; | |
1592 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1593 | |
1594 //add_method(this_comp, aworker); | |
1595 | |
1596 aworker = create_worker(prog, "Append@List", 2, 1, WORKER_TYPE); | |
1597 aworker->implement_func=(custom_worker *)vis_list_append; | |
1598 aworker->input_types[0] = BUILTIN_TYPE_LIST; | |
1599 aworker->input_types[1] = ANY_TYPE; | |
1600 | |
1601 //add_method(this_comp, aworker); | |
1602 | |
1603 aworker = create_worker(prog, "Swap@List",3, 1, WORKER_TYPE); | |
1604 aworker->implement_func=(custom_worker *)vis_list_swap; | |
1605 aworker->input_types[0] = BUILTIN_TYPE_LIST; | |
1606 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1607 aworker->input_types[2] = BUILTIN_TYPE_WHOLE; | |
1608 | |
1609 //add_method(this_comp, aworker); | |
1610 | |
1611 aworker = create_worker(prog, "Insert@List",3, 1, WORKER_TYPE); | |
1612 aworker->implement_func=(custom_worker *)vis_list_insert; | |
1613 aworker->input_types[0] = BUILTIN_TYPE_LIST; | |
1614 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1615 aworker->input_types[2] = ANY_TYPE; | |
1616 | |
1617 //add_method(this_comp, aworker); | |
1618 | |
1619 aworker = create_worker(prog, "Remove@List", 2, 1, WORKER_TYPE); | |
1620 aworker->implement_func=(custom_worker *)vis_list_remove; | |
1621 aworker->input_types[0] = BUILTIN_TYPE_LIST; | |
1622 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1623 | |
1624 //add_method(this_comp, aworker); | |
1625 | |
1626 aworker = create_worker(prog, "Set@List",3, 1, WORKER_TYPE); | |
1627 aworker->implement_func=(custom_worker *)vis_list_set; | |
1628 aworker->input_types[0] = BUILTIN_TYPE_LIST; | |
1629 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1630 aworker->input_types[2] = ANY_TYPE; | |
1631 | |
1632 //add_method(this_comp, aworker); | |
1633 | |
1634 aworker = create_worker(prog, "Length@List", 1, 1, WORKER_TYPE); | |
1635 aworker->implement_func = (custom_worker *)vis_list_length; | |
1636 aworker->input_types[0] = BUILTIN_TYPE_LIST; | |
1637 //add_method(this_comp, aworker); | |
1638 | |
47
6202b866d72c
Cleaned up constructor names and merged some other changes in to support the Rhope website
Mike Pavone <pavone@retrodev.com>
parents:
46
diff
changeset
|
1639 aworker = create_worker(prog, "List",0, 1, WORKER_TYPE); |
0 | 1640 aworker->implement_func=(custom_worker *)vis_list_new; |
1641 //add_method(this_comp, aworker); | |
1642 | |
1643 aworker = create_worker(prog, "First@List", 1, 2, WORKER_TYPE); | |
1644 aworker->implement_func=(custom_worker *)vis_list_first; | |
1645 aworker->input_types[0] = BUILTIN_TYPE_LIST; | |
1646 | |
1647 aworker = create_worker(prog, "Next@List", 2, 2, WORKER_TYPE); | |
1648 aworker->implement_func=(custom_worker *)vis_list_next; | |
1649 aworker->input_types[0] = BUILTIN_TYPE_LIST; | |
1650 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1651 | |
1652 current_method = 0; | |
1653 this_comp = create_company(prog, "Dictionary", 5, 0, FALSE);//Index, Swap, Remove, Set, Length, New | |
1654 aworker = create_worker(prog, "Index@Dictionary", 2, 2, WORKER_TYPE); | |
1655 aworker->implement_func=(custom_worker *)vis_dict_index; | |
1656 aworker->input_types[0] = BUILTIN_TYPE_DICT; | |
1657 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1658 | |
1659 //add_method(this_comp, aworker); | |
1660 | |
1661 aworker = create_worker(prog, "Swap@Dictionary",3, 1, WORKER_TYPE); | |
1662 aworker->implement_func=(custom_worker *)vis_dict_swap; | |
1663 aworker->input_types[0] = BUILTIN_TYPE_DICT; | |
1664 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1665 aworker->input_types[2] = BUILTIN_TYPE_STRING; | |
1666 | |
1667 //add_method(this_comp, aworker); | |
1668 | |
1669 aworker = create_worker(prog, "Remove@Dictionary", 2, 1, WORKER_TYPE); | |
1670 aworker->implement_func=(custom_worker *)vis_dict_remove; | |
1671 aworker->input_types[0] = BUILTIN_TYPE_DICT; | |
1672 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1673 | |
1674 //add_method(this_comp, aworker); | |
1675 | |
1676 aworker = create_worker(prog, "Set@Dictionary",3, 1, WORKER_TYPE); | |
1677 aworker->implement_func=(custom_worker *)vis_dict_set; | |
1678 aworker->input_types[0] = BUILTIN_TYPE_DICT; | |
1679 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1680 aworker->input_types[2] = ANY_TYPE; | |
1681 | |
1682 aworker = create_worker(prog, "Length@Dictionary", 1, 1, WORKER_TYPE); | |
1683 aworker->implement_func=(custom_worker *)vis_dict_length; | |
1684 aworker->input_types[0] = BUILTIN_TYPE_DICT; | |
1685 | |
1686 //add_method(this_comp, aworker); | |
1687 | |
47
6202b866d72c
Cleaned up constructor names and merged some other changes in to support the Rhope website
Mike Pavone <pavone@retrodev.com>
parents:
46
diff
changeset
|
1688 aworker = create_worker(prog, "Dictionary",0, 1, WORKER_TYPE); |
0 | 1689 aworker->implement_func=(custom_worker *)vis_dict_new; |
1690 //add_method(this_comp, aworker); | |
1691 | |
1692 aworker = create_worker(prog, "First@Dictionary", 1, 2, WORKER_TYPE); | |
1693 aworker->implement_func=(custom_worker *)vis_dict_first; | |
1694 aworker->input_types[0] = BUILTIN_TYPE_DICT; | |
1695 | |
1696 aworker = create_worker(prog, "Next@Dictionary", 2, 2, WORKER_TYPE); | |
1697 aworker->implement_func=(custom_worker *)vis_dict_next; | |
1698 aworker->input_types[0] = BUILTIN_TYPE_DICT; | |
1699 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1700 | |
1701 current_method = 0; | |
1702 #ifdef SEGA | |
1703 this_comp = create_company(prog, "File", 0, 0, FALSE); | |
1704 #else | |
1705 | |
1706 this_comp = create_company(prog, "File", 7, 0, FALSE);//<String, Get FString, Get DString, Get Byte, Get Word, Get Long, Put String | |
1707 aworker = create_worker(prog, "<String@File", 1, 1, WORKER_TYPE); | |
1708 aworker->implement_func=(custom_worker *)vis_file_from_string; | |
1709 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1710 //add_method(this_comp, aworker); | |
1711 | |
1712 aworker = create_worker(prog, "Get FString@File", 2, 2, WORKER_TYPE); | |
1713 aworker->implement_func=(custom_worker *)vis_file_get_fstring; | |
1714 aworker->input_types[0] = BUILTIN_TYPE_FILE; | |
1715 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1716 | |
1717 //add_method(this_comp, aworker); | |
1718 | |
1719 aworker = create_worker(prog, "Get DString@File", 2, 4, WORKER_TYPE); | |
1720 aworker->implement_func=(custom_worker *)vis_file_get_dstring; | |
1721 aworker->input_types[0] = BUILTIN_TYPE_FILE; | |
1722 aworker->input_types[1] = ANY_TYPE; | |
1723 | |
1724 //add_method(this_comp, aworker); | |
1725 | |
1726 aworker = create_worker(prog, "Get Byte@File", 1, 3, WORKER_TYPE); | |
1727 aworker->implement_func=(custom_worker *)vis_file_get_byte; | |
1728 aworker->input_types[0] = BUILTIN_TYPE_FILE; | |
1729 //add_method(this_comp, aworker); | |
1730 | |
1731 aworker = create_worker(prog, "Get Word@File", 1, 3, WORKER_TYPE); | |
1732 aworker->implement_func=(custom_worker *)vis_file_get_word; | |
1733 aworker->input_types[0] = BUILTIN_TYPE_FILE; | |
1734 //add_method(this_comp, aworker); | |
1735 | |
1736 aworker = create_worker(prog, "Get Long@File", 1, 3, WORKER_TYPE); | |
1737 aworker->implement_func=(custom_worker *)vis_file_get_long; | |
1738 aworker->input_types[0] = BUILTIN_TYPE_FILE; | |
1739 //add_method(this_comp, aworker); | |
1740 | |
26 | 1741 aworker = create_worker(prog, "Get Double@File", 1, 3, WORKER_TYPE); |
1742 aworker->implement_func=(custom_worker *)vis_file_get_double; | |
1743 aworker->input_types[0] = BUILTIN_TYPE_FILE; | |
1744 | |
0 | 1745 aworker = create_worker(prog, "Put String@File", 2, 1, WORKER_TYPE); |
1746 aworker->implement_func=(custom_worker *)vis_file_put_string; | |
1747 aworker->input_types[0] = BUILTIN_TYPE_FILE; | |
1748 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1749 | |
1750 aworker = create_worker(prog, "Length@File", 1, 1, WORKER_TYPE); | |
1751 aworker->implement_func=(custom_worker *)vis_file_length; | |
1752 aworker->input_types[0] = BUILTIN_TYPE_FILE; | |
1753 | |
1754 //add_method(this_comp, aworker); | |
1755 #endif | |
1756 | |
1757 current_method = 0; | |
1758 | |
1759 this_comp = create_company(prog, "Worker", 3, 0, FALSE);//<String, Do, Later: methods for manipulating | |
1760 | |
1761 aworker = create_worker(prog, "<String@Worker", 1, 1, WORKER_TYPE); | |
1762 aworker->implement_func=(custom_worker *)vis_worker_from_string; | |
1763 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1764 //add_method(this_comp, aworker); | |
1765 | |
1766 aworker = create_worker(prog, "Do@Worker", 2, 1, WORKER_TYPE); | |
1767 aworker->implement_func=(custom_worker *)vis_worker_do; | |
1768 aworker->input_types[0] = BUILTIN_TYPE_WORKER; | |
1769 aworker->input_types[1] = BUILTIN_TYPE_LIST; | |
1770 | |
1771 aworker = create_worker(prog, "Set Input@Worker", 3, 1, WORKER_TYPE); | |
1772 aworker->implement_func=(custom_worker *)vis_worker_setinput; | |
1773 aworker->input_types[0] = BUILTIN_TYPE_WORKER; | |
1774 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1775 aworker->input_types[2] = ANY_TYPE; | |
1776 //add_method(this_comp, aworker); | |
1777 | |
1778 aworker = create_worker(prog, "Add Worker Call@Worker", 2, 2, WORKER_TYPE); | |
1779 aworker->implement_func=(custom_worker *)vis_worker_add_worker_call; | |
1780 aworker->input_types[0] = BUILTIN_TYPE_WORKER; | |
1781 aworker->input_types[1] = BUILTIN_TYPE_WORKER; | |
1782 | |
1783 aworker = create_worker(prog, "Add Wire@Worker", 5, 1, WORKER_TYPE); | |
1784 aworker->implement_func=(custom_worker *)vis_worker_add_wire; | |
1785 aworker->input_types[0] = BUILTIN_TYPE_WORKER; | |
1786 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1787 aworker->input_types[2] = BUILTIN_TYPE_WHOLE; | |
1788 aworker->input_types[3] = BUILTIN_TYPE_WHOLE; | |
1789 aworker->input_types[4] = BUILTIN_TYPE_WHOLE; | |
1790 | |
1791 aworker = create_worker(prog, "Add Constant@Worker", 2, 2, WORKER_TYPE); | |
1792 aworker->implement_func=(custom_worker *)vis_worker_add_constant; | |
1793 aworker->input_types[0] = BUILTIN_TYPE_WORKER; | |
1794 aworker->input_types[1] = ANY_TYPE; | |
1795 | |
1796 aworker = create_worker(prog, "Add Input@Worker", 3, 2, WORKER_TYPE); | |
1797 aworker->implement_func=(custom_worker *)vis_worker_add_input; | |
1798 aworker->input_types[0] = BUILTIN_TYPE_WORKER; | |
1799 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1800 aworker->input_types[2] = BUILTIN_TYPE_WHOLE; | |
1801 | |
1802 aworker = create_worker(prog, "Add Output@Worker", 3, 2, WORKER_TYPE); | |
1803 aworker->implement_func=(custom_worker *)vis_worker_add_output; | |
1804 aworker->input_types[0] = BUILTIN_TYPE_WORKER; | |
1805 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1806 aworker->input_types[2] = BUILTIN_TYPE_WHOLE; | |
1807 | |
1808 aworker = create_worker(prog, "Add Object Get@Worker", 2, 2, WORKER_TYPE); | |
1809 aworker->implement_func=(custom_worker *)vis_worker_add_objectget; | |
1810 aworker->input_types[0] = BUILTIN_TYPE_WORKER; | |
1811 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1812 | |
1813 aworker = create_worker(prog, "Add Object Set@Worker", 2, 2, WORKER_TYPE); | |
1814 aworker->implement_func=(custom_worker *)vis_worker_add_objectset; | |
1815 aworker->input_types[0] = BUILTIN_TYPE_WORKER; | |
1816 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1817 | |
1818 aworker = create_worker(prog, "Add Global Get@Worker", 3, 2, WORKER_TYPE); | |
1819 aworker->implement_func=(custom_worker *)vis_worker_add_globalget; | |
1820 aworker->input_types[0] = BUILTIN_TYPE_WORKER; | |
1821 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1822 aworker->input_types[2] = BUILTIN_TYPE_STRING; | |
1823 | |
1824 aworker = create_worker(prog, "Add Global Set@Worker", 3, 2, WORKER_TYPE); | |
1825 aworker->implement_func=(custom_worker *)vis_worker_add_globalset; | |
1826 aworker->input_types[0] = BUILTIN_TYPE_WORKER; | |
1827 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1828 aworker->input_types[2] = BUILTIN_TYPE_STRING; | |
1829 | |
1830 aworker = create_worker(prog, "Clear@Worker", 1, 1, WORKER_TYPE); | |
1831 aworker->implement_func=(custom_worker *)vis_worker_clear; | |
1832 aworker->input_types[0] = BUILTIN_TYPE_WORKER; | |
1833 | |
1834 aworker = create_worker(prog, "Uses@Worker", 2, 1, WORKER_TYPE); | |
1835 aworker->implement_func=(custom_worker *)vis_worker_uses; | |
1836 aworker->input_types[0] = BUILTIN_TYPE_WORKER; | |
1837 aworker->input_types[1] = BUILTIN_TYPE_LIST; | |
1838 | |
1839 aworker = create_worker(prog, "Set IO Counts@Worker", 3, 1, WORKER_TYPE); | |
1840 aworker->implement_func=(custom_worker *)vis_worker_setio_counts; | |
1841 aworker->input_types[0] = BUILTIN_TYPE_WORKER; | |
1842 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1843 aworker->input_types[2] = BUILTIN_TYPE_WHOLE; | |
1844 | |
47
6202b866d72c
Cleaned up constructor names and merged some other changes in to support the Rhope website
Mike Pavone <pavone@retrodev.com>
parents:
46
diff
changeset
|
1845 aworker = create_worker(prog, "Worker", 1, 1, WORKER_TYPE); |
0 | 1846 aworker->implement_func=(custom_worker *)vis_worker_new; |
1847 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1848 | |
1849 #ifdef GUI_LIB | |
1850 current_method = 0; | |
1851 | |
1852 this_comp = create_company(prog, "Window", 3, 0, FALSE); | |
1853 | |
47
6202b866d72c
Cleaned up constructor names and merged some other changes in to support the Rhope website
Mike Pavone <pavone@retrodev.com>
parents:
46
diff
changeset
|
1854 aworker = create_worker(prog, "Window", 3, 1, WORKER_TYPE); |
0 | 1855 aworker->implement_func=(custom_worker *)vis_window_new; |
1856 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1857 aworker->input_types[1] = BUILTIN_TYPE_REAL; | |
1858 aworker->input_types[2] = BUILTIN_TYPE_REAL; | |
1859 //add_method(this_comp, aworker); | |
1860 | |
1861 aworker = create_worker(prog, "Add Widget@Window", 5, 1, WORKER_TYPE); | |
1862 aworker->implement_func=(custom_worker *)vis_window_add_widget; | |
1863 aworker->input_types[0] = BUILTIN_TYPE_WINDOW; | |
1864 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1865 aworker->input_types[2] = ANY_TYPE; | |
1866 aworker->input_types[3] = BUILTIN_TYPE_REAL; | |
1867 aworker->input_types[4] = BUILTIN_TYPE_REAL; | |
1868 //add_method(this_comp, aworker); | |
1869 | |
1870 aworker = create_worker(prog, "Show@Window", 3, 1, WORKER_TYPE); | |
1871 aworker->implement_func=(custom_worker *)vis_window_show; | |
1872 aworker->input_types[0] = BUILTIN_TYPE_WINDOW; | |
1873 aworker->input_types[1] = BUILTIN_TYPE_REAL; | |
1874 aworker->input_types[2] = BUILTIN_TYPE_REAL; | |
1875 //add_method(this_comp, aworker); | |
1876 | |
1877 current_method = 0; | |
1878 this_comp = create_company(prog, "Screen Window", 3, 0, FALSE); | |
1879 | |
1880 aworker = create_worker(prog, "Get Value@Screen Window", 2, 1, WORKER_TYPE); | |
1881 aworker->implement_func=(custom_worker *)vis_window_get_value; | |
1882 aworker->input_types[0] = BUILTIN_TYPE_WINDOW_SHOWN; | |
1883 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1884 //add_method(this_comp, aworker); | |
1885 | |
1886 aworker = create_worker(prog, "Set Value@Screen Window", 3, 0, WORKER_TYPE); | |
1887 aworker->implement_func=(custom_worker *)vis_window_set_value; | |
1888 aworker->input_types[0] = BUILTIN_TYPE_WINDOW_SHOWN; | |
1889 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1890 #ifdef SYLLABLE | |
1891 aworker->input_types[2] = ANY_TYPE; | |
1892 #else | |
1893 aworker->input_types[2] = BUILTIN_TYPE_STRING; | |
1894 #endif | |
1895 //add_method(this_comp, aworker); | |
1896 | |
1897 aworker = create_worker(prog, "Wait Close@Screen Window", 1, 1, WORKER_TYPE); | |
1898 aworker->implement_func=(custom_worker *)vis_window_wait_close; | |
1899 aworker->input_types[0] = BUILTIN_TYPE_WINDOW_SHOWN; | |
1900 //add_method(this_comp, aworker); | |
1901 | |
1902 #ifdef SYLLABLE | |
1903 aworker = create_worker(prog, "Add Widget@Screen Window", 5, 1, WORKER_TYPE); | |
1904 aworker->implement_func=(custom_worker *)vis_window_shown_addwidget; | |
1905 aworker->input_types[0] = BUILTIN_TYPE_WINDOW_SHOWN; | |
1906 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1907 aworker->input_types[2] = ANY_TYPE; | |
1908 aworker->input_types[3] = BUILTIN_TYPE_REAL; | |
1909 aworker->input_types[4] = BUILTIN_TYPE_REAL; | |
1910 #endif | |
1911 | |
1912 current_method = 0; | |
1913 create_company(prog, "Button", 2, 0, FALSE); | |
1914 | |
47
6202b866d72c
Cleaned up constructor names and merged some other changes in to support the Rhope website
Mike Pavone <pavone@retrodev.com>
parents:
46
diff
changeset
|
1915 aworker = create_worker(prog, "Button", 3, 1, WORKER_TYPE); |
0 | 1916 aworker->implement_func=(custom_worker *)vis_button_new; |
1917 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1918 aworker->input_types[1] = BUILTIN_TYPE_REAL; | |
1919 aworker->input_types[2] = BUILTIN_TYPE_REAL; | |
1920 //add_method(this_comp, aworker); | |
1921 | |
1922 aworker = create_worker(prog, "Set Handler@Button", 3, 1, WORKER_TYPE); | |
1923 aworker->implement_func=(custom_worker *)vis_button_set_handler; | |
1924 aworker->input_types[0] = BUILTIN_TYPE_BUTTON; | |
1925 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1926 aworker->input_types[2] = BUILTIN_TYPE_WORKER; | |
1927 //add_method(this_comp, aworker); | |
1928 | |
1929 current_method = 0; | |
1930 create_company(prog, "Input Box", 2, 0, FALSE); | |
1931 | |
47
6202b866d72c
Cleaned up constructor names and merged some other changes in to support the Rhope website
Mike Pavone <pavone@retrodev.com>
parents:
46
diff
changeset
|
1932 aworker = create_worker(prog, "Input Box", 3, 1, WORKER_TYPE); |
0 | 1933 aworker->implement_func=(custom_worker *)vis_inputbox_new; |
1934 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1935 aworker->input_types[1] = BUILTIN_TYPE_REAL; | |
1936 aworker->input_types[2] = BUILTIN_TYPE_REAL; | |
1937 //add_method(this_comp, aworker); | |
1938 | |
1939 aworker = create_worker(prog, "Set Type@Input Box", 2, 1, WORKER_TYPE); | |
1940 aworker->implement_func=(custom_worker *)vis_inputbox_settype; | |
1941 aworker->input_types[0] = BUILTIN_TYPE_INPUTBOX; | |
1942 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1943 //add_method(this_comp, aworker); | |
1944 | |
1945 #endif | |
1946 #ifndef NO_NET | |
1947 this_comp = create_company(prog, "Net Client", 3, 0, FALSE); | |
47
6202b866d72c
Cleaned up constructor names and merged some other changes in to support the Rhope website
Mike Pavone <pavone@retrodev.com>
parents:
46
diff
changeset
|
1948 aworker = create_worker(prog, "Net Client", 2, 1, WORKER_TYPE); |
0 | 1949 aworker->implement_func =(custom_worker *)net_client_new; |
1950 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
1951 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1952 | |
1953 aworker = create_worker(prog, "Put String@Net Client", 2, 2, WORKER_TYPE); | |
1954 aworker->implement_func = (custom_worker *)net_client_put_string; | |
1955 aworker->input_types[0] = BUILTIN_TYPE_NETCLIENT; | |
1956 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1957 | |
1958 aworker = create_worker(prog, "Get FString@Net Client", 2, 3, WORKER_TYPE); | |
1959 aworker->implement_func = (custom_worker *)net_client_get_fstring; | |
1960 aworker->input_types[0] = BUILTIN_TYPE_NETCLIENT; | |
1961 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
1962 | |
1963 aworker = create_worker(prog, "Get DString@Net Client", 2, 4, WORKER_TYPE); | |
1964 aworker->implement_func = (custom_worker *)net_client_get_dstring; | |
1965 aworker->input_types[0] = BUILTIN_TYPE_NETCLIENT; | |
1966 aworker->input_types[1] = ANY_TYPE; | |
1967 | |
1968 aworker = create_worker(prog, "Put Raw@Net Client", 2, 2, WORKER_TYPE); | |
1969 aworker->implement_func = (custom_worker *)net_client_put_raw; | |
1970 aworker->input_types[0] = BUILTIN_TYPE_NETCLIENT; | |
1971 aworker->input_types[1] = ANY_TYPE; | |
1972 | |
1973 aworker = create_worker(prog, "Get Raw@Net Client", 2, 3, WORKER_TYPE); | |
1974 aworker->implement_func = (custom_worker *)net_client_get_raw; | |
1975 aworker->input_types[0] = BUILTIN_TYPE_NETCLIENT; | |
1976 aworker->input_types[1] = ANY_TYPE; | |
1977 | |
1978 aworker = create_worker(prog, "Listen on Port", 2, 0, WORKER_TYPE); | |
1979 aworker->implement_func = (custom_worker *)vis_net_listenport; | |
1980 aworker->input_types[0] = BUILTIN_TYPE_WHOLE; | |
1981 aworker->input_types[1] = BUILTIN_TYPE_WORKER; | |
1982 #endif | |
1983 | |
1984 create_company(prog, "Global Store", 0, 0, FALSE); | |
1985 | |
1986 create_company(prog, "Program", 5, 0, FALSE); | |
1987 | |
47
6202b866d72c
Cleaned up constructor names and merged some other changes in to support the Rhope website
Mike Pavone <pavone@retrodev.com>
parents:
46
diff
changeset
|
1988 aworker = create_worker(prog, "Program", 0, 1, WORKER_TYPE); |
0 | 1989 aworker->implement_func = (custom_worker *)vis_program_new; |
1990 | |
1991 aworker = create_worker(prog, "New Worker@Program", 2, 2, WORKER_TYPE); | |
1992 aworker->implement_func = (custom_worker *)vis_program_new_worker; | |
1993 aworker->input_types[0] = BUILTIN_TYPE_PROGRAM; | |
1994 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
1995 | |
1996 aworker = create_worker(prog, "Add Worker@Program", 2, 2, WORKER_TYPE); | |
1997 aworker->implement_func = (custom_worker *)vis_program_add_worker; | |
1998 aworker->input_types[0] = BUILTIN_TYPE_PROGRAM; | |
1999 aworker->input_types[1] = BUILTIN_TYPE_WORKER; | |
2000 | |
2001 aworker = create_worker(prog, "Add Builtins@Program", 1, 1, WORKER_TYPE); | |
2002 aworker->implement_func = (custom_worker *)vis_program_add_builtins; | |
2003 aworker->input_types[0] = BUILTIN_TYPE_PROGRAM; | |
2004 | |
2005 aworker = create_worker(prog, "Run@Program", 2, 1, WORKER_TYPE); | |
2006 aworker->implement_func = (custom_worker *)vis_program_run; | |
2007 aworker->input_types[0] = BUILTIN_TYPE_PROGRAM; | |
2008 aworker->input_types[1] = ANY_TYPE; | |
2009 | |
2010 aworker = create_worker(prog, "Find Worker@Program", 2, 2, WORKER_TYPE); | |
2011 aworker->implement_func = (custom_worker *)vis_program_find_worker; | |
2012 aworker->input_types[0] = BUILTIN_TYPE_PROGRAM; | |
2013 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
2014 | |
2015 #ifdef GUI_LIB | |
2016 #ifdef SYLLABLE | |
2017 create_company(prog, "Custom Widget", 2, 0, FALSE); | |
2018 | |
47
6202b866d72c
Cleaned up constructor names and merged some other changes in to support the Rhope website
Mike Pavone <pavone@retrodev.com>
parents:
46
diff
changeset
|
2019 aworker = create_worker(prog, "Custom Widget", 3, 1, WORKER_TYPE); |
0 | 2020 aworker->implement_func=(custom_worker *)vis_customwidget_new; |
2021 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
2022 aworker->input_types[1] = BUILTIN_TYPE_REAL; | |
2023 aworker->input_types[2] = BUILTIN_TYPE_REAL; | |
2024 //add_method(this_comp, aworker); | |
2025 | |
2026 aworker = create_worker(prog, "Set Handler@Custom Widget", 3, 1, WORKER_TYPE); | |
2027 aworker->implement_func=(custom_worker *)vis_button_set_handler; | |
2028 aworker->input_types[0] = BUILTIN_TYPE_CUSTOM_WIDGET; | |
2029 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
2030 aworker->input_types[2] = BUILTIN_TYPE_WORKER; | |
2031 //add_method(this_comp, aworker); | |
2032 | |
2033 create_company(prog, "Screen Custom Widget", 3, 0, FALSE); | |
2034 | |
2035 aworker = create_worker(prog, "Default Draw@Screen Custom Widget", 1, 1, WORKER_TYPE); | |
2036 aworker->implement_func=(custom_worker *)vis_screen_custom_defaultpaint; | |
2037 aworker->input_types[0] = BUILTIN_TYPE_SCREEN_CUSTOM; | |
2038 //add_method(this_comp, aworker); | |
2039 | |
2040 aworker = create_worker(prog, "Draw Line@Screen Custom Widget", 5, 1, WORKER_TYPE); | |
2041 aworker->implement_func=(custom_worker *)vis_screen_custom_drawline; | |
2042 aworker->input_types[0] = BUILTIN_TYPE_SCREEN_CUSTOM; | |
2043 aworker->input_types[1] = BUILTIN_TYPE_REAL; | |
2044 aworker->input_types[2] = BUILTIN_TYPE_REAL; | |
2045 aworker->input_types[3] = BUILTIN_TYPE_REAL; | |
2046 aworker->input_types[4] = BUILTIN_TYPE_REAL; | |
2047 //add_method(this_comp, aworker); | |
2048 | |
2049 aworker = create_worker(prog, "Draw String@Screen Custom Widget", 4, 1, WORKER_TYPE); | |
2050 aworker->implement_func=(custom_worker *)vis_screen_custom_drawstring; | |
2051 aworker->input_types[0] = BUILTIN_TYPE_SCREEN_CUSTOM; | |
2052 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
2053 aworker->input_types[2] = BUILTIN_TYPE_REAL; | |
2054 aworker->input_types[3] = BUILTIN_TYPE_REAL; | |
2055 | |
2056 aworker = create_worker(prog, "Set Draw Color@Screen Custom Widget", 5, 1, WORKER_TYPE); | |
2057 aworker->implement_func=(custom_worker *)vis_screen_custom_setdrawcolor; | |
2058 aworker->input_types[0] = BUILTIN_TYPE_SCREEN_CUSTOM; | |
2059 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
2060 aworker->input_types[2] = BUILTIN_TYPE_WHOLE; | |
2061 aworker->input_types[3] = BUILTIN_TYPE_WHOLE; | |
2062 aworker->input_types[4] = BUILTIN_TYPE_WHOLE; | |
2063 | |
2064 aworker = create_worker(prog, "Move By@Screen Custom Widget", 3, 1, WORKER_TYPE); | |
2065 aworker->implement_func=(custom_worker *)vis_screen_custom_moveby; | |
2066 aworker->input_types[0] = BUILTIN_TYPE_SCREEN_CUSTOM; | |
2067 aworker->input_types[1] = BUILTIN_TYPE_REAL; | |
2068 aworker->input_types[2] = BUILTIN_TYPE_REAL; | |
2069 | |
2070 aworker = create_worker(prog, "Set Handler@Screen Custom Widget", 3, 1, WORKER_TYPE); | |
2071 aworker->implement_func=(custom_worker *)vis_screen_custom_sethandler; | |
2072 aworker->input_types[0] = BUILTIN_TYPE_SCREEN_CUSTOM; | |
2073 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
2074 aworker->input_types[2] = BUILTIN_TYPE_WORKER; | |
2075 | |
2076 aworker = create_worker(prog, "Remove Handler@Screen Custom Widget", 2, 1, WORKER_TYPE); | |
2077 aworker->implement_func=(custom_worker *)vis_screen_custom_removehandler; | |
2078 aworker->input_types[0] = BUILTIN_TYPE_SCREEN_CUSTOM; | |
2079 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
2080 | |
2081 aworker = create_worker(prog, "Give Focus@Screen Custom Widget", 2, 1, WORKER_TYPE); | |
2082 aworker->implement_func=(custom_worker *)vis_screen_custom_givefocus; | |
2083 aworker->input_types[0] = BUILTIN_TYPE_SCREEN_CUSTOM; | |
2084 aworker->input_types[1] = BUILTIN_TYPE_YESNO; | |
2085 | |
2086 aworker = create_worker(prog, "Add Widget@Screen Custom Widget", 5, 1, WORKER_TYPE); | |
2087 aworker->implement_func=(custom_worker *)vis_screen_custom_addwidget; | |
2088 aworker->input_types[0] = BUILTIN_TYPE_SCREEN_CUSTOM; | |
2089 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
2090 aworker->input_types[2] = ANY_TYPE; | |
2091 aworker->input_types[3] = BUILTIN_TYPE_REAL; | |
2092 aworker->input_types[4] = BUILTIN_TYPE_REAL; | |
2093 | |
2094 #endif | |
2095 #endif | |
2096 create_company(prog, "Buffer", 7, 0, FALSE); | |
2097 | |
47
6202b866d72c
Cleaned up constructor names and merged some other changes in to support the Rhope website
Mike Pavone <pavone@retrodev.com>
parents:
46
diff
changeset
|
2098 aworker = create_worker(prog, "Buffer", 1, 1, WORKER_TYPE); |
0 | 2099 aworker->implement_func=(custom_worker *)vis_buffer_new; |
2100 aworker->input_types[0] = BUILTIN_TYPE_WHOLE; | |
2101 | |
2102 aworker = create_worker(prog, "Lock@Buffer", 1, 1, WORKER_TYPE); | |
2103 aworker->implement_func=(custom_worker *)vis_buffer_lock; | |
2104 aworker->input_types[0] = BUILTIN_TYPE_BUFFER; | |
2105 | |
2106 aworker = create_worker(prog, "Unlock@Buffer", 1, 1, WORKER_TYPE); | |
2107 aworker->implement_func=(custom_worker *)vis_buffer_unlock; | |
2108 aworker->input_types[0] = BUILTIN_TYPE_BUFFER; | |
2109 | |
2110 aworker = create_worker(prog, "Put Byte@Buffer", 2, 1, WORKER_TYPE); | |
2111 aworker->implement_func=(custom_worker *)vis_buffer_putbyte; | |
2112 aworker->input_types[0] = BUILTIN_TYPE_BUFFER; | |
2113 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
2114 | |
2115 aworker = create_worker(prog, "Write Byte@Buffer", 2, 1, WORKER_TYPE); | |
2116 aworker->implement_func=(custom_worker *)vis_buffer_writebyte; | |
2117 aworker->input_types[0] = BUILTIN_TYPE_BUFFER; | |
2118 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
2119 | |
2120 aworker = create_worker(prog, "Put Word@Buffer", 2, 1, WORKER_TYPE); | |
2121 aworker->implement_func=(custom_worker *)vis_buffer_putshort; | |
2122 aworker->input_types[0] = BUILTIN_TYPE_BUFFER; | |
2123 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
2124 | |
2125 aworker = create_worker(prog, "Write Word@Buffer", 2, 1, WORKER_TYPE); | |
2126 aworker->implement_func=(custom_worker *)vis_buffer_writeshort; | |
2127 aworker->input_types[0] = BUILTIN_TYPE_BUFFER; | |
2128 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
2129 | |
2130 aworker = create_worker(prog, "Put Long@Buffer", 2, 1, WORKER_TYPE); | |
2131 aworker->implement_func=(custom_worker *)vis_buffer_putlong; | |
2132 aworker->input_types[0] = BUILTIN_TYPE_BUFFER; | |
2133 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
2134 | |
2135 aworker = create_worker(prog, "Write Long@Buffer", 2, 1, WORKER_TYPE); | |
2136 aworker->implement_func=(custom_worker *)vis_buffer_writelong; | |
2137 aworker->input_types[0] = BUILTIN_TYPE_BUFFER; | |
2138 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
2139 | |
2140 aworker = create_worker(prog, "Reset@Buffer", 1, 1, WORKER_TYPE); | |
2141 aworker->implement_func=(custom_worker *)vis_buffer_reset; | |
2142 aworker->input_types[0] = BUILTIN_TYPE_BUFFER; | |
2143 | |
2144 #if defined(SEGA) || defined(NINTENDO_DS) | |
2145 | |
2146 aworker = create_worker(prog, "From Address@Buffer", 2, 1, WORKER_TYPE); | |
2147 aworker->implement_func=(custom_worker *)vis_buffer_fromaddress; | |
2148 aworker->input_types[0] = BUILTIN_TYPE_WHOLE; | |
2149 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
2150 #endif //SEGA | |
2151 | |
2152 create_company(prog, "Blueprint", 4, 0, FALSE); | |
2153 | |
47
6202b866d72c
Cleaned up constructor names and merged some other changes in to support the Rhope website
Mike Pavone <pavone@retrodev.com>
parents:
46
diff
changeset
|
2154 aworker = create_worker(prog, "Blueprint", 1, 1, WORKER_TYPE); |
0 | 2155 aworker->implement_func=(custom_worker *)vis_blueprint_new; |
2156 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
2157 | |
2158 aworker = create_worker(prog, "Add Field@Blueprint", 3, 1, WORKER_TYPE); | |
2159 aworker->implement_func=(custom_worker *)vis_blueprint_addfield; | |
2160 aworker->input_types[0] = BUILTIN_TYPE_BLUEPRINT; | |
2161 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
2162 aworker->input_types[2] = BUILTIN_TYPE_STRING; | |
2163 | |
2164 aworker = create_worker(prog, "Name@Blueprint", 1, 1, WORKER_TYPE); | |
2165 aworker->implement_func=(custom_worker *)vis_blueprint_name; | |
2166 aworker->input_types[0] = BUILTIN_TYPE_BLUEPRINT; | |
2167 | |
2168 aworker = create_worker(prog, "Get Fields@Blueprint", 1, 1, WORKER_TYPE); | |
2169 aworker->implement_func=(custom_worker *)vis_blueprint_getfields; | |
2170 aworker->input_types[0] = BUILTIN_TYPE_BLUEPRINT; | |
2171 | |
2172 aworker = create_worker(prog, "Blueprint Of", 1, 1, WORKER_TYPE); | |
2173 aworker->implement_func=(custom_worker *)vis_get_blueprint; | |
2174 aworker->input_types[0] = ANY_TYPE; | |
2175 | |
2176 aworker = create_worker(prog, "Get Field", 2, 2, WORKER_TYPE); | |
2177 aworker->implement_func=(custom_worker *)vis_get_field; | |
2178 aworker->input_types[0] = ANY_TYPE; | |
2179 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
2180 | |
2181 aworker = create_worker(prog, "Set Field", 3, 1, WORKER_TYPE); | |
2182 aworker->implement_func=(custom_worker *)vis_set_field; | |
2183 aworker->input_types[0] = ANY_TYPE; | |
2184 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
2185 aworker->input_types[2] = ANY_TYPE; | |
2186 | |
2187 aworker = create_worker(prog, "New Blueprint@Program", 2, 2, WORKER_TYPE); | |
2188 aworker->implement_func=(custom_worker *)vis_program_newblueprint; | |
2189 aworker->input_types[0] = BUILTIN_TYPE_PROGRAM; | |
2190 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
2191 | |
13 | 2192 #ifdef GUI_LIB |
0 | 2193 #ifdef SYLLABLE |
2194 create_company(prog, "Checkbox", 2, 0, FALSE); | |
2195 | |
47
6202b866d72c
Cleaned up constructor names and merged some other changes in to support the Rhope website
Mike Pavone <pavone@retrodev.com>
parents:
46
diff
changeset
|
2196 aworker = create_worker(prog, "Checkbox", 4, 1, WORKER_TYPE); |
0 | 2197 aworker->implement_func=(custom_worker *)vis_checkbox_new; |
2198 aworker->input_types[0] = BUILTIN_TYPE_STRING; | |
2199 aworker->input_types[1] = BUILTIN_TYPE_REAL; | |
2200 aworker->input_types[2] = BUILTIN_TYPE_REAL; | |
2201 aworker->input_types[3] = BUILTIN_TYPE_YESNO; | |
2202 | |
2203 aworker = create_worker(prog, "Set Handler@Checkbox", 3, 1, WORKER_TYPE); | |
2204 aworker->implement_func=(custom_worker *)vis_button_set_handler; | |
2205 aworker->input_types[0] = BUILTIN_TYPE_CHECKBOX; | |
2206 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
2207 aworker->input_types[2] = BUILTIN_TYPE_WORKER; | |
2208 | |
2209 create_company(prog, "Dropdown", 4, 0, FALSE); | |
2210 | |
47
6202b866d72c
Cleaned up constructor names and merged some other changes in to support the Rhope website
Mike Pavone <pavone@retrodev.com>
parents:
46
diff
changeset
|
2211 aworker = create_worker(prog, "Dropdown", 3, 1, WORKER_TYPE); |
0 | 2212 aworker->implement_func=(custom_worker *)vis_dropdown_new; |
2213 aworker->input_types[0] = BUILTIN_TYPE_LIST; | |
2214 aworker->input_types[1] = BUILTIN_TYPE_REAL; | |
2215 aworker->input_types[2] = BUILTIN_TYPE_REAL; | |
2216 | |
2217 aworker = create_worker(prog, "Set Handler@Dropdown", 3, 1, WORKER_TYPE); | |
2218 aworker->implement_func=(custom_worker *)vis_button_set_handler; | |
2219 aworker->input_types[0] = BUILTIN_TYPE_DROPDOWN; | |
2220 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
2221 aworker->input_types[2] = BUILTIN_TYPE_WORKER; | |
2222 | |
2223 aworker = create_worker(prog, "Set Text@Dropdown", 2, 1, WORKER_TYPE); | |
2224 aworker->implement_func=(custom_worker *)vis_dropdown_settext; | |
2225 aworker->input_types[0] = BUILTIN_TYPE_DROPDOWN; | |
2226 aworker->input_types[1] = BUILTIN_TYPE_STRING; | |
2227 | |
2228 aworker = create_worker(prog, "Select@Dropdown", 2, 1, WORKER_TYPE); | |
2229 aworker->implement_func=(custom_worker *)vis_dropdown_select; | |
2230 aworker->input_types[0] = BUILTIN_TYPE_DROPDOWN; | |
2231 aworker->input_types[1] = BUILTIN_TYPE_WHOLE; | |
2232 #endif | |
13 | 2233 #endif |
31
fab5bb137cf9
Added Unix Time worker to interpreter
Mike Pavone <pavone@retrodev.com>
parents:
29
diff
changeset
|
2234 aworker = create_worker(prog, "Unix Time", 0, 1, WORKER_TYPE); |
fab5bb137cf9
Added Unix Time worker to interpreter
Mike Pavone <pavone@retrodev.com>
parents:
29
diff
changeset
|
2235 aworker->implement_func=(custom_worker *)unix_time; |
0 | 2236 /*if(current_def > num_defs) |
2237 num_defs = current_def; | |
2238 if(current_company > num_companies) | |
2239 num_companies = current_company;*/ | |
2240 } | |
2241 | |
2242 void initworkers(program * prog) | |
2243 { | |
2244 //num_defs=0; | |
2245 //num_companies=0; | |
2246 create_worker(prog, "Main", 0, 0, USER_FLAG | WORKER_TYPE); | |
2247 | |
2248 initpredefworkers(prog); | |
2249 | |
2250 } | |
2251 /* | |
2252 void add_if_ready(int workerNum, worker_instance * instance) | |
2253 { | |
2254 //int i, j, n, old_ready_count; | |
2255 BOOL ready=FALSE; | |
2256 //int paramstore[32]; | |
2257 //int * params = paramstore; | |
2258 DEBUGPUTS("add_if_ready\n"); | |
2259 if(!instance || !instance->def) | |
2260 return; | |
2261 VIS_PROFILE_START(PROF_ADDREADY); | |
2262 DEBUGPRINTF( "add_if_ready on %s\n", instance->def->implement_func->workerlist[workerNum].name); | |
2263 VIS_EnterCriticalSection(instance->workerlist[workerNum].worker_lock); | |
2264 ++instance->workerlist[workerNum].ready_count; | |
2265 if(instance->workerlist[workerNum].ready_count >= (instance->def->implement_func->workerlist[workerNum].num_inputs + (instance->def->implement_func->workerlist[workerNum].null_input ? 1 : 0))) | |
2266 { | |
2267 ready = TRUE; | |
2268 instance->workerlist[workerNum].ready_count = 0; | |
2269 } | |
2270 VIS_LeaveCriticalSection(instance->workerlist[workerNum].worker_lock); | |
2271 if(ready) | |
2272 { | |
2273 DEBUGPRINTF("add_queue on %s\n", instance->def->implement_func->workerlist[workerNum].name); | |
2274 add_queue(workerNum, instance); | |
2275 } | |
2276 VIS_PROFILE_END(PROF_ADDREADY); | |
2277 }*/ | |
2278 #define RETURN_CODE_EXIT 0xABCE1234 | |
2279 #define RETURN_CODE_IDLE 0x00BADFAD | |
2280 #define RETURN_CODE_NORMAL 0xABBAABBA | |
2281 #define RETURN_CODE_PARALLEL 0xC001D00D | |
2282 #define GET_OP1(opcode) ((opcode & 0xF0000000) >> 28) | |
2283 #define GET_OP2(opcode) ((opcode & 0x0F000000) >> 24) | |
2284 #define GET_INST(opcode) ((opcode & 0x00FF0000) >> 16) | |
2285 | |
2286 #define MOVE_INST 0x00 | |
2287 #define ADDREF_INST 0x01 | |
2288 #define RELEASE_INST 0x02 | |
2289 #define LOAD_INST 0x03 | |
2290 #define CALL_INST 0x04 | |
2291 #define CALLB_INST 0x05 | |
2292 #define CALLP_INST 0x06 | |
2293 #define CALLBP_INST 0x07 | |
2294 #define RETURN_INST 0x08 | |
2295 #define BRANCH_INST 0x09 | |
2296 #define BRANCHT_INST 0x0A | |
2297 #define BRANCHF_INST 0x0B | |
2298 #define WAIT_INST 0x0C | |
2299 #define ADD_INST 0x0D | |
2300 #define SUB_INST 0x0E | |
2301 #define SUBR_INST 0x0F | |
2302 #define GREATER_INST 0x10 | |
2303 #define LESSER_INST 0x11 | |
2304 | |
2305 #define REGISTER_BIT 0x8 | |
2306 #define NO_OPERAND 0x7 | |
2307 #define OP_REG_MASK 0x7 | |
2308 #define GET_REGNUM1(opcode) ((opcode & 0x0000FF00) >> 8) | |
2309 #define GET_REGNUM2(opcode) (opcode & 0x000000FF) | |
2310 | |
2311 #define REG_DIRECT 0 | |
2312 #define REG_INDIRECT 1 | |
2313 #define IMMED_8 2 | |
2314 #define IMMED_32 3 | |
2315 #define STACK_8 4 | |
2316 #define REG_REL_32 5 | |
2317 #define PC_REL_8 6 | |
2318 | |
2319 #define STACK_REG 31 | |
2320 #define PC_REG 30 | |
2321 | |
2322 #define OPC(inst, op1, reg1, op2, reg2) ((op1 << 28) | (op2 << 24) | (inst << 16) | ((reg1 & 0xff) << 8) | (reg2 & 0xFF)) | |
2323 | |
2324 //unsigned long test_program[] = | |
2325 //{ | |
2326 // OPC(LOAD_INST, PC_REL_8, 8 /* Hi */, REG_DIRECT, 0), | |
2327 // OPC(CALLB_INST, IMMED_8, 1/* Print */, NO_OPERAND, 0), | |
2328 // OPC(RETURN_INST, NO_OPERAND, 0, NO_OPERAND, 0), | |
2329 // 26952//Hi | |
2330 //}; | |
2331 | |
2332 unsigned long test_program[] = | |
2333 { | |
2334 //Main: | |
2335 OPC(LOAD_INST, PC_REL_8, 20/* 10 */, REG_DIRECT, 0), | |
2336 OPC(LOAD_INST, PC_REL_8, 20/* 2 */, PC_REL_8, 28), | |
2337 OPC(LOAD_INST, PC_REL_8, 20/* 1 */, PC_REL_8, 28), | |
2338 OPC(CALL_INST, PC_REL_8, 28/* Fib: */, NO_OPERAND, 0), | |
2339 OPC(CALLB_INST, IMMED_8, 1/* Print */, NO_OPERAND, 0), | |
2340 OPC(RETURN_INST, NO_OPERAND, 0, NO_OPERAND, 0), | |
2341 0x3033,//'30' | |
2342 0x32,//'2' | |
2343 0x31,//'1' | |
2344 0,//2 storage | |
2345 0,//1 storage | |
2346 //Fib: | |
2347 OPC(ADD_INST, IMMED_8, 8, REG_DIRECT, STACK_REG), | |
2348 OPC(MOVE_INST, REG_DIRECT, 0, STACK_8, -4), | |
2349 OPC(ADDREF_INST, REG_INDIRECT, 0, NO_OPERAND, 0), | |
2350 OPC(ADDREF_INST, REG_INDIRECT, 0, NO_OPERAND, 0), | |
2351 OPC(MOVE_INST, PC_REL_8, -28/* 2 */, REG_DIRECT, 1), | |
2352 OPC(ADDREF_INST, REG_INDIRECT, 1, NO_OPERAND, 0), | |
2353 OPC(CALLB_INST, IMMED_8, 8/* < */, NO_OPERAND, 0), | |
2354 OPC(CALLB_INST, IMMED_8, 11/* If */, NO_OPERAND, 0), | |
2355 OPC(BRANCHT_INST, PC_REL_8, 64/* _Base */, REG_DIRECT, 0), | |
2356 | |
2357 OPC(RELEASE_INST, REG_INDIRECT, 1, NO_OPERAND, 0), | |
2358 OPC(MOVE_INST, STACK_8, -4, REG_DIRECT, 0), | |
2359 OPC(MOVE_INST, PC_REL_8, -56/* 2 */, REG_DIRECT, 1), | |
2360 OPC(ADDREF_INST, REG_INDIRECT, 1, NO_OPERAND, 0), | |
2361 OPC(CALLB_INST, IMMED_8, 6/* - */, NO_OPERAND, 0), | |
2362 OPC(CALL_INST, PC_REL_8, -60/* Fib */, NO_OPERAND, 0), | |
2363 OPC(MOVE_INST, REG_DIRECT, 0, STACK_8, -8), | |
2364 OPC(MOVE_INST, STACK_8, -4, REG_DIRECT, 0), | |
2365 OPC(MOVE_INST, PC_REL_8, -76/* 1 */, REG_DIRECT, 1), | |
2366 OPC(ADDREF_INST, REG_INDIRECT, 1, NO_OPERAND, 0), | |
2367 OPC(CALLB_INST, IMMED_8, 6/* - */, NO_OPERAND, 0), | |
2368 OPC(CALL_INST, PC_REL_8, -84/* Fib */, NO_OPERAND, 0), | |
2369 OPC(MOVE_INST, STACK_8, -8, REG_DIRECT, 1), | |
2370 OPC(CALLB_INST, IMMED_8, 5/* + */, NO_OPERAND, 0), | |
2371 OPC(SUBR_INST, IMMED_8, 8, REG_DIRECT, STACK_REG), | |
2372 OPC(RETURN_INST, NO_OPERAND, 0, NO_OPERAND, 0), | |
2373 //_Base: | |
2374 OPC(RELEASE_INST, REG_INDIRECT, 0, NO_OPERAND, 0), | |
2375 OPC(MOVE_INST, PC_REL_8, -112/* 1 */, REG_DIRECT, 0), | |
2376 OPC(ADDREF_INST, REG_INDIRECT, 0, NO_OPERAND, 0), | |
2377 OPC(SUBR_INST, IMMED_8, 8, REG_DIRECT, STACK_REG), | |
2378 OPC(RETURN_INST, NO_OPERAND, 0, NO_OPERAND, 0), | |
2379 | |
2380 }; | |
2381 | |
2382 unsigned long * get_effective_address(char op, unsigned short regnum, unsigned long ** pc, unsigned long * registers, unsigned long * immed) | |
2383 { | |
2384 unsigned long * add = NULL; | |
2385 unsigned long work; | |
2386 if(op != NO_OPERAND) | |
2387 { | |
2388 if(op & REGISTER_BIT) | |
2389 add = (unsigned long *)(registers[regnum] + registers[op & OP_REG_MASK]); | |
2390 else | |
2391 { | |
2392 switch(op) | |
2393 { | |
2394 case REG_DIRECT: | |
2395 add = registers + regnum; | |
2396 break; | |
2397 case REG_INDIRECT: | |
2398 add = (unsigned long *) registers[regnum]; | |
2399 break; | |
2400 case IMMED_8: | |
2401 *immed = (char)regnum; | |
2402 add = (unsigned long *)immed; | |
2403 break; | |
2404 case IMMED_32: | |
2405 *immed = *((*pc)++); | |
2406 add = (unsigned long *)immed; | |
2407 break; | |
2408 case STACK_8: | |
2409 work = (char)regnum; | |
2410 add = (unsigned long *)(registers[STACK_REG] + work); | |
2411 break; | |
2412 case REG_REL_32: | |
2413 work = *((*pc)++); | |
2414 add = (unsigned long *)(registers[regnum] + work); | |
2415 break; | |
2416 case PC_REL_8: | |
2417 work = (char)regnum; | |
2418 add = (unsigned long *)(registers[PC_REG] + work); | |
2419 break; | |
2420 default: | |
2421 break; | |
2422 } | |
2423 } | |
2424 } | |
2425 return add; | |
2426 } | |
2427 | |
2428 DWORD WINAPI virtual_processor(unsigned long * program, BOOL main) | |
2429 { | |
2430 int i; | |
2431 unsigned long **pc; | |
2432 unsigned long **stack; | |
2433 unsigned long registers[32]; | |
2434 unsigned long opcode; | |
2435 unsigned long extra, extra2; | |
2436 queue_entry entry; | |
2437 stack_segment initial_stack; | |
2438 stack_segment * current = &initial_stack; | |
2439 char slot_usage[7]; | |
2440 char op1, op2; | |
2441 char inst; | |
2442 unsigned long *add1, *add2; | |
2443 long immed1, immed2; | |
2444 initial_stack.size = MIN_STACK_SIZE; | |
2445 initial_stack.parent = initial_stack.child = NULL; | |
2446 initial_stack.data[0] = main ? RETURN_CODE_EXIT : RETURN_CODE_IDLE; | |
2447 pc = (unsigned long **)(&(registers[PC_REG])); | |
2448 stack = (unsigned long **)(&(registers[STACK_REG])); | |
2449 *pc = program; | |
2450 *stack = (unsigned long *)(initial_stack.data + 1); | |
2451 entry.instance = NULL; | |
2452 entry.worker_num = 0; | |
2453 DEBUGPRINTF("Virtual processor, Program start: %X\n", program); | |
2454 #ifdef ENABLE_PROFILING | |
2455 for(i = 0; i < NUM_PROFS; ++i) | |
2456 { | |
2457 vis_profile_running_total[i] = 0; | |
2458 vis_profile_counts[i] = 0; | |
2459 } | |
2460 VIS_PROFILE_START(PROF_EMPTYFUNC); | |
2461 empty_test(NULL,NULL); | |
2462 VIS_PROFILE_END(PROF_EMPTYFUNC); | |
2463 VIS_PROFILE_START(PROF_NOCODE); | |
2464 VIS_PROFILE_END(PROF_NOCODE); | |
2465 #endif | |
2466 while(execute_active) | |
2467 { | |
2468 VIS_PROFILE_START(PROF_VIRTUAL_DECODE); | |
2469 DEBUGPRINTF("PC: %X\n", *pc); | |
2470 opcode = *((*pc)++); | |
2471 op1 = GET_OP1(opcode); | |
2472 op2 = GET_OP2(opcode); | |
2473 add1 = get_effective_address(op1, GET_REGNUM1(opcode), pc, registers, &immed1); | |
2474 add2 = get_effective_address(op2, GET_REGNUM2(opcode), pc, registers, &immed2); | |
2475 DEBUGPRINTF("Opcode: %X, Instruction: %X, op1 %X, op2 %X\n", opcode, GET_INST(opcode), op1, op2); | |
2476 inst = GET_INST(opcode); | |
2477 VIS_PROFILE_END(PROF_VIRTUAL_DECODE); | |
2478 VIS_PROFILE_START(PROF_VIRTUAL_EXECUTE); | |
2479 switch(inst) | |
2480 { | |
2481 case MOVE_INST: | |
2482 *add2 = *add1; | |
2483 break; | |
2484 case ADDREF_INST: | |
2485 add_ref((datum *)add1); | |
2486 break; | |
2487 case RELEASE_INST: | |
2488 release_ref((datum *)add1); | |
2489 break; | |
2490 /* | |
2491 Temporarily commented out until multiple program support is finished | |
2492 case LOAD_INST: | |
2493 *add2 = (long)get_constant((char *)add1, -1); | |
2494 break; | |
2495 */ | |
2496 case CALL_INST: | |
2497 *((*stack)++) = (unsigned long)*pc; | |
2498 *((*stack)++) = RETURN_CODE_NORMAL; | |
2499 *pc = add1; | |
2500 break; | |
2501 /* | |
2502 Temporarily commented out until multiple program support is finished | |
2503 case CALLB_INST: | |
2504 //TODO: Needs to be made 100% correct | |
2505 DEBUGPRINTF("Calling builtin: %s\n", deflist[*add1].name); | |
2506 execute_def(deflist + *add1, entry, (datum **)registers, NULL); | |
2507 break;*/ | |
2508 case CALLP_INST: | |
2509 //TODO Implement me | |
2510 break; | |
2511 case CALLBP_INST: | |
2512 //TODO Implement me | |
2513 break; | |
2514 case RETURN_INST: | |
2515 switch(*(--(*stack))) | |
2516 { | |
2517 case RETURN_CODE_EXIT: | |
2518 execute_active = FALSE; | |
2519 break; | |
2520 case RETURN_CODE_IDLE: | |
2521 //TODO: Implement me | |
2522 break; | |
2523 case RETURN_CODE_NORMAL: | |
2524 *pc = (unsigned long *)*(--(*stack)); | |
2525 break; | |
2526 default: | |
2527 break; | |
2528 } | |
2529 break; | |
2530 case BRANCH_INST: | |
2531 *pc = add1; | |
2532 break; | |
2533 case BRANCHT_INST: | |
2534 if(*add2) | |
2535 *pc = add1; | |
2536 break; | |
2537 case BRANCHF_INST: | |
2538 if(!*add2) | |
2539 *pc = add1; | |
2540 break; | |
2541 case WAIT_INST: | |
2542 //TODO: Implement Me | |
2543 break; | |
2544 case ADD_INST: | |
2545 *add2 = *add1 + *add2; | |
2546 break; | |
2547 case SUB_INST: | |
2548 *add2 = *add1 - *add2; | |
2549 break; | |
2550 case SUBR_INST: | |
2551 *add2 = *add2 - *add1; | |
2552 break; | |
2553 case GREATER_INST: | |
2554 *add2 = *add1 > *add2; | |
2555 break; | |
2556 case LESSER_INST: | |
2557 *add2 = *add1 < *add2; | |
2558 break; | |
2559 default: | |
2560 break; | |
2561 } | |
2562 VIS_PROFILE_END(PROF_VIRTUAL_EXECUTE); | |
2563 } | |
2564 #ifdef ENABLE_PROFILING | |
2565 for(i = 0; i < NUM_PROFS; ++i) | |
2566 printf("%d:\t%f,\tcount: %d,\taverage: %f\n", i, (double)vis_profile_running_total[i], vis_profile_counts[i], ((double)vis_profile_running_total[i])/((double)vis_profile_counts[i])); | |
2567 #endif | |
2568 return 0; | |
2569 } | |
2570 | |
2571 void test_virtual() | |
2572 { | |
2573 // int i,j,k; | |
2574 program * prog = new_program(START_DEF_STORAGE, START_COMP_STORAGE); | |
2575 initpredefworkers(prog); | |
2576 init_sync_primitives(); | |
2577 init_datum_storage(); | |
2578 //TODO Uncomment me | |
2579 // init_global_storage(); | |
2580 execute_active = TRUE; | |
2581 /* for(i = MOVE_INST; i <= LESSER_INST; ++i) | |
2582 { | |
2583 for(j = 0; j < 0x10; ++j) | |
2584 { | |
2585 for(k = 0; k < 0x10; ++k) | |
2586 { | |
2587 DEBUGPRINTF("i: %X, j: %X, k: %X, OPC: %X\n", i, j, k, OPC(i, j, j, k, k)); | |
2588 } | |
2589 } | |
2590 }*/ | |
2591 virtual_processor(test_program, TRUE); | |
2592 } | |
2593 | |
2594 DWORD WINAPI worker_thread(LPVOID param) | |
2595 { | |
2596 queue_entry aworker; | |
2597 int temp_queue_len; | |
2598 while(execute_active) | |
2599 { | |
2600 VIS_PROFILE_START(PROF_WORKER_THREAD); | |
2601 #ifdef NINTENDO_DS | |
2602 if(irq_queue_count > 0) | |
2603 run_queued_irqs(); | |
2604 #endif | |
2605 //DEBUGPUTS("Before WaitForSingleObect\n"); | |
2606 /*VIS_EnterCriticalSection(worker_queue_lock); | |
2607 temp_queue_len = queue_len; | |
2608 VIS_LeaveCriticalSection(worker_queue_lock);*/ | |
2609 //DEBUGPUTS("After WaitForSingleObject\n"); | |
2610 aworker = get_queue(); | |
2611 //DEBUGPUTS("After get_queue()\n"); | |
2612 //while(execute_active && aworker.worker_num < 0)//temp_queue_len == 0 && execute_active) | |
2613 //{ | |
2614 // VIS_WaitEvent(queue_add_event); | |
2615 // aworker = get_queue(); | |
2616 /*#if COMPILE_THREADS > 0 | |
2617 #ifdef WIN32 | |
2618 Sleep(0); | |
2619 #else | |
2620 sleep(0); | |
2621 #endif | |
2622 #endif | |
2623 VIS_EnterCriticalSection(worker_queue_lock); | |
2624 temp_queue_len = queue_len; | |
2625 VIS_LeaveCriticalSection(worker_queue_lock);*/ | |
2626 //} | |
2627 | |
2628 if(aworker.worker_num >= 0) | |
2629 { | |
2630 //DEBUGPUTS("Before EnterCriticalSection\n"); | |
2631 | |
2632 /* VIS_EnterCriticalSection(worker_queue_lock); | |
2633 if(queue_len > 0) | |
2634 { | |
2635 DEBUGPUTS("SetEvent\n"); | |
2636 VIS_SetEvent(queue_add_event); | |
2637 } | |
2638 VIS_LeaveCriticalSection(worker_queue_lock);*/ | |
2639 DEBUGPRINTF( "\nExecuting: %s<%d>, Instance: %X\n", aworker.instance->def->implement_func->workerlist[aworker.worker_num].name,aworker.worker_num,aworker.instance); | |
2640 | |
2641 if(process_worker(aworker) == 0) | |
2642 { | |
2643 //worker_complete(aworker); | |
2644 cleanup_check(aworker); | |
2645 //DEBUGPUTS("After cleanup_check\n"); | |
2646 | |
2647 } | |
2648 | |
2649 } | |
2650 VIS_PROFILE_END(PROF_WORKER_THREAD); | |
2651 } | |
2652 VIS_SetEvent(queue_add_event); | |
2653 return 0; | |
2654 } | |
2655 | |
2656 int set_comp_room(datum ** params, int room_index, queue_entry * entry, program * prog) | |
2657 { | |
2658 int i; | |
2659 char * data; | |
2660 //DEBUGPRINTF("params[0]->ref_count: %d\n", params[0]->ref_count); | |
2661 params[0] = copy_datum(params[0], 0); | |
2662 data = ((char *)(params[0]->c.generic.data) + (int)params[0]->company->room_list[room_index].set_func); | |
2663 DEBUGPRINTF("Set comp room: c.generic.data = %X, +get_func = %X\n", params[0]->c.generic.data, data); | |
2664 //TODO: input conversion | |
2665 switch(params[0]->company->room_list[room_index].get_func_type) | |
2666 { | |
2667 case ROOM_BYTE: | |
2668 *data = params[1]->c.integers.num_a; | |
2669 release_ref(params[1]); | |
2670 break; | |
2671 case ROOM_SHORT: | |
2672 *((short *)data) = params[1]->c.integers.num_a; | |
2673 release_ref(params[1]); | |
2674 break; | |
2675 case ROOM_LONG: | |
2676 *((long *)data) = params[1]->c.integers.num_a; | |
2677 release_ref(params[1]); | |
2678 break; | |
2679 case ROOM_SINGLE: | |
2680 *((float *)data) = params[1]->c.real; | |
2681 release_ref(params[1]); | |
2682 break; | |
2683 case ROOM_DOUBLE: | |
2684 *((double *)data) = params[1]->c.real; | |
2685 release_ref(params[1]); | |
2686 break; | |
2687 case ROOM_VIS_REF: | |
2688 release_ref(*((datum **)data)); | |
2689 *((datum **)data) = params[1]; | |
2690 break; | |
2691 case ROOM_CSTRING: //not implemented | |
2692 case ROOM_CSTRING_STRUCT: | |
2693 case ROOM_PSTRING: | |
2694 case ROOM_PSTRING_STRUCT: | |
2695 case ROOM_WORKER://not implemented | |
2696 case ROOM_VIS_OBJECT://not implemented | |
2697 default: | |
2698 release_ref(params[0]); | |
2699 release_ref(params[1]); | |
2700 params[0] = params[1] = NULL; | |
2701 puts("unimplemented company room type\n"); | |
2702 break; | |
2703 } | |
2704 return 0; | |
2705 } | |
2706 | |
2707 int set_comp_room_by_name(datum ** company, char * name, int * room_index_ret, queue_entry * entry, program * prog) | |
2708 { | |
2709 int i; | |
2710 for (i = 0; i < company[0]->company->num_rooms; ++i) | |
2711 if(!strcmp(name,company[0]->company->room_list[i].name)) | |
2712 { | |
2713 if(room_index_ret) | |
2714 *room_index_ret = i; | |
2715 return set_comp_room(company, i, entry, prog); | |
2716 } | |
2717 if(room_index_ret) | |
2718 *room_index_ret = -1; | |
30
914ad38f9b59
Compiler now works for some simple programs
Mike Pavone <pavone@retrodev.com>
parents:
29
diff
changeset
|
2719 printf("Error: Can't set field %s on object with blueprint %s\n", name, company[0]->company); |
0 | 2720 return -1; |
2721 } | |
2722 | |
2723 int get_comp_room(datum ** company, int room_index, queue_entry * entry, program * prog) | |
2724 { | |
2725 int i; | |
2726 datum * out; | |
2727 queue_entry empty; | |
2728 char * data = ((char *)(company[0]->c.generic.data) + (int)company[0]->company->room_list[room_index].get_func); | |
2729 company[1] = NULL; | |
2730 DEBUGPRINTF("Get comp room: c.generic.data = %X, +get_func = %X\n", company[0]->c.generic.data, data); | |
2731 switch(company[0]->company->room_list[room_index].get_func_type) | |
2732 { | |
2733 case ROOM_BYTE: | |
2734 out = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, prog); | |
2735 out->c.integers.num_a = *data; | |
2736 break; | |
2737 case ROOM_SHORT: | |
2738 out = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, prog); | |
2739 out->c.integers.num_a = *((short *)data); | |
2740 break; | |
2741 case ROOM_LONG: | |
2742 out = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, prog); | |
2743 out->c.integers.num_a = *((long *)data); | |
2744 break; | |
2745 case ROOM_SINGLE: | |
2746 out = new_datum(BUILTIN_TYPE_REAL, 3, 0, prog); | |
2747 out->c.real = *((float *)data); | |
2748 break; | |
2749 case ROOM_DOUBLE: | |
2750 out = new_datum(BUILTIN_TYPE_REAL, 3, 0, prog); | |
2751 out->c.real = *((double *)data); | |
2752 break; | |
2753 case ROOM_CSTRING: | |
2754 data = *((char **)data); | |
2755 case ROOM_CSTRING_STRUCT: | |
2756 out = new_datum(BUILTIN_TYPE_STRING, 1, strlen(data)+1, prog); | |
2757 strcpy(out->c.generic.data, data); | |
2758 break; | |
2759 case ROOM_PSTRING: | |
2760 data = *((char **)data); | |
2761 case ROOM_PSTRING_STRUCT: | |
2762 out = new_datum(BUILTIN_TYPE_STRING, 1, *((unsigned char *)data), prog); | |
2763 memcpy(out->c.generic.data, data, *((unsigned char *)data)); | |
2764 ((char *)out->c.generic.data)[*((unsigned char *)data)] = '\0'; | |
2765 break; | |
2766 case ROOM_VIS_REF: | |
2767 out = add_ref(*((datum **)data)); | |
2768 if(!out) { | |
2769 company[1] = company[0]; | |
2770 company[0] = NULL; | |
2771 } | |
2772 break; | |
2773 case ROOM_WORKER: | |
2774 if(entry) | |
2775 return execute_def((worker_def *)(company[0]->company->room_list[room_index].get_func), *entry, company, sub_callback); | |
2776 else | |
2777 { | |
2778 empty.instance = NULL; | |
2779 empty.worker_num = -1; | |
2780 return execute_def((worker_def *)(company[0]->company->room_list[room_index].get_func), empty, company, sub_callback); | |
2781 } | |
2782 case ROOM_VIS_OBJECT://not implemented | |
2783 default: | |
2784 out = NULL; | |
2785 puts("unimplemented company room type\n"); | |
2786 break; | |
2787 } | |
2788 release_ref(company[0]); | |
2789 company[0] = out; | |
2790 return 0; | |
2791 } | |
2792 | |
2793 int get_comp_room_by_name(datum ** company, char * name, int * room_index_ret, queue_entry * entry, program * prog) | |
2794 { | |
2795 int i; | |
2796 for (i = 0; i < company[0]->company->num_rooms; ++i) | |
2797 if(!strcmp(name,company[0]->company->room_list[i].name)) | |
2798 { | |
2799 if(room_index_ret) | |
2800 *room_index_ret = i; | |
2801 return get_comp_room(company, i, entry, prog); | |
2802 } | |
2803 if(room_index_ret) | |
2804 *room_index_ret = -1; | |
30
914ad38f9b59
Compiler now works for some simple programs
Mike Pavone <pavone@retrodev.com>
parents:
29
diff
changeset
|
2805 printf("Error: Can't get field %s from object with blueprint %s\n", name, company[0]->company); |
914ad38f9b59
Compiler now works for some simple programs
Mike Pavone <pavone@retrodev.com>
parents:
29
diff
changeset
|
2806 print_stack_trace(entry->instance); |
0 | 2807 return -1; |
2808 } | |
2809 | |
2810 datum * literal_string(char * value, int len, program * prog) | |
2811 { | |
2812 char literalchar; | |
2813 BOOL literal; | |
2814 int i, bufpos, lenstr; | |
2815 datum * returnval; | |
2816 | |
2817 if(len < 0) { | |
2818 len = strlen(value); | |
2819 } | |
2820 | |
2821 literal = FALSE; | |
2822 lenstr = 0; | |
2823 for(i = 0; i < len; ++i) | |
2824 if(literal) | |
2825 literal = FALSE; | |
2826 else | |
2827 { | |
2828 ++lenstr; | |
2829 if(value[i] == '\\') | |
2830 literal = TRUE; | |
2831 } | |
2832 //DEBUGPRINTF("Allocating %d bytes for string constant\n", lenstr+1); | |
2833 returnval = new_datum(BUILTIN_TYPE_STRING, 1, lenstr+1, prog); | |
2834 bufpos = 0; | |
2835 for(i = 0; i < len; ++i) | |
2836 { | |
2837 if(literal) | |
2838 { | |
2839 literal = FALSE; | |
2840 switch(value[i]) | |
2841 { | |
2842 case 'n': //newline | |
2843 literalchar = '\n'; | |
2844 break; | |
2845 case 'r': //carriage return | |
2846 literalchar = '\r'; | |
2847 break; | |
2848 case 't': // tab | |
2849 literalchar = '\t'; | |
2850 break; | |
2851 case '0': //NULL | |
2852 literalchar = '\0'; | |
2853 break; | |
2854 default: | |
2855 literalchar = value[i]; | |
2856 break; | |
2857 } | |
2858 ((char *)returnval->c.generic.data)[bufpos++] = literalchar; | |
2859 } | |
2860 else | |
2861 { | |
2862 if(value[i] == '\\') | |
2863 literal = TRUE; | |
2864 else | |
2865 { | |
2866 ((char *)returnval->c.generic.data)[bufpos++] = value[i]; | |
2867 } | |
2868 } | |
2869 } | |
2870 //DEBUGPRINTF("bufpos: %d\n", bufpos); | |
2871 ((char *)returnval->c.generic.data)[bufpos] = '\0'; | |
2872 DEBUGPUTS("Constant Type: String\n"); | |
2873 return returnval; | |
2874 } | |
2875 | |
2876 datum * get_constant(char * value, int len, program * prog) | |
2877 { | |
2878 datum * params[2]; | |
2879 datum * returnval; | |
2880 int i = 0,bufpos; | |
2881 int start; | |
2882 int lenstr; | |
2883 int leftcurly; | |
2884 int dotcount = 0; | |
2885 char literalchar; | |
2886 unsigned short const_type = ANY_TYPE; | |
2887 BOOL literal; | |
2888 if((len == 3 && memcmp(value, "Yes", len) == 0) || (len < 0 && strcmp(value, "Yes") == 0)) | |
2889 { | |
2890 DEBUGPUTS("Constnat: Yes\n"); | |
2891 returnval = new_datum(BUILTIN_TYPE_YESNO, 2, 0, prog); | |
2892 returnval->c.integers.num_a = 1; | |
2893 DEBUGPRINTF("Company: %s, integers.num_a: %d\n", returnval->company->name, returnval->c.integers.num_a); | |
2894 return returnval; | |
2895 } | |
2896 else if((len == 2 && memcmp(value, "No", len) == 0) || (len < 0 && strcmp(value, "No") == 0)) | |
2897 { | |
2898 DEBUGPUTS("Constant: No\n"); | |
2899 returnval = new_datum(BUILTIN_TYPE_YESNO, 2, 0, prog); | |
2900 returnval->c.integers.num_a = 0; | |
2901 DEBUGPRINTF("Company: %s, integers.num_a: %d\n", returnval->company->name, returnval->c.integers.num_a); | |
2902 return returnval; | |
2903 } | |
2904 if(value[0] == '{') | |
2905 { | |
2906 DEBUGPUTS("Constant type: List"); | |
2907 params[0] = create_list(prog); | |
2908 i = start = 1; | |
2909 literal = FALSE; | |
2910 leftcurly = 0; | |
2911 for(;value[i] != 0 && (len < 0 || i < len); ++i) | |
2912 { | |
2913 if(literal) | |
2914 literal = FALSE; | |
2915 else | |
2916 { | |
2917 if(value[i] == '\\') | |
2918 literal = TRUE; | |
2919 else if(value[i] == '}') | |
2920 if(leftcurly) | |
2921 --leftcurly; | |
2922 else | |
2923 break; | |
2924 else if(value[i] == '{') | |
2925 ++leftcurly; | |
2926 else if(value[i] == ',' && !leftcurly) | |
2927 { | |
2928 params[1] = get_constant(value+start, i-start, prog); | |
2929 vis_list_append(params, NULL); | |
2930 start = i+1; | |
2931 } | |
2932 } | |
2933 } | |
2934 params[1]= get_constant(value+start, i-start, prog); | |
2935 vis_list_append(params, NULL); | |
2936 returnval = params[0]; | |
2937 } | |
2938 else if(value[0] == '"') | |
2939 { | |
2940 if(len < 0) { | |
2941 len = strlen(value); | |
2942 } | |
2943 len -= 2; | |
2944 returnval = literal_string(value+1, len, prog); | |
2945 | |
2946 } | |
2947 else | |
2948 { | |
2949 while(value[i] != 0 && (len < 0 || i < len)) | |
2950 { | |
2951 if(value[i] >= '0' && value[i] <= '9') | |
2952 { | |
2953 if(const_type == ANY_TYPE) | |
2954 const_type = BUILTIN_TYPE_WHOLE; | |
2955 } | |
2956 else if(value[i] == '.') | |
2957 { | |
2958 if(dotcount) | |
2959 { | |
2960 const_type = BUILTIN_TYPE_STRING; | |
2961 } | |
2962 else | |
2963 { | |
2964 ++dotcount; | |
2965 if(const_type == BUILTIN_TYPE_WHOLE) | |
2966 const_type = BUILTIN_TYPE_REAL; | |
2967 } | |
2968 } | |
2969 else | |
2970 { | |
2971 //DEBUGPRINTF("Current character: %c resulted in String\n", value[i]); | |
2972 const_type = BUILTIN_TYPE_STRING; | |
2973 break; | |
2974 } | |
2975 ++i; | |
2976 } | |
2977 | |
2978 if(const_type == BUILTIN_TYPE_WHOLE) | |
2979 { | |
2980 returnval = new_datum(const_type, 2, 0, prog); | |
2981 returnval->c.integers.num_a = atol(value); | |
2982 DEBUGPUTS("Constant Type: Whole Number\n"); | |
2983 } | |
2984 else if(const_type == BUILTIN_TYPE_REAL) | |
2985 { | |
2986 returnval = new_datum(const_type, 3, 0, prog); | |
2987 returnval->c.real = atof(value); | |
2988 DEBUGPUTS("Constant Type: Real Number\n"); | |
2989 } | |
2990 else | |
2991 { | |
2992 /* literal = FALSE; | |
2993 lenstr = 0; | |
2994 for(i = 0; (i < len || len < 0) && value[i] != 0; ++i) | |
2995 if(literal) | |
2996 literal = FALSE; | |
2997 else | |
2998 { | |
2999 ++lenstr; | |
3000 if(value[i] == '\\') | |
3001 literal = TRUE; | |
3002 } | |
3003 DEBUGPRINTF("Allocating %d bytes for string constant\n", lenstr+1); | |
3004 returnval = new_datum(BUILTIN_TYPE_STRING, 1, lenstr+1, prog); | |
3005 bufpos = 0; | |
3006 for(i = 0; (i < len || len < 0) && value[i] != 0; ++i) | |
3007 { | |
3008 DEBUGPRINTF("bufpos: %d\n", bufpos); | |
3009 if(literal) | |
3010 { | |
3011 literal = FALSE; | |
3012 switch(value[i]) | |
3013 { | |
3014 case 'n': //newline | |
3015 literalchar = '\n'; | |
3016 break; | |
3017 case 'r': //carriage return | |
3018 literalchar = '\r'; | |
3019 break; | |
3020 case 't': // tab | |
3021 literalchar = '\t'; | |
3022 break; | |
3023 case '0': //NULL | |
3024 literalchar = '\0'; | |
3025 break; | |
3026 default: | |
3027 literalchar = value[i]; | |
3028 break; | |
3029 } | |
3030 ((char *)returnval->c.generic.data)[bufpos++] = literalchar; | |
3031 } | |
3032 else | |
3033 { | |
3034 if(value[i] == '\\') | |
3035 literal = TRUE; | |
3036 else | |
3037 { | |
3038 ((char *)returnval->c.generic.data)[bufpos++] = value[i]; | |
3039 } | |
3040 } | |
3041 } | |
3042 DEBUGPRINTF("bufpos: %d\n", bufpos); | |
3043 ((char *)returnval->c.generic.data)[bufpos] = '\0'; | |
3044 DEBUGPUTS("Constant Type: String\n"); */ | |
3045 returnval = literal_string(value, len, prog); | |
3046 } | |
3047 } | |
3048 return returnval; | |
3049 } | |
3050 | |
3051 int execute_def(worker_def * process_def, queue_entry worker_entry, datum ** params, instance_callback callback) | |
3052 { | |
3053 return execute_def_type(process_def, worker_entry, params, callback, NULL, WORKER); | |
3054 } | |
3055 int execute_def_data(worker_def * process_def, queue_entry worker_entry, datum ** params, instance_callback callback, void * data) | |
3056 { | |
3057 return execute_def_type(process_def, worker_entry, params, callback, data, WORKER); | |
3058 } | |
3059 | |
3060 int execute_def_type(worker_def * process_def, queue_entry worker_entry, datum ** params, instance_callback callback, void * data, int type) | |
3061 { | |
3062 int returnval, i; | |
3063 worker_instance * stack_instance; | |
3064 worker_def *temp_def, *converter; | |
3065 worker_def *parent_def = worker_entry.instance->def; | |
3066 unsigned short magic_cache_type; | |
3067 #ifdef USER_PROFILE | |
3068 LARGE_INTEGER start, end, duration; | |
3069 #endif | |
3070 VIS_PROFILE_START(PROF_PREP_MAGIC); | |
3071 if((process_def->type & TYPE_MASK) == MAGIC_TYPE) | |
3072 { | |
3073 DEBUGPRINTF( "Magic method: %s\n", process_def->name); | |
3074 if(!params || !params[0]) | |
3075 { | |
47
6202b866d72c
Cleaned up constructor names and merged some other changes in to support the Rhope website
Mike Pavone <pavone@retrodev.com>
parents:
46
diff
changeset
|
3076 ERRORPRINTF("Error: null first parmeter or null parameter array for worker %s, params: %X, params[0]: %X\n", process_def->name, params, params[0]); |
0 | 3077 print_stack_trace(worker_entry.instance); |
3078 execute_active = FALSE; | |
3079 return -1; | |
3080 } | |
3081 VIS_EnterCriticalSection(parent_def->implement_func->workerlist[worker_entry.worker_num].lock); | |
3082 temp_def = parent_def->implement_func->workerlist[worker_entry.worker_num].magic_cache_implement; | |
3083 magic_cache_type = parent_def->implement_func->workerlist[worker_entry.worker_num].magic_cache_type; | |
3084 VIS_LeaveCriticalSection(parent_def->implement_func->workerlist[worker_entry.worker_num].lock); | |
3085 if(!temp_def || magic_cache_type != params[0]->company->type_id) | |
3086 { | |
3087 DEBUGPRINTF("Finding method %s with %d inputs for type %s(%d)\n", process_def->name, process_def->num_inputs, params[0]->company->name, params[0]->company->type_id); | |
3088 temp_def = find_method(params[0]->company->type_id,process_def->name, process_def->num_inputs, process_def->program); | |
3089 if(!temp_def) | |
3090 { | |
3091 for(i = 1; i < process_def->program->num_companies; ++i) | |
3092 { | |
3093 temp_def = find_method(i,process_def->name, process_def->num_inputs, process_def->program); | |
3094 if(temp_def) | |
3095 { | |
3096 converter = find_converter_method(temp_def->input_types[0], params[0]->company->type_id, process_def->program); | |
3097 if(converter) | |
3098 { | |
3099 ((worker_impl)converter->implement_func)(params, &worker_entry); | |
3100 break; | |
3101 } | |
3102 else | |
3103 { | |
3104 //DEBUGPRINTF("Error: Needed conversion from %s to %s for input %d of %s\n", params[0]->company->name, process_def->program->companylist[temp_def->input_types[0]].name, 0, temp_def->name); | |
3105 //printf("Warning: Needed conversion from %s to %s for input %d of %s for loose method call\n", params[0]->company->name, process_def->program->companylist[temp_def->input_types[0]].name, 0, temp_def->name); | |
3106 temp_def = NULL; | |
3107 } | |
3108 } | |
3109 } | |
3110 } | |
3111 if(temp_def) | |
3112 { | |
3113 VIS_EnterCriticalSection(parent_def->implement_func->workerlist[worker_entry.worker_num].lock); | |
3114 parent_def->implement_func->workerlist[worker_entry.worker_num].magic_cache_implement = temp_def; | |
3115 parent_def->implement_func->workerlist[worker_entry.worker_num].magic_cache_type = temp_def->input_types[0]; | |
3116 VIS_LeaveCriticalSection(parent_def->implement_func->workerlist[worker_entry.worker_num].lock); | |
3117 } | |
3118 else | |
3119 { | |
3120 ERRORPRINTF("Error: Company %s doesn't implement worker %s. It implements the following:\n", params[0]->company->name, process_def->name); | |
3121 for(i = 0; i < params[0]->company->num_methods; ++i) | |
3122 { | |
3123 ERRORPRINTF("%s\n", params[0]->company->methodlist[i]->name); | |
3124 } | |
3125 print_stack_trace(worker_entry.instance); | |
3126 } | |
3127 } | |
3128 process_def = temp_def; | |
3129 } | |
3130 VIS_PROFILE_END(PROF_PREP_MAGIC); | |
3131 if(!process_def) | |
3132 { | |
3133 //DEBUGPUTS("Invalid def\n"); | |
3134 VIS_PROFILE_END(PROF_EXECUTE_WORKER); | |
3135 execute_active = FALSE; | |
3136 return -2; | |
3137 } | |
3138 | |
3139 VIS_PROFILE_START(PROF_CONVERT_INPUTS); | |
3140 for(i = 0; i < process_def->num_inputs; ++i) | |
3141 { | |
3142 DEBUGPRINTF("params[%d] = %X\n", i, params[i]); | |
3143 if(process_def->input_types[i] != ANY_TYPE && process_def->input_types[i] != params[i]->company->type_id) | |
3144 { | |
3145 DEBUGPRINTF("Input %d needs conversion from %d to %d\n", i, params[i]->company->type_id, process_def->input_types[i]); | |
3146 converter = find_converter_method(process_def->input_types[i], params[i]->company->type_id, process_def->program); | |
3147 if(!converter) | |
3148 { | |
3149 if(worker_entry.instance) { | |
3150 ERRORPRINTF("Error: Needed conversion from %s to %s for input %d of %s in worker %s\n", params[i]->company->name, process_def->program->companylist[process_def->input_types[i]].name, i, process_def->name, worker_entry.instance->def->name); | |
13 | 3151 print_stack_trace(worker_entry.instance); |
0 | 3152 } else { |
3153 DEBUGPRINTF("Error: Needed conversion from %s to %s for input %d of %s\n", params[i]->company->name, process_def->program->companylist[process_def->input_types[i]].name, i, process_def->name); | |
3154 printf("Error: Needed conversion from %s to %s for input %d of %s", params[i]->company->name, process_def->program->companylist[process_def->input_types[i]].name, i, process_def->name); | |
3155 } | |
3156 execute_active = FALSE; | |
3157 VIS_PROFILE_END(PROF_PROCESS_WORKER); | |
3158 return -3; | |
3159 } | |
3160 ((worker_impl)(converter->implement_func))(params+i, &worker_entry); | |
3161 } | |
3162 } | |
3163 VIS_PROFILE_END(PROF_CONVERT_INPUTS); | |
3164 | |
3165 if(process_def->type & USER_FLAG) | |
3166 { | |
3167 VIS_PROFILE_START(PROF_EXECUTE_CUSTOM); | |
3168 // | |
3169 init_custom_worker_type(worker_entry.worker_num, worker_entry.instance, process_def, callback, data, params, type); | |
3170 VIS_PROFILE_END(PROF_EXECUTE_CUSTOM); | |
3171 VIS_PROFILE_END(PROF_PROCESS_WORKER); | |
3172 VIS_PROFILE_END(PROF_EXECUTE_WORKER); | |
3173 return 1; | |
3174 } | |
3175 else | |
3176 { | |
3177 VIS_PROFILE_START(PROF_EXECUTE_BUILTIN); | |
3178 //DEBUGPRINTF("%s: before deflist[%d].implement_func: %X. vis_append: %X vis_print: %X\n",def->implement_func->workerlist[aworker].name, def->implement_func->workerlist[aworker].value_index, (int)deflist[def->implement_func->workerlist[aworker].value_index].implement_func, (int)vis_append, (int)vis_print); | |
3179 #ifdef USER_PROFILE | |
3180 QueryPerformanceCounter(&start); | |
3181 #endif | |
3182 returnval = ((worker_impl)(process_def->implement_func))(params, &worker_entry); | |
3183 #ifdef USER_PROFILE | |
3184 if(!returnval) | |
3185 { | |
3186 QueryPerformanceCounter(&end); | |
3187 duration.QuadPart = end.QuadPart - start.QuadPart; | |
3188 VIS_EnterCriticalSection(process_def->lock); | |
3189 process_def->total.QuadPart += duration.QuadPart; | |
3190 ++process_def->count; | |
3191 if(duration.QuadPart > process_def->worst.QuadPart) | |
3192 process_def->worst.QuadPart = duration.QuadPart; | |
3193 VIS_LeaveCriticalSection(process_def->lock); | |
3194 } | |
3195 #endif | |
3196 //DEBUGPUTS("Builtin worker returned\n"); | |
3197 VIS_PROFILE_END(PROF_EXECUTE_BUILTIN); | |
3198 return returnval; | |
3199 } | |
3200 } | |
3201 | |
3202 void wait_callback(worker_instance * caller_instance, int caller_workerenum, worker_instance * done_instance, void * data) | |
3203 { | |
3204 int i; | |
3205 def_done * done = (def_done *)data; | |
3206 //DEBUGPUTS("begin wait_callback\n"); | |
3207 for(i = 0; i < done_instance->def->num_outputs; ++i) | |
3208 done->params[i] = NULL; | |
3209 for(i = 0; i < done_instance->def->implement_func->num_workers; ++i) | |
3210 { | |
3211 if(done_instance->def->implement_func->workerlist[i].type == 4) | |
3212 { | |
3213 if(!(done->params[done_instance->def->implement_func->workerlist[i].io_num])) | |
3214 { | |
3215 done->params[done_instance->def->implement_func->workerlist[i].io_num] = done_instance->workerlist[i].value; | |
3216 done_instance->workerlist[i].value = NULL; | |
3217 } | |
3218 } | |
3219 } | |
3220 //DEBUGPUTS("Before EnterCritical\n"); | |
3221 VIS_EnterCriticalSection(done->lock); | |
3222 done->done_flag = TRUE; | |
3223 VIS_LeaveCriticalSection(done->lock); | |
3224 //DEBUGPUTS("After EnterCritical\n"); | |
3225 } | |
3226 | |
3227 | |
3228 BOOL execute_def_wait(worker_def * def, datum ** params) | |
3229 { | |
3230 int val; | |
3231 def_done done; | |
3232 queue_entry entry; | |
3233 entry.worker_num = 0; | |
3234 entry.instance = NULL; | |
3235 VIS_InitializeCriticalSection(done.lock); | |
3236 done.done_flag = FALSE; | |
3237 done.params = params; | |
3238 val = execute_def_data(def, entry, params, wait_callback, &done); | |
3239 if(val == 0) | |
3240 return TRUE; | |
3241 else if (val < 0) | |
3242 return FALSE; | |
3243 while(1) | |
3244 { | |
3245 VIS_EnterCriticalSection(done.lock); | |
3246 if(done.done_flag) | |
3247 { | |
3248 VIS_DeleteCriticalSection(done.lock); | |
3249 break; | |
3250 } | |
3251 VIS_LeaveCriticalSection(done.lock); | |
3252 #if COMPILE_THREADS > 1 | |
3253 #ifdef WIN32 | |
3254 Sleep(0); | |
3255 #else | |
3256 sleep(0); | |
3257 #endif | |
3258 #endif | |
3259 } | |
3260 return TRUE; | |
3261 } | |
3262 | |
3263 int process_worker(queue_entry worker_entry) | |
3264 { | |
3265 //datum * paramstore[32]; | |
3266 datum ** params;// = paramstore; | |
3267 int i, j, start=0; | |
3268 global_store * store; | |
3269 char * varname; | |
3270 datum * varname_dat; | |
3271 datum * tempvalindex, *todelete; | |
3272 int got_params=0; | |
3273 int aworker = worker_entry.worker_num; | |
3274 worker_instance * instance = worker_entry.instance; | |
3275 worker_def * def = instance->def; | |
3276 worker_def * process_def; | |
3277 worker_def * temp_def; | |
3278 worker_def * converter; | |
3279 int returnval = 0; | |
3280 short const_type; | |
3281 char * last; | |
3282 | |
3283 VIS_PROFILE_START(PROF_PROCESS_WORKER); | |
3284 | |
3285 DEBUGPRINTF( "Processing worker %d with %d inputs and %d outputs\n", aworker,def->implement_func->workerlist[aworker].num_inputs, def->implement_func->workerlist[aworker].num_outputs); | |
3286 /*VIS_EnterCriticalSection(instance->workerlist[aworker].worker_lock); | |
3287 for(i = 0; i < def->implement_func->workerlist[aworker].num_inputs; ++i) | |
3288 { | |
3289 params[i] = instance->workerlist[aworker].params[i+1]; | |
3290 DEBUGPRINTF("params[%d] = %X\n", i, params[i]); | |
3291 instance->workerlist[aworker].params[i+1] = NULL; | |
3292 }*/ | |
3293 if(def->implement_func->workerlist[aworker].null_input) | |
3294 { | |
3295 //DEBUGPUTS("About to call release_ref\n"); | |
3296 release_ref(instance->workerlist[aworker].params[0]); | |
3297 instance->workerlist[aworker].params[0] = NULL; | |
3298 } | |
3299 //VIS_LeaveCriticalSection(instance->workerlist[aworker].worker_lock); | |
3300 //DEBUGPRINTF("Param check complete. returnval: %d, start: %d\n", returnval, start); | |
3301 params = instance->workerlist[aworker].params+1; | |
3302 | |
3303 if(def->implement_func->workerlist[aworker].type == WORKER || def->implement_func->workerlist[aworker].type == TAIL_RECURSE || def->implement_func->workerlist[aworker].type == TAIL_CALL)//Worker | |
3304 { | |
3305 VIS_PROFILE_START(PROF_EXECUTE_WORKER); | |
3306 //DEBUGPUTS("Worker\n"); | |
3307 process_def = (worker_def *)(def->implement_func->workerlist[aworker].value_index); | |
3308 //DEBUGPUTS("Got process_def\n"); | |
3309 DEBUGPRINTF("process_def->type: %X, type & TYPE_MASK: %X\n", process_def->type, (process_def->type & TYPE_MASK)); | |
3310 | |
3311 returnval = execute_def_type(process_def, worker_entry, params, sub_callback, NULL, def->implement_func->workerlist[aworker].type); | |
3312 DEBUGPRINTF("execute_def returned %d\n", returnval); | |
3313 if(returnval != 0) | |
3314 { | |
3315 VIS_PROFILE_END(PROF_PROCESS_WORKER); | |
3316 VIS_PROFILE_END(PROF_EXECUTE_WORKER); | |
3317 return returnval; | |
3318 } | |
3319 //DEBUGPRINTF("params[0] after execute_def: %X\n", params[0]); | |
3320 | |
3321 //DEBUGPUTS("Before process_outputs\n"); | |
3322 | |
3323 process_outputs(params, aworker, instance); | |
3324 //DEBUGPUTS("After process_outputs\n"); | |
3325 | |
3326 VIS_PROFILE_END(PROF_EXECUTE_WORKER); | |
3327 | |
3328 } | |
3329 else if(def->implement_func->workerlist[aworker].type == GET_GLOBAL) | |
3330 { | |
3331 varname = def->implement_func->workerlist[aworker].name + def->implement_func->workerlist[aworker].io_num; | |
3332 varname_dat = make_string(varname, -1, def->program); | |
3333 if(def->implement_func->workerlist[aworker].value_index < 0) | |
3334 { | |
3335 for(i = 0; i < instance->trans->num_stores; ++i) | |
3336 { | |
3337 VIS_EnterCriticalSection(instance->trans->stores[i].lock); | |
3338 params[0] = add_ref(instance->trans->stores[i].instance_data); | |
3339 VIS_LeaveCriticalSection(instance->trans->stores[i].lock); | |
3340 params[1] = add_ref(varname_dat); | |
3341 vis_dict_index(params, NULL); | |
3342 | |
3343 if(params[0]) | |
3344 { | |
3345 def->implement_func->workerlist[aworker].value_index = i; | |
3346 break; | |
3347 } | |
3348 } | |
3349 if(def->implement_func->workerlist[aworker].value_index < 0) | |
3350 { | |
3351 printf("Error: Variable %s not found in any global stores used by worker %s\n", varname, def->name); | |
3352 DEBUGPRINTF("Error: Variable %s not found in any global stores used by worker %s\n", varname, def->name); | |
3353 execute_active = FALSE; | |
3354 return -1; | |
3355 } | |
3356 } | |
3357 else | |
3358 { | |
3359 VIS_EnterCriticalSection(instance->trans->stores[(int)def->implement_func->workerlist[aworker].value_index].lock); | |
3360 params[0] = add_ref(instance->trans->stores[(int)def->implement_func->workerlist[aworker].value_index].instance_data); | |
3361 VIS_LeaveCriticalSection(instance->trans->stores[(int)def->implement_func->workerlist[aworker].value_index].lock); | |
3362 params[1] = varname_dat; | |
3363 vis_dict_index(params, NULL); | |
3364 if(!params[0]) | |
3365 { | |
3366 printf("Error: Global variable %s not found in worker %s\n", def->implement_func->workerlist[aworker].name, def->name); | |
3367 DEBUGPRINTF("Error: Global variable %s not found in worker %s\n", def->implement_func->workerlist[aworker].name, def->name); | |
3368 execute_active = FALSE; | |
3369 return -1; | |
3370 } | |
3371 } | |
3372 process_outputs(params, aworker, instance); | |
3373 | |
3374 | |
3375 } | |
3376 else if(def->implement_func->workerlist[aworker].type == SET_GLOBAL) | |
3377 { | |
3378 varname = def->implement_func->workerlist[aworker].name + def->implement_func->workerlist[aworker].io_num; | |
3379 varname_dat = make_string(varname, -1, def->program); | |
3380 params[2] = params[0]; | |
3381 params[1] = varname_dat; | |
3382 VIS_EnterCriticalSection(instance->trans->stores[(int)def->implement_func->workerlist[aworker].value_index].lock); | |
3383 //no add_ref here because we'll be replacing instance_data with the result of vis_dict set | |
3384 params[0] = instance->trans->stores[(int)def->implement_func->workerlist[aworker].value_index].instance_data; | |
3385 vis_dict_set(params, NULL); | |
3386 instance->trans->stores[(int)def->implement_func->workerlist[aworker].value_index].instance_data = params[0]; | |
3387 VIS_LeaveCriticalSection(instance->trans->stores[(int)def->implement_func->workerlist[aworker].value_index].lock); | |
3388 //no outputs to process | |
3389 } | |
3390 else if(def->implement_func->workerlist[aworker].type == GET_COMP) | |
3391 { | |
3392 returnval = get_comp_room_by_name(params, def->implement_func->workerlist[aworker].name, NULL, &worker_entry, def->program); | |
3393 if(returnval) | |
3394 return returnval; | |
3395 process_outputs(params, aworker, instance); | |
3396 } | |
3397 else if(def->implement_func->workerlist[aworker].type == SET_COMP) | |
3398 { | |
3399 returnval = set_comp_room_by_name(params, def->implement_func->workerlist[aworker].name, NULL, &worker_entry, def->program); | |
3400 if(returnval) | |
3401 return returnval; | |
3402 process_outputs(params, aworker, instance); | |
3403 } | |
3404 else//Variable | |
3405 { | |
3406 VIS_PROFILE_START(PROF_EXECUTE_OTHER); | |
3407 if(def->implement_func->workerlist[aworker].num_inputs > 0 || def->implement_func->workerlist[aworker].type == INPUT) //Is this a Room or a constant? | |
3408 { | |
3409 todelete = NULL; | |
3410 VIS_EnterCriticalSection(instance->workerlist[aworker].worker_lock); | |
3411 if(def->implement_func->workerlist[aworker].type == OUTPUT) | |
3412 { | |
3413 todelete = instance->workerlist[aworker].value; | |
3414 instance->workerlist[aworker].value = params[0]; | |
3415 DEBUGPRINTF("Setting room/output at pos %d to %X in instance %X\n", aworker, params[0], instance); | |
3416 } | |
3417 //tempvalindex = instance->workerlist[aworker].value; | |
3418 VIS_LeaveCriticalSection(instance->workerlist[aworker].worker_lock); | |
3419 if(def->implement_func->workerlist[aworker].type == INPUT) | |
3420 { | |
3421 params[0] = instance->workerlist[aworker].value; | |
3422 instance->workerlist[aworker].value = NULL; | |
3423 } | |
3424 if(todelete) | |
3425 release_ref(todelete); | |
3426 if(def->implement_func->workerlist[aworker].num_outputs) | |
3427 { | |
3428 //add_ref(tempvalindex); | |
3429 process_outputs(params/*&tempvalindex*/, aworker, instance); | |
3430 } | |
3431 | |
3432 } | |
3433 else | |
3434 { | |
3435 //Hmm, do I potentially need another lock here? | |
3436 /*if(!(instance->def->implement_func->workerlist[aworker].value_index)) | |
3437 { | |
3438 instance->def->implement_func->workerlist[aworker].value_index = (int)(tempvalindex=get_constant(def->implement_func->workerlist[aworker].name,-1));//(int)tempvalindex; | |
3439 } | |
3440 else*/ | |
3441 tempvalindex = (datum *)instance->def->implement_func->workerlist[aworker].value_index; | |
3442 add_ref(tempvalindex); | |
3443 process_outputs(&tempvalindex, aworker, instance); | |
3444 } | |
3445 VIS_PROFILE_END(PROF_EXECUTE_OTHER); | |
3446 } | |
3447 VIS_PROFILE_END(PROF_PROCESS_WORKER); | |
3448 return returnval; | |
3449 } | |
3450 | |
3451 #define OPT_RESULT 0 | |
3452 #define OPT_CUST_RESULT 0x10000000 | |
3453 #define OPT_CONST 0x20000000 | |
3454 #define OPT_INPUT 0x30000000 | |
3455 | |
3456 int find_input_worker(custom_worker * cust, int aworker, int input, int *ret_output) | |
3457 { | |
3458 int o, p, wire_count; | |
3459 int out_worker; | |
3460 o = cust->workerlist[aworker].wire_up_lookup; | |
3461 wire_count = 0; | |
3462 while(cust->wirelist[p=cust->workers_to_wires_up[o]].end_worker == aworker && p >= 0) | |
3463 { | |
3464 if(cust->wirelist[p].input_num == input) | |
3465 { | |
3466 ++wire_count; | |
3467 out_worker = cust->wirelist[p].start_worker; | |
3468 DEBUGPRINTF("Input %d attached to %s(%d)\n", input, cust->workerlist[out_worker].name, out_worker); | |
3469 if(ret_output) | |
3470 *ret_output = cust->wirelist[p].output_num; | |
3471 } | |
3472 ++o; | |
3473 } | |
3474 DEBUGPRINTF("wire_count: %d\n", wire_count); | |
3475 if(wire_count == 1) | |
3476 return out_worker; | |
3477 return -1; | |
3478 } | |
3479 | |
3480 int make_input_code(custom_worker * cust, BOOL * in_opt, int * pos_in_opt, int source_worker, int output_num, int index, opt_entry * opts, int * branch_flags, opt_entry ** branch_refs, int input_num, program * prog) | |
3481 { | |
3482 /*if(in_opt[source_worker]) | |
3483 { | |
3484 if(prog->deflist[cust->workerlist[source_worker].value_index].type & USER_FLAG) | |
3485 { | |
3486 return OPT_CUST_RESULT | ((pos_in_opt[source_worker] & 0xFFFF) << 8) | (output_num & 0xFF); | |
3487 } | |
3488 else | |
3489 { | |
3490 if(strcmp(prog->deflist[cust->workerlist[source_worker].value_index].name, "If") == 0) | |
3491 { | |
3492 if(output_num == 0) | |
3493 { | |
3494 branch_flags[index] = 1; | |
3495 if(opts[pos_in_opt[source_worker]].branch1 <= index) | |
3496 opts[pos_in_opt[source_worker]].branch1 = index+1; | |
3497 } | |
3498 else | |
3499 { | |
3500 branch_flags[index] = 2; | |
3501 if(opts[pos_in_opt[source_worker]].branch2 <= index) | |
3502 opts[pos_in_opt[source_worker]].branch2 = index+1; | |
3503 } | |
3504 branch_refs[index] = opts + pos_in_opt[source_worker]; | |
3505 } | |
3506 else if(branch_flags[pos_in_opt[source_worker]]) | |
3507 { | |
3508 if(branch_flags[pos_in_opt[source_worker]] == 1) | |
3509 { | |
3510 branch_refs[pos_in_opt[source_worker]]->branch1 = index + 1; | |
3511 branch_flags[index] = 1; | |
3512 } | |
3513 else | |
3514 { | |
3515 branch_refs[pos_in_opt[source_worker]]->branch1 = index + 2; | |
3516 branch_flags[index] = 2; | |
3517 } | |
3518 branch_refs[index] = branch_refs[pos_in_opt[source_worker]]; | |
3519 } | |
3520 else | |
3521 branch_flags[index] = 0; | |
3522 if(input_num >= 0) | |
3523 ++opts[pos_in_opt[source_worker]].output_refs[output_num]; | |
3524 DEBUGPRINTF("OPT_RESULT: opt_num: %d, output_num: %d\n", pos_in_opt[source_worker], output_num); | |
3525 return OPT_RESULT | ((pos_in_opt[source_worker] & 0xFFFF) << 8) | (output_num & 0xFF); | |
3526 } | |
3527 } | |
3528 else if(cust->workerlist[source_worker].type == CONSTANT) | |
3529 { | |
3530 branch_flags[index] = 0; | |
3531 DEBUGPRINTF("OPT_CONST: %d\n", source_worker); | |
3532 return OPT_CONST | source_worker; | |
3533 } | |
3534 else if(cust->workerlist[source_worker].type == INPUT) | |
3535 { | |
3536 branch_flags[index] = 0; | |
3537 DEBUGPRINTF("OPT_INPUT: %d\n", cust->workerlist[source_worker].io_num); | |
3538 return OPT_INPUT | cust->workerlist[source_worker].io_num; | |
3539 }*/ | |
3540 return -1; | |
3541 } | |
3542 | |
3543 void optimize(worker_def * def) | |
3544 { | |
3545 /* | |
3546 int i,j,k,m,o,p; | |
3547 int * const_in; | |
3548 int num_entries = 0; | |
3549 int aworker; | |
3550 int adjust; | |
3551 int source_worker; | |
3552 int source_output; | |
3553 int source_null; | |
3554 int null_output; | |
3555 int wire_count; | |
3556 int * input_data; | |
3557 int current_null; | |
3558 int cust_result_count; | |
3559 int new_start; | |
3560 custom_worker * cust = def->implement_func; | |
3561 int start_current, end_current, new_current; | |
3562 worker_def * deflist = def->program->deflist; | |
3563 opt_entry * output = malloc(sizeof(opt_entry) * def->implement_func->num_workers); | |
3564 BOOL * in_opt = malloc(sizeof(BOOL) * cust->num_workers); | |
3565 int * branch_flags = malloc(sizeof(int) * cust->num_workers); | |
3566 opt_entry ** branch_refs = malloc(sizeof(int) * cust->num_workers); | |
3567 //BOOL * real_in_opt = malloc(sizeof(BOOL) * cust->num_workers); | |
3568 int * pos_in_opt = malloc(sizeof(int) * cust->num_workers); | |
3569 DEBUGPRINTF("deflist: %X\n", deflist); | |
3570 for(i = 0; i < cust->num_workers; ++i) | |
3571 { | |
3572 branch_flags[i] = 0; | |
3573 DEBUGPRINTF("%d: No input pass\n", i); | |
3574 DEBUGPRINTF("Examining: %s\n", cust->workerlist[i].name); | |
3575 if(cust->workerlist[i].num_inputs == 0 && !cust->workerlist[i].null_input && cust->workerlist[i].type == WORKER) | |
3576 { | |
3577 output[num_entries].def = deflist + cust->workerlist[i].value_index; | |
3578 DEBUGPRINTF("Set output[%d].def = %X\n", num_entries, output[num_entries].def); | |
3579 DEBUGPRINTF("opt: %d is %s\n\n", num_entries, cust->workerlist[i].name); | |
3580 output[num_entries].original_pos = i; | |
3581 output[num_entries].input_data = NULL; | |
3582 if(cust->workerlist[i].num_outputs) | |
3583 { | |
3584 output[num_entries].output_refs = malloc(sizeof(int)*cust->workerlist[i].num_outputs); | |
3585 for(j = 0; j < cust->workerlist[i].num_outputs; ++j) | |
3586 output[num_entries].output_refs[j] = 0; | |
3587 } | |
3588 else | |
3589 output[num_entries].output_refs = NULL; | |
3590 output[num_entries].branch1 = output[num_entries].branch2 = -1; | |
3591 //if(!(deflist[cust->workerlist[i].value_index].type & USER_FLAG)) | |
3592 //{ | |
3593 in_opt[i] = TRUE; | |
3594 pos_in_opt[i] = num_entries; | |
3595 //} | |
3596 //real_in_opt[i] = TRUE; | |
3597 ++num_entries; | |
3598 } | |
3599 else | |
3600 { | |
3601 //real_in_opt[i] = FALSE; | |
3602 in_opt[i] = FALSE; | |
3603 } | |
3604 } | |
3605 start_current = num_entries; | |
3606 for(i = 0; i < cust->num_workers; ++i) | |
3607 { | |
3608 DEBUGPRINTF("%d: Second pass\n", i); | |
3609 if(cust->workerlist[i].num_inputs == 0 && !cust->workerlist[i].null_input) | |
3610 { | |
3611 j = cust->workerlist[i].wire_down_lookup; | |
3612 while(cust->wirelist[k=cust->workers_to_wires_down[j]].start_worker == i && k >= 0) | |
3613 { | |
3614 aworker = cust->wirelist[k].end_worker; | |
3615 if(!in_opt[aworker]) | |
3616 { | |
3617 DEBUGPRINTF("Examining: %s(%d)\n", cust->workerlist[aworker].name, aworker); | |
3618 if(cust->workerlist[i].null_input) | |
3619 adjust = 1; | |
3620 else | |
3621 adjust = 0; | |
3622 input_data = malloc(sizeof(int)* (cust->workerlist[aworker].num_inputs+adjust)); | |
3623 for(m = (0-adjust); m < cust->workerlist[aworker].num_inputs; ++m) | |
3624 { | |
3625 DEBUGPRINTF("Input: %d\n", m); | |
3626 source_worker = find_input_worker(cust, aworker, m, &source_output); | |
3627 DEBUGPRINTF("source_worker: %d\n", source_worker); | |
3628 if(source_worker == -1) | |
3629 break; | |
3630 source_worker = make_input_code(cust, in_opt, pos_in_opt, source_worker, source_output, num_entries, output, branch_flags, branch_refs, m, def->program); | |
3631 DEBUGPRINTF("input code: %X\n", source_worker); | |
3632 if(source_worker == -1) | |
3633 break; | |
3634 input_data[m+adjust] = source_worker; | |
3635 if(source_worker == -1) | |
3636 break; | |
3637 } | |
3638 if(source_worker == -1) | |
3639 free(input_data); | |
3640 else | |
3641 { | |
3642 if(cust->workerlist[aworker].type == OUTPUT) | |
3643 output[num_entries].def = NULL; | |
3644 else | |
3645 output[num_entries].def = deflist + cust->workerlist[aworker].value_index; | |
3646 DEBUGPRINTF("Set output[%d].def = %X\n", num_entries, output[num_entries].def); | |
3647 DEBUGPRINTF("opt: %d is %s\n\n", num_entries, cust->workerlist[aworker].name); | |
3648 output[num_entries].original_pos = aworker; | |
3649 output[num_entries].input_data = input_data; | |
3650 output[num_entries].null_inputs = adjust; | |
3651 output[num_entries].branch1 = output[num_entries].branch2 = -1; | |
3652 if(cust->workerlist[aworker].num_outputs) | |
3653 { | |
3654 output[num_entries].output_refs = malloc(sizeof(int)*cust->workerlist[aworker].num_outputs); | |
3655 for(m = 0; m < cust->workerlist[aworker].num_outputs; ++m) | |
3656 output[num_entries].output_refs[m] = 0; | |
3657 } | |
3658 else | |
3659 output[num_entries].output_refs = NULL; | |
3660 //if(cust->workerlist[aworker].type != OUTPUT && !(deflist[cust->workerlist[aworker].value_index].type & USER_FLAG)) | |
3661 //{ | |
3662 in_opt[aworker] = TRUE; | |
3663 pos_in_opt[aworker] = num_entries; | |
3664 //} | |
3665 //real_in_opt[aworker] = TRUE; | |
3666 ++num_entries; | |
3667 | |
3668 } | |
3669 } | |
3670 ++j; | |
3671 } | |
3672 } | |
3673 } | |
3674 DEBUGPUTS("Before While\n"); | |
3675 end_current = num_entries; | |
3676 while(start_current != end_current) | |
3677 { | |
3678 DEBUGPRINTF("start_current: %d, end_current: %d\n", start_current, end_current); | |
3679 new_start = num_entries; | |
3680 for(i = start_current; i < end_current; ++i) | |
3681 { | |
3682 DEBUGPRINTF("opt: %d, def: %X, name: %s\n", i, output[i].def, cust->workerlist[output[i].original_pos].name); | |
3683 j = cust->workerlist[output[i].original_pos].wire_down_lookup; | |
3684 DEBUGPRINTF("wire_down_lookup: %d\n", j); | |
3685 while(cust->wirelist[k=cust->workers_to_wires_down[j]].start_worker == output[i].original_pos && k >= 0) | |
3686 { | |
3687 DEBUGPRINTF("Wire %d is attached to worker %d output %d and worker %d input %d\n", k, cust->wirelist[k].start_worker, cust->wirelist[k].output_num, cust->wirelist[k].end_worker, cust->wirelist[k].input_num); | |
3688 aworker = cust->wirelist[k].end_worker; | |
3689 //FIXME: Only works if constant/input attached to only one destination | |
3690 if(cust->workerlist[aworker].type == CONSTANT || cust->workerlist[aworker].type == INPUT) | |
3691 { | |
3692 DEBUGPRINTF("Worker is of type %d, ", cust->workerlist[aworker].type); | |
3693 aworker = cust->wirelist[cust->workers_to_wires_down[cust->workerlist[aworker].wire_down_lookup]].end_worker; | |
3694 DEBUGPRINTF("reruting to worker %d\n", aworker); | |
3695 } | |
3696 if(!in_opt[aworker]) | |
3697 { | |
3698 DEBUGPRINTF("Examining: %s(%d)\n", cust->workerlist[aworker].name, aworker); | |
3699 if(cust->workerlist[i].null_input) | |
3700 adjust = 1; | |
3701 else | |
3702 adjust = 0; | |
3703 for(m = (0-adjust); m < cust->workerlist[aworker].num_inputs; ++m) | |
3704 { | |
3705 source_worker = find_input_worker(cust, aworker, m, &source_output); | |
3706 if(source_worker == -1) | |
3707 break; | |
3708 if(cust->workerlist[source_worker].null_input && cust->workerlist[source_worker].type != WORKER) | |
3709 ++adjust; | |
3710 } | |
3711 if(source_worker != -1) | |
3712 { | |
3713 current_null = 0; | |
3714 input_data = malloc(sizeof(int)* (cust->workerlist[aworker].num_inputs+adjust)); | |
3715 cust_result_count = 0; | |
3716 for(m = (cust->workerlist[i].null_input ? -1 : 0); m < cust->workerlist[aworker].num_inputs; ++m) | |
3717 { | |
3718 DEBUGPRINTF("Input: %d\n", m); | |
3719 source_worker = find_input_worker(cust, aworker, m, &source_output); | |
3720 if(cust->workerlist[source_worker].null_input && cust->workerlist[source_worker].type != WORKER) | |
3721 { | |
3722 source_null = find_input_worker(cust, source_worker, -1, &null_output); | |
3723 if(source_null == -1) | |
3724 { | |
3725 source_worker = -1; | |
3726 break; | |
3727 } | |
3728 source_null = make_input_code(cust, in_opt, pos_in_opt, source_null, null_output, num_entries, output, branch_flags, branch_refs,-2, def->program); | |
3729 if((source_null & 0xF0000000) == OPT_CUST_RESULT) | |
3730 ++cust_result_count; | |
3731 if(source_null == -1) | |
3732 { | |
3733 source_worker = -1; | |
3734 break; | |
3735 } | |
3736 input_data[current_null++] = source_null; | |
3737 } | |
3738 DEBUGPRINTF("source_worker: %d\n", source_worker); | |
3739 source_worker = make_input_code(cust, in_opt, pos_in_opt, source_worker, source_output, num_entries, output, branch_flags, branch_refs, m, def->program); | |
3740 if((source_worker & 0xF0000000) == OPT_CUST_RESULT) | |
3741 ++cust_result_count; | |
3742 DEBUGPRINTF("input code: %d\n", source_worker); | |
3743 if(cust_result_count >= (cust->workerlist[aworker].num_inputs + adjust)) | |
3744 source_worker = -1; | |
3745 if(source_worker == -1) | |
3746 break; | |
3747 input_data[m+adjust] = source_worker; | |
3748 } | |
3749 if(source_worker == -1) | |
3750 free(input_data); | |
3751 else | |
3752 { | |
3753 if(cust->workerlist[aworker].type == OUTPUT) | |
3754 output[num_entries].def = NULL; | |
3755 else | |
3756 output[num_entries].def = deflist + cust->workerlist[aworker].value_index; | |
3757 DEBUGPRINTF("Set output[%d].def = %X\n", num_entries, output[num_entries].def); | |
3758 DEBUGPRINTF("opt: %d is %s\n\n", num_entries, cust->workerlist[aworker].name); | |
3759 output[num_entries].original_pos = aworker; | |
3760 output[num_entries].input_data = input_data; | |
3761 output[num_entries].null_inputs = adjust; | |
3762 output[num_entries].branch1 = output[num_entries].branch2 = -1; | |
3763 if(cust->workerlist[aworker].num_outputs) | |
3764 { | |
3765 output[num_entries].output_refs = malloc(sizeof(int)*cust->workerlist[aworker].num_outputs); | |
3766 for(m = 0; m < cust->workerlist[aworker].num_outputs; ++m) | |
3767 output[num_entries].output_refs[m] = 0; | |
3768 } | |
3769 else | |
3770 output[num_entries].output_refs = NULL; | |
3771 //if(cust->workerlist[aworker].type != OUTPUT && !(deflist[cust->workerlist[aworker].value_index].type & USER_FLAG)) | |
3772 //{ | |
3773 in_opt[aworker] = TRUE; | |
3774 pos_in_opt[aworker] = num_entries; | |
3775 //} | |
3776 //real_in_opt[aworker] = TRUE; | |
3777 ++num_entries; | |
3778 | |
3779 } | |
3780 } | |
3781 } | |
3782 ++j; | |
3783 } | |
3784 } | |
3785 start_current = new_start; | |
3786 end_current = num_entries; | |
3787 } | |
3788 def->optimized = output; | |
3789 def->opt_count = num_entries; | |
3790 DEBUGPUTS("optimize done\n\n\n"); | |
3791 */ | |
3792 } | |
3793 | |
3794 | |
3795 void run_optimized(worker_instance * instance, datum ** params) | |
3796 { | |
3797 int i = 0,j,k; | |
3798 unsigned short output, opt_num; | |
3799 datum * this_params[32]; | |
3800 queue_entry entry; | |
3801 datum * val; | |
3802 BOOL skip; | |
3803 BOOL partial_flag; | |
3804 BOOL continue_flag; | |
3805 int count; | |
3806 int ready; | |
3807 int jump_from = -1; | |
3808 int jump_to = -1; | |
3809 int tmp, addnum; | |
3810 opt_entry * exec_list = instance->def->optimized; | |
3811 datum ** results = instance->opt_results;//malloc(sizeof(datum *) * instance->def->opt_count * 32); | |
3812 VIS_PROFILE_START(PROF_RUN_OPT); | |
3813 entry.instance = instance; | |
3814 for(i = 0; i < instance->def->opt_count; ++i) | |
3815 { | |
3816 VIS_PROFILE_START(PROF_OPT_LOOP); | |
3817 skip = FALSE; | |
3818 partial_flag = FALSE; | |
3819 continue_flag = FALSE; | |
3820 DEBUGPRINTF("\nPeparing exec_list[%d]\n", i); | |
3821 if(exec_list[i].def) | |
3822 { | |
3823 DEBUGPRINTF("Name: %s\n", exec_list[i].def->name); | |
3824 count = exec_list[i].def->num_inputs; | |
3825 } | |
3826 else | |
3827 count = 1; | |
3828 count += exec_list[i].null_inputs; | |
3829 //DEBUGPRINTF("Input count: %d\n", count); | |
3830 if(count && !exec_list[i].input_data) | |
3831 puts("Runtime Error: input data is NULL\n"); | |
3832 //DEBUGPRINTF("input_data: %X\n", exec_list[i].input_data); | |
3833 VIS_PROFILE_START(PROF_OPT_PREP_INPUT); | |
3834 for(j = 0; j < count; ++j) | |
3835 { | |
3836 val = NULL; | |
3837 continue_flag = FALSE; | |
3838 switch(exec_list[i].input_data[j] & 0xF0000000) | |
3839 { | |
3840 case OPT_RESULT: | |
3841 output = exec_list[i].input_data[j] & 0xFF; | |
3842 opt_num = (exec_list[i].input_data[j] >> 8)& 0xFFFF; | |
3843 DEBUGPRINTF("OPT_RESULT for input %d, opt_num: %d, output: %d\n", j, opt_num, output); | |
3844 val = results[(opt_num * 32) | output]; | |
3845 break; | |
3846 case OPT_CUST_RESULT: | |
3847 val = NULL; | |
3848 partial_flag = TRUE; | |
3849 continue_flag = TRUE; | |
3850 break; | |
3851 case OPT_INPUT: | |
3852 DEBUGPRINTF("OPT_INPUT for input %d\n", j); | |
3853 val = add_ref(params[exec_list[i].input_data[j] & 0xFF]); | |
3854 break; | |
3855 case OPT_CONST: | |
3856 DEBUGPRINTF("OPT_CONST for input %d\n", j); | |
3857 val = add_ref((datum *)(instance->def->implement_func->workerlist[exec_list[i].input_data[j] & 0xFFFFFF].value_index)); | |
3858 break; | |
3859 default: | |
3860 puts("Runtime Error: Invalid bytecode\n"); | |
3861 val = NULL; | |
3862 break; | |
3863 } | |
3864 if(!val && !continue_flag) | |
3865 { | |
3866 for(k = exec_list[i].null_inputs; k < j; ++k) | |
3867 release_ref(this_params[k]); | |
3868 skip = TRUE; | |
3869 break; | |
3870 } | |
3871 DEBUGPRINTF("this_params[%d] = %X\n", j, val); | |
3872 if(j >= exec_list[i].null_inputs) | |
3873 if(val) | |
3874 this_params[j] = /*add_ref(*/val/*)*/; | |
3875 else | |
3876 this_params[j] = NULL; | |
3877 | |
3878 } | |
3879 VIS_PROFILE_END(PROF_OPT_PREP_INPUT); | |
3880 if(!skip) | |
3881 { | |
3882 if(partial_flag) | |
3883 { | |
3884 VIS_PROFILE_START(PROF_PARTIAL_EXEC); | |
3885 ready = 0; | |
3886 for(j = exec_list[i].null_inputs; j < count; ++j) | |
3887 if(this_params[j]) | |
3888 { | |
3889 instance->workerlist[exec_list[i].original_pos].params[j-exec_list[i].null_inputs+1] = this_params[j]; | |
3890 ++ready; | |
3891 } | |
3892 if(instance->def->implement_func->workerlist[exec_list[i].original_pos].null_input && this_params[exec_list[i].null_inputs-1]) | |
3893 ++ready; | |
3894 DEBUGPRINTF("ready: %d\n", ready); | |
3895 skip = TRUE; | |
3896 VIS_EnterCriticalSection(instance->workerlist[exec_list[i].original_pos].worker_lock); | |
3897 instance->workerlist[exec_list[i].original_pos].ready_count += ready; | |
3898 if(instance->workerlist[exec_list[i].original_pos].ready_count >= (exec_list[i].def->num_inputs + (instance->def->implement_func->workerlist[exec_list[i].original_pos].null_input ? 1 : 0))) | |
3899 { | |
3900 skip = FALSE; | |
3901 instance->workerlist[exec_list[i].original_pos].ready_count = 0; | |
3902 | |
3903 } | |
3904 DEBUGPRINTF("ready_count: %d\n", instance->workerlist[exec_list[i].original_pos].ready_count); | |
3905 VIS_LeaveCriticalSection(instance->workerlist[exec_list[i].original_pos].worker_lock); | |
3906 if(!skip) | |
3907 add_queue(exec_list[i].original_pos, instance); | |
3908 VIS_PROFILE_END(PROF_PARTIAL_EXEC); | |
3909 } | |
3910 else if(exec_list[i].def) | |
3911 { | |
3912 VIS_PROFILE_START(PROF_FULL_EXEC); | |
3913 DEBUGPRINTF("opt_exec: %s(%d)\n", exec_list[i].def->name, exec_list[i].original_pos); | |
3914 entry.worker_num = exec_list[i].original_pos; | |
3915 if(exec_list[i].def->type & USER_FLAG) | |
3916 { | |
3917 VIS_PROFILE_START(PROF_OPT_EXEC_USER); | |
3918 instance->workerlist[exec_list[i].original_pos].params[0] = NULL; | |
3919 memcpy(instance->workerlist[exec_list[i].original_pos].params+1, this_params + exec_list[i].null_inputs, sizeof(datum *) * exec_list[i].def->num_inputs); | |
3920 add_queue(exec_list[i].original_pos, instance); | |
3921 VIS_PROFILE_END(PROF_OPT_EXEC_USER); | |
3922 } | |
3923 else | |
3924 { | |
3925 VIS_PROFILE_START(PROF_OPT_EXEC_BUILT); | |
3926 if(execute_def(exec_list[i].def, entry, this_params + exec_list[i].null_inputs, sub_callback) == 0) | |
3927 { | |
3928 DEBUGPUTS("Exectuted with reslts\n"); | |
3929 if(exec_list[i].output_refs) | |
3930 { | |
3931 for(j = exec_list[i].null_inputs; j < (exec_list[i].def->num_outputs+exec_list[i].null_inputs); ++j) | |
3932 { | |
3933 DEBUGPRINTF("output_refs[%d] = %d\n", j-exec_list[i].null_inputs, exec_list[i].output_refs[j-exec_list[i].null_inputs]); | |
3934 if(!exec_list[i].output_refs[j-exec_list[i].null_inputs]) | |
3935 release_ref(this_params[j]); | |
3936 else if(exec_list[i].output_refs[j-exec_list[i].null_inputs] > 1) | |
3937 { | |
3938 /*DEBUGPRINTF("multi_add_ref(%X): %d\n", this_params[j], exec_list[i].output_refs[j-exec_list[i].null_inputs]-1); | |
3939 tmp = (int)(&(this_params[j]->ref_count)); | |
3940 addnum = exec_list[i].output_refs[j-exec_list[i].null_inputs]-1; | |
3941 __asm | |
3942 { | |
3943 mov ebx, tmp | |
3944 mov eax, addnum | |
3945 lock xadd dword ptr [ebx], eax | |
3946 }*/ | |
3947 VIS_EnterCriticalSection(this_params[j]->lock); | |
3948 this_params[j]->ref_count += exec_list[i].output_refs[j-exec_list[i].null_inputs]-1; | |
3949 | |
3950 VIS_LeaveCriticalSection(this_params[j]->lock); | |
3951 } | |
3952 } | |
3953 memcpy(results + i*32, this_params + exec_list[i].null_inputs, sizeof(datum *) * exec_list[i].def->num_outputs); | |
3954 if(exec_list[i].branch1 >= 0) | |
3955 { | |
3956 if(this_params[exec_list[i].null_inputs]) | |
3957 { | |
3958 jump_from = exec_list[i].branch1; | |
3959 jump_to = exec_list[i].branch2; | |
3960 } | |
3961 else | |
3962 { | |
3963 i = exec_list[i].branch1-1; | |
3964 } | |
3965 } | |
3966 } | |
3967 } | |
3968 /*else | |
3969 { | |
3970 for(j = exec_list[i].null_inputs; j < (exec_list[i].def->num_outputs + exec_list[i].null_inputs); ++j) | |
3971 results[(i*32)|j] = NULL; | |
3972 }*/ | |
3973 VIS_PROFILE_END(PROF_OPT_EXEC_BUILT); | |
3974 } | |
3975 VIS_PROFILE_END(PROF_FULL_EXEC); | |
3976 DEBUGPUTS("Executed\n"); | |
3977 } | |
3978 else | |
3979 instance->workerlist[exec_list[i].original_pos].value = this_params[exec_list[i].null_inputs]; | |
3980 } | |
3981 else | |
3982 { | |
3983 DEBUGPUTS("Skipped\n"); | |
3984 if(exec_list[i].def) | |
3985 { | |
3986 for(j = 0; j < exec_list[i].def->num_outputs; ++j) | |
3987 results[(i*32)|j] = NULL; | |
3988 } | |
3989 } | |
3990 if(jump_from >= 0 && (i+1) == jump_from) | |
3991 { | |
3992 i = jump_to-1; | |
3993 jump_from = -1; | |
3994 } | |
3995 VIS_PROFILE_END(PROF_OPT_LOOP); | |
3996 } | |
3997 DEBUGPUTS("run_optimized calling cleanup_check\n"); | |
3998 for(i = 0; i < instance->def->num_inputs; ++i) | |
3999 release_ref(params[i]); | |
4000 cleanup_check(entry); | |
4001 VIS_PROFILE_END(PROF_RUN_OPT); | |
4002 } | |
4003 | |
4004 int vis_print(datum ** inputlist, queue_entry * worker_entry) | |
4005 { | |
4006 int result; | |
4007 #ifdef CONSOLE | |
4008 puts((char *)inputlist[0]->c.generic.data); | |
4009 #else | |
4010 MessageBox(NULL, (char *)inputlist[0]->c.generic.data, "Visuality Output", MB_OK); | |
4011 #endif | |
4012 result = 1; | |
4013 | |
4014 release_ref(inputlist[0]); | |
4015 inputlist[0] = new_datum(BUILTIN_TYPE_YESNO, 2, 0, worker_entry->instance->def->program); | |
4016 //No one else knows about this new datum yet so we can skip getting a lock | |
4017 datum_set_yesno(inputlist[0], result); | |
4018 return 0; | |
4019 } | |
4020 | |
31
fab5bb137cf9
Added Unix Time worker to interpreter
Mike Pavone <pavone@retrodev.com>
parents:
29
diff
changeset
|
4021 int unix_time(datum ** inputlist, queue_entry * worker_entry) |
fab5bb137cf9
Added Unix Time worker to interpreter
Mike Pavone <pavone@retrodev.com>
parents:
29
diff
changeset
|
4022 { |
fab5bb137cf9
Added Unix Time worker to interpreter
Mike Pavone <pavone@retrodev.com>
parents:
29
diff
changeset
|
4023 inputlist[0] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program); |
fab5bb137cf9
Added Unix Time worker to interpreter
Mike Pavone <pavone@retrodev.com>
parents:
29
diff
changeset
|
4024 inputlist[0]->c.integers.num_a = time(NULL); |
fab5bb137cf9
Added Unix Time worker to interpreter
Mike Pavone <pavone@retrodev.com>
parents:
29
diff
changeset
|
4025 return 0; |
fab5bb137cf9
Added Unix Time worker to interpreter
Mike Pavone <pavone@retrodev.com>
parents:
29
diff
changeset
|
4026 } |
fab5bb137cf9
Added Unix Time worker to interpreter
Mike Pavone <pavone@retrodev.com>
parents:
29
diff
changeset
|
4027 |
0 | 4028 int vis_end(datum ** inputlist, queue_entry * worker_entry) |
4029 { | |
4030 // fprintf(outfile, "End worker reached.\n"); | |
4031 execute_active=FALSE; | |
4032 release_ref(inputlist[0]); | |
4033 //interp_stop(); | |
4034 return 0; | |
4035 } | |
4036 | |
4037 #ifdef NINTENDO_DS | |
4038 const char keyLetters[15] = "ABESRLUD><XYMC"; | |
4039 #define MAX_KEY_BITS 14 | |
4040 #endif | |
4041 | |
4042 int vis_getinput(datum ** inputlist, queue_entry * worker_entry) | |
4043 { | |
4044 #ifdef NINTENDO_DS | |
4045 int held,i,pos; | |
4046 char tempstring[14]; | |
4047 scanKeys(); | |
4048 held = keysHeld(); | |
4049 if(held) | |
4050 { | |
4051 pos = 0; | |
4052 for(i = 0; i < MAX_KEY_BITS; ++i) | |
4053 if(held & (1 << i)) | |
4054 tempstring[pos++] = keyLetters[i]; | |
4055 inputlist[0] = new_datum(BUILTIN_TYPE_STRING, 1, pos+1, worker_entry->instance->def->program); | |
4056 memcpy(inputlist[0]->c.generic.data, tempstring, pos); | |
4057 ((char *)inputlist[0]->c.generic.data)[pos]='\0'; | |
4058 return 0; | |
4059 } | |
4060 else | |
4061 { | |
4062 requeue(worker_entry->worker_num, worker_entry->instance); | |
4063 return 1; | |
4064 } | |
4065 #else | |
4066 #ifdef CONSOLE | |
4067 gets(text_buf); | |
4068 text_buf_size = strlen(text_buf); | |
4069 //Nasty hack for testing until I get around to supporting command line args propery | |
4070 //text_buf_size = strlen(global_argv[1]); | |
4071 #else | |
4072 | |
4073 while(text_buf_size <= 0) | |
4074 { | |
4075 Sleep(30); //TODO: replace with I/O queue mechanism | |
4076 } | |
4077 #endif | |
4078 // VIS_EnterCriticalSection(text_buf_lock); | |
4079 DEBUGPRINTF("Allocating %d bytes\n", text_buf_size+1); | |
4080 inputlist[0] = new_datum(BUILTIN_TYPE_STRING, 1, text_buf_size+1, worker_entry->instance->def->program); | |
4081 DEBUGPUTS("Allocated datum.\n"); | |
4082 memcpy(inputlist[0]->c.generic.data, text_buf, text_buf_size); | |
4083 DEBUGPUTS("Copied string.\n"); | |
4084 ((char *)inputlist[0]->c.generic.data)[text_buf_size]='\0'; | |
4085 DEBUGPRINTF("Input is %s\n", inputlist[0]->c.generic.data); | |
4086 text_buf_size = 0; | |
4087 // VIS_LeaveCriticalSection(text_buf_lock); | |
4088 return 0; | |
4089 #endif | |
4090 } | |
4091 | |
4092 int vis_if(datum ** inputlist, queue_entry * worker_entry) | |
4093 { | |
4094 if(!(inputlist[0]->c.integers.num_a)) | |
4095 { | |
4096 inputlist[1] = inputlist[0]; | |
4097 inputlist[0] = NULL; | |
4098 } | |
4099 else | |
4100 inputlist[1] = NULL; | |
4101 return 0; | |
4102 } | |
4103 | |
4104 int vis_build(datum ** inputlist, queue_entry * worker_entry) | |
4105 { | |
4106 int i,j; | |
4107 company * companylist = worker_entry->instance->def->program->companylist; | |
4108 int num_companies = worker_entry->instance->def->program->num_companies; | |
4109 DEBUGPRINTF("Looking for company named %s\n", inputlist[0]->c.generic.data); | |
4110 for(i = 0; i < num_companies; ++i) | |
4111 { | |
4112 DEBUGPRINTF("Checking company %d:%s\n", i, companylist[i].name); | |
4113 if(!strcmp(inputlist[0]->c.generic.data, companylist[i].name)) | |
4114 break; | |
4115 } | |
4116 release_ref(inputlist[0]); | |
4117 if(i < num_companies && companylist[i].build_size > 0) | |
4118 { | |
4119 DEBUGPRINTF("Building company with size %d\n", companylist[i].build_size); | |
4120 inputlist[0] = new_datum(i, 1, companylist[i].build_size, worker_entry->instance->def->program); | |
4121 for(j = 0; j < companylist[i].build_size; ++j) | |
4122 ((char*)(inputlist[0]->c.generic.data))[j] = 0; | |
4123 } | |
4124 else | |
4125 { | |
4126 DEBUGPUTS("Could not find company\n"); | |
4127 inputlist[0] = NULL; | |
4128 } | |
4129 return 0; | |
4130 } | |
4131 | |
4132 int vis_wait_forever(datum ** inputlist, queue_entry * worker_entry) | |
4133 { | |
4134 return 1; | |
4135 } | |
4136 | |
4137 int init_global_store(datum ** inputlist, queue_entry * worker_entry) | |
4138 { | |
4139 datum * params[3]; | |
4140 global_store * store; | |
4141 datum * store_dat = new_datum(BUILTIN_TYPE_GLOBAL_STORE, 1, sizeof(global_store), worker_entry->instance->def->program); | |
4142 store = store_dat->c.generic.data; | |
4143 store->name = add_ref(inputlist[0]); | |
4144 store->data = create_dict(worker_entry->instance->def->program); | |
4145 VIS_EnterCriticalSection(global_store_lock); | |
4146 params[0] = global_store_dict; | |
4147 params[1] = inputlist[0]; | |
4148 params[2] = store_dat; | |
4149 vis_dict_set(params, NULL); | |
4150 global_store_dict = params[0]; | |
4151 DEBUGPUTS("Global store init complete\n"); | |
4152 VIS_LeaveCriticalSection(global_store_lock); | |
4153 DEBUGPUTS("Released global_store_lock\n"); | |
4154 inputlist[0] = NULL; | |
4155 return 0; | |
4156 } | |
4157 | |
4158 int vis_type_of(datum ** inputlist, queue_entry * worker_entry) | |
4159 { | |
4160 datum * output = make_string(inputlist[0]->company->name, -1, worker_entry->instance->def->program); | |
4161 release_ref(inputlist[0]); | |
4162 inputlist[0] = output; | |
4163 return 0; | |
4164 } | |
4165 | |
4166 int vis_random(datum ** inputlist, queue_entry * worker_entry) | |
4167 { | |
4168 inputlist[0] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program); | |
4169 VIS_EnterCriticalSection(randlock); | |
4170 inputlist[0]->c.integers.num_a = genrand_int32(); | |
4171 VIS_LeaveCriticalSection(randlock); | |
4172 return 0; | |
4173 } |