mie: implement ir generation for message sending
This commit is contained in:
111
mie/builder.c
111
mie/builder.c
@@ -1,3 +1,4 @@
|
||||
#include <blue/object/hashmap.h>
|
||||
#include <blue/object/string.h>
|
||||
#include <mie/alloca.h>
|
||||
#include <mie/block.h>
|
||||
@@ -6,6 +7,7 @@
|
||||
#include <mie/data.h>
|
||||
#include <mie/func.h>
|
||||
#include <mie/module.h>
|
||||
#include <mie/msg.h>
|
||||
#include <mie/op.h>
|
||||
#include <mie/ptr.h>
|
||||
#include <mie/record.h>
|
||||
@@ -50,6 +52,8 @@ struct mie_ctx *mie_ctx_create(void)
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -85,6 +89,8 @@ void mie_ctx_destroy(struct mie_ctx *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
b_hashmap_release(ctx->ctx_sel_cache);
|
||||
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
@@ -184,6 +190,41 @@ struct mie_value *mie_ctx_get_int(
|
||||
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);
|
||||
@@ -279,6 +320,29 @@ void mie_builder_set_insert_point(
|
||||
builder->b_current_block = block;
|
||||
}
|
||||
|
||||
struct mie_value *mie_builder_get_data_ptr(
|
||||
struct mie_builder *builder, const char *data_ident)
|
||||
{
|
||||
if (!builder->b_module) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct mie_data *data = mie_module_get_data(builder->b_module, data_ident);
|
||||
if (!data) {
|
||||
struct mie_type *id
|
||||
= mie_ctx_get_type(builder->b_ctx, MIE_TYPE_ID);
|
||||
data = mie_data_create_extern_global(id, data_ident);
|
||||
|
||||
if (!data) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mie_module_put_data(builder->b_module, data);
|
||||
}
|
||||
|
||||
return MIE_VALUE(data);
|
||||
}
|
||||
|
||||
struct mie_value *mie_builder_ret(struct mie_builder *builder, struct mie_value *val)
|
||||
{
|
||||
if (!builder->b_current_block) {
|
||||
@@ -584,10 +648,51 @@ struct mie_value *mie_builder_br_if(
|
||||
}
|
||||
|
||||
struct mie_value *mie_builder_msg(
|
||||
struct mie_builder *builder, struct mie_value *ret_type,
|
||||
struct mie_value *dest, struct mie_value *src, const char *name)
|
||||
struct mie_builder *builder, struct mie_type *ret_type,
|
||||
struct mie_value *recipient, struct mie_value *selector,
|
||||
struct mie_value **args, size_t nr_args, enum mie_builder_flags flags,
|
||||
const char *name)
|
||||
{
|
||||
return NULL;
|
||||
if (!builder->b_current_block) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (builder->b_current_block->b_terminator) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((flags & MIE_BUILDER_IGNORE_RESULT) && name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct mie_msg *msg = malloc(sizeof *msg);
|
||||
if (!msg) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(msg, 0x0, sizeof *msg);
|
||||
|
||||
mie_instr_init(&msg->msg_base, MIE_INSTR_MSG);
|
||||
|
||||
msg->msg_ret_type = ret_type;
|
||||
msg->msg_recipient = recipient;
|
||||
msg->msg_selector = selector;
|
||||
|
||||
msg->msg_nr_args = nr_args;
|
||||
msg->msg_args = calloc(nr_args, sizeof(struct mie_value *));
|
||||
memcpy(msg->msg_args, args, nr_args * sizeof(struct mie_value *));
|
||||
|
||||
if (!mie_block_add_instr(builder->b_current_block, &msg->msg_base)) {
|
||||
free(msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(flags & MIE_BUILDER_IGNORE_RESULT)) {
|
||||
mie_func_generate_value_name(
|
||||
builder->b_current_block->b_parent, MIE_VALUE(msg), name);
|
||||
}
|
||||
|
||||
return MIE_VALUE(msg);
|
||||
}
|
||||
|
||||
struct mie_value *mie_builder_cmp_eq(
|
||||
|
||||
Reference in New Issue
Block a user