emnapi 0.33.1 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "emnapi",
3
- "version": "0.33.1",
3
+ "version": "0.35.0",
4
4
  "description": "Node-API implementation for Emscripten",
5
5
  "main": "index.js",
6
6
  "devDependencies": {
@@ -2859,7 +2859,7 @@ static size_t traverse_and_check(mstate m);
2859
2859
  #define treebin_at(M,i) (&((M)->treebins[i]))
2860
2860
 
2861
2861
  /* assign tree index for size S to variable I. Use x86 asm if possible */
2862
- #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
2862
+ #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__) || defined(__wasm__))
2863
2863
  #define compute_tree_index(S, I)\
2864
2864
  {\
2865
2865
  unsigned int X = S >> TREEBIN_SHIFT;\
@@ -2962,7 +2962,7 @@ static size_t traverse_and_check(mstate m);
2962
2962
 
2963
2963
  /* index corresponding to given bit. Use x86 asm if possible */
2964
2964
 
2965
- #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
2965
+ #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__) || defined(__wasm__))
2966
2966
  #define compute_bit2idx(X, I)\
2967
2967
  {\
2968
2968
  unsigned int J;\
@@ -0,0 +1,76 @@
1
+ #include <stddef.h>
2
+ #include <stdint.h>
3
+
4
+ void* calloc(size_t n, size_t size);
5
+
6
+ extern unsigned char __heap_base;
7
+ extern unsigned char __data_end;
8
+ extern unsigned char __global_base;
9
+ extern __attribute__((__weak__)) unsigned char __stack_high;
10
+ extern __attribute__((__weak__)) unsigned char __stack_low;
11
+
12
+ #define ROUND_UP(x, ALIGNMENT) (((x)+ALIGNMENT-1)&-ALIGNMENT)
13
+ #define STACK_ALIGN 16
14
+ #define DEFAULT_STACK_MAX (8<<20)
15
+
16
+ struct worker_args {
17
+ void* stack_base;
18
+ void* tls_base;
19
+ };
20
+
21
+ extern void __wasm_init_tls(void*);
22
+
23
+ void* __copy_tls(unsigned char *mem) {
24
+ size_t tls_align = __builtin_wasm_tls_align();
25
+ volatile void* tls_base = __builtin_wasm_tls_base();
26
+ mem += tls_align;
27
+ mem -= (uintptr_t)mem & (tls_align-1);
28
+ __wasm_init_tls(mem);
29
+ __asm__("local.get %0\n"
30
+ "global.set __tls_base\n"
31
+ :: "r"(tls_base));
32
+ return mem;
33
+ }
34
+
35
+ __attribute__((visibility("default")))
36
+ void* emnapi_async_worker_create() {
37
+ size_t args_size = sizeof(struct worker_args);
38
+ size_t size = args_size;
39
+
40
+ size_t tls_size = __builtin_wasm_tls_size();
41
+
42
+ size_t tls_block_size = 0;
43
+ if (tls_size) {
44
+ size_t tls_align = __builtin_wasm_tls_align();
45
+ tls_block_size = ROUND_UP(tls_size + tls_align - 1, tls_align);
46
+ size += tls_block_size;
47
+ }
48
+
49
+ ptrdiff_t stack_size = 0;
50
+ if (&__stack_high) {
51
+ stack_size = &__stack_high - &__stack_low;
52
+ } else {
53
+ unsigned char *sp;
54
+ __asm__(
55
+ ".globaltype __stack_pointer, i32\n"
56
+ "global.get __stack_pointer\n"
57
+ "local.set %0\n"
58
+ : "=r"(sp));
59
+ stack_size = sp > &__global_base ? &__heap_base - &__data_end : (ptrdiff_t)&__global_base;
60
+ }
61
+
62
+ stack_size = ROUND_UP(stack_size, STACK_ALIGN);
63
+ stack_size = stack_size < DEFAULT_STACK_MAX ? stack_size : DEFAULT_STACK_MAX;
64
+ size += stack_size;
65
+
66
+ void* block = calloc(1, size);
67
+ if (!block) return 0;
68
+
69
+ void* tls_base = tls_size ? __copy_tls(block + args_size) : 0;
70
+
71
+ struct worker_args* args = (struct worker_args*)block;
72
+
73
+ args->stack_base = block + args_size + tls_block_size + stack_size;
74
+ args->tls_base = tls_base;
75
+ return block;
76
+ }
@@ -0,0 +1,33 @@
1
+ #ifdef __wasm64__
2
+ #define PTR i64
3
+ #else
4
+ #define PTR i32
5
+ #endif
6
+
7
+ .text
8
+
9
+ .export_name emnapi_async_worker_init, emnapi_async_worker_init
10
+
11
+ .globaltype __stack_pointer, PTR
12
+ .globaltype __tls_base, PTR
13
+
14
+ .hidden emnapi_async_worker_init
15
+ .globl emnapi_async_worker_init
16
+ .type emnapi_async_worker_init,@function
17
+
18
+ emnapi_async_worker_init:
19
+ .functype emnapi_async_worker_init (PTR) -> ()
20
+
21
+ local.get 0
22
+ PTR.load 0
23
+ global.set __stack_pointer
24
+
25
+ local.get 0
26
+ #ifdef __wasm64__
27
+ PTR.load 8
28
+ #else
29
+ PTR.load 4
30
+ #endif
31
+ global.set __tls_base
32
+
33
+ end_function
@@ -362,7 +362,7 @@ static void _emnapi_tsfn_send(napi_threadsafe_function func) {
362
362
  if ((current_state & kDispatchRunning) == kDispatchRunning) {
363
363
  return;
364
364
  }
365
- uv_async_send(&func->async);
365
+ CHECK_EQ(0, uv_async_send(&func->async));
366
366
  }
367
367
 
368
368
  // only main thread
@@ -373,7 +373,7 @@ static void _emnapi_tsfn_dispatch(napi_threadsafe_function func) {
373
373
  // starvation. See `src/node_messaging.cc` for an inspiration.
374
374
  unsigned int iterations_left = kMaxIterationCount;
375
375
  while (has_more && --iterations_left != 0) {
376
- func->dispatch_state = kDispatchRunning;
376
+ atomic_store(&func->dispatch_state, kDispatchRunning);
377
377
  has_more = _emnapi_tsfn_dispatch_one(func);
378
378
 
379
379
  // Send() was called while we were executing the JS function
@@ -409,7 +409,7 @@ napi_create_threadsafe_function(napi_env env,
409
409
  napi_threadsafe_function* result) {
410
410
  #if EMNAPI_HAVE_THREADS
411
411
  CHECK_ENV(env);
412
- // CHECK_ARG(env, async_resource_name);
412
+ CHECK_ARG(env, async_resource_name);
413
413
  RETURN_STATUS_IF_FALSE(env, initial_thread_count > 0, napi_invalid_arg);
414
414
  CHECK_ARG(env, result);
415
415
 
@@ -439,7 +439,6 @@ napi_create_threadsafe_function(napi_env env,
439
439
  if (status != napi_ok) return status;
440
440
  }
441
441
 
442
- CHECK_ARG(env, async_resource_name);
443
442
  status = napi_coerce_to_string(env, async_resource_name, &resource_name);
444
443
  if (status != napi_ok) return status;
445
444
 
@@ -209,6 +209,7 @@ static void post(QUEUE* q, enum uv__work_kind kind) {
209
209
  // nthreads = 0;
210
210
  // }
211
211
 
212
+ EMNAPI_EXTERN int _emnapi_async_work_pool_size();
212
213
 
213
214
  static void init_threads(void) {
214
215
  unsigned int i;
@@ -223,9 +224,14 @@ static void init_threads(void) {
223
224
  nthreads = EMNAPI_WORKER_POOL_SIZE;
224
225
  #else
225
226
  nthreads = ARRAY_SIZE(default_threads);
226
- val = getenv("UV_THREADPOOL_SIZE");
227
- if (val != NULL)
228
- nthreads = atoi(val);
227
+ int async_work_pool_size = _emnapi_async_work_pool_size();
228
+ if (async_work_pool_size > 0) {
229
+ nthreads = (unsigned int) async_work_pool_size;
230
+ } else {
231
+ val = getenv("UV_THREADPOOL_SIZE");
232
+ if (val != NULL)
233
+ nthreads = atoi(val);
234
+ }
229
235
  #endif
230
236
  if (nthreads == 0)
231
237
  nthreads = 1;