summaryrefslogtreecommitdiff
path: root/src/main/c/simple_crt.c
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-08-10 11:11:18 -0700
committerCliff Click <cliffc@acm.org>2026-10-08 16:52:27 -0700
commitd32f97238c903765dec4e9a9f3cbfa5fd12cded6 (patch)
treea5ac731801ef7066bab6359c4e85c2bdd20082a6 /src/main/c/simple_crt.c
parentb5ebb2032aa04cf4506d533127d373d4cf5a25c6 (diff)
downloadSimple-linear.tar.gz
Simple-linear.zip
Chapter 25: Modules, Separate Compilation, and SSA Constructionlinear
Co-authored-by: Hsiang-Ying Fu <66062782+fuhsnn@users.noreply.github.com> Co-authored-by: fuhsnn <66062782+fuhsnn@users.noreply.github.com> Co-authored-by: Symious <14933944+symious@users.noreply.github.com> Co-authored-by: Jun Kawasaki <jun784@gmail.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'src/main/c/simple_crt.c')
-rw-r--r--src/main/c/simple_crt.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/main/c/simple_crt.c b/src/main/c/simple_crt.c
new file mode 100644
index 00000000..8656a3cc
--- /dev/null
+++ b/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);
+}