Skip to content

Commit 09c43b7

Browse files
authored
Update vm.c
1 parent a892f72 commit 09c43b7

File tree

1 file changed

+83
-7
lines changed

1 file changed

+83
-7
lines changed

vm.c

Lines changed: 83 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1+
#include "vm.h"
12
#include "bloat.h"
3+
#include "chunk.h"
24
#include "value.h"
3-
#include "vm.h"
5+
#include "object.h"
6+
7+
#include <stdio.h>
8+
#include <stdarg.h>
9+
#include <string.h>
410

511
static InterpretResult run(VM* vm) {
612
#define READ_BYTE() (*vm->ip++)
@@ -115,18 +121,88 @@ bool values_equal(Value a, Value b) {
115121
switch (a.type) {
116122
case VAL_NIL: return true;
117123
case VAL_BOOL: return AS_BOOL(a) == AS_BOOL(b);
118-
case VAL_INT: return AS_INT(a) == AS_INT(b);
119-
case VAL_FLOAT: return AS_FLOAT(a) == AS_FLOAT(b);
120-
case VAL_STRING: return strcmp(AS_STRING(a), AS_STRING(b)) == 0;
124+
case VAL_NUMBER: return AS_NUMBER(a) == AS_NUMBER(b);
121125
case VAL_OBJ: return AS_OBJ(a) == AS_OBJ(b);
122126
default: return false;
123127
}
124128
}
125129

126130
Value peek(int offset) {
127131
VM* vm;
128-
if ((intptr_t) (vm->stack_top - offset - 1) < 0) {
129-
printf("Stack underflow!");
132+
if ((intptr_t)(vm->stack_top - offset - 1) < 0) {
133+
runtime_error("Stack underflow!");
134+
return NIL_VAL;
135+
}
136+
return vm->stack[(int)(vm->stack_top - offset - 1)];
137+
}
138+
139+
void* reallocate(void* pointer, size_t oldSize, size_t newSize) {
140+
vm->bytes_allocated += newSize - oldSize;
141+
142+
if (newSize > oldSize) {
143+
if (vm->bytes_allocated > vm->next_gc) {
144+
collect_garbage(vm);
145+
}
146+
}
147+
148+
if (newSize == 0) {
149+
free(pointer);
150+
return NULL;
151+
}
152+
153+
void* result = realloc(pointer, newSize);
154+
if (result == NULL) exit(1);
155+
return result;
156+
}
157+
158+
void collect_garbage(VM* vm) {
159+
for (Value* slot = vm->stack; slot < vm->stack_top; slot++) {
160+
mark_value(vm, *slot);
161+
}
162+
163+
Object** object = &vm->objects;
164+
while (*object != NULL) {
165+
if (!(*object)->is_marked) {
166+
Object* unreached = *object;
167+
*object = unreached->next;
168+
free_object(unreached);
169+
} else {
170+
(*object)->is_marked = false;
171+
object = &(*object)->next;
172+
}
173+
}
174+
175+
vm->next_gc = vm->bytes_allocated * 2;
176+
}
177+
178+
void mark_object(VM* vm, Object* object) {
179+
if (object == NULL) return;
180+
if (object->is_marked) return;
181+
182+
object->is_marked = true;
183+
// If the object contains references to other objects,
184+
// they should be marked here
185+
}
186+
187+
void mark_value(VM* vm, Value value) {
188+
if (IS_OBJ(value)) {
189+
mark_object(vm, AS_OBJ(value));
190+
}
191+
}
192+
193+
void runtime_error(const char* format, ...) {
194+
va_list args;
195+
va_start(args, format);
196+
vfprintf(stderr, format, args);
197+
va_end(args);
198+
fputs("\n", stderr);
199+
}
200+
201+
void free_objects(VM* vm) {
202+
Object* object = vm->objects;
203+
while (object != NULL) {
204+
Object* next = object->next;
205+
free_object(object);
206+
object = next;
130207
}
131-
return vm->stack[(int) (vm->stack_top - offset - 1)];
132208
}

0 commit comments

Comments
 (0)