68 lines
1.6 KiB
C
68 lines
1.6 KiB
C
|
|
#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;
|
||
|
|
}
|