From 906f319673f6a2eddb62e59acc970b9497f3e96a Mon Sep 17 00:00:00 2001 From: "Wolfgang (Blub) Bumiller" Date: Thu, 15 Nov 2012 18:32:03 +0100 Subject: [PATCH] Replaced it all... --- ast.c | 150 +++++------ ast.h | 25 +- code.c | 224 +++++++--------- exec.c | 287 ++++++++------------ gmqcc.h | 129 ++++----- ir.c | 790 +++++++++++++++++++++++++------------------------------ ir.h | 75 ++---- lexer.c | 13 +- main.c | 24 +- parser.c | 518 +++++++++++++----------------------- util.c | 18 +- 11 files changed, 933 insertions(+), 1320 deletions(-) diff --git a/ast.c b/ast.c index 10c177e..dfed367 100644 --- a/ast.c +++ b/ast.c @@ -70,7 +70,7 @@ static void ast_expression_init(ast_expression *self, self->expression.outl = NULL; self->expression.outr = NULL; self->expression.variadic = false; - MEM_VECTOR_INIT(&self->expression, params); + self->expression.params = NULL; } static void ast_expression_delete(ast_expression *self) @@ -78,10 +78,10 @@ static void ast_expression_delete(ast_expression *self) size_t i; if (self->expression.next) ast_delete(self->expression.next); - for (i = 0; i < self->expression.params_count; ++i) { + for (i = 0; i < vec_size(self->expression.params); ++i) { ast_delete(self->expression.params[i]); } - MEM_VECTOR_CLEAR(&self->expression, params); + vec_free(self->expression.params); } static void ast_expression_delete_full(ast_expression *self) @@ -90,8 +90,6 @@ static void ast_expression_delete_full(ast_expression *self) mem_d(self); } -MEM_VEC_FUNCTIONS(ast_expression_common, ast_value*, params) - ast_value* ast_value_copy(const ast_value *self) { size_t i; @@ -108,12 +106,13 @@ ast_value* ast_value_copy(const ast_value *self) fromex = &self->expression; selfex = &cp->expression; selfex->variadic = fromex->variadic; - for (i = 0; i < fromex->params_count; ++i) { + for (i = 0; i < vec_size(fromex->params); ++i) { ast_value *v = ast_value_copy(fromex->params[i]); - if (!v || !ast_expression_common_params_add(selfex, v)) { + if (!v) { ast_value_delete(cp); return NULL; } + vec_push(selfex->params, v); } return cp; } @@ -132,10 +131,11 @@ bool ast_type_adopt_impl(ast_expression *self, const ast_expression *other) fromex = &other->expression; selfex = &self->expression; selfex->variadic = fromex->variadic; - for (i = 0; i < fromex->params_count; ++i) { + for (i = 0; i < vec_size(fromex->params); ++i) { ast_value *v = ast_value_copy(fromex->params[i]); - if (!v || !ast_expression_common_params_add(selfex, v)) + if (!v) return false; + vec_push(selfex->params, v); } return true; } @@ -182,12 +182,13 @@ ast_expression* ast_type_copy(lex_ctx ctx, const ast_expression *ex) selfex->next = NULL; selfex->variadic = fromex->variadic; - for (i = 0; i < fromex->params_count; ++i) { + for (i = 0; i < vec_size(fromex->params); ++i) { ast_value *v = ast_value_copy(fromex->params[i]); - if (!v || !ast_expression_common_params_add(selfex, v)) { + if (!v) { ast_expression_delete_full(self); return NULL; } + vec_push(selfex->params, v); } return self; @@ -200,13 +201,13 @@ bool ast_compare_type(ast_expression *a, ast_expression *b) return false; if (!a->expression.next != !b->expression.next) return false; - if (a->expression.params_count != b->expression.params_count) + if (vec_size(a->expression.params) != vec_size(b->expression.params)) return false; if (a->expression.variadic != b->expression.variadic) return false; - if (a->expression.params_count) { + if (vec_size(a->expression.params)) { size_t i; - for (i = 0; i < a->expression.params_count; ++i) { + for (i = 0; i < vec_size(a->expression.params); ++i) { if (!ast_compare_type((ast_expression*)a->expression.params[i], (ast_expression*)b->expression.params[i])) return false; @@ -257,14 +258,14 @@ static size_t ast_type_to_string_impl(ast_expression *e, char *buf, size_t bufsi pos = ast_type_to_string_impl(e->expression.next, buf, bufsize, pos); if (pos + 2 >= bufsize) goto full; - if (e->expression.params_count == 0) { + if (!vec_size(e->expression.params)) { buf[pos++] = '('; buf[pos++] = ')'; return pos; } buf[pos++] = '('; pos = ast_type_to_string_impl((ast_expression*)(e->expression.params[0]), buf, bufsize, pos); - for (i = 1; i < e->expression.params_count; ++i) { + for (i = 1; i < vec_size(e->expression.params); ++i) { if (pos + 2 >= bufsize) goto full; buf[pos++] = ','; @@ -360,9 +361,9 @@ void ast_value_delete(ast_value* self) mem_d(self); } -bool GMQCC_WARN ast_value_params_add(ast_value *self, ast_value *p) +void ast_value_params_add(ast_value *self, ast_value *p) { - return ast_expression_common_params_add(&self->expression, p); + vec_push(self->expression.params, p); } bool ast_value_set_name(ast_value *self, const char *name) @@ -705,9 +706,8 @@ ast_call* ast_call_new(lex_ctx ctx, ast_instantiate(ast_call, ctx, ast_call_delete); ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_call_codegen); - MEM_VECTOR_INIT(self, params); - - self->func = funcexpr; + self->params = NULL; + self->func = funcexpr; self->expression.vtype = funcexpr->expression.next->expression.vtype; if (funcexpr->expression.next->expression.next) @@ -715,14 +715,13 @@ ast_call* ast_call_new(lex_ctx ctx, return self; } -MEM_VEC_FUNCTIONS(ast_call, ast_expression*, params) void ast_call_delete(ast_call *self) { size_t i; - for (i = 0; i < self->params_count; ++i) + for (i = 0; i < vec_size(self->params); ++i) ast_unref(self->params[i]); - MEM_VECTOR_CLEAR(self, params); + vec_free(self->params); if (self->func) ast_unref(self->func); @@ -736,9 +735,9 @@ bool ast_call_check_types(ast_call *self) size_t i; bool retval = true; const ast_expression *func = self->func; - size_t count = self->params_count; - if (count > func->expression.params_count) - count = func->expression.params_count; + size_t count = vec_size(self->params); + if (count > vec_size(func->expression.params)) + count = vec_size(func->expression.params); for (i = 0; i < count; ++i) { if (!ast_compare_type(self->params[i], (ast_expression*)(func->expression.params[i]))) { @@ -789,36 +788,31 @@ ast_block* ast_block_new(lex_ctx ctx) ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_block_codegen); - MEM_VECTOR_INIT(self, locals); - MEM_VECTOR_INIT(self, exprs); - MEM_VECTOR_INIT(self, collect); + self->locals = NULL; + self->exprs = NULL; + self->collect = NULL; return self; } -MEM_VEC_FUNCTIONS(ast_block, ast_value*, locals) -MEM_VEC_FUNCTIONS(ast_block, ast_expression*, exprs) -MEM_VEC_FUNCTIONS(ast_block, ast_expression*, collect) -bool ast_block_collect(ast_block *self, ast_expression *expr) +void ast_block_collect(ast_block *self, ast_expression *expr) { - if (!ast_block_collect_add(self, expr)) - return false; + vec_push(self->collect, expr); expr->expression.node.keep = true; - return true; } void ast_block_delete(ast_block *self) { size_t i; - for (i = 0; i < self->exprs_count; ++i) + for (i = 0; i < vec_size(self->exprs); ++i) ast_unref(self->exprs[i]); - MEM_VECTOR_CLEAR(self, exprs); - for (i = 0; i < self->locals_count; ++i) + vec_free(self->exprs); + for (i = 0; i < vec_size(self->locals); ++i) ast_delete(self->locals[i]); - MEM_VECTOR_CLEAR(self, locals); - for (i = 0; i < self->collect_count; ++i) + vec_free(self->exprs); + for (i = 0; i < vec_size(self->collect); ++i) ast_delete(self->collect[i]); - MEM_VECTOR_CLEAR(self, collect); + vec_free(self->exprs); ast_expression_delete((ast_expression*)self); mem_d(self); } @@ -850,9 +844,9 @@ ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype) return NULL; } - self->vtype = vtype; - self->name = name ? util_strdup(name) : NULL; - MEM_VECTOR_INIT(self, blocks); + self->vtype = vtype; + self->name = name ? util_strdup(name) : NULL; + self->blocks = NULL; self->labelcount = 0; self->builtin = 0; @@ -869,8 +863,6 @@ ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype) return self; } -MEM_VEC_FUNCTIONS(ast_function, ast_block*, blocks) - void ast_function_delete(ast_function *self) { size_t i; @@ -885,9 +877,9 @@ void ast_function_delete(ast_function *self) */ ast_unref(self->vtype); } - for (i = 0; i < self->blocks_count; ++i) + for (i = 0; i < vec_size(self->blocks); ++i) ast_delete(self->blocks[i]); - MEM_VECTOR_CLEAR(self, blocks); + vec_free(self->blocks); mem_d(self); } @@ -1255,10 +1247,9 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) /* fill the parameter list */ ec = &self->vtype->expression; - for (i = 0; i < ec->params_count; ++i) + for (i = 0; i < vec_size(ec->params); ++i) { - if (!ir_function_params_add(irf, ec->params[i]->expression.vtype)) - return false; + vec_push(irf->params, ec->params[i]->expression.vtype); if (!self->builtin) { if (!ast_local_codegen(ec->params[i], self->ir_func, true)) return false; @@ -1270,7 +1261,7 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) return true; } - if (!self->blocks_count) { + if (!vec_size(self->blocks)) { asterror(ast_ctx(self), "function `%s` has no body", self->name); return false; } @@ -1281,7 +1272,7 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) return false; } - for (i = 0; i < self->blocks_count; ++i) { + for (i = 0; i < vec_size(self->blocks); ++i) { ast_expression_codegen *gen = self->blocks[i]->expression.codegen; if (!(*gen)((ast_expression*)self->blocks[i], self, false, &dummy)) return false; @@ -1342,7 +1333,7 @@ bool ast_block_codegen(ast_block *self, ast_function *func, bool lvalue, ir_valu *out = NULL; /* generate locals */ - for (i = 0; i < self->locals_count; ++i) + for (i = 0; i < vec_size(self->locals); ++i) { if (!ast_local_codegen(self->locals[i], func->ir_func, false)) { if (opts_debug) @@ -1351,7 +1342,7 @@ bool ast_block_codegen(ast_block *self, ast_function *func, bool lvalue, ir_valu } } - for (i = 0; i < self->exprs_count; ++i) + for (i = 0; i < vec_size(self->exprs); ++i) { ast_expression_codegen *gen = self->exprs[i]->expression.codegen; if (!(*gen)(self->exprs[i], func, false, out)) @@ -1423,10 +1414,8 @@ bool ast_store_codegen(ast_store *self, ast_function *func, bool lvalue, ir_valu call = ir_block_create_call(func->curblock, ast_function_label(func, "store"), funval); if (!call) return false; - if (!ir_call_param(call, iridx)) - return false; - if (!ir_call_param(call, right)) - return false; + ir_call_param(call, iridx); + ir_call_param(call, right); self->expression.outr = right; } else @@ -1747,8 +1736,7 @@ bool ast_array_index_codegen(ast_array_index *self, ast_function *func, bool lva call = ir_block_create_call(func->curblock, ast_function_label(func, "fetch"), funval); if (!call) return false; - if (!ir_call_param(call, iridx)) - return false; + ir_call_param(call, iridx); *out = ir_call_value(call); self->expression.outr = *out; @@ -1955,12 +1943,10 @@ bool ast_ternary_codegen(ast_ternary *self, ast_function *func, bool lvalue, ir_ /* create PHI */ phi = ir_block_create_phi(merge, ast_function_label(func, "phi"), trueval->vtype); - if (!phi || - !ir_phi_add(phi, ontrue, trueval) || - !ir_phi_add(phi, onfalse, falseval)) - { + if (!phi) return false; - } + ir_phi_add(phi, ontrue, trueval); + ir_phi_add(phi, onfalse, falseval); self->phi_out = ir_phi_value(phi); *out = self->phi_out; @@ -2072,7 +2058,7 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value bpostcond = end_bpostcond = NULL; } - bout_id = func->ir_func->blocks_count; + bout_id = vec_size(func->ir_func->blocks); bout = ir_function_create_block(func->ir_func, ast_function_label(func, "after_loop")); if (!bout) return false; @@ -2192,12 +2178,8 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value } /* Move 'bout' to the end */ - if (!ir_function_blocks_remove(func->ir_func, bout_id) || - !ir_function_blocks_add(func->ir_func, bout)) - { - ir_block_delete(bout); - return false; - } + vec_remove(func->ir_func->blocks, bout_id, 1); + vec_push(func->ir_func->blocks, bout); return true; } @@ -2205,7 +2187,7 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value bool ast_call_codegen(ast_call *self, ast_function *func, bool lvalue, ir_value **out) { ast_expression_codegen *cgen; - ir_value_vector params; + ir_value **params; ir_instr *callinstr; size_t i; @@ -2228,10 +2210,10 @@ bool ast_call_codegen(ast_call *self, ast_function *func, bool lvalue, ir_value if (!funval) return false; - MEM_VECTOR_INIT(¶ms, v); + params = NULL; /* parameters */ - for (i = 0; i < self->params_count; ++i) + for (i = 0; i < vec_size(self->params); ++i) { ir_value *param; ast_expression *expr = self->params[i]; @@ -2241,25 +2223,23 @@ bool ast_call_codegen(ast_call *self, ast_function *func, bool lvalue, ir_value goto error; if (!param) goto error; - if (!ir_value_vector_v_add(¶ms, param)) - goto error; + vec_push(params, param); } callinstr = ir_block_create_call(func->curblock, ast_function_label(func, "call"), funval); if (!callinstr) goto error; - for (i = 0; i < params.v_count; ++i) { - if (!ir_call_param(callinstr, params.v[i])) - goto error; + for (i = 0; i < vec_size(params); ++i) { + ir_call_param(callinstr, params[i]); } *out = ir_call_value(callinstr); self->expression.outr = *out; - MEM_VECTOR_CLEAR(¶ms, v); + vec_free(params); return true; error: - MEM_VECTOR_CLEAR(¶ms, v); + vec_free(params); return false; } diff --git a/ast.h b/ast.h index f2f05d6..16f9807 100644 --- a/ast.h +++ b/ast.h @@ -120,7 +120,7 @@ typedef struct ast_expression *next; /* arrays get a member-count */ size_t count; - MEM_VECTOR_MAKE(ast_value*, params); + ast_value* *params; bool variadic; /* The codegen functions should store their output values * so we can call it multiple times without re-evaluating. @@ -130,7 +130,6 @@ typedef struct ir_value *outl; ir_value *outr; } ast_expression_common; -MEM_VECTOR_PROTO(ast_expression_common, ast_value*, params); /* Value * @@ -183,7 +182,7 @@ bool ast_value_codegen(ast_value*, ast_function*, bool lvalue, ir_value**); bool ast_local_codegen(ast_value *self, ir_function *func, bool isparam); bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield); -bool GMQCC_WARN ast_value_params_add(ast_value*, ast_value*); +void ast_value_params_add(ast_value*, ast_value*); bool ast_compare_type(ast_expression *a, ast_expression *b); ast_expression* ast_type_copy(lex_ctx ctx, const ast_expression *ex); @@ -460,7 +459,7 @@ struct ast_call_s { ast_expression_common expression; ast_expression *func; - MEM_VECTOR_MAKE(ast_expression*, params); + ast_expression* *params; }; ast_call* ast_call_new(lex_ctx ctx, ast_expression *funcexpr); @@ -468,8 +467,6 @@ void ast_call_delete(ast_call*); bool ast_call_codegen(ast_call*, ast_function*, bool lvalue, ir_value**); bool ast_call_check_types(ast_call*); -MEM_VECTOR_PROTO(ast_call, ast_expression*, params); - /* Blocks * */ @@ -477,20 +474,16 @@ struct ast_block_s { ast_expression_common expression; - MEM_VECTOR_MAKE(ast_value*, locals); - MEM_VECTOR_MAKE(ast_expression*, exprs); - MEM_VECTOR_MAKE(ast_expression*, collect); + ast_value* *locals; + ast_expression* *exprs; + ast_expression* *collect; }; ast_block* ast_block_new(lex_ctx ctx); void ast_block_delete(ast_block*); bool ast_block_set_type(ast_block*, ast_expression *from); -MEM_VECTOR_PROTO(ast_block, ast_value*, locals); -MEM_VECTOR_PROTO(ast_block, ast_expression*, exprs); -MEM_VECTOR_PROTO(ast_block, ast_expression*, collect); - bool ast_block_codegen(ast_block*, ast_function*, bool lvalue, ir_value**); -bool ast_block_collect(ast_block*, ast_expression*); +void ast_block_collect(ast_block*, ast_expression*); /* Function * @@ -523,7 +516,7 @@ struct ast_function_s */ char labelbuf[64]; - MEM_VECTOR_MAKE(ast_block*, blocks); + ast_block* *blocks; }; ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype); /* This will NOT delete the underlying ast_value */ @@ -533,8 +526,6 @@ void ast_function_delete(ast_function*); */ const char* ast_function_label(ast_function*, const char *prefix); -MEM_VECTOR_PROTO(ast_function, ast_block*, blocks); - bool ast_function_codegen(ast_function *self, ir_builder *builder); /* Expression union diff --git a/code.c b/code.c index e828ccc..372e7eb 100644 --- a/code.c +++ b/code.c @@ -22,46 +22,12 @@ */ #include "gmqcc.h" -/* - * The macros below expand to a typesafe vector implementation, which - * can be viewed in gmqcc.h - * - * code_statements_data -- raw prog_section_statement array - * code_statements_elements -- number of elements - * code_statements_allocated -- size of the array allocated - * code_statements_add(T) -- add element (returns -1 on error) - * - * code_vars_data -- raw prog_section_var array - * code_vars_elements -- number of elements - * code_vars_allocated -- size of the array allocated - * code_vars_add(T) -- add element (returns -1 on error) - * - * code_fields_data -- raw prog_section_field array - * code_fields_elements -- number of elements - * code_fields_allocated -- size of the array allocated - * code_fields_add(T) -- add element (returns -1 on error) - * - * code_functions_data -- raw prog_section_function array - * code_functions_elements -- number of elements - * code_functions_allocated -- size of the array allocated - * code_functions_add(T) -- add element (returns -1 on error) - * - * code_globals_data -- raw prog_section_def array - * code_globals_elements -- number of elements - * code_globals_allocated -- size of the array allocated - * code_globals_add(T) -- add element (returns -1 on error) - * - * code_chars_data -- raw char* array - * code_chars_elements -- number of elements - * code_chars_allocated -- size of the array allocated - * code_chars_add(T) -- add element (returns -1 on error) - */ -VECTOR_MAKE(prog_section_statement, code_statements); -VECTOR_MAKE(prog_section_def, code_defs ); -VECTOR_MAKE(prog_section_field, code_fields ); -VECTOR_MAKE(prog_section_function, code_functions ); -VECTOR_MAKE(int, code_globals ); -VECTOR_MAKE(char, code_chars ); +prog_section_statement *code_statements; +prog_section_def *code_defs; +prog_section_field *code_fields; +prog_section_function *code_functions; +int *code_globals; +char *code_chars; uint16_t code_crc; uint32_t code_entfields; @@ -83,23 +49,23 @@ void code_init() { * some null (empty) statements, functions, and 28 globals */ for(; i < 28; i++) - code_globals_add(0); + vec_push(code_globals, 0); - code_chars_add ('\0'); - code_functions_add (empty_function); - code_statements_add(empty_statement); - code_defs_add (empty_def); - code_fields_add (empty_def); + vec_push(code_chars, '\0'); + vec_push(code_functions, empty_function); + vec_push(code_statements, empty_statement); + vec_push(code_defs, empty_def); + vec_push(code_fields, empty_def); } uint32_t code_genstring(const char *str) { - uint32_t off = code_chars_elements; + uint32_t off = vec_size(code_chars); while (*str) { - code_chars_add(*str); + vec_push(code_chars, *str); ++str; } - code_chars_add(0); + vec_push(code_chars, 0); return off; } @@ -110,10 +76,10 @@ uint32_t code_cachedstring(const char *str) * and also take substrings, but I'm uncomfortable with * pointing to subparts of strings for the sake of clarity... */ - while (s < code_chars_elements) { - if (!strcmp(str, code_chars_data + s)) + while (s < vec_size(code_chars)) { + if (!strcmp(str, code_chars + s)) return s; - while (code_chars_data[s]) ++s; + while (code_chars[s]) ++s; ++s; } return code_genstring(str); @@ -133,31 +99,31 @@ void code_test() { prog_section_statement s2 = { INSTR_CALL1, {29}, {0}, {0}}; prog_section_statement s3 = { INSTR_RETURN, {0}, {0}, {0}}; - code_chars_put("m_init", 0x6); - code_chars_put("print", 0x5); - code_chars_put("hello world\n", 0xC); - code_chars_put("m_keydown", 0x9); - code_chars_put("m_draw", 0x6); - code_chars_put("m_toggle", 0x8); - code_chars_put("m_shutdown", 0xA); + strcpy(vec_add(code_chars, 0x7), "m_init"); + strcpy(vec_add(code_chars, 0x6), "print"); + strcpy(vec_add(code_chars, 0xD), "hello world\n"); + strcpy(vec_add(code_chars, 0xA), "m_keydown"); + strcpy(vec_add(code_chars, 0x7), "m_draw"); + strcpy(vec_add(code_chars, 0x9), "m_toggle"); + strcpy(vec_add(code_chars, 0xB), "m_shutdown"); - code_globals_add(1); /* m_init */ - code_globals_add(2); /* print */ - code_globals_add(14); /* hello world in string table */ + vec_push(code_globals, 1); /* m_init */ + vec_push(code_globals, 2); /* print */ + vec_push(code_globals, 14); /* hello world in string table */ /* now the defs */ - code_defs_add (d1); /* m_init */ - code_defs_add (d2); /* print */ - code_defs_add (d3); /*hello_world*/ - code_functions_add (f1); /* m_init */ - code_functions_add (f2); /* print */ - code_functions_add (f3); /* m_keydown */ - code_functions_add (f4); - code_functions_add (f5); - code_functions_add (f6); - code_statements_add(s1); - code_statements_add(s2); - code_statements_add(s3); + vec_push(code_defs, d1); /* m_init */ + vec_push(code_defs, d2); /* print */ + vec_push(code_defs, d3); /*hello_world*/ + vec_push(code_functions, f1); /* m_init */ + vec_push(code_functions, f2); /* print */ + vec_push(code_functions, f3); /* m_keydown */ + vec_push(code_functions, f4); + vec_push(code_functions, f5); + vec_push(code_functions, f6); + vec_push(code_statements, s1); + vec_push(code_statements, s2); + vec_push(code_statements, s3); } qcint code_alloc_field (size_t qcsize) @@ -175,17 +141,17 @@ bool code_write(const char *filename) { /* see proposal.txt */ if (OPTS_FLAG(OMIT_NULL_BYTES)) {} code_header.statements.offset = sizeof(prog_header); - code_header.statements.length = code_statements_elements; - code_header.defs.offset = code_header.statements.offset + (sizeof(prog_section_statement) * code_statements_elements); - code_header.defs.length = code_defs_elements; - code_header.fields.offset = code_header.defs.offset + (sizeof(prog_section_def) * code_defs_elements); - code_header.fields.length = code_fields_elements; - code_header.functions.offset = code_header.fields.offset + (sizeof(prog_section_field) * code_fields_elements); - code_header.functions.length = code_functions_elements; - code_header.globals.offset = code_header.functions.offset + (sizeof(prog_section_function) * code_functions_elements); - code_header.globals.length = code_globals_elements; - code_header.strings.offset = code_header.globals.offset + (sizeof(int32_t) * code_globals_elements); - code_header.strings.length = code_chars_elements; + code_header.statements.length = vec_size(code_statements); + code_header.defs.offset = code_header.statements.offset + (sizeof(prog_section_statement) * vec_size(code_statements)); + code_header.defs.length = vec_size(code_defs); + code_header.fields.offset = code_header.defs.offset + (sizeof(prog_section_def) * vec_size(code_defs)); + code_header.fields.length = vec_size(code_fields); + code_header.functions.offset = code_header.fields.offset + (sizeof(prog_section_field) * vec_size(code_fields)); + code_header.functions.length = vec_size(code_functions); + code_header.globals.offset = code_header.functions.offset + (sizeof(prog_section_function) * vec_size(code_functions)); + code_header.globals.length = vec_size(code_globals); + code_header.strings.offset = code_header.globals.offset + (sizeof(int32_t) * vec_size(code_globals)); + code_header.strings.length = vec_size(code_chars); code_header.version = 6; if (opts_forcecrc) code_header.crc16 = opts_forced_crc; @@ -197,30 +163,30 @@ bool code_write(const char *filename) { util_debug("GEN", "Patching stringtable for -fdarkplaces-stringtablebug\n"); /* >= + P */ - code_chars_add('\0'); /* > */ - code_chars_add('\0'); /* = */ - code_chars_add('\0'); /* P */ + vec_push(code_chars, '\0'); /* > */ + vec_push(code_chars, '\0'); /* = */ + vec_push(code_chars, '\0'); /* P */ } /* ensure all data is in LE format */ util_endianswap(&code_header, 1, sizeof(prog_header)); - util_endianswap(code_statements_data, code_statements_elements, sizeof(prog_section_statement)); - util_endianswap(code_defs_data, code_defs_elements, sizeof(prog_section_def)); - util_endianswap(code_fields_data, code_fields_elements, sizeof(prog_section_field)); - util_endianswap(code_functions_data, code_functions_elements, sizeof(prog_section_function)); - util_endianswap(code_globals_data, code_globals_elements, sizeof(int32_t)); + util_endianswap(code_statements, vec_size(code_statements), sizeof(prog_section_statement)); + util_endianswap(code_defs, vec_size(code_defs), sizeof(prog_section_def)); + util_endianswap(code_fields, vec_size(code_fields), sizeof(prog_section_field)); + util_endianswap(code_functions, vec_size(code_functions), sizeof(prog_section_function)); + util_endianswap(code_globals, vec_size(code_globals), sizeof(int32_t)); fp = util_fopen(filename, "wb"); if (!fp) return false; if (1 != fwrite(&code_header, sizeof(prog_header), 1, fp) || - code_statements_elements != fwrite(code_statements_data, sizeof(prog_section_statement), code_statements_elements, fp) || - code_defs_elements != fwrite(code_defs_data, sizeof(prog_section_def) , code_defs_elements , fp) || - code_fields_elements != fwrite(code_fields_data, sizeof(prog_section_field) , code_fields_elements , fp) || - code_functions_elements != fwrite(code_functions_data, sizeof(prog_section_function) , code_functions_elements , fp) || - code_globals_elements != fwrite(code_globals_data, sizeof(int32_t) , code_globals_elements , fp) || - code_chars_elements != fwrite(code_chars_data, 1 , code_chars_elements , fp)) + vec_size(code_statements) != fwrite(code_statements, sizeof(prog_section_statement), vec_size(code_statements), fp) || + vec_size(code_defs) != fwrite(code_defs, sizeof(prog_section_def) , vec_size(code_defs) , fp) || + vec_size(code_fields) != fwrite(code_fields, sizeof(prog_section_field) , vec_size(code_fields) , fp) || + vec_size(code_functions) != fwrite(code_functions, sizeof(prog_section_function) , vec_size(code_functions) , fp) || + vec_size(code_globals) != fwrite(code_globals, sizeof(int32_t) , vec_size(code_globals) , fp) || + vec_size(code_chars) != fwrite(code_chars, 1 , vec_size(code_chars) , fp)) { fclose(fp); return false; @@ -239,37 +205,37 @@ bool code_write(const char *filename) { /* FUNCTIONS */ util_debug("GEN", "FUNCTIONS:\n"); - for (; it < code_functions_elements; it++) { - size_t j = code_functions_data[it].entry; + for (; it < vec_size(code_functions); it++) { + size_t j = code_functions[it].entry; util_debug("GEN", " {.entry =% 5d, .firstlocal =% 5d, .locals =% 5d, .profile =% 5d, .name =% 5d, .file =% 5d, .nargs =% 5d, .argsize ={%d,%d,%d,%d,%d,%d,%d,%d} }\n", - code_functions_data[it].entry, - code_functions_data[it].firstlocal, - code_functions_data[it].locals, - code_functions_data[it].profile, - code_functions_data[it].name, - code_functions_data[it].file, - code_functions_data[it].nargs, - code_functions_data[it].argsize[0], - code_functions_data[it].argsize[1], - code_functions_data[it].argsize[2], - code_functions_data[it].argsize[3], - code_functions_data[it].argsize[4], - code_functions_data[it].argsize[5], - code_functions_data[it].argsize[6], - code_functions_data[it].argsize[7] + code_functions[it].entry, + code_functions[it].firstlocal, + code_functions[it].locals, + code_functions[it].profile, + code_functions[it].name, + code_functions[it].file, + code_functions[it].nargs, + code_functions[it].argsize[0], + code_functions[it].argsize[1], + code_functions[it].argsize[2], + code_functions[it].argsize[3], + code_functions[it].argsize[4], + code_functions[it].argsize[5], + code_functions[it].argsize[6], + code_functions[it].argsize[7] ); - util_debug("GEN", " NAME: %s\n", &code_chars_data[code_functions_data[it].name]); + util_debug("GEN", " NAME: %s\n", &code_chars[code_functions[it].name]); /* Internal functions have no code */ - if (code_functions_data[it].entry >= 0) { + if (code_functions[it].entry >= 0) { util_debug("GEN", " CODE:\n"); for (;;) { - if (code_statements_data[j].opcode != AINSTR_END) + if (code_statements[j].opcode != AINSTR_END) util_debug("GEN", " %-12s {% 5i,% 5i,% 5i}\n", - asm_instr[code_statements_data[j].opcode].m, - code_statements_data[j].o1.s1, - code_statements_data[j].o2.s1, - code_statements_data[j].o3.s1 + asm_instr[code_statements[j].opcode].m, + code_statements[j].o1.s1, + code_statements[j].o2.s1, + code_statements[j].o3.s1 ); else { util_debug("GEN", " DONE {0x00000,0x00000,0x00000}\n"); @@ -280,12 +246,12 @@ bool code_write(const char *filename) { } } - mem_d(code_statements_data); - mem_d(code_defs_data); - mem_d(code_fields_data); - mem_d(code_functions_data); - mem_d(code_globals_data); - mem_d(code_chars_data); + vec_free(code_statements); + vec_free(code_defs); + vec_free(code_fields); + vec_free(code_functions); + vec_free(code_globals); + vec_free(code_chars); fclose(fp); return true; } diff --git a/exec.c b/exec.c index 872475b..ee61c1a 100644 --- a/exec.c +++ b/exec.c @@ -29,28 +29,21 @@ #include "gmqcc.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, bool, entitypool) - -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) - -MEM_VEC_FUNCTIONS(qc_program, const char*, function_stack) +/* +(prog_section_statement, code) +(prog_section_def, defs) +(prog_section_def, fields) +(prog_section_function, functions) +(char, strings) +(qcint, globals) +(qcint, entitydata) +(bool, entitypool) +(qcint, localstack) +(qc_exec_stack, stack) +(size_t, profile) +(prog_builtin, builtins) +(const char*, function_stack) +*/ static void loaderror(const char *fmt, ...) { @@ -78,7 +71,6 @@ qc_program* prog_load(const char *filename) { qc_program *prog; prog_header header; - size_t i; FILE *file; file = util_fopen(filename, "rb"); @@ -114,67 +106,57 @@ qc_program* prog_load(const char *filename) goto error; } -#define read_data(hdrvar, progvar, type) \ - if (fseek(file, header.hdrvar.offset, SEEK_SET) != 0) { \ - loaderror("seek failed"); \ - goto error; \ - } \ - prog->progvar##_alloc = header.hdrvar.length; \ - prog->progvar##_count = header.hdrvar.length; \ - prog->progvar = (type*)mem_a(header.hdrvar.length * sizeof(*prog->progvar)); \ - if (!prog->progvar) \ - goto error; \ - if (fread(prog->progvar, sizeof(*prog->progvar), header.hdrvar.length, file) \ - != header.hdrvar.length) { \ - loaderror("read failed"); \ - goto error; \ +#define read_data(hdrvar, progvar, reserved) \ + if (fseek(file, header.hdrvar.offset, SEEK_SET) != 0) { \ + loaderror("seek failed"); \ + goto error; \ + } \ + if (fread(vec_add(prog->progvar, header.hdrvar.length + reserved), \ + sizeof(*prog->progvar), \ + header.hdrvar.length, file) \ + != header.hdrvar.length) \ + { \ + loaderror("read failed"); \ + goto error; \ } -#define read_data1(x, y) read_data(x, x, y) +#define read_data1(x) read_data(x, x, 0) +#define read_data2(x, y) read_data(x, x, y) - read_data (statements, code, prog_section_statement); - read_data1(defs, prog_section_def); - read_data1(fields, prog_section_def); - read_data1(functions, prog_section_function); - read_data1(strings, char); - read_data1(globals, qcint); + read_data (statements, code, 0); + read_data1(defs); + read_data1(fields); + read_data1(functions); + read_data1(strings); + read_data2(globals, 2); /* reserve more in case a RETURN using with the global at "the end" exists */ fclose(file); /* profile counters */ - if (!qc_program_profile_resize(prog, prog->code_count)) - goto error; + memset(vec_add(prog->profile, vec_size(prog->code)), 0, sizeof(prog->profile[0]) * vec_size(prog->code)); /* Add tempstring area */ - prog->tempstring_start = prog->strings_count; - prog->tempstring_at = prog->strings_count; - if (!qc_program_strings_resize(prog, prog->strings_count + 16*1024)) - goto error; + prog->tempstring_start = vec_size(prog->strings); + prog->tempstring_at = vec_size(prog->strings); + memset(vec_add(prog->strings, 16*1024), 0, 16*1024); /* spawn the world entity */ - if (!qc_program_entitypool_add(prog, true)) { - loaderror("failed to allocate world entity\n"); - goto error; - } - for (i = 0; i < prog->entityfields; ++i) { - if (!qc_program_entitydata_add(prog, 0)) { - loaderror("failed to allocate world data\n"); - goto error; - } - } + vec_push(prog->entitypool, true); + memset(vec_add(prog->entitydata, prog->entityfields), 0, prog->entityfields * sizeof(prog->entitydata[0])); prog->entities = 1; return prog; error: - if (prog->filename) mem_d(prog->filename); - if (prog->code) mem_d(prog->code); - if (prog->defs) mem_d(prog->defs); - if (prog->fields) mem_d(prog->fields); - if (prog->functions) mem_d(prog->functions); - if (prog->strings) mem_d(prog->strings); - if (prog->globals) mem_d(prog->globals); - if (prog->entitydata) mem_d(prog->entitydata); - if (prog->entitypool) mem_d(prog->entitypool); + 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); return NULL; } @@ -182,22 +164,17 @@ error: void prog_delete(qc_program *prog) { if (prog->filename) mem_d(prog->filename); - MEM_VECTOR_CLEAR(prog, code); - MEM_VECTOR_CLEAR(prog, defs); - MEM_VECTOR_CLEAR(prog, fields); - MEM_VECTOR_CLEAR(prog, functions); - MEM_VECTOR_CLEAR(prog, strings); - MEM_VECTOR_CLEAR(prog, globals); - MEM_VECTOR_CLEAR(prog, entitydata); - MEM_VECTOR_CLEAR(prog, entitypool); - 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 */ + 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); } @@ -207,7 +184,7 @@ void prog_delete(qc_program *prog) char* prog_getstring(qc_program *prog, qcint str) { - if (str < 0 || str >= prog->strings_count) + if (str < 0 || str >= vec_size(prog->strings)) return "<<>>"; return prog->strings + str; } @@ -215,7 +192,7 @@ char* prog_getstring(qc_program *prog, qcint str) prog_section_def* prog_entfield(qc_program *prog, qcint off) { size_t i; - for (i = 0; i < prog->fields_count; ++i) { + for (i = 0; i < vec_size(prog->fields); ++i) { if (prog->fields[i].offset == off) return (prog->fields + i); } @@ -225,7 +202,7 @@ prog_section_def* prog_entfield(qc_program *prog, qcint off) prog_section_def* prog_getdef(qc_program *prog, qcint off) { size_t i; - for (i = 0; i < prog->defs_count; ++i) { + for (i = 0; i < vec_size(prog->defs); ++i) { if (prog->defs[i].offset == off) return (prog->defs + i); } @@ -234,7 +211,7 @@ prog_section_def* prog_getdef(qc_program *prog, qcint off) qcany* prog_getedict(qc_program *prog, qcint e) { - if (e >= prog->entitypool_count) { + if (e >= vec_size(prog->entitypool)) { prog->vmerror++; printf("Accessing out of bounds edict %i\n", (int)e); e = 0; @@ -245,28 +222,17 @@ qcany* prog_getedict(qc_program *prog, qcint e) qcint prog_spawn_entity(qc_program *prog) { char *data; - size_t i; qcint e; - for (e = 0; e < (qcint)prog->entitypool_count; ++e) { + for (e = 0; e < (qcint)vec_size(prog->entitypool); ++e) { if (!prog->entitypool[e]) { data = (char*)(prog->entitydata + (prog->entityfields * e)); memset(data, 0, prog->entityfields * sizeof(qcint)); return e; } } - if (!qc_program_entitypool_add(prog, true)) { - prog->vmerror++; - printf("Failed to allocate entity\n"); - return 0; - } + vec_push(prog->entitypool, true); prog->entities++; - for (i = 0; i < prog->entityfields; ++i) { - if (!qc_program_entitydata_add(prog, 0)) { - printf("Failed to allocate entity\n"); - return 0; - } - } - data = (char*)(prog->entitydata + (prog->entityfields * e)); + data = (char*)vec_add(prog->entitydata, prog->entityfields); memset(data, 0, prog->entityfields * sizeof(qcint)); return e; } @@ -278,7 +244,7 @@ void prog_free_entity(qc_program *prog, qcint e) printf("Trying to free world entity\n"); return; } - if (e >= prog->entitypool_count) { + if (e >= vec_size(prog->entitypool)) { prog->vmerror++; printf("Trying to free out of bounds entity\n"); return; @@ -302,17 +268,14 @@ qcint prog_tempstring(qc_program *prog, const char *_str) size_t at = prog->tempstring_at; /* when we reach the end we start over */ - if (at + len >= prog->strings_count) + if (at + len >= vec_size(prog->strings)) at = prog->tempstring_start; /* when it doesn't fit, reallocate */ - if (at + len >= prog->strings_count) + if (at + len >= vec_size(prog->strings)) { - prog->strings_count = at; - if (!qc_program_strings_append(prog, str, len+1)) { - prog->vmerror = VMERR_TEMPSTRING_ALLOC; - return 0; - } + (void)vec_add(prog->strings, len+1); + memcpy(prog->strings + at, str, len+1); return at; } @@ -419,11 +382,11 @@ static void prog_print_statement(qc_program *prog, prog_section_statement *st) printf("\n", st->opcode); return; } - if ((prog->xflags & VMXF_TRACE) && prog->function_stack_count) { + if ((prog->xflags & VMXF_TRACE) && vec_size(prog->function_stack)) { size_t i; - for (i = 0; i < prog->function_stack_count; ++i) + for (i = 0; i < vec_size(prog->function_stack); ++i) printf("->"); - printf("%s:", prog->function_stack[prog->function_stack_count-1]); + printf("%s:", vec_last(prog->function_stack)); } printf(" <> %-12s", asm_instr[st->opcode].m); if (st->opcode >= INSTR_IF && @@ -518,37 +481,29 @@ static qcint prog_enterfunction(qc_program *prog, prog_section_function *func) size_t p, parampos; /* back up locals */ - st.localsp = prog->localstack_count; + st.localsp = vec_size(prog->localstack); st.stmt = prog->statement; st.function = func; if (prog->xflags & VMXF_TRACE) { - (void)!qc_program_function_stack_add(prog, prog_getstring(prog, func->name)); + vec_push(prog->function_stack, prog_getstring(prog, func->name)); } #ifdef QCVM_BACKUP_STRATEGY_CALLER_VARS - if (prog->stack_count) + if (vec_size(prog->stack)) { prog_section_function *cur; - cur = prog->stack[prog->stack_count-1].function; + cur = prog->stack[vec_size(prog->stack)-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); - } + vec_append(prog->localstack, cur->locals, globals); } } #else { qcint *globals = prog->globals + func->firstlocal; - if (!qc_program_localstack_append(prog, globals, func->locals)) - { - printf("out of memory\n"); - exit(1); - } + vec_append(prog->localstack, func->locals, globals); } #endif @@ -563,10 +518,7 @@ static qcint prog_enterfunction(qc_program *prog, prog_section_function *func) } } - if (!qc_program_stack_add(prog, st)) { - printf("out of memory\n"); - exit(1); - } + vec_push(prog->stack, st); return func->entry; } @@ -576,35 +528,30 @@ 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]; + qc_exec_stack st = vec_last(prog->stack); if (prog->xflags & VMXF_TRACE) { - if (prog->function_stack_count) - prog->function_stack_count--; + if (vec_size(prog->function_stack)) + vec_pop(prog->function_stack); } #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; + if (vec_size(prog->stack) > 1) { + prev = prog->stack[vec_size(prog->stack)-2].function; + oldsp = prog->stack[vec_size(prog->stack)-2].localsp; } #else - prev = prog->stack[prog->stack_count-1].function; - oldsp = prog->stack[prog->stack_count-1].localsp; + prev = prog->stack[vec_size(prog->stack)-1].function; + oldsp = prog->stack[vec_size(prog->stack)-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); - } + /* vec_remove(prog->localstack, oldsp, vec_size(prog->localstack)-oldsp); */ + vec_shrinkto(prog->localstack, oldsp); } - if (!qc_program_stack_remove(prog, prog->stack_count-1)) { - printf("out of memory\n"); - exit(1); - } + vec_pop(prog->stack); return st.stmt - 1; /* offset the ++st */ } @@ -656,8 +603,8 @@ bool prog_exec(qc_program *prog, prog_section_function *func, size_t flags, long cleanup: prog->xflags = oldxflags; - prog->localstack_count = 0; - prog->stack_count = 0; + vec_free(prog->localstack); + vec_free(prog->stack); if (prog->vmerror) return false; return true; @@ -693,7 +640,7 @@ typedef struct { const char *value; } qcvm_parameter; -VECTOR_MAKE(qcvm_parameter, main_params); +qcvm_parameter *main_params = NULL; #define CheckArgs(num) do { \ if (prog->argc != (num)) { \ @@ -827,33 +774,33 @@ static void prog_main_setparams(qc_program *prog) size_t i; qcany *arg; - for (i = 0; i < main_params_elements; ++i) { + for (i = 0; i < vec_size(main_params); ++i) { arg = GetGlobal(OFS_PARM0 + 3*i); arg->vector[0] = 0; arg->vector[1] = 0; arg->vector[2] = 0; - switch (main_params_data[i].vtype) { + switch (main_params[i].vtype) { case TYPE_VECTOR: #ifdef WIN32 - (void)sscanf_s(main_params_data[i].value, " %f %f %f ", + (void)sscanf_s(main_params[i].value, " %f %f %f ", &arg->vector[0], &arg->vector[1], &arg->vector[2]); #else - (void)sscanf(main_params_data[i].value, " %f %f %f ", + (void)sscanf(main_params[i].value, " %f %f %f ", &arg->vector[0], &arg->vector[1], &arg->vector[2]); #endif break; case TYPE_FLOAT: - arg->_float = atof(main_params_data[i].value); + arg->_float = atof(main_params[i].value); break; case TYPE_STRING: - arg->string = prog_tempstring(prog, main_params_data[i].value); + arg->string = prog_tempstring(prog, main_params[i].value); break; default: - printf("error: unhandled parameter type: %i\n", main_params_data[i].vtype); + printf("error: unhandled parameter type: %i\n", main_params[i].vtype); break; } } @@ -925,12 +872,7 @@ int main(int argc, char **argv) usage(); p.value = argv[1]; - if (main_params_add(p) < 0) { - if (main_params_data) - mem_d(main_params_data); - printf("cannot add parameter\n"); - exit(1); - } + vec_push(main_params, p); --argc; ++argv; } @@ -947,14 +889,13 @@ int main(int argc, char **argv) prog->builtins = qc_builtins; prog->builtins_count = qc_builtins_count; - prog->builtins_alloc = 0; if (opts_info) { printf("Program's system-checksum = 0x%04x\n", (int)prog->crc16); printf("Entity field space: %i\n", (int)prog->entityfields); } - for (i = 1; i < prog->functions_count; ++i) { + for (i = 1; i < vec_size(prog->functions); ++i) { const char *name = prog_getstring(prog, prog->functions[i].name); /* printf("Found function: %s\n", name); */ if (!strcmp(name, "main")) @@ -965,12 +906,12 @@ int main(int argc, char **argv) return 0; } if (opts_disasm) { - for (i = 1; i < prog->functions_count; ++i) + for (i = 1; i < vec_size(prog->functions); ++i) prog_disasm_function(prog, i); return 0; } if (opts_printdefs) { - for (i = 0; i < prog->defs_count; ++i) { + for (i = 0; i < vec_size(prog->defs); ++i) { printf("Global: %8s %-16s at %u\n", type_name[prog->defs[i].type & DEF_TYPEMASK], prog_getstring(prog, prog->defs[i].name), @@ -978,7 +919,7 @@ int main(int argc, char **argv) } } else if (opts_printfields) { - for (i = 0; i < prog->fields_count; ++i) { + for (i = 0; i < vec_size(prog->fields); ++i) { printf("Field: %8s %-16s at %u\n", type_name[prog->fields[i].type], prog_getstring(prog, prog->fields[i].name), @@ -1068,7 +1009,7 @@ while (1) { GLOBAL(OFS_RETURN)->ivector[2] = OPA->ivector[2]; st = prog->code + prog_leavefunction(prog); - if (!prog->stack_count) + if (!vec_size(prog->stack)) goto cleanup; break; @@ -1236,7 +1177,7 @@ while (1) { case INSTR_STOREP_ENT: case INSTR_STOREP_FLD: case INSTR_STOREP_FNC: - if (OPB->_int < 0 || OPB->_int >= prog->entitydata_count) { + if (OPB->_int < 0 || OPB->_int >= vec_size(prog->entitydata)) { qcvmerror(prog, "`%s` attempted to write to an out of bounds edict (%i)", prog->filename, OPB->_int); goto cleanup; } @@ -1249,7 +1190,7 @@ while (1) { ptr->_int = OPA->_int; break; case INSTR_STOREP_V: - if (OPB->_int < 0 || OPB->_int + 2 >= prog->entitydata_count) { + if (OPB->_int < 0 || OPB->_int + 2 >= vec_size(prog->entitydata)) { qcvmerror(prog, "`%s` attempted to write to an out of bounds edict (%i)", prog->filename, OPB->_int); goto cleanup; } @@ -1314,7 +1255,7 @@ while (1) { if (!OPA->function) qcvmerror(prog, "NULL function in `%s`", prog->filename); - if(!OPA->function || OPA->function >= (unsigned int)prog->functions_count) + if(!OPA->function || OPA->function >= (unsigned int)vec_size(prog->functions)) { qcvmerror(prog, "CALL outside the program in `%s`", prog->filename); goto cleanup; diff --git a/gmqcc.h b/gmqcc.h index c8440cc..d25ac3b 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -191,8 +191,9 @@ typedef char intptr_size_is_correct [sizeof(uintptr_t)== sizeof(int*)?1:-1]; /*===================================================================*/ FILE *util_fopen(const char *filename, const char *mode); -void *util_memory_a (unsigned int, unsigned int, const char *); +void *util_memory_a (size_t, unsigned int, const char *); void util_memory_d (void *, unsigned int, const char *); +void *util_memory_r (void *, size_t, unsigned int, const char *); void util_meminfo (); bool util_strupper (const char *); @@ -214,11 +215,13 @@ uint16_t util_crc16(uint16_t crc, const char *data, size_t len); uint32_t util_crc32(uint32_t crc, const char *data, size_t len); #ifdef NOTRACK -# define mem_a(x) malloc(x) -# define mem_d(x) free (x) +# define mem_a(x) malloc(x) +# define mem_d(x) free (x) +# define mem_r(x, n) free (x, n) #else -# define mem_a(x) util_memory_a((x), __LINE__, __FILE__) -# define mem_d(x) util_memory_d((x), __LINE__, __FILE__) +# define mem_a(x) util_memory_a((x), __LINE__, __FILE__) +# define mem_d(x) util_memory_d((x), __LINE__, __FILE__) +# define mem_r(x, n) util_memory_r((x), (n), __LINE__, __FILE__) #endif /* @@ -229,50 +232,27 @@ uint32_t util_crc32(uint32_t crc, const char *data, size_t len); #define FLT2INT(Y) *((int32_t*)&(Y)) #define INT2FLT(Y) *((float *)&(Y)) -/* Builds vector type (usefull for inside structures) */ -#define VECTOR_SNAP(X,Y) X ## Y -#define VECTOR_FILL(X,Y) VECTOR_SNAP(X,Y) -#define VECTOR_TYPE(T,N) \ - T* N##_data = NULL; \ - long N##_elements = 0; \ - long N##_allocated = 0 -/* Builds vector add */ -#define VECTOR_CORE(T,N) \ - int N##_add(T element) { \ - void *temp = NULL; \ - if (N##_elements == N##_allocated) { \ - if (N##_allocated == 0) { \ - N##_allocated = 12; \ - } else { \ - N##_allocated *= 2; \ - } \ - if (!(temp = mem_a(N##_allocated * sizeof(T)))) { \ - mem_d(temp); \ - return -1; \ - } \ - memcpy(temp, N##_data, (N##_elements * sizeof(T))); \ - mem_d(N##_data); \ - N##_data = (T*)temp; \ - } \ - N##_data[N##_elements] = element; \ - return N##_elements++; \ - } \ - int N##_put(T* elements, size_t len) { \ - len --; \ - elements--; \ - while (N##_add(*++elements) != -1 && len--); \ - return N##_elements; \ - } \ - typedef char VECTOR_FILL(extra_semicolon_##N,__COUNTER__) -#define VECTOR_PROT(T,N) \ - extern T* N##_data ; \ - extern long N##_elements ; \ - extern long N##_allocated; \ - int N##_add(T); \ - int N##_put(T *, size_t) -#define VECTOR_MAKE(T,N) \ - VECTOR_TYPE(T,N); \ - VECTOR_CORE(T,N) +/* New flexible vector implementation from Dale */ +#define _vec_raw(A) (((size_t*)(A)) - 2) +#define _vec_beg(A) (_vec_raw(A)[0]) +#define _vec_end(A) (_vec_raw(A)[1]) +#define _vec_needsgrow(A,N) ((!(A)) || (_vec_end(A) + (N) >= _vec_beg(A))) +#define _vec_mightgrow(A,N) (_vec_needsgrow((A), (N)) ? _vec_forcegrow((A),(N)) : 0) +#define _vec_forcegrow(A,N) _util_vec_grow((void**)&(A), (N), sizeof(*(A))) +void _util_vec_grow(void **a, size_t i, size_t s); +/* exposed interface */ +#define vec_free(A) ((A) ? (mem_d(_vec_raw(A)), (A) = NULL) : 0) +#define vec_push(A,V) (_vec_mightgrow((A),1), (A)[_vec_end(A)++] = (V)) +#define vec_size(A) ((A) ? _vec_end(A) : 0) +#define vec_add(A,N) (_vec_mightgrow((A),(N)), _vec_end(A)+=(N), &(A)[_vec_end(A)-(N)]) +#define vec_last(A) ((A)[_vec_end(A)-1]) +#define vec_append(A,N,S) memcpy(vec_add((A), (N)), (S), N * sizeof(*(S))) +#define _vec_remove(A,S,I,N) (memmove((char*)(A)+(I)*(S),(char*)(A)+((I)+(N))*(S),(S)*(vec_size(A)-(I)-(N))), _vec_end(A)-=(N)) +#define vec_remove(A,I,N) _vec_remove((A), sizeof(*(A)), (I), (N)) +#define vec_pop(A) vec_remove((A), _vec_end(A)-1, 1) +/* these are supposed to NOT reallocate */ +#define vec_shrinkto(A,N) (_vec_end(A) = (N)) +#define vec_shrinkby(A,N) (_vec_end(A) -= (N)) /*===================================================================*/ /*=========================== code.c ================================*/ @@ -499,24 +479,12 @@ enum { VINSTR_COND }; -/* - * The symbols below are created by the following - * expanded macros: - * - * VECTOR_MAKE(prog_section_statement, code_statements); - * VECTOR_MAKE(prog_section_def, code_defs ); - * VECTOR_MAKE(prog_section_field, code_fields ); - * VECTOR_MAKE(prog_section_function, code_functions ); - * VECTOR_MAKE(int, code_globals ); - * VECTOR_MAKE(char, code_chars ); - */ -VECTOR_PROT(prog_section_statement, code_statements); -VECTOR_PROT(prog_section_statement, code_statements); -VECTOR_PROT(prog_section_def, code_defs ); -VECTOR_PROT(prog_section_field, code_fields ); -VECTOR_PROT(prog_section_function, code_functions ); -VECTOR_PROT(int, code_globals ); -VECTOR_PROT(char, code_chars ); +extern prog_section_statement *code_statements; +extern prog_section_def *code_defs; +extern prog_section_field *code_fields; +extern prog_section_function *code_functions; +extern int *code_globals; +extern char *code_chars; extern uint16_t code_crc; typedef float qcfloat; @@ -900,16 +868,16 @@ typedef struct { typedef struct qc_program_s { char *filename; - MEM_VECTOR_MAKE(prog_section_statement, code); - MEM_VECTOR_MAKE(prog_section_def, defs); - MEM_VECTOR_MAKE(prog_section_def, fields); - MEM_VECTOR_MAKE(prog_section_function, functions); - MEM_VECTOR_MAKE(char, strings); - MEM_VECTOR_MAKE(qcint, globals); - MEM_VECTOR_MAKE(qcint, entitydata); - MEM_VECTOR_MAKE(bool, entitypool); + prog_section_statement *code; + prog_section_def *defs; + prog_section_def *fields; + prog_section_function *functions; + char *strings; + qcint *globals; + qcint *entitydata; + bool *entitypool; - MEM_VECTOR_MAKE(const char*, function_stack); + const char* *function_stack; uint16_t crc16; @@ -918,17 +886,18 @@ typedef struct qc_program_s { qcint vmerror; - MEM_VECTOR_MAKE(size_t, profile); + size_t *profile; - MEM_VECTOR_MAKE(prog_builtin, builtins); + prog_builtin *builtins; + size_t builtins_count; /* size_t ip; */ qcint entities; size_t entityfields; bool allowworldwrites; - MEM_VECTOR_MAKE(qcint, localstack); - MEM_VECTOR_MAKE(qc_exec_stack, stack); + qcint *localstack; + qc_exec_stack *stack; size_t statement; size_t xflags; diff --git a/ir.c b/ir.c index 4ae49d9..1a99150 100644 --- a/ir.c +++ b/ir.c @@ -171,8 +171,6 @@ uint16_t type_ne_instr[TYPE_COUNT] = { AINSTR_END, /* array */ }; -MEM_VEC_FUNCTIONS(ir_value_vector, ir_value*, v) - static void irerror(lex_ctx ctx, const char *msg, ...) { va_list ap; @@ -200,7 +198,50 @@ static bool irwarning(lex_ctx ctx, int warntype, const char *fmt, ...) } /*********************************************************************** - *IR Builder + * Vector utility functions + */ + +bool GMQCC_WARN vec_ir_value_find(ir_value **vec, ir_value *what, size_t *idx) +{ + size_t i; + size_t len = vec_size(vec); + for (i = 0; i < len; ++i) { + if (vec[i] == what) { + if (idx) *idx = i; + return true; + } + } + return false; +} + +bool GMQCC_WARN vec_ir_block_find(ir_block **vec, ir_block *what, size_t *idx) +{ + size_t i; + size_t len = vec_size(vec); + for (i = 0; i < len; ++i) { + if (vec[i] == what) { + if (idx) *idx = i; + return true; + } + } + return false; +} + +bool GMQCC_WARN vec_ir_instr_find(ir_instr **vec, ir_instr *what, size_t *idx) +{ + size_t i; + size_t len = vec_size(vec); + for (i = 0; i < len; ++i) { + if (vec[i] == what) { + if (idx) *idx = i; + return true; + } + } + return false; +} + +/*********************************************************************** + * IR Builder */ static void ir_block_delete_quick(ir_block* self); @@ -215,11 +256,12 @@ ir_builder* ir_builder_new(const char *modulename) if (!self) return NULL; - MEM_VECTOR_INIT(self, functions); - MEM_VECTOR_INIT(self, globals); - MEM_VECTOR_INIT(self, fields); - MEM_VECTOR_INIT(self, filenames); - MEM_VECTOR_INIT(self, filestrings); + self->functions = NULL; + self->globals = NULL; + self->fields = NULL; + self->filenames = NULL; + self->filestrings = NULL; + self->str_immediate = 0; self->name = NULL; if (!ir_builder_set_name(self, modulename)) { @@ -230,30 +272,24 @@ ir_builder* ir_builder_new(const char *modulename) return self; } -MEM_VEC_FUNCTIONS(ir_builder, ir_value*, globals) -MEM_VEC_FUNCTIONS(ir_builder, ir_value*, fields) -MEM_VEC_FUNCTIONS(ir_builder, ir_function*, functions) -MEM_VEC_FUNCTIONS(ir_builder, const char*, filenames) -MEM_VEC_FUNCTIONS(ir_builder, qcint, filestrings) - void ir_builder_delete(ir_builder* self) { size_t i; mem_d((void*)self->name); - for (i = 0; i != self->functions_count; ++i) { + for (i = 0; i != vec_size(self->functions); ++i) { ir_function_delete_quick(self->functions[i]); } - MEM_VECTOR_CLEAR(self, functions); - for (i = 0; i != self->globals_count; ++i) { + vec_free(self->functions); + for (i = 0; i != vec_size(self->globals); ++i) { ir_value_delete(self->globals[i]); } - MEM_VECTOR_CLEAR(self, globals); - for (i = 0; i != self->fields_count; ++i) { + vec_free(self->globals); + for (i = 0; i != vec_size(self->fields); ++i) { ir_value_delete(self->fields[i]); } - MEM_VECTOR_CLEAR(self, fields); - MEM_VECTOR_CLEAR(self, filenames); - MEM_VECTOR_CLEAR(self, filestrings); + vec_free(self->fields); + vec_free(self->filenames); + vec_free(self->filestrings); mem_d(self); } @@ -268,7 +304,7 @@ bool ir_builder_set_name(ir_builder *self, const char *name) ir_function* ir_builder_get_function(ir_builder *self, const char *name) { size_t i; - for (i = 0; i < self->functions_count; ++i) { + for (i = 0; i < vec_size(self->functions); ++i) { if (!strcmp(name, self->functions[i]->name)) return self->functions[i]; } @@ -283,12 +319,12 @@ ir_function* ir_builder_create_function(ir_builder *self, const char *name, int } fn = ir_function_new(self, outtype); - if (!ir_function_set_name(fn, name) || - !ir_builder_functions_add(self, fn) ) + if (!ir_function_set_name(fn, name)) { ir_function_delete(fn); return NULL; } + vec_push(self->functions, fn); fn->value = ir_builder_create_global(self, fn->name, TYPE_FUNCTION); if (!fn->value) { @@ -307,7 +343,7 @@ ir_function* ir_builder_create_function(ir_builder *self, const char *name, int ir_value* ir_builder_get_global(ir_builder *self, const char *name) { size_t i; - for (i = 0; i < self->globals_count; ++i) { + for (i = 0; i < vec_size(self->globals); ++i) { if (!strcmp(self->globals[i]->name, name)) return self->globals[i]; } @@ -327,17 +363,14 @@ ir_value* ir_builder_create_global(ir_builder *self, const char *name, int vtype } ve = ir_value_var(name, store_global, vtype); - if (!ir_builder_globals_add(self, ve)) { - ir_value_delete(ve); - return NULL; - } + vec_push(self->globals, ve); return ve; } ir_value* ir_builder_get_field(ir_builder *self, const char *name) { size_t i; - for (i = 0; i < self->fields_count; ++i) { + for (i = 0; i < vec_size(self->fields); ++i) { if (!strcmp(self->fields[i]->name, name)) return self->fields[i]; } @@ -354,10 +387,7 @@ ir_value* ir_builder_create_field(ir_builder *self, const char *name, int vtype) ve = ir_value_var(name, store_global, TYPE_FIELD); ve->fieldtype = vtype; - if (!ir_builder_fields_add(self, ve)) { - ir_value_delete(ve); - return NULL; - } + vec_push(self->fields, ve); return ve; } @@ -391,10 +421,11 @@ ir_function* ir_function_new(ir_builder* owner, int outtype) self->outtype = outtype; self->value = NULL; self->builtin = 0; - MEM_VECTOR_INIT(self, params); - MEM_VECTOR_INIT(self, blocks); - MEM_VECTOR_INIT(self, values); - MEM_VECTOR_INIT(self, locals); + + self->params = NULL; + self->blocks = NULL; + self->values = NULL; + self->locals = NULL; self->code_function_def = -1; self->allocated_locals = 0; @@ -402,10 +433,6 @@ ir_function* ir_function_new(ir_builder* owner, int outtype) self->run_id = 0; return self; } -MEM_VEC_FUNCTIONS(ir_function, ir_value*, values) -MEM_VEC_FUNCTIONS(ir_function, ir_block*, blocks) -MEM_VEC_FUNCTIONS(ir_function, ir_value*, locals) -MEM_VEC_FUNCTIONS(ir_function, int, params) bool ir_function_set_name(ir_function *self, const char *name) { @@ -420,19 +447,19 @@ static void ir_function_delete_quick(ir_function *self) size_t i; mem_d((void*)self->name); - for (i = 0; i != self->blocks_count; ++i) + for (i = 0; i != vec_size(self->blocks); ++i) ir_block_delete_quick(self->blocks[i]); - MEM_VECTOR_CLEAR(self, blocks); + vec_free(self->blocks); - MEM_VECTOR_CLEAR(self, params); + vec_free(self->params); - for (i = 0; i != self->values_count; ++i) + for (i = 0; i != vec_size(self->values); ++i) ir_value_delete(self->values[i]); - MEM_VECTOR_CLEAR(self, values); + vec_free(self->values); - for (i = 0; i != self->locals_count; ++i) + for (i = 0; i != vec_size(self->locals); ++i) ir_value_delete(self->locals[i]); - MEM_VECTOR_CLEAR(self, locals); + vec_free(self->locals); /* self->value is deleted by the builder */ @@ -444,38 +471,35 @@ void ir_function_delete(ir_function *self) size_t i; mem_d((void*)self->name); - for (i = 0; i != self->blocks_count; ++i) + for (i = 0; i != vec_size(self->blocks); ++i) ir_block_delete(self->blocks[i]); - MEM_VECTOR_CLEAR(self, blocks); + vec_free(self->blocks); - MEM_VECTOR_CLEAR(self, params); + vec_free(self->params); - for (i = 0; i != self->values_count; ++i) + for (i = 0; i != vec_size(self->values); ++i) ir_value_delete(self->values[i]); - MEM_VECTOR_CLEAR(self, values); + vec_free(self->values); - for (i = 0; i != self->locals_count; ++i) + for (i = 0; i != vec_size(self->locals); ++i) ir_value_delete(self->locals[i]); - MEM_VECTOR_CLEAR(self, locals); + vec_free(self->locals); /* self->value is deleted by the builder */ mem_d(self); } -bool GMQCC_WARN ir_function_collect_value(ir_function *self, ir_value *v) +void ir_function_collect_value(ir_function *self, ir_value *v) { - return ir_function_values_add(self, v); + vec_push(self->values, v); } ir_block* ir_function_create_block(ir_function *self, const char *label) { ir_block* bn = ir_block_new(self, label); memcpy(&bn->context, &self->context, sizeof(self->context)); - if (!ir_function_blocks_add(self, bn)) { - ir_block_delete(bn); - return NULL; - } + vec_push(self->blocks, bn); return bn; } @@ -500,7 +524,7 @@ bool ir_function_finalize(ir_function *self) ir_value* ir_function_get_local(ir_function *self, const char *name) { size_t i; - for (i = 0; i < self->locals_count; ++i) { + for (i = 0; i < vec_size(self->locals); ++i) { if (!strcmp(self->locals[i]->name, name)) return self->locals[i]; } @@ -517,17 +541,14 @@ ir_value* ir_function_create_local(ir_function *self, const char *name, int vtyp */ if (param && - self->locals_count && - self->locals[self->locals_count-1]->store != store_param) { + vec_size(self->locals) && + self->locals[vec_size(self->locals)-1]->store != store_param) { irerror(self->context, "cannot add parameters after adding locals"); return NULL; } ve = ir_value_var(name, (param ? store_param : store_local), vtype); - if (!ir_function_locals_add(self, ve)) { - ir_value_delete(ve); - return NULL; - } + vec_push(self->locals, ve); return ve; } @@ -553,34 +574,32 @@ ir_block* ir_block_new(ir_function* owner, const char *name) self->context.file = "<@no context>"; self->context.line = 0; self->final = false; - MEM_VECTOR_INIT(self, instr); - MEM_VECTOR_INIT(self, entries); - MEM_VECTOR_INIT(self, exits); + + self->instr = NULL; + self->entries = NULL; + self->exits = NULL; self->eid = 0; self->is_return = false; self->run_id = 0; - MEM_VECTOR_INIT(self, living); + + self->living = NULL; self->generated = false; return self; } -MEM_VEC_FUNCTIONS(ir_block, ir_instr*, instr) -MEM_VEC_FUNCTIONS_ALL(ir_block, ir_block*, entries) -MEM_VEC_FUNCTIONS_ALL(ir_block, ir_block*, exits) -MEM_VEC_FUNCTIONS_ALL(ir_block, ir_value*, living) static void ir_block_delete_quick(ir_block* self) { size_t i; if (self->label) mem_d(self->label); - for (i = 0; i != self->instr_count; ++i) + for (i = 0; i != vec_size(self->instr); ++i) ir_instr_delete_quick(self->instr[i]); - MEM_VECTOR_CLEAR(self, instr); - MEM_VECTOR_CLEAR(self, entries); - MEM_VECTOR_CLEAR(self, exits); - MEM_VECTOR_CLEAR(self, living); + vec_free(self->instr); + vec_free(self->entries); + vec_free(self->exits); + vec_free(self->living); mem_d(self); } @@ -588,12 +607,12 @@ void ir_block_delete(ir_block* self) { size_t i; if (self->label) mem_d(self->label); - for (i = 0; i != self->instr_count; ++i) + for (i = 0; i != vec_size(self->instr); ++i) ir_instr_delete(self->instr[i]); - MEM_VECTOR_CLEAR(self, instr); - MEM_VECTOR_CLEAR(self, entries); - MEM_VECTOR_CLEAR(self, exits); - MEM_VECTOR_CLEAR(self, living); + vec_free(self->instr); + vec_free(self->entries); + vec_free(self->exits); + vec_free(self->living); mem_d(self); } @@ -625,19 +644,18 @@ ir_instr* ir_instr_new(ir_block* owner, int op) self->_ops[2] = NULL; self->bops[0] = NULL; self->bops[1] = NULL; - MEM_VECTOR_INIT(self, phi); - MEM_VECTOR_INIT(self, params); + + self->phi = NULL; + self->params = NULL; self->eid = 0; return self; } -MEM_VEC_FUNCTIONS(ir_instr, ir_phi_entry_t, phi) -MEM_VEC_FUNCTIONS(ir_instr, ir_value*, params) static void ir_instr_delete_quick(ir_instr *self) { - MEM_VECTOR_CLEAR(self, phi); - MEM_VECTOR_CLEAR(self, params); + vec_free(self->phi); + vec_free(self->params); mem_d(self); } @@ -650,25 +668,25 @@ void ir_instr_delete(ir_instr *self) * gcc doesn't care about an explicit: (void)foo(); to ignore the result, * I have to improvise here and use if(foo()); */ - for (i = 0; i < self->phi_count; ++i) { + for (i = 0; i < vec_size(self->phi); ++i) { size_t idx; - if (ir_value_writes_find(self->phi[i].value, self, &idx)) - if (ir_value_writes_remove(self->phi[i].value, idx)) GMQCC_SUPPRESS_EMPTY_BODY; - if (ir_value_reads_find(self->phi[i].value, self, &idx)) - if (ir_value_reads_remove (self->phi[i].value, idx)) GMQCC_SUPPRESS_EMPTY_BODY; + if (vec_ir_instr_find(self->phi[i].value->writes, self, &idx)) + vec_remove(self->phi[i].value->writes, idx, 1); + if (vec_ir_instr_find(self->phi[i].value->reads, self, &idx)) + vec_remove(self->phi[i].value->reads, idx, 1); } - MEM_VECTOR_CLEAR(self, phi); - for (i = 0; i < self->params_count; ++i) { + vec_free(self->phi); + for (i = 0; i < vec_size(self->params); ++i) { size_t idx; - if (ir_value_writes_find(self->params[i], self, &idx)) - if (ir_value_writes_remove(self->params[i], idx)) GMQCC_SUPPRESS_EMPTY_BODY; - if (ir_value_reads_find(self->params[i], self, &idx)) - if (ir_value_reads_remove (self->params[i], idx)) GMQCC_SUPPRESS_EMPTY_BODY; + if (vec_ir_instr_find(self->params[i]->writes, self, &idx)) + vec_remove(self->params[i]->writes, idx, 1); + if (vec_ir_instr_find(self->params[i]->reads, self, &idx)) + vec_remove(self->params[i]->reads, idx, 1); } - MEM_VECTOR_CLEAR(self, params); - if (ir_instr_op(self, 0, NULL, false)) GMQCC_SUPPRESS_EMPTY_BODY; - if (ir_instr_op(self, 1, NULL, false)) GMQCC_SUPPRESS_EMPTY_BODY; - if (ir_instr_op(self, 2, NULL, false)) GMQCC_SUPPRESS_EMPTY_BODY; + vec_free(self->params); + (void)!ir_instr_op(self, 0, NULL, false); + (void)!ir_instr_op(self, 1, NULL, false); + (void)!ir_instr_op(self, 2, NULL, false); mem_d(self); } @@ -676,25 +694,16 @@ bool ir_instr_op(ir_instr *self, int op, ir_value *v, bool writing) { if (self->_ops[op]) { size_t idx; - if (writing && ir_value_writes_find(self->_ops[op], self, &idx)) - { - if (!ir_value_writes_remove(self->_ops[op], idx)) - return false; - } - else if (ir_value_reads_find(self->_ops[op], self, &idx)) - { - if (!ir_value_reads_remove(self->_ops[op], idx)) - return false; - } + if (writing && vec_ir_instr_find(self->_ops[op]->writes, self, &idx)) + vec_remove(self->_ops[op]->writes, idx, 1); + else if (vec_ir_instr_find(self->_ops[op]->reads, self, &idx)) + vec_remove(self->_ops[op]->reads, idx, 1); } if (v) { - if (writing) { - if (!ir_value_writes_add(v, self)) - return false; - } else { - if (!ir_value_reads_add(v, self)) - return false; - } + if (writing) + vec_push(v->writes, self); + else + vec_push(v->reads, self); } self->_ops[op] = v; return true; @@ -727,8 +736,10 @@ ir_value* ir_value_var(const char *name, int storetype, int vtype) self->fieldtype = TYPE_VOID; self->outtype = TYPE_VOID; self->store = storetype; - MEM_VECTOR_INIT(self, reads); - MEM_VECTOR_INIT(self, writes); + + self->reads = NULL; + self->writes = NULL; + self->isconst = false; self->context.file = "<@no context>"; self->context.line = 0; @@ -747,7 +758,7 @@ ir_value* ir_value_var(const char *name, int storetype, int vtype) self->members[2] = NULL; self->memberof = NULL; - MEM_VECTOR_INIT(self, life); + self->life = NULL; return self; } @@ -793,20 +804,12 @@ ir_value* ir_value_vector_member(ir_value *self, unsigned int member) return m; } -MEM_VEC_FUNCTIONS(ir_value, ir_life_entry_t, life) -MEM_VEC_FUNCTIONS_ALL(ir_value, ir_instr*, reads) -MEM_VEC_FUNCTIONS_ALL(ir_value, ir_instr*, writes) - ir_value* ir_value_out(ir_function *owner, const char *name, int storetype, int vtype) { ir_value *v = ir_value_var(name, storetype, vtype); if (!v) return NULL; - if (!ir_function_collect_value(owner, v)) - { - ir_value_delete(v); - return NULL; - } + ir_function_collect_value(owner, v); return v; } @@ -824,9 +827,9 @@ void ir_value_delete(ir_value* self) if (self->members[i]) ir_value_delete(self->members[i]); } - MEM_VECTOR_CLEAR(self, reads); - MEM_VECTOR_CLEAR(self, writes); - MEM_VECTOR_CLEAR(self, life); + vec_free(self->reads); + vec_free(self->writes); + vec_free(self->life); mem_d(self); } @@ -908,7 +911,7 @@ bool ir_value_set_int(ir_value *self, int i) bool ir_value_lives(ir_value *self, size_t at) { size_t i; - for (i = 0; i < self->life_count; ++i) + for (i = 0; i < vec_size(self->life); ++i) { ir_life_entry_t *life = &self->life[i]; if (life->start <= at && at <= life->end) @@ -922,9 +925,8 @@ bool ir_value_lives(ir_value *self, size_t at) bool ir_value_life_insert(ir_value *self, size_t idx, ir_life_entry_t e) { size_t k; - if (!ir_value_life_add(self, e)) /* naive... */ - return false; - for (k = self->life_count-1; k > idx; --k) + vec_push(self->life, e); + for (k = vec_size(self->life)-1; k > idx; --k) self->life[k] = self->life[k-1]; self->life[idx] = e; return true; @@ -938,7 +940,7 @@ bool ir_value_life_merge(ir_value *self, size_t s) ir_life_entry_t new_entry; /* Find the first range >= s */ - for (i = 0; i < self->life_count; ++i) + for (i = 0; i < vec_size(self->life); ++i) { before = life; life = &self->life[i]; @@ -946,7 +948,7 @@ bool ir_value_life_merge(ir_value *self, size_t s) break; } /* nothing found? append */ - if (i == self->life_count) { + if (i == vec_size(self->life)) { ir_life_entry_t e; if (life && life->end+1 == s) { @@ -957,8 +959,7 @@ bool ir_value_life_merge(ir_value *self, size_t s) if (life && life->end >= s) return false; e.start = e.end = s; - if (!ir_value_life_add(self, e)) - return false; /* failing */ + vec_push(self->life, e); return true; } /* found */ @@ -969,8 +970,7 @@ bool ir_value_life_merge(ir_value *self, size_t s) { /* merge */ before->end = life->end; - if (!ir_value_life_remove(self, i)) - return false; /* failing */ + vec_remove(self->life, i, 1); return true; } if (before->end + 1 == s) @@ -998,19 +998,18 @@ bool ir_value_life_merge_into(ir_value *self, const ir_value *other) { size_t i, myi; - if (!other->life_count) + if (!vec_size(other->life)) return true; - if (!self->life_count) { - for (i = 0; i < other->life_count; ++i) { - if (!ir_value_life_add(self, other->life[i])) - return false; - } + if (!vec_size(self->life)) { + size_t count = vec_size(other->life); + ir_life_entry_t *life = vec_add(self->life, count); + memcpy(life, other->life, count * sizeof(*life)); return true; } myi = 0; - for (i = 0; i < other->life_count; ++i) + for (i = 0; i < vec_size(other->life); ++i) { const ir_life_entry_t *life = &other->life[i]; while (true) @@ -1041,14 +1040,13 @@ bool ir_value_life_merge_into(ir_value *self, const ir_value *other) } /* see if our change combines it with the next ranges */ - while (myi+1 < self->life_count && + while (myi+1 < vec_size(self->life) && entry->end+1 >= self->life[1+myi].start) { /* overlaps with (myi+1) */ if (entry->end < self->life[1+myi].end) entry->end = self->life[1+myi].end; - if (!ir_value_life_remove(self, myi+1)) - return false; + vec_remove(self->life, myi+1, 1); entry = &self->life[myi]; } @@ -1057,9 +1055,8 @@ bool ir_value_life_merge_into(ir_value *self, const ir_value *other) { ++myi; /* append if we're at the end */ - if (myi >= self->life_count) { - if (!ir_value_life_add(self, *life)) - return false; + if (myi >= vec_size(self->life)) { + vec_push(self->life, *life); break; } /* otherweise check the next range */ @@ -1083,13 +1080,13 @@ bool ir_values_overlap(const ir_value *a, const ir_value *b) ir_life_entry_t *la, *lb, *enda, *endb; /* first of all, if either has no life range, they cannot clash */ - if (!a->life_count || !b->life_count) + if (!vec_size(a->life) || !vec_size(b->life)) return false; la = a->life; lb = b->life; - enda = la + a->life_count; - endb = lb + b->life_count; + enda = la + vec_size(a->life); + endb = lb + vec_size(b->life); while (true) { /* check if the entries overlap, for that, @@ -1145,11 +1142,11 @@ bool ir_block_create_store_op(ir_block *self, int op, ir_value *target, ir_value } if (!ir_instr_op(in, 0, target, true) || - !ir_instr_op(in, 1, what, false) || - !ir_block_instr_add(self, in) ) + !ir_instr_op(in, 1, what, false)) { return false; } + vec_push(self->instr, in); return true; } @@ -1216,8 +1213,7 @@ bool ir_block_create_return(ir_block *self, ir_value *v) if (v && !ir_instr_op(in, 0, v, false)) return false; - if (!ir_block_instr_add(self, in)) - return false; + vec_push(self->instr, in); return true; } @@ -1243,16 +1239,12 @@ bool ir_block_create_if(ir_block *self, ir_value *v, in->bops[0] = ontrue; in->bops[1] = onfalse; - if (!ir_block_instr_add(self, in)) - return false; + vec_push(self->instr, in); - if (!ir_block_exits_add(self, ontrue) || - !ir_block_exits_add(self, onfalse) || - !ir_block_entries_add(ontrue, self) || - !ir_block_entries_add(onfalse, self) ) - { - return false; - } + vec_push(self->exits, ontrue); + vec_push(self->exits, onfalse); + vec_push(ontrue->entries, self); + vec_push(onfalse->entries, self); return true; } @@ -1269,14 +1261,10 @@ bool ir_block_create_jump(ir_block *self, ir_block *to) return false; in->bops[0] = to; - if (!ir_block_instr_add(self, in)) - return false; + vec_push(self->instr, in); - if (!ir_block_exits_add(self, to) || - !ir_block_entries_add(to, self) ) - { - return false; - } + vec_push(self->exits, to); + vec_push(to->entries, self); return true; } @@ -1293,14 +1281,10 @@ bool ir_block_create_goto(ir_block *self, ir_block *to) return false; in->bops[0] = to; - if (!ir_block_instr_add(self, in)) - return false; + vec_push(self->instr, in); - if (!ir_block_exits_add(self, to) || - !ir_block_entries_add(to, self) ) - { - return false; - } + vec_push(self->exits, to); + vec_push(to->entries, self); return true; } @@ -1321,11 +1305,7 @@ ir_instr* ir_block_create_phi(ir_block *self, const char *label, int ot) ir_value_delete(out); return NULL; } - if (!ir_block_instr_add(self, in)) { - ir_instr_delete(in); - ir_value_delete(out); - return NULL; - } + vec_push(self->instr, in); return in; } @@ -1334,11 +1314,11 @@ ir_value* ir_phi_value(ir_instr *self) return self->_ops[0]; } -bool ir_phi_add(ir_instr* self, ir_block *b, ir_value *v) +void ir_phi_add(ir_instr* self, ir_block *b, ir_value *v) { ir_phi_entry_t pe; - if (!ir_block_entries_find(self->owner, b, NULL)) { + if (!vec_ir_block_find(self->owner->entries, b, NULL)) { /* Must not be possible to cause this, otherwise the AST * is doing something wrong. */ @@ -1348,9 +1328,8 @@ bool ir_phi_add(ir_instr* self, ir_block *b, ir_value *v) pe.value = v; pe.from = b; - if (!ir_value_reads_add(v, self)) - return false; - return ir_instr_phi_add(self, pe); + vec_push(v->reads, self); + vec_push(self->phi, pe); } /* call related code */ @@ -1367,13 +1346,13 @@ ir_instr* ir_block_create_call(ir_block *self, const char *label, ir_value *func return NULL; } if (!ir_instr_op(in, 0, out, true) || - !ir_instr_op(in, 1, func, false) || - !ir_block_instr_add(self, in)) + !ir_instr_op(in, 1, func, false)) { ir_instr_delete(in); ir_value_delete(out); return NULL; } + vec_push(self->instr, in); return in; } @@ -1382,16 +1361,10 @@ ir_value* ir_call_value(ir_instr *self) return self->_ops[0]; } -bool ir_call_param(ir_instr* self, ir_value *v) +void ir_call_param(ir_instr* self, ir_value *v) { - if (!ir_instr_params_add(self, v)) - return false; - if (!ir_value_reads_add(v, self)) { - if (!ir_instr_params_remove(self, self->params_count-1)) - GMQCC_SUPPRESS_EMPTY_BODY; - return false; - } - return true; + vec_push(self->params, v); + vec_push(v->reads, self); } /* binary op related code */ @@ -1544,8 +1517,7 @@ ir_value* ir_block_create_general_instr(ir_block *self, const char *label, goto on_error; } - if (!ir_block_instr_add(self, instr)) - goto on_error; + vec_push(self->instr, instr); return out; on_error: @@ -1778,7 +1750,7 @@ bool ir_function_naive_phi(ir_function *self) { size_t i; - for (i = 0; i < self->blocks_count; ++i) + for (i = 0; i < vec_size(self->blocks); ++i) { if (!ir_block_naive_phi(self->blocks[i])) return false; @@ -1796,8 +1768,8 @@ static bool ir_naive_phi_emit_store(ir_block *block, size_t iid, ir_value *old, return false; /* we now move it up */ - instr = block->instr[block->instr_count-1]; - for (i = block->instr_count; i > iid; --i) + instr = vec_last(block->instr); + for (i = vec_size(block->instr)-1; i > iid; --i) block->instr[i] = block->instr[i-1]; block->instr[i] = instr; @@ -1811,20 +1783,19 @@ static bool ir_block_naive_phi(ir_block *self) * to a list so we don't need to loop through blocks * - anyway: "don't optimize YET" */ - for (i = 0; i < self->instr_count; ++i) + for (i = 0; i < vec_size(self->instr); ++i) { ir_instr *instr = self->instr[i]; if (instr->opcode != VINSTR_PHI) continue; - if (!ir_block_instr_remove(self, i)) - return false; + vec_remove(self->instr, i, 1); --i; /* NOTE: i+1 below */ - for (p = 0; p < instr->phi_count; ++p) + for (p = 0; p < vec_size(instr->phi); ++p) { ir_value *v = instr->phi[p].value; - for (w = 0; w < v->writes_count; ++w) { + for (w = 0; w < vec_size(v->writes); ++w) { ir_value *old; if (!v->writes[w]->_ops[0]) @@ -1844,7 +1815,7 @@ static bool ir_block_naive_phi(ir_block *self) */ if (!ir_naive_phi_emit_store(self, i+1, old, v)) return false; - if (i+1 < self->instr_count) + if (i+1 < vec_size(self->instr)) instr = self->instr[i+1]; else instr = NULL; @@ -1857,11 +1828,11 @@ static bool ir_block_naive_phi(ir_block *self) { /* If it didn't, we can replace all reads by the phi target now. */ size_t r; - for (r = 0; r < old->reads_count; ++r) + for (r = 0; r < vec_size(old->reads); ++r) { size_t op; ir_instr *ri = old->reads[r]; - for (op = 0; op < ri->phi_count; ++op) { + for (op = 0; op < vec_size(ri->phi); ++op) { if (ri->phi[op].value == old) ri->phi[op].value = v; } @@ -1887,21 +1858,13 @@ static bool ir_block_naive_phi(ir_block *self) * Though this implementation might run an additional time for if nests. */ -typedef struct -{ - ir_value* *v; - size_t v_count; - size_t v_alloc; -} new_reads_t; -MEM_VEC_FUNCTIONS_ALL(new_reads_t, ir_value*, v) - /* Enumerate instructions used by value's life-ranges */ static void ir_block_enumerate(ir_block *self, size_t *_eid) { size_t i; size_t eid = *_eid; - for (i = 0; i < self->instr_count; ++i) + for (i = 0; i < vec_size(self->instr); ++i) { self->instr[i]->eid = eid++; } @@ -1917,7 +1880,7 @@ void ir_function_enumerate(ir_function *self) { size_t i; size_t instruction_id = 0; - for (i = 0; i < self->blocks_count; ++i) + for (i = 0; i < vec_size(self->blocks); ++i) { self->blocks[i]->eid = i; self->blocks[i]->run_id = 0; @@ -1934,19 +1897,19 @@ bool ir_function_calculate_liferanges(ir_function *self) do { self->run_id++; changed = false; - for (i = 0; i != self->blocks_count; ++i) + for (i = 0; i != vec_size(self->blocks); ++i) { if (self->blocks[i]->is_return) { - self->blocks[i]->living_count = 0; + vec_free(self->blocks[i]->living); if (!ir_block_life_propagate(self->blocks[i], NULL, &changed)) return false; } } } while (changed); - if (self->blocks_count) { + if (vec_size(self->blocks)) { ir_block *block = self->blocks[0]; - for (i = 0; i < block->living_count; ++i) { + for (i = 0; i < vec_size(block->living); ++i) { ir_value *v = block->living[i]; if (v->memberof || v->store != store_local) continue; @@ -1966,13 +1929,10 @@ bool ir_function_calculate_liferanges(ir_function *self) * This is the counterpart to register-allocation in register machines. */ typedef struct { - MEM_VECTOR_MAKE(ir_value*, locals); - MEM_VECTOR_MAKE(size_t, sizes); - MEM_VECTOR_MAKE(size_t, positions); + ir_value **locals; + size_t *sizes; + size_t *positions; } function_allocator; -MEM_VEC_FUNCTIONS(function_allocator, ir_value*, locals) -MEM_VEC_FUNCTIONS(function_allocator, size_t, sizes) -MEM_VEC_FUNCTIONS(function_allocator, size_t, positions) static bool function_allocator_alloc(function_allocator *alloc, const ir_value *var) { @@ -1986,11 +1946,8 @@ static bool function_allocator_alloc(function_allocator *alloc, const ir_value * if (!ir_value_life_merge_into(slot, var)) goto localerror; - if (!function_allocator_locals_add(alloc, slot)) - goto localerror; - - if (!function_allocator_sizes_add(alloc, vsize)) - goto localerror; + vec_push(alloc->locals, slot); + vec_push(alloc->sizes, vsize); return true; @@ -2010,28 +1967,28 @@ bool ir_function_allocate_locals(ir_function *self) function_allocator alloc; - if (!self->locals_count && !self->values_count) + if (!vec_size(self->locals) && !vec_size(self->values)) return true; - MEM_VECTOR_INIT(&alloc, locals); - MEM_VECTOR_INIT(&alloc, sizes); - MEM_VECTOR_INIT(&alloc, positions); + alloc.locals = NULL; + alloc.sizes = NULL; + alloc.positions = NULL; - for (i = 0; i < self->locals_count; ++i) + for (i = 0; i < vec_size(self->locals); ++i) { if (!function_allocator_alloc(&alloc, self->locals[i])) goto error; } /* Allocate a slot for any value that still exists */ - for (i = 0; i < self->values_count; ++i) + for (i = 0; i < vec_size(self->values); ++i) { v = self->values[i]; - if (!v->life_count) + if (!vec_size(v->life)) continue; - for (a = 0; a < alloc.locals_count; ++a) + for (a = 0; a < vec_size(alloc.locals); ++a) { slot = alloc.locals[a]; @@ -2048,8 +2005,8 @@ bool ir_function_allocate_locals(ir_function *self) self->values[i]->code.local = a; break; } - if (a >= alloc.locals_count) { - self->values[i]->code.local = alloc.locals_count; + if (a >= vec_size(alloc.locals)) { + self->values[i]->code.local = vec_size(alloc.locals); if (!function_allocator_alloc(&alloc, v)) goto error; } @@ -2060,24 +2017,22 @@ bool ir_function_allocate_locals(ir_function *self) } /* Adjust slot positions based on sizes */ - if (!function_allocator_positions_add(&alloc, 0)) - goto error; + vec_push(alloc.positions, 0); - if (alloc.sizes_count) + if (vec_size(alloc.sizes)) pos = alloc.positions[0] + alloc.sizes[0]; else pos = 0; - for (i = 1; i < alloc.sizes_count; ++i) + for (i = 1; i < vec_size(alloc.sizes); ++i) { pos = alloc.positions[i-1] + alloc.sizes[i-1]; - if (!function_allocator_positions_add(&alloc, pos)) - goto error; + vec_push(alloc.positions, pos); } - self->allocated_locals = pos + alloc.sizes[alloc.sizes_count-1]; + self->allocated_locals = pos + vec_last(alloc.sizes); /* Take over the actual slot positions */ - for (i = 0; i < self->values_count; ++i) { + for (i = 0; i < vec_size(self->values); ++i) { self->values[i]->code.local = alloc.positions[self->values[i]->code.local]; } @@ -2086,11 +2041,11 @@ bool ir_function_allocate_locals(ir_function *self) error: retval = false; cleanup: - for (i = 0; i < alloc.locals_count; ++i) + for (i = 0; i < vec_size(alloc.locals); ++i) ir_value_delete(alloc.locals[i]); - MEM_VECTOR_CLEAR(&alloc, locals); - MEM_VECTOR_CLEAR(&alloc, sizes); - MEM_VECTOR_CLEAR(&alloc, positions); + vec_free(alloc.locals); + vec_free(alloc.sizes); + vec_free(alloc.positions); return retval; } @@ -2138,7 +2093,7 @@ static bool ir_block_living_add_instr(ir_block *self, size_t eid) size_t i; bool changed = false; bool tempbool; - for (i = 0; i != self->living_count; ++i) + for (i = 0; i != vec_size(self->living); ++i) { tempbool = ir_value_life_merge(self->living[i], eid); /* debug @@ -2159,11 +2114,10 @@ static bool ir_block_life_prop_previous(ir_block* self, ir_block *prev, bool *ch * They will be re-added on-read, but the liferange merge won't cause * a change. */ - for (i = 0; i < self->living_count; ++i) + for (i = 0; i < vec_size(self->living); ++i) { - if (!ir_block_living_find(prev, self->living[i], NULL)) { - if (!ir_block_living_remove(self, i)) - return false; + if (!vec_ir_value_find(prev->living, self->living[i], NULL)) { + vec_remove(self->living, i, 1); --i; } } @@ -2171,12 +2125,11 @@ static bool ir_block_life_prop_previous(ir_block* self, ir_block *prev, bool *ch /* Whatever the previous block still has in its living set * must now be added to ours as well. */ - for (i = 0; i < prev->living_count; ++i) + for (i = 0; i < vec_size(prev->living); ++i) { - if (ir_block_living_find(self, prev->living[i], NULL)) + if (vec_ir_value_find(self->living, prev->living[i], NULL)) continue; - if (!ir_block_living_add(self, prev->living[i])) - return false; + vec_push(self->living, prev->living[i]); /* irerror(self->contextt from prev: %s", self->label, prev->living[i]->_name); */ @@ -2201,35 +2154,29 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change return false; } - i = self->instr_count; + i = vec_size(self->instr); while (i) { --i; instr = self->instr[i]; /* PHI operands are always read operands */ - for (p = 0; p < instr->phi_count; ++p) + for (p = 0; p < vec_size(instr->phi); ++p) { value = instr->phi[p].value; if (value->memberof) value = value->memberof; - if (!ir_block_living_find(self, value, NULL) && - !ir_block_living_add(self, value)) - { - return false; - } + if (!vec_ir_value_find(self->living, value, NULL)) + vec_push(self->living, value); } /* call params are read operands too */ - for (p = 0; p < instr->params_count; ++p) + for (p = 0; p < vec_size(instr->params); ++p) { value = instr->params[p]; if (value->memberof) value = value->memberof; - if (!ir_block_living_find(self, value, NULL) && - !ir_block_living_add(self, value)) - { - return false; - } + if (!vec_ir_value_find(self->living, value, NULL)) + vec_push(self->living, value); } /* See which operands are read and write operands */ @@ -2269,11 +2216,8 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change /* read operands */ if (read & (1<living, value, NULL)) + vec_push(self->living, value); } /* write operands */ @@ -2284,7 +2228,7 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change if (write & (1<living, value, &idx); if (!in_living) { /* If the value isn't alive it hasn't been read before... */ @@ -2314,8 +2258,7 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change */ *changed = *changed || tempbool; /* Then remove */ - if (!ir_block_living_remove(self, idx)) - return false; + vec_remove(self->living, idx, 1); } } } @@ -2331,7 +2274,7 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change self->run_id = self->owner->run_id; - for (i = 0; i < self->entries_count; ++i) + for (i = 0; i < vec_size(self->entries); ++i) { ir_block *entry = self->entries[i]; ir_block_life_propagate(entry, self, changed); @@ -2381,18 +2324,20 @@ static bool gen_global_field(ir_value *global) } /* copy the field's value */ - ir_value_code_setaddr(global, code_globals_add(code_globals_data[fld->code.globaladdr])); + ir_value_code_setaddr(global, vec_size(code_globals)); + vec_push(code_globals, code_globals[fld->code.globaladdr]); if (global->fieldtype == TYPE_VECTOR) { - code_globals_add(code_globals_data[fld->code.globaladdr]+1); - code_globals_add(code_globals_data[fld->code.globaladdr]+2); + vec_push(code_globals, code_globals[fld->code.globaladdr]+1); + vec_push(code_globals, code_globals[fld->code.globaladdr]+2); } } else { - ir_value_code_setaddr(global, code_globals_add(0)); + ir_value_code_setaddr(global, vec_size(code_globals)); + vec_push(code_globals, 0); if (global->fieldtype == TYPE_VECTOR) { - code_globals_add(0); - code_globals_add(0); + vec_push(code_globals, 0); + vec_push(code_globals, 0); } } if (global->code.globaladdr < 0) @@ -2426,11 +2371,13 @@ static bool gen_global_pointer(ir_value *global) return false; } - ir_value_code_setaddr(global, code_globals_add(target->code.globaladdr)); + ir_value_code_setaddr(global, vec_size(code_globals)); + vec_push(code_globals, target->code.globaladdr); } else { - ir_value_code_setaddr(global, code_globals_add(0)); + ir_value_code_setaddr(global, vec_size(code_globals)); + vec_push(code_globals, 0); } if (global->code.globaladdr < 0) return false; @@ -2449,8 +2396,8 @@ static bool gen_blocks_recursive(ir_function *func, ir_block *block) tailcall: block->generated = true; - block->code_start = code_statements_elements; - for (i = 0; i < block->instr_count; ++i) + block->code_start = vec_size(code_statements); + for (i = 0; i < vec_size(block->instr); ++i) { instr = block->instr[i]; @@ -2471,11 +2418,10 @@ tailcall: /* otherwise we generate a jump instruction */ stmt.opcode = INSTR_GOTO; - stmt.o1.s1 = (target->code_start) - code_statements_elements; + stmt.o1.s1 = (target->code_start) - vec_size(code_statements); stmt.o2.s1 = 0; stmt.o3.s1 = 0; - if (code_statements_add(stmt) < 0) - return false; + vec_push(code_statements, stmt); /* no further instructions can be in this block */ return true; @@ -2494,15 +2440,13 @@ tailcall: if (ontrue->generated) { stmt.opcode = INSTR_IF; - stmt.o2.s1 = (ontrue->code_start) - code_statements_elements; - if (code_statements_add(stmt) < 0) - return false; + stmt.o2.s1 = (ontrue->code_start) - vec_size(code_statements); + vec_push(code_statements, stmt); } if (onfalse->generated) { stmt.opcode = INSTR_IFNOT; - stmt.o2.s1 = (onfalse->code_start) - code_statements_elements; - if (code_statements_add(stmt) < 0) - return false; + stmt.o2.s1 = (onfalse->code_start) - vec_size(code_statements); + vec_push(code_statements, stmt); } if (!ontrue->generated) { if (onfalse->generated) { @@ -2518,24 +2462,24 @@ tailcall: } /* neither ontrue nor onfalse exist */ stmt.opcode = INSTR_IFNOT; - stidx = code_statements_elements; - if (code_statements_add(stmt) < 0) - return false; + stidx = vec_size(code_statements); + vec_push(code_statements, stmt); /* on false we jump, so add ontrue-path */ if (!gen_blocks_recursive(func, ontrue)) return false; /* fixup the jump address */ - code_statements_data[stidx].o2.s1 = code_statements_elements - stidx; + code_statements[stidx].o2.s1 = vec_size(code_statements) - stidx; /* generate onfalse path */ if (onfalse->generated) { /* fixup the jump address */ - code_statements_data[stidx].o2.s1 = (onfalse->code_start) - (stidx); + code_statements[stidx].o2.s1 = (onfalse->code_start) - (stidx); /* may have been generated in the previous recursive call */ stmt.opcode = INSTR_GOTO; - stmt.o1.s1 = (onfalse->code_start) - code_statements_elements; + stmt.o1.s1 = (onfalse->code_start) - vec_size(code_statements); stmt.o2.s1 = 0; stmt.o3.s1 = 0; - return (code_statements_add(stmt) >= 0); + vec_push(code_statements, stmt); + return true; } /* if not, generate now */ block = onfalse; @@ -2559,7 +2503,7 @@ tailcall: size_t p; ir_value *retvalue; - for (p = 0; p < instr->params_count; ++p) + for (p = 0; p < vec_size(instr->params); ++p) { ir_value *param = instr->params[p]; @@ -2572,20 +2516,18 @@ tailcall: stmt.opcode = type_store_instr[param->vtype]; stmt.o1.u1 = ir_value_code_addr(param); stmt.o2.u1 = OFS_PARM0 + 3 * p; - if (code_statements_add(stmt) < 0) - return false; + vec_push(code_statements, stmt); } - stmt.opcode = INSTR_CALL0 + instr->params_count; + stmt.opcode = INSTR_CALL0 + vec_size(instr->params); if (stmt.opcode > INSTR_CALL8) stmt.opcode = INSTR_CALL8; stmt.o1.u1 = ir_value_code_addr(instr->_ops[1]); stmt.o2.u1 = 0; stmt.o3.u1 = 0; - if (code_statements_add(stmt) < 0) - return false; + vec_push(code_statements, stmt); retvalue = instr->_ops[0]; - if (retvalue && retvalue->store != store_return && retvalue->life_count) + if (retvalue && retvalue->store != store_return && vec_size(retvalue->life)) { /* not to be kept in OFS_RETURN */ if (retvalue->vtype == TYPE_FIELD) @@ -2595,8 +2537,7 @@ tailcall: stmt.o1.u1 = OFS_RETURN; stmt.o2.u1 = ir_value_code_addr(retvalue); stmt.o3.u1 = 0; - if (code_statements_add(stmt) < 0) - return false; + vec_push(code_statements, stmt); } continue; } @@ -2636,8 +2577,7 @@ tailcall: stmt.o3.u1 = 0; } - if (code_statements_add(stmt) < 0) - return false; + vec_push(code_statements, stmt); } return true; } @@ -2650,7 +2590,7 @@ static bool gen_function_code(ir_function *self) /* Starting from entry point, we generate blocks "as they come" * for now. Dead blocks will not be translated obviously. */ - if (!self->blocks_count) { + if (!vec_size(self->blocks)) { irerror(self->context, "Function '%s' declared without body.", self->name); return false; } @@ -2669,8 +2609,7 @@ static bool gen_function_code(ir_function *self) stmt.o1.u1 = 0; stmt.o2.u1 = 0; stmt.o3.u1 = 0; - if (code_statements_add(stmt) < 0) - return false; + vec_push(code_statements, stmt); return true; } @@ -2682,16 +2621,14 @@ static qcint ir_builder_filestring(ir_builder *ir, const char *filename) size_t i; qcint str; - for (i = 0; i < ir->filenames_count; ++i) { + for (i = 0; i < vec_size(ir->filenames); ++i) { if (ir->filenames[i] == filename) return ir->filestrings[i]; } str = code_genstring(filename); - if (!ir_builder_filenames_add(ir, filename)) - return 0; - if (!ir_builder_filestrings_add(ir, str)) - ir->filenames_count--; + vec_push(ir->filenames, filename); + vec_push(ir->filestrings, str); return str; } @@ -2714,7 +2651,7 @@ static bool gen_global_function(ir_builder *ir, ir_value *global) fun.name = global->code.name; fun.file = ir_builder_filestring(ir, global->context.file); fun.profile = 0; /* always 0 */ - fun.nargs = irfun->params_count; + fun.nargs = vec_size(irfun->params); for (i = 0;i < 8; ++i) { if (i >= fun.nargs) @@ -2723,21 +2660,21 @@ static bool gen_global_function(ir_builder *ir, ir_value *global) fun.argsize[i] = type_sizeof[irfun->params[i]]; } - fun.firstlocal = code_globals_elements; + fun.firstlocal = vec_size(code_globals); local_var_end = fun.firstlocal; - for (i = 0; i < irfun->locals_count; ++i) { + for (i = 0; i < vec_size(irfun->locals); ++i) { if (!ir_builder_gen_global(ir, irfun->locals[i], true)) { irerror(irfun->locals[i]->context, "Failed to generate local %s", irfun->locals[i]->name); return false; } } - if (irfun->locals_count) { - ir_value *last = irfun->locals[irfun->locals_count-1]; + if (vec_size(irfun->locals)) { + ir_value *last = vec_last(irfun->locals); local_var_end = last->code.globaladdr; local_var_end += type_sizeof[last->vtype]; } - for (i = 0; i < irfun->values_count; ++i) + for (i = 0; i < vec_size(irfun->values); ++i) { /* generate code.globaladdr for ssa values */ ir_value *v = irfun->values[i]; @@ -2745,19 +2682,20 @@ static bool gen_global_function(ir_builder *ir, ir_value *global) } for (i = 0; i < irfun->allocated_locals; ++i) { /* fill the locals with zeros */ - code_globals_add(0); + vec_push(code_globals, 0); } - fun.locals = code_globals_elements - fun.firstlocal; + fun.locals = vec_size(code_globals) - fun.firstlocal; if (irfun->builtin) fun.entry = irfun->builtin; else { - irfun->code_function_def = code_functions_elements; - fun.entry = code_statements_elements; + irfun->code_function_def = vec_size(code_functions); + fun.entry = vec_size(code_statements); } - return (code_functions_add(fun) >= 0); + vec_push(code_functions, fun); + return true; } static bool gen_global_function_code(ir_builder *ir, ir_value *global) @@ -2780,9 +2718,9 @@ static bool gen_global_function_code(ir_builder *ir, ir_value *global) irerror(irfun->context, "`%s`: IR global wasn't generated, failed to access function-def", irfun->name); return false; } - fundef = &code_functions_data[irfun->code_function_def]; + fundef = &code_functions[irfun->code_function_def]; - fundef->entry = code_statements_elements; + fundef->entry = vec_size(code_statements); if (!gen_function_code(irfun)) { irerror(irfun->context, "Failed to generate code for function %s", irfun->name); return false; @@ -2797,7 +2735,7 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc prog_section_def def; def.type = global->vtype; - def.offset = code_globals_elements; + def.offset = vec_size(code_globals); if (global->name) { if (global->name[0] == '#') { @@ -2831,100 +2769,96 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc * Maybe this could be an -foption * fteqcc creates data for end_sys_* - of size 1, so let's do the same */ - ir_value_code_setaddr(global, code_globals_add(0)); + ir_value_code_setaddr(global, vec_size(code_globals)); + vec_push(code_globals, 0); /* Add the def */ - if (code_defs_add(def) < 0) - return false; + vec_push(code_defs, def); return true; case TYPE_POINTER: - if (code_defs_add(def) < 0) - return false; + vec_push(code_defs, def); return gen_global_pointer(global); case TYPE_FIELD: - if (code_defs_add(def) < 0) - return false; + vec_push(code_defs, def); return gen_global_field(global); case TYPE_ENTITY: /* fall through */ case TYPE_FLOAT: { + ir_value_code_setaddr(global, vec_size(code_globals)); if (global->isconst) { iptr = (int32_t*)&global->constval.ivec[0]; - ir_value_code_setaddr(global, code_globals_add(*iptr)); + vec_push(code_globals, *iptr); } else { - ir_value_code_setaddr(global, code_globals_add(0)); + vec_push(code_globals, 0); if (!islocal) def.type |= DEF_SAVEGLOBAL; } - if (code_defs_add(def) < 0) - return false; + vec_push(code_defs, def); return global->code.globaladdr >= 0; } case TYPE_STRING: { - if (global->isconst) - ir_value_code_setaddr(global, code_globals_add(code_genstring(global->constval.vstring))); - else { - ir_value_code_setaddr(global, code_globals_add(0)); + ir_value_code_setaddr(global, vec_size(code_globals)); + if (global->isconst) { + vec_push(code_globals, code_genstring(global->constval.vstring)); + } else { + vec_push(code_globals, 0); if (!islocal) def.type |= DEF_SAVEGLOBAL; } - if (code_defs_add(def) < 0) - return false; + vec_push(code_defs, def); return global->code.globaladdr >= 0; } case TYPE_VECTOR: { size_t d; + ir_value_code_setaddr(global, vec_size(code_globals)); if (global->isconst) { iptr = (int32_t*)&global->constval.ivec[0]; - ir_value_code_setaddr(global, code_globals_add(iptr[0])); + vec_push(code_globals, iptr[0]); if (global->code.globaladdr < 0) return false; for (d = 1; d < type_sizeof[global->vtype]; ++d) { - if (code_globals_add(iptr[d]) < 0) - return false; + vec_push(code_globals, iptr[d]); } } else { - ir_value_code_setaddr(global, code_globals_add(0)); + vec_push(code_globals, 0); if (global->code.globaladdr < 0) return false; for (d = 1; d < type_sizeof[global->vtype]; ++d) { - if (code_globals_add(0) < 0) - return false; + vec_push(code_globals, 0); } if (!islocal) def.type |= DEF_SAVEGLOBAL; } - if (code_defs_add(def) < 0) - return false; + vec_push(code_defs, def); return global->code.globaladdr >= 0; } case TYPE_FUNCTION: + ir_value_code_setaddr(global, vec_size(code_globals)); if (!global->isconst) { - ir_value_code_setaddr(global, code_globals_add(0)); + vec_push(code_globals, 0); if (global->code.globaladdr < 0) return false; } else { - ir_value_code_setaddr(global, code_globals_elements); - code_globals_add(code_functions_elements); + vec_push(code_globals, vec_size(code_functions)); if (!gen_global_function(self, global)) return false; if (!islocal) def.type |= DEF_SAVEGLOBAL; } - if (code_defs_add(def) < 0) - return false; + vec_push(code_defs, def); return true; case TYPE_VARIANT: /* assume biggest type */ - ir_value_code_setaddr(global, code_globals_add(0)); + ir_value_code_setaddr(global, vec_size(code_globals)); + vec_push(code_globals, 0); for (i = 1; i < type_sizeof[TYPE_VARIANT]; ++i) - code_globals_add(0); + vec_push(code_globals, 0); return true; default: /* refuse to create 'void' type or any other fancy business. */ @@ -2940,7 +2874,7 @@ static bool ir_builder_gen_field(ir_builder *self, ir_value *field) prog_section_field fld; def.type = field->vtype; - def.offset = code_globals_elements; + def.offset = vec_size(code_globals); /* create a global named the same as the field */ if (opts_standard == COMPILER_GMQCC) { @@ -2974,8 +2908,7 @@ static bool ir_builder_gen_field(ir_builder *self, ir_value *field) field->code.name = def.name; - if (code_defs_add(def) < 0) - return false; + vec_push(code_defs, def); fld.type = field->fieldtype; @@ -2986,17 +2919,13 @@ static bool ir_builder_gen_field(ir_builder *self, ir_value *field) fld.offset = code_alloc_field(type_sizeof[field->fieldtype]); - if (code_fields_add(fld) < 0) - return false; + vec_push(code_fields, fld); - ir_value_code_setaddr(field, code_globals_elements); - if (!code_globals_add(fld.offset)) - return false; + ir_value_code_setaddr(field, vec_size(code_globals)); + vec_push(code_globals, fld.offset); if (fld.type == TYPE_VECTOR) { - if (!code_globals_add(fld.offset+1)) - return false; - if (!code_globals_add(fld.offset+2)) - return false; + vec_push(code_globals, fld.offset+1); + vec_push(code_globals, fld.offset+2); } return field->code.globaladdr >= 0; @@ -3009,14 +2938,14 @@ bool ir_builder_generate(ir_builder *self, const char *filename) code_init(); - for (i = 0; i < self->globals_count; ++i) + for (i = 0; i < vec_size(self->globals); ++i) { if (!ir_builder_gen_global(self, self->globals[i], false)) { return false; } } - for (i = 0; i < self->fields_count; ++i) + for (i = 0; i < vec_size(self->fields); ++i) { if (!ir_builder_gen_field(self, self->fields[i])) { return false; @@ -3024,7 +2953,7 @@ bool ir_builder_generate(ir_builder *self, const char *filename) } /* generate function code */ - for (i = 0; i < self->globals_count; ++i) + for (i = 0; i < vec_size(self->globals); ++i) { if (self->globals[i]->vtype == TYPE_FUNCTION) { if (!gen_global_function_code(self, self->globals[i])) { @@ -3041,8 +2970,7 @@ bool ir_builder_generate(ir_builder *self, const char *filename) stmt.o1.u1 = 0; stmt.o2.u1 = 0; stmt.o3.u1 = 0; - if (code_statements_add(stmt) < 0) - return false; + vec_push(code_statements, stmt); printf("writing '%s'...\n", filename); return code_write(filename); @@ -3079,7 +3007,7 @@ void ir_builder_dump(ir_builder *b, int (*oprintf)(const char*, ...)) indent[1] = 0; oprintf("module %s\n", b->name); - for (i = 0; i < b->globals_count; ++i) + for (i = 0; i < vec_size(b->globals); ++i) { oprintf("global "); if (b->globals[i]->isconst) @@ -3087,7 +3015,7 @@ void ir_builder_dump(ir_builder *b, int (*oprintf)(const char*, ...)) ir_value_dump(b->globals[i], oprintf); oprintf("\n"); } - for (i = 0; i < b->functions_count; ++i) + for (i = 0; i < vec_size(b->functions); ++i) ir_function_dump(b->functions[i], indent, oprintf); oprintf("endmodule %s\n", b->name); } @@ -3102,38 +3030,38 @@ void ir_function_dump(ir_function *f, char *ind, } oprintf("%sfunction %s\n", ind, f->name); strncat(ind, "\t", IND_BUFSZ); - if (f->locals_count) + if (vec_size(f->locals)) { - oprintf("%s%i locals:\n", ind, (int)f->locals_count); - for (i = 0; i < f->locals_count; ++i) { + oprintf("%s%i locals:\n", ind, (int)vec_size(f->locals)); + for (i = 0; i < vec_size(f->locals); ++i) { oprintf("%s\t", ind); ir_value_dump(f->locals[i], oprintf); oprintf("\n"); } } oprintf("%sliferanges:\n", ind); - for (i = 0; i < f->locals_count; ++i) { + for (i = 0; i < vec_size(f->locals); ++i) { size_t l; ir_value *v = f->locals[i]; oprintf("%s\t%s: unique ", ind, v->name); - for (l = 0; l < v->life_count; ++l) { + for (l = 0; l < vec_size(v->life); ++l) { oprintf("[%i,%i] ", v->life[l].start, v->life[l].end); } oprintf("\n"); } - for (i = 0; i < f->values_count; ++i) { + for (i = 0; i < vec_size(f->values); ++i) { size_t l; ir_value *v = f->values[i]; oprintf("%s\t%s: @%i ", ind, v->name, (int)v->code.local); - for (l = 0; l < v->life_count; ++l) { + for (l = 0; l < vec_size(v->life); ++l) { oprintf("[%i,%i] ", v->life[l].start, v->life[l].end); } oprintf("\n"); } - if (f->blocks_count) + if (vec_size(f->blocks)) { oprintf("%slife passes (check): %i\n", ind, (int)f->run_id); - for (i = 0; i < f->blocks_count; ++i) { + for (i = 0; i < vec_size(f->blocks); ++i) { if (f->blocks[i]->run_id != f->run_id) { oprintf("%slife pass check fail! %i != %i\n", ind, (int)f->blocks[i]->run_id, (int)f->run_id); } @@ -3152,7 +3080,7 @@ void ir_block_dump(ir_block* b, char *ind, oprintf("%s:%s\n", ind, b->label); strncat(ind, "\t", IND_BUFSZ); - for (i = 0; i < b->instr_count; ++i) + for (i = 0; i < vec_size(b->instr); ++i) ir_instr_dump(b->instr[i], ind, oprintf); ind[strlen(ind)-1] = 0; } @@ -3162,7 +3090,7 @@ void dump_phi(ir_instr *in, char *ind, { size_t i; oprintf("%s <- phi ", in->_ops[0]->name); - for (i = 0; i < in->phi_count; ++i) + for (i = 0; i < vec_size(in->phi); ++i) { oprintf("([%s] : %s) ", in->phi[i].from->label, in->phi[i].value->name); @@ -3191,7 +3119,7 @@ void ir_instr_dump(ir_instr *in, char *ind, oprintf(" <- "); } if (in->opcode == INSTR_CALL0) { - oprintf("CALL%i\t", in->params_count); + oprintf("CALL%i\t", vec_size(in->params)); } else oprintf("%s\t", qc_opname(in->opcode)); @@ -3218,9 +3146,9 @@ void ir_instr_dump(ir_instr *in, char *ind, } if (in->bops[1]) oprintf("%s[%s]", comma, in->bops[1]->label); - if (in->params_count) { + if (vec_size(in->params)) { oprintf("\tparams: "); - for (i = 0; i != in->params_count; ++i) { + for (i = 0; i != vec_size(in->params); ++i) { oprintf("%s, ", in->params[i]->name); } } @@ -3273,7 +3201,7 @@ void ir_value_dump_life(const ir_value *self, int (*oprintf)(const char*,...)) { size_t i; oprintf("Life of %12s:", self->name); - for (i = 0; i < self->life_count; ++i) + for (i = 0; i < vec_size(self->life); ++i) { oprintf(" + [%i, %i]\n", self->life[i].start, self->life[i].end); } diff --git a/ir.h b/ir.h index a7f41d0..9b5171d 100644 --- a/ir.h +++ b/ir.h @@ -43,8 +43,8 @@ typedef struct ir_value_s { /* and the output type of a function */ int outtype; - MEM_VECTOR_MAKE(struct ir_instr_s*, reads); - MEM_VECTOR_MAKE(struct ir_instr_s*, writes); + struct ir_instr_s **reads; + struct ir_instr_s **writes; /* constantvalues */ bool isconst; @@ -72,7 +72,7 @@ typedef struct ir_value_s { struct ir_value_s *memberof; /* For the temp allocator */ - MEM_VECTOR_MAKE(ir_life_entry_t, life); + ir_life_entry_t *life; } ir_value; int32_t ir_value_code_addr(const ir_value*); @@ -87,8 +87,7 @@ void ir_value_delete(ir_value*); bool ir_value_set_name(ir_value*, const char *name); ir_value* ir_value_vector_member(ir_value*, unsigned int member); -MEM_VECTOR_PROTO_ALL(ir_value, struct ir_instr_s*, reads); -MEM_VECTOR_PROTO_ALL(ir_value, struct ir_instr_s*, writes); +bool GMQCC_WARN vec_ir_value_find(ir_value **vec, ir_value *what, size_t *idx); bool GMQCC_WARN ir_value_set_float(ir_value*, float f); bool GMQCC_WARN ir_value_set_func(ir_value*, int f); @@ -101,7 +100,6 @@ bool GMQCC_WARN ir_value_set_field(ir_value*, ir_value *fld); /*bool ir_value_set_pointer_v(ir_value*, ir_value* p); */ /*bool ir_value_set_pointer_i(ir_value*, int i); */ -MEM_VECTOR_PROTO(ir_value, ir_life_entry_t, life); /* merge an instruction into the life-range */ /* returns false if the lifepoint was already known */ bool ir_value_life_merge(ir_value*, size_t); @@ -114,12 +112,6 @@ bool ir_values_overlap(const ir_value*, const ir_value*); void ir_value_dump(ir_value*, int (*oprintf)(const char*,...)); void ir_value_dump_life(const ir_value *self, int (*oprintf)(const char*,...)); -/* A vector of IR values */ -typedef struct { - MEM_VECTOR_MAKE(ir_value*, v); -} ir_value_vector; -MEM_VECTOR_PROTO(ir_value_vector, ir_value*, v); - /* PHI data */ typedef struct ir_phi_entry_s { @@ -135,8 +127,8 @@ typedef struct ir_instr_s ir_value* (_ops[3]); struct ir_block_s* (bops[2]); - MEM_VECTOR_MAKE(ir_phi_entry_t, phi); - MEM_VECTOR_MAKE(ir_value*, params); + ir_phi_entry_t *phi; + ir_value **params; /* For the temp-allocation */ size_t eid; @@ -147,10 +139,9 @@ typedef struct ir_instr_s ir_instr* ir_instr_new(struct ir_block_s *owner, int opcode); void ir_instr_delete(ir_instr*); -MEM_VECTOR_PROTO(ir_value, ir_phi_entry_t, phi); -bool GMQCC_WARN ir_instr_op(ir_instr*, int op, ir_value *value, bool writing); +bool GMQCC_WARN vec_ir_instr_find(ir_instr **vec, ir_instr *what, size_t *idx); -MEM_VECTOR_PROTO(ir_value, ir_value*, params); +bool GMQCC_WARN ir_instr_op(ir_instr*, int op, ir_value *value, bool writing); void ir_instr_dump(ir_instr* in, char *ind, int (*oprintf)(const char*,...)); @@ -161,10 +152,10 @@ typedef struct ir_block_s lex_ctx context; bool final; /* once a jump is added we're done */ - MEM_VECTOR_MAKE(ir_instr*, instr); - MEM_VECTOR_MAKE(struct ir_block_s*, entries); - MEM_VECTOR_MAKE(struct ir_block_s*, exits); - MEM_VECTOR_MAKE(ir_value*, living); + ir_instr **instr; + struct ir_block_s **entries; + struct ir_block_s **exits; + ir_value **living; /* For the temp-allocation */ size_t eid; @@ -182,10 +173,6 @@ void ir_block_delete(ir_block*); bool ir_block_set_label(ir_block*, const char *label); -MEM_VECTOR_PROTO(ir_block, ir_instr*, instr); -MEM_VECTOR_PROTO_ALL(ir_block, ir_block*, exits); -MEM_VECTOR_PROTO_ALL(ir_block, ir_block*, entries); - ir_value* ir_block_create_binop(ir_block*, const char *label, int op, ir_value *left, ir_value *right); ir_value* ir_block_create_unary(ir_block*, const char *label, int op, @@ -211,10 +198,10 @@ ir_value* ir_block_create_mul(ir_block*, const char *label, ir_value *l, ir_valu ir_value* ir_block_create_div(ir_block*, const char *label, ir_value *l, ir_value *r); ir_instr* ir_block_create_phi(ir_block*, const char *label, int vtype); ir_value* ir_phi_value(ir_instr*); -bool GMQCC_WARN ir_phi_add(ir_instr*, ir_block *b, ir_value *v); +void ir_phi_add(ir_instr*, ir_block *b, ir_value *v); ir_instr* ir_block_create_call(ir_block*, const char *label, ir_value *func); ir_value* ir_call_value(ir_instr*); -bool GMQCC_WARN ir_call_param(ir_instr*, ir_value*); +void ir_call_param(ir_instr*, ir_value*); bool GMQCC_WARN ir_block_create_return(ir_block*, ir_value *opt_value); @@ -229,18 +216,16 @@ bool GMQCC_WARN ir_block_create_if(ir_block*, ir_value *cond, bool GMQCC_WARN ir_block_create_jump(ir_block*, ir_block *to); bool GMQCC_WARN ir_block_create_goto(ir_block*, ir_block *to); -MEM_VECTOR_PROTO_ALL(ir_block, ir_value*, living); - void ir_block_dump(ir_block*, char *ind, int (*oprintf)(const char*,...)); /* function */ typedef struct ir_function_s { - char *name; - int outtype; - MEM_VECTOR_MAKE(int, params); - MEM_VECTOR_MAKE(ir_block*, blocks); + char *name; + int outtype; + int *params; + ir_block **blocks; int builtin; @@ -250,10 +235,10 @@ typedef struct ir_function_s * which might get optimized away, so anything * in there needs to be deleted in the dtor. */ - MEM_VECTOR_MAKE(ir_value*, values); + ir_value **values; /* locally defined variables */ - MEM_VECTOR_MAKE(ir_value*, locals); + ir_value **locals; size_t allocated_locals; @@ -279,11 +264,9 @@ typedef struct ir_function_s ir_function* ir_function_new(struct ir_builder_s *owner, int returntype); void ir_function_delete(ir_function*); -bool GMQCC_WARN ir_function_collect_value(ir_function*, ir_value *value); +void ir_function_collect_value(ir_function*, ir_value *value); bool ir_function_set_name(ir_function*, const char *name); -MEM_VECTOR_PROTO(ir_function, int, params); -MEM_VECTOR_PROTO(ir_function, ir_block*, blocks); ir_value* ir_function_get_local(ir_function *self, const char *name); ir_value* ir_function_create_local(ir_function *self, const char *name, int vtype, bool param); @@ -303,12 +286,12 @@ void ir_function_dump(ir_function*, char *ind, int (*oprintf)(const char*,...)); typedef struct ir_builder_s { char *name; - MEM_VECTOR_MAKE(ir_function*, functions); - MEM_VECTOR_MAKE(ir_value*, globals); - MEM_VECTOR_MAKE(ir_value*, fields); + ir_function **functions; + ir_value **globals; + ir_value **fields; - MEM_VECTOR_MAKE(const char*, filenames); - MEM_VECTOR_MAKE(qcint, filestrings); + const char **filenames; + qcint *filestrings; /* we cache the #IMMEDIATE string here */ qcint str_immediate; } ir_builder; @@ -318,12 +301,6 @@ void ir_builder_delete(ir_builder*); bool ir_builder_set_name(ir_builder *self, const char *name); -MEM_VECTOR_PROTO(ir_builder, ir_function*, functions); -MEM_VECTOR_PROTO(ir_builder, ir_value*, globals); -MEM_VECTOR_PROTO(ir_builder, ir_value*, fields); -MEM_VECTOR_PROTO(ir_builder, const char*, filenames); -MEM_VECTOR_PROTO(ir_builder, qcint, filestrings); - ir_function* ir_builder_get_function(ir_builder*, const char *fun); ir_function* ir_builder_create_function(ir_builder*, const char *name, int outtype); diff --git a/lexer.c b/lexer.c index 0ed938c..094c6ef 100644 --- a/lexer.c +++ b/lexer.c @@ -9,7 +9,7 @@ MEM_VEC_FUNCTIONS(token, char, value) MEM_VEC_FUNCTIONS(lex_file, frame_macro, frames) -VECTOR_MAKE(char*, lex_filenames); +char* *lex_filenames; void lexerror(lex_file *lex, const char *fmt, ...) { @@ -157,8 +157,7 @@ lex_file* lex_open(const char *file) lex->peekpos = 0; lex->eof = false; - lex_filenames_add(lex->name); - + vec_push(lex_filenames, lex->name); return lex; } @@ -185,7 +184,7 @@ lex_file* lex_open_string(const char *str, size_t len, const char *name) lex->peekpos = 0; lex->eof = false; - lex_filenames_add(lex->name); + vec_push(lex_filenames, lex->name); return lex; } @@ -193,9 +192,9 @@ lex_file* lex_open_string(const char *str, size_t len, const char *name) void lex_cleanup(void) { size_t i; - for (i = 0; i < lex_filenames_elements; ++i) - mem_d(lex_filenames_data[i]); - mem_d(lex_filenames_data); + for (i = 0; i < vec_size(lex_filenames); ++i) + mem_d(lex_filenames[i]); + vec_free(lex_filenames); } void lex_close(lex_file *lex) diff --git a/main.c b/main.c index d057b36..2c14249 100644 --- a/main.c +++ b/main.c @@ -46,7 +46,7 @@ const oper_info *operators = NULL; size_t operator_count = 0; typedef struct { char *filename; int type; } argitem; -VECTOR_MAKE(argitem, items); +static argitem *items = NULL; #define TYPE_QC 0 #define TYPE_ASM 1 @@ -341,7 +341,7 @@ static bool options_parse(int argc, char **argv) { return false; } item.filename = argarg; - items_add(item); + vec_push(items, item); break; case '-': @@ -378,7 +378,7 @@ static bool options_parse(int argc, char **argv) { argitem item; item.filename = argv[0]; item.type = TYPE_QC; - items_add(item); + vec_push(items, item); } } con_change(redirout, redirerr); @@ -471,18 +471,18 @@ int main(int argc, char **argv) { util_debug("COM", "starting ...\n"); - if (items_elements) { + if (vec_size(items)) { con_out("Mode: manual\n"); - con_out("There are %lu items to compile:\n", (unsigned long)items_elements); - for (itr = 0; itr < items_elements; ++itr) { + con_out("There are %lu items to compile:\n", (unsigned long)vec_size(items)); + for (itr = 0; itr < vec_size(items); ++itr) { con_out(" item: %s (%s)\n", - items_data[itr].filename, - ( (items_data[itr].type == TYPE_QC ? "qc" : - (items_data[itr].type == TYPE_ASM ? "asm" : - (items_data[itr].type == TYPE_SRC ? "progs.src" : + items[itr].filename, + ( (items[itr].type == TYPE_QC ? "qc" : + (items[itr].type == TYPE_ASM ? "asm" : + (items[itr].type == TYPE_SRC ? "progs.src" : ("unknown")))))); - if (!parser_compile_file(items_data[itr].filename)) + if (!parser_compile_file(items[itr].filename)) { retval = 1; goto cleanup; @@ -541,7 +541,7 @@ srcdone: cleanup: util_debug("COM", "cleaning ...\n"); con_close(); - mem_d(items_data); + vec_free(items); parser_cleanup(); if (opts_output_free) diff --git a/parser.c b/parser.c index 59d4a33..805c28c 100644 --- a/parser.c +++ b/parser.c @@ -13,12 +13,12 @@ typedef struct { lex_file *lex; int tok; - MEM_VECTOR_MAKE(varentry_t, globals); - MEM_VECTOR_MAKE(varentry_t, fields); - MEM_VECTOR_MAKE(ast_function*, functions); - MEM_VECTOR_MAKE(ast_value*, imm_float); - MEM_VECTOR_MAKE(ast_value*, imm_string); - MEM_VECTOR_MAKE(ast_value*, imm_vector); + varentry_t *globals; + varentry_t *fields; + ast_function **functions; + ast_value **imm_float; + ast_value **imm_string; + ast_value **imm_vector; ast_value *imm_float_zero; ast_value *imm_vector_zero; @@ -27,7 +27,7 @@ typedef struct { size_t crc_fields; ast_function *function; - MEM_VECTOR_MAKE(varentry_t, locals); + varentry_t *locals; size_t blocklocal; size_t errors; @@ -42,13 +42,6 @@ typedef struct { qcint memberof; } parser_t; -MEM_VEC_FUNCTIONS(parser_t, varentry_t, globals) -MEM_VEC_FUNCTIONS(parser_t, varentry_t, fields) -MEM_VEC_FUNCTIONS(parser_t, ast_value*, imm_float) -MEM_VEC_FUNCTIONS(parser_t, ast_value*, imm_string) -MEM_VEC_FUNCTIONS(parser_t, ast_value*, imm_vector) -MEM_VEC_FUNCTIONS(parser_t, varentry_t, locals) -MEM_VEC_FUNCTIONS(parser_t, ast_function*, functions) static bool GMQCC_WARN parser_pop_local(parser_t *parser); static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofields); @@ -169,17 +162,14 @@ static ast_value* parser_const_float(parser_t *parser, double d) { size_t i; ast_value *out; - for (i = 0; i < parser->imm_float_count; ++i) { + for (i = 0; i < vec_size(parser->imm_float); ++i) { if (parser->imm_float[i]->constval.vfloat == d) return parser->imm_float[i]; } out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_FLOAT); out->isconst = true; out->constval.vfloat = d; - if (!parser_t_imm_float_add(parser, out)) { - ast_value_delete(out); - return NULL; - } + vec_push(parser->imm_float, out); return out; } @@ -205,17 +195,14 @@ static ast_value* parser_const_string(parser_t *parser, const char *str) { size_t i; ast_value *out; - for (i = 0; i < parser->imm_string_count; ++i) { + for (i = 0; i < vec_size(parser->imm_string); ++i) { if (!strcmp(parser->imm_string[i]->constval.vstring, str)) return parser->imm_string[i]; } out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_STRING); out->isconst = true; out->constval.vstring = parser_strdup(str); - if (!parser_t_imm_string_add(parser, out)) { - ast_value_delete(out); - return NULL; - } + vec_push(parser->imm_string, out); return out; } @@ -223,17 +210,14 @@ static ast_value* parser_const_vector(parser_t *parser, vector v) { size_t i; ast_value *out; - for (i = 0; i < parser->imm_vector_count; ++i) { + for (i = 0; i < vec_size(parser->imm_vector); ++i) { if (!memcmp(&parser->imm_vector[i]->constval.vvec, &v, sizeof(v))) return parser->imm_vector[i]; } out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_VECTOR); out->isconst = true; out->constval.vvec = v; - if (!parser_t_imm_vector_add(parser, out)) { - ast_value_delete(out); - return NULL; - } + vec_push(parser->imm_vector, out); return out; } @@ -256,7 +240,7 @@ static ast_value* parser_const_vector_0(parser_t *parser) static ast_expression* parser_find_field(parser_t *parser, const char *name) { size_t i; - for (i = 0; i < parser->fields_count; ++i) { + for (i = 0; i < vec_size(parser->fields); ++i) { if (!strcmp(parser->fields[i].name, name)) return parser->fields[i].var; } @@ -266,7 +250,7 @@ static ast_expression* parser_find_field(parser_t *parser, const char *name) static ast_expression* parser_find_global(parser_t *parser, const char *name) { size_t i; - for (i = 0; i < parser->globals_count; ++i) { + for (i = 0; i < vec_size(parser->globals); ++i) { if (!strcmp(parser->globals[i].name, name)) return parser->globals[i].var; } @@ -280,7 +264,7 @@ static ast_expression* parser_find_param(parser_t *parser, const char *name) if (!parser->function) return NULL; fun = parser->function->vtype; - for (i = 0; i < fun->expression.params_count; ++i) { + for (i = 0; i < vec_size(fun->expression.params); ++i) { if (!strcmp(fun->expression.params[i]->name, name)) return (ast_expression*)(fun->expression.params[i]); } @@ -291,7 +275,7 @@ static ast_expression* parser_find_local(parser_t *parser, const char *name, siz { size_t i; *isparam = false; - for (i = parser->locals_count; i > upto;) { + for (i = vec_size(parser->locals); i > upto;) { --i; if (!strcmp(parser->locals[i].name, name)) return parser->locals[i].var; @@ -320,11 +304,9 @@ typedef struct } sy_elem; typedef struct { - MEM_VECTOR_MAKE(sy_elem, out); - MEM_VECTOR_MAKE(sy_elem, ops); + sy_elem *out; + sy_elem *ops; } shunt; -MEM_VEC_FUNCTIONS(shunt, sy_elem, out) -MEM_VEC_FUNCTIONS(shunt, sy_elem, ops) #define SY_PAREN_EXPR '(' #define SY_PAREN_FUNC 'f' @@ -432,37 +414,37 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy) char ty1[1024]; char ty2[1024]; - if (!sy->ops_count) { + if (!vec_size(sy->ops)) { parseerror(parser, "internal error: missing operator"); return false; } - if (sy->ops[sy->ops_count-1].paren) { + if (sy->ops[vec_size(sy->ops)-1].paren) { parseerror(parser, "unmatched parenthesis"); return false; } - op = &operators[sy->ops[sy->ops_count-1].etype - 1]; - ctx = sy->ops[sy->ops_count-1].ctx; + op = &operators[sy->ops[vec_size(sy->ops)-1].etype - 1]; + ctx = sy->ops[vec_size(sy->ops)-1].ctx; DEBUGSHUNTDO(con_out("apply %s\n", op->op)); - if (sy->out_count < op->operands) { - parseerror(parser, "internal error: not enough operands: %i (operator %s (%i))", sy->out_count, + if (vec_size(sy->out) < op->operands) { + parseerror(parser, "internal error: not enough operands: %i (operator %s (%i))", vec_size(sy->out), op->op, (int)op->id); return false; } - sy->ops_count--; + vec_shrinkby(sy->ops, 1); - sy->out_count -= op->operands; + vec_shrinkby(sy->out, op->operands); for (i = 0; i < op->operands; ++i) { - exprs[i] = sy->out[sy->out_count+i].out; - blocks[i] = sy->out[sy->out_count+i].block; + exprs[i] = sy->out[vec_size(sy->out)+i].out; + blocks[i] = sy->out[vec_size(sy->out)+i].block; asvalue[i] = (ast_value*)exprs[i]; } - if (blocks[0] && !blocks[0]->exprs_count && op->id != opid1(',')) { + if (blocks[0] && !vec_size(blocks[0]->exprs) && op->id != opid1(',')) { parseerror(parser, "internal error: operator cannot be applied on empty blocks"); return false; } @@ -529,20 +511,16 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy) case opid1(','): if (blocks[0]) { - if (!ast_block_exprs_add(blocks[0], exprs[1])) - return false; + vec_push(blocks[0]->exprs, exprs[1]); } else { blocks[0] = ast_block_new(ctx); - if (!ast_block_exprs_add(blocks[0], exprs[0]) || - !ast_block_exprs_add(blocks[0], exprs[1])) - { - return false; - } + vec_push(blocks[0]->exprs, exprs[0]); + vec_push(blocks[0]->exprs, exprs[1]); } if (!ast_block_set_type(blocks[0], exprs[1])) return false; - sy->out[sy->out_count++] = syblock(ctx, blocks[0]); + vec_push(sy->out, syblock(ctx, blocks[0])); return true; case opid2('-','P'): @@ -923,7 +901,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy) } DEBUGSHUNTDO(con_out("applied %s\n", op->op)); - sy->out[sy->out_count++] = syexp(ctx, out); + vec_push(sy->out, syexp(ctx, out)); return true; } @@ -936,8 +914,8 @@ static bool parser_close_call(parser_t *parser, shunt *sy) size_t fid; size_t paramcount; - sy->ops_count--; - fid = sy->ops[sy->ops_count].off; + vec_shrinkby(sy->ops, 1); + fid = sy->ops[vec_size(sy->ops)].off; /* out[fid] is the function * everything above is parameters... @@ -946,37 +924,34 @@ static bool parser_close_call(parser_t *parser, shunt *sy) * more = ast_block */ - if (sy->out_count < 1 || sy->out_count <= fid) { + if (vec_size(sy->out) < 1 || vec_size(sy->out) <= fid) { parseerror(parser, "internal error: function call needs function and parameter list..."); return false; } fun = sy->out[fid].out; - call = ast_call_new(sy->ops[sy->ops_count].ctx, fun); + call = ast_call_new(sy->ops[vec_size(sy->ops)].ctx, fun); if (!call) { parseerror(parser, "out of memory"); return false; } - if (fid+1 == sy->out_count) { + if (fid+1 == vec_size(sy->out)) { /* no arguments */ paramcount = 0; - } else if (fid+2 == sy->out_count) { + } else if (fid+2 == vec_size(sy->out)) { ast_block *params; - sy->out_count--; - params = sy->out[sy->out_count].block; + vec_shrinkby(sy->out, 1); + params = sy->out[vec_size(sy->out)].block; if (!params) { /* 1 param */ paramcount = 1; - if (!ast_call_params_add(call, sy->out[sy->out_count].out)) { - ast_delete(sy->out[sy->out_count].out); - parseerror(parser, "out of memory"); - return false; - } + vec_push(call->params, sy->out[vec_size(sy->out)].out); } else { - paramcount = params->exprs_count; - MEM_VECTOR_MOVE(params, exprs, call, params); + paramcount = vec_size(params->exprs); + call->params = params->exprs; + params->exprs = NULL; ast_delete(params); } if (!ast_call_check_types(call)) @@ -998,12 +973,12 @@ static bool parser_close_call(parser_t *parser, shunt *sy) parseerror(parser, "could not determine function return type"); return false; } else { - if (fun->expression.params_count != paramcount && + if (vec_size(fun->expression.params) != paramcount && !(fun->expression.variadic && - fun->expression.params_count < paramcount)) + vec_size(fun->expression.params) < paramcount)) { ast_value *fval; - const char *fewmany = (fun->expression.params_count > paramcount) ? "few" : "many"; + const char *fewmany = (vec_size(fun->expression.params) > paramcount) ? "few" : "many"; fval = (ast_istype(fun, ast_value) ? ((ast_value*)fun) : NULL); if (opts_standard == COMPILER_GMQCC) @@ -1011,12 +986,12 @@ static bool parser_close_call(parser_t *parser, shunt *sy) if (fval) parseerror(parser, "too %s parameters for call to %s: expected %i, got %i\n" " -> `%s` has been declared here: %s:%i", - fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount, + fewmany, fval->name, (int)vec_size(fun->expression.params), (int)paramcount, fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line); else parseerror(parser, "too %s parameters for function call: expected %i, got %i\n" " -> `%s` has been declared here: %s:%i", - fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount, + fewmany, fval->name, (int)vec_size(fun->expression.params), (int)paramcount, fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line); return false; } @@ -1026,13 +1001,13 @@ static bool parser_close_call(parser_t *parser, shunt *sy) return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS, "too %s parameters for call to %s: expected %i, got %i\n" " -> `%s` has been declared here: %s:%i", - fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount, + fewmany, fval->name, (int)vec_size(fun->expression.params), (int)paramcount, fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line); else return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS, "too %s parameters for function call: expected %i, got %i\n" " -> `%s` has been declared here: %s:%i", - fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount, + fewmany, fval->name, (int)vec_size(fun->expression.params), (int)paramcount, fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line); } } @@ -1043,31 +1018,31 @@ static bool parser_close_call(parser_t *parser, shunt *sy) static bool parser_close_paren(parser_t *parser, shunt *sy, bool functions_only) { - if (!sy->ops_count) { + if (!vec_size(sy->ops)) { parseerror(parser, "unmatched closing paren"); return false; } /* this would for bit a + (x) because there are no operators inside (x) - if (sy->ops[sy->ops_count-1].paren == 1) { + if (sy->ops[vec_size(sy->ops)-1].paren == 1) { parseerror(parser, "empty parenthesis expression"); return false; } */ - while (sy->ops_count) { - if (sy->ops[sy->ops_count-1].paren == SY_PAREN_FUNC) { + while (vec_size(sy->ops)) { + if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_FUNC) { if (!parser_close_call(parser, sy)) return false; break; } - if (sy->ops[sy->ops_count-1].paren == SY_PAREN_EXPR) { - sy->ops_count--; + if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_EXPR) { + vec_shrinkby(sy->ops, 1); return !functions_only; } - if (sy->ops[sy->ops_count-1].paren == SY_PAREN_INDEX) { + if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_INDEX) { if (functions_only) return false; /* pop off the parenthesis */ - sy->ops_count--; + vec_shrinkby(sy->ops, 1); /* then apply the index operator */ if (!parser_sy_pop(parser, sy)) return false; @@ -1102,8 +1077,8 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma */ int parens = 0; - MEM_VECTOR_INIT(&sy, out); - MEM_VECTOR_INIT(&sy, ops); + sy.out = NULL; + sy.ops = NULL; parser->lex->flags.noops = false; @@ -1155,10 +1130,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma } if (ast_istype(var, ast_value)) ((ast_value*)var)->uses++; - if (!shunt_out_add(&sy, syexp(parser_ctx(parser), var))) { - parseerror(parser, "out of memory"); - goto onerr; - } + vec_push(sy.out, syexp(parser_ctx(parser), var)); DEBUGSHUNTDO(con_out("push %s\n", parser_tokval(parser))); } else if (parser->tok == TOKEN_FLOATCONST) { @@ -1171,10 +1143,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma val = parser_const_float(parser, (parser_token(parser)->constval.f)); if (!val) return false; - if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) { - parseerror(parser, "out of memory"); - goto onerr; - } + vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val)); DEBUGSHUNTDO(con_out("push %g\n", parser_token(parser)->constval.f)); } else if (parser->tok == TOKEN_INTCONST) { @@ -1187,10 +1156,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma val = parser_const_float(parser, (double)(parser_token(parser)->constval.i)); if (!val) return false; - if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) { - parseerror(parser, "out of memory"); - goto onerr; - } + vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val)); DEBUGSHUNTDO(con_out("push %i\n", parser_token(parser)->constval.i)); } else if (parser->tok == TOKEN_STRINGCONST) { @@ -1203,10 +1169,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma val = parser_const_string(parser, parser_tokval(parser)); if (!val) return false; - if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) { - parseerror(parser, "out of memory"); - goto onerr; - } + vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val)); DEBUGSHUNTDO(con_out("push string\n")); } else if (parser->tok == TOKEN_VECTORCONST) { @@ -1219,10 +1182,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma val = parser_const_vector(parser, parser_token(parser)->constval.v); if (!val) return false; - if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) { - parseerror(parser, "out of memory"); - goto onerr; - } + vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val)); DEBUGSHUNTDO(con_out("push '%g %g %g'\n", parser_token(parser)->constval.v.x, parser_token(parser)->constval.v.y, @@ -1303,8 +1263,8 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma break; } - if (sy.ops_count && !sy.ops[sy.ops_count-1].paren) - olast = &operators[sy.ops[sy.ops_count-1].etype-1]; + if (vec_size(sy.ops) && !vec_last(sy.ops).paren) + olast = &operators[vec_last(sy.ops).etype-1]; while (olast && ( (op->prec < olast->prec) || @@ -1312,15 +1272,15 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma { if (!parser_sy_pop(parser, &sy)) goto onerr; - if (sy.ops_count && !sy.ops[sy.ops_count-1].paren) - olast = &operators[sy.ops[sy.ops_count-1].etype-1]; + if (vec_size(sy.ops) && !vec_last(sy.ops).paren) + olast = &operators[vec_last(sy.ops).etype-1]; else olast = NULL; } if (op->id == opid1('.') && opts_standard == COMPILER_GMQCC) { /* for gmqcc standard: open up the namespace of the previous type */ - ast_expression *prevex = sy.out[sy.out_count-1].out; + ast_expression *prevex = vec_last(sy.out).out; if (!prevex) { parseerror(parser, "unexpected member operator"); goto onerr; @@ -1338,19 +1298,14 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma if (op->id == opid1('(')) { if (wantop) { + size_t sycount = vec_size(sy.out); DEBUGSHUNTDO(con_out("push [op] (\n")); ++parens; /* we expected an operator, this is the function-call operator */ - if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), SY_PAREN_FUNC, sy.out_count-1))) { - parseerror(parser, "out of memory"); - goto onerr; - } + vec_push(sy.ops, syparen(parser_ctx(parser), SY_PAREN_FUNC, sycount-1)); } else { ++parens; - if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), SY_PAREN_EXPR, 0))) { - parseerror(parser, "out of memory"); - goto onerr; - } + vec_push(sy.ops, syparen(parser_ctx(parser), SY_PAREN_EXPR, 0)); DEBUGSHUNTDO(con_out("push [nop] (\n")); } wantop = false; @@ -1361,15 +1316,12 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma } ++parens; /* push both the operator and the paren, this makes life easier */ - if (!shunt_ops_add(&sy, syop(parser_ctx(parser), op))) - goto onerr; - if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), SY_PAREN_INDEX, 0))) - goto onerr; + vec_push(sy.ops, syop(parser_ctx(parser), op)); + vec_push(sy.ops, syparen(parser_ctx(parser), SY_PAREN_INDEX, 0)); wantop = false; } else { DEBUGSHUNTDO(con_out("push operator %s\n", op->op)); - if (!shunt_ops_add(&sy, syop(parser_ctx(parser), op))) - goto onerr; + vec_push(sy.ops, syop(parser_ctx(parser), op)); wantop = false; } } @@ -1381,26 +1333,26 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma } } - while (sy.ops_count) { + while (vec_size(sy.ops)) { if (!parser_sy_pop(parser, &sy)) goto onerr; } parser->lex->flags.noops = true; - if (!sy.out_count) { + if (!vec_size(sy.out)) { parseerror(parser, "empty expression"); expr = NULL; } else expr = sy.out[0].out; - MEM_VECTOR_CLEAR(&sy, out); - MEM_VECTOR_CLEAR(&sy, ops); + vec_free(sy.out); + vec_free(sy.ops); DEBUGSHUNTDO(con_out("shunt done\n")); return expr; onerr: parser->lex->flags.noops = true; - MEM_VECTOR_CLEAR(&sy, out); - MEM_VECTOR_CLEAR(&sy, ops); + vec_free(sy.out); + vec_free(sy.ops); return NULL; } @@ -1613,7 +1565,7 @@ static bool parse_for(parser_t *parser, ast_block *block, ast_expression **out) lex_ctx ctx = parser_ctx(parser); oldblocklocal = parser->blocklocal; - parser->blocklocal = parser->locals_count; + parser->blocklocal = vec_size(parser->locals); initexpr = NULL; cond = NULL; @@ -1709,7 +1661,7 @@ static bool parse_for(parser_t *parser, ast_block *block, ast_expression **out) aloop = ast_loop_new(ctx, initexpr, cond, NULL, increment, ontrue); *out = (ast_expression*)aloop; - while (parser->locals_count > parser->blocklocal) + while (vec_size(parser->locals) > parser->blocklocal) retval = retval && parser_pop_local(parser); parser->blocklocal = oldblocklocal; return retval; @@ -1717,7 +1669,7 @@ onerr: if (initexpr) ast_delete(initexpr); if (cond) ast_delete(cond); if (increment) ast_delete(increment); - while (parser->locals_count > parser->blocklocal) + while (vec_size(parser->locals) > parser->blocklocal) (void)!parser_pop_local(parser); parser->blocklocal = oldblocklocal; return false; @@ -1848,16 +1800,17 @@ static bool parse_statement(parser_t *parser, ast_block *block, ast_expression * static bool GMQCC_WARN parser_pop_local(parser_t *parser) { + bool rv = true; varentry_t *ve; - parser->locals_count--; - ve = &parser->locals[parser->locals_count]; + ve = &vec_last(parser->locals); if (ast_istype(ve->var, ast_value) && !(((ast_value*)(ve->var))->uses)) { if (parsewarning(parser, WARN_UNUSED_VARIABLE, "unused variable: `%s`", ve->name)) - return false; + rv = false; } - mem_d(parser->locals[parser->locals_count].name); - return true; + mem_d(ve->name); + vec_pop(parser->locals); + return rv; } static bool parse_block_into(parser_t *parser, ast_block *block, bool warnreturn) @@ -1866,7 +1819,7 @@ static bool parse_block_into(parser_t *parser, ast_block *block, bool warnreturn bool retval = true; oldblocklocal = parser->blocklocal; - parser->blocklocal = parser->locals_count; + parser->blocklocal = vec_size(parser->locals); if (!parser_next(parser)) { /* skip the '{' */ parseerror(parser, "expected function body"); @@ -1886,11 +1839,7 @@ static bool parse_block_into(parser_t *parser, ast_block *block, bool warnreturn } if (!expr) continue; - if (!ast_block_exprs_add(block, expr)) { - ast_delete(expr); - block = NULL; - goto cleanup; - } + vec_push(block->exprs, expr); } if (parser->tok != '}') { @@ -1898,8 +1847,8 @@ static bool parse_block_into(parser_t *parser, ast_block *block, bool warnreturn } else { if (warnreturn && parser->function->vtype->expression.next->expression.vtype != TYPE_VOID) { - if (!block->exprs_count || - !ast_istype(block->exprs[block->exprs_count-1], ast_return)) + if (!vec_size(block->exprs) || + !ast_istype(vec_last(block->exprs), ast_return)) { if (parsewarning(parser, WARN_MISSING_RETURN_VALUES, "control reaches end of non-void function")) { block = NULL; @@ -1911,7 +1860,7 @@ static bool parse_block_into(parser_t *parser, ast_block *block, bool warnreturn } cleanup: - while (parser->locals_count > parser->blocklocal) + while (vec_size(parser->locals) > parser->blocklocal) retval = retval && parser_pop_local(parser); parser->blocklocal = oldblocklocal; return !!block; @@ -2077,11 +2026,7 @@ static bool parse_function_body(parser_t *parser, ast_value *var) varent.var = (ast_expression*)thinkfunc; varent.name = util_strdup(thinkfunc->name); - if (!parser_t_globals_add(parser, varent)) { - ast_unref(framenum); - ast_delete(thinkfunc); - return false; - } + vec_push(parser->globals, varent); nextthink = (ast_expression*)thinkfunc; } else { @@ -2181,24 +2126,9 @@ static bool parse_function_body(parser_t *parser, ast_value *var) if (store_think) ast_delete(store_think); retval = false; } - if (retval && !ast_block_exprs_add(block, (ast_expression*)store_frame)) { - ast_delete(store_frame); - ast_delete(store_nextthink); - ast_delete(store_think); - retval = false; - } - - if (retval && !ast_block_exprs_add(block, (ast_expression*)store_nextthink)) { - ast_delete(store_nextthink); - ast_delete(store_think); - retval = false; - } - - if (retval && !ast_block_exprs_add(block, (ast_expression*)store_think) ) - { - ast_delete(store_think); - retval = false; - } + vec_push(block->exprs, (ast_expression*)store_frame); + vec_push(block->exprs, (ast_expression*)store_nextthink); + vec_push(block->exprs, (ast_expression*)store_think); } if (!retval) { @@ -2210,7 +2140,7 @@ static bool parse_function_body(parser_t *parser, ast_value *var) } } - for (parami = 0; parami < var->expression.params_count; ++parami) { + for (parami = 0; parami < vec_size(var->expression.params); ++parami) { size_t e; varentry_t ve[3]; ast_value *param = var->expression.params[parami]; @@ -2228,23 +2158,10 @@ static bool parse_function_body(parser_t *parser, ast_value *var) } for (e = 0; e < 3; ++e) { - if (!parser_t_locals_add(parser, ve[e])) - break; - if (!ast_block_collect(block, ve[e].var)) { - parser->locals_count--; - break; - } + vec_push(parser->locals, ve[e]); + ast_block_collect(block, ve[e].var); ve[e].var = NULL; /* collected */ } - if (e != 3) { - parser->locals -= e; - do { - mem_d(ve[e].name); - --e; - } while (e); - ast_block_delete(block); - return false; - } } func = ast_function_new(ast_ctx(var), var->name, var); @@ -2253,25 +2170,18 @@ static bool parse_function_body(parser_t *parser, ast_value *var) ast_block_delete(block); goto enderr; } - if (!parser_t_functions_add(parser, func)) { - parseerror(parser, "failed to allocate slot for function `%s`", var->name); - ast_block_delete(block); - goto enderrfn; - } + vec_push(parser->functions, func); parser->function = func; if (!parse_block_into(parser, block, true)) { ast_block_delete(block); - goto enderrfn2; + goto enderrfn; } - if (!ast_function_blocks_add(func, block)) { - ast_block_delete(block); - goto enderrfn2; - } + vec_push(func->blocks, block); parser->function = old; - while (parser->locals_count) + while (vec_size(parser->locals)) retval = retval && parser_pop_local(parser); if (parser->tok == ';') @@ -2280,16 +2190,15 @@ static bool parse_function_body(parser_t *parser, ast_value *var) parseerror(parser, "missing semicolon after function body (mandatory with -std=qcc)"); return retval; -enderrfn2: - parser->functions_count--; enderrfn: + vec_pop(parser->functions); ast_function_delete(func); var->constval.vfunc = NULL; enderr: - while (parser->locals_count) { - parser->locals_count--; - mem_d(parser->locals[parser->locals_count].name); + while (vec_size(parser->locals)) { + mem_d(vec_last(parser->locals).name); + vec_pop(parser->locals); } parser->function = old; return false; @@ -2365,10 +2274,7 @@ static ast_expression *array_setter_node(parser_t *parser, ast_value *array, ast return NULL; } - if (!ast_block_exprs_add(block, (ast_expression*)st)) { - ast_delete(block); - return NULL; - } + vec_push(block->exprs, (ast_expression*)st); ret = ast_return_new(ctx, NULL); if (!ret) { @@ -2376,10 +2282,7 @@ static ast_expression *array_setter_node(parser_t *parser, ast_value *array, ast return NULL; } - if (!ast_block_exprs_add(block, (ast_expression*)ret)) { - ast_delete(block); - return NULL; - } + vec_push(block->exprs, (ast_expression*)ret); return (ast_expression*)block; } else { @@ -2439,10 +2342,7 @@ static ast_expression *array_field_setter_node( return NULL; } - if (!ast_block_exprs_add(block, (ast_expression*)st)) { - ast_delete(block); - return NULL; - } + vec_push(block->exprs, (ast_expression*)st); ret = ast_return_new(ctx, NULL); if (!ret) { @@ -2450,10 +2350,7 @@ static ast_expression *array_field_setter_node( return NULL; } - if (!ast_block_exprs_add(block, (ast_expression*)ret)) { - ast_delete(block); - return NULL; - } + vec_push(block->exprs, (ast_expression*)ret); return (ast_expression*)block; } else { @@ -2551,8 +2448,8 @@ static bool parser_create_array_setter(parser_t *parser, ast_value *array, const goto cleanup; } (void)!ast_value_set_name(value, "value"); /* not important */ - (void)!ast_expression_common_params_add(&fval->expression, index); - (void)!ast_expression_common_params_add(&fval->expression, value); + vec_push(fval->expression.params, index); + vec_push(fval->expression.params, value); root = array_setter_node(parser, array, index, value, 0, array->expression.count); if (!root) { @@ -2560,8 +2457,8 @@ static bool parser_create_array_setter(parser_t *parser, ast_value *array, const goto cleanup; } - (void)!ast_block_exprs_add(body, root); - (void)!ast_function_blocks_add(func, body); + vec_push(body->exprs, root); + vec_push(func->blocks, body); array->setter = fval; return true; cleanup: @@ -2608,9 +2505,9 @@ static bool parser_create_array_field_setter(parser_t *parser, ast_value *array, goto cleanup; } (void)!ast_value_set_name(value, "value"); /* not important */ - (void)!ast_expression_common_params_add(&fval->expression, entity); - (void)!ast_expression_common_params_add(&fval->expression, index); - (void)!ast_expression_common_params_add(&fval->expression, value); + vec_push(fval->expression.params, entity); + vec_push(fval->expression.params, index); + vec_push(fval->expression.params, value); root = array_field_setter_node(parser, array, entity, index, value, 0, array->expression.count); if (!root) { @@ -2618,8 +2515,8 @@ static bool parser_create_array_field_setter(parser_t *parser, ast_value *array, goto cleanup; } - (void)!ast_block_exprs_add(body, root); - (void)!ast_function_blocks_add(func, body); + vec_push(body->exprs, root); + vec_push(func->blocks, body); array->setter = fval; return true; cleanup: @@ -2666,7 +2563,7 @@ static bool parser_create_array_getter(parser_t *parser, ast_value *array, const parseerror(parser, "failed to create locals for array accessor"); goto cleanup; } - (void)!ast_expression_common_params_add(&fval->expression, index); + vec_push(fval->expression.params, index); root = array_getter_node(parser, array, index, 0, array->expression.count); if (!root) { @@ -2674,8 +2571,8 @@ static bool parser_create_array_getter(parser_t *parser, ast_value *array, const goto cleanup; } - (void)!ast_block_exprs_add(body, root); - (void)!ast_function_blocks_add(func, body); + vec_push(body->exprs, root); + vec_push(func->blocks, body); array->getter = fval; return true; cleanup: @@ -2687,17 +2584,12 @@ cleanup: return false; } -typedef struct { - MEM_VECTOR_MAKE(ast_value*, p); -} paramlist_t; -MEM_VEC_FUNCTIONS(paramlist_t, ast_value*, p) - static ast_value *parse_typename(parser_t *parser, ast_value **storebase); static ast_value *parse_parameter_list(parser_t *parser, ast_value *var) { lex_ctx ctx; size_t i; - paramlist_t params; + ast_value **params; ast_value *param; ast_value *fval; bool first = true; @@ -2711,7 +2603,7 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var) return NULL; } - MEM_VECTOR_INIT(¶ms, p); + params = NULL; /* parse variables until we hit a closing paren */ while (parser->tok != ')') { @@ -2746,10 +2638,7 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var) param = parse_typename(parser, NULL); if (!param) goto on_error; - if (!paramlist_t_p_add(¶ms, param)) { - ast_delete(param); - goto on_error; - } + vec_push(params, param); if (param->expression.vtype >= TYPE_VARIANT) { char typename[1024]; ast_type_to_string((ast_expression*)param, typename, sizeof(typename)); @@ -2760,7 +2649,7 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var) } /* sanity check */ - if (params.p_count > 8) + if (vec_size(params) > 8) parseerror(parser, "more than 8 parameters are currently not supported"); /* parse-out */ @@ -2775,15 +2664,16 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var) fval->expression.variadic = variadic; var = fval; - MEM_VECTOR_MOVE(¶ms, p, &var->expression, params); + var->expression.params = params; + params = NULL; return var; on_error: ast_delete(var); - for (i = 0; i < params.p_count; ++i) - ast_delete(params.p[i]); - MEM_VECTOR_CLEAR(¶ms, p); + for (i = 0; i < vec_size(params); ++i) + ast_delete(params[i]); + vec_free(params); return NULL; } @@ -3046,11 +2936,11 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield /* Deal with end_sys_ vars */ was_end = false; if (!strcmp(var->name, "end_sys_globals")) { - parser->crc_globals = parser->globals_count; + parser->crc_globals = vec_size(parser->globals); was_end = true; } else if (!strcmp(var->name, "end_sys_fields")) { - parser->crc_fields = parser->fields_count; + parser->crc_fields = vec_size(parser->fields); was_end = true; } if (was_end && var->expression.vtype == TYPE_FIELD) { @@ -3115,7 +3005,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield goto cleanup; } /* we need the new parameter-names */ - for (i = 0; i < proto->expression.params_count; ++i) + for (i = 0; i < vec_size(proto->expression.params); ++i) ast_value_set_name(proto->expression.params[i], var->expression.params[i]->name); ast_delete(var); var = proto; @@ -3191,53 +3081,28 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield if (!localblock) { /* deal with global variables, fields, functions */ if (!nofields && var->expression.vtype == TYPE_FIELD) { - if (!(retval = parser_t_fields_add(parser, varent))) - goto cleanup; + vec_push(parser->fields, varent); if (isvector) { - for (i = 0; i < 3; ++i) { - if (!(retval = parser_t_fields_add(parser, ve[i]))) - break; - } - if (!retval) { - parser->fields_count -= i+1; - goto cleanup; - } + for (i = 0; i < 3; ++i) + vec_push(parser->fields, ve[i]); } } else { - if (!(retval = parser_t_globals_add(parser, varent))) - goto cleanup; + vec_push(parser->globals, varent); if (isvector) { - for (i = 0; i < 3; ++i) { - if (!(retval = parser_t_globals_add(parser, ve[i]))) - break; - } - if (!retval) { - parser->globals_count -= i+1; - goto cleanup; - } + for (i = 0; i < 3; ++i) + vec_push(parser->globals, ve[i]); } } } else { - if (!(retval = parser_t_locals_add(parser, varent))) - goto cleanup; - if (!(retval = ast_block_locals_add(localblock, var))) { - parser->locals_count--; - goto cleanup; - } + vec_push(parser->locals, varent); + vec_push(localblock->locals, var); if (isvector) { for (i = 0; i < 3; ++i) { - if (!(retval = parser_t_locals_add(parser, ve[i]))) - break; - if (!(retval = ast_block_collect(localblock, ve[i].var))) - break; + vec_push(parser->locals, ve[i]); + ast_block_collect(localblock, ve[i].var); ve[i].var = NULL; /* from here it's being collected in the block */ } - if (!retval) { - parser->locals_count -= i+1; - localblock->locals_count--; - goto cleanup; - } } } @@ -3358,12 +3223,7 @@ skipvar: parseerror(parser, "failed to allocate function for `%s`", var->name); break; } - if (!parser_t_functions_add(parser, func)) { - parseerror(parser, "failed to allocate slot for function `%s`", var->name); - ast_function_delete(func); - var->constval.vfunc = NULL; - break; - } + vec_push(parser->functions, func); func->builtin = -parser_token(parser)->constval.i; @@ -3407,29 +3267,19 @@ skipvar: ast_unref(cval); } } else { - shunt sy; - MEM_VECTOR_INIT(&sy, out); - MEM_VECTOR_INIT(&sy, ops); - if (!shunt_out_add(&sy, syexp(ast_ctx(var), (ast_expression*)var)) || - !shunt_out_add(&sy, syexp(ast_ctx(cexp), (ast_expression*)cexp)) || - !shunt_ops_add(&sy, syop(ast_ctx(var), parser->assign_op))) - { - parseerror(parser, "internal error: failed to prepare initializer"); - ast_unref(cexp); - } - else if (!parser_sy_pop(parser, &sy)) + shunt sy = { NULL, NULL }; + vec_push(sy.out, syexp(ast_ctx(var), (ast_expression*)var)); + vec_push(sy.out, syexp(ast_ctx(cexp), (ast_expression*)cexp)); + vec_push(sy.ops, syop(ast_ctx(var), parser->assign_op)); + if (!parser_sy_pop(parser, &sy)) ast_unref(cexp); else { - if (sy.out_count != 1 && sy.ops_count != 0) + if (vec_size(sy.out) != 1 && vec_size(sy.ops) != 0) parseerror(parser, "internal error: leaked operands"); - else if (!ast_block_exprs_add(localblock, (ast_expression*)sy.out[0].out)) { - parseerror(parser, "failed to create intializing expression"); - ast_unref(sy.out[0].out); - ast_unref(cexp); - } + vec_push(localblock->exprs, (ast_expression*)sy.out[0].out); } - MEM_VECTOR_CLEAR(&sy, out); - MEM_VECTOR_CLEAR(&sy, ops); + vec_free(sy.out); + vec_free(sy.ops); } } @@ -3600,33 +3450,33 @@ bool parser_compile_string(const char *name, const char *str) void parser_cleanup() { size_t i; - for (i = 0; i < parser->functions_count; ++i) { + for (i = 0; i < vec_size(parser->functions); ++i) { ast_delete(parser->functions[i]); } - for (i = 0; i < parser->imm_vector_count; ++i) { + for (i = 0; i < vec_size(parser->imm_vector); ++i) { ast_delete(parser->imm_vector[i]); } - for (i = 0; i < parser->imm_string_count; ++i) { + for (i = 0; i < vec_size(parser->imm_string); ++i) { ast_delete(parser->imm_string[i]); } - for (i = 0; i < parser->imm_float_count; ++i) { + for (i = 0; i < vec_size(parser->imm_float); ++i) { ast_delete(parser->imm_float[i]); } - for (i = 0; i < parser->fields_count; ++i) { + for (i = 0; i < vec_size(parser->fields); ++i) { ast_delete(parser->fields[i].var); mem_d(parser->fields[i].name); } - for (i = 0; i < parser->globals_count; ++i) { + for (i = 0; i < vec_size(parser->globals); ++i) { ast_delete(parser->globals[i].var); mem_d(parser->globals[i].name); } - MEM_VECTOR_CLEAR(parser, functions); - MEM_VECTOR_CLEAR(parser, imm_vector); - MEM_VECTOR_CLEAR(parser, imm_string); - MEM_VECTOR_CLEAR(parser, imm_float); - MEM_VECTOR_CLEAR(parser, globals); - MEM_VECTOR_CLEAR(parser, fields); - MEM_VECTOR_CLEAR(parser, locals); + vec_free(parser->functions); + vec_free(parser->imm_vector); + vec_free(parser->imm_string); + vec_free(parser->imm_float); + vec_free(parser->globals); + vec_free(parser->fields); + vec_free(parser->locals); mem_d(parser); } @@ -3717,7 +3567,7 @@ bool parser_finish(const char *output) return false; } - for (i = 0; i < parser->fields_count; ++i) { + for (i = 0; i < vec_size(parser->fields); ++i) { ast_value *field; bool isconst; if (!ast_istype(parser->fields[i].var, ast_value)) @@ -3743,7 +3593,7 @@ bool parser_finish(const char *output) (void)!ir_value_set_field(field->ir_v, ifld); } } - for (i = 0; i < parser->globals_count; ++i) { + for (i = 0; i < vec_size(parser->globals); ++i) { ast_value *asvalue; if (!ast_istype(parser->globals[i].var, ast_value)) continue; @@ -3762,28 +3612,28 @@ bool parser_finish(const char *output) return false; } } - for (i = 0; i < parser->imm_float_count; ++i) { + for (i = 0; i < vec_size(parser->imm_float); ++i) { if (!ast_global_codegen(parser->imm_float[i], ir, false)) { con_out("failed to generate global %s\n", parser->imm_float[i]->name); ir_builder_delete(ir); return false; } } - for (i = 0; i < parser->imm_string_count; ++i) { + for (i = 0; i < vec_size(parser->imm_string); ++i) { if (!ast_global_codegen(parser->imm_string[i], ir, false)) { con_out("failed to generate global %s\n", parser->imm_string[i]->name); ir_builder_delete(ir); return false; } } - for (i = 0; i < parser->imm_vector_count; ++i) { + for (i = 0; i < vec_size(parser->imm_vector); ++i) { if (!ast_global_codegen(parser->imm_vector[i], ir, false)) { con_out("failed to generate global %s\n", parser->imm_vector[i]->name); ir_builder_delete(ir); return false; } } - for (i = 0; i < parser->globals_count; ++i) { + for (i = 0; i < vec_size(parser->globals); ++i) { ast_value *asvalue; if (!ast_istype(parser->globals[i].var, ast_value)) continue; @@ -3809,7 +3659,7 @@ bool parser_finish(const char *output) } } } - for (i = 0; i < parser->fields_count; ++i) { + for (i = 0; i < vec_size(parser->fields); ++i) { ast_value *asvalue; asvalue = (ast_value*)(parser->fields[i].var->expression.next); @@ -3838,7 +3688,7 @@ bool parser_finish(const char *output) } } } - for (i = 0; i < parser->functions_count; ++i) { + for (i = 0; i < vec_size(parser->functions); ++i) { if (!ast_function_codegen(parser->functions[i], ir)) { con_out("failed to generate function %s\n", parser->functions[i]->name); ir_builder_delete(ir); diff --git a/util.c b/util.c index 2689bc0..3c2e4d3 100644 --- a/util.c +++ b/util.c @@ -32,14 +32,14 @@ uint64_t mem_dt = 0; struct memblock_t { const char *file; unsigned int line; - unsigned int byte; + size_t byte; struct memblock_t *next; struct memblock_t *prev; }; static struct memblock_t *mem_start = NULL; -void *util_memory_a(unsigned int byte, unsigned int line, const char *file) { +void *util_memory_a(size_t byte, unsigned int line, const char *file) { struct memblock_t *info = malloc(sizeof(struct memblock_t) + byte); void *data = (void*)(info+1); if (!info) return NULL; @@ -79,7 +79,7 @@ void util_memory_d(void *ptrn, unsigned int line, const char *file) { free(info); } -void *util_memory_r(void *ptrn, unsigned int byte, unsigned int line, const char *file) { +void *util_memory_r(void *ptrn, size_t byte, unsigned int line, const char *file) { struct memblock_t *oldinfo = NULL; struct memblock_t *newinfo; @@ -106,6 +106,10 @@ void *util_memory_r(void *ptrn, unsigned int byte, unsigned int line, const char newinfo->file = file; newinfo->next = oldinfo->next; newinfo->prev = oldinfo->prev; + if (newinfo->next) + newinfo->next->prev = newinfo; + if (newinfo->prev) + newinfo->prev->next = newinfo; if (mem_start == oldinfo) mem_start = newinfo; @@ -511,3 +515,11 @@ FILE *util_fopen(const char *filename, const char *mode) #endif } +void _util_vec_grow(void **a, size_t i, size_t s) { + size_t m = *a ? 2*_vec_beg(*a)+i : i+1; + void *p = mem_r((*a ? _vec_raw(*a) : NULL), s * m + sizeof(size_t)*2); + if (!*a) + ((size_t*)p)[1] = 0; + *a = (void*)((size_t*)p + 2); + _vec_beg(*a) = m; +}