void event_loop() { ULONG wait, signal; BOOL shouldplay = FALSE; char *symbol = NULL; branch branchallowed = NOBRANCH; /* Obtain the window wait signal mask. */ //IIntuition->GetAttr( WINDOW_SigMask, MainWinObj, &signal ); /* Input Event Loop */ while( !done ) { signal = obtain_all_signals(); wait = IExec->Wait(signal|SIGBREAKF_CTRL_C|SIGF_CHILD); if (wait & SIGBREAKF_CTRL_C) done = TRUE; if(wait & debug_sigfield) { //console_printf(OUTPUT_SYSTEM, "SIG from debug hook\n"); //console_printf(OUTPUT_SYSTEM, "traptype = 0x%08x\n", *((uint32 *)debug_hook.h_Data)); button_set_continue(); BOOL crashed = FALSE; uint32 traptype = *((uint32 *)debug_hook.h_Data); if(traptype != 0x700 && traptype != 0xd00) { catch_sline = FALSE; should_continue = FALSE; console_printf(OUTPUT_WARNING, "Your program has crashed! ip = 0x%x", context_copy.ip); } BOOL tracing = FALSE; //signal from debugger means TRAP task_playing = FALSE; suspend_all_breakpoints(); if(stepping_out) { stepping_out = FALSE; stepout_remove(); } if (asm_trace) { asmstep_remove(); if(!should_continue && !stepping_over) { switch(is_branch_allowed()) { case DISALLOWEDBRANCH: if(catch_sline) { stepping_out = TRUE; stepout_install(); shouldplay = TRUE; } else { //console_printf(OUTPUT_WARNING, "Branch into new area not allowed!"); enable(TRUE, GAD_STEPOUT_BUTTON, TAG_END); enable(FALSE, GAD_STEPINTO_BUTTON, GAD_STEPOVER_BUTTON, GAD_DISASSEMBLER_STEP_BUTTON, TAG_END); } catch_sline = FALSE; stepping_over = FALSE; break; case DISALLOWEDBRANCHCOND: if(catch_sline) { stepping_out = TRUE; stepout_install(); shouldplay = TRUE; } else { //console_printf(OUTPUT_WARNING, "Branch into new area not allowed!"); enable(TRUE, GAD_STEPOVER_BUTTON, GAD_STEPOUT_BUTTON, TAG_END); enable(FALSE, GAD_STEPINTO_BUTTON, GAD_DISASSEMBLER_STEP_BUTTON, TAG_END); } catch_sline = FALSE; stepping_over = FALSE; break; default: break; } } tracing = TRUE; if(!should_continue && !catch_sline) { disassembler_makelist(); variables_update(); source_update(); } } if (should_continue) { install_all_breakpoints(); shouldplay = TRUE; should_continue = FALSE; } else { current_function = stabs_get_function_from_address (context_copy.ip); if (current_function) hasfunctioncontext = TRUE; else if(!stepping_over && try_import_segment(context_copy.ip) > 0) { current_function = stabs_get_function_from_address(context_copy.ip); if(current_function) hasfunctioncontext = TRUE; else hasfunctioncontext = FALSE; } else hasfunctioncontext = FALSE; if (hasfunctioncontext) { //dprintf("current_function == %s\n", current_function->name); //if(stepover_func) // dprintf("stepover_func == %s\n", stepover_func->name); int nline = get_nline_from_address (context_copy.ip); if(nline >= 0) { if(stepping_over) { if(current_function == stepover_func && current_function->line[nline].infile != current_function->line[current_function->currentline].infile) { catch_sline = FALSE; stepping_over = FALSE; current_function->currentline = nline; } } else { catch_sline = FALSE; current_function->currentline = nline; } } else if (!catch_sline) { nline = guess_line_in_function(); if(nline) current_function->currentline = nline; } else if (!tracing) { console_printf(OUTPUT_WARNING, "Function overload error!"); //printf("function size: 0x%x function address: 0x%x\n", current_function->size, current_function->address); } } else if(!stepping_over && (symbol = get_symbol_from_value(context_copy.ip))) { console_printf(OUTPUT_NORMAL, "At symbol %s: 0x%x", symbol, context_copy.ip); if(catch_sline) { catch_sline = FALSE; enable(TRUE, GAD_START_BUTTON, GAD_STEPINTO_BUTTON, GAD_STEPOUT_BUTTON, GAD_DISASSEMBLER_STEP_BUTTON, TAG_END); enable(FALSE, GAD_PAUSE_BUTTON, GAD_STEPOVER_BUTTON, TAG_END); } source_update(); variables_update(); stacktrace_update(); disassembler_makelist(); show_disassembler(); } else if(!stepping_over && !tracing) { console_printf(OUTPUT_WARNING, "Program has stopped at an unknown point in memory (TRAP)"); disassembler_makelist(); variables_update(); stacktrace_update(); show_disassembler(); } if(catch_sline) { if(stepping_over && get_branched_function() != current_function) asmstep_nobranch(); else asmstep(); } else if(hasfunctioncontext) { if (current_function != old_function) output_functionheader(); old_function = current_function; enable(TRUE, GAD_START_BUTTON, GAD_STEPOVER_BUTTON, GAD_STEPINTO_BUTTON, GAD_STEPOUT_BUTTON, GAD_KILL_BUTTON, TAG_END); enable(FALSE, GAD_PAUSE_BUTTON, GAD_SELECT_BUTTON, TAG_END); remove_line_breakpoints(); variables_update(); stacktrace_update(); disassembler_makelist(); source_update(); if(!tracing) show_source(); } } } if(wait & SIGF_CHILD) { task_exists = FALSE; task_playing = FALSE; should_continue = FALSE; asm_trace = FALSE; hasfunctioncontext = FALSE; current_function = NULL; breakpoints_installed = FALSE; enable(TRUE, GAD_RELOAD_BUTTON, GAD_SELECT_BUTTON, TAG_END); enable(FALSE, GAD_START_BUTTON, GAD_PAUSE_BUTTON, GAD_STEPOVER_BUTTON, GAD_STEPINTO_BUTTON, GAD_KILL_BUTTON, GAD_SETBREAK_BUTTON, GAD_FILENAME_STRING, GAD_HEX_BUTTON, TAG_END); button_set_start(); IIntuition->RefreshGadgets ((struct Gadget *)MainObj[GAD_FILENAME_STRING], mainwin, NULL); close_all_elfhandles(); free_symbols(); stabs_free_stabs(); free_breakpoints(); //tracking_clear(); modules_close_window(); hex_close_window(); variables_clear(); source_clear(); sourcelist_clear(); stacktrace_clear(); disassembler_clear(); console_printf(OUTPUT_SYSTEM, "Program has ended"); } if (wait & main_obtain_window_signal()) { main_event_handler(); } if (wait & hex_obtain_window_signal()) { hex_event_handler(); } if (wait & breakpoints_obtain_window_signal()) { breakpoints_event_handler(); } if (wait & sigwin_obtain_signal()) { sigwin_event_handler(); } if(wait & import_obtain_window_signal()) { import_event_handler(); } if(wait & arexx_obtain_signal()) { arexx_event_handler(); } if(wait & pipe_obtain_signal()) { char buffer[1024]; int len = pipe_read(buffer); console_write_raw_data(OUTPUT_FROM_EXECUTABLE, buffer, len); } if (shouldplay) { play(); task_playing = TRUE; } shouldplay = FALSE; } return; }
void eval(BOOLEAN do_gc) { static unsigned int count = 0; OBJECT_PTR exp = car(reg_next_expression); OBJECT_PTR opcode = car(exp); pin_globals(); if(do_gc) { count++; if(count == GC_FREQUENCY) { gc(false, true); count = 0; } } if(opcode == APPLY && profiling_in_progress) { last_operator = reg_accumulator; if(prev_operator != NIL) { OBJECT_PTR operator_to_be_used; hashtable_entry_t *e; unsigned int count; unsigned int mem_alloc; double elapsed_wall_time; double elapsed_cpu_time; double temp1 = get_wall_time(); clock_t temp2 = clock(); unsigned int temp3 = memory_allocated(); profiling_datum_t *pd = (profiling_datum_t *)malloc(sizeof(profiling_datum_t)); if(IS_SYMBOL_OBJECT(prev_operator)) operator_to_be_used = prev_operator; else { OBJECT_PTR res = get_symbol_from_value(prev_operator, reg_current_env); if(car(res) != NIL) operator_to_be_used = cdr(res); else operator_to_be_used = cons(LAMBDA, cons(get_params_object(prev_operator), cons(car(get_source_object(prev_operator)), NIL))); } e = hashtable_get(profiling_tab, (void *)operator_to_be_used); if(e) { profiling_datum_t *pd = (profiling_datum_t *)e->value; count = pd->count + 1; elapsed_wall_time = pd->elapsed_wall_time + temp1 - wall_time_var; elapsed_cpu_time = pd->elapsed_cpu_time + (temp2 - cpu_time_var) * 1.0 / CLOCKS_PER_SEC; mem_alloc = pd->mem_allocated + temp3 - mem_alloc_var; hashtable_remove(profiling_tab, (void *)operator_to_be_used); free(pd); } else { count = 1; elapsed_wall_time = temp1 - wall_time_var; elapsed_cpu_time = (temp2 - cpu_time_var) * 1.0 / CLOCKS_PER_SEC; mem_alloc = temp3 - mem_alloc_var; } pd->count = count; pd->elapsed_wall_time = elapsed_wall_time; pd->elapsed_cpu_time = elapsed_cpu_time; pd->mem_allocated = mem_alloc; hashtable_put(profiling_tab, (void *)operator_to_be_used, (void *)pd); } wall_time_var = get_wall_time(); cpu_time_var = clock(); mem_alloc_var = memory_allocated(); prev_operator = reg_accumulator; } if(opcode == HALT) { halt_op(); } else if(opcode == REFER) { if(refer(CADR(exp))) return; reg_next_expression = CADDR(exp); } else if(opcode == CONSTANT) { if(constant(CADR(exp))) return; reg_next_expression = CADDR(exp); } else if(opcode == CLOSE) { if(closure(exp)) return; reg_next_expression = fifth(exp); } else if(opcode == MACRO) { if(macro(exp)) return; reg_next_expression = CADDDDR(exp); } else if(opcode == TEST) { if(reg_accumulator != NIL) reg_next_expression = CADR(exp); else reg_next_expression = CADDR(exp); } //Not using this WHILE; reverting //to macro definition, as this //version doesn't handle (BREAK) else if(opcode == WHILE) { OBJECT_PTR cond = CADR(exp); OBJECT_PTR body = CADDR(exp); OBJECT_PTR ret = NIL; while(1) { OBJECT_PTR temp = reg_current_stack; reg_next_expression = cond; while(car(reg_next_expression) != NIL) { eval(false); if(in_error) return; } if(reg_accumulator == NIL) break; reg_next_expression = body; while(car(reg_next_expression) != NIL) { eval(false); if(in_error) return; } //to handle premature exits //via RETURN-FROM if(reg_current_stack != temp) return; ret = reg_accumulator; } reg_accumulator = ret; reg_next_expression = CADDDR(exp); } else if(opcode == ASSIGN) { if(assign(CADR(exp))) return; reg_next_expression = CADDR(exp); } else if(opcode == DEFINE) { if(define(CADR(exp))) return; reg_next_expression = CADDR(exp); } else if(opcode == CONTI) { if(conti()) return; reg_next_expression = CADR(exp); } else if(opcode == NUATE) //this never gets called { reg_current_stack = CADR(exp); reg_accumulator = CADDR(exp); reg_current_value_rib = NIL; reg_next_expression = cons(CONS_RETURN_NIL, cdr(reg_next_expression)); } else if(opcode == FRAME) { if(frame(exp)) return; reg_next_expression = CADDR(exp); } else if(opcode == ARGUMENT) { if(argument()) return; reg_next_expression = CADR(exp); } else if(opcode == APPLY) { apply_compiled(); } else if(opcode == RETURN) { return_op(); } }