diff --git a/include/QF/pr_comp.h b/include/QF/pr_comp.h index 823c42f40..a61cd0f0f 100644 --- a/include/QF/pr_comp.h +++ b/include/QF/pr_comp.h @@ -320,7 +320,7 @@ typedef struct pr_va_list_s { } pr_va_list_t; #define PROG_ID_VERSION 6 -#define PROG_VERSION 0x00fff002 // MMmmmRRR 0.fff.002 (hex) +#define PROG_VERSION 0x00fff003 // MMmmmRRR 0.fff.003 (hex) typedef struct dprograms_s { unsigned int version; diff --git a/include/QF/progs.h b/include/QF/progs.h index 9a57e9538..1f3255f4c 100644 --- a/include/QF/progs.h +++ b/include/QF/progs.h @@ -134,7 +134,7 @@ qboolean PR_EdictValid (progs_t *pr, int e); #define G_GPOINTER(p,o) PR_GetPointer (p, o) #define G_STRUCT(p,t,o) (*(t *)G_GPOINTER (p, o)) -#define P_var(p,n,t) G_var (p, (OFS_PARM0 + (n) * 3), t) +#define P_var(p,n,t) ((p)->pr_params[n]->t##_var) #define P_FLOAT(p,n) P_var (p, n, float) #define P_INT(p,n) P_var (p, n, integer) @@ -150,7 +150,7 @@ qboolean PR_EdictValid (progs_t *pr, int e); #define P_GPOINTER(p,n) PR_GetPointer (p, P_POINTER (p, n)) #define P_STRUCT(p,t,n) (*(t *)P_GPOINTER (p, n)) -#define R_var(p,t) G_var (p, OFS_RETURN, t) +#define R_var(p,t) ((p)->pr_return->t##_var) #define R_FLOAT(p) R_var (p, float) #define R_INT(p) R_var (p, integer) @@ -320,6 +320,10 @@ struct progs_s { pr_type_t *pr_globals; // same as pr_global_struct int globals_size; + pr_type_t *pr_return; + pr_type_t *pr_params[MAX_PARMS]; + int pr_param_size; // covers both params and return + int pr_edict_size; // in bytes int pr_edictareasize; // for bounds checking, starts at 0 diff --git a/libs/gamecode/builtins/pr_cmds.c b/libs/gamecode/builtins/pr_cmds.c index e8e8be481..1c0f65809 100644 --- a/libs/gamecode/builtins/pr_cmds.c +++ b/libs/gamecode/builtins/pr_cmds.c @@ -598,7 +598,7 @@ PF_charcount (progs_t *pr) # define INT_WIDTH 20 #endif -#define MAX_ARG 23 +#define MAX_ARG 7 static void PF_sprintf (progs_t *pr) @@ -611,7 +611,7 @@ PF_sprintf (progs_t *pr) fmt_precision, fmt_signed, fmt_space, fmt_type, looping, ret; size_t new_format_i; - int curarg = 3, out_max = 32, out_size = 0; + int curarg = 1, out_max = 32, out_size = 0; format = P_GSTRING (pr, 0); c = format; @@ -656,7 +656,7 @@ PF_sprintf (progs_t *pr) } else if (*c == '*') { fmt_minwidth = P_INT (pr, 0 + curarg); - curarg += 3; + curarg++; } // precision @@ -672,7 +672,7 @@ PF_sprintf (progs_t *pr) } } else if (*c == '*') { fmt_precision = P_INT (pr, 0 + curarg); - curarg += 3; + curarg++; } } if (!*c) @@ -734,7 +734,7 @@ PF_sprintf (progs_t *pr) out = o; } out_size += ret; - curarg += 3; + curarg++; break; case 'f': while ((ret = snprintf (&out[out_size], out_max - out_size, @@ -749,7 +749,7 @@ PF_sprintf (progs_t *pr) out = o; } out_size += ret; - curarg += 3; + curarg++; break; case 'v': { int i; @@ -758,8 +758,7 @@ PF_sprintf (progs_t *pr) goto maxargs; while ((ret = snprintf (&out[out_size], out_max - out_size, new_format, - P_FLOAT (pr, 0 + - curarg))) + P_VECTOR (pr, 0 + curarg)[i])) >= out_max - out_size) { char *o; out_max *= 2; @@ -769,9 +768,9 @@ PF_sprintf (progs_t *pr) out = o; } out_size += ret; - curarg++; i++; } + curarg++; break; } } @@ -791,7 +790,7 @@ PF_sprintf (progs_t *pr) out = o; } out_size += ret; - curarg += 3; + curarg++; c += 2; } else { if (*c == '%') diff --git a/libs/gamecode/engine/pr_exec.c b/libs/gamecode/engine/pr_exec.c index c6cab4ff9..57947159d 100644 --- a/libs/gamecode/engine/pr_exec.c +++ b/libs/gamecode/engine/pr_exec.c @@ -129,10 +129,9 @@ PR_EnterFunction (progs_t * pr, dfunction_t *f) } argc->integer_var = pr->pr_argc - i; argv->integer_var = o; - while (i < MAX_PARMS) { - memcpy (&pr->pr_globals[o], &P_INT (pr, i), 3); - o += 3; - i++; + if (i < MAX_PARMS) { + memcpy (&pr->pr_globals[o], &P_INT (pr, i), + (MAX_PARMS - i) * pr->pr_param_size * sizeof (pr_type_t)); } } @@ -679,7 +678,7 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum) break; case OP_DONE: case OP_RETURN: - memcpy (&R_INT (pr), &OPA, 3 * sizeof (OPA)); + memcpy (&R_INT (pr), &OPA, pr->pr_param_size * sizeof (OPA)); PR_LeaveFunction (pr); st = pr->pr_statements + pr->pr_xstatement; if (pr->pr_depth == exitdepth) { diff --git a/libs/gamecode/engine/pr_obj.c b/libs/gamecode/engine/pr_obj.c index 36fa3d884..2f27136d8 100644 --- a/libs/gamecode/engine/pr_obj.c +++ b/libs/gamecode/engine/pr_obj.c @@ -359,7 +359,7 @@ pr_obj_msg_sendv (progs_t *pr) if (args.count > 6) args.count = 6; memcpy (P_GPOINTER (pr, 2), G_GPOINTER (pr, args.list), - args.count * 4 * 3); + args.count * 4 * pr->pr_param_size); call_function (pr, imp); } diff --git a/libs/gamecode/engine/pr_resolve.c b/libs/gamecode/engine/pr_resolve.c index bc133e0e1..01bd62ecc 100644 --- a/libs/gamecode/engine/pr_resolve.c +++ b/libs/gamecode/engine/pr_resolve.c @@ -164,7 +164,32 @@ PR_ResolveGlobals (progs_t *pr) { const char *sym; ddef_t *def; + int i; + if (pr->progs->version == PROG_ID_VERSION) { + pr->pr_return = &pr->pr_globals[OFS_RETURN]; + pr->pr_params[0] = &pr->pr_globals[OFS_PARM0]; + pr->pr_params[1] = &pr->pr_globals[OFS_PARM1]; + pr->pr_params[2] = &pr->pr_globals[OFS_PARM2]; + pr->pr_params[3] = &pr->pr_globals[OFS_PARM3]; + pr->pr_params[4] = &pr->pr_globals[OFS_PARM4]; + pr->pr_params[5] = &pr->pr_globals[OFS_PARM5]; + pr->pr_params[6] = &pr->pr_globals[OFS_PARM6]; + pr->pr_params[7] = &pr->pr_globals[OFS_PARM7]; + pr->pr_param_size = OFS_PARM1 - OFS_PARM0; + } else { + if (!(def = PR_FindGlobal (pr, sym = ".return"))) + goto error; + pr->pr_return = &pr->pr_globals[def->ofs]; + for (i = 0; i < MAX_PARMS; i++) { + if (!(def = PR_FindGlobal (pr, sym = va(".param_%d", i)))) + goto error; + pr->pr_params[i] = &pr->pr_globals[def->ofs]; + } + if (!(def = PR_FindGlobal (pr, sym = ".param_size"))) + goto error; + pr->pr_param_size = G_INT (pr, def->ofs); + } if (!(def = PR_FindGlobal (pr, sym = "time"))) goto error; pr->globals.time = &G_FLOAT (pr, def->ofs); diff --git a/tools/qfcc/include/type.h b/tools/qfcc/include/type.h index 911869eee..f36dd423f 100644 --- a/tools/qfcc/include/type.h +++ b/tools/qfcc/include/type.h @@ -73,8 +73,8 @@ extern type_t *type_category; extern type_t *type_ivar; extern type_t *type_module; extern type_t type_va_list; -extern type_t *type_param; -extern type_t *type_zero; +extern type_t type_param; +extern type_t type_zero; extern type_t *vector_struct; diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index b265953e1..dfad07d53 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -671,7 +671,7 @@ new_this_expr (void) static expr_t * param_expr (const char *name, type_t *type) { - def_t *def = get_def (type_param, name, pr.scope, st_extern);; + def_t *def = get_def (&type_param, name, pr.scope, st_extern);; expr_t *def_expr; def_initialized (def); diff --git a/tools/qfcc/source/immediate.c b/tools/qfcc/source/immediate.c index 0d1bcc650..4e954d596 100644 --- a/tools/qfcc/source/immediate.c +++ b/tools/qfcc/source/immediate.c @@ -345,7 +345,7 @@ clear_immediates (void) } imm = calloc (1, sizeof (immediate_t)); - imm->def = get_def (type_zero, ".zero", pr.scope, st_extern); + imm->def = get_def (&type_zero, ".zero", pr.scope, st_extern); Hash_AddElement (string_imm_defs, imm); Hash_AddElement (float_imm_defs, imm); diff --git a/tools/qfcc/source/linker.c b/tools/qfcc/source/linker.c index 1377cc9f4..806047cc0 100644 --- a/tools/qfcc/source/linker.c +++ b/tools/qfcc/source/linker.c @@ -91,22 +91,20 @@ typedef union defref_s { typedef struct builtin_sym_s { const char *name; - etype_t basic_type; - const char *full_type; - int size; + type_t *type; } builtin_sym_t; static builtin_sym_t builtin_symbols[] = { - {".zero", ev_struct, "{-*fEFv(v)^viI}", 1}, - {".return", ev_struct, "{-*fVEFv(v)^viI}", 3}, - {".param_0", ev_struct, "{-*fVEFv(v)^viI}", 3}, - {".param_1", ev_struct, "{-*fVEFv(v)^viI}", 3}, - {".param_2", ev_struct, "{-*fVEFv(v)^viI}", 3}, - {".param_3", ev_struct, "{-*fVEFv(v)^viI}", 3}, - {".param_4", ev_struct, "{-*fVEFv(v)^viI}", 3}, - {".param_5", ev_struct, "{-*fVEFv(v)^viI}", 3}, - {".param_6", ev_struct, "{-*fVEFv(v)^viI}", 3}, - {".param_7", ev_struct, "{-*fVEFv(v)^viI}", 3}, + {".zero", &type_zero}, + {".return", &type_param}, + {".param_0", &type_param}, + {".param_1", &type_param}, + {".param_2", &type_param}, + {".param_3", &type_param}, + {".param_4", &type_param}, + {".param_5", &type_param}, + {".param_6", &type_param}, + {".param_7", &type_param}, }; static defref_t *free_defrefs; @@ -704,12 +702,18 @@ linker_begin (void) pr.strings = strings; if (!options.partial_link) { + dstring_t *encoding = dstring_new (); + for (i = 0; i < sizeof (builtin_symbols) / sizeof (builtin_symbols[0]); i++) { - define_def (builtin_symbols[i].name, builtin_symbols[i].basic_type, - builtin_symbols[i].full_type, builtin_symbols[i].size, - 0); + etype_t basic_type = builtin_symbols[i].type->type; + int size = type_size (builtin_symbols[i].type); + + dstring_clearstr (encoding); + encode_type (encoding, builtin_symbols[i].type); + define_def (builtin_symbols[i].name, basic_type, encoding->str, + size, 0); } } } diff --git a/tools/qfcc/source/qfcc.c b/tools/qfcc/source/qfcc.c index 55a78c454..e60978a0c 100644 --- a/tools/qfcc/source/qfcc.c +++ b/tools/qfcc/source/qfcc.c @@ -349,16 +349,16 @@ begin_compilation (void) static void setup_param_block (void) { - def_initialized (get_def (type_zero, ".zero", pr.scope, st_global)); - def_initialized (get_def (type_param, ".return", pr.scope, st_global)); - def_initialized (get_def (type_param, ".param_0", pr.scope, st_global)); - def_initialized (get_def (type_param, ".param_1", pr.scope, st_global)); - def_initialized (get_def (type_param, ".param_2", pr.scope, st_global)); - def_initialized (get_def (type_param, ".param_3", pr.scope, st_global)); - def_initialized (get_def (type_param, ".param_4", pr.scope, st_global)); - def_initialized (get_def (type_param, ".param_5", pr.scope, st_global)); - def_initialized (get_def (type_param, ".param_6", pr.scope, st_global)); - def_initialized (get_def (type_param, ".param_7", pr.scope, st_global)); + def_initialized (get_def (&type_zero, ".zero", pr.scope, st_global)); + def_initialized (get_def (&type_param, ".return", pr.scope, st_global)); + def_initialized (get_def (&type_param, ".param_0", pr.scope, st_global)); + def_initialized (get_def (&type_param, ".param_1", pr.scope, st_global)); + def_initialized (get_def (&type_param, ".param_2", pr.scope, st_global)); + def_initialized (get_def (&type_param, ".param_3", pr.scope, st_global)); + def_initialized (get_def (&type_param, ".param_4", pr.scope, st_global)); + def_initialized (get_def (&type_param, ".param_5", pr.scope, st_global)); + def_initialized (get_def (&type_param, ".param_6", pr.scope, st_global)); + def_initialized (get_def (&type_param, ".param_7", pr.scope, st_global)); } static qboolean @@ -395,6 +395,13 @@ finish_compilation (void) if (errors) return !errors; + if (!options.traditional) { + e.type = ex_integer; + e.e.integer_val = type_size (&type_param); + ReuseConstant (&e, get_def (&type_integer, ".param_size", pr.scope, + st_global)); + } + if (options.code.debug) { e.type = ex_string; e.e.string_val = debugfile; diff --git a/tools/qfcc/source/type.c b/tools/qfcc/source/type.c index 3569a0fcc..9ff0ffa4a 100644 --- a/tools/qfcc/source/type.c +++ b/tools/qfcc/source/type.c @@ -92,8 +92,8 @@ type_t *type_category; type_t *type_ivar; type_t *type_module; type_t type_va_list; -type_t *type_param; -type_t *type_zero; +type_t type_param; +type_t type_zero; type_t *vector_struct; @@ -594,7 +594,8 @@ init_types (void) { type_t *type; - type = type_zero = new_union (0); + init_struct (malloc (sizeof (struct_t)), type = &type_zero, 0); + ((struct_t *) type->class)->is_union = 1; new_struct_field (type, &type_string, "string_val", vis_public); new_struct_field (type, &type_float, "float_val", vis_public); new_struct_field (type, &type_entity, "entity_val", vis_public); @@ -604,7 +605,8 @@ init_types (void) new_struct_field (type, &type_integer, "integer_val", vis_public); new_struct_field (type, &type_uinteger, "uinteger_val", vis_public); - type = type_param = new_union (0); + init_struct (malloc (sizeof (struct_t)), type = &type_param, 0); + ((struct_t *) type->class)->is_union = 1; new_struct_field (type, &type_string, "string_val", vis_public); new_struct_field (type, &type_float, "float_val", vis_public); new_struct_field (type, &type_vector, "vector_val", vis_public); @@ -680,7 +682,7 @@ init_types (void) init_struct (malloc (sizeof (struct_t)), &type_va_list, 0); new_struct_field (&type_va_list, &type_integer, "count", vis_public); - new_struct_field (&type_va_list, pointer_type (type_param), "list", + new_struct_field (&type_va_list, pointer_type (&type_param), "list", vis_public); #if 0 type = type_module = new_struct ("obj_module_t"); @@ -704,8 +706,8 @@ chain_initial_types (void) chain_type (&type_pointer); chain_type (&type_floatfield); - chain_type (type_param); - chain_type (type_zero); + chain_type (&type_param); + chain_type (&type_zero); if (options.traditional) return; diff --git a/tools/qwaq/builtins.c b/tools/qwaq/builtins.c index 6e6f7f417..7653fa24a 100644 --- a/tools/qwaq/builtins.c +++ b/tools/qwaq/builtins.c @@ -152,16 +152,19 @@ bi_printf (progs_t *pr) if (c == '%' && count < 7) { switch (c = *fmt++) { case 'i': - fprintf (stdout, "%i", P_INT (pr, 1 + count++ * 3)); + fprintf (stdout, "%i", + P_INT (pr, 1 + count++ * pr->pr_param_size)); break; case 'f': - fprintf (stdout, "%f", P_FLOAT (pr, 1 + count++ * 3)); + fprintf (stdout, "%f", + P_FLOAT (pr, 1 + count++ * pr->pr_param_size)); break; case 's': - fputs (P_GSTRING (pr, 1 + count++ * 3), stdout); + fputs (P_GSTRING (pr, 1 + count++ * pr->pr_param_size), + stdout); break; case 'v': - v = P_VECTOR (pr, 1 + count++ * 3); + v = P_VECTOR (pr, 1 + count++ * pr->pr_param_size); fprintf (stdout, "'%f %f %f'", v[0], v[1], v[2]); break; default: