chunk.c
1 #include <kuroko/chunk.h>
2 #include <kuroko/memory.h>
3 #include <kuroko/vm.h>
4 
5 #include "opcode_enum.h"
6 
7 void krk_initChunk(KrkChunk * chunk) {
8  chunk->count = 0;
9  chunk->capacity = 0;
10  chunk->code = NULL;
11 
12  chunk->linesCount = 0;
13  chunk->linesCapacity = 0;
14  chunk->lines = NULL;
15  chunk->filename = NULL;
16  krk_initValueArray(&chunk->constants);
17 }
18 
19 static void addLine(KrkChunk * chunk, size_t line) {
20  if (chunk->linesCount && chunk->lines[chunk->linesCount-1].line == line) return;
21  if (chunk->linesCapacity < chunk->linesCount + 1) {
22  int old = chunk->linesCapacity;
23  chunk->linesCapacity = GROW_CAPACITY(old);
24  chunk->lines = GROW_ARRAY(KrkLineMap, chunk->lines, old, chunk->linesCapacity);
25  }
26  chunk->lines[chunk->linesCount] = (KrkLineMap){chunk->count, line};
27  chunk->linesCount++;
28 }
29 
30 void krk_writeChunk(KrkChunk * chunk, uint8_t byte, size_t line) {
31  if (chunk->capacity < chunk->count + 1) {
32  int old = chunk->capacity;
33  chunk->capacity = GROW_CAPACITY(old);
34  chunk->code = GROW_ARRAY(uint8_t, chunk->code, old, chunk->capacity);
35  }
36 
37  chunk->code[chunk->count] = byte;
38  addLine(chunk, line);
39  chunk->count++;
40 }
41 
42 void krk_freeChunk(KrkChunk * chunk) {
43  FREE_ARRAY(uint8_t, chunk->code, chunk->capacity);
44  FREE_ARRAY(KrkLineMap, chunk->lines, chunk->linesCapacity);
45  krk_freeValueArray(&chunk->constants);
46  krk_initChunk(chunk);
47 }
48 
49 size_t krk_addConstant(KrkChunk * chunk, KrkValue value) {
50  krk_push(value);
51  krk_writeValueArray(&chunk->constants, value);
52  krk_pop();
53  return chunk->constants.count - 1;
54 }
55 
56 void krk_emitConstant(KrkChunk * chunk, size_t ind, size_t line) {
57  if (ind >= 256) {
58  krk_writeChunk(chunk, OP_CONSTANT_LONG, line);
59  krk_writeChunk(chunk, 0xFF & (ind >> 16), line);
60  krk_writeChunk(chunk, 0xFF & (ind >> 8), line);
61  krk_writeChunk(chunk, 0xFF & (ind >> 0), line);
62  } else {
63  krk_writeChunk(chunk, OP_CONSTANT, line);
64  krk_writeChunk(chunk, ind, line);
65  }
66 }
67 
68 size_t krk_writeConstant(KrkChunk * chunk, KrkValue value, size_t line) {
69  size_t ind = krk_addConstant(chunk, value);
70  krk_emitConstant(chunk, ind, line);
71  return ind;
72 }
73 
74 size_t krk_lineNumber(KrkChunk * chunk, size_t offset) {
75  size_t line = 0;
76  for (size_t i = 0; i < chunk->linesCount; ++i) {
77  if (chunk->lines[i].startOffset > offset) break;
78  line = chunk->lines[i].line;
79  }
80  return line;
81 }
82 
Structures and enums for bytecode chunks.
Functions for dealing with garbage collection and memory allocation.
Opcode chunk of a code object.
Definition: chunk.h:36
void krk_initChunk(KrkChunk *chunk)
Initialize an opcode chunk.
Definition: chunk.c:7
void krk_freeChunk(KrkChunk *chunk)
Release the resources allocated to an opcode chunk.
Definition: chunk.c:42
void krk_emitConstant(KrkChunk *chunk, size_t ind, size_t line)
Write an OP_CONSTANT(_LONG) instruction.
Definition: chunk.c:56
size_t krk_writeConstant(KrkChunk *chunk, KrkValue value, size_t line)
Add a new constant and write an instruction for it.
Definition: chunk.c:68
size_t krk_lineNumber(KrkChunk *chunk, size_t offset)
Obtain the line number for a byte offset into a bytecode chunk.
Definition: chunk.c:74
size_t krk_addConstant(KrkChunk *chunk, KrkValue value)
Add a new constant value to an opcode chunk.
Definition: chunk.c:49
void krk_writeChunk(KrkChunk *chunk, uint8_t byte, size_t line)
Append a byte to an opcode chunk.
Definition: chunk.c:30
Map entry of instruction offsets to line numbers.
Definition: chunk.h:19
void krk_initValueArray(KrkValueArray *array)
Initialize a value array.
Definition: value.c:11
void krk_freeValueArray(KrkValueArray *array)
Release relesources used by a value array.
Definition: value.c:28
void krk_writeValueArray(KrkValueArray *array, KrkValue value)
Add a value to a value array.
Definition: value.c:17
size_t count
Definition: value.h:72
Stack reference or primative value.
Core API for the bytecode virtual machine.
KrkValue krk_pop(void)
Pop the top of the stack.
Definition: vm.c:170
void krk_push(KrkValue value)
Push a stack value.
Definition: vm.c:157