From 28ce35f1c1dbc0dbcf524bfaad0ed338d3f8d225 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 18 Jul 2012 23:01:09 +0900 Subject: [PATCH] Make values independent objects. values are now uniquely allocated (for the current object file). With this, constants in dags will work. --- tools/qfcc/include/expr.h | 3 +- tools/qfcc/include/symtab.h | 2 +- tools/qfcc/include/value.h | 22 ++++ tools/qfcc/source/constfold.c | 2 +- tools/qfcc/source/def.c | 26 ++--- tools/qfcc/source/dot_expr.c | 42 ++++---- tools/qfcc/source/emit.c | 2 +- tools/qfcc/source/expr.c | 181 ++++++++++++++------------------- tools/qfcc/source/obj_type.c | 2 +- tools/qfcc/source/statements.c | 16 +-- tools/qfcc/source/struct.c | 10 +- tools/qfcc/source/switch.c | 4 +- tools/qfcc/source/value.c | 162 ++++++++++++++++++++++++++++- 13 files changed, 317 insertions(+), 157 deletions(-) diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index 7ae7b55bf..05e8b07c5 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -157,6 +157,7 @@ typedef struct { } ex_state_t; typedef struct ex_value_s { + struct ex_value_s *next; etype_t type; union { const char *string_val; ///< string constant @@ -191,7 +192,7 @@ typedef struct expr_s { ex_expr_t expr; ///< binary or unary expression struct symbol_s *symbol; ///< symbol reference expression ex_temp_t temp; ///< temporary variable expression - ex_value_t value; ///< constant value + ex_value_t *value; ///< constant value } e; } expr_t; diff --git a/tools/qfcc/include/symtab.h b/tools/qfcc/include/symtab.h index 083d34d7b..fbe8cb9c5 100644 --- a/tools/qfcc/include/symtab.h +++ b/tools/qfcc/include/symtab.h @@ -68,7 +68,7 @@ typedef struct symbol_s { union { int offset; ///< st_var (in a struct/union) struct def_s *def; ///< st_var - struct ex_value_s value; ///< st_const + struct ex_value_s *value; ///< st_const struct expr_s *expr; ///< st_expr struct function_s *func; ///< st_func } s; diff --git a/tools/qfcc/include/value.h b/tools/qfcc/include/value.h index f884f9bca..95be55212 100644 --- a/tools/qfcc/include/value.h +++ b/tools/qfcc/include/value.h @@ -31,9 +31,29 @@ #ifndef __value_h #define __value_h +/** \defgroup qfcc_value Constant values. + \ingroup qfcc_expr +*/ +//@{ + struct ex_value_s; struct type_s; +struct ex_value_s *new_string_val (const char *string_val); +struct ex_value_s *new_float_val (float float_val); +struct ex_value_s *new_vector_val (const float *vector_val); +struct ex_value_s *new_entity_val (int entity_val); +struct ex_value_s *new_field_val (int field_val, struct type_s *type, + struct def_s *def); +struct ex_value_s *new_func_val (int func_val); +struct ex_value_s *new_pointer_val (int val, struct type_s *type, + struct def_s *def); +struct ex_value_s *new_quaternion_val (const float *quaternion_val); +struct ex_value_s *new_integer_val (int integer_val); +struct ex_value_s *new_uinteger_val (int uinteger_val); +struct ex_value_s *new_short_val (short short_val); +struct ex_value_s *new_nil_val (struct type_s *type); + void convert_value (struct ex_value_s *value, struct type_s *type); struct def_s *emit_value (struct ex_value_s *value, struct def_s *def); @@ -41,4 +61,6 @@ int ReuseString (const char *str); void clear_immediates (void); +//@} + #endif//__value_h diff --git a/tools/qfcc/source/constfold.c b/tools/qfcc/source/constfold.c index ec38f9daa..6198df948 100644 --- a/tools/qfcc/source/constfold.c +++ b/tools/qfcc/source/constfold.c @@ -140,7 +140,7 @@ convert_to_float (expr_t *e) switch (e->type) { case ex_value: - switch (e->e.value.type) { + switch (e->e.value->type) { case ev_integer: convert_int (e); return e; diff --git a/tools/qfcc/source/def.c b/tools/qfcc/source/def.c index a710626a5..4a5087fba 100644 --- a/tools/qfcc/source/def.c +++ b/tools/qfcc/source/def.c @@ -284,7 +284,7 @@ init_elements (struct def_s *def, expr_t *eles) reloc_def_op (c->e.labelref.label, &loc); continue; } else if (c->type == ex_value) { - if (c->e.value.type == ev_integer + if (c->e.value->type == ev_integer && elements[i].type->type == ev_float) convert_int (c); if (get_type (c) != elements[i].type) { @@ -306,11 +306,11 @@ init_elements (struct def_s *def, expr_t *eles) } else { if (c->type != ex_value) internal_error (c, "bogus expression type in init_elements()"); - if (c->e.value.type == ev_string) { + if (c->e.value->type == ev_string) { EMIT_STRING (def->space, g->string_var, - c->e.value.v.string_val); + c->e.value->v.string_val); } else { - memcpy (g, &c->e.value.v, type_size (get_type (c)) * 4); + memcpy (g, &c->e.value->v, type_size (get_type (c)) * 4); } } } @@ -341,12 +341,12 @@ init_vector_components (symbol_t *vector_sym, int is_field) expr = sym->s.expr; if (is_field) { if (expr->type != ex_value - || expr->e.value.type != ev_field) { + || expr->e.value->type != ev_field) { error (0, "%s redefined", name); sym = 0; } else { - expr->e.value.v.pointer.def = vector_sym->s.def; - expr->e.value.v.pointer.val = i; + expr->e.value->v.pointer.def = vector_sym->s.def; + expr->e.value->v.pointer.val = i; } } } @@ -505,14 +505,14 @@ initialize_def (symbol_t *sym, type_t *type, expr_t *init, defspace_t *space, error (0, "non-constant initializier"); return; } - if (init->e.value.type == ev_pointer - || init->e.value.type == ev_field) { + if (init->e.value->type == ev_pointer + || init->e.value->type == ev_field) { // FIXME offset pointers - D_INT (sym->s.def) = init->e.value.v.pointer.val; - if (init->e.value.v.pointer.def) - reloc_def_field (init->e.value.v.pointer.def, sym->s.def); + D_INT (sym->s.def) = init->e.value->v.pointer.val; + if (init->e.value->v.pointer.def) + reloc_def_field (init->e.value->v.pointer.def, sym->s.def); } else { - ex_value_t v = init->e.value; + ex_value_t v = *init->e.value; if (is_scalar (sym->type)) convert_value (&v, sym->type); if (v.type == ev_string) { diff --git a/tools/qfcc/source/dot_expr.c b/tools/qfcc/source/dot_expr.c index 52982839f..bf1cb4e96 100644 --- a/tools/qfcc/source/dot_expr.c +++ b/tools/qfcc/source/dot_expr.c @@ -305,55 +305,55 @@ print_value (expr_t *e, int level, int id) type_t *type; const char *label = "?!?"; - switch (e->e.value.type) { + switch (e->e.value->type) { case ev_string: - label = va ("\\\"%s\\\"", e->e.value.v.string_val); + label = va ("\\\"%s\\\"", e->e.value->v.string_val); break; case ev_float: - label = va ("%g", e->e.value.v.float_val); + label = va ("%g", e->e.value->v.float_val); break; case ev_vector: label = va ("'%g %g %g'", - e->e.value.v.vector_val[0], - e->e.value.v.vector_val[1], - e->e.value.v.vector_val[2]); + e->e.value->v.vector_val[0], + e->e.value->v.vector_val[1], + e->e.value->v.vector_val[2]); break; case ev_quat: label = va ("'%g %g %g %g'", - e->e.value.v.quaternion_val[0], - e->e.value.v.quaternion_val[1], - e->e.value.v.quaternion_val[2], - e->e.value.v.quaternion_val[3]); + e->e.value->v.quaternion_val[0], + e->e.value->v.quaternion_val[1], + e->e.value->v.quaternion_val[2], + e->e.value->v.quaternion_val[3]); break; case ev_pointer: - type = e->e.value.v.pointer.type; - if (e->e.value.v.pointer.def) + type = e->e.value->v.pointer.type; + if (e->e.value->v.pointer.def) label = va ("(%s)[%d]<%s>", type ? pr_type_name[type->type] : "???", - e->e.value.v.pointer.val, - e->e.value.v.pointer.def->name); + e->e.value->v.pointer.val, + e->e.value->v.pointer.def->name); else label = va ("(%s)[%d]", type ? pr_type_name[type->type] : "???", - e->e.value.v.pointer.val); + e->e.value->v.pointer.val); break; case ev_field: - label = va ("field %d", e->e.value.v.pointer.val); + label = va ("field %d", e->e.value->v.pointer.val); break; case ev_entity: - label = va ("ent %d", e->e.value.v.integer_val); + label = va ("ent %d", e->e.value->v.integer_val); break; case ev_func: - label = va ("func %d", e->e.value.v.integer_val); + label = va ("func %d", e->e.value->v.integer_val); break; case ev_integer: - label = va ("%d", e->e.value.v.integer_val); + label = va ("%d", e->e.value->v.integer_val); break; case ev_uinteger: - label = va ("%u", e->e.value.v.uinteger_val); + label = va ("%u", e->e.value->v.uinteger_val); break; case ev_short: - label = va ("%d", e->e.value.v.short_val); + label = va ("%d", e->e.value->v.short_val); break; case ev_void: label = ""; diff --git a/tools/qfcc/source/emit.c b/tools/qfcc/source/emit.c index 800653994..e8cfc2a9b 100644 --- a/tools/qfcc/source/emit.c +++ b/tools/qfcc/source/emit.c @@ -94,7 +94,7 @@ get_operand_def (expr_t *expr, operand_t *op) case sy_func: return op->o.symbol->s.func->def; case sy_const: - return get_value_def (&op->o.symbol->s.value, op->type); + return get_value_def (op->o.symbol->s.value, op->type); case sy_type: case sy_expr: case sy_class: diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 00a27a631..e6e0f00ee 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -60,6 +60,7 @@ #include "struct.h" #include "symtab.h" #include "type.h" +#include "value.h" #include "qc-parse.h" static expr_t *free_exprs; @@ -164,16 +165,16 @@ get_type (expr_t *e) case ex_temp: return e->e.temp.type; case ex_value: - if (e->e.value.type == ev_pointer) - return pointer_type (e->e.value.v.pointer.type); - if (e->e.value.type == ev_field) - return field_type (e->e.value.v.pointer.type); - if (e->e.value.type == ev_integer + if (e->e.value->type == ev_pointer) + return pointer_type (e->e.value->v.pointer.type); + if (e->e.value->type == ev_field) + return field_type (e->e.value->v.pointer.type); + if (e->e.value->type == ev_integer && options.code.progsversion == PROG_ID_VERSION) { - e->e.value.type = ev_float; - e->e.value.v.float_val = e->e.value.v.integer_val; + e->e.value->type = ev_float; + e->e.value->v.float_val = e->e.value->v.integer_val; } - return ev_types[e->e.value.type]; + return ev_types[e->e.value->type]; } return 0; } @@ -511,8 +512,7 @@ new_string_expr (const char *string_val) { expr_t *e = new_expr (); e->type = ex_value; - e->e.value.type = ev_string; - e->e.value.v.string_val = string_val; + e->e.value = new_string_val (string_val); return e; } @@ -521,8 +521,7 @@ new_float_expr (float float_val) { expr_t *e = new_expr (); e->type = ex_value; - e->e.value.type = ev_float; - e->e.value.v.float_val = float_val; + e->e.value = new_float_val (float_val); return e; } @@ -531,8 +530,7 @@ new_vector_expr (const float *vector_val) { expr_t *e = new_expr (); e->type = ex_value; - e->e.value.type = ev_vector; - VectorCopy (vector_val, e->e.value.v.vector_val); + e->e.value = new_vector_val (vector_val); return e; } @@ -541,8 +539,7 @@ new_entity_expr (int entity_val) { expr_t *e = new_expr (); e->type = ex_value; - e->e.value.type = ev_entity; - e->e.value.v.entity_val = entity_val; + e->e.value = new_entity_val (entity_val); return e; } @@ -551,10 +548,7 @@ new_field_expr (int field_val, type_t *type, def_t *def) { expr_t *e = new_expr (); e->type = ex_value; - e->e.value.type = ev_field; - e->e.value.v.pointer.val = field_val; - e->e.value.v.pointer.type = type; - e->e.value.v.pointer.def = def; + e->e.value = new_field_val (field_val, type, def); return e; } @@ -563,8 +557,7 @@ new_func_expr (int func_val) { expr_t *e = new_expr (); e->type = ex_value; - e->e.value.type = ev_func; - e->e.value.v.func_val = func_val; + e->e.value = new_func_val (func_val); return e; } @@ -573,10 +566,7 @@ new_pointer_expr (int val, type_t *type, def_t *def) { expr_t *e = new_expr (); e->type = ex_value; - e->e.value.type = ev_pointer; - e->e.value.v.pointer.val = val; - e->e.value.v.pointer.type = type; - e->e.value.v.pointer.def = def; + e->e.value = new_pointer_val (val, type, def); return e; } @@ -585,8 +575,7 @@ new_quaternion_expr (const float *quaternion_val) { expr_t *e = new_expr (); e->type = ex_value; - e->e.value.type = ev_quat; - QuatCopy (quaternion_val, e->e.value.v.quaternion_val); + e->e.value = new_quaternion_val (quaternion_val); return e; } @@ -595,8 +584,7 @@ new_integer_expr (int integer_val) { expr_t *e = new_expr (); e->type = ex_value; - e->e.value.type = ev_integer; - e->e.value.v.integer_val = integer_val; + e->e.value = new_integer_val (integer_val); return e; } @@ -605,8 +593,7 @@ new_uinteger_expr (unsigned uinteger_val) { expr_t *e = new_expr (); e->type = ex_value; - e->e.value.type = ev_uinteger; - e->e.value.v.uinteger_val = uinteger_val; + e->e.value = new_uinteger_val (uinteger_val); return e; } @@ -615,8 +602,7 @@ new_short_expr (short short_val) { expr_t *e = new_expr (); e->type = ex_value; - e->e.value.type = ev_short; - e->e.value.v.short_val = short_val; + e->e.value = new_short_val (short_val); return e; } @@ -636,7 +622,7 @@ constant_expr (expr_t *e) { expr_t *new; symbol_t *sym; - ex_value_t value; + ex_value_t *value; if (!is_constant (e)) return e; @@ -649,9 +635,10 @@ constant_expr (expr_t *e) value = sym->s.value; } else if (sym->sy_type == sy_var && sym->s.def->constant) { //FIXME pointers and fields - memset (&value, 0, sizeof (value)); - memcpy (&value.v, &D_INT (sym->s.def), - type_size (sym->s.def->type) * sizeof (pr_type_t)); + internal_error (e, "what to do here?"); + //memset (&value, 0, sizeof (value)); + //memcpy (&value.v, &D_INT (sym->s.def), + //type_size (sym->s.def->type) * sizeof (pr_type_t)); } else { return e; } @@ -668,7 +655,7 @@ is_string_val (expr_t *e) { if (e->type == ex_nil) return 1; - if (e->type == ex_value && e->e.value.type == ev_string) + if (e->type == ex_value && e->e.value->type == ev_string) return 1; if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const && e->e.symbol->type->type == ev_string) @@ -681,11 +668,8 @@ expr_string (expr_t *e) { if (e->type == ex_nil) return 0; - if (e->type == ex_value && e->e.value.type == ev_string) - return e->e.value.v.string_val; - //if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const - // && e->e.symbol->type->type == ev_string) - // return e->e.symbol->s.value; + if (e->type == ex_value && e->e.value->type == ev_string) + return e->e.value->v.string_val; internal_error (e, "not a string constant"); } @@ -694,7 +678,7 @@ is_float_val (expr_t *e) { if (e->type == ex_nil) return 1; - if (e->type == ex_value && e->e.value.type == ev_float) + if (e->type == ex_value && e->e.value->type == ev_float) return 1; if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const && e->e.symbol->type->type == ev_float) @@ -707,11 +691,11 @@ expr_float (expr_t *e) { if (e->type == ex_nil) return 0; - if (e->type == ex_value && e->e.value.type == ev_float) - return e->e.value.v.float_val; + if (e->type == ex_value && e->e.value->type == ev_float) + return e->e.value->v.float_val; if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const && e->e.symbol->type->type == ev_float) - return e->e.symbol->s.value.v.float_val; + return e->e.symbol->s.value->v.float_val; if (e->type == ex_symbol && e->e.symbol->sy_type == sy_var && e->e.symbol->s.def->constant && is_float (e->e.symbol->s.def->type)) @@ -724,7 +708,7 @@ is_vector_val (expr_t *e) { if (e->type == ex_nil) return 1; - if (e->type == ex_value && e->e.value.type == ev_vector) + if (e->type == ex_value && e->e.value->type == ev_vector) return 1; if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const && e->e.symbol->type->type == ev_vector) @@ -737,11 +721,11 @@ expr_vector (expr_t *e) { if (e->type == ex_nil) return vec3_origin; - if (e->type == ex_value && e->e.value.type == ev_vector) - return e->e.value.v.vector_val; + if (e->type == ex_value && e->e.value->type == ev_vector) + return e->e.value->v.vector_val; if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const && e->e.symbol->type->type == ev_vector) - return e->e.symbol->s.value.v.vector_val; + return e->e.symbol->s.value->v.vector_val; if (e->type == ex_symbol && e->e.symbol->sy_type == sy_var && e->e.symbol->s.def->constant && e->e.symbol->s.def->type->type == ev_vector) @@ -754,7 +738,7 @@ is_quaternion_val (expr_t *e) { if (e->type == ex_nil) return 1; - if (e->type == ex_value && e->e.value.type == ev_quat) + if (e->type == ex_value && e->e.value->type == ev_quat) return 1; if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const && e->e.symbol->type->type == ev_quat) @@ -767,11 +751,11 @@ expr_quaternion (expr_t *e) { if (e->type == ex_nil) return quat_origin; - if (e->type == ex_value && e->e.value.type == ev_quat) - return e->e.value.v.quaternion_val; + if (e->type == ex_value && e->e.value->type == ev_quat) + return e->e.value->v.quaternion_val; if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const && e->e.symbol->type->type == ev_quat) - return e->e.symbol->s.value.v.quaternion_val; + return e->e.symbol->s.value->v.quaternion_val; if (e->type == ex_symbol && e->e.symbol->sy_type == sy_var && e->e.symbol->s.def->constant && e->e.symbol->s.def->type->type == ev_quat) @@ -784,7 +768,7 @@ is_integer_val (expr_t *e) { if (e->type == ex_nil) return 1; - if (e->type == ex_value && e->e.value.type == ev_integer) + if (e->type == ex_value && e->e.value->type == ev_integer) return 1; if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const && (e->e.symbol->type->type == ev_integer @@ -798,12 +782,12 @@ expr_integer (expr_t *e) { if (e->type == ex_nil) return 0; - if (e->type == ex_value && e->e.value.type == ev_integer) - return e->e.value.v.integer_val; + if (e->type == ex_value && e->e.value->type == ev_integer) + return e->e.value->v.integer_val; if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const && (e->e.symbol->type->type == ev_integer || is_enum (e->e.symbol->type))) - return e->e.symbol->s.value.v.integer_val; + return e->e.symbol->s.value->v.integer_val; if (e->type == ex_symbol && e->e.symbol->sy_type == sy_var && e->e.symbol->s.def->constant && is_integral (e->e.symbol->s.def->type)) @@ -816,11 +800,11 @@ expr_uinteger (expr_t *e) { if (e->type == ex_nil) return 0; - if (e->type == ex_value && e->e.value.type == ev_uinteger) - return e->e.value.v.uinteger_val; + if (e->type == ex_value && e->e.value->type == ev_uinteger) + return e->e.value->v.uinteger_val; if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const && e->e.symbol->type->type == ev_uinteger) - return e->e.symbol->s.value.v.uinteger_val; + return e->e.symbol->s.value->v.uinteger_val; if (e->type == ex_symbol && e->e.symbol->sy_type == sy_var && e->e.symbol->s.def->constant && is_integral (e->e.symbol->s.def->type)) @@ -833,7 +817,7 @@ is_short_val (expr_t *e) { if (e->type == ex_nil) return 1; - if (e->type == ex_value && e->e.value.type == ev_short) + if (e->type == ex_value && e->e.value->type == ev_short) return 1; if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const && e->e.symbol->type->type == ev_short) @@ -846,11 +830,11 @@ expr_short (expr_t *e) { if (e->type == ex_nil) return 0; - if (e->type == ex_value && e->e.value.type == ev_short) - return e->e.value.v.short_val; + if (e->type == ex_value && e->e.value->type == ev_short) + return e->e.value->v.short_val; if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const && e->e.symbol->type->type == ev_short) - return e->e.symbol->s.value.v.short_val; + return e->e.symbol->s.value->v.short_val; internal_error (e, "not a short constant"); } @@ -998,8 +982,8 @@ field_expr (expr_t *e1, expr_t *e2) return e1; e2->type = ex_value; - e2->e.value.type = ev_short; - e2->e.value.v.short_val = field->s.offset; + e2->e.value->type = ev_short; + e2->e.value->v.short_val = field->s.offset; e = new_binary_expr ('&', e1, e2); e->e.expr.type = pointer_type (field->type); return unary_expr ('.', e); @@ -1012,8 +996,8 @@ field_expr (expr_t *e1, expr_t *e2) if (!ivar) return new_error_expr (); e2->type = ex_value; - e2->e.value.type = ev_short; - e2->e.value.v.short_val = ivar->s.offset; + e2->e.value->type = ev_short; + e2->e.value->v.short_val = ivar->s.offset; e = new_binary_expr ('&', e1, e2); e->e.expr.type = pointer_type (ivar->type); return unary_expr ('.', e); @@ -1042,17 +1026,17 @@ field_expr (expr_t *e1, expr_t *e2) } def = sym->s.def; e2 = new_field_expr (0, field->type, def); - } else if (e2->type != ex_value || e2->e.value.type != ev_field) { + } else if (e2->type != ex_value || e2->e.value->type != ev_field) { internal_error (e2, "unexpected field exression"); } - e2->e.value.v.pointer.val += field->s.offset; - e2->e.value.v.pointer.type = field->type; + e2->e.value->v.pointer.val += field->s.offset; + e2->e.value->v.pointer.type = field->type; // create a new . expression return field_expr (e1, e2); } else { e2->type = ex_value; - e2->e.value.type = ev_short; - e2->e.value.v.short_val = field->s.offset; + e2->e.value->type = ev_short; + e2->e.value->v.short_val = field->s.offset; e = address_expr (e1, e2, field->type); return unary_expr ('.', e); } @@ -1302,35 +1286,32 @@ bool_expr (int op, expr_t *label, expr_t *e1, expr_t *e2) void convert_int (expr_t *e) { - e->e.value.v.float_val = expr_integer (e); - e->e.value.type = ev_float; + e->e.value->v.float_val = expr_integer (e); + e->e.value->type = ev_float; e->type = ex_value; } void convert_short (expr_t *e) { - e->e.value.v.float_val = expr_short (e); - e->e.value.type = ev_float; + e->e.value->v.float_val = expr_short (e); + e->e.value->type = ev_float; e->type = ex_value; } void convert_short_int (expr_t *e) { - e->e.value.v.integer_val = expr_short (e); - e->e.value.type = ev_integer; + e->e.value->v.integer_val = expr_short (e); + e->e.value->type = ev_integer; e->type = ex_value; } void convert_nil (expr_t *e, type_t *t) { - memset (&e->e.value, 0, sizeof (e->e.value)); - e->e.value.type = low_level_type (t); - if (t->type == ev_pointer || t->type == ev_field) - e->e.value.v.pointer.type = t->t.fldptr.type; e->type = ex_value; + e->e.value = new_nil_val (t); } int @@ -2197,10 +2178,7 @@ address_expr (expr_t *e1, expr_t *e2, type_t *t) if (is_array (type)) { e = e1; e->type = ex_value; - e->e.value.type = ev_pointer; - e->e.value.v.pointer.val = 0; - e->e.value.v.pointer.type = t; - e->e.value.v.pointer.def = def; + e->e.value = new_pointer_val (0, t, def); } else { e = new_pointer_expr (0, t, def); e->line = e1->line; @@ -2245,10 +2223,9 @@ address_expr (expr_t *e1, expr_t *e2, type_t *t) if (e2) { if (e2->type == ex_error) return e2; - if (e->type == ex_value && e->e.value.type == ev_pointer + if (e->type == ex_value && e->e.value->type == ev_pointer && is_short_val (e2)) { - e->e.value.v.pointer.val += expr_short (e2); - e->e.value.v.pointer.type = t; + e->e.value = new_pointer_val (e->e.value->v.pointer.val + expr_short (e2), t, e->e.value->v.pointer.def); } else { if (!is_short_val (e2) || expr_short (e2)) { if (e->type == ex_expr && e->e.expr.op == '&') { @@ -2475,9 +2452,9 @@ is_indirect (expr_t *e) if (!(e->type == ex_uexpr && e->e.expr.op == '.')) return 0; e = e->e.expr.e1; - if (e->type != ex_value || e->e.value.type != ev_pointer - || !(POINTER_VAL (e->e.value.v.pointer) >= 0 - && POINTER_VAL (e->e.value.v.pointer) < 65536)) { + if (e->type != ex_value || e->e.value->type != ev_pointer + || !(POINTER_VAL (e->e.value->v.pointer) >= 0 + && POINTER_VAL (e->e.value->v.pointer) < 65536)) { return 1; } return 0; @@ -2615,9 +2592,9 @@ assign_expr (expr_t *e1, expr_t *e2) op = PAS; } else { e = e1->e.expr.e1; - if ((e->type != ex_value || e->e.value.type != ev_pointer) - || !(POINTER_VAL (e->e.value.v.pointer) > 0 - && POINTER_VAL (e->e.value.v.pointer) < 65536)) { + if ((e->type != ex_value || e->e.value->type != ev_pointer) + || !(POINTER_VAL (e->e.value->v.pointer) > 0 + && POINTER_VAL (e->e.value->v.pointer) < 65536)) { e1 = e; op = PAS; } @@ -2631,9 +2608,9 @@ assign_expr (expr_t *e1, expr_t *e2) } if (e2->type == ex_uexpr) { e = e2->e.expr.e1; - if ((e->type != ex_value || e->e.value.type != ev_pointer) - || !(POINTER_VAL (e->e.value.v.pointer) > 0 - && POINTER_VAL (e->e.value.v.pointer) < 65536)) { + if ((e->type != ex_value || e->e.value->type != ev_pointer) + || !(POINTER_VAL (e->e.value->v.pointer) > 0 + && POINTER_VAL (e->e.value->v.pointer) < 65536)) { if (e->type == ex_expr && e->e.expr.op == '&' && e->e.expr.type->type == ev_pointer && !is_constant (e)) { diff --git a/tools/qfcc/source/obj_type.c b/tools/qfcc/source/obj_type.c index 99eb189d7..8efdf6d6e 100644 --- a/tools/qfcc/source/obj_type.c +++ b/tools/qfcc/source/obj_type.c @@ -212,7 +212,7 @@ qfo_encode_struct (type_t *type) if (i == num_fields) internal_error (0, "whoa, what happened?"); if (sym->sy_type == sy_const) - offset = sym->s.value.v.integer_val; + offset = sym->s.value->v.integer_val; else offset = sym->s.offset; ENC_DEF (strct->fields[i].type, field_types[i]); diff --git a/tools/qfcc/source/statements.c b/tools/qfcc/source/statements.c index 484aab16b..5c443d6e1 100644 --- a/tools/qfcc/source/statements.c +++ b/tools/qfcc/source/statements.c @@ -508,7 +508,7 @@ vector_call (sblock_t *sblock, expr_t *earg, expr_t *param, int ind, for (i = 0; i < 3; i++) { n = new_name_expr (names[i]); - v = new_float_expr (earg->e.value.v.vector_val[i]); + v = new_float_expr (earg->e.value->v.vector_val[i]); a = assign_expr (binary_expr ('.', param, n), v); param = new_param_expr (get_type (earg), ind); a->line = earg->line; @@ -544,7 +544,7 @@ expr_call (sblock_t *sblock, expr_t *call, operand_t **op) pref = "R"; sblock = statement_subexpr (sblock, param, &arguments[ind]); if (options.code.vector_calls && a->type == ex_value - && a->e.value.type == ev_vector) + && a->e.value->type == ev_vector) sblock = vector_call (sblock, a, param, ind, &arguments[ind]); else sblock = statement_subexpr (sblock, a, &arguments[ind]); @@ -558,7 +558,7 @@ expr_call (sblock_t *sblock, expr_t *call, operand_t **op) sblock = statement_slist (sblock, mov); } else { if (options.code.vector_calls && a->type == ex_value - && a->e.value.type == ev_vector) { + && a->e.value->type == ev_vector) { sblock = vector_call (sblock, a, param, ind, 0); } else { operand_t *p = 0; @@ -659,10 +659,10 @@ expr_deref (sblock_t *sblock, expr_t *deref, operand_t **op) s->opc = *op; sblock_add_statement (sblock, s); } - } else if (e->type == ex_value && e->e.value.type == ev_pointer) { + } else if (e->type == ex_value && e->e.value->type == ev_pointer) { *op = new_operand (op_pointer); - (*op)->type = low_level_type (e->e.value.v.pointer.type); - (*op)->o.pointer = &e->e.value.v.pointer; + (*op)->type = low_level_type (e->e.value->v.pointer.type); + (*op)->o.pointer = &e->e.value->v.pointer; } else { statement_t *s; operand_t *ptr = 0; @@ -830,8 +830,8 @@ static sblock_t * expr_value (sblock_t *sblock, expr_t *e, operand_t **op) { *op = new_operand (op_value); - (*op)->type = e->e.value.type; - (*op)->o.value = &e->e.value; + (*op)->type = e->e.value->type; + (*op)->o.value = e->e.value; return sblock; } diff --git a/tools/qfcc/source/struct.c b/tools/qfcc/source/struct.c index dbd8782dc..c2a12b0c7 100644 --- a/tools/qfcc/source/struct.c +++ b/tools/qfcc/source/struct.c @@ -59,6 +59,7 @@ #include "struct.h" #include "symtab.h" #include "type.h" +#include "value.h" static symbol_t * find_tag (ty_meta_e meta, symbol_t *tag, type_t *type) @@ -172,7 +173,7 @@ add_enum (symbol_t *enm, symbol_t *name, expr_t *val) enum_tab = enum_type->t.symtab; value = 0; if (enum_tab->symbols) - value = ((symbol_t *)(enum_tab->symtail))->s.value.v.integer_val + 1; + value = ((symbol_t *)(enum_tab->symtail))->s.value->v.integer_val + 1; if (val) { if (!is_constant (val)) error (val, "non-constant initializer"); @@ -181,8 +182,7 @@ add_enum (symbol_t *enm, symbol_t *name, expr_t *val) else value = expr_integer (val); } - name->s.value.type = ev_integer; - name->s.value.v.integer_val = value; + name->s.value = new_integer_val (value); symtab_addsymbol (enum_tab, name); sym = new_symbol_type (name->name, name->type); sym->sy_type = sy_const; @@ -204,12 +204,12 @@ enum_as_bool (type_t *enm, expr_t **zero, expr_t **one) for (sym = symtab->symbols; sym; sym = sym->next) { if (sym->sy_type != sy_const) continue; - val = sym->s.value.v.integer_val; + val = sym->s.value->v.integer_val; if (!val) { zero_sym = sym; } else { if (one_sym) { - v = one_sym->s.value.v.integer_val; + v = one_sym->s.value->v.integer_val; if (val * val > v * v) continue; } diff --git a/tools/qfcc/source/switch.c b/tools/qfcc/source/switch.c index c663c96f7..4c5f83459 100644 --- a/tools/qfcc/source/switch.c +++ b/tools/qfcc/source/switch.c @@ -67,8 +67,8 @@ static ex_value_t * get_value (expr_t *e) { if (e->type == ex_symbol) - return &e->e.symbol->s.value; - return &e->e.value; + return e->e.symbol->s.value; + return e->e.value; } static uintptr_t diff --git a/tools/qfcc/source/value.c b/tools/qfcc/source/value.c index 1e421943a..54f7af29b 100644 --- a/tools/qfcc/source/value.c +++ b/tools/qfcc/source/value.c @@ -71,6 +71,162 @@ typedef struct { } i; } immediate_t; +static hashtab_t *value_table; +static ex_value_t *free_values; + +static uintptr_t +value_get_hash (const void *_val, void *unused) +{ + const ex_value_t *val = (const ex_value_t *) _val; + return Hash_Buffer (&val->v, sizeof (val->v)) + val->type; +} + +static int +value_compare (const void *_val1, const void *_val2, void *unused) +{ + const ex_value_t *val1 = (const ex_value_t *) _val1; + const ex_value_t *val2 = (const ex_value_t *) _val2; + if (val1->type != val2->type) + return 0; + return memcmp (&val1->v, &val2->v, sizeof (val1->v)) == 0; +} + +static ex_value_t * +new_value (void) +{ + ex_value_t *value; + ALLOC (256, ex_value_t, values, value); + return value; +} + +static ex_value_t * +find_value (const ex_value_t *val) +{ + ex_value_t *value; + + value = Hash_FindElement (value_table, val); + if (value) + return value; + value = new_value (); + *value = *val; + return value; +} + +ex_value_t * +new_string_val (const char *string_val) +{ + ex_value_t val; + val.type = ev_string; + if (string_val) + val.v.string_val = save_string (string_val); + return find_value (&val); +} + +ex_value_t * +new_float_val (float float_val) +{ + ex_value_t val; + val.type = ev_float; + val.v.float_val = float_val; + return find_value (&val); +} + +ex_value_t * +new_vector_val (const float *vector_val) +{ + ex_value_t val; + val.type = ev_vector; + VectorCopy (vector_val, val.v.vector_val); + return find_value (&val); +} + +ex_value_t * +new_entity_val (int entity_val) +{ + ex_value_t val; + val.type = ev_entity; + val.v.entity_val = entity_val; + return find_value (&val); +} + +ex_value_t * +new_field_val (int field_val, type_t *type, def_t *def) +{ + ex_value_t val; + val.type = ev_field; + val.v.pointer.val = field_val; + val.v.pointer.type = type; + val.v.pointer.def = def; + return find_value (&val); +} + +ex_value_t * +new_func_val (int func_val) +{ + ex_value_t val; + val.type = ev_func; + val.v.func_val = func_val; + return find_value (&val); +} + +ex_value_t * +new_pointer_val (int pointer_val, type_t *type, def_t *def) +{ + ex_value_t val; + val.type = ev_pointer; + val.v.pointer.val = pointer_val; + val.v.pointer.type = type; + val.v.pointer.def = def; + return find_value (&val); +} + +ex_value_t * +new_quaternion_val (const float *quaternion_val) +{ + ex_value_t val; + val.type = ev_quat; + QuatCopy (quaternion_val, val.v.quaternion_val); + return find_value (&val); +} + +ex_value_t * +new_integer_val (int integer_val) +{ + ex_value_t val; + val.type = ev_integer; + val.v.integer_val = integer_val; + return find_value (&val); +} + +ex_value_t * +new_uinteger_val (int uinteger_val) +{ + ex_value_t val; + val.type = ev_uinteger; + val.v.uinteger_val = uinteger_val; + return find_value (&val); +} + +ex_value_t * +new_short_val (short short_val) +{ + ex_value_t val; + val.type = ev_short; + val.v.short_val = short_val; + return find_value (&val); +} + +ex_value_t * +new_nil_val (type_t *type) +{ + ex_value_t val; + val.type = low_level_type (type); + memset (&val.v, 0, sizeof (val.v)); + if (val.type == ev_pointer|| val.type == ev_field ) + val.v.pointer.type = type->t.fldptr.type; + return find_value (&val); +} + static hashtab_t *string_imm_defs; static hashtab_t *float_imm_defs; static hashtab_t *vector_imm_defs; @@ -370,7 +526,8 @@ clear_immediates (void) { immediate_t *imm; - if (string_imm_defs) { + if (value_table) { + Hash_FlushTable (value_table); Hash_FlushTable (string_imm_defs); Hash_FlushTable (float_imm_defs); Hash_FlushTable (vector_imm_defs); @@ -381,6 +538,9 @@ clear_immediates (void) Hash_FlushTable (quaternion_imm_defs); Hash_FlushTable (integer_imm_defs); } else { + value_table = Hash_NewTable (16381, 0, 0, 0); + Hash_SetHashCompare (value_table, value_get_hash, value_compare); + string_imm_defs = Hash_NewTable (16381, 0, 0, &string_imm_defs); Hash_SetHashCompare (string_imm_defs, imm_get_hash, imm_compare);