quickjs 0.19.0 → 0.20.0.rc1

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.
@@ -1179,7 +1179,7 @@ int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len,
1179
1179
  is_compat = n_type >> 1;
1180
1180
 
1181
1181
  dbuf_init2(dbuf, opaque, realloc_func);
1182
- if (dbuf_realloc(dbuf, sizeof(int) * src_len))
1182
+ if (dbuf_claim(dbuf, sizeof(int) * src_len))
1183
1183
  goto fail;
1184
1184
 
1185
1185
  /* common case: latin1 is unaffected by NFC */
@@ -1189,7 +1189,8 @@ int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len,
1189
1189
  goto not_latin1;
1190
1190
  }
1191
1191
  buf = (int *)dbuf->buf;
1192
- memcpy(buf, src, src_len * sizeof(int));
1192
+ if (src_len != 0)
1193
+ memcpy(buf, src, src_len * sizeof(int));
1193
1194
  *pdst = (uint32_t *)buf;
1194
1195
  return src_len;
1195
1196
  not_latin1: ;
@@ -26,6 +26,11 @@
26
26
 
27
27
  #include <stdint.h>
28
28
 
29
+ /* unicode standard version */
30
+ #define LIBUNICODE_UNICODE_VERSION_MAJOR 17
31
+ #define LIBUNICODE_UNICODE_VERSION_MINOR 0
32
+ #define LIBUNICODE_UNICODE_VERSION_PATCH 0
33
+
29
34
  /* define it to include all the unicode tables (40KB larger) */
30
35
  #define CONFIG_ALL_UNICODE
31
36
 
@@ -147,6 +152,11 @@ static inline int lre_is_id_continue_byte(uint8_t c) {
147
152
  UNICODE_C_DIGIT);
148
153
  }
149
154
 
155
+ static inline int lre_is_word_byte(uint8_t c) {
156
+ return lre_ctype_bits[c] & (UNICODE_C_UPPER | UNICODE_C_LOWER |
157
+ UNICODE_C_UNDER | UNICODE_C_DIGIT);
158
+ }
159
+
150
160
  int lre_is_space_non_ascii(uint32_t c);
151
161
 
152
162
  static inline int lre_is_space(uint32_t c) {
@@ -75,7 +75,7 @@ static int eval_buf(JSContext *ctx, const void *buf, int buf_len,
75
75
  return ret;
76
76
  }
77
77
 
78
- static int eval_file(JSContext *ctx, const char *filename, int module)
78
+ static int eval_file(JSContext *ctx, const char *filename, int module, int strict)
79
79
  {
80
80
  uint8_t *buf;
81
81
  int ret, eval_flags;
@@ -91,10 +91,13 @@ static int eval_file(JSContext *ctx, const char *filename, int module)
91
91
  module = (has_suffix(filename, ".mjs") ||
92
92
  JS_DetectModule((const char *)buf, buf_len));
93
93
  }
94
- if (module)
94
+ if (module) {
95
95
  eval_flags = JS_EVAL_TYPE_MODULE;
96
- else
96
+ } else {
97
97
  eval_flags = JS_EVAL_TYPE_GLOBAL;
98
+ if (strict)
99
+ eval_flags |= JS_EVAL_FLAG_STRICT;
100
+ }
98
101
  ret = eval_buf(ctx, buf, buf_len, filename, eval_flags);
99
102
  js_free(ctx, buf);
100
103
  return ret;
@@ -136,7 +139,7 @@ static size_t js_trace_malloc_usable_size(const void *ptr)
136
139
  return malloc_size(ptr);
137
140
  #elif defined(_WIN32)
138
141
  return _msize((void *)ptr);
139
- #elif defined(EMSCRIPTEN)
142
+ #elif defined(__EMSCRIPTEN__)
140
143
  return 0;
141
144
  #elif defined(__linux__) || defined(__GLIBC__)
142
145
  return malloc_usable_size((void *)ptr);
@@ -294,6 +297,7 @@ void help(void)
294
297
  "-i --interactive go to interactive mode\n"
295
298
  "-m --module load as ES6 module (default=autodetect)\n"
296
299
  " --script load as ES6 script (default=autodetect)\n"
300
+ " --strict force strict mode\n"
297
301
  "-I --include file include an additional file\n"
298
302
  " --std make 'std' and 'os' available to the loaded script\n"
299
303
  "-T --trace trace memory allocation\n"
@@ -319,6 +323,7 @@ int main(int argc, char **argv)
319
323
  int trace_memory = 0;
320
324
  int empty_run = 0;
321
325
  int module = -1;
326
+ int strict = 0;
322
327
  int load_std = 0;
323
328
  int dump_unhandled_promise_rejection = 1;
324
329
  size_t memory_limit = 0;
@@ -388,6 +393,10 @@ int main(int argc, char **argv)
388
393
  module = 0;
389
394
  continue;
390
395
  }
396
+ if (!strcmp(longopt, "strict")) {
397
+ strict = 1;
398
+ continue;
399
+ }
391
400
  if (opt == 'd' || !strcmp(longopt, "dump")) {
392
401
  dump_memory++;
393
402
  continue;
@@ -485,12 +494,20 @@ int main(int argc, char **argv)
485
494
  }
486
495
 
487
496
  for(i = 0; i < include_count; i++) {
488
- if (eval_file(ctx, include_list[i], module))
497
+ if (eval_file(ctx, include_list[i], 0, strict))
489
498
  goto fail;
490
499
  }
491
500
 
492
501
  if (expr) {
493
- if (eval_buf(ctx, expr, strlen(expr), "<cmdline>", 0))
502
+ int eval_flags;
503
+ if (module > 0) {
504
+ eval_flags = JS_EVAL_TYPE_MODULE;
505
+ } else {
506
+ eval_flags = JS_EVAL_TYPE_GLOBAL;
507
+ if (strict)
508
+ eval_flags |= JS_EVAL_FLAG_STRICT;
509
+ }
510
+ if (eval_buf(ctx, expr, strlen(expr), "<cmdline>", eval_flags))
494
511
  goto fail;
495
512
  } else
496
513
  if (optind >= argc) {
@@ -499,7 +516,7 @@ int main(int argc, char **argv)
499
516
  } else {
500
517
  const char *filename;
501
518
  filename = argv[optind];
502
- if (eval_file(ctx, filename, module))
519
+ if (eval_file(ctx, filename, module, strict))
503
520
  goto fail;
504
521
  }
505
522
  if (interactive) {
@@ -78,6 +78,8 @@ DEF(await, "await")
78
78
  /* empty string */
79
79
  DEF(empty_string, "")
80
80
  /* identifiers */
81
+ DEF(keys, "keys")
82
+ DEF(size, "size")
81
83
  DEF(length, "length")
82
84
  DEF(fileName, "fileName")
83
85
  DEF(lineNumber, "lineNumber")
@@ -145,6 +147,7 @@ DEF(flags, "flags")
145
147
  DEF(global, "global")
146
148
  DEF(unicode, "unicode")
147
149
  DEF(raw, "raw")
150
+ DEF(rawJSON, "rawJSON")
148
151
  DEF(new_target, "new.target")
149
152
  DEF(this_active_func, "this.active_func")
150
153
  DEF(home_object, "<home_object>")
@@ -187,8 +190,13 @@ DEF(unicodeSets, "unicodeSets")
187
190
  DEF(not_equal, "not-equal")
188
191
  DEF(timed_out, "timed-out")
189
192
  DEF(ok, "ok")
193
+ DEF(toISOString, "toISOString")
194
+ DEF(alphabet, "alphabet")
195
+ DEF(lastChunkHandling, "lastChunkHandling")
196
+ DEF(omitPadding, "omitPadding")
190
197
  /* */
191
198
  DEF(toJSON, "toJSON")
199
+ DEF(maxByteLength, "maxByteLength")
192
200
  /* class names */
193
201
  DEF(Object, "Object")
194
202
  DEF(Array, "Array")
@@ -228,6 +236,10 @@ DEF(Map, "Map")
228
236
  DEF(Set, "Set") /* Map + 1 */
229
237
  DEF(WeakMap, "WeakMap") /* Map + 2 */
230
238
  DEF(WeakSet, "WeakSet") /* Map + 3 */
239
+ DEF(Iterator, "Iterator")
240
+ DEF(IteratorHelper, "Iterator Helper")
241
+ DEF(IteratorConcat, "Iterator Concat")
242
+ DEF(IteratorWrap, "Iterator Wrap")
231
243
  DEF(Map_Iterator, "Map Iterator")
232
244
  DEF(Set_Iterator, "Set Iterator")
233
245
  DEF(Array_Iterator, "Array Iterator")
@@ -250,6 +262,7 @@ DEF(SyntaxError, "SyntaxError")
250
262
  DEF(TypeError, "TypeError")
251
263
  DEF(URIError, "URIError")
252
264
  DEF(InternalError, "InternalError")
265
+ DEF(AggregateError, "AggregateError")
253
266
  /* private symbols */
254
267
  DEF(Private_brand, "<brand>")
255
268
  /* symbols */
@@ -46,6 +46,7 @@
46
46
  #include <termios.h>
47
47
  #include <sys/ioctl.h>
48
48
  #include <sys/wait.h>
49
+ #include <poll.h>
49
50
 
50
51
  #if defined(__FreeBSD__)
51
52
  extern char **environ;
@@ -87,6 +88,7 @@ typedef sig_t sighandler_t;
87
88
  typedef struct {
88
89
  struct list_head link;
89
90
  int fd;
91
+ int poll_fd_index; /* temporary use in js_os_poll() */
90
92
  JSValue rw_func[2];
91
93
  } JSOSRWHandler;
92
94
 
@@ -134,6 +136,7 @@ typedef struct {
134
136
  struct list_head link;
135
137
  JSWorkerMessagePipe *recv_pipe;
136
138
  JSValue on_message_func;
139
+ int poll_fd_index; /* temporary use in js_os_poll() */
137
140
  } JSWorkerMessageHandler;
138
141
 
139
142
  typedef struct {
@@ -152,6 +155,10 @@ typedef struct JSThreadState {
152
155
  int next_timer_id; /* for setTimeout() */
153
156
  /* not used in the main thread */
154
157
  JSWorkerMessagePipe *recv_pipe, *send_pipe;
158
+ #if !defined(_WIN32)
159
+ struct pollfd *poll_fds;
160
+ int poll_fds_size;
161
+ #endif
155
162
  } JSThreadState;
156
163
 
157
164
  static uint64_t os_pending_signals;
@@ -2507,16 +2514,44 @@ static int js_os_poll(JSContext *ctx)
2507
2514
 
2508
2515
  #else
2509
2516
 
2517
+ static no_inline int js_poll_expand(JSThreadState *ts)
2518
+ {
2519
+ struct pollfd *new_fds;
2520
+ int new_size = max_int(ts->poll_fds_size +
2521
+ ts->poll_fds_size / 2, 16);
2522
+ new_fds = realloc(ts->poll_fds, new_size * sizeof(struct pollfd));
2523
+ if (!new_fds)
2524
+ return -1;
2525
+ ts->poll_fds = new_fds;
2526
+ ts->poll_fds_size = new_size;
2527
+ return 0;
2528
+ }
2529
+
2530
+ static int js_poll_add_poll_fd(JSThreadState *ts, int *pnfds, int fd, int events)
2531
+ {
2532
+ struct pollfd *fds;
2533
+ int nfds;
2534
+ nfds = *pnfds;
2535
+ if (unlikely(nfds >= ts->poll_fds_size)) {
2536
+ if (js_poll_expand(ts))
2537
+ return -1;
2538
+ }
2539
+ fds = &ts->poll_fds[nfds++];
2540
+ fds->fd = fd;
2541
+ fds->events = events;
2542
+ fds->revents = 0;
2543
+ *pnfds = nfds;
2544
+ return 0;
2545
+ }
2546
+
2510
2547
  static int js_os_poll(JSContext *ctx)
2511
2548
  {
2512
2549
  JSRuntime *rt = JS_GetRuntime(ctx);
2513
2550
  JSThreadState *ts = JS_GetRuntimeOpaque(rt);
2514
- int ret, fd_max, min_delay;
2551
+ int min_delay, nfds;
2515
2552
  int64_t cur_time, delay;
2516
- fd_set rfds, wfds;
2517
2553
  JSOSRWHandler *rh;
2518
2554
  struct list_head *el;
2519
- struct timeval tv, *tvp;
2520
2555
 
2521
2556
  /* only check signals in the main thread */
2522
2557
  if (!ts->recv_pipe &&
@@ -2558,46 +2593,49 @@ static int js_os_poll(JSContext *ctx)
2558
2593
  min_delay = delay;
2559
2594
  }
2560
2595
  }
2561
- tv.tv_sec = min_delay / 1000;
2562
- tv.tv_usec = (min_delay % 1000) * 1000;
2563
- tvp = &tv;
2564
2596
  } else {
2565
- tvp = NULL;
2597
+ min_delay = -1; /* infinite */
2566
2598
  }
2567
2599
 
2568
- FD_ZERO(&rfds);
2569
- FD_ZERO(&wfds);
2570
- fd_max = -1;
2600
+ nfds = 0;
2571
2601
  list_for_each(el, &ts->os_rw_handlers) {
2602
+ int events;
2603
+
2572
2604
  rh = list_entry(el, JSOSRWHandler, link);
2573
- fd_max = max_int(fd_max, rh->fd);
2605
+ events = 0;
2574
2606
  if (!JS_IsNull(rh->rw_func[0]))
2575
- FD_SET(rh->fd, &rfds);
2607
+ events |= POLLIN;
2576
2608
  if (!JS_IsNull(rh->rw_func[1]))
2577
- FD_SET(rh->fd, &wfds);
2609
+ events |= POLLOUT;
2610
+ if (events) {
2611
+ rh->poll_fd_index = nfds;
2612
+ if (js_poll_add_poll_fd(ts, &nfds, rh->fd, events))
2613
+ return -1;
2614
+ }
2578
2615
  }
2579
2616
 
2580
2617
  list_for_each(el, &ts->port_list) {
2581
2618
  JSWorkerMessageHandler *port = list_entry(el, JSWorkerMessageHandler, link);
2582
2619
  if (!JS_IsNull(port->on_message_func)) {
2583
2620
  JSWorkerMessagePipe *ps = port->recv_pipe;
2584
- fd_max = max_int(fd_max, ps->waker.read_fd);
2585
- FD_SET(ps->waker.read_fd, &rfds);
2621
+ port->poll_fd_index = nfds;
2622
+ if (js_poll_add_poll_fd(ts, &nfds, ps->waker.read_fd, POLLIN))
2623
+ return -1;
2586
2624
  }
2587
2625
  }
2588
2626
 
2589
- ret = select(fd_max + 1, &rfds, &wfds, NULL, tvp);
2590
- if (ret > 0) {
2627
+ nfds = poll(ts->poll_fds, nfds, min_delay);
2628
+ if (nfds > 0) {
2591
2629
  list_for_each(el, &ts->os_rw_handlers) {
2592
2630
  rh = list_entry(el, JSOSRWHandler, link);
2593
2631
  if (!JS_IsNull(rh->rw_func[0]) &&
2594
- FD_ISSET(rh->fd, &rfds)) {
2632
+ (ts->poll_fds[rh->poll_fd_index].revents & (POLLERR | POLLHUP | POLLNVAL | POLLIN))) {
2595
2633
  call_handler(ctx, rh->rw_func[0]);
2596
2634
  /* must stop because the list may have been modified */
2597
2635
  goto done;
2598
2636
  }
2599
2637
  if (!JS_IsNull(rh->rw_func[1]) &&
2600
- FD_ISSET(rh->fd, &wfds)) {
2638
+ (ts->poll_fds[rh->poll_fd_index].revents & (POLLERR | POLLHUP | POLLNVAL | POLLOUT))) {
2601
2639
  call_handler(ctx, rh->rw_func[1]);
2602
2640
  /* must stop because the list may have been modified */
2603
2641
  goto done;
@@ -2607,8 +2645,7 @@ static int js_os_poll(JSContext *ctx)
2607
2645
  list_for_each(el, &ts->port_list) {
2608
2646
  JSWorkerMessageHandler *port = list_entry(el, JSWorkerMessageHandler, link);
2609
2647
  if (!JS_IsNull(port->on_message_func)) {
2610
- JSWorkerMessagePipe *ps = port->recv_pipe;
2611
- if (FD_ISSET(ps->waker.read_fd, &rfds)) {
2648
+ if (ts->poll_fds[port->poll_fd_index].revents != 0) {
2612
2649
  if (handle_posted_message(rt, ctx, port))
2613
2650
  goto done;
2614
2651
  }
@@ -3268,14 +3305,14 @@ static JSValue js_os_exec(JSContext *ctx, JSValueConst this_val,
3268
3305
  if (chdir(cwd) < 0)
3269
3306
  _exit(127);
3270
3307
  }
3271
- if (uid != -1) {
3272
- if (setuid(uid) < 0)
3273
- _exit(127);
3274
- }
3275
3308
  if (gid != -1) {
3276
3309
  if (setgid(gid) < 0)
3277
3310
  _exit(127);
3278
3311
  }
3312
+ if (uid != -1) {
3313
+ if (setuid(uid) < 0)
3314
+ _exit(127);
3315
+ }
3279
3316
 
3280
3317
  if (!file)
3281
3318
  file = exec_argv[0];
@@ -3309,7 +3346,7 @@ static JSValue js_os_exec(JSContext *ctx, JSValueConst this_val,
3309
3346
  for(i = 0; i < exec_argc; i++)
3310
3347
  JS_FreeCString(ctx, exec_argv[i]);
3311
3348
  js_free(ctx, exec_argv);
3312
- if (envp != environ) {
3349
+ if (envp && envp != environ) {
3313
3350
  char **p;
3314
3351
  p = envp;
3315
3352
  while (*p != NULL) {
@@ -3543,7 +3580,8 @@ static void js_free_port(JSRuntime *rt, JSWorkerMessageHandler *port)
3543
3580
  if (port) {
3544
3581
  js_free_message_pipe(port->recv_pipe);
3545
3582
  JS_FreeValueRT(rt, port->on_message_func);
3546
- list_del(&port->link);
3583
+ if (port->link.prev)
3584
+ list_del(&port->link);
3547
3585
  js_free_rt(rt, port);
3548
3586
  }
3549
3587
  }
@@ -3559,9 +3597,22 @@ static void js_worker_finalizer(JSRuntime *rt, JSValue val)
3559
3597
  }
3560
3598
  }
3561
3599
 
3600
+ static void js_worker_mark(JSRuntime *rt, JSValueConst val,
3601
+ JS_MarkFunc *mark_func)
3602
+ {
3603
+ JSWorkerData *worker = JS_GetOpaque(val, js_worker_class_id);
3604
+ if (worker) {
3605
+ JSWorkerMessageHandler *port = worker->msg_handler;
3606
+ if (port) {
3607
+ JS_MarkValue(rt, port->on_message_func, mark_func);
3608
+ }
3609
+ }
3610
+ }
3611
+
3562
3612
  static JSClassDef js_worker_class = {
3563
3613
  "Worker",
3564
3614
  .finalizer = js_worker_finalizer,
3615
+ .gc_mark = js_worker_mark,
3565
3616
  };
3566
3617
 
3567
3618
  static void *worker_func(void *opaque)
@@ -3865,7 +3916,7 @@ void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt))
3865
3916
  #define OS_PLATFORM "win32"
3866
3917
  #elif defined(__APPLE__)
3867
3918
  #define OS_PLATFORM "darwin"
3868
- #elif defined(EMSCRIPTEN)
3919
+ #elif defined(__EMSCRIPTEN__)
3869
3920
  #define OS_PLATFORM "js"
3870
3921
  #else
3871
3922
  #define OS_PLATFORM "linux"
@@ -4139,9 +4190,19 @@ void js_std_free_handlers(JSRuntime *rt)
4139
4190
  }
4140
4191
 
4141
4192
  #ifdef USE_WORKER
4142
- /* XXX: free port_list ? */
4143
4193
  js_free_message_pipe(ts->recv_pipe);
4144
4194
  js_free_message_pipe(ts->send_pipe);
4195
+
4196
+ list_for_each_safe(el, el1, &ts->port_list) {
4197
+ JSWorkerMessageHandler *port = list_entry(el, JSWorkerMessageHandler, link);
4198
+ /* unlink the message ports. They are freed by the Worker object */
4199
+ port->link.prev = NULL;
4200
+ port->link.next = NULL;
4201
+ }
4202
+ #endif
4203
+
4204
+ #if !defined(_WIN32)
4205
+ free(ts->poll_fds);
4145
4206
  #endif
4146
4207
 
4147
4208
  free(ts);
@@ -123,19 +123,14 @@ DEF( regexp, 1, 2, 1, none) /* create a RegExp object from the pattern a
123
123
  DEF( get_super, 1, 1, 1, none)
124
124
  DEF( import, 1, 2, 1, none) /* dynamic module import */
125
125
 
126
- DEF( check_var, 5, 0, 1, atom) /* check if a variable exists */
127
- DEF( get_var_undef, 5, 0, 1, atom) /* push undefined if the variable does not exist */
128
- DEF( get_var, 5, 0, 1, atom) /* throw an exception if the variable does not exist */
129
- DEF( put_var, 5, 1, 0, atom) /* must come after get_var */
130
- DEF( put_var_init, 5, 1, 0, atom) /* must come after put_var. Used to initialize a global lexical variable */
131
- DEF( put_var_strict, 5, 2, 0, atom) /* for strict mode variable write */
126
+ DEF( get_var_undef, 3, 0, 1, var_ref) /* push undefined if the variable does not exist */
127
+ DEF( get_var, 3, 0, 1, var_ref) /* throw an exception if the variable does not exist */
128
+ DEF( put_var, 3, 1, 0, var_ref) /* must come after get_var */
129
+ DEF( put_var_init, 3, 1, 0, var_ref) /* must come after put_var. Used to initialize a global lexical variable */
132
130
 
133
131
  DEF( get_ref_value, 1, 2, 3, none)
134
132
  DEF( put_ref_value, 1, 3, 0, none)
135
133
 
136
- DEF( define_var, 6, 0, 0, atom_u8)
137
- DEF(check_define_var, 6, 0, 0, atom_u8)
138
- DEF( define_func, 6, 1, 0, atom_u8)
139
134
  DEF( get_field, 5, 1, 1, atom)
140
135
  DEF( get_field2, 5, 1, 2, atom)
141
136
  DEF( put_field, 5, 2, 0, atom)
@@ -173,6 +168,7 @@ DEF( set_var_ref, 3, 1, 1, var_ref) /* must come after put_var_ref */
173
168
  DEF(set_loc_uninitialized, 3, 0, 0, loc)
174
169
  DEF( get_loc_check, 3, 0, 1, loc)
175
170
  DEF( put_loc_check, 3, 1, 0, loc) /* must come after get_loc_check */
171
+ DEF( set_loc_check, 3, 1, 1, loc) /* must come after put_loc_check */
176
172
  DEF( put_loc_check_init, 3, 1, 0, loc)
177
173
  DEF(get_loc_checkthis, 3, 0, 1, loc)
178
174
  DEF(get_var_ref_check, 3, 0, 1, var_ref)