static short read_short P1(int, offset) { short l; COPY_SHORT(&l, mem_block[current_block].block + offset); return l; }
static void upd_short P2(int, offset, short, l) { IF_DEBUG(UPDATE_PROGRAM_SIZE); DEBUG_CHECK2(offset > CURRENT_PROGRAM_SIZE, "patch offset %x larger than current program size %x.\n", offset, CURRENT_PROGRAM_SIZE); COPY_SHORT(mem_block[current_block].block + offset, &l); }
static void upd_short P3(int, offset, int, l, char *, where) { unsigned short s; IF_DEBUG(UPDATE_PROGRAM_SIZE); DEBUG_CHECK2(offset > CURRENT_PROGRAM_SIZE, "patch offset %x larger than current program size %x.\n", offset, CURRENT_PROGRAM_SIZE); if (l > USHRT_MAX) { char buf[256]; sprintf(buf, "branch limit exceeded in %s, near line %i", where, line_being_generated); yyerror(buf); } s = l; COPY_SHORT(mem_block[A_PROGRAM].block + offset, &s); }
// we don't actually have to fill this data structure, but thought it might be easier // to work with if we did when changes come about. bool FillINFOQuery ( const mem_t* data, int data_len, A2S_INFO_t &info, mem_t **pPlayers, mem_t **pPassword ) { if ( (data[0]!=0xFF) && (data[1]!=0xFF) && (data[2]!=0xFF) && (data[3]!=0xFF) ) return false; int strcount=0; mem_t* start = (mem_t *)data; //byte type; //byte netversion; //char server_name[256]; //char map[256]; //char gamedir[256]; //char gamedesc[256]; //short appid; //byte players; //byte maxplayers; //byte bots; //char dedicated; //char os; //bool passwordset; //bool secure; //char version[256]; data+=4; COPY_BYTE(info.type); COPY_BYTE(info.netversion); COPY_STRING(info.server_name); COPY_STRING(info.map); COPY_STRING(info.gamedir); COPY_STRING(info.gamedesc); COPY_SHORT(&info.appid); *pPlayers = (mem_t *)data; COPY_BYTE(info.players); COPY_BYTE(info.maxplayers); COPY_BYTE(info.bots); COPY_BYTE(info.dedicated); COPY_BYTE(info.os); *pPassword = (mem_t *)data; COPY_BOOL(info.passwordset); COPY_BOOL(info.secure); COPY_STRING(info.version); return true; }
/* Currently, this procedure handles: * - jump threading */ void optimize_icode P3(char *, start, char *, pc, char *, end) { int instr; if (start == 0) { /* we don't optimize the initializer block right now b/c all the * stuff we do (jump threading, etc) can't occur there. */ start = mem_block[A_PROGRAM].block; pc = start; end = pc + mem_block[A_PROGRAM].current_size; if (*pc == 0) { /* no initializer jump */ pc += 3; } } while (pc < end) { switch (instr = EXTRACT_UCHAR(pc++)) { case F_NUMBER: case F_REAL: case F_CALL_INHERITED: pc += 4; break; case F_SIMUL_EFUN: case F_CALL_FUNCTION_BY_ADDRESS: pc += 3; break; case F_BRANCH: case F_BRANCH_WHEN_ZERO: case F_BRANCH_WHEN_NON_ZERO: case F_BBRANCH: case F_BBRANCH_WHEN_ZERO: case F_BBRANCH_WHEN_NON_ZERO: { char *tmp; short sarg; /* thread jumps */ COPY_SHORT(&sarg, pc); if (instr > F_BRANCH) tmp = pc - sarg; else tmp = pc + sarg; sarg = 0; while (1) { if (EXTRACT_UCHAR(tmp) == F_BRANCH) { COPY_SHORT(&sarg, tmp + 1); tmp += sarg + 1; } else if (EXTRACT_UCHAR(tmp) == F_BBRANCH) { COPY_SHORT(&sarg, tmp + 1); tmp -= sarg - 1; } else break; } if (!sarg) { pc += 2; break; } /* be careful; in the process of threading a forward jump * may have changed to a reverse one or vice versa */ if (tmp > pc) { if (instr > F_BRANCH) { pc[-1] -= 3; /* change to forward branch */ } sarg = tmp - pc; } else { if (instr <= F_BRANCH) { pc[-1] += 3; /* change to backwards branch */ } sarg = pc - tmp; } STORE_SHORT(pc, sarg); break; } #ifdef F_LOR case F_LOR: case F_LAND: { char *tmp; short sarg; /* thread jumps */ COPY_SHORT(&sarg, pc); tmp = pc + sarg; sarg = 0; while (1) { if (EXTRACT_UCHAR(tmp) == F_BRANCH) { COPY_SHORT(&sarg, tmp + 1); tmp += sarg + 1; } else if (EXTRACT_UCHAR(tmp) == F_BBRANCH) { COPY_SHORT(&sarg, tmp + 1); tmp -= sarg - 1; } else break; } if (!sarg) { pc += 2; break; } /* be careful; in the process of threading a forward jump * may have changed to a reverse one or vice versa */ if (tmp > pc) { sarg = tmp - pc; } else { #ifdef DEBUG fprintf(stderr,"Optimization failed; can't || or && backwards.\n"); #endif pc += 2; break; } STORE_SHORT(pc, sarg); break; } #endif case F_CATCH: case F_AGGREGATE: case F_AGGREGATE_ASSOC: case F_STRING: #ifdef F_JUMP_WHEN_ZERO case F_JUMP_WHEN_ZERO: case F_JUMP_WHEN_NON_ZERO: #endif #ifdef F_JUMP case F_JUMP: #endif pc += 2; break; case F_GLOBAL_LVALUE: case F_GLOBAL: case F_SHORT_STRING: case F_LOOP_INCR: case F_WHILE_DEC: case F_LOCAL: case F_LOCAL_LVALUE: case F_SSCANF: case F_PARSE_COMMAND: case F_BYTE: case F_POP_BREAK: case F_NBYTE: pc++; break; case F_FUNCTION_CONSTRUCTOR: switch (EXTRACT_UCHAR(pc++)) { case FP_SIMUL: case FP_LOCAL: pc += 2; break; case FP_FUNCTIONAL: case FP_FUNCTIONAL | FP_NOT_BINDABLE: pc += 3; break; case FP_ANONYMOUS: pc += 4; break; case FP_EFUN: #ifdef NEEDS_CALL_EXTRA if (EXTRACT_UCHAR(pc++) == F_CALL_EXTRA) #endif pc++; break; } break; case F_LOOP_COND: if (*pc++ == F_LOCAL) pc += 3; else pc += 7; break; case F_SWITCH: { unsigned short stable, etable; pc++; /* table type */ LOAD_SHORT(stable, pc); LOAD_SHORT(etable, pc); pc += 2; /* def */ DEBUG_CHECK(stable < pc - start || etable < pc - start || etable < stable, "Error in switch table found while optimizing\n"); /* recursively optimize the inside of the switch */ optimize_icode(start, pc, start + stable); pc = start + etable; break; } case F_CALL_EXTRA: instr = EXTRACT_UCHAR(pc++) + 0xff; default: if ((instr >= BASE) && (instrs[instr].min_arg != instrs[instr].max_arg)) pc++; } } }