#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "vm/ByteCode.h"

ByteCode* bcInit() {
    ByteCode* bc = malloc(sizeof(ByteCode));
    bc->capacity = 16;
    bc->length = 0;
    bc->code = malloc(bc->capacity);
    return bc;
}

void bcDelete(ByteCode* bc) {
    free(bc->code);
    free(bc);
}

static void bcReAlloc(ByteCode* bc, int length) {
    while(bc->length + length > bc->capacity) {
        bc->capacity *= 2;
        bc->code = realloc(bc->code, bc->capacity);
    }
}

int bcReserveBytes(ByteCode* bc, int length) {
    bcReAlloc(bc, length);
    int p = bc->length;
    bc->length += length;
    return p;
}

void bcSetBytes(ByteCode* bc, int p, const void* data, int length) {
    memcpy(bc->code + p, data, length);
}

void bcAddBytes(ByteCode* bc, const void* data, int length) {
    bcSetBytes(bc, bcReserveBytes(bc, length), data, length);
}

int bcGetAddress(ByteCode* bc) {
    return bc->length;
}

void bcInsertBytes(ByteCode* bc, const void* data, int length, int address) {
    bcReAlloc(bc, length);
    memmove(bc->code + address + length, bc->code + address,
            bc->length - address);
    memcpy(bc->code + address, data, length);
    bc->length += length;
}