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;
- qc_program_t *prog;
- size_t i;
- FILE *file = fopen(filename, "rb");
+ prog_header_t header;
+ qc_program_t *prog;
+ FILE *file = fopen(filename, "rb");
/* we need all those in order to support INSTR_STATE: */
bool has_self = false,
has_frame = false;
if (!file)
- return NULL;
+ return nullptr;
if (fread(&header, sizeof(header), 1, file) != 1) {
loaderror("failed to read header from '%s'", filename);
fclose(file);
- return NULL;
+ return nullptr;
}
- util_swap_header(&header);
+ util_swap_header(header);
if (!skipversion && header.version != 6) {
loaderror("header says this is a version %i progs, we need version 6\n", header.version);
fclose(file);
- return NULL;
- }
-
- prog = (qc_program_t*)mem_a(sizeof(qc_program_t));
- if (!prog) {
- fclose(file);
- fprintf(stderr, "failed to allocate program data\n");
- return NULL;
+ 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) { \
loaderror("seek failed"); \
goto error; \
} \
+ prog->progvar.resize(header.hdrvar.length + reserved); \
if (fread( \
- vec_add(prog->progvar, header.hdrvar.length + reserved), \
- sizeof(*prog->progvar), \
+ &prog->progvar[0], \
+ sizeof(prog->progvar[0]), \
header.hdrvar.length, \
file \
)!= header.hdrvar.length \
read_data1(strings);
read_data2(globals, 2); /* reserve more in case a RETURN using with the global at "the end" exists */
- util_swap_statements (prog->code);
+ util_swap_statements(prog->code);
util_swap_defs_fields(prog->defs);
util_swap_defs_fields(prog->fields);
- util_swap_functions (prog->functions);
- util_swap_globals (prog->globals);
+ util_swap_functions(prog->functions);
+ util_swap_globals(prog->globals);
fclose(file);
/* profile counters */
- memset(vec_add(prog->profile, vec_size(prog->code)), 0, sizeof(prog->profile[0]) * vec_size(prog->code));
+ prog->profile.resize(prog->code.size());
+ memset(&prog->profile[0], 0, sizeof(prog->profile[0]) * prog->profile.size());
/* Add tempstring area */
- prog->tempstring_start = vec_size(prog->strings);
- prog->tempstring_at = vec_size(prog->strings);
- memset(vec_add(prog->strings, 16*1024), 0, 16*1024);
+ prog->tempstring_start = prog->strings.size();
+ prog->tempstring_at = prog->strings.size();
+
+ 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);
+ if (prog->entitydata.size())
+ memset(prog->entitydata.data(), 0, sizeof(prog->entitydata[0]) * prog->entityfields);
prog->entities = 1;
/* cache some globals and fields from names */
- for (i = 0; i < vec_size(prog->defs); ++i) {
- const char *name = prog_getstring(prog, prog->defs[i].name);
- if (!strcmp(name, "self")) {
- prog->cached_globals.self = prog->defs[i].offset;
+ for (auto &it : prog->defs) {
+ const char *name = prog_getstring(prog, it.name);
+ if (!strcmp(name, "self")) {
+ prog->cached_globals.self = it.offset;
has_self = true;
}
else if (!strcmp(name, "time")) {
- prog->cached_globals.time = prog->defs[i].offset;
+ prog->cached_globals.time = it.offset;
has_time = true;
}
}
- for (i = 0; i < vec_size(prog->fields); ++i) {
- const char *name = prog_getstring(prog, prog->fields[i].name);
- if (!strcmp(name, "think")) {
- prog->cached_fields.think = prog->fields[i].offset;
+ for (auto &it : prog->fields) {
+ const char *name = prog_getstring(prog, it.name);
+ if (!strcmp(name, "think")) {
+ prog->cached_fields.think = it.offset;
has_think = true;
}
else if (!strcmp(name, "nextthink")) {
- prog->cached_fields.nextthink = prog->fields[i].offset;
+ prog->cached_fields.nextthink = it.offset;
has_nextthink = true;
}
else if (!strcmp(name, "frame")) {
- prog->cached_fields.frame = prog->fields[i].offset;
+ prog->cached_fields.frame = it.offset;
has_frame = true;
}
}
return prog;
error:
- if (prog->filename)
- mem_d(prog->filename);
- vec_free(prog->code);
- vec_free(prog->defs);
- vec_free(prog->fields);
- vec_free(prog->functions);
- vec_free(prog->strings);
- vec_free(prog->globals);
- vec_free(prog->entitydata);
- vec_free(prog->entitypool);
- mem_d(prog);
+ delete prog;
fclose(file);
- return NULL;
+ return nullptr;
}
void prog_delete(qc_program_t *prog)
{
- if (prog->filename) mem_d(prog->filename);
- vec_free(prog->code);
- vec_free(prog->defs);
- vec_free(prog->fields);
- vec_free(prog->functions);
- vec_free(prog->strings);
- vec_free(prog->globals);
- 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;
}
/***********************************************************************
const char* prog_getstring(qc_program_t *prog, qcint_t str) {
/* cast for return required for C++ */
- if (str < 0 || str >= (qcint_t)vec_size(prog->strings))
+ if (str < 0 || str >= (qcint_t)prog->strings.size())
return "<<<invalid string>>>";
- return prog->strings + str;
+ return &prog->strings[0] + str;
}
prog_section_def_t* prog_entfield(qc_program_t *prog, qcint_t off) {
- size_t i;
- for (i = 0; i < vec_size(prog->fields); ++i) {
- if (prog->fields[i].offset == off)
- return (prog->fields + i);
- }
- return NULL;
+ for (auto &it : prog->fields)
+ if (it.offset == off)
+ return ⁢
+ return nullptr;
}
prog_section_def_t* prog_getdef(qc_program_t *prog, qcint_t off)
{
- size_t i;
- for (i = 0; i < vec_size(prog->defs); ++i) {
- if (prog->defs[i].offset == off)
- return (prog->defs + i);
- }
- return NULL;
+ for (auto &it : prog->defs)
+ if (it.offset == off)
+ return ⁢
+ return nullptr;
}
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;
}
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;
size_t at = prog->tempstring_at;
/* when we reach the end we start over */
- if (at + len >= vec_size(prog->strings))
+ if (at + len >= prog->strings.size())
at = prog->tempstring_start;
/* when it doesn't fit, reallocate */
- if (at + len >= vec_size(prog->strings))
+ if (at + len >= prog->strings.size())
{
- (void)vec_add(prog->strings, len+1);
- memcpy(prog->strings + at, str, len+1);
+ prog->strings.resize(prog->strings.size() + len+1);
+ memcpy(&prog->strings[0] + at, str, len+1);
return at;
}
/* when it fits, just copy */
- memcpy(prog->strings + at, str, len+1);
+ memcpy(&prog->strings[0] + at, str, len+1);
prog->tempstring_at += len+1;
return at;
}
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 &&
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 + cur->firstlocal;
- vec_append(prog->localstack, cur->locals, globals);
+ qcint_t *globals = &prog->globals[0] + cur->firstlocal;
+ prog->localstack.insert(prog->localstack.end(), globals, globals + cur->locals);
}
}
#else
{
- qcint_t *globals = prog->globals + func->firstlocal;
- vec_append(prog->localstack, func->locals, globals);
+ qcint_t *globals = &prog->globals[0] + func->firstlocal;
+ prog->localstack.insert(prog->localstack.end(), globals, globals + func->locals);
}
#endif
}
}
- vec_push(prog->stack, st);
+ prog->stack.emplace_back(st);
return func->entry;
}
static qcint_t prog_leavefunction(qc_program_t *prog) {
- prog_section_function_t *prev = NULL;
+ 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 + 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);
+ if (prev->locals) {
+ qcint_t *globals = &prog->globals[0] + prev->firstlocal;
+ 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 */
}
prog->vmerror = 0;
prog->xflags = flags;
- st = prog->code + prog_enterfunction(prog, func);
+ st = &prog->code[0] + prog_enterfunction(prog, func);
--st;
switch (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;
"noexpr"
};
-typedef struct {
+struct qcvm_parameter {
int vtype;
const char *value;
-} qcvm_parameter;
+};
-static qcvm_parameter *main_params = NULL;
+static std::vector<qcvm_parameter> main_params;
#define CheckArgs(num) do { \
if (prog->argc != (num)) { \
prog->vmerror++; \
fprintf(stderr, "ERROR: invalid number of arguments for %s: %i, expected %i\n", \
- __FUNCTION__, prog->argc, (num)); \
+ __func__, prog->argc, (num)); \
return -1; \
} \
} while (0)
-#define GetGlobal(idx) ((qcany_t*)(prog->globals + (idx)))
+#define GetGlobal(idx) ((qcany_t*)(&prog->globals[0] + (idx)))
#define GetArg(num) GetGlobal(OFS_PARM0 + 3*(num))
#define Return(any) *(GetGlobal(OFS_RETURN)) = (any)
static int qc_print(qc_program_t *prog) {
size_t i;
- const char *laststr = NULL;
+ const char *laststr = nullptr;
for (i = 0; i < (size_t)prog->argc; ++i) {
- qcany_t *str = (qcany_t*)(prog->globals + OFS_PARM0 + 3*i);
+ qcany_t *str = (qcany_t*)(&prog->globals[0] + OFS_PARM0 + 3*i);
laststr = prog_getstring(prog, str->string);
printf("%s", laststr);
}
qcany_t num;
CheckArgs(1);
str = GetArg(0);
- num._float = (float)strtod(prog_getstring(prog, str->string), NULL);
+ num._float = (float)strtod(prog_getstring(prog, str->string), nullptr);
+ Return(num);
+ return 0;
+}
+
+static int qc_stov(qc_program_t *prog) {
+ qcany_t *str;
+ qcany_t num;
+ CheckArgs(1);
+ str = GetArg(0);
+ (void)util_sscanf(prog_getstring(prog, str->string), " ' %f %f %f ' ",
+ &num.vector[0],
+ &num.vector[1],
+ &num.vector[2]);
Return(num);
return 0;
}
}
static prog_builtin_t qc_builtins[] = {
- NULL,
+ nullptr,
&qc_print, /* 1 */
&qc_ftos, /* 2 */
&qc_spawn, /* 3 */
&qc_normalize, /* 12 */
&qc_sqrt, /* 13 */
&qc_floor, /* 14 */
- &qc_pow /* 15 */
+ &qc_pow, /* 15 */
+ &qc_stov /* 16 */
};
-static const char *arg0 = NULL;
+static const char *arg0 = nullptr;
static void version(void) {
printf("GMQCC-QCVM %d.%d.%d Built %s %s\n",
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;
bool opts_disasm = false;
bool opts_info = false;
bool noexec = false;
- const char *progsfile = NULL;
- const char **dis_list = NULL;
+ const char *progsfile = nullptr;
int opts_v = 0;
+ std::vector<const char*> dis_list;
arg0 = argv[0];
usage();
exit(EXIT_FAILURE);
}
- vec_push(dis_list, argv[1]);
+ dis_list.emplace_back(argv[1]);
--argc;
++argv;
noexec = true;
}
p.value = argv[1];
- vec_push(main_params, p);
+ main_params.emplace_back(p);
--argc;
++argv;
}
if (opts_info) {
printf("Program's system-checksum = 0x%04x\n", (unsigned int)prog->crc16);
printf("Entity field space: %u\n", (unsigned int)prog->entityfields);
- printf("Globals: %u\n", (unsigned int)vec_size(prog->globals));
+ printf("Globals: %zu\n", prog->globals.size());
printf("Counts:\n"
- " code: %lu\n"
- " defs: %lu\n"
- " fields: %lu\n"
- " functions: %lu\n"
- " strings: %lu\n",
- (unsigned long)vec_size(prog->code),
- (unsigned long)vec_size(prog->defs),
- (unsigned long)vec_size(prog->fields),
- (unsigned long)vec_size(prog->functions),
- (unsigned long)vec_size(prog->strings));
+ " code: %zu\n"
+ " defs: %zu\n"
+ " fields: %zu\n"
+ " functions: %zu\n"
+ " strings: %zu\n",
+ prog->code.size(),
+ prog->defs.size(),
+ prog->fields.size(),
+ prog->functions.size(),
+ prog->strings.size());
}
if (opts_info) {
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 < vec_size(prog->functions); ++k) {
+ for (k = 1; k < prog->functions.size(); ++k) {
const char *name = prog_getstring(prog, prog->functions[k].name);
if (!strcmp(name, dis_list[i])) {
prog_disasm_function(prog, k);
}
}
if (opts_disasm) {
- for (i = 1; i < vec_size(prog->functions); ++i)
+ for (i = 1; i < prog->functions.size(); ++i)
prog_disasm_function(prog, i);
return 0;
}
if (opts_printdefs) {
- const char *getstring = NULL;
- for (i = 0; i < vec_size(prog->defs); ++i) {
+ const char *getstring = nullptr;
+ for (auto &it : prog->defs) {
printf("Global: %8s %-16s at %u%s",
- type_name[prog->defs[i].type & DEF_TYPEMASK],
- prog_getstring(prog, prog->defs[i].name),
- (unsigned int)prog->defs[i].offset,
- ((prog->defs[i].type & DEF_SAVEGLOBAL) ? " [SAVE]" : ""));
+ type_name[it.type & DEF_TYPEMASK],
+ prog_getstring(prog, it.name),
+ (unsigned int)it.offset,
+ ((it.type & DEF_SAVEGLOBAL) ? " [SAVE]" : ""));
if (opts_v) {
- switch (prog->defs[i].type & DEF_TYPEMASK) {
+ switch (it.type & DEF_TYPEMASK) {
case TYPE_FLOAT:
- printf(" [init: %g]", ((qcany_t*)(prog->globals + prog->defs[i].offset))->_float);
+ printf(" [init: %g]", ((qcany_t*)(&prog->globals[0] + it.offset))->_float);
break;
case TYPE_INTEGER:
- printf(" [init: %i]", (int)( ((qcany_t*)(prog->globals + prog->defs[i].offset))->_int ));
+ printf(" [init: %i]", (int)( ((qcany_t*)(&prog->globals[0] + it.offset))->_int ));
break;
case TYPE_ENTITY:
case TYPE_FUNCTION:
case TYPE_FIELD:
case TYPE_POINTER:
- printf(" [init: %u]", (unsigned)( ((qcany_t*)(prog->globals + prog->defs[i].offset))->_int ));
+ printf(" [init: %u]", (unsigned)( ((qcany_t*)(&prog->globals[0] + it.offset))->_int ));
break;
case TYPE_STRING:
- getstring = prog_getstring(prog, ((qcany_t*)(prog->globals + prog->defs[i].offset))->string);
+ getstring = prog_getstring(prog, ((qcany_t*)(&prog->globals[0] + it.offset))->string);
printf(" [init: `");
print_escaped_string(getstring, strlen(getstring));
printf("`]\n");
}
}
if (opts_printfields) {
- for (i = 0; i < vec_size(prog->fields); ++i) {
- printf("Field: %8s %-16s at %u%s\n",
- type_name[prog->fields[i].type],
- prog_getstring(prog, prog->fields[i].name),
- (unsigned int)prog->fields[i].offset,
- ((prog->fields[i].type & DEF_SAVEGLOBAL) ? " [SAVE]" : ""));
+ for (auto &it : prog->fields) {
+ printf("Field: %8s %-16s at %d%s\n",
+ type_name[it.type],
+ prog_getstring(prog, it.name),
+ it.offset,
+ ((it.type & DEF_SAVEGLOBAL) ? " [SAVE]" : ""));
}
}
if (opts_printfuns) {
- for (i = 0; i < vec_size(prog->functions); ++i) {
+ for (auto &it : prog->functions) {
int32_t a;
printf("Function: %-16s taking %u parameters:(",
- prog_getstring(prog, prog->functions[i].name),
- (unsigned int)prog->functions[i].nargs);
- for (a = 0; a < prog->functions[i].nargs; ++a) {
- printf(" %i", prog->functions[i].argsize[a]);
+ prog_getstring(prog, it.name),
+ (unsigned int)it.nargs);
+ for (a = 0; a < it.nargs; ++a) {
+ printf(" %i", it.argsize[a]);
}
if (opts_v > 1) {
- int32_t start = prog->functions[i].entry;
+ int32_t start = it.entry;
if (start < 0)
printf(") builtin %i\n", (int)-start);
else {
size_t funsize = 0;
- prog_section_statement_t *st = prog->code + start;
+ prog_section_statement_t *st = &prog->code[0] + start;
for (;st->opcode != INSTR_DONE; ++st)
++funsize;
- printf(") - %lu instructions", (unsigned long)funsize);
+ printf(") - %zu instructions", funsize);
if (opts_v > 2) {
printf(" - locals: %i + %i\n",
- prog->functions[i].firstlocal,
- prog->functions[i].locals);
+ it.firstlocal,
+ it.locals);
}
else
printf("\n");
}
else if (opts_v) {
printf(") locals: %i + %i\n",
- prog->functions[i].firstlocal,
- prog->functions[i].locals);
+ it.firstlocal,
+ it.locals);
}
else
printf(")\n");
}
}
if (!noexec) {
- for (i = 1; i < vec_size(prog->functions); ++i) {
+ for (i = 1; i < prog->functions.size(); ++i) {
const char *name = prog_getstring(prog, prog->functions[i].name);
if (!strcmp(name, "main"))
fnmain = (qcint_t)i;
}
static void prog_disasm_function(qc_program_t *prog, size_t id) {
- prog_section_function_t *fdef = prog->functions + id;
+ prog_section_function_t *fdef = &prog->functions[0] + id;
prog_section_statement_t *st;
if (fdef->entry < 0) {
else
printf("FUNCTION \"%s\"\n", prog_getstring(prog, fdef->name));
- st = prog->code + fdef->entry;
+ st = &prog->code[0] + fdef->entry;
while (st->opcode != INSTR_DONE) {
prog_print_statement(prog, st);
++st;
* sort of isn't, which makes it nicer looking.
*/
-#define OPA ( (qcany_t*) (prog->globals + st->o1.u1) )
-#define OPB ( (qcany_t*) (prog->globals + st->o2.u1) )
-#define OPC ( (qcany_t*) (prog->globals + st->o3.u1) )
+#define OPA ( (qcany_t*) (&prog->globals[0] + st->o1.u1) )
+#define OPB ( (qcany_t*) (&prog->globals[0] + st->o2.u1) )
+#define OPC ( (qcany_t*) (&prog->globals[0] + st->o3.u1) )
-#define GLOBAL(x) ( (qcany_t*) (prog->globals + (x)) )
+#define GLOBAL(x) ( (qcany_t*) (&prog->globals[0] + (x)) )
/* to be consistent with current darkplaces behaviour */
#if !defined(FLOAT_IS_TRUE_FOR_INT)
++st;
#if QCVM_PROFILE
- prog->profile[st - prog->code]++;
+ prog->profile[st - &prog->code[0]]++;
#endif
#if QCVM_TRACE
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:
GLOBAL(OFS_RETURN)->ivector[1] = OPA->ivector[1];
GLOBAL(OFS_RETURN)->ivector[2] = OPA->ivector[2];
- st = prog->code + prog_leavefunction(prog);
- if (!vec_size(prog->stack))
+ st = &prog->code[0] + prog_leavefunction(prog);
+ if (prog->stack.empty())
goto cleanup;
break;
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;
}
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;
}
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:
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];
{
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:
{
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_CALL8:
prog->argc = st->opcode - INSTR_CALL0;
if (!OPA->function)
- qcvmerror(prog, "NULL function in `%s`", prog->filename);
+ qcvmerror(prog, "nullptr function in `%s`", prog->filename.c_str());
- if(!OPA->function || OPA->function >= (qcint_t)vec_size(prog->functions))
+ 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;
}
newf = &prog->functions[OPA->function];
newf->profile++;
- prog->statement = (st - prog->code) + 1;
+ prog->statement = (st - &prog->code[0]) + 1;
if (newf->entry < 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 + prog_enterfunction(prog, newf) - 1; /* offset st++ */
+ st = &prog->code[0] + prog_enterfunction(prog, newf) - 1; /* offset st++ */
if (prog->vmerror)
goto cleanup;
break;
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]);
frame = (qcfloat_t*)&((qcint_t*)ed)[prog->cached_fields.frame];
*frame = OPA->_float;
nextthink = (qcfloat_t*)&((qcint_t*)ed)[prog->cached_fields.nextthink];
- time = (qcfloat_t*)(prog->globals + prog->cached_globals.time);
+ time = (qcfloat_t*)(&prog->globals[0] + prog->cached_globals.time);
*nextthink = *time + 0.1;
break;
}
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: