mie: implement more ir building functionality

This commit is contained in:
2025-04-13 18:34:02 +01:00
parent 7f0d8b87c5
commit deb1232bf9
21 changed files with 694 additions and 132 deletions

12
mie/arg.c Normal file
View File

@@ -0,0 +1,12 @@
#include <mie/arg.h>
static struct mie_type *get_type(struct mie_value *v)
{
struct mie_arg *arg = MIE_ARG(v);
return arg->arg_type;
}
const struct mie_value_type arg_value_type = {
.t_id = MIE_VALUE_ARG,
.t_get_type = get_type,
};

84
mie/block.c Normal file
View File

@@ -0,0 +1,84 @@
#include <mie/block.h>
#include <mie/func.h>
#include <mie/instr.h>
#include <mie/type.h>
#include <stdlib.h>
static struct mie_type label_type = {};
struct mie_block *mie_block_create(struct mie_func *parent, const char *name)
{
struct mie_block *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
mie_value_init(&out->b_base, MIE_VALUE_BLOCK);
struct mie_value *block = MIE_VALUE(out);
if (parent) {
block = mie_func_generate_value_name(parent, block, name);
if (!block) {
free(out);
return NULL;
}
b_queue_push_back(&parent->f_blocks, &block->v_entry);
out->b_parent = parent;
}
return out;
}
bool mie_block_add_instr(struct mie_block *block, struct mie_instr *instr)
{
switch (instr->i_type) {
case MIE_INSTR_PHI:
if (!b_queue_empty(&block->b_instr) || block->b_terminator) {
return false;
}
b_queue_push_back(&block->b_phi, &instr->i_base.v_entry);
return true;
case MIE_INSTR_RET:
case MIE_INSTR_BR:
case MIE_INSTR_SWITCH:
if (block->b_terminator) {
return false;
}
block->b_terminator = instr;
return true;
default:
if (block->b_terminator) {
return false;
}
b_queue_push_back(&block->b_instr, &instr->i_base.v_entry);
return true;
}
}
static void init_label_type(struct mie_type *out)
{
mie_value_init(&out->t_base, MIE_VALUE_TYPE);
out->t_id = MIE_TYPE_LABEL;
out->t_width = sizeof(uintptr_t) * 8;
}
static struct mie_type *get_type(struct mie_value *v)
{
if (!label_type.t_id) {
init_label_type(&label_type);
}
return &label_type;
}
const struct mie_value_type block_value_type = {
.t_id = MIE_VALUE_BLOCK,
.t_get_type = get_type,
};

View File

@@ -1,21 +1,41 @@
#include <blue/object/string.h>
#include <mie/alloca.h>
#include <mie/block.h>
#include <mie/branch.h>
#include <mie/builder.h>
#include <mie/data.h>
#include <mie/func.h>
#include <mie/module.h>
#include <mie/op.h>
#include <mie/ptr.h>
#include <mie/record.h>
#include <mie/type.h>
#include <stdlib.h>
#include <string.h>
struct ctx_cached_int {
struct mie_int i_val;
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_cached_int, i_node, i_val.i_value, put_cached_int)
struct ctx_int_cache_entry, i_node, i_type.t_width, put_cached_int_type)
B_BTREE_DEFINE_SIMPLE_GET(
struct ctx_cached_int, long long, i_node, i_val.i_value, get_cached_int)
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)
{
@@ -27,8 +47,8 @@ struct mie_ctx *mie_ctx_create(void)
memset(out, 0x0, sizeof *out);
out->ctx_true = mie_int_create(1, 1);
out->ctx_false = mie_int_create(0, 1);
out->ctx_true = MIE_CONST(mie_ctx_get_int(out, 1, 1));
out->ctx_false = MIE_CONST(mie_ctx_get_int(out, 0, 1));
return out;
}
@@ -36,52 +56,131 @@ struct mie_ctx *mie_ctx_create(void)
void mie_ctx_destroy(struct mie_ctx *ctx)
{
if (ctx->ctx_true) {
mie_value_release(MIE_VALUE(ctx->ctx_true));
mie_value_destroy(MIE_VALUE(ctx->ctx_true));
ctx->ctx_true = NULL;
}
if (ctx->ctx_false) {
mie_value_release(MIE_VALUE(ctx->ctx_false));
mie_value_destroy(MIE_VALUE(ctx->ctx_false));
ctx->ctx_false = NULL;
}
b_btree_iterator it = {};
b_btree_iterator_begin(&ctx->ctx_ints, &it);
b_btree_iterator_begin(&ctx->ctx_int_cache, &it);
while (b_btree_iterator_is_valid(&it)) {
b_btree_node *node = it.node;
struct ctx_int_cache_entry *entry
= b_unbox(struct ctx_int_cache_entry, it.node, i_node);
b_btree_iterator_erase(&it);
struct ctx_cached_int *entry
= b_unbox(struct ctx_cached_int, node, i_node);
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);
}
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)
struct mie_value *mie_ctx_get_int(
struct mie_ctx *ctx, long long val, unsigned int nr_bits)
{
struct ctx_cached_int *cache_entry = get_cached_int(&ctx->ctx_ints, val);
if (cache_entry) {
return MIE_VALUE(&cache_entry->i_val);
}
struct ctx_int_cache_entry *entry
= get_cached_int_type(&ctx->ctx_int_cache, nr_bits);
cache_entry = malloc(sizeof *cache_entry);
if (!cache_entry) {
if (!entry) {
entry = malloc(sizeof *entry);
if (!entry) {
return NULL;
}
memset(cache_entry, 0x0, sizeof *cache_entry);
memset(entry, 0x0, sizeof *entry);
mie_int_init(&cache_entry->i_val, val, 32);
cache_entry->i_val.i_base.c_base.v_flags |= MIE_VALUE_F_STATIC;
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;
return MIE_VALUE(&cache_entry->i_val);
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_builder *mie_builder_create(struct mie_ctx *ctx, struct mie_module *mod)
@@ -171,24 +270,66 @@ void mie_builder_set_insert_point(
struct mie_value *mie_builder_ret(struct mie_builder *builder, struct mie_value *val)
{
if (!builder->b_current_block) {
return NULL;
}
if (builder->b_current_block->b_terminator) {
return NULL;
}
struct mie_ret *ret = malloc(sizeof *ret);
if (!ret) {
return NULL;
}
mie_instr_init(&ret->r_base, MIE_INSTR_RET);
ret->r_val = mie_value_retain(val);
ret->r_val = val;
if (!mie_block_add_instr(builder->b_current_block, &ret->r_base)) {
free(ret);
return NULL;
}
return MIE_VALUE(ret);
}
struct mie_value *mie_builder_add(
struct mie_builder *builder, struct mie_value *left,
struct mie_value *right, const char *name)
{
if (!builder->b_current_block) {
return NULL;
}
if (builder->b_current_block->b_terminator) {
return NULL;
}
struct mie_binary_op *add = malloc(sizeof *add);
if (!add) {
return NULL;
}
memset(add, 0x0, sizeof *add);
mie_instr_init(&add->op_base, MIE_INSTR_ADD);
add->op_left = left;
add->op_right = right;
add->op_type = mie_value_get_type(left);
if (!mie_block_add_instr(builder->b_current_block, &add->op_base)) {
free(add);
return NULL;
}
mie_func_generate_value_name(
builder->b_current_block->b_parent, MIE_VALUE(add), name);
return MIE_VALUE(add);
}
struct mie_value *mie_builder_sub(
struct mie_builder *builder, struct mie_value *left,
struct mie_value *right, const char *name)
@@ -211,24 +352,95 @@ struct mie_value *mie_builder_div(
}
struct mie_value *mie_builder_load(
struct mie_builder *builder, struct mie_value *type,
struct mie_builder *builder, struct mie_type *type,
struct mie_value *src, const char *name)
{
if (!builder->b_current_block) {
return NULL;
}
if (builder->b_current_block->b_terminator) {
return NULL;
}
struct mie_load *load = malloc(sizeof *load);
if (!load) {
return NULL;
}
mie_instr_init(&load->l_base, MIE_INSTR_LOAD);
load->l_src = src;
load->l_type = type;
if (!mie_block_add_instr(builder->b_current_block, &load->l_base)) {
free(load);
return NULL;
}
mie_func_generate_value_name(
builder->b_current_block->b_parent, MIE_VALUE(load), name);
return MIE_VALUE(load);
}
struct mie_value *mie_builder_store(
struct mie_builder *builder, struct mie_value *val, struct mie_value *dest)
{
if (!builder->b_current_block) {
return NULL;
}
if (builder->b_current_block->b_terminator) {
return NULL;
}
struct mie_store *store = malloc(sizeof *store);
if (!store) {
return NULL;
}
mie_instr_init(&store->s_base, MIE_INSTR_STORE);
store->s_val = val;
store->s_dest = dest;
if (!mie_block_add_instr(builder->b_current_block, &store->s_base)) {
free(store);
return NULL;
}
return MIE_VALUE(store);
}
struct mie_value *mie_builder_alloca(
struct mie_builder *builder, struct mie_type *type, const char *name)
{
if (!builder->b_current_block) {
return NULL;
}
if (builder->b_current_block->b_terminator) {
return NULL;
}
struct mie_alloca *alloca = malloc(sizeof *alloca);
if (!alloca) {
return NULL;
}
mie_instr_init(&alloca->a_base, MIE_INSTR_ALLOCA);
alloca->a_type = type;
if (!mie_block_add_instr(builder->b_current_block, &alloca->a_base)) {
free(alloca);
return NULL;
}
mie_func_generate_value_name(
builder->b_current_block->b_parent, MIE_VALUE(alloca), name);
return MIE_VALUE(alloca);
}
struct mie_value *mie_builder_switch(
struct mie_builder *builder, struct mie_value *cond,
struct mie_switch_branch *branches, size_t nr_branches,
@@ -239,9 +451,33 @@ struct mie_value *mie_builder_switch(
struct mie_value *mie_builder_br(struct mie_builder *builder, struct mie_block *dest)
{
if (!builder->b_current_block) {
return NULL;
}
if (builder->b_current_block->b_terminator) {
return NULL;
}
struct mie_branch *br = malloc(sizeof *br);
if (!br) {
return NULL;
}
memset(br, 0x0, sizeof *br);
mie_instr_init(&br->b_base, MIE_INSTR_BR);
br->b_dest = dest;
if (!mie_block_add_instr(builder->b_current_block, &br->b_base)) {
free(br);
return NULL;
}
return MIE_VALUE(br);
}
struct mie_value *mie_builder_br_if(
struct mie_builder *builder, struct mie_value *cond,
struct mie_block *if_true, struct mie_block *if_false)

View File

@@ -2,25 +2,13 @@
#include <stdlib.h>
#include <string.h>
void mie_int_init(struct mie_int *out, long long val, unsigned int nr_bits)
static struct mie_type *get_type(struct mie_value *v)
{
memset(out, 0x0, sizeof *out);
mie_value_init(&out->i_base.c_base, MIE_VALUE_CONST);
out->i_base.c_type = MIE_CONST_INT;
out->i_value = val;
out->i_width = nr_bits;
struct mie_const *c = MIE_CONST(v);
return c->c_type;
}
struct mie_int *mie_int_create(long long val, unsigned int nr_bits)
{
struct mie_int *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
mie_int_init(out, val, nr_bits);
return out;
}
const struct mie_value_type const_value_type = {
.t_id = MIE_VALUE_CONST,
.t_get_type = get_type,
};

92
mie/func.c Normal file
View File

@@ -0,0 +1,92 @@
#include <blue/core/hash.h>
#include <blue/object/string.h>
#include <mie/block.h>
#include <mie/func.h>
#include <mie/name.h>
#include <stdlib.h>
#include <string.h>
struct mie_func *mie_func_create(
const char *name, enum mie_func_type type, struct mie_type *ret_type,
struct mie_arg **args, unsigned int nr_args)
{
struct mie_func *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
mie_value_init(&out->f_base, MIE_VALUE_FUNC);
out->f_base.v_name.n_str = b_strdup(name);
out->f_base.v_name.n_base.e_hash = b_hash_string(name);
out->f_type = type;
out->f_ret = ret_type;
out->f_names = mie_name_map_create();
for (size_t i = 0; i < nr_args; i++) {
if (args[i]) {
struct mie_value *arg_value = MIE_VALUE(args[i]);
b_queue_push_back(&out->f_args, &arg_value->v_entry);
}
}
return out;
}
struct mie_block *mie_func_create_block(struct mie_func *func, const char *name)
{
struct mie_block *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
mie_value_init(&out->b_base, MIE_VALUE_BLOCK);
struct mie_value *block = MIE_VALUE(out);
block = mie_func_generate_value_name(func, block, name);
if (!block) {
free(out);
return NULL;
}
out->b_parent = func;
return out;
}
void mie_func_insert_block(
struct mie_func *func, struct mie_block *block, struct mie_block *after)
{
if (after) {
b_queue_insert_after(
&func->f_blocks, &block->b_base.v_entry,
&after->b_base.v_entry);
} else {
b_queue_push_back(&func->f_blocks, &block->b_base.v_entry);
}
}
struct mie_value *mie_func_generate_value_name(
struct mie_func *func, struct mie_value *val, const char *hint)
{
struct mie_name *name
= mie_name_map_put(func->f_names, &val->v_name, hint);
return b_unbox(struct mie_value, name, v_name);
}
static struct mie_type *get_type(struct mie_value *v)
{
struct mie_func *f = MIE_FUNC(v);
return f->f_ret;
}
const struct mie_value_type func_value_type = {
.t_id = MIE_VALUE_FUNC,
.t_get_type = get_type,
};

13
mie/include/mie/arg.h Normal file
View File

@@ -0,0 +1,13 @@
#ifndef MIE_ARG_H_
#define MIE_ARG_H_
#include <mie/value.h>
#define MIE_ARG(p) ((struct mie_arg *)(p))
struct mie_arg {
struct mie_value arg_base;
struct mie_type *arg_type;
};
#endif

View File

@@ -1,10 +1,13 @@
#ifndef MIE_BLOCK_H_
#define MIE_BLOCK_H_
#define MIE_BLOCK(p) ((struct mie_block *)(p))
#include <mie/value.h>
struct mie_block {
struct mie_value b_base;
struct mie_func *b_parent;
/* the phi instruction(s). these must appear at the start of the block
* and are separated to make traversing the CFG easier */
b_queue b_phi;
@@ -15,4 +18,8 @@ struct mie_block {
struct mie_instr *b_terminator;
};
MIE_API struct mie_block *mie_block_create(
struct mie_func *parent, const char *name);
MIE_API bool mie_block_add_instr(struct mie_block *block, struct mie_instr *instr);
#endif

View File

@@ -6,7 +6,7 @@
struct mie_branch {
struct mie_instr b_base;
struct mie_label *b_dest;
struct mie_block *b_dest;
};
struct mie_branch_if {

View File

@@ -4,6 +4,7 @@
#include <blue/core/btree.h>
#include <mie/misc.h>
#include <mie/switch.h>
#include <mie/type.h>
#include <mie/value.h>
struct b_dict;
@@ -15,22 +16,28 @@ struct mie_type;
struct mie_phi;
struct mie_ctx {
struct mie_int *ctx_true, *ctx_false;
b_btree ctx_ints;
struct mie_const *ctx_true, *ctx_false;
struct mie_type *ctx_types[__MIE_TYPE_COUNT];
b_btree ctx_int_cache;
};
struct mie_builder {
struct mie_ctx *b_ctx;
struct mie_module *b_module;
struct mie_instr *b_prev_instr;
struct mie_block *b_current_block;
struct mie_instr *b_prev_instr;
};
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);
extern struct mie_value *mie_ctx_get_int(
struct mie_ctx *ctx, long long val, unsigned int nr_bits);
extern struct mie_builder *mie_builder_create(
struct mie_ctx *ctx, struct mie_module *mod);
@@ -58,7 +65,7 @@ extern struct mie_value *mie_builder_div(
struct mie_builder *builder, struct mie_value *left,
struct mie_value *right, const char *name);
extern struct mie_value *mie_builder_load(
struct mie_builder *builder, struct mie_value *type,
struct mie_builder *builder, struct mie_type *type,
struct mie_value *src, const char *name);
extern struct mie_value *mie_builder_store(
struct mie_builder *builder, struct mie_value *val, struct mie_value *dest);

View File

@@ -3,54 +3,18 @@
#include <mie/value.h>
enum mie_const_type {
MIE_CONST_NONE = 0,
MIE_CONST_INT,
MIE_CONST_FLOAT,
MIE_CONST_STRING,
MIE_CONST_ATOM,
MIE_CONST_LABEL,
MIE_CONST_ARRAY,
};
#define MIE_CONST(p) ((struct mie_const *)(p))
struct mie_const {
struct mie_value c_base;
enum mie_const_type c_type;
};
struct mie_type *c_type;
struct mie_int {
struct mie_const i_base;
unsigned short i_width;
long long i_value;
union {
int64_t v_int;
double v_float;
char *v_str;
char *v_atom;
} c_v;
};
struct mie_float {
struct mie_const f_base;
double f_value;
};
struct mie_str {
struct mie_const s_base;
char *s_value;
};
struct mie_atom {
struct mie_const s_base;
char *s_value;
};
struct mie_label {
struct mie_const l_base;
char *l_value;
};
struct mie_array {
struct mie_const a_base;
unsigned int a_nr_values;
struct mie_value **a_values;
};
extern void mie_int_init(struct mie_int *out, long long val, unsigned int nr_bits);
extern struct mie_int *mie_int_create(long long val, unsigned int nr_bits);
#endif

View File

@@ -1,10 +1,14 @@
#ifndef MIE_FUNC_H_
#define MIE_FUNC_H_
#define MIE_FUNC(p) ((struct mie_func *)(p))
#include <mie/value.h>
struct mie_name_map;
struct mie_type;
struct mie_arg;
struct mie_block;
struct b_dict;
enum mie_func_type {
@@ -17,11 +21,11 @@ enum mie_func_type {
struct mie_func {
struct mie_value f_base;
struct b_dict *f_named_values;
enum mie_func_type f_type;
struct mie_type *f_ret;
struct mie_name_map *f_names;
b_queue f_args;
b_queue f_blocks;
};
@@ -29,7 +33,11 @@ struct mie_func {
extern struct mie_func *mie_func_create(
const char *name, enum mie_func_type type, struct mie_type *ret_type,
struct mie_arg **args, unsigned int nr_args);
extern char *mie_func_generate_value_name(
struct mie_func *func, const char *name_hint);
extern struct mie_block *mie_func_create_block(
struct mie_func *func, const char *name);
extern void mie_func_insert_block(
struct mie_func *func, struct mie_block *block, struct mie_block *after);
extern struct mie_value *mie_func_generate_value_name(
struct mie_func *func, struct mie_value *val, const char *hint);
#endif

View File

@@ -3,6 +3,8 @@
#include <mie/value.h>
#define MIE_INSTR(p) ((struct mie_instr *)(p))
enum mie_instr_type {
MIE_INSTR_NONE = 0,
MIE_INSTR_RET,

View File

@@ -1,9 +1,13 @@
#ifndef MIE_MODULE_H_
#define MIE_MODULE_H_
#define MIE_MODULE(p) ((struct mie_module *)(p))
#include <blue/core/queue.h>
#include <mie/value.h>
struct mie_func;
struct mie_module {
struct mie_value m_base;
b_queue m_records;
@@ -12,4 +16,7 @@ struct mie_module {
b_queue m_func;
};
extern struct mie_module *mie_module_create(void);
extern void mie_module_add_function(struct mie_module *mod, struct mie_func *func);
#endif

View File

@@ -1,6 +1,8 @@
#ifndef MIE_RECORD_H_
#define MIE_RECORD_H_
#define MIE_RECORD(p) ((struct mie_record *)(p))
#include <mie/const.h>
#include <mie/value.h>

View File

@@ -1,15 +1,21 @@
#ifndef MIE_TYPE_H_
#define MIE_TYPE_H_
#define MIE_TYPE(p) ((struct mie_type *)(p))
#include <mie/value.h>
enum mie_type_id {
MIE_TYPE_VOID = 0x00u,
MIE_TYPE_INT = 0x01u,
MIE_TYPE_ID = 0x02u,
MIE_TYPE_STR = 0x03u,
MIE_TYPE_SYM = 0x04u,
MIE_TYPE_CLASS = 0x05u,
MIE_TYPE_PTR = 0x02u,
MIE_TYPE_ID = 0x03u,
MIE_TYPE_STR = 0x04u,
MIE_TYPE_ATOM = 0x05u,
MIE_TYPE_CLASS = 0x06u,
MIE_TYPE_ARRAY = 0x08u,
MIE_TYPE_LABEL = 0x09u,
__MIE_TYPE_COUNT,
};
struct mie_type {

View File

@@ -7,14 +7,18 @@
#define MIE_VALUE(p) ((struct mie_value *)(p))
enum mie_value_type {
struct mie_value;
enum mie_value_type_id {
MIE_VALUE_NONE = 0,
MIE_VALUE_CONST,
MIE_VALUE_MODULE,
MIE_VALUE_TYPE,
MIE_VALUE_RECORD,
MIE_VALUE_FUNC,
MIE_VALUE_ARG,
MIE_VALUE_BLOCK,
MIE_VALUE_INSTR,
MIE_VALUE_OP,
MIE_VALUE_RECORD,
MIE_VALUE_CONST,
};
enum mie_value_flags {
@@ -22,16 +26,31 @@ enum mie_value_flags {
MIE_VALUE_F_STATIC = 0x01u,
};
struct mie_value_type {
enum mie_value_type_id t_id;
struct mie_type *(*t_get_type)(struct mie_value *);
};
struct mie_value {
unsigned int v_ref;
struct mie_name v_name;
enum mie_value_type v_type;
const struct mie_value_type *v_type;
enum mie_value_flags v_flags;
b_queue_entry v_entry;
};
MIE_API void mie_value_init(struct mie_value *val, enum mie_value_type type);
MIE_API struct mie_value *mie_value_retain(struct mie_value *val);
MIE_API void mie_value_release(struct mie_value *val);
MIE_API void mie_value_init(struct mie_value *val, enum mie_value_type_id type);
MIE_API void mie_value_destroy(struct mie_value *val);
MIE_API struct mie_type *mie_value_get_type(struct mie_value *val);
static inline bool mie_value_is(
const struct mie_value *val, enum mie_value_type_id type_id)
{
if (!val->v_type) {
return false;
}
return val->v_type->t_id == type_id;
}
#endif

View File

@@ -1,4 +1,8 @@
#include <mie/instr.h>
#include <mie/op.h>
#include <mie/ptr.h>
static struct mie_type ptr_type = {};
void mie_instr_init(struct mie_instr *instr, enum mie_instr_type type)
{
@@ -6,3 +10,46 @@ void mie_instr_init(struct mie_instr *instr, enum mie_instr_type type)
mie_value_init(&instr->i_base, MIE_VALUE_INSTR);
instr->i_type = type;
}
static void init_ptr_type(struct mie_type *out)
{
mie_value_init(&out->t_base, MIE_VALUE_TYPE);
out->t_id = MIE_TYPE_PTR;
out->t_width = sizeof(uintptr_t) * 8;
}
static struct mie_type *get_type(struct mie_value *v)
{
struct mie_instr *instr = MIE_INSTR(v);
if (!ptr_type.t_id) {
init_ptr_type(&ptr_type);
}
switch (instr->i_type) {
case MIE_INSTR_RET: {
struct mie_ret *ret = (struct mie_ret *)instr;
return mie_value_get_type(ret->r_val);
}
case MIE_INSTR_ADD:
case MIE_INSTR_SUB:
case MIE_INSTR_MUL:
case MIE_INSTR_DIV: {
struct mie_binary_op *op = (struct mie_binary_op *)instr;
return op->op_type;
}
case MIE_INSTR_LOAD: {
struct mie_load *load = (struct mie_load *)instr;
return load->l_type;
}
case MIE_INSTR_ALLOCA:
return &ptr_type;
default:
return NULL;
}
}
const struct mie_value_type instr_value_type = {
.t_id = MIE_VALUE_INSTR,
.t_get_type = get_type,
};

27
mie/module.c Normal file
View File

@@ -0,0 +1,27 @@
#include <mie/func.h>
#include <mie/module.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);
mie_value_init(&out->m_base, MIE_VALUE_MODULE);
return out;
}
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);
}
const struct mie_value_type module_value_type = {
.t_id = MIE_VALUE_MODULE,
};

View File

@@ -13,7 +13,17 @@ struct mie_record *mie_record_create(const struct mie_const *val)
mie_value_init(&out->r_base, MIE_VALUE_RECORD);
out->r_value = val;
mie_value_retain(MIE_VALUE(out->r_value));
return out;
}
static struct mie_type *get_type(struct mie_value *v)
{
struct mie_record *r = MIE_RECORD(v);
return r->r_value->c_type;
}
const struct mie_value_type record_value_type = {
.t_id = MIE_VALUE_RECORD,
.t_get_type = get_type,
};

11
mie/type.c Normal file
View File

@@ -0,0 +1,11 @@
#include <mie/type.h>
static struct mie_type *get_type(struct mie_value *v)
{
return MIE_TYPE(v);
}
const struct mie_value_type type_value_type = {
.t_id = MIE_VALUE_TYPE,
.t_get_type = get_type,
};

View File

@@ -1,25 +1,45 @@
#include <mie/const.h>
#include <mie/value.h>
void mie_value_init(struct mie_value *val, enum mie_value_type type)
extern const struct mie_value_type module_value_type;
extern const struct mie_value_type type_value_type;
extern const struct mie_value_type record_value_type;
extern const struct mie_value_type func_value_type;
extern const struct mie_value_type arg_value_type;
extern const struct mie_value_type block_value_type;
extern const struct mie_value_type instr_value_type;
extern const struct mie_value_type const_value_type;
static const struct mie_value_type *value_types[] = {
[MIE_VALUE_NONE] = NULL,
[MIE_VALUE_MODULE] = &module_value_type,
[MIE_VALUE_TYPE] = &type_value_type,
[MIE_VALUE_RECORD] = &record_value_type,
[MIE_VALUE_FUNC] = &func_value_type,
[MIE_VALUE_ARG] = &arg_value_type,
[MIE_VALUE_BLOCK] = &block_value_type,
[MIE_VALUE_INSTR] = &instr_value_type,
[MIE_VALUE_CONST] = &const_value_type,
};
static const size_t nr_value_types = sizeof value_types / sizeof value_types[0];
void mie_value_init(struct mie_value *val, enum mie_value_type_id type)
{
memset(val, 0x0, sizeof *val);
val->v_ref = 1;
val->v_type = type;
val->v_type = value_types[type];
}
struct mie_value *mie_value_retain(struct mie_value *val)
void mie_value_destroy(struct mie_value *val)
{
val->v_ref++;
return val;
}
void mie_value_release(struct mie_value *val)
{
if (val->v_ref > 1) {
val->v_ref--;
return;
}
/* TODO cleanup value */
}
struct mie_type *mie_value_get_type(struct mie_value *val)
{
if (val->v_type->t_get_type) {
return val->v_type->t_get_type(val);
}
return NULL;
}