diff options
Diffstat (limited to 'bytecode')
| -rw-r--r-- | bytecode/byte_slice.h | 10 | ||||
| -rw-r--r-- | bytecode/bytecode.c | 14 | ||||
| -rw-r--r-- | bytecode/encoding.c | 8 | ||||
| -rw-r--r-- | bytecode/encoding.h | 4 | ||||
| -rw-r--r-- | bytecode/heap.c | 43 | ||||
| -rw-r--r-- | bytecode/heap.h | 10 | ||||
| -rw-r--r-- | bytecode/oper.c | 9 | ||||
| -rw-r--r-- | bytecode/oper.h | 4 | ||||
| -rw-r--r-- | bytecode/slice.h | 46 | ||||
| -rw-r--r-- | bytecode/value_slice.h | 9 |
10 files changed, 97 insertions, 60 deletions
diff --git a/bytecode/byte_slice.h b/bytecode/byte_slice.h new file mode 100644 index 0000000..7109b52 --- /dev/null +++ b/bytecode/byte_slice.h @@ -0,0 +1,10 @@ +#ifndef _BYTE_SLICE_H_ +#define _BYTE_SLICE_H_ + +#include <stdint.h> + +#include "slice.h" + +DEFINE_SLICE(uint8_t) + +#endif diff --git a/bytecode/bytecode.c b/bytecode/bytecode.c index 1d0f957..9ac4a1e 100644 --- a/bytecode/bytecode.c +++ b/bytecode/bytecode.c @@ -4,27 +4,27 @@ #include "oper.h" #include "panic.h" -#include "slice.h" +#include "byte_slice.h" -static struct slice xrealloc(void *ptr, size_t size) +static uint8_t_slice xrealloc(void *ptr, size_t size) { void *p = realloc(ptr, size); if (!p) { panicf("Out of memory!\n"); } - return (struct slice) { + return (uint8_t_slice) { .buf = p, .size = size, }; } -struct slice read_file(char *filename) +static uint8_t_slice read_file(char *filename) { FILE *f = fopen(filename, "r"); if (!f) { panicf("File %s does not exit!\n", filename); } - struct slice out = { .size = 0, .buf = NULL }; + uint8_t_slice out = { .size = 0, .buf = NULL }; size_t offset = 0; while (true) { if (offset >= out.size) { @@ -37,7 +37,7 @@ struct slice read_file(char *filename) if (ferror(f)) { panicf("Read error!\n"); } - return slice(out, 0, offset + n); + return uint8_t_slice2(out, 0, offset + n); } offset += n; } @@ -50,7 +50,7 @@ int main(int argc, char **argv) return 1; } - struct slice program = read_file(argv[1]); + uint8_t_slice program = read_file(argv[1]); run(program); diff --git a/bytecode/encoding.c b/bytecode/encoding.c index 520b6c3..246e944 100644 --- a/bytecode/encoding.c +++ b/bytecode/encoding.c @@ -2,19 +2,19 @@ #include <stdlib.h> #include "panic.h" -#include "slice.h" +#include "byte_slice.h" #include "value.h" #include "encoding.h" struct reader { - struct slice data; + uint8_t_slice data; int n; }; static void advance(struct reader *r, int size) { - r->data = slice1(r->data, size); + r->data = uint8_t_slice1(r->data, size); r->n += size; } @@ -69,7 +69,7 @@ static uint8_t parse_offset(struct reader *r) return res; } -struct result parse(struct slice data) +struct result parse(uint8_t_slice data) { struct reader r = { .data = data, .n = 0 }; diff --git a/bytecode/encoding.h b/bytecode/encoding.h index fed187b..9d4da14 100644 --- a/bytecode/encoding.h +++ b/bytecode/encoding.h @@ -4,7 +4,7 @@ #include <stdbool.h> #include <stdint.h> -#include "slice.h" +#include "byte_slice.h" #include "value.h" typedef uint8_t local; @@ -58,6 +58,6 @@ struct result { int n; }; -struct result parse(struct slice); +struct result parse(uint8_t_slice); #endif diff --git a/bytecode/heap.c b/bytecode/heap.c index 863bf0c..1ba5faf 100644 --- a/bytecode/heap.c +++ b/bytecode/heap.c @@ -6,8 +6,9 @@ #include "heap.h" #include "panic.h" #include "value.h" +#include "value_slice.h" -struct heap new_heap(struct val_slice gc_roots) +struct heap new_heap(value_slice gc_roots) { return (struct heap) { .buf = NULL, @@ -56,14 +57,16 @@ static value process_gc_value(struct heap *h, value val) // Allocate space in the new buffer. value *q = simple_alloc(h, size); + // Write forwarding pointer. + value first_value = p[0]; + p[0] = from_pointer(q); + // Copy values, recursively modifying pointers. - for (size_t i = 0; i < size; i++) { + q[0] = process_gc_value(h, first_value); + for (size_t i = 1; i < size; i++) { q[i] = process_gc_value(h, p[i]); } - // Write forwarding pointer. - p[0] = from_pointer(q); - return from_pointer(q); } @@ -74,7 +77,7 @@ static void collect_garbage(struct heap *h) } // Swap the heaps. - struct val_slice temp = h->active; + value_slice temp = h->active; h->active = h->standby; h->standby = temp; @@ -85,19 +88,25 @@ static void collect_garbage(struct heap *h) } } -static void more_space(struct heap *h, int64_t size_hint) +static value_slice xcalloc(size_t size) { - size_t new_size = h->active.size * 2 + size_hint; - value *new_buf = calloc(2 * new_size, sizeof(value)); - if (!new_buf) { + value *p = calloc(size, sizeof(value)); + if (!p) { panicf("Out of memory!\n"); } - memcpy(new_buf, h->active.buf, h->active.size * sizeof(value)); - free(h->buf); + return (value_slice) { .size = size, .buf = p }; +} + +static void more_space(struct heap *h, int64_t size_hint) +{ + size_t new_size = h->active.size * 2 + size_hint; + value_slice new_buf = xcalloc(2 * new_size); + memcpy(new_buf.buf, h->active.buf, h->active.size * sizeof(value)); - h->buf = new_buf; - h->active = (struct val_slice) { .size = new_size, .buf = new_buf }; - h->standby = (struct val_slice) { .size = new_size, .buf = new_buf + new_size }; + free(h->buf); + h->buf = new_buf.buf; + h->active = value_slice2(new_buf, 0, new_size); + h->standby = value_slice1(new_buf, new_size); } value *alloc(struct heap *h, int64_t size) @@ -110,5 +119,7 @@ value *alloc(struct heap *h, int64_t size) if (h->free_ptr + size >= h->active.size) { more_space(h, size); } - return simple_alloc(h, size); + value *p = simple_alloc(h, size); + memset(p, 0, size * sizeof(value)); + return p; } diff --git a/bytecode/heap.h b/bytecode/heap.h index c8d7e2c..c6c10c4 100644 --- a/bytecode/heap.h +++ b/bytecode/heap.h @@ -4,24 +4,24 @@ #include <stddef.h> #include <stdint.h> -#include "slice.h" #include "value.h" +#include "value_slice.h" struct heap { // The heap is divided into two halves for garbage collection. // buf holds the malloc'd heap buffer. value *buf; // active and standby are slices that partition buf. - struct val_slice active; - struct val_slice standby; + value_slice active; + value_slice standby; size_t free_ptr; size_t last_free; - struct val_slice gc_roots; + value_slice gc_roots; }; -struct heap new_heap(struct val_slice); +struct heap new_heap(value_slice); value *alloc(struct heap *, int64_t); #endif diff --git a/bytecode/oper.c b/bytecode/oper.c index fcb7d77..0bdb8f6 100644 --- a/bytecode/oper.c +++ b/bytecode/oper.c @@ -1,11 +1,12 @@ #include <stdbool.h> #include <stdlib.h> +#include "byte_slice.h" #include "encoding.h" #include "heap.h" #include "panic.h" -#include "slice.h" #include "value.h" +#include "value_slice.h" #include "oper.h" @@ -81,15 +82,15 @@ static void op(struct st *s, struct op oper) } } -void run(struct slice prog) +void run(uint8_t_slice prog) { struct st s = { .i = 0, .locals = { 0 }, }; - s.heap = new_heap((struct val_slice) { .size = NUM_LOCALS, .buf = s.locals }); + s.heap = new_heap((value_slice) { .size = NUM_LOCALS, .buf = s.locals }); while (true) { - struct result oper = parse(slice1(prog, s.i)); + struct result oper = parse(uint8_t_slice1(prog, s.i)); s.i += oper.n; op(&s, oper.op); } diff --git a/bytecode/oper.h b/bytecode/oper.h index f3bb688..7174e1d 100644 --- a/bytecode/oper.h +++ b/bytecode/oper.h @@ -1,8 +1,8 @@ #ifndef _OPER_H_ #define _OPER_H_ -#include "slice.h" +#include "byte_slice.h" -void run(struct slice); +void run(uint8_t_slice); #endif diff --git a/bytecode/slice.h b/bytecode/slice.h index 577befd..4f4624c 100644 --- a/bytecode/slice.h +++ b/bytecode/slice.h @@ -1,27 +1,33 @@ #ifndef _SLICE_H_ #define _SLICE_H_ +#include <assert.h> #include <stddef.h> -#include <stdint.h> -#include "value.h" - -struct slice { - size_t size; - uint8_t *buf; -}; - -struct val_slice { - size_t size; - value *buf; -}; - -struct slice slice(struct slice, size_t, size_t); - -struct slice slice1(struct slice, size_t); - -struct val_slice val_slice(struct val_slice, size_t, size_t); - -struct val_slice val_slice1(struct val_slice, size_t); +#define DEFINE_SLICE(t) \ + typedef struct { \ + size_t size; \ + t *buf; \ + } t##_slice; \ + \ + static inline t##_slice \ + t##_slice2(t##_slice slice, size_t i, size_t j) \ + { \ + assert(i <= slice.size && j <= slice.size && i <= j); \ + return (t##_slice) { \ + .size = j - i, \ + .buf = slice.buf + i, \ + }; \ + } \ + \ + static inline t##_slice \ + t##_slice1(t##_slice slice, size_t i) \ + { \ + assert(i <= slice.size); \ + return (t##_slice) { \ + .size = slice.size - i, \ + .buf = slice.buf + i, \ + }; \ + } #endif diff --git a/bytecode/value_slice.h b/bytecode/value_slice.h new file mode 100644 index 0000000..09b2873 --- /dev/null +++ b/bytecode/value_slice.h @@ -0,0 +1,9 @@ +#ifndef _VALUE_SLICE_H_ +#define _VALUE_SLICE_H_ + +#include "slice.h" +#include "value.h" + +DEFINE_SLICE(value) + +#endif |
