void stmt_free(Stmt* stmt) { assert(stmt_is_valid(stmt)); SID_del(stmt); if (stmt->node != NULL) code_free(stmt->node); free((void*)stmt->filename); free((void*)stmt->text); free(stmt); }
code_t*code_cut(code_t*c) { if(!c) return c; code_t*prev = c->prev; code_t*next = c->next; c->prev = 0; c->next = 0; if(prev) prev->next=next; if(next) next->prev=prev; code_free(c); if(next) return code_end(next); else return prev; }
void nteh_framehandler(symbol *scopetable) { code *c; // Generate: // MOV EAX,&scope_table // JMP __cpp_framehandler if (scopetable) { symbol_debug(scopetable); c = gencs(NULL,0xB8+AX,0,FLextern,scopetable); // MOV EAX,&scope_table gencs(c,0xE9,0,FLfunc,rtlsym[RTLSYM_CPP_HANDLER]); // JMP __cpp_framehandler pinholeopt(c,NULL); codout(c); code_free(c); } }
void nteh_framehandler(symbol *scopetable) { // Generate: // MOV EAX,&scope_table // JMP __cpp_framehandler if (scopetable) { symbol_debug(scopetable); code *c = gencs(NULL,0xB8+AX,0,FLextern,scopetable); // MOV EAX,&scope_table #if MARS gencs(c,0xE9,0,FLfunc,getRtlsym(RTLSYM_D_HANDLER)); // JMP _d_framehandler #else gencs(c,0xE9,0,FLfunc,getRtlsym(RTLSYM_CPP_HANDLER)); // JMP __cpp_framehandler #endif pinholeopt(c,NULL); codout(c); code_free(c); } }
void nteh_framehandler(Symbol *sfunc, Symbol *scopetable) { // Generate: // MOV EAX,&scope_table // JMP __cpp_framehandler if (scopetable) { symbol_debug(scopetable); CodeBuilder cdb; cdb.gencs(0xB8+AX,0,FLextern,scopetable); // MOV EAX,&scope_table #if MARS cdb.gencs(0xE9,0,FLfunc,getRtlsym(RTLSYM_D_HANDLER)); // JMP _d_framehandler #else cdb.gencs(0xE9,0,FLfunc,getRtlsym(RTLSYM_CPP_HANDLER)); // JMP __cpp_framehandler #endif code *c = cdb.finish(); pinholeopt(c,NULL); codout(sfunc->Sseg,c); code_free(c); } }
void state_free(struct state *state) { /* We have to stop the system call thread first, since it's using * sockets that we want to close and reset. */ syscalls_free(state, state->syscalls); /* Then we close the sockets and reset the connections, while * we still have a netdev for injecting reset packets to free * per-connection kernel state. */ close_all_sockets(state); netdev_free(state->netdev); packets_free(state->packets); code_free(state->code); run_unlock(state); if (pthread_mutex_destroy(&state->mutex) != 0) die_perror("pthread_mutex_destroy"); memset(state, 0, sizeof(*state)); /* paranoia to help catch bugs */ free(state); }
void eval_block(code *block, map* vars) { while (true) { code_skip_whitespace(block); if (block->source[block->pos] == '?') { uint8_t brackets = 0; size_t start, length = 0; mpz_t value; mpz_init(value); block->pos++; code_skip_whitespace(block); _parse_value(block, value, vars); code_skip_whitespace(block); start = block->pos + 1; while (true) { length++; if (block->source[block->pos] == '{') { brackets++; block->pos++; } else if (block->source[block->pos] == '}') { brackets--; block->pos++; if (brackets == 0) break; } else { block->pos++; } } if (mpz_sgn(value) == 0) { code subblock; code_init(&subblock); code_append(&subblock, block->source + start * sizeof(char), length - 2); eval_block(&subblock, vars); code_free(&subblock); } mpz_clear(value); } else if (block->source[block->pos] == '!') { mpz_t value; mpz_init(value); block->pos++; code_skip_whitespace(block); _parse_value(block, value, vars); mpz_out_str(stdout, 10, value); printf("\n"); mpz_clear(value); } else { char *var = malloc(1024 * sizeof(char)); mpz_t value; mpz_init(value); _parse_variable_name(block, var); code_skip_whitespace(block); switch (block->source[block->pos]) { case '=': block->pos++; code_skip_whitespace(block); _parse_value(block, value, vars); map_set(vars, var, value, false); break; case '+': block->pos += 2; code_skip_whitespace(block); _parse_value(block, value, vars); map_set(vars, var, value, true); break; case '-': block->pos += 2; code_skip_whitespace(block); _parse_value(block, value, vars); mpz_neg(value, value); map_set(vars, var, value, true); break; default: fprintf(stderr, "Parse error\n"); } free(var); mpz_clear(value); } code_skip_whitespace(block); if (block->pos >= block->length) return; if (block->source[block->pos] == ';') { block->pos++; } else { fprintf(stderr, "Missing ;\n"); return; } } }
struct code* code_analyse(struct prx *p) { struct code *c = code_alloc(); struct subroutine *sub; element el; c->file = p; if (!decode_instructions(c)) { code_free(c); return NULL ; } extract_switches(c); extract_subroutines(c); live_registers(c); el = list_head(c->subroutines); while (el) { sub = element_getvalue(el); if (!sub->import && !sub->haserror) { cfg_traverse(sub, FALSE); if (!sub->haserror) { sub->status |= SUB_STAT_CFG_TRAVERSE; cfg_traverse(sub, TRUE); } if (!sub->haserror) { sub->status |= SUB_STAT_CFG_TRAVERSE_REV; fixup_call_arguments(sub); } if (!sub->haserror) { sub->status |= SUB_STAT_FIXUP_CALL_ARGS; build_ssa(sub); } if (!sub->haserror) { sub->status |= SUB_STAT_SSA; } } el = element_next(el); } live_registers_imports(c); el = list_head(c->subroutines); while (el) { sub = element_getvalue(el); if (!sub->import && !sub->haserror) { if (!(sub->status & SUB_STAT_FIXUP_CALL_ARGS)) { fixup_call_arguments(sub); if (!sub->haserror) { sub->status |= SUB_STAT_FIXUP_CALL_ARGS; build_ssa(sub); } } if (!sub->haserror) { sub->status |= SUB_STAT_SSA; propagate_constants(sub); } if (!sub->haserror) { sub->status |= SUB_STAT_CONSTANTS_EXTRACTED; extract_variables(sub); } if (!sub->haserror) { sub->status |= SUB_STAT_VARIABLES_EXTRACTED; extract_structures(sub); } if (!sub->haserror) { sub->status |= SUB_STAT_STRUCTURES_EXTRACTED; } } el = element_next(el); } return c; }