diff options
Diffstat (limited to 'lib/fwd.h')
-rw-r--r-- | lib/fwd.h | 66 |
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 */ |