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 
17  krk_initValueArray(&chunk->constants);
18 }
19 
20 static void addLine(KrkChunk * chunk, size_t line) {
21  if (chunk->linesCount && chunk->lines[chunk->linesCount-1].line == line) return;
22  if (chunk->linesCapacity < chunk->linesCount + 1) {
23  int old = chunk->linesCapacity;
24  chunk->linesCapacity = KRK_GROW_CAPACITY(old);
25  chunk->lines = KRK_GROW_ARRAY(KrkLineMap, chunk->lines, old, chunk->linesCapacity);
26  }
27  chunk->lines[chunk->linesCount] = (KrkLineMap){chunk->count, line};
28  chunk->linesCount++;
29 }
30 
31 void krk_writeChunk(KrkChunk * chunk, uint8_t byte, size_t line) {
32  if (chunk->capacity < chunk->count + 1) {
33  int old = chunk->capacity;
34  chunk->capacity = KRK_GROW_CAPACITY(old);
35  chunk->code = KRK_GROW_ARRAY(uint8_t, chunk->code, old, chunk->capacity);
36  }
37 
38  chunk->code[chunk->count] = byte;
39  addLine(chunk, line);
40  chunk->count++;
41 }
42 
43 void krk_freeChunk(KrkChunk * chunk) {
44  KRK_FREE_ARRAY(uint8_t, chunk->code, chunk->capacity);
45  KRK_FREE_ARRAY(KrkLineMap, chunk->lines, chunk->linesCapacity);
46  krk_freeValueArray(&chunk->constants);
47  krk_initChunk(chunk);
48 }
49 
50 size_t krk_addConstant(KrkChunk * chunk, KrkValue value) {
51  krk_push(value);
52  krk_writeValueArray(&chunk->constants, value);
53  krk_pop();
54  return chunk->constants.count - 1;
55 }
56 
57 void krk_emitConstant(KrkChunk * chunk, size_t ind, size_t line) {
58  if (ind >= 256) {
59  krk_writeChunk(chunk, OP_CONSTANT_LONG, line);
60  krk_writeChunk(chunk, 0xFF & (ind >> 16), line);
61  krk_writeChunk(chunk, 0xFF & (ind >> 8), line);
62  krk_writeChunk(chunk, 0xFF & (ind >> 0), line);
63  } else {
64  krk_writeChunk(chunk, OP_CONSTANT, line);
65  krk_writeChunk(chunk, ind, line);
66  }
67 }
68 
69 size_t krk_writeConstant(KrkChunk * chunk, KrkValue value, size_t line) {
70  size_t ind = krk_addConstant(chunk, value);
71  krk_emitConstant(chunk, ind, line);
72  return ind;
73 }
74 
75 size_t krk_lineNumber(KrkChunk * chunk, size_t offset) {
76 
77  size_t lo = 0;
78  size_t hi = chunk->linesCount;
79 
80  while (lo != hi) {
81  if (hi - lo < 10) {
82  size_t line = 0;
83  for (size_t i = lo; i < hi; ++i) {
84  if (chunk->lines[i].startOffset > offset) break;
85  line = chunk->lines[i].line;
86  }
87  return line;
88  }
89 
90  size_t mp = lo + (hi - lo) / 2;
91 
92  if (chunk->lines[mp].startOffset > offset) {
93  hi = mp;
94  } else {
95  lo = mp;
96  }
97  }
98 
99  return 0;
100 }
101 
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:43
void krk_emitConstant(KrkChunk *chunk, size_t ind, size_t line)
Write an OP_CONSTANT(_LONG) instruction.
Definition: chunk.c:57
size_t krk_writeConstant(KrkChunk *chunk, KrkValue value, size_t line)
Add a new constant and write an instruction for it.
Definition: chunk.c:69
size_t krk_lineNumber(KrkChunk *chunk, size_t offset)
Obtain the line number for a byte offset into a bytecode chunk.
Definition: chunk.c:75
size_t krk_addConstant(KrkChunk *chunk, KrkValue value)
Add a new constant value to an opcode chunk.
Definition: chunk.c:50
void krk_writeChunk(KrkChunk *chunk, uint8_t byte, size_t line)
Append a byte to an opcode chunk.
Definition: chunk.c:31
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:77
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:131
void krk_push(KrkValue value)
Push a stack value.
Definition: vm.c:118