2020-10-28 05:16:30 +00:00
|
|
|
#include "cmem.h"
|
|
|
|
#include "cchunk.h"
|
|
|
|
#include "cvalue.h"
|
|
|
|
#include "cvm.h"
|
|
|
|
|
|
|
|
CChunk *newChunk(CState* state, size_t startCapacity) {
|
|
|
|
CChunk *chunk = cosmoM_xmalloc(state, sizeof(CChunk));
|
|
|
|
initChunk(state, chunk, startCapacity);
|
|
|
|
return chunk;
|
|
|
|
}
|
|
|
|
|
|
|
|
void initChunk(CState* state, CChunk *chunk, size_t startCapacity) {
|
|
|
|
chunk->capacity = startCapacity;
|
|
|
|
chunk->lineCapacity = startCapacity;
|
|
|
|
chunk->count = 0;
|
|
|
|
chunk->buf = NULL; // when writeByteChunk is called, it'll allocate the array for us
|
|
|
|
chunk->lineInfo = NULL;
|
|
|
|
|
|
|
|
// constants
|
|
|
|
initValArray(state, &chunk->constants, ARRAY_START);
|
|
|
|
}
|
|
|
|
|
|
|
|
void cleanChunk(CState* state, CChunk *chunk) {
|
|
|
|
// first, free the chunk buffer
|
|
|
|
cosmoM_freearray(state, INSTRUCTION, chunk->buf, chunk->capacity);
|
|
|
|
// then the line info
|
|
|
|
cosmoM_freearray(state, int, chunk->lineInfo, chunk->capacity);
|
|
|
|
// free the constants
|
|
|
|
cleanValArray(state, &chunk->constants);
|
|
|
|
}
|
|
|
|
|
|
|
|
void freeChunk(CState* state, CChunk *chunk) {
|
|
|
|
cleanChunk(state, chunk);
|
|
|
|
// now, free the wrapper struct
|
|
|
|
cosmoM_free(state, CChunk, chunk);
|
|
|
|
}
|
|
|
|
|
|
|
|
int addConstant(CState* state, CChunk *chunk, CValue value) {
|
|
|
|
// before adding the constant, check if we already have it
|
2021-01-02 05:06:24 +00:00
|
|
|
for (size_t i = 0; i < chunk->constants.count; i++) {
|
2020-10-28 05:16:30 +00:00
|
|
|
if (cosmoV_equal(value, chunk->constants.values[i]))
|
|
|
|
return i; // we already have a matching constant!
|
|
|
|
}
|
|
|
|
|
|
|
|
cosmoM_freezeGC(state); // so our GC doesn't free it
|
|
|
|
appendValArray(state, &chunk->constants, value);
|
2020-11-26 05:34:02 +00:00
|
|
|
cosmoM_unfreezeGC(state);
|
2020-10-28 05:16:30 +00:00
|
|
|
return chunk->constants.count - 1; // return the index of the new constants
|
|
|
|
}
|
|
|
|
|
|
|
|
// ================================================================ [WRITE TO CHUNK] ================================================================
|
|
|
|
|
|
|
|
void writeu8Chunk(CState* state, CChunk *chunk, INSTRUCTION i, int line) {
|
|
|
|
// does the buffer need to be reallocated?
|
|
|
|
cosmoM_growarray(state, INSTRUCTION, chunk->buf, chunk->count, chunk->capacity);
|
|
|
|
cosmoM_growarray(state, int, chunk->lineInfo, chunk->count, chunk->lineCapacity);
|
|
|
|
|
|
|
|
// write data to the chunk :)
|
|
|
|
chunk->lineInfo[chunk->count] = line;
|
|
|
|
chunk->buf[chunk->count++] = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
void writeu16Chunk(CState* state, CChunk *chunk, uint16_t i, int line) {
|
|
|
|
INSTRUCTION *buffer = (INSTRUCTION*)(&i);
|
|
|
|
int sz = sizeof(uint16_t) / sizeof(INSTRUCTION);
|
|
|
|
|
|
|
|
for (int i = 0; i < sz; i++) {
|
|
|
|
writeu8Chunk(state, chunk, buffer[i], line);
|
|
|
|
}
|
|
|
|
}
|