... |
... |
@@ -5,6 +5,8 @@ |
5
|
5
|
#include "Threads.h"
|
6
|
6
|
#include "sm/Sanity.h"
|
7
|
7
|
|
|
8
|
+#include <sysexits.h>
|
|
9
|
+
|
8
|
10
|
#if defined(__wasm_reference_types__)
|
9
|
11
|
|
10
|
12
|
extern HsBool rts_JSFFI_flag;
|
... |
... |
@@ -12,21 +14,8 @@ extern HsStablePtr rts_threadDelay_impl; |
12
|
14
|
extern StgClosure ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure;
|
13
|
15
|
extern StgClosure ghczminternal_GHCziInternalziWasmziPrimziConcziInternal_threadDelay_closure;
|
14
|
16
|
|
15
|
|
-int __main_void(void);
|
16
|
|
-
|
17
|
|
-int __main_argc_argv(int, char*[]);
|
18
|
|
-
|
19
|
|
-int __main_argc_argv(int argc, char *argv[]) {
|
20
|
|
- RtsConfig __conf = defaultRtsConfig;
|
21
|
|
- __conf.rts_opts_enabled = RtsOptsAll;
|
22
|
|
- __conf.rts_hs_main = false;
|
23
|
|
- hs_init_ghc(&argc, &argv, __conf);
|
24
|
|
- // See Note [threadDelay on wasm] for details.
|
25
|
|
- rts_JSFFI_flag = HS_BOOL_TRUE;
|
26
|
|
- getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure);
|
27
|
|
- rts_threadDelay_impl = getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziConcziInternal_threadDelay_closure);
|
28
|
|
- return 0;
|
29
|
|
-}
|
|
17
|
+__attribute__((__weak__))
|
|
18
|
+int __main_argc_argv(int argc, char *argv[]);
|
30
|
19
|
|
31
|
20
|
// Note [JSFFI initialization]
|
32
|
21
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
... |
... |
@@ -66,11 +55,69 @@ int __main_argc_argv(int argc, char *argv[]) { |
66
|
55
|
// by the GHC codegen, and priority 102 to the initialization logic
|
67
|
56
|
// here to ensure hs_init_ghc() sees everything it needs to see.
|
68
|
57
|
__attribute__((constructor(102))) static void __ghc_wasm_jsffi_init(void) {
|
69
|
|
- // See
|
70
|
|
- // https://gitlab.haskell.org/ghc/wasi-libc/-/blob/master/libc-bottom-half/sources/__main_void.c
|
71
|
|
- // for its definition. It initializes some libc state, then calls
|
72
|
|
- // __main_argc_argv defined above.
|
73
|
|
- __main_void();
|
|
58
|
+ // If linking static code without -no-hs-main, then the driver
|
|
59
|
+ // emitted main() is in charge of its own RTS initialization, so
|
|
60
|
+ // skip.
|
|
61
|
+#if !defined(__PIC__)
|
|
62
|
+ if (__main_argc_argv) {
|
|
63
|
+ return;
|
|
64
|
+ }
|
|
65
|
+#endif
|
|
66
|
+
|
|
67
|
+ // Code below is mirrored from
|
|
68
|
+ // https://gitlab.haskell.org/haskell-wasm/wasi-libc/-/blob/master/libc-bottom-half/sources/__main_void.c,
|
|
69
|
+ // fetches argc/argv using wasi api
|
|
70
|
+ __wasi_errno_t err;
|
|
71
|
+
|
|
72
|
+ // Get the sizes of the arrays we'll have to create to copy in the args.
|
|
73
|
+ size_t argv_buf_size;
|
|
74
|
+ size_t argc;
|
|
75
|
+ err = __wasi_args_sizes_get(&argc, &argv_buf_size);
|
|
76
|
+ if (err != __WASI_ERRNO_SUCCESS) {
|
|
77
|
+ _Exit(EX_OSERR);
|
|
78
|
+ }
|
|
79
|
+
|
|
80
|
+ // Add 1 for the NULL pointer to mark the end, and check for overflow.
|
|
81
|
+ size_t num_ptrs = argc + 1;
|
|
82
|
+ if (num_ptrs == 0) {
|
|
83
|
+ _Exit(EX_SOFTWARE);
|
|
84
|
+ }
|
|
85
|
+
|
|
86
|
+ // Allocate memory for storing the argument chars.
|
|
87
|
+ char *argv_buf = malloc(argv_buf_size);
|
|
88
|
+ if (argv_buf == NULL) {
|
|
89
|
+ _Exit(EX_SOFTWARE);
|
|
90
|
+ }
|
|
91
|
+
|
|
92
|
+ // Allocate memory for the array of pointers. This uses `calloc` both to
|
|
93
|
+ // handle overflow and to initialize the NULL pointer at the end.
|
|
94
|
+ char **argv = calloc(num_ptrs, sizeof(char *));
|
|
95
|
+ if (argv == NULL) {
|
|
96
|
+ free(argv_buf);
|
|
97
|
+ _Exit(EX_SOFTWARE);
|
|
98
|
+ }
|
|
99
|
+
|
|
100
|
+ // Fill the argument chars, and the argv array with pointers into those chars.
|
|
101
|
+ // TODO: Remove the casts on `argv_ptrs` and `argv_buf` once the witx is
|
|
102
|
+ // updated with char8 support.
|
|
103
|
+ err = __wasi_args_get((uint8_t **)argv, (uint8_t *)argv_buf);
|
|
104
|
+ if (err != __WASI_ERRNO_SUCCESS) {
|
|
105
|
+ free(argv_buf);
|
|
106
|
+ free(argv);
|
|
107
|
+ _Exit(EX_OSERR);
|
|
108
|
+ }
|
|
109
|
+
|
|
110
|
+ // Now that we have argc/argv, proceed to initialize the GHC RTS
|
|
111
|
+ RtsConfig __conf = defaultRtsConfig;
|
|
112
|
+ __conf.rts_opts_enabled = RtsOptsAll;
|
|
113
|
+ __conf.rts_hs_main = false;
|
|
114
|
+ hs_init_ghc((int *)&argc, &argv, __conf);
|
|
115
|
+ // See Note [threadDelay on wasm] for details.
|
|
116
|
+ rts_JSFFI_flag = HS_BOOL_TRUE;
|
|
117
|
+ getStablePtr((
|
|
118
|
+ StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure);
|
|
119
|
+ rts_threadDelay_impl = getStablePtr((
|
|
120
|
+ StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziConcziInternal_threadDelay_closure);
|
74
|
121
|
}
|
75
|
122
|
|
76
|
123
|
typedef __externref_t HsJSVal;
|