quickjs 0.10.0 → 0.11.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.
@@ -136,11 +136,18 @@ typedef struct {
136
136
  JSValue on_message_func;
137
137
  } JSWorkerMessageHandler;
138
138
 
139
+ typedef struct {
140
+ struct list_head link;
141
+ JSValue promise;
142
+ JSValue reason;
143
+ } JSRejectedPromiseEntry;
144
+
139
145
  typedef struct JSThreadState {
140
146
  struct list_head os_rw_handlers; /* list of JSOSRWHandler.link */
141
147
  struct list_head os_signal_handlers; /* list JSOSSignalHandler.link */
142
148
  struct list_head os_timers; /* list of JSOSTimer.link */
143
149
  struct list_head port_list; /* list of JSWorkerMessageHandler.link */
150
+ struct list_head rejected_promise_list; /* list of JSRejectedPromiseEntry.link */
144
151
  int eval_script_recurse; /* only used in the main thread */
145
152
  int next_timer_id; /* for setTimeout() */
146
153
  /* not used in the main thread */
@@ -160,6 +167,7 @@ static BOOL my_isdigit(int c)
160
167
  return (c >= '0' && c <= '9');
161
168
  }
162
169
 
170
+ /* XXX: use 'o' and 'O' for object using JS_PrintValue() ? */
163
171
  static JSValue js_printf_internal(JSContext *ctx,
164
172
  int argc, JSValueConst *argv, FILE *fp)
165
173
  {
@@ -583,17 +591,101 @@ int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val,
583
591
  return 0;
584
592
  }
585
593
 
586
- JSModuleDef *js_module_loader(JSContext *ctx,
587
- const char *module_name, void *opaque)
594
+ static int json_module_init(JSContext *ctx, JSModuleDef *m)
595
+ {
596
+ JSValue val;
597
+ val = JS_GetModulePrivateValue(ctx, m);
598
+ JS_SetModuleExport(ctx, m, "default", val);
599
+ return 0;
600
+ }
601
+
602
+ static JSModuleDef *create_json_module(JSContext *ctx, const char *module_name, JSValue val)
588
603
  {
589
604
  JSModuleDef *m;
605
+ m = JS_NewCModule(ctx, module_name, json_module_init);
606
+ if (!m) {
607
+ JS_FreeValue(ctx, val);
608
+ return NULL;
609
+ }
610
+ /* only export the "default" symbol which will contain the JSON object */
611
+ JS_AddModuleExport(ctx, m, "default");
612
+ JS_SetModulePrivateValue(ctx, m, val);
613
+ return m;
614
+ }
615
+
616
+ /* in order to conform with the specification, only the keys should be
617
+ tested and not the associated values. */
618
+ int js_module_check_attributes(JSContext *ctx, void *opaque,
619
+ JSValueConst attributes)
620
+ {
621
+ JSPropertyEnum *tab;
622
+ uint32_t i, len;
623
+ int ret;
624
+ const char *cstr;
625
+ size_t cstr_len;
626
+
627
+ if (JS_GetOwnPropertyNames(ctx, &tab, &len, attributes, JS_GPN_ENUM_ONLY | JS_GPN_STRING_MASK))
628
+ return -1;
629
+ ret = 0;
630
+ for(i = 0; i < len; i++) {
631
+ cstr = JS_AtomToCStringLen(ctx, &cstr_len, tab[i].atom);
632
+ if (!cstr) {
633
+ ret = -1;
634
+ break;
635
+ }
636
+ if (!(cstr_len == 4 && !memcmp(cstr, "type", cstr_len))) {
637
+ JS_ThrowTypeError(ctx, "import attribute '%s' is not supported", cstr);
638
+ ret = -1;
639
+ }
640
+ JS_FreeCString(ctx, cstr);
641
+ if (ret)
642
+ break;
643
+ }
644
+ JS_FreePropertyEnum(ctx, tab, len);
645
+ return ret;
646
+ }
647
+
648
+ /* return > 0 if the attributes indicate a JSON module */
649
+ int js_module_test_json(JSContext *ctx, JSValueConst attributes)
650
+ {
651
+ JSValue str;
652
+ const char *cstr;
653
+ size_t len;
654
+ BOOL res;
655
+
656
+ if (JS_IsUndefined(attributes))
657
+ return FALSE;
658
+ str = JS_GetPropertyStr(ctx, attributes, "type");
659
+ if (!JS_IsString(str))
660
+ return FALSE;
661
+ cstr = JS_ToCStringLen(ctx, &len, str);
662
+ JS_FreeValue(ctx, str);
663
+ if (!cstr)
664
+ return FALSE;
665
+ /* XXX: raise an error if unknown type ? */
666
+ if (len == 4 && !memcmp(cstr, "json", len)) {
667
+ res = 1;
668
+ } else if (len == 5 && !memcmp(cstr, "json5", len)) {
669
+ res = 2;
670
+ } else {
671
+ res = 0;
672
+ }
673
+ JS_FreeCString(ctx, cstr);
674
+ return res;
675
+ }
590
676
 
677
+ JSModuleDef *js_module_loader(JSContext *ctx,
678
+ const char *module_name, void *opaque,
679
+ JSValueConst attributes)
680
+ {
681
+ JSModuleDef *m;
682
+ int res;
683
+
591
684
  if (has_suffix(module_name, ".so")) {
592
685
  m = js_module_loader_so(ctx, module_name);
593
686
  } else {
594
687
  size_t buf_len;
595
688
  uint8_t *buf;
596
- JSValue func_val;
597
689
 
598
690
  buf = js_load_file(ctx, &buf_len, module_name);
599
691
  if (!buf) {
@@ -601,18 +693,36 @@ JSModuleDef *js_module_loader(JSContext *ctx,
601
693
  module_name);
602
694
  return NULL;
603
695
  }
604
-
605
- /* compile the module */
606
- func_val = JS_Eval(ctx, (char *)buf, buf_len, module_name,
607
- JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
608
- js_free(ctx, buf);
609
- if (JS_IsException(func_val))
610
- return NULL;
611
- /* XXX: could propagate the exception */
612
- js_module_set_import_meta(ctx, func_val, TRUE, FALSE);
613
- /* the module is already referenced, so we must free it */
614
- m = JS_VALUE_GET_PTR(func_val);
615
- JS_FreeValue(ctx, func_val);
696
+ res = js_module_test_json(ctx, attributes);
697
+ if (has_suffix(module_name, ".json") || res > 0) {
698
+ /* compile as JSON or JSON5 depending on "type" */
699
+ JSValue val;
700
+ int flags;
701
+ if (res == 2)
702
+ flags = JS_PARSE_JSON_EXT;
703
+ else
704
+ flags = 0;
705
+ val = JS_ParseJSON2(ctx, (char *)buf, buf_len, module_name, flags);
706
+ js_free(ctx, buf);
707
+ if (JS_IsException(val))
708
+ return NULL;
709
+ m = create_json_module(ctx, module_name, val);
710
+ if (!m)
711
+ return NULL;
712
+ } else {
713
+ JSValue func_val;
714
+ /* compile the module */
715
+ func_val = JS_Eval(ctx, (char *)buf, buf_len, module_name,
716
+ JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
717
+ js_free(ctx, buf);
718
+ if (JS_IsException(func_val))
719
+ return NULL;
720
+ /* XXX: could propagate the exception */
721
+ js_module_set_import_meta(ctx, func_val, TRUE, FALSE);
722
+ /* the module is already referenced, so we must free it */
723
+ m = JS_VALUE_GET_PTR(func_val);
724
+ JS_FreeValue(ctx, func_val);
725
+ }
616
726
  }
617
727
  return m;
618
728
  }
@@ -804,7 +914,7 @@ static JSValue js_evalScript(JSContext *ctx, JSValueConst this_val,
804
914
  /* convert the uncatchable "interrupted" error into a normal error
805
915
  so that it can be caught by the REPL */
806
916
  if (JS_IsException(ret))
807
- JS_ResetUncatchableError(ctx);
917
+ JS_SetUncatchableException(ctx, FALSE);
808
918
  }
809
919
  return ret;
810
920
  }
@@ -1083,6 +1193,19 @@ static JSValue js_std_file_printf(JSContext *ctx, JSValueConst this_val,
1083
1193
  return js_printf_internal(ctx, argc, argv, f);
1084
1194
  }
1085
1195
 
1196
+ static void js_print_value_write(void *opaque, const char *buf, size_t len)
1197
+ {
1198
+ FILE *fo = opaque;
1199
+ fwrite(buf, 1, len, fo);
1200
+ }
1201
+
1202
+ static JSValue js_std_file_printObject(JSContext *ctx, JSValueConst this_val,
1203
+ int argc, JSValueConst *argv)
1204
+ {
1205
+ JS_PrintValue(ctx, js_print_value_write, stdout, argv[0], NULL);
1206
+ return JS_UNDEFINED;
1207
+ }
1208
+
1086
1209
  static JSValue js_std_file_flush(JSContext *ctx, JSValueConst this_val,
1087
1210
  int argc, JSValueConst *argv)
1088
1211
  {
@@ -1540,6 +1663,7 @@ static const JSCFunctionListEntry js_std_funcs[] = {
1540
1663
  JS_PROP_INT32_DEF("SEEK_CUR", SEEK_CUR, JS_PROP_CONFIGURABLE ),
1541
1664
  JS_PROP_INT32_DEF("SEEK_END", SEEK_END, JS_PROP_CONFIGURABLE ),
1542
1665
  JS_OBJECT_DEF("Error", js_std_error_props, countof(js_std_error_props), JS_PROP_CONFIGURABLE),
1666
+ JS_CFUNC_DEF("__printObject", 1, js_std_file_printObject ),
1543
1667
  };
1544
1668
 
1545
1669
  static const JSCFunctionListEntry js_std_file_proto_funcs[] = {
@@ -2916,9 +3040,7 @@ static char **build_envp(JSContext *ctx, JSValueConst obj)
2916
3040
  JS_FreeCString(ctx, str);
2917
3041
  }
2918
3042
  done:
2919
- for(i = 0; i < len; i++)
2920
- JS_FreeAtom(ctx, tab[i].atom);
2921
- js_free(ctx, tab);
3043
+ JS_FreePropertyEnum(ctx, tab, len);
2922
3044
  return envp;
2923
3045
  fail:
2924
3046
  if (envp) {
@@ -3458,7 +3580,7 @@ static void *worker_func(void *opaque)
3458
3580
  JS_SetStripInfo(rt, args->strip_flags);
3459
3581
  js_std_init_handlers(rt);
3460
3582
 
3461
- JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
3583
+ JS_SetModuleLoaderFunc2(rt, NULL, js_module_loader, js_module_check_attributes, NULL);
3462
3584
 
3463
3585
  /* set the pipe to communicate with the parent */
3464
3586
  ts = JS_GetRuntimeOpaque(rt);
@@ -3891,17 +4013,23 @@ static JSValue js_print(JSContext *ctx, JSValueConst this_val,
3891
4013
  int argc, JSValueConst *argv)
3892
4014
  {
3893
4015
  int i;
3894
- const char *str;
3895
- size_t len;
3896
-
4016
+ JSValueConst v;
4017
+
3897
4018
  for(i = 0; i < argc; i++) {
3898
4019
  if (i != 0)
3899
4020
  putchar(' ');
3900
- str = JS_ToCStringLen(ctx, &len, argv[i]);
3901
- if (!str)
3902
- return JS_EXCEPTION;
3903
- fwrite(str, 1, len, stdout);
3904
- JS_FreeCString(ctx, str);
4021
+ v = argv[i];
4022
+ if (JS_IsString(v)) {
4023
+ const char *str;
4024
+ size_t len;
4025
+ str = JS_ToCStringLen(ctx, &len, v);
4026
+ if (!str)
4027
+ return JS_EXCEPTION;
4028
+ fwrite(str, 1, len, stdout);
4029
+ JS_FreeCString(ctx, str);
4030
+ } else {
4031
+ JS_PrintValue(ctx, js_print_value_write, stdout, v, NULL);
4032
+ }
3905
4033
  }
3906
4034
  putchar('\n');
3907
4035
  return JS_UNDEFINED;
@@ -3965,6 +4093,7 @@ void js_std_init_handlers(JSRuntime *rt)
3965
4093
  init_list_head(&ts->os_signal_handlers);
3966
4094
  init_list_head(&ts->os_timers);
3967
4095
  init_list_head(&ts->port_list);
4096
+ init_list_head(&ts->rejected_promise_list);
3968
4097
  ts->next_timer_id = 1;
3969
4098
 
3970
4099
  JS_SetRuntimeOpaque(rt, ts);
@@ -4002,6 +4131,13 @@ void js_std_free_handlers(JSRuntime *rt)
4002
4131
  free_timer(rt, th);
4003
4132
  }
4004
4133
 
4134
+ list_for_each_safe(el, el1, &ts->rejected_promise_list) {
4135
+ JSRejectedPromiseEntry *rp = list_entry(el, JSRejectedPromiseEntry, link);
4136
+ JS_FreeValueRT(rt, rp->promise);
4137
+ JS_FreeValueRT(rt, rp->reason);
4138
+ free(rp);
4139
+ }
4140
+
4005
4141
  #ifdef USE_WORKER
4006
4142
  /* XXX: free port_list ? */
4007
4143
  js_free_message_pipe(ts->recv_pipe);
@@ -4012,33 +4148,10 @@ void js_std_free_handlers(JSRuntime *rt)
4012
4148
  JS_SetRuntimeOpaque(rt, NULL); /* fail safe */
4013
4149
  }
4014
4150
 
4015
- static void js_dump_obj(JSContext *ctx, FILE *f, JSValueConst val)
4016
- {
4017
- const char *str;
4018
-
4019
- str = JS_ToCString(ctx, val);
4020
- if (str) {
4021
- fprintf(f, "%s\n", str);
4022
- JS_FreeCString(ctx, str);
4023
- } else {
4024
- fprintf(f, "[exception]\n");
4025
- }
4026
- }
4027
-
4028
4151
  static void js_std_dump_error1(JSContext *ctx, JSValueConst exception_val)
4029
4152
  {
4030
- JSValue val;
4031
- BOOL is_error;
4032
-
4033
- is_error = JS_IsError(ctx, exception_val);
4034
- js_dump_obj(ctx, stderr, exception_val);
4035
- if (is_error) {
4036
- val = JS_GetPropertyStr(ctx, exception_val, "stack");
4037
- if (!JS_IsUndefined(val)) {
4038
- js_dump_obj(ctx, stderr, val);
4039
- }
4040
- JS_FreeValue(ctx, val);
4041
- }
4153
+ JS_PrintValue(ctx, js_print_value_write, stderr, exception_val, NULL);
4154
+ fputc('\n', stderr);
4042
4155
  }
4043
4156
 
4044
4157
  void js_std_dump_error(JSContext *ctx)
@@ -4050,13 +4163,66 @@ void js_std_dump_error(JSContext *ctx)
4050
4163
  JS_FreeValue(ctx, exception_val);
4051
4164
  }
4052
4165
 
4166
+ static JSRejectedPromiseEntry *find_rejected_promise(JSContext *ctx, JSThreadState *ts,
4167
+ JSValueConst promise)
4168
+ {
4169
+ struct list_head *el;
4170
+
4171
+ list_for_each(el, &ts->rejected_promise_list) {
4172
+ JSRejectedPromiseEntry *rp = list_entry(el, JSRejectedPromiseEntry, link);
4173
+ if (JS_SameValue(ctx, rp->promise, promise))
4174
+ return rp;
4175
+ }
4176
+ return NULL;
4177
+ }
4178
+
4053
4179
  void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise,
4054
4180
  JSValueConst reason,
4055
4181
  BOOL is_handled, void *opaque)
4056
4182
  {
4183
+ JSRuntime *rt = JS_GetRuntime(ctx);
4184
+ JSThreadState *ts = JS_GetRuntimeOpaque(rt);
4185
+ JSRejectedPromiseEntry *rp;
4186
+
4057
4187
  if (!is_handled) {
4058
- fprintf(stderr, "Possibly unhandled promise rejection: ");
4059
- js_std_dump_error1(ctx, reason);
4188
+ /* add a new entry if needed */
4189
+ rp = find_rejected_promise(ctx, ts, promise);
4190
+ if (!rp) {
4191
+ rp = malloc(sizeof(*rp));
4192
+ if (rp) {
4193
+ rp->promise = JS_DupValue(ctx, promise);
4194
+ rp->reason = JS_DupValue(ctx, reason);
4195
+ list_add_tail(&rp->link, &ts->rejected_promise_list);
4196
+ }
4197
+ }
4198
+ } else {
4199
+ /* the rejection is handled, so the entry can be removed if present */
4200
+ rp = find_rejected_promise(ctx, ts, promise);
4201
+ if (rp) {
4202
+ JS_FreeValue(ctx, rp->promise);
4203
+ JS_FreeValue(ctx, rp->reason);
4204
+ list_del(&rp->link);
4205
+ free(rp);
4206
+ }
4207
+ }
4208
+ }
4209
+
4210
+ /* check if there are pending promise rejections. It must be done
4211
+ asynchrously in case a rejected promise is handled later. Currently
4212
+ we do it once the application is about to sleep. It could be done
4213
+ more often if needed. */
4214
+ static void js_std_promise_rejection_check(JSContext *ctx)
4215
+ {
4216
+ JSRuntime *rt = JS_GetRuntime(ctx);
4217
+ JSThreadState *ts = JS_GetRuntimeOpaque(rt);
4218
+ struct list_head *el;
4219
+
4220
+ if (unlikely(!list_empty(&ts->rejected_promise_list))) {
4221
+ list_for_each(el, &ts->rejected_promise_list) {
4222
+ JSRejectedPromiseEntry *rp = list_entry(el, JSRejectedPromiseEntry, link);
4223
+ fprintf(stderr, "Possibly unhandled promise rejection: ");
4224
+ js_std_dump_error1(ctx, rp->reason);
4225
+ }
4060
4226
  exit(1);
4061
4227
  }
4062
4228
  }
@@ -4064,21 +4230,21 @@ void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise,
4064
4230
  /* main loop which calls the user JS callbacks */
4065
4231
  void js_std_loop(JSContext *ctx)
4066
4232
  {
4067
- JSContext *ctx1;
4068
4233
  int err;
4069
4234
 
4070
4235
  for(;;) {
4071
4236
  /* execute the pending jobs */
4072
4237
  for(;;) {
4073
- err = JS_ExecutePendingJob(JS_GetRuntime(ctx), &ctx1);
4238
+ err = JS_ExecutePendingJob(JS_GetRuntime(ctx), NULL);
4074
4239
  if (err <= 0) {
4075
- if (err < 0) {
4076
- js_std_dump_error(ctx1);
4077
- }
4240
+ if (err < 0)
4241
+ js_std_dump_error(ctx);
4078
4242
  break;
4079
4243
  }
4080
4244
  }
4081
4245
 
4246
+ js_std_promise_rejection_check(ctx);
4247
+
4082
4248
  if (!os_poll_func || os_poll_func(ctx))
4083
4249
  break;
4084
4250
  }
@@ -4103,14 +4269,17 @@ JSValue js_std_await(JSContext *ctx, JSValue obj)
4103
4269
  JS_FreeValue(ctx, obj);
4104
4270
  break;
4105
4271
  } else if (state == JS_PROMISE_PENDING) {
4106
- JSContext *ctx1;
4107
4272
  int err;
4108
- err = JS_ExecutePendingJob(JS_GetRuntime(ctx), &ctx1);
4273
+ err = JS_ExecutePendingJob(JS_GetRuntime(ctx), NULL);
4109
4274
  if (err < 0) {
4110
- js_std_dump_error(ctx1);
4275
+ js_std_dump_error(ctx);
4276
+ }
4277
+ if (err == 0) {
4278
+ js_std_promise_rejection_check(ctx);
4279
+
4280
+ if (os_poll_func)
4281
+ os_poll_func(ctx);
4111
4282
  }
4112
- if (os_poll_func)
4113
- os_poll_func(ctx);
4114
4283
  } else {
4115
4284
  /* not a promise */
4116
4285
  ret = obj;
@@ -4131,6 +4300,7 @@ void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len,
4131
4300
  if (JS_VALUE_GET_TAG(obj) == JS_TAG_MODULE) {
4132
4301
  js_module_set_import_meta(ctx, obj, FALSE, FALSE);
4133
4302
  }
4303
+ JS_FreeValue(ctx, obj);
4134
4304
  } else {
4135
4305
  if (JS_VALUE_GET_TAG(obj) == JS_TAG_MODULE) {
4136
4306
  if (JS_ResolveModule(ctx, obj) < 0) {
@@ -4151,3 +4321,22 @@ void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len,
4151
4321
  JS_FreeValue(ctx, val);
4152
4322
  }
4153
4323
  }
4324
+
4325
+ void js_std_eval_binary_json_module(JSContext *ctx,
4326
+ const uint8_t *buf, size_t buf_len,
4327
+ const char *module_name)
4328
+ {
4329
+ JSValue obj;
4330
+ JSModuleDef *m;
4331
+
4332
+ obj = JS_ReadObject(ctx, buf, buf_len, 0);
4333
+ if (JS_IsException(obj))
4334
+ goto exception;
4335
+ m = create_json_module(ctx, module_name, obj);
4336
+ if (!m) {
4337
+ exception:
4338
+ js_std_dump_error(ctx);
4339
+ exit(1);
4340
+ }
4341
+ }
4342
+
@@ -44,10 +44,16 @@ void js_std_dump_error(JSContext *ctx);
44
44
  uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename);
45
45
  int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val,
46
46
  JS_BOOL use_realpath, JS_BOOL is_main);
47
+ int js_module_test_json(JSContext *ctx, JSValueConst attributes);
48
+ int js_module_check_attributes(JSContext *ctx, void *opaque, JSValueConst attributes);
47
49
  JSModuleDef *js_module_loader(JSContext *ctx,
48
- const char *module_name, void *opaque);
50
+ const char *module_name, void *opaque,
51
+ JSValueConst attributes);
49
52
  void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len,
50
53
  int flags);
54
+ void js_std_eval_binary_json_module(JSContext *ctx,
55
+ const uint8_t *buf, size_t buf_len,
56
+ const char *module_name);
51
57
  void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise,
52
58
  JSValueConst reason,
53
59
  JS_BOOL is_handled, void *opaque);
@@ -121,7 +121,7 @@ DEF( apply_eval, 3, 2, 1, u16) /* func array -> ret_eval */
121
121
  DEF( regexp, 1, 2, 1, none) /* create a RegExp object from the pattern and a
122
122
  bytecode string */
123
123
  DEF( get_super, 1, 1, 1, none)
124
- DEF( import, 1, 1, 1, none) /* dynamic module import */
124
+ DEF( import, 1, 2, 1, none) /* dynamic module import */
125
125
 
126
126
  DEF( check_var, 5, 0, 1, atom) /* check if a variable exists */
127
127
  DEF( get_var_undef, 5, 0, 1, atom) /* push undefined if the variable does not exist */
@@ -144,6 +144,7 @@ DEF( put_private_field, 1, 3, 0, none) /* obj value prop -> */
144
144
  DEF(define_private_field, 1, 3, 1, none) /* obj prop value -> obj */
145
145
  DEF( get_array_el, 1, 2, 1, none)
146
146
  DEF( get_array_el2, 1, 2, 2, none) /* obj prop -> obj value */
147
+ DEF( get_array_el3, 1, 2, 3, none) /* obj prop -> obj prop1 value */
147
148
  DEF( put_array_el, 1, 3, 0, none)
148
149
  DEF(get_super_value, 1, 3, 1, none) /* this obj prop -> value */
149
150
  DEF(put_super_value, 1, 4, 0, none) /* this obj prop value -> */
@@ -189,7 +190,6 @@ DEF( nip_catch, 1, 2, 1, none) /* catch ... a -> a */
189
190
  DEF( to_object, 1, 1, 1, none)
190
191
  //DEF( to_string, 1, 1, 1, none)
191
192
  DEF( to_propkey, 1, 1, 1, none)
192
- DEF( to_propkey2, 1, 2, 2, none)
193
193
 
194
194
  DEF( with_get_var, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */
195
195
  DEF( with_put_var, 10, 2, 1, atom_label_u8) /* must be in the same order as scope_xxx */