diff options
| author | Cliff Click <cliffc@acm.org> | 2026-11-07 14:10:42 -0800 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2026-11-07 14:10:42 -0800 |
| commit | 6560a92433a38825fd1d44d9c66ffba9f26990ff (patch) | |
| tree | 09e291e08bf3fc902791cb33b8c13b02b5da405f /chapter30/src/main/c | |
| parent | bb9b30b2ce6b5278e6d557b2bbb39ac3ec9406dc (diff) | |
| download | Simple-6560a92433a38825fd1d44d9c66ffba9f26990ff.tar.gz Simple-6560a92433a38825fd1d44d9c66ffba9f26990ff.zip | |
Start Chapter 30 from the completed Chapter 29 compiler
Diffstat (limited to 'chapter30/src/main/c')
| -rw-r--r-- | chapter30/src/main/c/simple_crt.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/chapter30/src/main/c/simple_crt.c b/chapter30/src/main/c/simple_crt.c new file mode 100644 index 00000000..8656a3cc --- /dev/null +++ b/chapter30/src/main/c/simple_crt.c @@ -0,0 +1,61 @@ +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +// errno may be thread-local or a macro calling a platform accessor. +int32_t simple_errno(void) { return errno; } + +// Native process arguments converted to ordinary Simple array layouts. +// The outer array is mutable; every contained byte array is published as +// immutable and non-null to Simple code. +typedef struct SimpleBytes { + uint32_t len; + unsigned char bytes[]; +} SimpleBytes; + +typedef struct SimpleArgs { + uint32_t len; + uint32_t pad; + SimpleBytes *args[]; +} SimpleArgs; + +__attribute__((CALL_CONV)) +extern int64_t simple_main(SimpleArgs *args); + +static SimpleArgs *simple_args(int argc, char **argv) { + if (argc < 0 || (uint64_t)argc > UINT32_MAX) + return NULL; + + SimpleArgs *args = calloc(1, sizeof(*args) + (size_t)argc * sizeof(args->args[0])); + if (args == NULL) + return NULL; + args->len = (uint32_t)argc; + + for (int i = 0; i < argc; i++) { + size_t len = strlen(argv[i]); + if (len > UINT32_MAX) { + free(args); + return NULL; + } + SimpleBytes *str = malloc(sizeof(*str) + len); + if (str == NULL) { + for (int j = 0; j < i; j++) free(args->args[j]); + free(args); + return NULL; + } + str->len = (uint32_t)len; + memcpy(str->bytes, argv[i], len); + args->args[i] = str; + } + return args; +} + +int main(int argc, char **argv) { + SimpleArgs *args = simple_args(argc, argv); + if (args == NULL) + return 1; + // The language-level hidden receiver is not part of the emitted ABI for + // free functions; source argument zero occupies native argument zero. + return (int)simple_main(args); +} |
