mie: implement caching and emitting string data

This commit is contained in:
2025-04-17 22:55:17 +01:00
parent abb7cfaf0e
commit 9cce4bf541
11 changed files with 211 additions and 58 deletions

View File

@@ -66,43 +66,39 @@ void mie_builder_put_record(
b_queue_push_back(&builder->b_module->m_records, &rec->r_base.v_entry);
}
#if 0
void mie_builder_put_data(struct mie_builder *builder, struct mie_data *data)
{
if (!builder->b_module) {
return;
}
b_queue_iterator it = {};
b_queue_foreach (&it, &builder->b_module->m_data) {
struct mie_value *cur
= b_unbox(struct mie_value, it.entry, v_entry);
if (!strcmp(cur->v_name.n_str, data->d_base.v_name.n_str)) {
const char *data_name = data->d_base.v_name.n_str;
struct mie_data *v = mie_module_get_data(builder->b_module, data_name);
if (v) {
return;
}
}
b_queue_push_back(&builder->b_module->m_data, &data->d_base.v_entry);
mie_module_put_data(builder->b_module, data);
}
#endif
#if 0
void mie_builder_put_type(struct mie_builder *builder, struct mie_type *type)
{
if (!builder->b_module) {
return;
}
b_queue_iterator it = {};
b_queue_foreach (&it, &builder->b_module->m_types) {
struct mie_value *cur
= b_unbox(struct mie_value, it.entry, v_entry);
if (!strcmp(cur->v_name.n_str, type->t_base.v_name.n_str)) {
const char *type_name = type->t_base.v_name.n_str;
struct mie_data *v = mie_module_get_data(builder->b_module, type_name);
if (v) {
return;
}
}
b_queue_push_back(&builder->b_module->m_data, &type->t_base.v_entry);
mie_module_put_data(builder->b_module, MIE_VALUE);
}
#endif
void mie_builder_set_insert_point(
struct mie_builder *builder, struct mie_block *block)
@@ -127,7 +123,32 @@ struct mie_value *mie_builder_get_data_ptr(
return NULL;
}
mie_module_put_data(builder->b_module, data);
mie_module_put_data(builder->b_module, data, data_ident);
}
return MIE_VALUE(data);
}
struct mie_value *mie_builder_get_string_ptr(
struct mie_builder *builder, const char *s)
{
if (!builder->b_module) {
return NULL;
}
struct mie_data *data = mie_module_get_string_ptr(builder->b_module, s);
if (!data) {
struct mie_type *str
= mie_ctx_get_type(builder->b_ctx, MIE_TYPE_STR);
struct mie_value *value = mie_ctx_get_string(builder->b_ctx, s);
data = mie_data_create_const((struct mie_const *)value);
if (!data) {
return NULL;
}
mie_module_put_data(builder->b_module, data, ".str");
}
return MIE_VALUE(data);

View File

@@ -2,6 +2,22 @@
#include <stdlib.h>
#include <string.h>
struct mie_const *mie_const_create(struct mie_type *type)
{
struct mie_const *c = malloc(sizeof *c);
if (!c) {
return NULL;
}
memset(c, 0x0, sizeof *c);
mie_value_init(&c->c_base, MIE_VALUE_CONST);
c->c_type = type;
return c;
}
static struct mie_type *get_type(struct mie_value *v)
{
struct mie_const *c = MIE_CONST(v);

View File

@@ -1,5 +1,6 @@
#include "convert.h"
#include <blue/object/hashmap.h>
#include <inttypes.h>
#include <mie/alloca.h>
#include <mie/arg.h>
@@ -153,7 +154,7 @@ static b_status write_operand_const(
break;
case MIE_TYPE_STR:
case MIE_TYPE_ATOM:
write_string(converter, c->c_v.v_str);
write_string_f(converter, "\"%s\"", c->c_v.v_str);
break;
case MIE_TYPE_CLASS:
write_string_f(converter, "@%s", value->v_name.n_str);
@@ -266,9 +267,10 @@ static b_status write_module(
write_char(converter, '\n');
}
b_queue_foreach (&it, &mod->m_data) {
struct mie_value *data
= b_unbox(struct mie_value, it.entry, v_entry);
b_hashmap_iterator it2;
b_hashmap_foreach(&it2, mod->m_data)
{
struct mie_value *data = it2.value->value_data;
status = write_value_to_text(converter, data);
if (!B_OK(status)) {
@@ -276,7 +278,7 @@ static b_status write_module(
}
}
if (!b_queue_empty(&mod->m_data)) {
if (!b_hashmap_is_empty(mod->m_data)) {
write_char(converter, '\n');
}
@@ -552,7 +554,8 @@ static b_status write_data(
break;
case MIE_DATA_CONST:
write_operand_const(
converter, data->d_const.c_value, F_INCLUDE_TYPE);
converter, MIE_VALUE(data->d_const.c_value),
F_INCLUDE_TYPE);
break;
default:
write_string(converter, "<unknown>");

View File

@@ -43,6 +43,7 @@ struct mie_ctx *mie_ctx_create(void)
out->ctx_false = MIE_CONST(mie_ctx_get_int(out, 0, 1));
out->ctx_sel_cache = b_hashmap_create(free, free);
out->ctx_string_cache = b_hashmap_create(free, free);
return out;
}
@@ -214,3 +215,38 @@ struct mie_value *mie_ctx_get_selector(struct mie_ctx *ctx, const char *sel)
return MIE_VALUE(sel_value);
}
struct mie_value *mie_ctx_get_string(struct mie_ctx *ctx, const char *s)
{
b_hashmap_key key = {
.key_data = s,
.key_size = strlen(s),
};
const b_hashmap_value *cache_entry
= b_hashmap_get(ctx->ctx_string_cache, &key);
if (cache_entry) {
return cache_entry->value_data;
}
struct mie_const *string_value = malloc(sizeof *string_value);
if (!string_value) {
return NULL;
}
mie_value_init(&string_value->c_base, MIE_VALUE_CONST);
string_value->c_type = mie_ctx_get_type(ctx, MIE_TYPE_STR);
string_value->c_v.v_str = b_strdup(s);
key.key_data = string_value->c_v.v_str;
b_hashmap_value hashmap_value = {
.value_data = string_value,
.value_size = sizeof *string_value,
};
b_hashmap_put(ctx->ctx_string_cache, &key, &hashmap_value);
return MIE_VALUE(string_value);
}

View File

@@ -33,6 +33,23 @@ struct mie_data *mie_data_create_extern_global(
return data;
}
struct mie_data *mie_data_create_const(struct mie_const *value)
{
struct mie_data *data = malloc(sizeof *data);
if (!data) {
return NULL;
}
memset(data, 0x0, sizeof *data);
mie_value_init(&data->d_base, MIE_VALUE_DATA);
data->d_type = MIE_DATA_CONST;
data->d_const.c_value = value;
return data;
}
static struct mie_type *get_type(struct mie_value *v)
{
if (!ptr_type.t_id) {

View File

@@ -27,18 +27,6 @@ enum mie_builder_flags {
MIE_BUILDER_IGNORE_RESULT = 0x01u,
};
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);
extern struct mie_builder *mie_builder_create(
struct mie_ctx *ctx, struct mie_module *mod);
extern void mie_builder_destroy(struct mie_builder *builder);
@@ -59,6 +47,8 @@ extern void mie_builder_set_insert_point(
extern struct mie_value *mie_builder_get_data_ptr(
struct mie_builder *builder, const char *data_ident);
extern struct mie_value *mie_builder_get_string_ptr(
struct mie_builder *builder, const char *s);
extern struct mie_value *mie_builder_ret(
struct mie_builder *builder, struct mie_value *val);

View File

@@ -18,4 +18,6 @@ struct mie_const {
} c_v;
};
extern struct mie_const *mie_const_create(struct mie_type *type);
#endif

View File

@@ -9,6 +9,7 @@ struct mie_ctx {
struct mie_type *ctx_types[__MIE_TYPE_COUNT];
b_btree ctx_int_cache;
struct b_hashmap *ctx_sel_cache;
struct b_hashmap *ctx_string_cache;
};
extern struct mie_ctx *mie_ctx_create(void);
@@ -21,6 +22,7 @@ extern struct mie_type *mie_ctx_get_int_type(
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_string(struct mie_ctx *ctx, const char *s);
extern struct mie_value *mie_ctx_get_selector(struct mie_ctx *ctx, const char *sel);
#endif

View File

@@ -16,7 +16,7 @@ struct mie_data {
enum mie_data_type d_type;
union {
struct {
struct mie_value *c_value;
struct mie_const *c_value;
} d_const;
struct {
@@ -27,5 +27,6 @@ struct mie_data {
extern struct mie_data *mie_data_create_extern_global(
struct mie_type *type, const char *ident);
extern struct mie_data *mie_data_create_const(struct mie_const *value);
#endif

View File

@@ -4,23 +4,33 @@
#define MIE_MODULE(p) ((struct mie_module *)(p))
#include <blue/core/queue.h>
#include <mie/name.h>
#include <mie/value.h>
struct mie_func;
struct b_hashmap;
struct mie_module {
struct mie_value m_base;
struct mie_name_map *m_names;
b_queue m_records;
b_queue m_data;
b_queue m_types;
b_queue m_func;
struct b_hashmap *m_data;
struct b_hashmap *m_data_strings;
};
extern struct mie_module *mie_module_create(void);
extern void mie_module_add_function(struct mie_module *mod, struct mie_func *func);
extern struct mie_data *mie_module_get_string_ptr(
struct mie_module *mod, const char *s);
extern struct mie_data *mie_module_get_data(
struct mie_module *mod, const char *name);
extern enum b_status mie_module_put_data(
struct mie_module *mod, struct mie_data *data);
struct mie_module *mod, struct mie_data *data, const char *name);
extern struct mie_value *mie_module_generate_value_name(
struct mie_module *mod, struct mie_value *val, const char *hint);
#endif

View File

@@ -1,6 +1,9 @@
#include <blue/object/hashmap.h>
#include <mie/const.h>
#include <mie/data.h>
#include <mie/func.h>
#include <mie/module.h>
#include <mie/type.h>
#include <stdlib.h>
#include <string.h>
@@ -15,6 +18,10 @@ struct mie_module *mie_module_create(void)
mie_value_init(&out->m_base, MIE_VALUE_MODULE);
out->m_names = mie_name_map_create();
out->m_data = b_hashmap_create(NULL, NULL);
out->m_data_strings = b_hashmap_create(NULL, NULL);
return out;
}
@@ -23,27 +30,79 @@ void mie_module_add_function(struct mie_module *mod, struct mie_func *func)
b_queue_push_back(&mod->m_func, &func->f_base.v_entry);
}
struct mie_data *mie_module_get_data(struct mie_module *mod, const char *name)
struct mie_data *mie_module_get_string_ptr(struct mie_module *mod, const char *s)
{
b_queue_iterator it;
b_queue_foreach (&it, &mod->m_data) {
struct mie_data *data = (struct mie_data *)b_unbox(
struct mie_value, it.entry, v_entry);
if (!strcmp(data->d_base.v_name.n_str, name)) {
return data;
}
b_hashmap_key key = {
.key_data = s,
.key_size = strlen(s),
};
const b_hashmap_value *entry = b_hashmap_get(mod->m_data_strings, &key);
if (entry) {
return entry->value_data;
}
return NULL;
}
enum b_status mie_module_put_data(struct mie_module *mod, struct mie_data *data)
struct mie_data *mie_module_get_data(struct mie_module *mod, const char *name)
{
/* TODO enforce unique names */
b_queue_push_back(&mod->m_data, &data->d_base.v_entry);
b_hashmap_key key = {
.key_data = name,
.key_size = strlen(name),
};
const b_hashmap_value *entry = b_hashmap_get(mod->m_data, &key);
if (entry) {
return entry->value_data;
}
/* don't search m_data_strings, as it is keyed by the string contents
* rather than the data entry name, and its entries are duplicated in
* m_data anyway */
return NULL;
}
enum b_status mie_module_put_data(
struct mie_module *mod, struct mie_data *data, const char *name)
{
struct mie_value *v
= mie_module_generate_value_name(mod, MIE_VALUE(data), name);
b_hashmap_key key = {
.key_data = v->v_name.n_str,
.key_size = strlen(name),
};
b_hashmap_value value = {
.value_data = data,
.value_size = sizeof *data,
};
b_hashmap_put(mod->m_data, &key, &value);
if (data->d_type != MIE_DATA_CONST) {
return B_SUCCESS;
}
struct mie_const *const_data = data->d_const.c_value;
if (const_data->c_type->t_id == MIE_TYPE_STR) {
key.key_data = const_data->c_v.v_str;
key.key_size = strlen(key.key_data);
b_hashmap_put(mod->m_data_strings, &key, &value);
}
return B_SUCCESS;
}
struct mie_value *mie_module_generate_value_name(
struct mie_module *mod, struct mie_value *val, const char *hint)
{
struct mie_name *name = mie_name_map_put(mod->m_names, &val->v_name, hint);
return b_unbox(struct mie_value, name, v_name);
}
static void cleanup(struct mie_value *value)
{
struct mie_module *module = MIE_MODULE(value);
@@ -56,13 +115,6 @@ static void cleanup(struct mie_value *value)
mie_value_destroy(v);
}
b_queue_iterator_begin(&module->m_data, &it);
while (b_queue_iterator_is_valid(&it)) {
struct mie_value *v = b_unbox(struct mie_value, it.entry, v_entry);
b_queue_iterator_erase(&it);
mie_value_destroy(v);
}
b_queue_iterator_begin(&module->m_types, &it);
while (b_queue_iterator_is_valid(&it)) {
struct mie_value *v = b_unbox(struct mie_value, it.entry, v_entry);
@@ -76,6 +128,9 @@ static void cleanup(struct mie_value *value)
b_queue_iterator_erase(&it);
mie_value_destroy(v);
}
b_hashmap_release(module->m_data_strings);
b_hashmap_release(module->m_data);
}
const struct mie_value_type module_value_type = {