@scriptc/runtime 0.0.21 → 0.0.22
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.
- package/package.json +1 -1
- package/src/scr_assert.c +23 -0
- package/src/scr_bytes.c +7 -0
- package/src/scr_dyn_invoke.c +58 -6
- package/src/scr_fetch.c +5624 -123
- package/src/scr_fetch_curl.c +21 -9
- package/src/scr_http.c +13 -0
- package/src/scr_inspect.c +6 -0
- package/src/scr_island.c +19 -0
- package/src/scr_json.c +327 -7
- package/src/scr_runtime.h +124 -17
- package/src/scr_tls.c +15 -11
- package/src/scr_tls_ca.c +35 -8
- package/src/scr_url.c +103 -15
- package/src/scr_web.c +77 -1
- package/vendor/README.md +4 -4
package/package.json
CHANGED
package/src/scr_assert.c
CHANGED
|
@@ -444,6 +444,8 @@ static bool scr_assert_dyn_same_value(const ScrDyn *a, const ScrDyn *b) {
|
|
|
444
444
|
* === — exact for SameValue too, since wrap-time scalar
|
|
445
445
|
* normalization leaves only reference kinds behind. */
|
|
446
446
|
return a == b || scr_dyn_jsval_ops()->strict_eq(a->v.jsval.cell, b->v.jsval.cell);
|
|
447
|
+
case SCR_DYN_TYPED_REF:
|
|
448
|
+
return scr_dyn_strict_eq(a, b);
|
|
447
449
|
default:
|
|
448
450
|
return a == b; /* ARR/OBJ/BYTES: node identity */
|
|
449
451
|
}
|
|
@@ -459,6 +461,18 @@ static bool scr_assert_dyn_same_value(const ScrDyn *a, const ScrDyn *b) {
|
|
|
459
461
|
* memo here where Node carries one (documented divergence). */
|
|
460
462
|
static bool scr_assert_dyn_deep_eq(const ScrDyn *a, const ScrDyn *b) {
|
|
461
463
|
if (a == b) return true;
|
|
464
|
+
if (a->kind == SCR_DYN_TYPED_REF || b->kind == SCR_DYN_TYPED_REF) {
|
|
465
|
+
ScrDyn *ma = a->kind == SCR_DYN_TYPED_REF
|
|
466
|
+
? scr_dyn_typed_ref_materialize(a)
|
|
467
|
+
: scr_dyn_retain((ScrDyn *)a);
|
|
468
|
+
ScrDyn *mb = b->kind == SCR_DYN_TYPED_REF
|
|
469
|
+
? scr_dyn_typed_ref_materialize(b)
|
|
470
|
+
: scr_dyn_retain((ScrDyn *)b);
|
|
471
|
+
bool same = scr_assert_dyn_deep_eq(ma, mb);
|
|
472
|
+
scr_dyn_release(ma);
|
|
473
|
+
scr_dyn_release(mb);
|
|
474
|
+
return same;
|
|
475
|
+
}
|
|
462
476
|
if (a->kind != b->kind) {
|
|
463
477
|
/* A MIXED comparison with an island side (wrapped engine object vs
|
|
464
478
|
* dyn data): Node walks both structurally — a plain `false` would
|
|
@@ -524,6 +538,8 @@ static bool scr_assert_dyn_deep_eq(const ScrDyn *a, const ScrDyn *b) {
|
|
|
524
538
|
if (scr_dyn_jsval_ops()->strict_eq(a->v.jsval.cell, b->v.jsval.cell)) return true;
|
|
525
539
|
scr_dyn_isl_fence(a, "deepStrictEqual");
|
|
526
540
|
return false;
|
|
541
|
+
case SCR_DYN_TYPED_REF:
|
|
542
|
+
return false; /* both mixed and same-kind capsules returned above */
|
|
527
543
|
}
|
|
528
544
|
return false; /* unreachable */
|
|
529
545
|
}
|
|
@@ -684,6 +700,12 @@ static void scr_assert_cf_value(ScrAssertBuf *b, const ScrDyn *d, size_t indent,
|
|
|
684
700
|
ab_cstr(b, "[island value]");
|
|
685
701
|
return;
|
|
686
702
|
}
|
|
703
|
+
case SCR_DYN_TYPED_REF: {
|
|
704
|
+
ScrDyn *materialized = scr_dyn_typed_ref_materialize(d);
|
|
705
|
+
scr_assert_cf_value(b, materialized, indent, depth);
|
|
706
|
+
scr_dyn_release(materialized);
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
687
709
|
case SCR_DYN_OBJ: {
|
|
688
710
|
/* The null-proto dictionary renders with Node's prefix in the
|
|
689
711
|
* failure diff too (assertion_error.js inspects both sides). */
|
|
@@ -928,6 +950,7 @@ static bool scr_assert_print_myers(ScrAssertBuf *b, const ScrDiffOp *diff, size_
|
|
|
928
950
|
static bool scr_assert_dyn_is_object(const ScrDyn *d) {
|
|
929
951
|
return d->kind == SCR_DYN_ARR || d->kind == SCR_DYN_OBJ || d->kind == SCR_DYN_BYTES ||
|
|
930
952
|
d->kind == SCR_DYN_HANDLE || d->kind == SCR_DYN_PROMISE ||
|
|
953
|
+
d->kind == SCR_DYN_TYPED_REF ||
|
|
931
954
|
scr_dyn_isl_typeof_is(d, "object"); /* engine-held: the engine's typeof */
|
|
932
955
|
}
|
|
933
956
|
|
package/src/scr_bytes.c
CHANGED
|
@@ -86,6 +86,13 @@ void scr_bytes_release_v(void *b) { scr_bytes_release((ScrBytes *)b); }
|
|
|
86
86
|
|
|
87
87
|
double scr_bytes_len(const ScrBytes *b) { return (double)b->len; }
|
|
88
88
|
|
|
89
|
+
void scr_bytes_copy_contents(ScrBytes *dst, const ScrBytes *src) {
|
|
90
|
+
if (dst->elem != src->elem || dst->len != src->len) {
|
|
91
|
+
scr_trap("scriptc: typed array snapshot shape changed\n");
|
|
92
|
+
}
|
|
93
|
+
memcpy(dst->data, src->data, dst->len * scr_bytes_elem_size(dst->elem));
|
|
94
|
+
}
|
|
95
|
+
|
|
89
96
|
double scr_bytes_byte_len(const ScrBytes *b) {
|
|
90
97
|
return (double)(b->len * scr_bytes_elem_size(b->elem));
|
|
91
98
|
}
|
package/src/scr_dyn_invoke.c
CHANGED
|
@@ -119,6 +119,12 @@ static void scr_dyn_display_buf(ScrJsonBuf *b, const ScrDyn *d) {
|
|
|
119
119
|
* pending and appends nothing — the loud path). */
|
|
120
120
|
scr_dyn_isl_tostr_buf(b, d);
|
|
121
121
|
return;
|
|
122
|
+
case SCR_DYN_TYPED_REF: {
|
|
123
|
+
ScrDyn *materialized = scr_dyn_typed_ref_materialize(d);
|
|
124
|
+
scr_dyn_display_buf(b, materialized);
|
|
125
|
+
scr_dyn_release(materialized);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
122
128
|
}
|
|
123
129
|
}
|
|
124
130
|
|
|
@@ -306,6 +312,13 @@ static bool dyn_arr_proto_unimpl(const char *m) {
|
|
|
306
312
|
for (size_t i = 0; names[i]; i++) if (dyn_name_is(m, names[i])) return true;
|
|
307
313
|
return false;
|
|
308
314
|
}
|
|
315
|
+
static bool dyn_arr_proto_mutates(const char *m) {
|
|
316
|
+
static const char *names[] = {
|
|
317
|
+
"push", "pop", "shift", "unshift", "reverse", "sort", NULL
|
|
318
|
+
};
|
|
319
|
+
for (size_t i = 0; names[i]; i++) if (dyn_name_is(m, names[i])) return true;
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
309
322
|
static bool dyn_bytes_proto_real(const char *m) {
|
|
310
323
|
static const char *names[] = { "slice", "at", "indexOf", "lastIndexOf", "includes", "join",
|
|
311
324
|
"forEach", "map", "filter", "some", "every", "find", "findIndex", "reverse", "fill", "set",
|
|
@@ -315,7 +328,19 @@ static bool dyn_bytes_proto_real(const char *m) {
|
|
|
315
328
|
return false;
|
|
316
329
|
}
|
|
317
330
|
|
|
318
|
-
ScrDyn *
|
|
331
|
+
static ScrDyn *scr_dyn_invoke_impl(
|
|
332
|
+
ScrDyn *recv, const char *method, ScrDyn *const *args, size_t argc,
|
|
333
|
+
const char *what, ScrDyn *callback_recv);
|
|
334
|
+
|
|
335
|
+
ScrDyn *scr_dyn_invoke(ScrDyn *recv, const char *method,
|
|
336
|
+
ScrDyn *const *args, size_t argc,
|
|
337
|
+
const char *what) {
|
|
338
|
+
return scr_dyn_invoke_impl(recv, method, args, argc, what, NULL);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
static ScrDyn *scr_dyn_invoke_impl(
|
|
342
|
+
ScrDyn *recv, const char *method, ScrDyn *const *args, size_t argc,
|
|
343
|
+
const char *what, ScrDyn *callback_recv) {
|
|
319
344
|
if (recv->kind == SCR_DYN_UNDEF || recv->kind == SCR_DYN_NULL) {
|
|
320
345
|
ScrJsonBuf b;
|
|
321
346
|
scr_jb_init(&b);
|
|
@@ -347,6 +372,26 @@ ScrDyn *scr_dyn_invoke(ScrDyn *recv, const char *method, ScrDyn *const *args, si
|
|
|
347
372
|
return scr_dyn_jsval_ops()->invoke(recv->v.jsval.cell, method, args, argc, what);
|
|
348
373
|
}
|
|
349
374
|
|
|
375
|
+
/* Live Web-boundary capsules expose the prototype of their materialized
|
|
376
|
+
* value. Run the ordinary dispatch against the stable snapshot, then
|
|
377
|
+
* commit successful mutations back into the original static value.
|
|
378
|
+
* Mutators such as reverse/sort return their receiver, so translate that
|
|
379
|
+
* snapshot identity back to the externally visible capsule. */
|
|
380
|
+
if (recv->kind == SCR_DYN_TYPED_REF) {
|
|
381
|
+
ScrDyn *materialized = scr_dyn_typed_ref_materialize(recv);
|
|
382
|
+
bool mutates = materialized->kind == SCR_DYN_ARR &&
|
|
383
|
+
dyn_arr_proto_mutates(method);
|
|
384
|
+
ScrDyn *result = scr_dyn_invoke_impl(
|
|
385
|
+
materialized, method, args, argc, what, recv);
|
|
386
|
+
if (mutates && !scr_exc_pending()) scr_dyn_typed_ref_commit(recv);
|
|
387
|
+
if (result == materialized) {
|
|
388
|
+
scr_dyn_release(result);
|
|
389
|
+
result = scr_dyn_retain(recv);
|
|
390
|
+
}
|
|
391
|
+
scr_dyn_release(materialized);
|
|
392
|
+
return result;
|
|
393
|
+
}
|
|
394
|
+
|
|
350
395
|
/* OBJ: the own member calls (own properties shadow prototypes in JS
|
|
351
396
|
* too); anything else is Node's is-not-a-function. */
|
|
352
397
|
if (recv->kind == SCR_DYN_OBJ) {
|
|
@@ -556,11 +601,17 @@ ScrDyn *scr_dyn_invoke(ScrDyn *recv, const char *method, ScrDyn *const *args, si
|
|
|
556
601
|
if (!dyn_cb_check(args, argc)) return NULL;
|
|
557
602
|
ScrDyn *cb = args[0];
|
|
558
603
|
ScrDyn *out = (dyn_name_is(method, "map") || dyn_name_is(method, "filter")) ? scr_dyn_new_arr() : NULL;
|
|
559
|
-
/*
|
|
560
|
-
*
|
|
561
|
-
|
|
604
|
+
/* Array iteration methods snapshot length before the first callback.
|
|
605
|
+
* A shrinking callback can remove a later dense entry; an expanding
|
|
606
|
+
* callback must not make the new tail observable to this pass. Live
|
|
607
|
+
* Web-boundary capsules are the externally visible receiver, so pass
|
|
608
|
+
* that capsule as callback arg 3: mutations through the callback's
|
|
609
|
+
* array argument then commit directly to the original static array. */
|
|
610
|
+
size_t n = len;
|
|
611
|
+
ScrDyn *visible_recv = callback_recv ? callback_recv : recv;
|
|
612
|
+
for (size_t i = 0; i < n && i < recv->v.arr.len; i++) {
|
|
562
613
|
ScrDyn *item = scr_dyn_retain(recv->v.arr.items[i]);
|
|
563
|
-
ScrDyn *r = dyn_call_cb(cb, item, i,
|
|
614
|
+
ScrDyn *r = dyn_call_cb(cb, item, i, visible_recv);
|
|
564
615
|
if (!r) { scr_dyn_release(item); scr_dyn_release(out); return NULL; }
|
|
565
616
|
if (dyn_name_is(method, "map")) {
|
|
566
617
|
scr_dyn_arr_push(out, r); /* ownership moves in */
|
|
@@ -597,7 +648,8 @@ ScrDyn *scr_dyn_invoke(ScrDyn *recv, const char *method, ScrDyn *const *args, si
|
|
|
597
648
|
size_t n = recv->v.arr.len;
|
|
598
649
|
for (size_t i = 0; i < n && i < recv->v.arr.len; i++) {
|
|
599
650
|
ScrDyn *item = scr_dyn_retain(recv->v.arr.items[i]);
|
|
600
|
-
ScrDyn *r = dyn_call_cb(
|
|
651
|
+
ScrDyn *r = dyn_call_cb(
|
|
652
|
+
cb, item, i, callback_recv ? callback_recv : recv);
|
|
601
653
|
scr_dyn_release(item);
|
|
602
654
|
if (!r) { scr_dyn_release(out); return NULL; }
|
|
603
655
|
if (r->kind == SCR_DYN_ARR) {
|