#include "compile-node.h" size_t compile_declare_label(struct compile_ctx *ctx) { size_t id = ctx->c_labels.count; struct compile_label *label = fx_vector_emplace_back( ctx->c_labels, NULL); return id; } void compile_define_label(struct compile_ctx *ctx, size_t label_id) { size_t offset = 0; bshell_scriptblock_get_text(ctx->c_block, NULL, &offset); offset *= sizeof(bshell_instruction); ctx->c_labels.items[label_id].l_ip = offset; } void compile_ref_label(struct compile_ctx *ctx, size_t label_id) { struct compile_label_ref *ref = malloc(sizeof *ref); if (!ref) { return; } memset(ref, 0x0, sizeof *ref); ref->ref_label_id = label_id; bshell_scriptblock_get_text(ctx->c_block, NULL, &ref->ref_offset); ref->ref_offset *= sizeof(bshell_instruction); fx_queue_push_back(&ctx->c_label_refs, &ref->ref_entry); } enum bshell_status compile_resolve_labels(struct compile_ctx *ctx) { fx_queue_entry *cur = fx_queue_pop_front(&ctx->c_label_refs); while (cur) { struct compile_label_ref *ref = fx_unbox( struct compile_label_ref, cur, ref_entry); struct compile_label *label = &ctx->c_labels.items [ref->ref_label_id]; long long rel_value = (long long)label->l_ip - (long long)ref->ref_offset; enum bshell_opcode op; uint32_t arg; bshell_scriptblock_read_instruction( ctx->c_block, ref->ref_offset, &op, &arg); arg = (uint32_t)rel_value; bshell_scriptblock_patch_instruction( ctx->c_block, ref->ref_offset, op, arg); free(ref); cur = fx_queue_pop_front(&ctx->c_label_refs); } return BSHELL_SUCCESS; }