aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/fwd.h66
1 files changed, 66 insertions, 0 deletions
diff --git a/lib/fwd.h b/lib/fwd.h
new file mode 100644
index 0000000..54d75a2
--- /dev/null
+++ b/lib/fwd.h
@@ -0,0 +1,66 @@
+#ifndef FWD_H
+#define FWD_H
+
+#include <fwd/mod.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#ifndef FWD_FRAME_SIZE
+#error "no frame size defined, internal compiler error"
+#endif
+
+/* should probably add some compiler checks but good enough for now */
+#define FWD_MUSTTAIL [[clang::musttail]]
+
+typedef void *fwd_stack_t;
+typedef void *fwd_args_t;
+typedef fwd_stack_t (*fwd_call_t)(fwd_stack_t, fwd_args_t);
+
+typedef struct {
+ fwd_call_t call;
+ fwd_args_t args;
+} fwd_closure_t;
+
+typedef struct {} fwd_start_t;
+
+static inline fwd_stack_t create_fwd_stack()
+{
+ return NULL;
+}
+
+static inline void *fwd_stack_alloc(fwd_stack_t *top)
+{
+ if (*top) {
+ fwd_stack_t *prev = *top;
+ *top = *prev;
+ return prev + 1;
+ }
+
+ fwd_stack_t *new = malloc(FWD_FRAME_SIZE + sizeof(fwd_stack_t));
+ *new = NULL;
+ return new + 1;
+}
+
+static inline void fwd_stack_free(fwd_stack_t *stack, void *loc)
+{
+ fwd_stack_t *freed = (fwd_stack_t *)loc - 1;
+ *freed = *stack;
+ *stack = freed;
+}
+
+static inline void destroy_fwd_stack(fwd_stack_t *stack)
+{
+ fwd_stack_t *prev = *stack;
+ while (prev) {
+ fwd_stack_t *cur = prev;
+ prev = *cur;
+ free(cur);
+ }
+}
+
+#define FWD_CONTAINER_OF(ptr, type, member) \
+ (type *)((char *)(ptr) - offsetof(type, member))
+
+#endif /* FWD_H */