summaryrefslogtreecommitdiffstats
path: root/bytecode
diff options
context:
space:
mode:
authorRose Hogenson <rhogenson@posteo.net>2023-02-11 21:31:04 -0800
committerRose Hogenson <rhogenson@posteo.net>2023-02-11 21:31:04 -0800
commit5989629a7951e544ad4656672025a99ecd08c7c9 (patch)
tree89e2ca80f73d8dcf16a9fadcea41b2e141bdf4eb /bytecode
parentaafc502de6f9ecbeb4638b1862f4fa5ac82199d7 (diff)
downloadsml-5989629a7951e544ad4656672025a99ecd08c7c9.tar.zst
Change how slices work.
I'm switching to a more macro-heavy solution. Hopefully it proves robust.
Diffstat (limited to 'bytecode')
-rw-r--r--bytecode/byte_slice.h10
-rw-r--r--bytecode/bytecode.c14
-rw-r--r--bytecode/encoding.c8
-rw-r--r--bytecode/encoding.h4
-rw-r--r--bytecode/heap.c43
-rw-r--r--bytecode/heap.h10
-rw-r--r--bytecode/oper.c9
-rw-r--r--bytecode/oper.h4
-rw-r--r--bytecode/slice.h46
-rw-r--r--bytecode/value_slice.h9
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