X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=exec.c;h=e792affd0bf3d61f8d6ac20e4b05e48357a6f0a6;hb=6cbc0a84d7c876a1fbd29b412d516c72d7b661d8;hp=b957a83a8722401f76a7e8f723e13f36661844f6;hpb=b36fabe4d76fce6c1bc8ab1e3c40fe33165747ce;p=xonotic%2Fgmqcc.git diff --git a/exec.c b/exec.c index b957a83..e792aff 100644 --- a/exec.c +++ b/exec.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -35,9 +36,12 @@ static void loaderror(const char *fmt, ...) printf(": %s\n", strerror(err)); } -static void printvmerr(const char *fmt, ...) +static void qcvmerror(qc_program *prog, const char *fmt, ...) { va_list ap; + + prog->vmerror++; + va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); @@ -51,7 +55,7 @@ qc_program* prog_load(const char *filename) size_t i; FILE *file; - file = fopen(filename, "rb"); + file = util_fopen(filename, "rb"); if (!file) return NULL; @@ -76,6 +80,7 @@ qc_program* prog_load(const char *filename) memset(prog, 0, sizeof(*prog)); prog->entityfields = header.entfield; + prog->crc16 = header.crc16; prog->filename = util_strdup(filename); if (!prog->filename) { @@ -316,13 +321,15 @@ static int print_escaped_string(const char *str) static void trace_print_global(qc_program *prog, unsigned int glob, int vtype) { - static char spaces[16+1] = " "; + static char spaces[40+1] = " "; prog_section_def *def; qcany *value; int len; - if (!glob) - return; + if (!glob) { + len = printf(","); + goto done; + } def = prog_getdef(prog, glob); value = (qcany*)(&prog->globals[glob]); @@ -349,6 +356,7 @@ static void trace_print_global(qc_program *prog, unsigned int glob, int vtype) break; case TYPE_STRING: len += print_escaped_string(prog_getstring(prog, value->string)); + len += printf(","); /* len += printf("\"%s\",", prog_getstring(prog, value->string)); */ break; case TYPE_FLOAT: @@ -356,10 +364,11 @@ static void trace_print_global(qc_program *prog, unsigned int glob, int vtype) len += printf("%g,", value->_float); break; } - if (len < 16) { - spaces[16-len] = 0; +done: + if (len < sizeof(spaces)-1) { + spaces[sizeof(spaces)-1-len] = 0; printf(spaces); - spaces[16-len] = ' '; + spaces[sizeof(spaces)-1-len] = ' '; } } @@ -409,18 +418,50 @@ static void prog_print_statement(qc_program *prog, prog_section_statement *st) case INSTR_NE_S: t[0] = t[1] = TYPE_STRING; break; + case INSTR_STORE_F: + case INSTR_STOREP_F: + t[2] = -1; + break; case INSTR_STORE_V: t[0] = t[1] = TYPE_VECTOR; t[2] = -1; break; case INSTR_STORE_S: t[0] = t[1] = TYPE_STRING; t[2] = -1; break; + case INSTR_STORE_ENT: + t[0] = t[1] = TYPE_ENTITY; t[2] = -1; + break; + case INSTR_STORE_FLD: + t[0] = t[1] = TYPE_FIELD; t[2] = -1; + break; + case INSTR_STORE_FNC: + t[0] = t[1] = TYPE_FUNCTION; t[2] = -1; + break; + case INSTR_STOREP_V: + t[0] = TYPE_VECTOR; t[1] = TYPE_ENTITY; t[2] = -1; + break; + case INSTR_STOREP_S: + t[0] = TYPE_STRING; t[1] = TYPE_ENTITY; t[2] = -1; + break; + case INSTR_STOREP_ENT: + t[0] = TYPE_ENTITY; t[1] = TYPE_ENTITY; t[2] = -1; + break; + case INSTR_STOREP_FLD: + t[0] = TYPE_FIELD; t[1] = TYPE_ENTITY; t[2] = -1; + break; + case INSTR_STOREP_FNC: + t[0] = TYPE_FUNCTION; t[1] = TYPE_ENTITY; t[2] = -1; + break; } if (t[0] >= 0) trace_print_global(prog, st->o1.u1, t[0]); + else printf("(none), "); if (t[1] >= 0) trace_print_global(prog, st->o2.u1, t[1]); + else printf("(none), "); if (t[2] >= 0) trace_print_global(prog, st->o3.u1, t[2]); + else printf("(none)"); printf("\n"); } + fflush(stdout); } static qcint prog_enterfunction(qc_program *prog, prog_section_function *func) @@ -508,7 +549,7 @@ static qcint prog_leavefunction(qc_program *prog) exit(1); } - return st.stmt; + return st.stmt - 1; /* offset the ++st */ } bool prog_exec(qc_program *prog, prog_section_function *func, size_t flags, long maxjumps) @@ -566,6 +607,21 @@ cleanup: */ #if defined(QCVM_EXECUTOR) +const char *type_name[TYPE_COUNT] = { + "void", + "string", + "float", + "vector", + "entity", + "field", + "function", + "pointer", +#if 0 + "integer", +#endif + "variant" +}; + bool opts_debug = false; bool opts_memchk = false; @@ -605,6 +661,19 @@ static int qc_ftos(qc_program *prog) return 0; } +static int qc_vtos(qc_program *prog) +{ + char buffer[512]; + qcany *num; + qcany str; + CheckArgs(1); + num = GetArg(0); + snprintf(buffer, sizeof(buffer), "`%g %g %g`", num->vector[0], num->vector[1], num->vector[2]); + str.string = prog_tempstring(prog, buffer); + Return(str); + return 0; +} + static int qc_spawn(qc_program *prog) { qcany ent; @@ -628,21 +697,65 @@ static prog_builtin qc_builtins[] = { &qc_print, &qc_ftos, &qc_spawn, - &qc_kill + &qc_kill, + &qc_vtos, }; static size_t qc_builtins_count = sizeof(qc_builtins) / sizeof(qc_builtins[0]); +static const char *arg0 = NULL; + +void usage() +{ + printf("usage: [-debug] %s file\n", arg0); + exit(1); +} + int main(int argc, char **argv) { size_t i; qcint fnmain = -1; qc_program *prog; + size_t xflags = VMXF_DEFAULT; + bool opts_printfields = false; + bool opts_printdefs = false; + bool opts_info = false; - if (argc != 2) { - printf("usage: %s file\n", argv[0]); - exit(1); + arg0 = argv[0]; + + if (argc < 2) + usage(); + + while (argc > 2) { + if (!strcmp(argv[1], "-trace")) { + --argc; + ++argv; + xflags |= VMXF_TRACE; + } + else if (!strcmp(argv[1], "-profile")) { + --argc; + ++argv; + xflags |= VMXF_PROFILE; + } + else if (!strcmp(argv[1], "-info")) { + --argc; + ++argv; + opts_info = true; + } + else if (!strcmp(argv[1], "-printdefs")) { + --argc; + ++argv; + opts_printdefs = true; + } + else if (!strcmp(argv[1], "-printfields")) { + --argc; + ++argv; + opts_printfields = true; + } + else + usage(); } + prog = prog_load(argv[1]); if (!prog) { printf("failed to load program '%s'\n", argv[1]); @@ -653,19 +766,44 @@ int main(int argc, char **argv) prog->builtins_count = qc_builtins_count; prog->builtins_alloc = 0; + printf("Program's system-checksum = 0x%04x\n", (int)prog->crc16); + for (i = 1; i < prog->functions_count; ++i) { const char *name = prog_getstring(prog, prog->functions[i].name); - printf("Found function: %s\n", name); + /* printf("Found function: %s\n", name); */ if (!strcmp(name, "main")) fnmain = (qcint)i; } printf("Entity field space: %i\n", (int)prog->entityfields); - if (fnmain > 0) - { - prog_exec(prog, &prog->functions[fnmain], VMXF_TRACE, VM_JUMPS_DEFAULT); + if (opts_info) { + prog_delete(prog); + return 0; + } + if (opts_printdefs) { + for (i = 0; i < prog->defs_count; ++i) { + printf("Global: %8s %-16s at %u\n", + type_name[prog->defs[i].type], + prog_getstring(prog, prog->defs[i].name), + (unsigned int)prog->defs[i].offset); + } + } + else if (opts_printfields) { + for (i = 0; i < prog->fields_count; ++i) { + printf("Field: %8s %-16s at %u\n", + type_name[prog->fields[i].type], + prog_getstring(prog, prog->fields[i].name), + (unsigned int)prog->fields[i].offset); + } } else - printf("No main function found\n"); + { + if (fnmain > 0) + { + prog_exec(prog, &prog->functions[fnmain], xflags, VM_JUMPS_DEFAULT); + } + else + printf("No main function found\n"); + } prog_delete(prog); return 0;