blob: 8656a3ccd430aece17a44603f1a4c7cac67a5f73 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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);
}
|