#include "gmqcc.h"
-#include "exec.h"
+MEM_VEC_FUNCTIONS(qc_program, prog_section_statement, code)
+MEM_VEC_FUNCTIONS(qc_program, prog_section_def, defs)
+MEM_VEC_FUNCTIONS(qc_program, prog_section_def, fields)
+MEM_VEC_FUNCTIONS(qc_program, prog_section_function, functions)
+MEM_VEC_FUNCTIONS(qc_program, char, strings)
+MEM_VEC_FUN_APPEND(qc_program, char, strings)
+MEM_VEC_FUN_RESIZE(qc_program, char, strings)
+MEM_VEC_FUNCTIONS(qc_program, qcint, globals)
+MEM_VEC_FUNCTIONS(qc_program, qcint, entitydata)
+
+MEM_VEC_FUNCTIONS(qc_program, qcint, localstack)
+MEM_VEC_FUN_APPEND(qc_program, qcint, localstack)
+MEM_VEC_FUN_RESIZE(qc_program, qcint, localstack)
+MEM_VEC_FUNCTIONS(qc_program, qc_exec_stack, stack)
+
+MEM_VEC_FUNCTIONS(qc_program, size_t, profile)
+MEM_VEC_FUN_RESIZE(qc_program, size_t, profile)
+
+MEM_VEC_FUNCTIONS(qc_program, prog_builtin, builtins)
static void loaderror(const char *fmt, ...)
{
MEM_VECTOR_CLEAR(prog, localstack);
MEM_VECTOR_CLEAR(prog, stack);
MEM_VECTOR_CLEAR(prog, profile);
+
+ if (prog->builtins_alloc) {
+ MEM_VECTOR_CLEAR(prog, builtins);
+ }
+ /* otherwise the builtins were statically allocated */
mem_d(prog);
}
static qcint prog_enterfunction(qc_program *prog, prog_section_function *func)
{
qc_exec_stack st;
- prog_section_function *cur = NULL;
-
- if (prog->stack_count)
- cur = prog->stack[prog->stack_count-1].function;
+ size_t p, parampos;
/* back up locals */
st.localsp = prog->localstack_count;
st.stmt = prog->statement;
st.function = func;
- if (cur)
+#ifdef QCVM_BACKUP_STRATEGY_CALLER_VARS
+ if (prog->stack_count)
{
- qcint *globals = prog->globals + cur->firstlocal;
- if (!qc_program_localstack_append(prog, globals, cur->locals))
+ prog_section_function *cur;
+ cur = prog->stack[prog->stack_count-1].function;
+ if (cur)
+ {
+ qcint *globals = prog->globals + cur->firstlocal;
+ if (!qc_program_localstack_append(prog, globals, cur->locals))
+ {
+ printf("out of memory\n");
+ exit(1);
+ }
+ }
+ }
+#else
+ {
+ qcint *globals = prog->globals + func->firstlocal;
+ if (!qc_program_localstack_append(prog, globals, func->locals))
{
printf("out of memory\n");
exit(1);
}
}
+#endif
+
+ /* copy parameters */
+ parampos = func->firstlocal;
+ for (p = 0; p < func->nargs; ++p)
+ {
+ size_t s;
+ for (s = 0; s < func->argsize[p]; ++s) {
+ prog->globals[parampos] = prog->globals[OFS_PARM0 + 3*p + s];
+ ++parampos;
+ }
+ }
if (!qc_program_stack_add(prog, st)) {
printf("out of memory\n");
static qcint prog_leavefunction(qc_program *prog)
{
+ prog_section_function *prev = NULL;
+ size_t oldsp;
+
qc_exec_stack st = prog->stack[prog->stack_count-1];
- if (!qc_program_stack_remove(prog, prog->stack_count-1)) {
- printf("out of memory\n");
- exit(1);
- }
- if (st.localsp != prog->localstack_count) {
- if (!qc_program_localstack_resize(prog, st.localsp)) {
+#ifdef QCVM_BACKUP_STRATEGY_CALLER_VARS
+ if (prog->stack_count > 1) {
+ prev = prog->stack[prog->stack_count-2].function;
+ oldsp = prog->stack[prog->stack_count-2].localsp;
+ }
+#else
+ prev = prog->stack[prog->stack_count-1].function;
+ oldsp = prog->stack[prog->stack_count-1].localsp;
+#endif
+ if (prev) {
+ qcint *globals = prog->globals + prev->firstlocal;
+ memcpy(globals, prog->localstack + oldsp, prev->locals);
+ if (!qc_program_localstack_resize(prog, oldsp)) {
printf("out of memory\n");
exit(1);
}
}
+ if (!qc_program_stack_remove(prog, prog->stack_count-1)) {
+ printf("out of memory\n");
+ exit(1);
+ }
+
return st.stmt;
}
*/
#if defined(QCVM_EXECUTOR)
+static int qc_print(qc_program *prog)
+{
+ qcany *str = (qcany*)(prog->globals + OFS_PARM0);
+ printf("%s", prog_getstring(prog, str->string));
+ return 0;
+}
+
+static prog_builtin qc_builtins[] = {
+ NULL,
+ &qc_print
+};
+static size_t qc_builtins_count = sizeof(qc_builtins) / sizeof(qc_builtins[0]);
+
int main(int argc, char **argv)
{
size_t i;
exit(1);
}
+ prog->builtins = qc_builtins;
+ prog->builtins_count = qc_builtins_count;
+ prog->builtins_alloc = 0;
+
for (i = 1; i < prog->functions_count; ++i) {
const char *name = prog_getstring(prog, prog->functions[i].name);
printf("Found function: %s\n", name);