Cosmo/src/cchunk.c

81 lines
2.4 KiB
C
Raw Normal View History

2020-10-28 05:16:30 +00:00
#include "cchunk.h"
2023-02-09 18:32:48 +00:00
#include "cmem.h"
#include "cobj.h"
2020-10-28 05:16:30 +00:00
#include "cvalue.h"
#include "cvm.h"
2023-02-09 18:32:48 +00:00
CChunk *newChunk(CState *state, size_t startCapacity)
{
2020-10-28 05:16:30 +00:00
CChunk *chunk = cosmoM_xmalloc(state, sizeof(CChunk));
initChunk(state, chunk, startCapacity);
return chunk;
}
2023-02-09 18:32:48 +00:00
void initChunk(CState *state, CChunk *chunk, size_t startCapacity)
{
2020-10-28 05:16:30 +00:00
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;
2023-02-09 18:32:48 +00:00
2020-10-28 05:16:30 +00:00
// constants
initValArray(state, &chunk->constants, ARRAY_START);
}
2023-02-09 18:32:48 +00:00
void cleanChunk(CState *state, CChunk *chunk)
{
2020-10-28 05:16:30 +00:00
// first, free the chunk buffer
2023-08-30 04:21:52 +00:00
cosmoM_freeArray(state, INSTRUCTION, chunk->buf, chunk->capacity);
2020-10-28 05:16:30 +00:00
// then the line info
2023-08-30 04:21:52 +00:00
cosmoM_freeArray(state, int, chunk->lineInfo, chunk->capacity);
2020-10-28 05:16:30 +00:00
// free the constants
cleanValArray(state, &chunk->constants);
}
2023-02-09 18:32:48 +00:00
void freeChunk(CState *state, CChunk *chunk)
{
2020-10-28 05:16:30 +00:00
cleanChunk(state, chunk);
// now, free the wrapper struct
cosmoM_free(state, CChunk, chunk);
}
2023-02-09 18:32:48 +00:00
int addConstant(CState *state, CChunk *chunk, CValue value)
{
2020-10-28 05:16:30 +00:00
// 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++) {
if (cosmoV_equal(state, value, chunk->constants.values[i]))
2020-10-28 05:16:30 +00:00
return i; // we already have a matching constant!
}
cosmoV_pushValue(state, value); // push the value to the stack so our GC can see it
2020-10-28 05:16:30 +00:00
appendValArray(state, &chunk->constants, value);
cosmoV_pop(state);
2020-10-28 05:16:30 +00:00
return chunk->constants.count - 1; // return the index of the new constants
}
2023-02-09 18:32:48 +00:00
// ================================================================ [WRITE TO CHUNK]
2020-10-28 05:16:30 +00:00
2023-02-09 18:32:48 +00:00
void writeu8Chunk(CState *state, CChunk *chunk, INSTRUCTION i, int line)
{
2020-10-28 05:16:30 +00:00
// does the buffer need to be reallocated?
2023-08-30 04:21:52 +00:00
cosmoM_growArray(state, INSTRUCTION, chunk->buf, chunk->count, chunk->capacity);
cosmoM_growArray(state, int, chunk->lineInfo, chunk->count, chunk->lineCapacity);
2020-10-28 05:16:30 +00:00
// write data to the chunk :)
chunk->lineInfo[chunk->count] = line;
chunk->buf[chunk->count++] = i;
}
2023-02-09 18:32:48 +00:00
void writeu16Chunk(CState *state, CChunk *chunk, uint16_t i, int line)
{
2023-02-09 18:52:36 +00:00
static const int sz = sizeof(uint16_t) / sizeof(INSTRUCTION);
2023-02-09 18:32:48 +00:00
INSTRUCTION *buffer = (INSTRUCTION *)(&i);
2020-10-28 05:16:30 +00:00
for (int i = 0; i < sz; i++) {
writeu8Chunk(state, chunk, buffer[i], line);
}
}