From a01ee103f9bc0c6defe9ce8cd85651f19f7127bd Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 11 Feb 2024 21:29:15 +0000 Subject: Create separate lib for patio runtime --- runtime/meson.build | 20 +++-- runtime/src/alloc.c | 6 -- runtime/src/alloc.h | 19 ---- runtime/src/closures.h | 19 ---- runtime/src/effects.c | 51 ----------- runtime/src/effects.h | 9 -- runtime/src/gc.c | 132 ---------------------------- runtime/src/gc.h | 23 ----- runtime/src/ints.c | 46 ---------- runtime/src/namespaces/Shed/Builtins.c | 59 ------------- runtime/src/primitives.c | 3 - runtime/src/primitives.h | 10 --- runtime/src/shed.h | 8 -- runtime/src/shed/alloc.c | 6 ++ runtime/src/shed/alloc.h | 19 ++++ runtime/src/shed/closures.h | 19 ++++ runtime/src/shed/effects.c | 51 +++++++++++ runtime/src/shed/effects.h | 9 ++ runtime/src/shed/gc.c | 132 ++++++++++++++++++++++++++++ runtime/src/shed/gc.h | 23 +++++ runtime/src/shed/ints.c | 46 ++++++++++ runtime/src/shed/namespaces/Shed/Builtins.c | 59 +++++++++++++ runtime/src/shed/primitives.c | 3 + runtime/src/shed/primitives.h | 10 +++ runtime/src/shed/shed.h | 8 ++ runtime/src/shed/std/unistd.h | 14 +++ runtime/src/shed/strings.c | 22 +++++ runtime/src/shed/strings.h | 19 ++++ runtime/src/std/unistd.h | 14 --- runtime/src/strings.c | 22 ----- runtime/src/strings.h | 19 ---- 31 files changed, 452 insertions(+), 448 deletions(-) delete mode 100644 runtime/src/alloc.c delete mode 100644 runtime/src/alloc.h delete mode 100644 runtime/src/closures.h delete mode 100644 runtime/src/effects.c delete mode 100644 runtime/src/effects.h delete mode 100644 runtime/src/gc.c delete mode 100644 runtime/src/gc.h delete mode 100644 runtime/src/ints.c delete mode 100644 runtime/src/namespaces/Shed/Builtins.c delete mode 100644 runtime/src/primitives.c delete mode 100644 runtime/src/primitives.h delete mode 100644 runtime/src/shed.h create mode 100644 runtime/src/shed/alloc.c create mode 100644 runtime/src/shed/alloc.h create mode 100644 runtime/src/shed/closures.h create mode 100644 runtime/src/shed/effects.c create mode 100644 runtime/src/shed/effects.h create mode 100644 runtime/src/shed/gc.c create mode 100644 runtime/src/shed/gc.h create mode 100644 runtime/src/shed/ints.c create mode 100644 runtime/src/shed/namespaces/Shed/Builtins.c create mode 100644 runtime/src/shed/primitives.c create mode 100644 runtime/src/shed/primitives.h create mode 100644 runtime/src/shed/shed.h create mode 100644 runtime/src/shed/std/unistd.h create mode 100644 runtime/src/shed/strings.c create mode 100644 runtime/src/shed/strings.h delete mode 100644 runtime/src/std/unistd.h delete mode 100644 runtime/src/strings.c delete mode 100644 runtime/src/strings.h (limited to 'runtime') diff --git a/runtime/meson.build b/runtime/meson.build index 569d2d92..2acb806a 100644 --- a/runtime/meson.build +++ b/runtime/meson.build @@ -1,15 +1,19 @@ project('shed-runtime', 'c', default_options : ['warning_level=1']) static_library( - 'shed', + 'patio', 'src/patio/exceptions.c', - 'src/alloc.c', - 'src/effects.c', - 'src/gc.c', - 'src/ints.c', - 'src/primitives.c', - 'src/strings.c', - 'src/namespaces/Shed/Builtins.c', +) + +static_library( + 'shed', + 'src/shed/alloc.c', + 'src/shed/effects.c', + 'src/shed/gc.c', + 'src/shed/ints.c', + 'src/shed/primitives.c', + 'src/shed/strings.c', + 'src/shed/namespaces/Shed/Builtins.c', ) if meson.get_external_property('shed_runtime_is_wasm', false) diff --git a/runtime/src/alloc.c b/runtime/src/alloc.c deleted file mode 100644 index f68fb128..00000000 --- a/runtime/src/alloc.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "./std/unistd.h" -#include "./alloc.h" - -void* shed__runtime__alloc(size_t size) { - return malloc(size); -} diff --git a/runtime/src/alloc.h b/runtime/src/alloc.h deleted file mode 100644 index 07a14436..00000000 --- a/runtime/src/alloc.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef SHED_ALLOC_H -#define SHED_ALLOC_H - -#include "./std/unistd.h" - -#ifdef __wasm__ - -void* malloc(unsigned long); -void free(void*); - -#else - -#include - -#endif - -void* shed__runtime__alloc(size_t size); - -#endif diff --git a/runtime/src/closures.h b/runtime/src/closures.h deleted file mode 100644 index e32244ea..00000000 --- a/runtime/src/closures.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef SHED_CLOSURES_H -#define SHED_CLOSURES_H - -#include "./gc.h" -#include "./primitives.h" - -struct ShedClosure { - struct ShedGcObjectHeader gc_object_header; - void* function; - ShedObject freeVariables[]; -}; - -typedef struct ShedClosure ShedClosureStruct; - -typedef struct ShedClosure* ShedClosurePointer; - -typedef ShedObject* ShedEnv; - -#endif diff --git a/runtime/src/effects.c b/runtime/src/effects.c deleted file mode 100644 index 39dabe56..00000000 --- a/runtime/src/effects.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include "./std/unistd.h" -#include "./gc.h" -#include "./closures.h" -#include "./effects.h" - -struct ShedEffectHandler { - struct ShedGcObjectHeader gc_object_header; - struct ShedEffectHandler* parent; - ShedClosurePointer methods[]; -}; - -typedef struct ShedEffectHandler ShedEffectHandler; - -struct ShedEffectHandler* shed__runtime__current_effect_handler = NULL; - -ShedEffectHandler* shed__runtime__effects_get_handler() { - return shed__runtime__current_effect_handler; -} - -void shed__runtime__effects_set_handler(ShedEffectHandler* effect_handler) { - shed__runtime__current_effect_handler = effect_handler; -} - -void shed__runtime__effects_push_handler( - ShedEffectHandler* effect_handler -) { - effect_handler->parent = shed__runtime__current_effect_handler; - - shed__runtime__current_effect_handler = effect_handler; -} - -void shed__runtime__effects_pop_handler() { - shed__runtime__current_effect_handler = shed__runtime__current_effect_handler->parent; -} - -ShedClosurePointer shed__runtime__effects_find_handler_method( - ShedEffectTag effect_tag, - ShedEffectMethodIndex method_index -) { - ShedEffectHandler* handler = shed__runtime__current_effect_handler; - while (handler != NULL) { - if (handler->gc_object_header.runtime_type_tag == effect_tag) { - return handler->methods[method_index]; - } - handler = handler->parent; - } - - // TODO: more informative error - return NULL; -} diff --git a/runtime/src/effects.h b/runtime/src/effects.h deleted file mode 100644 index 8f496784..00000000 --- a/runtime/src/effects.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef SHED_EFFECTS_H -#define SHED_EFFECTS_H - -#include "./patio/patio.h" - -typedef PatioInt ShedEffectTag; -typedef PatioInt ShedEffectMethodIndex; - -#endif diff --git a/runtime/src/gc.c b/runtime/src/gc.c deleted file mode 100644 index 12f668cb..00000000 --- a/runtime/src/gc.c +++ /dev/null @@ -1,132 +0,0 @@ -#include - -#include "./patio/patio.h" -#include "./alloc.h" -#include "./gc.h" -#include "./primitives.h" - -// == GC objects == - -bool is_gc_object(ShedObject object) { - // Check that the object is not one of: - // * unit (0) - // * false (0) - // * true (1) - return !(object == 0 || object == 1); -} - -// == Marking == - -// The mark value for each object is initialized to 0. Each mark phase -// alternates between using 0b010 and 0b100 as the mark value. We check only for -// the bit set to 1, meaning static values can have a mark value of 0b110 to be -// considered always marked. -PatioInt current_mark_value = 0b010; - -void alternate_mark_value() { - current_mark_value ^= 0b110; -} - -bool is_marked(struct ShedGcObjectHeader* object) { - return (object->mark & current_mark_value) == current_mark_value; -} - -void mark(struct ShedGcObjectHeader* object) { - if (object == NULL || is_marked(object)) { - return; - } - - object->mark = current_mark_value; - - struct RuntimeType* runtime_type = &shed__rtti[object->runtime_type_tag]; - - struct ShedGcObjectHeader** children = (struct ShedGcObjectHeader**) ( - ((void*) object) + runtime_type->children_offset - ); - - for (size_t child_index = 0; child_index < runtime_type->children_count; child_index++) { - mark(children[child_index]); - } -} - -// == Roots == - -typedef size_t ShedGcRootIndex; - -ShedGcRootIndex gc_root_stack_index = 0; - -struct ShedGcObjectHeader* gc_root_stack[16384]; - -ShedGcRootIndex shed__runtime__gc_get_root_stack_index() { - return gc_root_stack_index; -} - -void shed__runtime__gc_set_root_stack_index(ShedGcRootIndex new_gc_root_stack_index) { - gc_root_stack_index = new_gc_root_stack_index; -} - -static void shed__runtime__gc_push_root_gc_object(struct ShedGcObjectHeader* gc_root) { - gc_root_stack[gc_root_stack_index] = gc_root; - gc_root_stack_index++; -} - -void shed__runtime__gc_push_root(ShedObject gc_root) { - if (!is_gc_object(gc_root)) { - return; - } - - shed__runtime__gc_push_root_gc_object((struct ShedGcObjectHeader*) gc_root); -} - -// == Allocation == - -struct ShedGcObjectHeader* first = NULL; - -void* shed__runtime__gc_alloc(size_t size, uint32_t runtime_type_tag) { - struct ShedGcObjectHeader* object = malloc(size); - object->next = first; - object->mark = 0; - object->runtime_type_tag = runtime_type_tag; - - // TODO: is it possible to leave adding the root to the caller, and avoid - // having to add so many roots? (Since some values will immediately become a - // descendant of a root.) - - shed__runtime__gc_push_root_gc_object(object); - - first = object; - - return object; -} - -// == Collection == - -void mark_reachable() { - for (size_t i = 0; i < gc_root_stack_index; i++) { - mark(gc_root_stack[i]); - } -} - -void sweep() { - struct ShedGcObjectHeader** object = &first; - while (*object != NULL) { - if (is_marked(*object)) { - object = &(*object)->next; - } else { - struct ShedGcObjectHeader* next = (*object)->next; - free(*object); - *object = next; - } - } -} - -void shed__runtime__gc_collect() { - // We only want to collect periodically, but we currently always collect to - // hopefully surface errors more quickly. - - alternate_mark_value(); - - mark_reachable(); - - sweep(); -} diff --git a/runtime/src/gc.h b/runtime/src/gc.h deleted file mode 100644 index a91e57d1..00000000 --- a/runtime/src/gc.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef SHED_GC_H -#define SHED_GC_H - -#include "./std/unistd.h" - -#include "./patio/patio.h" - -struct ShedGcObjectHeader { - struct ShedGcObjectHeader* next; - uint32_t mark; - uint32_t runtime_type_tag; -}; - -struct RuntimeType { - uint32_t children_offset; - uint32_t children_count; -}; - -extern struct RuntimeType shed__rtti[]; - -void* shed__runtime__gc_alloc(size_t size, uint32_t runtime_type_tag); - -#endif diff --git a/runtime/src/ints.c b/runtime/src/ints.c deleted file mode 100644 index 572a2ee7..00000000 --- a/runtime/src/ints.c +++ /dev/null @@ -1,46 +0,0 @@ -#include - -#include "./patio/patio.h" -#include "./gc.h" -#include "./primitives.h" - -struct ShedInt { - struct ShedGcObjectHeader gc_object_header; - PatioInt value; -}; - -ShedObject shed__runtime__int_create(PatioInt value) { - struct ShedInt* result = shed__runtime__gc_alloc(sizeof(struct ShedInt), 0); - result->value = value; - return (ShedObject) result; -} - -PatioInt shed__runtime__int_value(ShedObject object) { - return ((struct ShedInt*) object)->value; -} - -ShedObject shed__runtime__int_add(ShedObject left, ShedObject right) { - PatioInt left_value = shed__runtime__int_value(left); - PatioInt right_value = shed__runtime__int_value(right); - PatioInt result_value = left_value + right_value; - return shed__runtime__int_create(result_value); -} - -ShedObject shed__runtime__int_sub(ShedObject left, ShedObject right) { - PatioInt left_value = shed__runtime__int_value(left); - PatioInt right_value = shed__runtime__int_value(right); - PatioInt result_value = left_value - right_value; - return shed__runtime__int_create(result_value); -} - -bool shed__runtime__int_equals(ShedObject left, ShedObject right) { - PatioInt left_value = shed__runtime__int_value(left); - PatioInt right_value = shed__runtime__int_value(right); - return left_value == right_value; -} - -bool shed__runtime__int_not_equal(ShedObject left, ShedObject right) { - PatioInt left_value = shed__runtime__int_value(left); - PatioInt right_value = shed__runtime__int_value(right); - return left_value != right_value; -} diff --git a/runtime/src/namespaces/Shed/Builtins.c b/runtime/src/namespaces/Shed/Builtins.c deleted file mode 100644 index 142a1317..00000000 --- a/runtime/src/namespaces/Shed/Builtins.c +++ /dev/null @@ -1,59 +0,0 @@ -#include "../../std/unistd.h" - -#include "../../shed.h" - -#ifdef __wasm__ - -typedef struct __wasi_ciovec_t { - uint8_t * buf; - size_t buf_len; -} __wasi_ciovec_t; - -uint16_t wasi_fd_write(uint32_t fd, __wasi_ciovec_t* iovs_ptr, uint32_t iovs_len, uint32_t *nwritten) - __attribute__(( - __import_module__("wasi_snapshot_preview1"), - __import_name__("fd_write"), - )); - -ShedObject shed__runtime__print(ShedClosurePointer closurePointer, ShedString value) { - uint32_t stdout = 1; - __wasi_ciovec_t iov = {.buf = value->data, .buf_len = value->length}; - uint32_t iovs_len = 1; - uint32_t nwritten; - wasi_fd_write(stdout, &iov, iovs_len, &nwritten); - return shed_unit; -} - -#else - -ShedObject shed__runtime__print(ShedClosurePointer closurePointer, ShedString value) { - size_t total_bytes_written = 0; - while (total_bytes_written < value->length) { - ssize_t bytes_written = write(STDOUT_FILENO, &value->data[total_bytes_written], value->length - total_bytes_written); - if (bytes_written == -1) { - break; - } - total_bytes_written += bytes_written; - } - return shed_unit; -} - -#endif - -ShedClosureStruct shed__runtime__print_closure = { - .function = shed__runtime__print, - .freeVariables = {}, -}; - -struct shed__namespace__Shed_Builtins { - struct ShedGcObjectHeader gc_object_header; - ShedObject print; -}; - -struct shed__namespace__Shed_Builtins shed__namespace__Shed_Builtins = { - .print = (ShedObject) &shed__runtime__print_closure -}; - -ShedObject shed__namespaceImport__Shed_Builtins() { - return (ShedObject) &shed__namespace__Shed_Builtins; -} diff --git a/runtime/src/primitives.c b/runtime/src/primitives.c deleted file mode 100644 index a103ba6d..00000000 --- a/runtime/src/primitives.c +++ /dev/null @@ -1,3 +0,0 @@ -#include "./primitives.h" - -ShedObject const shed_unit = 0; diff --git a/runtime/src/primitives.h b/runtime/src/primitives.h deleted file mode 100644 index 25bcbf5c..00000000 --- a/runtime/src/primitives.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef SHED_PRIMITIVES_H -#define SHED_PRIMITIVES_H - -#include "./patio/patio.h" - -typedef PatioInt ShedObject; - -extern ShedObject const shed_unit; - -#endif diff --git a/runtime/src/shed.h b/runtime/src/shed.h deleted file mode 100644 index ff44cd9c..00000000 --- a/runtime/src/shed.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef SHED_H -#define SHED_H - -#include "./closures.h" -#include "./primitives.h" -#include "./strings.h" - -#endif diff --git a/runtime/src/shed/alloc.c b/runtime/src/shed/alloc.c new file mode 100644 index 00000000..f68fb128 --- /dev/null +++ b/runtime/src/shed/alloc.c @@ -0,0 +1,6 @@ +#include "./std/unistd.h" +#include "./alloc.h" + +void* shed__runtime__alloc(size_t size) { + return malloc(size); +} diff --git a/runtime/src/shed/alloc.h b/runtime/src/shed/alloc.h new file mode 100644 index 00000000..07a14436 --- /dev/null +++ b/runtime/src/shed/alloc.h @@ -0,0 +1,19 @@ +#ifndef SHED_ALLOC_H +#define SHED_ALLOC_H + +#include "./std/unistd.h" + +#ifdef __wasm__ + +void* malloc(unsigned long); +void free(void*); + +#else + +#include + +#endif + +void* shed__runtime__alloc(size_t size); + +#endif diff --git a/runtime/src/shed/closures.h b/runtime/src/shed/closures.h new file mode 100644 index 00000000..e32244ea --- /dev/null +++ b/runtime/src/shed/closures.h @@ -0,0 +1,19 @@ +#ifndef SHED_CLOSURES_H +#define SHED_CLOSURES_H + +#include "./gc.h" +#include "./primitives.h" + +struct ShedClosure { + struct ShedGcObjectHeader gc_object_header; + void* function; + ShedObject freeVariables[]; +}; + +typedef struct ShedClosure ShedClosureStruct; + +typedef struct ShedClosure* ShedClosurePointer; + +typedef ShedObject* ShedEnv; + +#endif diff --git a/runtime/src/shed/effects.c b/runtime/src/shed/effects.c new file mode 100644 index 00000000..39dabe56 --- /dev/null +++ b/runtime/src/shed/effects.c @@ -0,0 +1,51 @@ +#include +#include "./std/unistd.h" +#include "./gc.h" +#include "./closures.h" +#include "./effects.h" + +struct ShedEffectHandler { + struct ShedGcObjectHeader gc_object_header; + struct ShedEffectHandler* parent; + ShedClosurePointer methods[]; +}; + +typedef struct ShedEffectHandler ShedEffectHandler; + +struct ShedEffectHandler* shed__runtime__current_effect_handler = NULL; + +ShedEffectHandler* shed__runtime__effects_get_handler() { + return shed__runtime__current_effect_handler; +} + +void shed__runtime__effects_set_handler(ShedEffectHandler* effect_handler) { + shed__runtime__current_effect_handler = effect_handler; +} + +void shed__runtime__effects_push_handler( + ShedEffectHandler* effect_handler +) { + effect_handler->parent = shed__runtime__current_effect_handler; + + shed__runtime__current_effect_handler = effect_handler; +} + +void shed__runtime__effects_pop_handler() { + shed__runtime__current_effect_handler = shed__runtime__current_effect_handler->parent; +} + +ShedClosurePointer shed__runtime__effects_find_handler_method( + ShedEffectTag effect_tag, + ShedEffectMethodIndex method_index +) { + ShedEffectHandler* handler = shed__runtime__current_effect_handler; + while (handler != NULL) { + if (handler->gc_object_header.runtime_type_tag == effect_tag) { + return handler->methods[method_index]; + } + handler = handler->parent; + } + + // TODO: more informative error + return NULL; +} diff --git a/runtime/src/shed/effects.h b/runtime/src/shed/effects.h new file mode 100644 index 00000000..e74ed171 --- /dev/null +++ b/runtime/src/shed/effects.h @@ -0,0 +1,9 @@ +#ifndef SHED_EFFECTS_H +#define SHED_EFFECTS_H + +#include "../patio/patio.h" + +typedef PatioInt ShedEffectTag; +typedef PatioInt ShedEffectMethodIndex; + +#endif diff --git a/runtime/src/shed/gc.c b/runtime/src/shed/gc.c new file mode 100644 index 00000000..2d6ab05f --- /dev/null +++ b/runtime/src/shed/gc.c @@ -0,0 +1,132 @@ +#include + +#include "../patio/patio.h" +#include "./alloc.h" +#include "./gc.h" +#include "./primitives.h" + +// == GC objects == + +bool is_gc_object(ShedObject object) { + // Check that the object is not one of: + // * unit (0) + // * false (0) + // * true (1) + return !(object == 0 || object == 1); +} + +// == Marking == + +// The mark value for each object is initialized to 0. Each mark phase +// alternates between using 0b010 and 0b100 as the mark value. We check only for +// the bit set to 1, meaning static values can have a mark value of 0b110 to be +// considered always marked. +PatioInt current_mark_value = 0b010; + +void alternate_mark_value() { + current_mark_value ^= 0b110; +} + +bool is_marked(struct ShedGcObjectHeader* object) { + return (object->mark & current_mark_value) == current_mark_value; +} + +void mark(struct ShedGcObjectHeader* object) { + if (object == NULL || is_marked(object)) { + return; + } + + object->mark = current_mark_value; + + struct RuntimeType* runtime_type = &shed__rtti[object->runtime_type_tag]; + + struct ShedGcObjectHeader** children = (struct ShedGcObjectHeader**) ( + ((void*) object) + runtime_type->children_offset + ); + + for (size_t child_index = 0; child_index < runtime_type->children_count; child_index++) { + mark(children[child_index]); + } +} + +// == Roots == + +typedef size_t ShedGcRootIndex; + +ShedGcRootIndex gc_root_stack_index = 0; + +struct ShedGcObjectHeader* gc_root_stack[16384]; + +ShedGcRootIndex shed__runtime__gc_get_root_stack_index() { + return gc_root_stack_index; +} + +void shed__runtime__gc_set_root_stack_index(ShedGcRootIndex new_gc_root_stack_index) { + gc_root_stack_index = new_gc_root_stack_index; +} + +static void shed__runtime__gc_push_root_gc_object(struct ShedGcObjectHeader* gc_root) { + gc_root_stack[gc_root_stack_index] = gc_root; + gc_root_stack_index++; +} + +void shed__runtime__gc_push_root(ShedObject gc_root) { + if (!is_gc_object(gc_root)) { + return; + } + + shed__runtime__gc_push_root_gc_object((struct ShedGcObjectHeader*) gc_root); +} + +// == Allocation == + +struct ShedGcObjectHeader* first = NULL; + +void* shed__runtime__gc_alloc(size_t size, uint32_t runtime_type_tag) { + struct ShedGcObjectHeader* object = malloc(size); + object->next = first; + object->mark = 0; + object->runtime_type_tag = runtime_type_tag; + + // TODO: is it possible to leave adding the root to the caller, and avoid + // having to add so many roots? (Since some values will immediately become a + // descendant of a root.) + + shed__runtime__gc_push_root_gc_object(object); + + first = object; + + return object; +} + +// == Collection == + +void mark_reachable() { + for (size_t i = 0; i < gc_root_stack_index; i++) { + mark(gc_root_stack[i]); + } +} + +void sweep() { + struct ShedGcObjectHeader** object = &first; + while (*object != NULL) { + if (is_marked(*object)) { + object = &(*object)->next; + } else { + struct ShedGcObjectHeader* next = (*object)->next; + free(*object); + *object = next; + } + } +} + +void shed__runtime__gc_collect() { + // We only want to collect periodically, but we currently always collect to + // hopefully surface errors more quickly. + + alternate_mark_value(); + + mark_reachable(); + + sweep(); +} diff --git a/runtime/src/shed/gc.h b/runtime/src/shed/gc.h new file mode 100644 index 00000000..9e39e7b7 --- /dev/null +++ b/runtime/src/shed/gc.h @@ -0,0 +1,23 @@ +#ifndef SHED_GC_H +#define SHED_GC_H + +#include "./std/unistd.h" + +#include "../patio/patio.h" + +struct ShedGcObjectHeader { + struct ShedGcObjectHeader* next; + uint32_t mark; + uint32_t runtime_type_tag; +}; + +struct RuntimeType { + uint32_t children_offset; + uint32_t children_count; +}; + +extern struct RuntimeType shed__rtti[]; + +void* shed__runtime__gc_alloc(size_t size, uint32_t runtime_type_tag); + +#endif diff --git a/runtime/src/shed/ints.c b/runtime/src/shed/ints.c new file mode 100644 index 00000000..c7c2c8ea --- /dev/null +++ b/runtime/src/shed/ints.c @@ -0,0 +1,46 @@ +#include + +#include "../patio/patio.h" +#include "./gc.h" +#include "./primitives.h" + +struct ShedInt { + struct ShedGcObjectHeader gc_object_header; + PatioInt value; +}; + +ShedObject shed__runtime__int_create(PatioInt value) { + struct ShedInt* result = shed__runtime__gc_alloc(sizeof(struct ShedInt), 0); + result->value = value; + return (ShedObject) result; +} + +PatioInt shed__runtime__int_value(ShedObject object) { + return ((struct ShedInt*) object)->value; +} + +ShedObject shed__runtime__int_add(ShedObject left, ShedObject right) { + PatioInt left_value = shed__runtime__int_value(left); + PatioInt right_value = shed__runtime__int_value(right); + PatioInt result_value = left_value + right_value; + return shed__runtime__int_create(result_value); +} + +ShedObject shed__runtime__int_sub(ShedObject left, ShedObject right) { + PatioInt left_value = shed__runtime__int_value(left); + PatioInt right_value = shed__runtime__int_value(right); + PatioInt result_value = left_value - right_value; + return shed__runtime__int_create(result_value); +} + +bool shed__runtime__int_equals(ShedObject left, ShedObject right) { + PatioInt left_value = shed__runtime__int_value(left); + PatioInt right_value = shed__runtime__int_value(right); + return left_value == right_value; +} + +bool shed__runtime__int_not_equal(ShedObject left, ShedObject right) { + PatioInt left_value = shed__runtime__int_value(left); + PatioInt right_value = shed__runtime__int_value(right); + return left_value != right_value; +} diff --git a/runtime/src/shed/namespaces/Shed/Builtins.c b/runtime/src/shed/namespaces/Shed/Builtins.c new file mode 100644 index 00000000..142a1317 --- /dev/null +++ b/runtime/src/shed/namespaces/Shed/Builtins.c @@ -0,0 +1,59 @@ +#include "../../std/unistd.h" + +#include "../../shed.h" + +#ifdef __wasm__ + +typedef struct __wasi_ciovec_t { + uint8_t * buf; + size_t buf_len; +} __wasi_ciovec_t; + +uint16_t wasi_fd_write(uint32_t fd, __wasi_ciovec_t* iovs_ptr, uint32_t iovs_len, uint32_t *nwritten) + __attribute__(( + __import_module__("wasi_snapshot_preview1"), + __import_name__("fd_write"), + )); + +ShedObject shed__runtime__print(ShedClosurePointer closurePointer, ShedString value) { + uint32_t stdout = 1; + __wasi_ciovec_t iov = {.buf = value->data, .buf_len = value->length}; + uint32_t iovs_len = 1; + uint32_t nwritten; + wasi_fd_write(stdout, &iov, iovs_len, &nwritten); + return shed_unit; +} + +#else + +ShedObject shed__runtime__print(ShedClosurePointer closurePointer, ShedString value) { + size_t total_bytes_written = 0; + while (total_bytes_written < value->length) { + ssize_t bytes_written = write(STDOUT_FILENO, &value->data[total_bytes_written], value->length - total_bytes_written); + if (bytes_written == -1) { + break; + } + total_bytes_written += bytes_written; + } + return shed_unit; +} + +#endif + +ShedClosureStruct shed__runtime__print_closure = { + .function = shed__runtime__print, + .freeVariables = {}, +}; + +struct shed__namespace__Shed_Builtins { + struct ShedGcObjectHeader gc_object_header; + ShedObject print; +}; + +struct shed__namespace__Shed_Builtins shed__namespace__Shed_Builtins = { + .print = (ShedObject) &shed__runtime__print_closure +}; + +ShedObject shed__namespaceImport__Shed_Builtins() { + return (ShedObject) &shed__namespace__Shed_Builtins; +} diff --git a/runtime/src/shed/primitives.c b/runtime/src/shed/primitives.c new file mode 100644 index 00000000..a103ba6d --- /dev/null +++ b/runtime/src/shed/primitives.c @@ -0,0 +1,3 @@ +#include "./primitives.h" + +ShedObject const shed_unit = 0; diff --git a/runtime/src/shed/primitives.h b/runtime/src/shed/primitives.h new file mode 100644 index 00000000..c523e4a4 --- /dev/null +++ b/runtime/src/shed/primitives.h @@ -0,0 +1,10 @@ +#ifndef SHED_PRIMITIVES_H +#define SHED_PRIMITIVES_H + +#include "../patio/patio.h" + +typedef PatioInt ShedObject; + +extern ShedObject const shed_unit; + +#endif diff --git a/runtime/src/shed/shed.h b/runtime/src/shed/shed.h new file mode 100644 index 00000000..ff44cd9c --- /dev/null +++ b/runtime/src/shed/shed.h @@ -0,0 +1,8 @@ +#ifndef SHED_H +#define SHED_H + +#include "./closures.h" +#include "./primitives.h" +#include "./strings.h" + +#endif diff --git a/runtime/src/shed/std/unistd.h b/runtime/src/shed/std/unistd.h new file mode 100644 index 00000000..8f4dc71a --- /dev/null +++ b/runtime/src/shed/std/unistd.h @@ -0,0 +1,14 @@ +#ifndef SHED_STD_UNISTD_H +#define SHED_STD_UNISTD_H + +#ifdef __wasm__ +typedef unsigned long size_t; +typedef long ssize_t; +#ifndef NULL +#define NULL 0 +#endif +#else +#include +#endif + +#endif diff --git a/runtime/src/shed/strings.c b/runtime/src/shed/strings.c new file mode 100644 index 00000000..8ef25433 --- /dev/null +++ b/runtime/src/shed/strings.c @@ -0,0 +1,22 @@ +#include "./gc.h" +#include "./strings.h" + +ShedString shed__runtime__string_alloc(ShedStringLength length) { + return shed__runtime__gc_alloc(sizeof(struct ShedString) + length, 0); +} + +ShedString shed__runtime__string_add(ShedString left, ShedString right) { + ShedStringLength length = left->length + right->length; + ShedString string = shed__runtime__string_alloc(length); + string->length = length; + + for(ShedStringLength i = 0; i < left->length; i++) { + string->data[i] = left->data[i]; + } + + for(ShedStringLength i = 0; i < right->length; i++) { + string->data[left->length + i] = right->data[i]; + } + + return string; +} diff --git a/runtime/src/shed/strings.h b/runtime/src/shed/strings.h new file mode 100644 index 00000000..060262fa --- /dev/null +++ b/runtime/src/shed/strings.h @@ -0,0 +1,19 @@ +#ifndef SHED_STRINGS_H +#define SHED_STRINGS_H + +#include + +#include "../patio/patio.h" +#include "./gc.h" + +typedef PatioInt ShedStringLength; + +struct ShedString { + struct ShedGcObjectHeader gc_object_header; + ShedStringLength length; + uint8_t data[]; +}; + +typedef struct ShedString* ShedString; + +#endif diff --git a/runtime/src/std/unistd.h b/runtime/src/std/unistd.h deleted file mode 100644 index 8f4dc71a..00000000 --- a/runtime/src/std/unistd.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef SHED_STD_UNISTD_H -#define SHED_STD_UNISTD_H - -#ifdef __wasm__ -typedef unsigned long size_t; -typedef long ssize_t; -#ifndef NULL -#define NULL 0 -#endif -#else -#include -#endif - -#endif diff --git a/runtime/src/strings.c b/runtime/src/strings.c deleted file mode 100644 index 8ef25433..00000000 --- a/runtime/src/strings.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "./gc.h" -#include "./strings.h" - -ShedString shed__runtime__string_alloc(ShedStringLength length) { - return shed__runtime__gc_alloc(sizeof(struct ShedString) + length, 0); -} - -ShedString shed__runtime__string_add(ShedString left, ShedString right) { - ShedStringLength length = left->length + right->length; - ShedString string = shed__runtime__string_alloc(length); - string->length = length; - - for(ShedStringLength i = 0; i < left->length; i++) { - string->data[i] = left->data[i]; - } - - for(ShedStringLength i = 0; i < right->length; i++) { - string->data[left->length + i] = right->data[i]; - } - - return string; -} diff --git a/runtime/src/strings.h b/runtime/src/strings.h deleted file mode 100644 index d299a098..00000000 --- a/runtime/src/strings.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef SHED_STRINGS_H -#define SHED_STRINGS_H - -#include - -#include "./patio/patio.h" -#include "./gc.h" - -typedef PatioInt ShedStringLength; - -struct ShedString { - struct ShedGcObjectHeader gc_object_header; - ShedStringLength length; - uint8_t data[]; -}; - -typedef struct ShedString* ShedString; - -#endif -- cgit v1.2.3