From d19e8626da21c0290712aaeeeb80289dd6701c73 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Mon, 12 Jan 2026 10:40:57 +0000 Subject: [PATCH] mie: stop using movable memory for mie_name instances. any struct that contains a mie_name cannot be stored in movable memory (i.e. any memory that may be re-allocated using realloc(), or whose contents may be moved to a different buffer). mie_names form part of a bst when they are added to a mie_name_map, and moving them after this happens will result in the bst pointers being invalidated. this causes some obscure and hard-to-debug memory errors. all structs that contain a mie_name (including named IR objects like mie_register and mie_block) are no longer stored directly in vectors. rather, vectors of pointers are used instead. --- mie/include/mie/ir/block.h | 2 +- mie/include/mie/ir/op.h | 2 +- mie/include/mie/ir/region.h | 2 +- mie/include/mie/name.h | 7 +++ mie/include/mie/parse/{parse.h => parser.h} | 6 +-- mie/ir/module.c | 28 ++++++++++++ mie/ir/region.c | 18 ++++++++ mie/parse/{parse.c => parser.c} | 50 ++++++++++++++------- mie/vector.c | 4 +- 9 files changed, 95 insertions(+), 24 deletions(-) rename mie/include/mie/parse/{parse.h => parser.h} (97%) create mode 100644 mie/ir/module.c create mode 100644 mie/ir/region.c rename mie/parse/{parse.c => parser.c} (96%) diff --git a/mie/include/mie/ir/block.h b/mie/include/mie/ir/block.h index 71af2aa..73b23f5 100644 --- a/mie/include/mie/ir/block.h +++ b/mie/include/mie/ir/block.h @@ -12,7 +12,7 @@ struct mie_register; struct mie_block { struct mie_name b_name; - MIE_VECTOR_DECLARE(struct mie_register, b_params); + MIE_VECTOR_DECLARE(struct mie_register *, b_params); MIE_VECTOR_DECLARE(struct mie_op, b_ops); }; diff --git a/mie/include/mie/ir/op.h b/mie/include/mie/ir/op.h index a2139e8..5c48ccf 100644 --- a/mie/include/mie/ir/op.h +++ b/mie/include/mie/ir/op.h @@ -67,7 +67,7 @@ struct mie_op { MIE_VECTOR_DECLARE(struct mie_op_successor, op_successors); MIE_VECTOR_DECLARE(struct mie_op_attribute, op_attrib); MIE_VECTOR_DECLARE(struct mie_op_arg, op_args); - MIE_VECTOR_DECLARE(struct mie_register, op_result); + MIE_VECTOR_DECLARE(struct mie_register *, op_result); }; MIE_API void mie_op_destroy(struct mie_op *op); diff --git a/mie/include/mie/ir/region.h b/mie/include/mie/ir/region.h index f8870c8..d190a1b 100644 --- a/mie/include/mie/ir/region.h +++ b/mie/include/mie/ir/region.h @@ -9,7 +9,7 @@ struct mie_block; struct mie_region { struct mie_name_map *r_names; - MIE_VECTOR_DECLARE(struct mie_block, r_blocks); + MIE_VECTOR_DECLARE(struct mie_block *, r_blocks); }; MIE_API struct mie_block *mie_region_add_block(struct mie_region *region); diff --git a/mie/include/mie/name.h b/mie/include/mie/name.h index 52a0c7d..370044b 100644 --- a/mie/include/mie/name.h +++ b/mie/include/mie/name.h @@ -35,6 +35,13 @@ struct mie_name_map_entry { }; }; +/* stores a unique name, and forms a binary tree of similar entries. + * this struct is designed to be embedded directly within a larger struct + * (rather than just as a pointer), allowing the larger struct to be part + * of a name map. Because of this, mie_name CANNOT be used in any memory that + * may be re-allocated. If a mie_name is moved after it is added to a + * mie_name_map, the internal bst pointers that make up the map will be + * invalidated, causing some very obscure memory-related errors. */ struct mie_name { struct mie_name_map_entry n_base; struct mie_name_map *n_parent; diff --git a/mie/include/mie/parse/parse.h b/mie/include/mie/parse/parser.h similarity index 97% rename from mie/include/mie/parse/parse.h rename to mie/include/mie/parse/parser.h index b433c54..2e3d6c1 100644 --- a/mie/include/mie/parse/parse.h +++ b/mie/include/mie/parse/parser.h @@ -1,5 +1,5 @@ -#ifndef MIE_PARSE_PARSE_H_ -#define MIE_PARSE_PARSE_H_ +#ifndef MIE_PARSE_PARSER_H_ +#define MIE_PARSE_PARSER_H_ #include #include @@ -94,7 +94,7 @@ MIE_API bool mie_parser_parse_register( struct mie_register *out); MIE_API bool mie_parser_parse_register_list( struct mie_parser *ctx, struct mie_name_map *names, - MIE_VECTOR_REF_PARAM(struct mie_register, out)); + MIE_VECTOR_REF_PARAM(struct mie_register *, out)); MIE_API bool mie_parser_parse_region( struct mie_parser *ctx, struct mie_region *region); diff --git a/mie/ir/module.c b/mie/ir/module.c new file mode 100644 index 0000000..6609ba2 --- /dev/null +++ b/mie/ir/module.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include + +struct mie_module *mie_module_create(void) +{ + struct mie_module *out = malloc(sizeof *out); + if (!out) { + return NULL; + } + + memset(out, 0x0, sizeof *out); + + out->m_names = mie_name_map_create(NULL); + + return out; +} + +void mie_module_destroy(struct mie_module *mod) +{ + /* TODO */ +} + +struct mie_op *mie_module_add_op(struct mie_module *mod) +{ + return mie_vector_emplace_back(mod->m_ops); +} diff --git a/mie/ir/region.c b/mie/ir/region.c new file mode 100644 index 0000000..4dab861 --- /dev/null +++ b/mie/ir/region.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include + +struct mie_block *mie_region_add_block(struct mie_region *region) +{ + struct mie_block *block = malloc(sizeof *block); + if (!block) { + return NULL; + } + + memset(block, 0x0, sizeof *block); + + mie_vector_push_back(region->r_blocks, &block); + + return block; +} diff --git a/mie/parse/parse.c b/mie/parse/parser.c similarity index 96% rename from mie/parse/parse.c rename to mie/parse/parser.c index 73c30e3..53214bc 100644 --- a/mie/parse/parse.c +++ b/mie/parse/parser.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include @@ -200,7 +200,11 @@ bool mie_parser_parse_linefeed(struct mie_parser *ctx) return false; } - mie_lex_advance(ctx->p_lex); + while (tok && tok->tok_type == MIE_TOK_LINEFEED) { + mie_lex_advance(ctx->p_lex); + tok = mie_lex_peek(ctx->p_lex); + } + return true; } @@ -617,7 +621,7 @@ bool mie_parser_parse_register( bool mie_parser_parse_register_list( struct mie_parser *ctx, struct mie_name_map *names, - MIE_VECTOR_REF_PARAM(struct mie_register, out)) + MIE_VECTOR_REF_PARAM(struct mie_register *, out)) { bool ok = false; struct mie_register *reg = NULL; @@ -628,11 +632,13 @@ bool mie_parser_parse_register_list( return false; } - reg = mie_vector_ref_emplace_back(out); + reg = calloc(1, sizeof *reg); if (!reg) { return false; } + mie_vector_ref_push_back(out, ®); + if (!mie_parser_parse_register(ctx, names, reg)) { return false; } @@ -652,10 +658,11 @@ bool mie_parser_parse_register_list( return false; } - reg = mie_vector_ref_emplace_back(out); + reg = calloc(1, sizeof *reg); if (!reg) { return false; } + mie_vector_ref_push_back(out, ®); if (!mie_parser_parse_register(ctx, names, reg)) { return false; @@ -670,7 +677,16 @@ bool mie_parser_parse_module(struct mie_parser *ctx, struct mie_module *mod) #define OP_TOKEN_TYPES \ (MIE_TOK_NAME | MIE_TOK_OPNAME | MIE_TOK_VREGNAME | MIE_TOK_MREGNAME \ | MIE_TOK_GRAPHNAME | MIE_TOK_INSTNAME) - while (1) { + + for (size_t i = 0;; i++) { + if (mie_parser_check_eof(ctx)) { + break; + } + + if (i > 0 && !mie_parser_parse_linefeed(ctx)) { + return false; + } + enum mie_token_type type = mie_parser_peek_type(ctx); bool is_op = (type & OP_TOKEN_TYPES); @@ -678,7 +694,7 @@ bool mie_parser_parse_module(struct mie_parser *ctx, struct mie_module *mod) break; } - struct mie_op *op = mie_vector_emplace_back(mod->m_ops); + struct mie_op *op = mie_module_add_op(mod); if (!op) { return false; } @@ -699,11 +715,14 @@ bool mie_parser_parse_region(struct mie_parser *ctx, struct mie_region *region) return false; } - mie_parser_parse_linefeed(ctx); + if (!mie_parser_parse_linefeed(ctx)) { + return false; + } + struct mie_block *block = NULL; if (mie_parser_peek_type(ctx) != MIE_TOK_BLOCKNAME) { - block = mie_vector_emplace_back(region->r_blocks); + block = mie_region_add_block(region); if (!mie_parser_parse_anonymous_block(ctx, region->r_names, block)) { return false; @@ -715,7 +734,7 @@ bool mie_parser_parse_region(struct mie_parser *ctx, struct mie_region *region) break; } - block = mie_vector_emplace_back(region->r_blocks); + block = mie_region_add_block(region); if (!mie_parser_parse_block(ctx, region->r_names, block)) { return false; @@ -804,16 +823,15 @@ static bool parse_block_parameters( return false; } - if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN) - || !mie_parser_parse_symbol(ctx, MIE_SYM_COLON) - || !mie_parser_parse_linefeed(ctx)) { + if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) { mie_vector_destroy(block_params, NULL); return false; } for (size_t i = 0; i < MIE_VECTOR_COUNT(block_params); i++) { - struct mie_register *param_reg - = mie_vector_emplace_back(block->b_params); + struct mie_register *param_reg = calloc(1, sizeof *param_reg); + mie_vector_push_back(block->b_params, ¶m_reg); + param_reg->reg_flags = block_params.items[i].arg_unresolved.reg_flags | MIE_REGISTER_F_BLOCK_PARAM; param_reg->reg_type = block_params.items[i].arg_unresolved.reg_type; @@ -1134,7 +1152,7 @@ static bool parse_generic_op( } for (size_t i = 0; i < MIE_VECTOR_COUNT(func_type->func_out); i++) { - dest->op_result.items[i].reg_type = func_type->func_out.items[i]; + dest->op_result.items[i]->reg_type = func_type->func_out.items[i]; } return true; diff --git a/mie/vector.c b/mie/vector.c index fd31dfb..4a24f3b 100644 --- a/mie/vector.c +++ b/mie/vector.c @@ -2,7 +2,7 @@ #include #include -#define DEFAULT_CAPACITY 4 +#define DEFAULT_CAPACITY 16 struct vector { void *v_buf; @@ -49,7 +49,7 @@ static int vector_reserve(struct vector *v, size_t new_capacity) static int vector_push_back(struct vector *v, const void *item) { - int err = vector_reserve(v, v->v_count + 1); + int err = vector_reserve(v, v->v_count + DEFAULT_CAPACITY); if (err != 0) { return err; }