Cheng Shao pushed to branch wip/wasm-command-jsval at Glasgow Haskell Compiler / GHC

Commits:

1 changed file:

Changes:

  • rts/wasm/JSFFI.c
    ... ... @@ -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;