.
This commit is contained in:
9
Makefile
9
Makefile
@@ -75,18 +75,11 @@ uninstall:
|
|||||||
|
|
||||||
.PHONY: all check clean install uninstall
|
.PHONY: all check clean install uninstall
|
||||||
|
|
||||||
#
|
|
||||||
# intermediate rules
|
|
||||||
#
|
|
||||||
|
|
||||||
%.o: %.c
|
|
||||||
$(CC) $(CFLAGS) -c -o $@ $^
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# executable files
|
# executable files
|
||||||
#
|
#
|
||||||
|
|
||||||
LIB_SRC=lib/value.o lib/stack.o lib/heap.o lib/vm.o
|
LIB_SRC=lib/value.o lib/stack.o lib/heap.o lib/vm.o lib/utils.o
|
||||||
|
|
||||||
tyche: CFLAGS += ${RELEASE_CFLAGS}
|
tyche: CFLAGS += ${RELEASE_CFLAGS}
|
||||||
tyche: LDFLAGS += ${RELEASE_LDFLAGS}
|
tyche: LDFLAGS += ${RELEASE_LDFLAGS}
|
||||||
|
|||||||
17
lib/heap.c
17
lib/heap.c
@@ -16,15 +16,20 @@ typedef struct {
|
|||||||
// TODO - array and table
|
// TODO - array and table
|
||||||
} value;
|
} value;
|
||||||
} HeapValue;
|
} HeapValue;
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wconversion"
|
||||||
KHASH_MAP_INIT_INT64(HEAP, HeapValue)
|
KHASH_MAP_INIT_INT64(HEAP, HeapValue)
|
||||||
|
KHASH_MAP_INIT_INT64(MARK, bool)
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
struct Heap {
|
struct Heap {
|
||||||
khash_t(HEAP) *items;
|
khash_t(HEAP) *items;
|
||||||
};
|
};
|
||||||
|
|
||||||
Heap* heap_new()
|
Heap* heap_new(void)
|
||||||
{
|
{
|
||||||
Heap* h = calloc(1, sizeof(Heap));
|
Heap* h = xcalloc(1, sizeof(Heap));
|
||||||
h->items = kh_init(HEAP);
|
h->items = kh_init(HEAP);
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
@@ -65,7 +70,7 @@ HEAP_KEY heap_add_string(Heap* h, const char* value)
|
|||||||
HEAP_KEY key;
|
HEAP_KEY key;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
key = rand();
|
key = (HEAP_KEY) rand();
|
||||||
k = kh_get(HEAP, h->items, key);
|
k = kh_get(HEAP, h->items, key);
|
||||||
} while (k != kh_end(h->items));
|
} while (k != kh_end(h->items));
|
||||||
|
|
||||||
@@ -97,8 +102,6 @@ size_t heap_size(Heap* h)
|
|||||||
// GC
|
// GC
|
||||||
//
|
//
|
||||||
|
|
||||||
KHASH_MAP_INIT_INT64(MARK, bool)
|
|
||||||
|
|
||||||
void heap_gc(Heap* h, VALUE const* roots, size_t n_roots)
|
void heap_gc(Heap* h, VALUE const* roots, size_t n_roots)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@@ -112,6 +115,8 @@ void heap_gc(Heap* h, VALUE const* roots, size_t n_roots)
|
|||||||
int ret;
|
int ret;
|
||||||
uint32_t key = value_idx(roots[i]);
|
uint32_t key = value_idx(roots[i]);
|
||||||
khiter_t k = kh_put(MARK, marked, key, &ret);
|
khiter_t k = kh_put(MARK, marked, key, &ret);
|
||||||
|
if (ret < 0)
|
||||||
|
out_of_memory();
|
||||||
kh_value(marked, k) = true;
|
kh_value(marked, k) = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,7 +127,7 @@ void heap_gc(Heap* h, VALUE const* roots, size_t n_roots)
|
|||||||
|
|
||||||
for (khiter_t k = kh_begin(h->items); k != kh_end(h->items); ++k) {
|
for (khiter_t k = kh_begin(h->items); k != kh_end(h->items); ++k) {
|
||||||
if (kh_exist(h->items, k)) {
|
if (kh_exist(h->items, k)) {
|
||||||
HEAP_KEY key = kh_key(h->items, k);
|
HEAP_KEY key = (HEAP_KEY) kh_key(h->items, k);
|
||||||
if (kh_get(MARK, marked, key) == kh_end(marked)) {
|
if (kh_get(MARK, marked, key) == kh_end(marked)) {
|
||||||
khiter_t kk = kh_get(HEAP, h->items, key);
|
khiter_t kk = kh_get(HEAP, h->items, key);
|
||||||
heap_free_item(kh_value(h->items, kk));
|
heap_free_item(kh_value(h->items, kk));
|
||||||
|
|||||||
17
lib/priv.h
17
lib/priv.h
@@ -7,6 +7,15 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// UTILS
|
||||||
|
//
|
||||||
|
|
||||||
|
__attribute__((noreturn)) void out_of_memory(void);
|
||||||
|
void* xmalloc(size_t n);
|
||||||
|
void* xcalloc(size_t n, size_t size);
|
||||||
|
void* xrealloc(void* p, size_t n);
|
||||||
|
|
||||||
//
|
//
|
||||||
// VALUE
|
// VALUE
|
||||||
//
|
//
|
||||||
@@ -26,7 +35,7 @@ float value_real(VALUE v);
|
|||||||
uint32_t value_idx(VALUE v);
|
uint32_t value_idx(VALUE v);
|
||||||
bool value_is_zero(VALUE v);
|
bool value_is_zero(VALUE v);
|
||||||
|
|
||||||
VALUE create_value_nil();
|
VALUE create_value_nil(void);
|
||||||
VALUE create_value_integer(int32_t v);
|
VALUE create_value_integer(int32_t v);
|
||||||
VALUE create_value_real(float f);
|
VALUE create_value_real(float f);
|
||||||
VALUE create_value_idx(TYC_TYPE type, uint32_t idx);
|
VALUE create_value_idx(TYC_TYPE type, uint32_t idx);
|
||||||
@@ -37,7 +46,7 @@ VALUE create_value_idx(TYC_TYPE type, uint32_t idx);
|
|||||||
|
|
||||||
typedef struct Stack Stack;
|
typedef struct Stack Stack;
|
||||||
|
|
||||||
Stack* stack_new();
|
Stack* stack_new(void);
|
||||||
void stack_destroy(Stack* s);
|
void stack_destroy(Stack* s);
|
||||||
|
|
||||||
TYC_RESULT stack_push(Stack* s, VALUE v);
|
TYC_RESULT stack_push(Stack* s, VALUE v);
|
||||||
@@ -60,9 +69,9 @@ size_t stack_fp_level(Stack* s);
|
|||||||
|
|
||||||
typedef struct Heap Heap;
|
typedef struct Heap Heap;
|
||||||
|
|
||||||
typedef int HEAP_KEY;
|
typedef uint32_t HEAP_KEY;
|
||||||
|
|
||||||
Heap* heap_new();
|
Heap* heap_new(void);
|
||||||
void heap_destroy(Heap* h);
|
void heap_destroy(Heap* h);
|
||||||
|
|
||||||
HEAP_KEY heap_add_string(Heap* h, const char* value);
|
HEAP_KEY heap_add_string(Heap* h, const char* value);
|
||||||
|
|||||||
15
lib/stack.c
15
lib/stack.c
@@ -12,15 +12,16 @@ struct Stack {
|
|||||||
size_t fp_cap;
|
size_t fp_cap;
|
||||||
};
|
};
|
||||||
|
|
||||||
Stack* stack_new()
|
Stack* stack_new(void)
|
||||||
{
|
{
|
||||||
Stack* s = calloc(1, sizeof(Stack));
|
Stack* s = xcalloc(1, sizeof(Stack));
|
||||||
|
|
||||||
s->stack_n = s->fp_n = 0;
|
s->stack_n = 0;
|
||||||
|
s->fp_n = 0;
|
||||||
s->stack_cap = 64;
|
s->stack_cap = 64;
|
||||||
s->fp_cap = 8;
|
s->fp_cap = 8;
|
||||||
s->stack = malloc(s->stack_cap * sizeof s->stack[0]);
|
s->stack = xmalloc(s->stack_cap * sizeof s->stack[0]);
|
||||||
s->fp = malloc(s->stack_cap * sizeof s->fp[0]);
|
s->fp = xmalloc(s->stack_cap * sizeof s->fp[0]);
|
||||||
|
|
||||||
assert(s->stack);
|
assert(s->stack);
|
||||||
assert(s->fp);
|
assert(s->fp);
|
||||||
@@ -41,7 +42,7 @@ TYC_RESULT stack_push(Stack* s, VALUE v)
|
|||||||
{
|
{
|
||||||
if (s->stack_n == s->stack_cap) {
|
if (s->stack_n == s->stack_cap) {
|
||||||
s->stack_cap *= 2;
|
s->stack_cap *= 2;
|
||||||
s->stack = realloc(s->stack, s->stack_cap * sizeof s->stack[0]);
|
s->stack = xrealloc(s->stack, s->stack_cap * sizeof s->stack[0]);
|
||||||
assert(s->stack);
|
assert(s->stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,7 +113,7 @@ TYC_RESULT stack_push_fp(Stack* s)
|
|||||||
{
|
{
|
||||||
if (s->fp_n == s->fp_cap) {
|
if (s->fp_n == s->fp_cap) {
|
||||||
s->fp_cap *= 2;
|
s->fp_cap *= 2;
|
||||||
s->fp = realloc(s->fp, s->fp_cap * sizeof s->fp[0]);
|
s->fp = xrealloc(s->fp, s->fp_cap * sizeof s->fp[0]);
|
||||||
assert(s->fp);
|
assert(s->fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
31
lib/utils.c
Normal file
31
lib/utils.c
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#include "priv.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
__attribute__((noreturn)) void out_of_memory(void)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "out of memory\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
void* xmalloc(size_t n)
|
||||||
|
{
|
||||||
|
void* p = malloc(n);
|
||||||
|
if (!p) out_of_memory();
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* xcalloc(size_t n, size_t size)
|
||||||
|
{
|
||||||
|
void* p = calloc(n, size);
|
||||||
|
if (!p) out_of_memory();
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* xrealloc(void* p, size_t n)
|
||||||
|
{
|
||||||
|
void* q = realloc(p, n);
|
||||||
|
if (!q) out_of_memory();
|
||||||
|
return q;
|
||||||
|
}
|
||||||
@@ -36,7 +36,7 @@ uint32_t value_idx(VALUE v)
|
|||||||
return v.v.idx;
|
return v.v.idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE create_value_nil()
|
VALUE create_value_nil(void)
|
||||||
{
|
{
|
||||||
return (VALUE) { .type = TT_NIL };
|
return (VALUE) { .type = TT_NIL };
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user