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.
This commit is contained in:
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 <blue/ds/string.h>
|
||||
#include <mie/ir/register.h>
|
||||
@@ -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);
|
||||
28
mie/ir/module.c
Normal file
28
mie/ir/module.c
Normal file
@@ -0,0 +1,28 @@
|
||||
#include <mie/ir/module.h>
|
||||
#include <mie/ir/op.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
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);
|
||||
}
|
||||
18
mie/ir/region.c
Normal file
18
mie/ir/region.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <mie/ir/block.h>
|
||||
#include <mie/ir/region.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <mie/ir/region.h>
|
||||
#include <mie/ir/register.h>
|
||||
#include <mie/parse/lex.h>
|
||||
#include <mie/parse/parse.h>
|
||||
#include <mie/parse/parser.h>
|
||||
#include <mie/parse/token.h>
|
||||
#include <mie/type/function.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
@@ -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;
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user