<commit_before>#include <slash/compile.h>
#include <slash/string.h>
#include <string.h>

typedef struct fixup {
    struct fixup* next;
    size_t fixup;
}
fixup_t;

typedef struct next_last_frame {
    struct next_last_frame* prev;
    fixup_t* next_fixups;
    fixup_t* last_fixups;
    size_t try_catch_blocks;
}
next_last_frame_t;

typedef struct sl_compile_state {
    sl_vm_t* vm;
    st_table_t* vars;
    struct sl_compile_state* parent;
    int last_line;
    uint8_t* registers;
    sl_vm_section_t* section;
    next_last_frame_t* next_last_frames;
}
sl_compile_state_t;

static void
init_compile_state(sl_compile_state_t* cs, sl_vm_t* vm, sl_compile_state_t* parent, size_t init_registers)
{
    size_t i;
    cs->vm = vm;
    cs->vars = st_init_table(vm->arena, &sl_string_hash_type);
    cs->parent = parent;
    cs->last_line = 0;
    cs->section = sl_alloc(vm->arena, sizeof(sl_vm_section_t));
    if(parent) {
        cs->section->filename = parent->section->filename;
    }
    cs->section->max_registers = init_registers;
    cs->section->req_registers = 0;
    cs->section->arg_registers = 0;
    cs->section->insns_cap = 4;
    cs->section->insns_count = 0;
    cs->section->insns = sl_alloc(vm->arena, sizeof(sl_vm_insn_t) * cs->section->insns_cap);
    cs->section->can_stack_alloc_frame = 1;
    cs->section->opt_skip = NULL;
    cs->registers = sl_alloc(vm->arena, cs->section->max_registers);
    for(i = 0; i < init_registers; i++) {
        cs->registers[i] = 1;
    }
    cs->next_last_frames = NULL;
}

static size_t
reg_alloc(sl_compile_state_t* cs)
{
    size_t i;
    for(i = 0; i < cs->section->max_registers; i++) {
        if(!cs->registers[i]) {
            cs->registers[i] = 1;
            return i;
        }
    }
    cs->section->max_registers++;
    cs->registers = sl_realloc(cs->vm->arena, cs->registers, cs->section->max_registers);
    cs->registers[cs->section->max_registers - 1] = 1;
    return cs->section->max_registers - 1;
}

static size_t
reg_alloc_block(sl_compile_state_t* cs, size_t count)
{
    size_t i, j;
    for(i = 0; i + count < cs->section->max_registers + 1; i++) {
        if(cs->registers[i]) {
            continue_outer: continue;
        }
        for(j = 0; j < count; j++) {
            if(cs->registers[i + j]) {
                i += j;
                goto continue_outer;
            }
        }
        for(j = 0; j < count; j++) {
            cs->registers[i + j] = 1;
        }
        return i;
    }
    cs->section->max_registers += count;
    cs->registers = sl_realloc(cs->vm->arena, cs->registers, cs->section->max_registers);
    i = cs->section->max_registers - count;
    for(j = 0; j < count; j++) {
        cs->registers[i + j] = 1;
    }
    return i;
}

static void
reg_free(sl_compile_state_t* cs, size_t reg)
{<commit_msg>avoid overrunning registers if count == 0<commit_after>#include <slash/compile.h>
#include <slash/string.h>
#include <string.h>

typedef struct fixup {
    struct fixup* next;
    size_t fixup;
}
fixup_t;

typedef struct next_last_frame {
    struct next_last_frame* prev;
    fixup_t* next_fixups;
    fixup_t* last_fixups;
    size_t try_catch_blocks;
}
next_last_frame_t;

typedef struct sl_compile_state {
    sl_vm_t* vm;
    st_table_t* vars;
    struct sl_compile_state* parent;
    int last_line;
    uint8_t* registers;
    sl_vm_section_t* section;
    next_last_frame_t* next_last_frames;
}
sl_compile_state_t;

static void
init_compile_state(sl_compile_state_t* cs, sl_vm_t* vm, sl_compile_state_t* parent, size_t init_registers)
{
    size_t i;
    cs->vm = vm;
    cs->vars = st_init_table(vm->arena, &sl_string_hash_type);
    cs->parent = parent;
    cs->last_line = 0;
    cs->section = sl_alloc(vm->arena, sizeof(sl_vm_section_t));
    if(parent) {
        cs->section->filename = parent->section->filename;
    }
    cs->section->max_registers = init_registers;
    cs->section->req_registers = 0;
    cs->section->arg_registers = 0;
    cs->section->insns_cap = 4;
    cs->section->insns_count = 0;
    cs->section->insns = sl_alloc(vm->arena, sizeof(sl_vm_insn_t) * cs->section->insns_cap);
    cs->section->can_stack_alloc_frame = 1;
    cs->section->opt_skip = NULL;
    cs->registers = sl_alloc(vm->arena, cs->section->max_registers);
    for(i = 0; i < init_registers; i++) {
        cs->registers[i] = 1;
    }
    cs->next_last_frames = NULL;
}

static size_t
reg_alloc(sl_compile_state_t* cs)
{
    size_t i;
    for(i = 0; i < cs->section->max_registers; i++) {
        if(!cs->registers[i]) {
            cs->registers[i] = 1;
            return i;
        }
    }
    cs->section->max_registers++;
    cs->registers = sl_realloc(cs->vm->arena, cs->registers, cs->section->max_registers);
    cs->registers[cs->section->max_registers - 1] = 1;
    return cs->section->max_registers - 1;
}

static size_t
reg_alloc_block(sl_compile_state_t* cs, size_t count)
{
    if(count == 0) {
        return 0;
    }
    
    size_t i, j;
    for(i = 0; i + count < cs->section->max_registers + 1; i++) {
        if(cs->registers[i]) {
            continue_outer: continue;
        }
        for(j = 0; j < count; j++) {
            if(cs->registers[i + j]) {
                i += j;
                goto continue_outer;
            }
        }
        for(j = 0; j < count; j++) {
            cs->registers[i + j] = 1;
        }
        return i;
    }
    cs->section->max_registers += count;
    cs->registers = sl_realloc(cs->vm->arena, cs->registers, cs->section->max_registers);
    i = cs->section->max_registers - count;
    for(j = 0; j < count; j++) {
        cs->registers[i + j] = 1;
    }
    return i;
}

static void
reg_free(sl_compile_state_t* cs, size_t reg)
{
{'fraction_non_alphanumeric': 0.14443277310924368, 'fraction_numerical': 0.007878151260504201, 'mean_word_length': 2.697734627831715, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 147, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3983835', 'n_tokens_mistral': 2211, 'n_tokens_neox': 2152, 'n_words': 401}