diff --git a/mie/builder.c b/mie/builder.c index a2b1f8d..245063e 100644 --- a/mie/builder.c +++ b/mie/builder.c @@ -1,9 +1,9 @@ -#include #include #include #include #include #include +#include #include #include #include @@ -15,216 +15,6 @@ #include #include -struct ctx_int_cache_entry { - b_btree_node i_node; - struct mie_type i_type; - b_btree i_values; -}; - -struct ctx_int_value_cache_entry { - b_btree_node i_node; - struct mie_const i_value; -}; - -B_BTREE_DEFINE_SIMPLE_INSERT( - struct ctx_int_cache_entry, i_node, i_type.t_width, put_cached_int_type) -B_BTREE_DEFINE_SIMPLE_GET( - struct ctx_int_cache_entry, unsigned int, i_node, i_type.t_width, - get_cached_int_type) - -B_BTREE_DEFINE_SIMPLE_INSERT( - struct ctx_int_value_cache_entry, i_node, i_value.c_v.v_int, - put_cached_int_value) -B_BTREE_DEFINE_SIMPLE_GET( - struct ctx_int_value_cache_entry, int64_t, i_node, i_value.c_v.v_int, - get_cached_int_value) - -struct mie_ctx *mie_ctx_create(void) -{ - struct mie_ctx *out = malloc(sizeof *out); - - if (!out) { - return NULL; - } - - memset(out, 0x0, sizeof *out); - - out->ctx_true = MIE_CONST(mie_ctx_get_int(out, 1, 1)); - out->ctx_false = MIE_CONST(mie_ctx_get_int(out, 0, 1)); - - out->ctx_sel_cache = b_hashmap_create(free, free); - - return out; -} - -void mie_ctx_destroy(struct mie_ctx *ctx) -{ - ctx->ctx_true = NULL; - ctx->ctx_false = NULL; - - b_btree_iterator it = {}; - b_btree_iterator_begin(&ctx->ctx_int_cache, &it); - while (b_btree_iterator_is_valid(&it)) { - struct ctx_int_cache_entry *entry - = b_unbox(struct ctx_int_cache_entry, it.node, i_node); - b_btree_iterator_erase(&it); - - b_btree_iterator it2 = {}; - b_btree_iterator_begin(&entry->i_values, &it2); - while (b_btree_iterator_is_valid(&it2)) { - struct ctx_int_value_cache_entry *value = b_unbox( - struct ctx_int_value_cache_entry, it2.node, i_node); - b_btree_iterator_erase(&it2); - free(value); - } - - free(entry); - } - - const size_t nr_types = sizeof ctx->ctx_types / sizeof ctx->ctx_types[0]; - for (size_t i = 0; i < nr_types; i++) { - if (ctx->ctx_types[i]) { - mie_value_destroy(MIE_VALUE(ctx->ctx_types[i])); - ctx->ctx_types[i] = NULL; - } - } - - b_hashmap_release(ctx->ctx_sel_cache); - - free(ctx); -} - -struct mie_type *mie_ctx_get_type(struct mie_ctx *ctx, enum mie_type_id type_id) -{ - if (type_id == MIE_TYPE_INT) { - return NULL; - } - - if (ctx->ctx_types[type_id]) { - return ctx->ctx_types[type_id]; - } - - struct mie_type *type = malloc(sizeof *type); - if (!type) { - return NULL; - } - - memset(type, 0x0, sizeof *type); - - mie_value_init(&type->t_base, MIE_VALUE_TYPE); - type->t_id = type_id; - - ctx->ctx_types[type_id] = type; - return type; -} - -struct mie_type *mie_ctx_get_int_type(struct mie_ctx *ctx, unsigned int nr_bits) -{ - struct ctx_int_cache_entry *entry - = get_cached_int_type(&ctx->ctx_int_cache, nr_bits); - - if (entry) { - return &entry->i_type; - } - - entry = malloc(sizeof *entry); - if (!entry) { - return NULL; - } - - memset(entry, 0x0, sizeof *entry); - - mie_value_init(&entry->i_type.t_base, MIE_VALUE_TYPE); - entry->i_type.t_id = MIE_TYPE_INT; - entry->i_type.t_width = nr_bits; - - put_cached_int_type(&ctx->ctx_int_cache, entry); - return &entry->i_type; -} - -struct mie_value *mie_ctx_get_bool(struct mie_ctx *ctx, bool val) -{ - return MIE_VALUE(val ? ctx->ctx_true : ctx->ctx_false); -} - -struct mie_value *mie_ctx_get_int( - struct mie_ctx *ctx, long long val, unsigned int nr_bits) -{ - struct ctx_int_cache_entry *entry - = get_cached_int_type(&ctx->ctx_int_cache, nr_bits); - - if (!entry) { - entry = malloc(sizeof *entry); - if (!entry) { - return NULL; - } - - memset(entry, 0x0, sizeof *entry); - - mie_value_init(&entry->i_type.t_base, MIE_VALUE_TYPE); - entry->i_type.t_id = MIE_TYPE_INT; - entry->i_type.t_width = nr_bits; - - put_cached_int_type(&ctx->ctx_int_cache, entry); - } - - struct ctx_int_value_cache_entry *value - = get_cached_int_value(&entry->i_values, val); - if (value) { - return MIE_VALUE(&value->i_value); - } - - value = malloc(sizeof *value); - if (!value) { - return NULL; - } - - memset(value, 0x0, sizeof *value); - - mie_value_init(&value->i_value.c_base, MIE_VALUE_CONST); - value->i_value.c_type = &entry->i_type; - value->i_value.c_v.v_int = val; - - put_cached_int_value(&entry->i_values, value); - - return MIE_VALUE(&value->i_value); -} - -struct mie_value *mie_ctx_get_selector(struct mie_ctx *ctx, const char *sel) -{ - b_hashmap_key key = { - .key_data = sel, - .key_size = strlen(sel), - }; - - const b_hashmap_value *cache_entry - = b_hashmap_get(ctx->ctx_sel_cache, &key); - - if (cache_entry) { - return cache_entry->value_data; - } - - struct mie_const *sel_value = malloc(sizeof *sel_value); - if (!sel_value) { - return NULL; - } - - mie_value_init(&sel_value->c_base, MIE_VALUE_CONST); - sel_value->c_type = mie_ctx_get_type(ctx, MIE_TYPE_SELECTOR); - sel_value->c_v.v_selector = b_strdup(sel); - - key.key_data = sel_value->c_v.v_selector; - - b_hashmap_value hashmap_value = { - .value_data = sel_value, - .value_size = sizeof *sel_value, - }; - - b_hashmap_put(ctx->ctx_sel_cache, &key, &hashmap_value); - - return MIE_VALUE(sel_value); -} - struct mie_builder *mie_builder_create(struct mie_ctx *ctx, struct mie_module *mod) { struct mie_builder *out = malloc(sizeof *out); diff --git a/mie/ctx.c b/mie/ctx.c new file mode 100644 index 0000000..621101e --- /dev/null +++ b/mie/ctx.c @@ -0,0 +1,216 @@ +#include +#include +#include +#include +#include +#include + +struct ctx_int_cache_entry { + b_btree_node i_node; + struct mie_type i_type; + b_btree i_values; +}; + +struct ctx_int_value_cache_entry { + b_btree_node i_node; + struct mie_const i_value; +}; + +B_BTREE_DEFINE_SIMPLE_INSERT( + struct ctx_int_cache_entry, i_node, i_type.t_width, put_cached_int_type) +B_BTREE_DEFINE_SIMPLE_GET( + struct ctx_int_cache_entry, unsigned int, i_node, i_type.t_width, + get_cached_int_type) + +B_BTREE_DEFINE_SIMPLE_INSERT( + struct ctx_int_value_cache_entry, i_node, i_value.c_v.v_int, + put_cached_int_value) +B_BTREE_DEFINE_SIMPLE_GET( + struct ctx_int_value_cache_entry, int64_t, i_node, i_value.c_v.v_int, + get_cached_int_value) + +struct mie_ctx *mie_ctx_create(void) +{ + struct mie_ctx *out = malloc(sizeof *out); + + if (!out) { + return NULL; + } + + memset(out, 0x0, sizeof *out); + + out->ctx_true = MIE_CONST(mie_ctx_get_int(out, 1, 1)); + out->ctx_false = MIE_CONST(mie_ctx_get_int(out, 0, 1)); + + out->ctx_sel_cache = b_hashmap_create(free, free); + + return out; +} + +void mie_ctx_destroy(struct mie_ctx *ctx) +{ + ctx->ctx_true = NULL; + ctx->ctx_false = NULL; + + b_btree_iterator it = {}; + b_btree_iterator_begin(&ctx->ctx_int_cache, &it); + while (b_btree_iterator_is_valid(&it)) { + struct ctx_int_cache_entry *entry + = b_unbox(struct ctx_int_cache_entry, it.node, i_node); + b_btree_iterator_erase(&it); + + b_btree_iterator it2 = {}; + b_btree_iterator_begin(&entry->i_values, &it2); + while (b_btree_iterator_is_valid(&it2)) { + struct ctx_int_value_cache_entry *value = b_unbox( + struct ctx_int_value_cache_entry, it2.node, i_node); + b_btree_iterator_erase(&it2); + free(value); + } + + free(entry); + } + + const size_t nr_types = sizeof ctx->ctx_types / sizeof ctx->ctx_types[0]; + for (size_t i = 0; i < nr_types; i++) { + if (ctx->ctx_types[i]) { + mie_value_destroy(MIE_VALUE(ctx->ctx_types[i])); + ctx->ctx_types[i] = NULL; + } + } + + b_hashmap_release(ctx->ctx_sel_cache); + + free(ctx); +} + +struct mie_type *mie_ctx_get_type(struct mie_ctx *ctx, enum mie_type_id type_id) +{ + if (type_id == MIE_TYPE_INT) { + return NULL; + } + + if (ctx->ctx_types[type_id]) { + return ctx->ctx_types[type_id]; + } + + struct mie_type *type = malloc(sizeof *type); + if (!type) { + return NULL; + } + + memset(type, 0x0, sizeof *type); + + mie_value_init(&type->t_base, MIE_VALUE_TYPE); + type->t_id = type_id; + + ctx->ctx_types[type_id] = type; + return type; +} + +struct mie_type *mie_ctx_get_int_type(struct mie_ctx *ctx, unsigned int nr_bits) +{ + struct ctx_int_cache_entry *entry + = get_cached_int_type(&ctx->ctx_int_cache, nr_bits); + + if (entry) { + return &entry->i_type; + } + + entry = malloc(sizeof *entry); + if (!entry) { + return NULL; + } + + memset(entry, 0x0, sizeof *entry); + + mie_value_init(&entry->i_type.t_base, MIE_VALUE_TYPE); + entry->i_type.t_id = MIE_TYPE_INT; + entry->i_type.t_width = nr_bits; + + put_cached_int_type(&ctx->ctx_int_cache, entry); + return &entry->i_type; +} + +struct mie_value *mie_ctx_get_bool(struct mie_ctx *ctx, bool val) +{ + return MIE_VALUE(val ? ctx->ctx_true : ctx->ctx_false); +} + +struct mie_value *mie_ctx_get_int( + struct mie_ctx *ctx, long long val, unsigned int nr_bits) +{ + struct ctx_int_cache_entry *entry + = get_cached_int_type(&ctx->ctx_int_cache, nr_bits); + + if (!entry) { + entry = malloc(sizeof *entry); + if (!entry) { + return NULL; + } + + memset(entry, 0x0, sizeof *entry); + + mie_value_init(&entry->i_type.t_base, MIE_VALUE_TYPE); + entry->i_type.t_id = MIE_TYPE_INT; + entry->i_type.t_width = nr_bits; + + put_cached_int_type(&ctx->ctx_int_cache, entry); + } + + struct ctx_int_value_cache_entry *value + = get_cached_int_value(&entry->i_values, val); + if (value) { + return MIE_VALUE(&value->i_value); + } + + value = malloc(sizeof *value); + if (!value) { + return NULL; + } + + memset(value, 0x0, sizeof *value); + + mie_value_init(&value->i_value.c_base, MIE_VALUE_CONST); + value->i_value.c_type = &entry->i_type; + value->i_value.c_v.v_int = val; + + put_cached_int_value(&entry->i_values, value); + + return MIE_VALUE(&value->i_value); +} + +struct mie_value *mie_ctx_get_selector(struct mie_ctx *ctx, const char *sel) +{ + b_hashmap_key key = { + .key_data = sel, + .key_size = strlen(sel), + }; + + const b_hashmap_value *cache_entry + = b_hashmap_get(ctx->ctx_sel_cache, &key); + + if (cache_entry) { + return cache_entry->value_data; + } + + struct mie_const *sel_value = malloc(sizeof *sel_value); + if (!sel_value) { + return NULL; + } + + mie_value_init(&sel_value->c_base, MIE_VALUE_CONST); + sel_value->c_type = mie_ctx_get_type(ctx, MIE_TYPE_SELECTOR); + sel_value->c_v.v_selector = b_strdup(sel); + + key.key_data = sel_value->c_v.v_selector; + + b_hashmap_value hashmap_value = { + .value_data = sel_value, + .value_size = sizeof *sel_value, + }; + + b_hashmap_put(ctx->ctx_sel_cache, &key, &hashmap_value); + + return MIE_VALUE(sel_value); +} diff --git a/mie/include/mie/builder.h b/mie/include/mie/builder.h index 74f77fa..a1ca8b7 100644 --- a/mie/include/mie/builder.h +++ b/mie/include/mie/builder.h @@ -14,13 +14,7 @@ struct mie_module; struct mie_data; struct mie_type; struct mie_phi; - -struct mie_ctx { - struct mie_const *ctx_true, *ctx_false; - struct mie_type *ctx_types[__MIE_TYPE_COUNT]; - b_btree ctx_int_cache; - struct b_hashmap *ctx_sel_cache; -}; +struct mie_ctx; struct mie_builder { struct mie_ctx *b_ctx; diff --git a/mie/include/mie/ctx.h b/mie/include/mie/ctx.h new file mode 100644 index 0000000..616fd8b --- /dev/null +++ b/mie/include/mie/ctx.h @@ -0,0 +1,26 @@ +#ifndef MIE_CTX_H_ +#define MIE_CTX_H_ + +#include +#include + +struct mie_ctx { + struct mie_const *ctx_true, *ctx_false; + struct mie_type *ctx_types[__MIE_TYPE_COUNT]; + b_btree ctx_int_cache; + struct b_hashmap *ctx_sel_cache; +}; + +extern struct mie_ctx *mie_ctx_create(void); +extern void mie_ctx_destroy(struct mie_ctx *ctx); + +extern struct mie_type *mie_ctx_get_type( + struct mie_ctx *ctx, enum mie_type_id type_id); +extern struct mie_type *mie_ctx_get_int_type( + struct mie_ctx *ctx, unsigned int nr_bits); +extern struct mie_value *mie_ctx_get_bool(struct mie_ctx *ctx, bool val); +extern struct mie_value *mie_ctx_get_int( + struct mie_ctx *ctx, long long val, unsigned int nr_bits); +extern struct mie_value *mie_ctx_get_selector(struct mie_ctx *ctx, const char *sel); + +#endif