@mikrojs/quickjs 0.18.0 → 0.18.2-next.20260826235606

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.
@@ -4193,7 +4193,7 @@ bool JS_IsRegisteredClass(JSRuntime *rt, JSClassID class_id)
4193
4193
  JSAtom JS_GetClassName(JSRuntime *rt, JSClassID class_id)
4194
4194
  {
4195
4195
  if (JS_IsRegisteredClass(rt, class_id)) {
4196
- return JS_DupAtomRT(rt, rt->class_array[class_id].class_id);
4196
+ return JS_DupAtomRT(rt, rt->class_array[class_id].class_name);
4197
4197
  } else {
4198
4198
  return JS_ATOM_NULL;
4199
4199
  }
@@ -6339,48 +6339,21 @@ JSValue JS_NewObjectProto(JSContext *ctx, JSValueConst proto)
6339
6339
  JSValue JS_NewObjectFrom(JSContext *ctx, int count, const JSAtom *props,
6340
6340
  const JSValue *values)
6341
6341
  {
6342
- JSShapeProperty *pr;
6343
- uint32_t *hash;
6344
- JSRuntime *rt;
6345
- JSObject *p;
6346
- JSShape *sh;
6347
6342
  JSValue obj;
6348
- JSAtom atom;
6349
- intptr_t h;
6350
6343
  int i;
6351
6344
 
6352
- rt = ctx->rt;
6353
6345
  obj = JS_NewObject(ctx);
6354
6346
  if (JS_IsException(obj))
6355
6347
  return JS_EXCEPTION;
6356
- if (count > 0) {
6357
- p = JS_VALUE_GET_OBJ(obj);
6358
- sh = p->shape;
6359
- assert(sh->is_hashed);
6360
- assert(JS_REF_COUNT(sh) == 1);
6361
- js_shape_hash_unlink(rt, sh);
6362
- if (resize_properties(ctx, &sh, p, count)) {
6363
- js_shape_hash_link(rt, sh);
6364
- JS_FreeValue(ctx, obj);
6365
- return JS_EXCEPTION;
6366
- }
6367
- p->shape = sh;
6368
- for (i = 0; i < count; i++) {
6369
- atom = props[i];
6370
- pr = &get_shape_prop(sh)[i];
6371
- sh->hash = shape_hash(shape_hash(sh->hash, atom), JS_PROP_C_W_E);
6372
- h = atom & sh->prop_hash_mask;
6373
- hash = &prop_hash_end(sh)[-h - 1];
6374
- pr->hash_next = *hash;
6375
- *hash = i + 1;
6376
- pr->atom = JS_DupAtom(ctx, atom);
6377
- pr->flags = JS_PROP_C_W_E;
6378
- p->prop[i].u.value = values[i];
6379
- }
6380
- js_shape_hash_link(rt, sh);
6381
- sh->prop_count = count;
6382
- }
6348
+ for (i = 0; i < count; i++)
6349
+ if (JS_SetProperty(ctx, obj, props[i], values[i]) < 0)
6350
+ goto fail;
6383
6351
  return obj;
6352
+ fail:
6353
+ for (/*empty*/; i < count; i++)
6354
+ JS_FreeValue(ctx, values[i]);
6355
+ JS_FreeValue(ctx, obj);
6356
+ return JS_EXCEPTION;
6384
6357
  }
6385
6358
 
6386
6359
  JSValue JS_NewObjectFromStr(JSContext *ctx, int count, const char **props,
@@ -22398,6 +22371,7 @@ typedef struct JSToken {
22398
22371
  int line_num; /* line number of token start */
22399
22372
  int col_num; /* column number of token start */
22400
22373
  const uint8_t *ptr;
22374
+ const uint8_t *line_start; /* first character of the line of token start */
22401
22375
  union {
22402
22376
  struct {
22403
22377
  JSValue str;
@@ -22431,6 +22405,7 @@ typedef struct JSParseState {
22431
22405
  const uint8_t *buf_start;
22432
22406
  const uint8_t *buf_ptr;
22433
22407
  const uint8_t *buf_end;
22408
+ const uint8_t *line_start; /* first character of the current line */
22434
22409
  const uint8_t *eol; // most recently seen end-of-line character
22435
22410
  const uint8_t *mark; // first token character, invariant: eol < mark
22436
22411
 
@@ -22591,13 +22566,8 @@ int JS_PRINTF_FORMAT_ATTR(2, 3) js_parse_error(JSParseState *s, JS_PRINTF_FORMAT
22591
22566
  /* s->col_num is not advanced during token scanning, so derive the column
22592
22567
  as the 1-based offset of the token from the start of its line. */
22593
22568
  int err_col_num = s->token.col_num;
22594
- if (s->token.ptr && s->token.ptr >= s->buf_start) {
22595
- const uint8_t *line_start = s->token.ptr;
22596
- while (line_start > s->buf_start &&
22597
- line_start[-1] != '\n' && line_start[-1] != '\r')
22598
- line_start--;
22599
- err_col_num = (int)(s->token.ptr - line_start) + 1;
22600
- }
22569
+ if (s->token.ptr && s->token.ptr >= s->token.line_start)
22570
+ err_col_num = (int)(s->token.ptr - s->token.line_start) + 1;
22601
22571
  build_backtrace(ctx, ctx->rt->current_exception, JS_UNDEFINED, s->filename,
22602
22572
  s->token.line_num, err_col_num, backtrace_flags);
22603
22573
  return -1;
@@ -22697,6 +22667,7 @@ static __exception int js_parse_template_part(JSParseState *s,
22697
22667
  }
22698
22668
  if (c == '\n') {
22699
22669
  s->line_num++;
22670
+ s->line_start = p;
22700
22671
  s->eol = &p[-1];
22701
22672
  s->mark = p;
22702
22673
  } else if (c >= 0x80) {
@@ -22790,6 +22761,7 @@ static __exception int js_parse_string(JSParseState *s, int sep,
22790
22761
  p++;
22791
22762
  if (sep != '`') {
22792
22763
  s->line_num++;
22764
+ s->line_start = p;
22793
22765
  s->eol = &p[-1];
22794
22766
  s->mark = p;
22795
22767
  }
@@ -23117,6 +23089,7 @@ static __exception int next_token(JSParseState *s)
23117
23089
  s->token.line_num = s->line_num;
23118
23090
  s->token.col_num = s->col_num;
23119
23091
  s->token.ptr = p;
23092
+ s->token.line_start = s->line_start;
23120
23093
  c = *p;
23121
23094
  switch(c) {
23122
23095
  case 0:
@@ -23144,6 +23117,7 @@ static __exception int next_token(JSParseState *s)
23144
23117
  case '\n':
23145
23118
  p++;
23146
23119
  line_terminator:
23120
+ s->line_start = p;
23147
23121
  s->eol = &p[-1];
23148
23122
  s->mark = p;
23149
23123
  s->got_lf = true;
@@ -23172,10 +23146,12 @@ static __exception int next_token(JSParseState *s)
23172
23146
  s->line_num++;
23173
23147
  s->got_lf = true; /* considered as LF for ASI */
23174
23148
  s->eol = p++;
23149
+ s->line_start = p;
23175
23150
  s->mark = p;
23176
23151
  } else if (*p == '\r') {
23177
23152
  s->got_lf = true; /* considered as LF for ASI */
23178
23153
  p++;
23154
+ s->line_start = p;
23179
23155
  } else if (*p >= 0x80) {
23180
23156
  c = utf8_decode(p, &p);
23181
23157
  /* ignore invalid UTF-8 in comments */
@@ -23763,6 +23739,7 @@ static __exception int json_next_token(JSParseState *s)
23763
23739
  s->token.line_num = s->line_num;
23764
23740
  s->token.col_num = s->col_num;
23765
23741
  s->token.ptr = p;
23742
+ s->token.line_start = s->line_start;
23766
23743
  c = *p;
23767
23744
  switch(c) {
23768
23745
  case 0:
@@ -23788,6 +23765,7 @@ static __exception int json_next_token(JSParseState *s)
23788
23765
  case '\n':
23789
23766
  s->line_num++;
23790
23767
  s->eol = p++;
23768
+ s->line_start = p;
23791
23769
  s->mark = p;
23792
23770
  goto redo;
23793
23771
  case '\f':
@@ -25020,6 +24998,7 @@ typedef struct JSParsePos {
25020
24998
  int col_num;
25021
24999
  bool got_lf;
25022
25000
  const uint8_t *ptr;
25001
+ const uint8_t *line_start;
25023
25002
  const uint8_t *eol;
25024
25003
  const uint8_t *mark;
25025
25004
  } JSParsePos;
@@ -25031,6 +25010,7 @@ static int js_parse_get_pos(JSParseState *s, JSParsePos *sp)
25031
25010
  sp->line_num = s->token.line_num;
25032
25011
  sp->col_num = s->token.col_num;
25033
25012
  sp->ptr = s->token.ptr;
25013
+ sp->line_start = s->line_start;
25034
25014
  sp->eol = s->eol;
25035
25015
  sp->mark = s->mark;
25036
25016
  sp->got_lf = s->got_lf;
@@ -25044,6 +25024,7 @@ static __exception int js_parse_seek_token(JSParseState *s, const JSParsePos *sp
25044
25024
  s->line_num = sp->line_num;
25045
25025
  s->col_num = sp->col_num;
25046
25026
  s->buf_ptr = sp->ptr;
25027
+ s->line_start = sp->line_start;
25047
25028
  s->eol = sp->eol;
25048
25029
  s->mark = sp->mark;
25049
25030
  s->got_lf = sp->got_lf;
@@ -27204,13 +27185,8 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags)
27204
27185
  {
27205
27186
  JSAtom name;
27206
27187
  int identifier_line_num = s->token.line_num;
27207
- const uint8_t *identifier_line_start = s->token.ptr;
27208
- while (identifier_line_start > s->buf_start &&
27209
- identifier_line_start[-1] != '\n' &&
27210
- identifier_line_start[-1] != '\r')
27211
- identifier_line_start--;
27212
27188
  int identifier_col_num =
27213
- (int)(s->token.ptr - identifier_line_start) + 1;
27189
+ (int)(s->token.ptr - s->line_start) + 1;
27214
27190
  if (s->token.u.ident.is_reserved) {
27215
27191
  return js_parse_error_reserved_identifier(s);
27216
27192
  }
@@ -30364,27 +30340,36 @@ static void js_free_module_def(JSContext *ctx, JSModuleDef *m)
30364
30340
 
30365
30341
  JS_FreeAtom(ctx, m->module_name);
30366
30342
 
30367
- for(i = 0; i < m->req_module_entries_count; i++) {
30368
- JSReqModuleEntry *rme = &m->req_module_entries[i];
30369
- JS_FreeAtom(ctx, rme->module_name);
30370
- JS_FreeValue(ctx, rme->attributes);
30343
+ /* mikrojs patch: a partially-deserialized module (JS_ReadModule OOM
30344
+ mid-read) can carry a non-zero entry count with a NULL array — the
30345
+ count is decoded before the array allocation. Guard each loop. */
30346
+ if (m->req_module_entries) {
30347
+ for(i = 0; i < m->req_module_entries_count; i++) {
30348
+ JSReqModuleEntry *rme = &m->req_module_entries[i];
30349
+ JS_FreeAtom(ctx, rme->module_name);
30350
+ JS_FreeValue(ctx, rme->attributes);
30351
+ }
30371
30352
  }
30372
30353
  js_free(ctx, m->req_module_entries);
30373
30354
 
30374
- for(i = 0; i < m->export_entries_count; i++) {
30375
- JSExportEntry *me = &m->export_entries[i];
30376
- if (me->export_type == JS_EXPORT_TYPE_LOCAL)
30377
- free_var_ref(ctx->rt, me->u.local.var_ref);
30378
- JS_FreeAtom(ctx, me->export_name);
30379
- JS_FreeAtom(ctx, me->local_name);
30355
+ if (m->export_entries) {
30356
+ for(i = 0; i < m->export_entries_count; i++) {
30357
+ JSExportEntry *me = &m->export_entries[i];
30358
+ if (me->export_type == JS_EXPORT_TYPE_LOCAL)
30359
+ free_var_ref(ctx->rt, me->u.local.var_ref);
30360
+ JS_FreeAtom(ctx, me->export_name);
30361
+ JS_FreeAtom(ctx, me->local_name);
30362
+ }
30380
30363
  }
30381
30364
  js_free(ctx, m->export_entries);
30382
30365
 
30383
30366
  js_free(ctx, m->star_export_entries);
30384
30367
 
30385
- for(i = 0; i < m->import_entries_count; i++) {
30386
- JSImportEntry *mi = &m->import_entries[i];
30387
- JS_FreeAtom(ctx, mi->import_name);
30368
+ if (m->import_entries) {
30369
+ for(i = 0; i < m->import_entries_count; i++) {
30370
+ JSImportEntry *mi = &m->import_entries[i];
30371
+ JS_FreeAtom(ctx, mi->import_name);
30372
+ }
30388
30373
  }
30389
30374
  js_free(ctx, m->import_entries);
30390
30375
  js_free(ctx, m->async_parent_modules);
@@ -34181,6 +34166,14 @@ static int resolve_scope_var(JSContext *ctx, JSFunctionDef *s,
34181
34166
  idx = get_closure_var(ctx, s, fd, JS_CLOSURE_LOCAL,
34182
34167
  fd->var_object_idx, vd->var_name,
34183
34168
  false, false, JS_VAR_NORMAL);
34169
+ /* mikrojs patch: get_closure_var fails under OOM; the -1 index
34170
+ would be emitted as var_ref 65535 (or dereference
34171
+ closure_var[-1] at has_idx). Poison the dbuf so
34172
+ resolve_variables reports the error. */
34173
+ if (idx < 0) {
34174
+ dbuf_set_error(bc);
34175
+ goto done;
34176
+ }
34184
34177
  dbuf_putc(bc, OP_get_var_ref);
34185
34178
  dbuf_put_u16(bc, idx);
34186
34179
  var_object_test(ctx, s, var_name, op, bc, &label_done, 0);
@@ -34193,6 +34186,11 @@ static int resolve_scope_var(JSContext *ctx, JSFunctionDef *s,
34193
34186
  idx = get_closure_var(ctx, s, fd, JS_CLOSURE_LOCAL,
34194
34187
  fd->arg_var_object_idx, vd->var_name,
34195
34188
  false, false, JS_VAR_NORMAL);
34189
+ /* mikrojs patch: see the eval object case above */
34190
+ if (idx < 0) {
34191
+ dbuf_set_error(bc);
34192
+ goto done;
34193
+ }
34196
34194
  dbuf_putc(bc, OP_get_var_ref);
34197
34195
  dbuf_put_u16(bc, idx);
34198
34196
  var_object_test(ctx, s, var_name, op, bc, &label_done, 0);
@@ -34220,6 +34218,11 @@ static int resolve_scope_var(JSContext *ctx, JSFunctionDef *s,
34220
34218
  } else {
34221
34219
  idx = idx1;
34222
34220
  }
34221
+ /* mikrojs patch: see the eval object case above */
34222
+ if (idx < 0) {
34223
+ dbuf_set_error(bc);
34224
+ goto done;
34225
+ }
34223
34226
  goto has_idx;
34224
34227
  } else if ((cv->var_name == JS_ATOM__var_ ||
34225
34228
  cv->var_name == JS_ATOM__arg_var_ ||
@@ -34234,6 +34237,11 @@ static int resolve_scope_var(JSContext *ctx, JSFunctionDef *s,
34234
34237
  } else {
34235
34238
  idx = idx1;
34236
34239
  }
34240
+ /* mikrojs patch: see the eval object case above */
34241
+ if (idx < 0) {
34242
+ dbuf_set_error(bc);
34243
+ goto done;
34244
+ }
34237
34245
  dbuf_putc(bc, OP_get_var_ref);
34238
34246
  dbuf_put_u16(bc, idx);
34239
34247
  var_object_test(ctx, s, var_name, op, bc, &label_done, is_with);
@@ -35939,18 +35947,24 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
35939
35947
  for(re = ls->first_reloc; re != NULL; re = re_next) {
35940
35948
  int diff = ls->addr - re->addr;
35941
35949
  re_next = re->next;
35942
- switch (re->size) {
35943
- case 4:
35944
- put_u32(bc_out.buf + re->addr, diff);
35945
- break;
35946
- case 2:
35947
- assert(diff == (int16_t)diff);
35948
- put_u16(bc_out.buf + re->addr, diff);
35949
- break;
35950
- case 1:
35951
- assert(diff == (int8_t)diff);
35952
- put_u8(bc_out.buf + re->addr, diff);
35953
- break;
35950
+ /* mikrojs patch: after a dbuf OOM the recorded addresses
35951
+ no longer match the buffer contents (and the buffer may
35952
+ be NULL); skip the writes and let the dbuf_error check
35953
+ at the end of resolve_labels report the failure. */
35954
+ if (!dbuf_error(&bc_out)) {
35955
+ switch (re->size) {
35956
+ case 4:
35957
+ put_u32(bc_out.buf + re->addr, diff);
35958
+ break;
35959
+ case 2:
35960
+ assert(diff == (int16_t)diff);
35961
+ put_u16(bc_out.buf + re->addr, diff);
35962
+ break;
35963
+ case 1:
35964
+ assert(diff == (int8_t)diff);
35965
+ put_u8(bc_out.buf + re->addr, diff);
35966
+ break;
35967
+ }
35954
35968
  }
35955
35969
  js_free(ctx, re);
35956
35970
  }
@@ -36635,6 +36649,11 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
36635
36649
 
36636
36650
  /* more jump optimizations */
36637
36651
  patch_offsets = 0;
36652
+ /* mikrojs patch: on dbuf OOM the recorded jump/label offsets are stale
36653
+ relative to the buffer contents; skip the peephole passes and let the
36654
+ dbuf_error check below report the failure. */
36655
+ if (dbuf_error(&bc_out))
36656
+ goto skip_peephole;
36638
36657
  for (i = 0, jp = s->jump_slots; i < s->jump_count; i++, jp++) {
36639
36658
  LabelSlot *ls;
36640
36659
  JumpSlot *jp1;
@@ -36708,6 +36727,7 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
36708
36727
  }
36709
36728
  }
36710
36729
 
36730
+ skip_peephole: /* mikrojs patch */
36711
36731
  js_free(ctx, s->jump_slots);
36712
36732
  s->jump_slots = NULL;
36713
36733
  js_free(ctx, s->label_slots);
@@ -37096,6 +37116,14 @@ static JSValue js_create_function(JSContext *ctx, JSFunctionDef *fd)
37096
37116
  }
37097
37117
  #endif
37098
37118
 
37119
+ /* mikrojs patch: a dbuf error during emission leaves byte_code truncated
37120
+ relative to its opcode structure; the resolve passes would then read
37121
+ past the end of the buffer. Fail before walking it. */
37122
+ if (dbuf_error(&fd->byte_code)) {
37123
+ JS_ThrowOutOfMemory(ctx);
37124
+ goto fail;
37125
+ }
37126
+
37099
37127
  if (resolve_variables(ctx, fd))
37100
37128
  goto fail;
37101
37129
 
@@ -37118,8 +37146,8 @@ static JSValue js_create_function(JSContext *ctx, JSFunctionDef *fd)
37118
37146
  goto fail;
37119
37147
 
37120
37148
  function_size = sizeof(*b);
37121
- cpool_offset = function_size;
37122
- function_size += fd->cpool_count * sizeof(*fd->cpool);
37149
+ cpool_offset = (function_size + 7) & ~7;
37150
+ function_size = cpool_offset + fd->cpool_count * sizeof(*fd->cpool);
37123
37151
  vardefs_offset = function_size;
37124
37152
  function_size += (fd->arg_count + fd->var_count) * sizeof(*b->vardefs);
37125
37153
  closure_var_offset = function_size;
@@ -38164,6 +38192,7 @@ static void js_parse_init(JSContext *ctx, JSParseState *s,
38164
38192
  s->col_num = 1;
38165
38193
  s->buf_start = s->buf_ptr = (const uint8_t *)input;
38166
38194
  s->buf_end = s->buf_ptr + input_len;
38195
+ s->line_start = s->buf_ptr;
38167
38196
  s->mark = s->buf_ptr + min_int(1, input_len);
38168
38197
  s->eol = s->buf_ptr;
38169
38198
  s->token.val = ' ';
@@ -39819,8 +39848,8 @@ static JSValue JS_ReadFunctionTag(BCReaderState *s)
39819
39848
  goto fail;
39820
39849
 
39821
39850
  function_size = sizeof(*b);
39822
- cpool_offset = function_size;
39823
- function_size += bc.cpool_count * sizeof(*bc.cpool);
39851
+ cpool_offset = (function_size + 7) & ~7;
39852
+ function_size = cpool_offset + bc.cpool_count * sizeof(*bc.cpool);
39824
39853
  vardefs_offset = function_size;
39825
39854
  function_size += local_count * sizeof(*bc.vardefs);
39826
39855
  closure_var_offset = function_size;
@@ -41013,7 +41042,7 @@ static JSValue JS_NewCConstructor(JSContext *ctx, int class_id, const char *name
41013
41042
  const JSCFunctionListEntry *proto_fields, int n_proto_fields,
41014
41043
  int flags)
41015
41044
  {
41016
- JSValue ctor = JS_UNDEFINED, proto, parent_proto;
41045
+ JSValue ctor = JS_UNDEFINED, proto, parent_proto, *class_proto;
41017
41046
  int proto_class_id, proto_flags, ctor_flags;
41018
41047
 
41019
41048
  proto_flags = 0;
@@ -41044,8 +41073,12 @@ static JSValue JS_NewCConstructor(JSContext *ctx, int class_id, const char *name
41044
41073
  n_proto_fields + 1);
41045
41074
  if (JS_IsException(proto))
41046
41075
  goto fail;
41047
- if (class_id >= 0)
41048
- ctx->class_proto[class_id] = js_dup(proto);
41076
+ if (class_id >= 0) {
41077
+ class_proto = &ctx->class_proto[class_id];
41078
+ if (!JS_IsNull(*class_proto))
41079
+ JS_FreeValue(ctx, *class_proto);
41080
+ *class_proto = js_dup(proto);
41081
+ }
41049
41082
  }
41050
41083
  if (JS_SetPropertyFunctionList(ctx, proto, proto_fields, n_proto_fields))
41051
41084
  goto fail;
@@ -41244,8 +41277,9 @@ static int js_obj_to_desc(JSContext *ctx, JSPropertyDescriptor *d,
41244
41277
  if (present) {
41245
41278
  flags |= JS_PROP_HAS_GET;
41246
41279
  getter = JS_GetProperty(ctx, desc, JS_ATOM_get);
41247
- if (JS_IsException(getter) ||
41248
- !(JS_IsUndefined(getter) || JS_IsFunction(ctx, getter))) {
41280
+ if (JS_IsException(getter))
41281
+ goto fail;
41282
+ if (!(JS_IsUndefined(getter) || JS_IsFunction(ctx, getter))) {
41249
41283
  JS_ThrowTypeError(ctx, "Getter must be a function");
41250
41284
  goto fail;
41251
41285
  }
@@ -41256,8 +41290,9 @@ static int js_obj_to_desc(JSContext *ctx, JSPropertyDescriptor *d,
41256
41290
  if (present) {
41257
41291
  flags |= JS_PROP_HAS_SET;
41258
41292
  setter = JS_GetProperty(ctx, desc, JS_ATOM_set);
41259
- if (JS_IsException(setter) ||
41260
- !(JS_IsUndefined(setter) || JS_IsFunction(ctx, setter))) {
41293
+ if (JS_IsException(setter))
41294
+ goto fail;
41295
+ if (!(JS_IsUndefined(setter) || JS_IsFunction(ctx, setter))) {
41261
41296
  JS_ThrowTypeError(ctx, "Setter must be a function");
41262
41297
  goto fail;
41263
41298
  }
@@ -43630,6 +43665,8 @@ static JSValue js_array_every(JSContext *ctx, JSValueConst this_val,
43630
43665
  n = 0;
43631
43666
 
43632
43667
  for(k = 0; k < len; k++) {
43668
+ if (js_poll_interrupts(ctx))
43669
+ goto exception;
43633
43670
  if (special & special_TA) {
43634
43671
  val = JS_GetPropertyInt64(ctx, obj, k);
43635
43672
  if (JS_IsException(val))
@@ -43751,6 +43788,8 @@ static JSValue js_array_reduce(JSContext *ctx, JSValueConst this_val,
43751
43788
  acc = js_dup(argv[1]);
43752
43789
  } else {
43753
43790
  for(;;) {
43791
+ if (js_poll_interrupts(ctx))
43792
+ goto exception;
43754
43793
  if (k >= len) {
43755
43794
  JS_ThrowTypeError(ctx, "empty array");
43756
43795
  goto exception;
@@ -43772,6 +43811,8 @@ static JSValue js_array_reduce(JSContext *ctx, JSValueConst this_val,
43772
43811
  }
43773
43812
  }
43774
43813
  for (; k < len; k++) {
43814
+ if (js_poll_interrupts(ctx))
43815
+ goto exception;
43775
43816
  k1 = (special & special_reduceRight) ? len - k - 1 : k;
43776
43817
  if (special & special_TA) {
43777
43818
  val = JS_GetPropertyInt64(ctx, obj, k1);
@@ -43873,6 +43914,8 @@ static JSValue js_array_includes(JSContext *ctx, JSValueConst this_val,
43873
43914
  }
43874
43915
  }
43875
43916
  for (; n < len; n++) {
43917
+ if (js_poll_interrupts(ctx))
43918
+ goto exception;
43876
43919
  val = JS_GetPropertyInt64(ctx, obj, n);
43877
43920
  if (JS_IsException(val))
43878
43921
  goto exception;
@@ -43919,6 +43962,8 @@ static JSValue js_array_indexOf(JSContext *ctx, JSValueConst this_val,
43919
43962
  }
43920
43963
  }
43921
43964
  for (; n < len; n++) {
43965
+ if (js_poll_interrupts(ctx))
43966
+ goto exception;
43922
43967
  int present = JS_TryGetPropertyInt64(ctx, obj, n, &val);
43923
43968
  if (present < 0)
43924
43969
  goto exception;
@@ -43948,6 +43993,7 @@ static JSValue js_array_lastIndexOf(JSContext *ctx, JSValueConst this_val,
43948
43993
  int64_t len, n;
43949
43994
  JSValue *arrp;
43950
43995
  uint32_t count;
43996
+ int present;
43951
43997
 
43952
43998
  obj = JS_ToObject(ctx, this_val);
43953
43999
  if (js_get_length64(ctx, &len, obj))
@@ -43968,7 +44014,9 @@ static JSValue js_array_lastIndexOf(JSContext *ctx, JSValueConst this_val,
43968
44014
  }
43969
44015
  }
43970
44016
  for (; n >= 0; n--) {
43971
- int present = JS_TryGetPropertyInt64(ctx, obj, n, &val);
44017
+ if (js_poll_interrupts(ctx))
44018
+ goto exception;
44019
+ present = JS_TryGetPropertyInt64(ctx, obj, n, &val);
43972
44020
  if (present < 0)
43973
44021
  goto exception;
43974
44022
  if (present) {
@@ -44031,6 +44079,8 @@ static JSValue js_array_find(JSContext *ctx, JSValueConst this_val,
44031
44079
 
44032
44080
  // TODO(bnoordhuis) add fast path for fast arrays
44033
44081
  for(; k != end; k += dir) {
44082
+ if (js_poll_interrupts(ctx))
44083
+ goto exception;
44034
44084
  index_val = js_int64(k);
44035
44085
  val = JS_GetPropertyValue(ctx, obj, index_val);
44036
44086
  if (JS_IsException(val))
@@ -44739,11 +44789,6 @@ static int js_array_cmp_generic(const void *a, const void *b, void *opaque) {
44739
44789
  return 0;
44740
44790
 
44741
44791
  if (psc->has_method) {
44742
- /* custom sort function is specified as returning 0 for identical
44743
- * objects: avoid method call overhead.
44744
- */
44745
- if (!memcmp(&ap->val, &bp->val, sizeof(ap->val)))
44746
- goto cmp_same;
44747
44792
  argv[0] = ap->val;
44748
44793
  argv[1] = bp->val;
44749
44794
  res = JS_Call(ctx, psc->method, JS_UNDEFINED, 2, argv);
@@ -44778,7 +44823,6 @@ static int js_array_cmp_generic(const void *a, const void *b, void *opaque) {
44778
44823
  }
44779
44824
  if (cmp != 0)
44780
44825
  return cmp;
44781
- cmp_same:
44782
44826
  /* make sort stable: compare array offsets */
44783
44827
  return (ap->pos > bp->pos) - (ap->pos < bp->pos);
44784
44828
 
@@ -52290,7 +52334,7 @@ static int js_proxy_has(JSContext *ctx, JSValueConst obj, JSAtom atom)
52290
52334
  int res;
52291
52335
  JSObject *p;
52292
52336
  JSValueConst args[2];
52293
- bool ret, res2;
52337
+ bool ret;
52294
52338
 
52295
52339
  s = get_proxy_method(ctx, &method, obj, JS_ATOM_has);
52296
52340
  if (!s)
@@ -52316,8 +52360,15 @@ static int js_proxy_has(JSContext *ctx, JSValueConst obj, JSAtom atom)
52316
52360
  if (res < 0)
52317
52361
  return -1;
52318
52362
  if (res) {
52319
- res2 = !(desc_flags & JS_PROP_CONFIGURABLE);
52320
- if (res2 || !p->extensible) {
52363
+ if (!(desc_flags & JS_PROP_CONFIGURABLE))
52364
+ goto inconsistent;
52365
+ /* must go through IsExtensible(): the target can be a proxy
52366
+ itself, whose isExtensible trap is observable */
52367
+ res = JS_IsExtensible(ctx, s->target);
52368
+ if (res < 0)
52369
+ return -1;
52370
+ if (!res) {
52371
+ inconsistent:
52321
52372
  JS_ThrowTypeError(ctx, "proxy: inconsistent has");
52322
52373
  return -1;
52323
52374
  }
@@ -52513,7 +52564,14 @@ static int js_proxy_get_own_property(JSContext *ctx, JSPropertyDescriptor *pdesc
52513
52564
  js_free_desc(ctx, &target_desc);
52514
52565
  if (JS_IsUndefined(trap_result_obj)) {
52515
52566
  if (target_desc_ret) {
52516
- if (!(target_desc.flags & JS_PROP_CONFIGURABLE) || !p->extensible)
52567
+ if (!(target_desc.flags & JS_PROP_CONFIGURABLE))
52568
+ goto fail;
52569
+ /* must go through IsExtensible(): the target can be a proxy
52570
+ itself, whose isExtensible trap is observable */
52571
+ res = JS_IsExtensible(ctx, s->target);
52572
+ if (res < 0)
52573
+ return -1;
52574
+ if (!res)
52517
52575
  goto fail;
52518
52576
  }
52519
52577
  ret = false;
@@ -52576,7 +52634,7 @@ static int js_proxy_define_own_property(JSContext *ctx, JSValueConst obj,
52576
52634
  {
52577
52635
  JSProxyData *s;
52578
52636
  JSValue method, ret1, prop_val, desc_val;
52579
- int res;
52637
+ int res, extensible_target;
52580
52638
  JSObject *p;
52581
52639
  JSValueConst args[3];
52582
52640
  JSPropertyDescriptor desc;
@@ -52620,11 +52678,19 @@ static int js_proxy_define_own_property(JSContext *ctx, JSValueConst obj,
52620
52678
  res = JS_GetOwnPropertyInternal(ctx, &desc, p, prop);
52621
52679
  if (res < 0)
52622
52680
  return -1;
52681
+ /* must go through IsExtensible(): the target can be a proxy itself, in
52682
+ which case its isExtensible trap is observable and may throw */
52683
+ extensible_target = JS_IsExtensible(ctx, s->target);
52684
+ if (extensible_target < 0) {
52685
+ if (res)
52686
+ js_free_desc(ctx, &desc);
52687
+ return -1;
52688
+ }
52623
52689
  setting_not_configurable = ((flags & (JS_PROP_HAS_CONFIGURABLE |
52624
52690
  JS_PROP_CONFIGURABLE)) ==
52625
52691
  JS_PROP_HAS_CONFIGURABLE);
52626
52692
  if (!res) {
52627
- if (!p->extensible || setting_not_configurable)
52693
+ if (!extensible_target || setting_not_configurable)
52628
52694
  goto fail;
52629
52695
  } else {
52630
52696
  if (!check_define_prop_flags(desc.flags, flags) ||
@@ -52753,6 +52819,12 @@ static int js_proxy_get_own_property_names(JSContext *ctx,
52753
52819
  prop_array = JS_CallFree(ctx, method, s->handler, 1, vc(&s->target));
52754
52820
  if (JS_IsException(prop_array))
52755
52821
  return -1;
52822
+ /* CreateListFromArrayLike() requires an object */
52823
+ if (JS_VALUE_GET_TAG(prop_array) != JS_TAG_OBJECT) {
52824
+ JS_FreeValue(ctx, prop_array);
52825
+ JS_ThrowTypeError(ctx, "proxy: ownKeys must return an object");
52826
+ return -1;
52827
+ }
52756
52828
  tab = NULL;
52757
52829
  len = 0;
52758
52830
  tab_size = 0;
@@ -60168,10 +60240,13 @@ static JSValue js_typed_array_with(JSContext *ctx, JSValueConst this_val,
60168
60240
  if (idx < 0)
60169
60241
  idx = len + idx;
60170
60242
 
60171
- val = JS_ToPrimitive(ctx, argv[1], HINT_NUMBER);
60243
+ if (p->class_id == JS_CLASS_BIG_INT64_ARRAY || p->class_id == JS_CLASS_BIG_UINT64_ARRAY) {
60244
+ val = JS_ToBigInt(ctx, argv[1]);
60245
+ } else {
60246
+ val = JS_ToNumber(ctx, argv[1]);
60247
+ }
60172
60248
  if (JS_IsException(val))
60173
60249
  return JS_EXCEPTION;
60174
-
60175
60250
  /* re-validate after user code (spec step 9: IsValidIntegerIndex) */
60176
60251
  if (typed_array_is_oob(p)) {
60177
60252
  JS_FreeValue(ctx, val);
@@ -63827,7 +63902,7 @@ int JS_AddIntrinsicDOMException(JSContext *ctx)
63827
63902
  }
63828
63903
  JS_DefinePropertyValue(ctx, ctx->global_obj, JS_ATOM_DOMException, ctor,
63829
63904
  JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
63830
- ctx->class_proto[JS_CLASS_DOM_EXCEPTION] = proto;
63905
+ set_value(ctx, &ctx->class_proto[JS_CLASS_DOM_EXCEPTION], proto);
63831
63906
  return 0;
63832
63907
  }
63833
63908
  /* base64 */
@@ -64891,6 +64966,10 @@ uintptr_t js_std_cmd(int cmd, ...) {
64891
64966
  if (JS_IsString(*pv))
64892
64967
  rv = JS_VALUE_GET_STRING(*pv)->kind;
64893
64968
  break;
64969
+ case 4: // GetShapeHashCount
64970
+ rt = va_arg(ap, JSRuntime *);
64971
+ rv = rt->shape_hash_count;
64972
+ break;
64894
64973
  default:
64895
64974
  rv = -1;
64896
64975
  }
@@ -1469,7 +1469,7 @@ JS_EXTERN int JS_SetModuleExportList(JSContext *ctx, JSModuleDef *m,
1469
1469
 
1470
1470
  #define QJS_VERSION_MAJOR 0
1471
1471
  #define QJS_VERSION_MINOR 16
1472
- #define QJS_VERSION_PATCH 0
1472
+ #define QJS_VERSION_PATCH 2
1473
1473
  #define QJS_VERSION_SUFFIX ""
1474
1474
 
1475
1475
  JS_EXTERN const char* JS_GetVersion(void);