mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-04-05 01:11:00 +00:00
c++: exec.cpp
This commit is contained in:
parent
2dde6d903e
commit
c285eb385d
2 changed files with 90 additions and 102 deletions
171
exec.cpp
171
exec.cpp
|
@ -28,6 +28,12 @@ static void qcvmerror(qc_program_t *prog, const char *fmt, ...)
|
|||
putchar('\n');
|
||||
}
|
||||
|
||||
qc_program::qc_program(const char *name, uint16_t crc, size_t entfields)
|
||||
: filename(name)
|
||||
, crc16(crc)
|
||||
, entityfields(entfields)
|
||||
{}
|
||||
|
||||
qc_program_t* prog_load(const char *filename, bool skipversion)
|
||||
{
|
||||
prog_header_t header;
|
||||
|
@ -58,22 +64,7 @@ qc_program_t* prog_load(const char *filename, bool skipversion)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
prog = (qc_program_t*)mem_a(sizeof(qc_program_t));
|
||||
if (!prog) {
|
||||
fclose(file);
|
||||
fprintf(stderr, "failed to allocate program data\n");
|
||||
return nullptr;
|
||||
}
|
||||
memset(prog, 0, sizeof(*prog));
|
||||
|
||||
prog->entityfields = header.entfield;
|
||||
prog->crc16 = header.crc16;
|
||||
|
||||
prog->filename = util_strdup(filename);
|
||||
if (!prog->filename) {
|
||||
loaderror("failed to store program name");
|
||||
goto error;
|
||||
}
|
||||
prog = new qc_program(filename, header.crc16, header.entfield);
|
||||
|
||||
#define read_data(hdrvar, progvar, reserved) \
|
||||
if (fseek(file, header.hdrvar.offset, SEEK_SET) != 0) { \
|
||||
|
@ -110,7 +101,8 @@ qc_program_t* prog_load(const char *filename, bool skipversion)
|
|||
fclose(file);
|
||||
|
||||
/* profile counters */
|
||||
memset(vec_add(prog->profile, prog->code.size()), 0, sizeof(prog->profile[0]) * prog->code.size());
|
||||
prog->profile.resize(prog->code.size());
|
||||
memset(&prog->profile[0], 0, sizeof(prog->profile[0]) * prog->profile.size());
|
||||
|
||||
/* Add tempstring area */
|
||||
prog->tempstring_start = prog->strings.size();
|
||||
|
@ -119,8 +111,9 @@ qc_program_t* prog_load(const char *filename, bool skipversion)
|
|||
prog->strings.resize(prog->strings.size() + 16*1024, '\0');
|
||||
|
||||
/* spawn the world entity */
|
||||
vec_push(prog->entitypool, true);
|
||||
memset(vec_add(prog->entitydata, prog->entityfields), 0, prog->entityfields * sizeof(prog->entitydata[0]));
|
||||
prog->entitypool.emplace_back(true);
|
||||
prog->entitydata.resize(prog->entityfields);
|
||||
memset(prog->entitydata.data(), 0, sizeof(prog->entitydata[0]) * prog->entityfields);
|
||||
prog->entities = 1;
|
||||
|
||||
/* cache some globals and fields from names */
|
||||
|
@ -156,11 +149,7 @@ qc_program_t* prog_load(const char *filename, bool skipversion)
|
|||
return prog;
|
||||
|
||||
error:
|
||||
if (prog->filename)
|
||||
mem_d(prog->filename);
|
||||
vec_free(prog->entitydata);
|
||||
vec_free(prog->entitypool);
|
||||
mem_d(prog);
|
||||
delete prog;
|
||||
|
||||
fclose(file);
|
||||
return nullptr;
|
||||
|
@ -168,13 +157,7 @@ error:
|
|||
|
||||
void prog_delete(qc_program_t *prog)
|
||||
{
|
||||
if (prog->filename) mem_d(prog->filename);
|
||||
vec_free(prog->entitydata);
|
||||
vec_free(prog->entitypool);
|
||||
vec_free(prog->localstack);
|
||||
vec_free(prog->stack);
|
||||
vec_free(prog->profile);
|
||||
mem_d(prog);
|
||||
delete prog;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -205,28 +188,31 @@ prog_section_def_t* prog_getdef(qc_program_t *prog, qcint_t off)
|
|||
}
|
||||
|
||||
qcany_t* prog_getedict(qc_program_t *prog, qcint_t e) {
|
||||
if (e >= (qcint_t)vec_size(prog->entitypool)) {
|
||||
if (e >= (qcint_t)prog->entitypool.size()) {
|
||||
prog->vmerror++;
|
||||
fprintf(stderr, "Accessing out of bounds edict %i\n", (int)e);
|
||||
e = 0;
|
||||
}
|
||||
return (qcany_t*)(prog->entitydata + (prog->entityfields * e));
|
||||
return (qcany_t*)&prog->entitydata[prog->entityfields * e];
|
||||
}
|
||||
|
||||
static qcint_t prog_spawn_entity(qc_program_t *prog) {
|
||||
char *data;
|
||||
qcint_t e;
|
||||
for (e = 0; e < (qcint_t)vec_size(prog->entitypool); ++e) {
|
||||
for (e = 0; e < (qcint_t)prog->entitypool.size(); ++e) {
|
||||
if (!prog->entitypool[e]) {
|
||||
data = (char*)(prog->entitydata + (prog->entityfields * e));
|
||||
data = (char*)&prog->entitydata[prog->entityfields * e];
|
||||
memset(data, 0, prog->entityfields * sizeof(qcint_t));
|
||||
return e;
|
||||
}
|
||||
}
|
||||
vec_push(prog->entitypool, true);
|
||||
prog->entitypool.emplace_back(true);
|
||||
prog->entities++;
|
||||
data = (char*)vec_add(prog->entitydata, prog->entityfields);
|
||||
memset(data, 0, prog->entityfields * sizeof(qcint_t));
|
||||
size_t sz = prog->entitydata.size();
|
||||
prog->entitydata.resize(sz + prog->entityfields);
|
||||
data = (char*)&prog->entitydata[sz];
|
||||
memset(data, 0, sz * sizeof(qcint_t));
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
@ -236,7 +222,7 @@ static void prog_free_entity(qc_program_t *prog, qcint_t e) {
|
|||
fprintf(stderr, "Trying to free world entity\n");
|
||||
return;
|
||||
}
|
||||
if (e >= (qcint_t)vec_size(prog->entitypool)) {
|
||||
if (e >= (qcint_t)prog->entitypool.size()) {
|
||||
prog->vmerror++;
|
||||
fprintf(stderr, "Trying to free out of bounds entity\n");
|
||||
return;
|
||||
|
@ -369,11 +355,11 @@ static void prog_print_statement(qc_program_t *prog, prog_section_statement_t *s
|
|||
printf("<illegal instruction %d>\n", st->opcode);
|
||||
return;
|
||||
}
|
||||
if ((prog->xflags & VMXF_TRACE) && vec_size(prog->function_stack)) {
|
||||
if ((prog->xflags & VMXF_TRACE) && !prog->function_stack.empty()) {
|
||||
size_t i;
|
||||
for (i = 0; i < vec_size(prog->function_stack); ++i)
|
||||
for (i = 0; i < prog->function_stack.size(); ++i)
|
||||
printf("->");
|
||||
printf("%s:", vec_last(prog->function_stack));
|
||||
printf("%s:", prog->function_stack.back());
|
||||
}
|
||||
printf(" <> %-12s", util_instr_str[st->opcode]);
|
||||
if (st->opcode >= INSTR_IF &&
|
||||
|
@ -467,30 +453,30 @@ static qcint_t prog_enterfunction(qc_program_t *prog, prog_section_function_t *f
|
|||
int32_t p;
|
||||
|
||||
/* back up locals */
|
||||
st.localsp = vec_size(prog->localstack);
|
||||
st.localsp = prog->localstack.size();
|
||||
st.stmt = prog->statement;
|
||||
st.function = func;
|
||||
|
||||
if (prog->xflags & VMXF_TRACE) {
|
||||
const char *str = prog_getstring(prog, func->name);
|
||||
vec_push(prog->function_stack, str);
|
||||
prog->function_stack.emplace_back(str);
|
||||
}
|
||||
|
||||
#ifdef QCVM_BACKUP_STRATEGY_CALLER_VARS
|
||||
if (vec_size(prog->stack))
|
||||
if (prog->stack.size())
|
||||
{
|
||||
prog_section_function_t *cur;
|
||||
cur = prog->stack[vec_size(prog->stack)-1].function;
|
||||
cur = prog->stack.back().function;
|
||||
if (cur)
|
||||
{
|
||||
qcint_t *globals = &prog->globals[0] + cur->firstlocal;
|
||||
vec_append(prog->localstack, cur->locals, globals);
|
||||
prog->localstack.insert(prog->localstack.end(), globals, globals + cur->locals);
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
qcint_t *globals = &prog->globals[0] + func->firstlocal;
|
||||
vec_append(prog->localstack, func->locals, globals);
|
||||
prog->localstack.insert(prog->localstack.end(), globals, globals + func->locals);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -505,7 +491,7 @@ static qcint_t prog_enterfunction(qc_program_t *prog, prog_section_function_t *f
|
|||
}
|
||||
}
|
||||
|
||||
vec_push(prog->stack, st);
|
||||
prog->stack.emplace_back(st);
|
||||
|
||||
return func->entry;
|
||||
}
|
||||
|
@ -514,30 +500,29 @@ static qcint_t prog_leavefunction(qc_program_t *prog) {
|
|||
prog_section_function_t *prev = nullptr;
|
||||
size_t oldsp;
|
||||
|
||||
qc_exec_stack_t st = vec_last(prog->stack);
|
||||
qc_exec_stack_t st = prog->stack.back();
|
||||
|
||||
if (prog->xflags & VMXF_TRACE) {
|
||||
if (vec_size(prog->function_stack))
|
||||
vec_pop(prog->function_stack);
|
||||
if (!prog->function_stack.empty())
|
||||
prog->function_stack.pop_back();
|
||||
}
|
||||
|
||||
#ifdef QCVM_BACKUP_STRATEGY_CALLER_VARS
|
||||
if (vec_size(prog->stack) > 1) {
|
||||
prev = prog->stack[vec_size(prog->stack)-2].function;
|
||||
oldsp = prog->stack[vec_size(prog->stack)-2].localsp;
|
||||
if (prog->stack.size() > 1) {
|
||||
prev = prog->stack[prog->stack.size()-2].function;
|
||||
oldsp = prog->stack[prog->stack.size()-2].localsp;
|
||||
}
|
||||
#else
|
||||
prev = prog->stack[vec_size(prog->stack)-1].function;
|
||||
oldsp = prog->stack[vec_size(prog->stack)-1].localsp;
|
||||
prev = prog->stack[prog->stack.size()-1].function;
|
||||
oldsp = prog->stack[prog->stack.size()-1].localsp;
|
||||
#endif
|
||||
if (prev) {
|
||||
qcint_t *globals = &prog->globals[0] + prev->firstlocal;
|
||||
memcpy(globals, prog->localstack + oldsp, prev->locals * sizeof(prog->localstack[0]));
|
||||
/* vec_remove(prog->localstack, oldsp, vec_size(prog->localstack)-oldsp); */
|
||||
vec_shrinkto(prog->localstack, oldsp);
|
||||
memcpy(globals, &prog->localstack[oldsp], prev->locals * sizeof(prog->localstack[0]));
|
||||
prog->localstack.resize(oldsp);
|
||||
}
|
||||
|
||||
vec_pop(prog->stack);
|
||||
prog->stack.pop_back();
|
||||
|
||||
return st.stmt - 1; /* offset the ++st */
|
||||
}
|
||||
|
@ -584,8 +569,8 @@ bool prog_exec(qc_program_t *prog, prog_section_function_t *func, size_t flags,
|
|||
|
||||
cleanup:
|
||||
prog->xflags = oldxflags;
|
||||
vec_free(prog->localstack);
|
||||
vec_free(prog->stack);
|
||||
prog->localstack.clear();
|
||||
prog->stack.clear();
|
||||
if (prog->vmerror)
|
||||
return false;
|
||||
return true;
|
||||
|
@ -623,7 +608,7 @@ struct qcvm_parameter {
|
|||
const char *value;
|
||||
};
|
||||
|
||||
static qcvm_parameter *main_params = nullptr;
|
||||
static std::vector<qcvm_parameter> main_params;
|
||||
|
||||
#define CheckArgs(num) do { \
|
||||
if (prog->argc != (num)) { \
|
||||
|
@ -887,7 +872,7 @@ static void prog_main_setparams(qc_program_t *prog) {
|
|||
size_t i;
|
||||
qcany_t *arg;
|
||||
|
||||
for (i = 0; i < vec_size(main_params); ++i) {
|
||||
for (i = 0; i < main_params.size(); ++i) {
|
||||
arg = GetGlobal(OFS_PARM0 + 3*i);
|
||||
arg->vector[0] = 0;
|
||||
arg->vector[1] = 0;
|
||||
|
@ -926,8 +911,8 @@ int main(int argc, char **argv) {
|
|||
bool opts_info = false;
|
||||
bool noexec = false;
|
||||
const char *progsfile = nullptr;
|
||||
const char **dis_list = nullptr;
|
||||
int opts_v = 0;
|
||||
std::vector<const char*> dis_list;
|
||||
|
||||
arg0 = argv[0];
|
||||
|
||||
|
@ -997,7 +982,7 @@ int main(int argc, char **argv) {
|
|||
usage();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
vec_push(dis_list, argv[1]);
|
||||
dis_list.emplace_back(argv[1]);
|
||||
--argc;
|
||||
++argv;
|
||||
noexec = true;
|
||||
|
@ -1042,7 +1027,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
p.value = argv[1];
|
||||
|
||||
vec_push(main_params, p);
|
||||
main_params.emplace_back(p);
|
||||
--argc;
|
||||
++argv;
|
||||
}
|
||||
|
@ -1111,7 +1096,7 @@ int main(int argc, char **argv) {
|
|||
prog_delete(prog);
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < vec_size(dis_list); ++i) {
|
||||
for (i = 0; i < dis_list.size(); ++i) {
|
||||
size_t k;
|
||||
printf("Looking for `%s`\n", dis_list[i]);
|
||||
for (k = 1; k < prog->functions.size(); ++k) {
|
||||
|
@ -1282,7 +1267,7 @@ while (prog->vmerror == 0) {
|
|||
switch (st->opcode)
|
||||
{
|
||||
default:
|
||||
qcvmerror(prog, "Illegal instruction in %s\n", prog->filename);
|
||||
qcvmerror(prog, "Illegal instruction in %s\n", prog->filename.c_str());
|
||||
goto cleanup;
|
||||
|
||||
case INSTR_DONE:
|
||||
|
@ -1293,7 +1278,7 @@ while (prog->vmerror == 0) {
|
|||
GLOBAL(OFS_RETURN)->ivector[2] = OPA->ivector[2];
|
||||
|
||||
st = &prog->code[0] + prog_leavefunction(prog);
|
||||
if (!vec_size(prog->stack))
|
||||
if (prog->stack.empty())
|
||||
goto cleanup;
|
||||
|
||||
break;
|
||||
|
@ -1402,12 +1387,12 @@ while (prog->vmerror == 0) {
|
|||
case INSTR_LOAD_ENT:
|
||||
case INSTR_LOAD_FNC:
|
||||
if (OPA->edict < 0 || OPA->edict >= prog->entities) {
|
||||
qcvmerror(prog, "progs `%s` attempted to read an out of bounds entity", prog->filename);
|
||||
qcvmerror(prog, "progs `%s` attempted to read an out of bounds entity", prog->filename.c_str());
|
||||
goto cleanup;
|
||||
}
|
||||
if ((unsigned int)(OPB->_int) >= (unsigned int)(prog->entityfields)) {
|
||||
qcvmerror(prog, "prog `%s` attempted to read an invalid field from entity (%i)",
|
||||
prog->filename,
|
||||
prog->filename.c_str(),
|
||||
OPB->_int);
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -1416,13 +1401,13 @@ while (prog->vmerror == 0) {
|
|||
break;
|
||||
case INSTR_LOAD_V:
|
||||
if (OPA->edict < 0 || OPA->edict >= prog->entities) {
|
||||
qcvmerror(prog, "progs `%s` attempted to read an out of bounds entity", prog->filename);
|
||||
qcvmerror(prog, "progs `%s` attempted to read an out of bounds entity", prog->filename.c_str());
|
||||
goto cleanup;
|
||||
}
|
||||
if (OPB->_int < 0 || OPB->_int + 3 > (qcint_t)prog->entityfields)
|
||||
{
|
||||
qcvmerror(prog, "prog `%s` attempted to read an invalid field from entity (%i)",
|
||||
prog->filename,
|
||||
prog->filename.c_str(),
|
||||
OPB->_int + 2);
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -1435,19 +1420,19 @@ while (prog->vmerror == 0) {
|
|||
|
||||
case INSTR_ADDRESS:
|
||||
if (OPA->edict < 0 || OPA->edict >= prog->entities) {
|
||||
qcvmerror(prog, "prog `%s` attempted to address an out of bounds entity %i", prog->filename, OPA->edict);
|
||||
qcvmerror(prog, "prog `%s` attempted to address an out of bounds entity %i", prog->filename.c_str(), OPA->edict);
|
||||
goto cleanup;
|
||||
}
|
||||
if ((unsigned int)(OPB->_int) >= (unsigned int)(prog->entityfields))
|
||||
{
|
||||
qcvmerror(prog, "prog `%s` attempted to read an invalid field from entity (%i)",
|
||||
prog->filename,
|
||||
prog->filename.c_str(),
|
||||
OPB->_int);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ed = prog_getedict(prog, OPA->edict);
|
||||
OPC->_int = ((qcint_t*)ed) - prog->entitydata + OPB->_int;
|
||||
OPC->_int = ((qcint_t*)ed) - prog->entitydata.data() + OPB->_int;
|
||||
break;
|
||||
|
||||
case INSTR_STORE_F:
|
||||
|
@ -1468,29 +1453,29 @@ while (prog->vmerror == 0) {
|
|||
case INSTR_STOREP_ENT:
|
||||
case INSTR_STOREP_FLD:
|
||||
case INSTR_STOREP_FNC:
|
||||
if (OPB->_int < 0 || OPB->_int >= (qcint_t)vec_size(prog->entitydata)) {
|
||||
qcvmerror(prog, "`%s` attempted to write to an out of bounds edict (%i)", prog->filename, OPB->_int);
|
||||
if (OPB->_int < 0 || OPB->_int >= (qcint_t)prog->entitydata.size()) {
|
||||
qcvmerror(prog, "`%s` attempted to write to an out of bounds edict (%i)", prog->filename.c_str(), OPB->_int);
|
||||
goto cleanup;
|
||||
}
|
||||
if (OPB->_int < (qcint_t)prog->entityfields && !prog->allowworldwrites)
|
||||
qcvmerror(prog, "`%s` tried to assign to world.%s (field %i)\n",
|
||||
prog->filename,
|
||||
prog->filename.c_str(),
|
||||
prog_getstring(prog, prog_entfield(prog, OPB->_int)->name),
|
||||
OPB->_int);
|
||||
ptr = (qcany_t*)(prog->entitydata + OPB->_int);
|
||||
ptr = (qcany_t*)&prog->entitydata[OPB->_int];
|
||||
ptr->_int = OPA->_int;
|
||||
break;
|
||||
case INSTR_STOREP_V:
|
||||
if (OPB->_int < 0 || OPB->_int + 2 >= (qcint_t)vec_size(prog->entitydata)) {
|
||||
qcvmerror(prog, "`%s` attempted to write to an out of bounds edict (%i)", prog->filename, OPB->_int);
|
||||
if (OPB->_int < 0 || OPB->_int + 2 >= (qcint_t)prog->entitydata.size()) {
|
||||
qcvmerror(prog, "`%s` attempted to write to an out of bounds edict (%i)", prog->filename.c_str(), OPB->_int);
|
||||
goto cleanup;
|
||||
}
|
||||
if (OPB->_int < (qcint_t)prog->entityfields && !prog->allowworldwrites)
|
||||
qcvmerror(prog, "`%s` tried to assign to world.%s (field %i)\n",
|
||||
prog->filename,
|
||||
prog->filename.c_str(),
|
||||
prog_getstring(prog, prog_entfield(prog, OPB->_int)->name),
|
||||
OPB->_int);
|
||||
ptr = (qcany_t*)(prog->entitydata + OPB->_int);
|
||||
ptr = (qcany_t*)&prog->entitydata[OPB->_int];
|
||||
ptr->ivector[0] = OPA->ivector[0];
|
||||
ptr->ivector[1] = OPA->ivector[1];
|
||||
ptr->ivector[2] = OPA->ivector[2];
|
||||
|
@ -1521,7 +1506,7 @@ while (prog->vmerror == 0) {
|
|||
{
|
||||
st += st->o2.s1 - 1; /* offset the s++ */
|
||||
if (++jumpcount >= maxjumps)
|
||||
qcvmerror(prog, "`%s` hit the runaway loop counter limit of %li jumps", prog->filename, jumpcount);
|
||||
qcvmerror(prog, "`%s` hit the runaway loop counter limit of %li jumps", prog->filename.c_str(), jumpcount);
|
||||
}
|
||||
break;
|
||||
case INSTR_IFNOT:
|
||||
|
@ -1529,7 +1514,7 @@ while (prog->vmerror == 0) {
|
|||
{
|
||||
st += st->o2.s1 - 1; /* offset the s++ */
|
||||
if (++jumpcount >= maxjumps)
|
||||
qcvmerror(prog, "`%s` hit the runaway loop counter limit of %li jumps", prog->filename, jumpcount);
|
||||
qcvmerror(prog, "`%s` hit the runaway loop counter limit of %li jumps", prog->filename.c_str(), jumpcount);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1544,11 +1529,11 @@ while (prog->vmerror == 0) {
|
|||
case INSTR_CALL8:
|
||||
prog->argc = st->opcode - INSTR_CALL0;
|
||||
if (!OPA->function)
|
||||
qcvmerror(prog, "nullptr function in `%s`", prog->filename);
|
||||
qcvmerror(prog, "nullptr function in `%s`", prog->filename.c_str());
|
||||
|
||||
if(!OPA->function || OPA->function >= (qcint_t)prog->functions.size())
|
||||
{
|
||||
qcvmerror(prog, "CALL outside the program in `%s`", prog->filename);
|
||||
qcvmerror(prog, "CALL outside the program in `%s`", prog->filename.c_str());
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
@ -1565,7 +1550,7 @@ while (prog->vmerror == 0) {
|
|||
prog->builtins[builtinnumber](prog);
|
||||
else
|
||||
qcvmerror(prog, "No such builtin #%i in %s! Try updating your gmqcc sources",
|
||||
builtinnumber, prog->filename);
|
||||
builtinnumber, prog->filename.c_str());
|
||||
}
|
||||
else
|
||||
st = &prog->code[0] + prog_enterfunction(prog, newf) - 1; /* offset st++ */
|
||||
|
@ -1579,7 +1564,7 @@ while (prog->vmerror == 0) {
|
|||
qcfloat_t *time;
|
||||
qcfloat_t *frame;
|
||||
if (!prog->supports_state) {
|
||||
qcvmerror(prog, "`%s` tried to execute a STATE operation but misses its defs!", prog->filename);
|
||||
qcvmerror(prog, "`%s` tried to execute a STATE operation but misses its defs!", prog->filename.c_str());
|
||||
goto cleanup;
|
||||
}
|
||||
ed = prog_getedict(prog, prog->globals[prog->cached_globals.self]);
|
||||
|
@ -1596,7 +1581,7 @@ while (prog->vmerror == 0) {
|
|||
case INSTR_GOTO:
|
||||
st += st->o1.s1 - 1; /* offset the s++ */
|
||||
if (++jumpcount == 10000000)
|
||||
qcvmerror(prog, "`%s` hit the runaway loop counter limit of %li jumps", prog->filename, jumpcount);
|
||||
qcvmerror(prog, "`%s` hit the runaway loop counter limit of %li jumps", prog->filename.c_str(), jumpcount);
|
||||
break;
|
||||
|
||||
case INSTR_AND:
|
||||
|
|
21
gmqcc.h
21
gmqcc.h
|
@ -660,7 +660,7 @@ enum {
|
|||
#define VMXF_TRACE 0x0001 /* trace: print statements before executing */
|
||||
#define VMXF_PROFILE 0x0002 /* profile: increment the profile counters */
|
||||
|
||||
struct qc_program_t;
|
||||
typedef struct qc_program qc_program_t;
|
||||
typedef int (*prog_builtin_t)(qc_program_t *prog);
|
||||
|
||||
struct qc_exec_stack_t {
|
||||
|
@ -669,18 +669,21 @@ struct qc_exec_stack_t {
|
|||
prog_section_function_t *function;
|
||||
};
|
||||
|
||||
struct qc_program_t {
|
||||
char *filename;
|
||||
struct qc_program {
|
||||
qc_program() = delete;
|
||||
qc_program(const char *name, uint16_t crc, size_t entfields);
|
||||
|
||||
std::string filename;
|
||||
std::vector<prog_section_statement_t> code;
|
||||
std::vector<prog_section_def_t> defs;
|
||||
std::vector<prog_section_def_t> fields;
|
||||
std::vector<prog_section_function_t> functions;
|
||||
std::vector<char> strings;
|
||||
std::vector<qcint_t> globals;
|
||||
qcint_t *entitydata;
|
||||
bool *entitypool;
|
||||
std::vector<qcint_t> entitydata;
|
||||
std::vector<bool> entitypool;
|
||||
|
||||
const char* *function_stack;
|
||||
std::vector<const char*> function_stack;
|
||||
|
||||
uint16_t crc16;
|
||||
|
||||
|
@ -689,7 +692,7 @@ struct qc_program_t {
|
|||
|
||||
qcint_t vmerror;
|
||||
|
||||
size_t *profile;
|
||||
std::vector<size_t> profile;
|
||||
|
||||
prog_builtin_t *builtins;
|
||||
size_t builtins_count;
|
||||
|
@ -699,8 +702,8 @@ struct qc_program_t {
|
|||
size_t entityfields;
|
||||
bool allowworldwrites;
|
||||
|
||||
qcint_t *localstack;
|
||||
qc_exec_stack_t *stack;
|
||||
std::vector<qcint_t> localstack;
|
||||
std::vector<qc_exec_stack_t> stack;
|
||||
size_t statement;
|
||||
|
||||
size_t xflags;
|
||||
|
|
Loading…
Reference in a new issue