@scriptc/runtime 0.0.25 → 0.0.26

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/src/scr_runtime.h CHANGED
@@ -15,22 +15,18 @@
15
15
  #include <string.h> /* memcpy in the inline slot accessors */
16
16
  #include <sys/types.h> /* ssize_t in the transport ops table */
17
17
 
18
- /* ── win32 libc shims (scr_win.c; see the windows portability inventory) ──
19
- * The POSIX/BSD functions the runtime calls that mingw-w64's CRT does not
20
- * provide: stpcpy (POSIX.1-2008; scr_number.c's digit writer), the
21
- * arc4random_buf CSPRNG (Math.random and node:crypto; RtlGenRandom
22
- * underneath), gmtime_r (scr_http.c's Date header; the CRT's gmtime is
23
- * already per-thread), and strcasestr (scr_http.c's token scan).
24
- * scr_win.c — compiled into win32-target builds only (cc.ts) —
25
- * implements all of them. Declared here so every TU that calls them
26
- * through scr_runtime.h compiles unchanged; POSIX hosts never see
27
- * these. */
18
+ /* ── libc shims ─────────────────────────────────────────────────────────
19
+ * Win32's missing POSIX/BSD functions live in scr_win.c. Zig's musl sysroot
20
+ * additionally lacks arc4random_buf; scr_musl.c supplies it from Linux's
21
+ * getrandom syscall. Both files are selected by cc.ts only for their target. */
28
22
  #ifdef _WIN32
29
23
  #include <time.h> /* time_t / struct tm for the gmtime_r shim */
30
24
  char *stpcpy(char *dst, const char *src);
31
25
  void arc4random_buf(void *buf, size_t n);
32
26
  struct tm *gmtime_r(const time_t *t, struct tm *out);
33
27
  char *strcasestr(const char *hay, const char *needle);
28
+ #elif defined(SCR_MUSL)
29
+ void arc4random_buf(void *buf, size_t n);
34
30
  #endif
35
31
 
36
32
  /* ── process ──────────────────────────────────────────────────────────── */
@@ -241,16 +237,22 @@ typedef struct ScrCycHdr {
241
237
  size_t buf_index; /* position there (O(1) removal when rc hits 0) */
242
238
  } ScrCycHdr;
243
239
 
244
- /* This layout is an ABI, not an implementation detail: the LLVM backend
245
- * inlines scr_cyc_mark_live as a raw `store i32 0` at obj-16 (it is a
246
- * static inline here, so there is no symbol to call) and reaches the header
247
- * at obj-32. Three sites emit it — llvm/shapes.ts, llvm/classes.ts,
248
- * llvm/emitter.ts. Nothing but `color` may share those four bytes: a field
249
- * placed in them is silently zeroed by every retain, which is invisible to
250
- * the type system and to the C compiler. Hence the assertions. */
251
- _Static_assert(sizeof(ScrCycHdr) == 32, "LLVM backend reads the header at obj-32");
240
+ /* This layout is an ABI, not an implementation detail. The LLVM backend
241
+ * inlines scr_cyc_mark_live as a raw `store i32 0`: color is at obj-16 on
242
+ * 64-bit targets and obj-12 on wasm32. Three sites emit it
243
+ * llvm/shapes.ts, llvm/classes.ts, and llvm/emitter.ts. Nothing but `color`
244
+ * may share those four bytes: a field placed in them is silently zeroed by
245
+ * every retain, which is invisible to the type system and to the C
246
+ * compiler. Hence the target-width assertions. */
247
+ #if UINTPTR_MAX == UINT64_MAX
248
+ _Static_assert(sizeof(ScrCycHdr) == 32, "LLVM backend expects a 32-byte cycle header");
252
249
  _Static_assert(offsetof(ScrCycHdr, color) == 16,
253
250
  "LLVM backend's inlined mark-live stores i32 0 at obj-16");
251
+ #elif UINTPTR_MAX == UINT32_MAX
252
+ _Static_assert(sizeof(ScrCycHdr) == 20, "LLVM backend expects a 20-byte cycle header");
253
+ _Static_assert(offsetof(ScrCycHdr, color) == 8,
254
+ "LLVM backend's inlined mark-live stores i32 0 at obj-12");
255
+ #endif
254
256
  _Static_assert(sizeof(((ScrCycHdr *)0)->color) == 4,
255
257
  "mark-live is an i32 store: color must own all four bytes");
256
258
  _Static_assert(SCR_CYC_BLACK == 0,
@@ -1421,9 +1423,10 @@ ScrEmitter *scr_emitter_on_via(ScrEmitter *em, ScrStr *name, ScrClosure *orig /*
1421
1423
  * slots off the emit tuple and calls cb->fn behind the fixed signature
1422
1424
  * `void (ScrClosure *, void * ×k)` — the fixed-signature adapter the
1423
1425
  * backend provides. Such backends pass every user tuple argument
1424
- * pointer-classed at the emit site (f64 as its i64 bit pattern, bool
1425
- * zero-extended); the runtime's own emits (data/error/pipe/meta) carry
1426
- * pointers only, so the shims read every tuple either lane produces.
1426
+ * pointer-classed at the emit site: scalar values point at call-lived
1427
+ * typed stack slots and reference values ride directly. The runtime's own
1428
+ * emits (data/error/pipe/meta) carry pointers only, so the shims read every
1429
+ * tuple either lane produces on 32- and 64-bit targets.
1427
1430
  * SCR_EE_FIXED_MAX is the registry's audited arity ceiling — backends
1428
1431
  * refuse listeners past it rather than guess. */
1429
1432
  #define SCR_EE_FIXED_MAX 4
@@ -3548,6 +3551,28 @@ void scr_promise_release_v(void *p);
3548
3551
  typedef struct ScrFiber ScrFiber;
3549
3552
  /* Spawn + run eagerly to the first suspension; returns the promise, +1. */
3550
3553
  ScrPromise *scr_async_spawn(void (*entry)(ScrFiber *, void *), void *argpack);
3554
+ /* Runtime-authored C waiters cannot themselves become LLVM switched
3555
+ * coroutines on wasm32. Spawn after `dependency` settles so their first
3556
+ * (and only) await is extraction from an already-settled promise, while
3557
+ * retaining the ordinary promise-job hop on every target. +1. */
3558
+ ScrPromise *scr_async_spawn_after(ScrPromise *dependency,
3559
+ void (*entry)(ScrFiber *, void *),
3560
+ void *argpack);
3561
+
3562
+ /* wasm32-wasi lowers async functions and generators through LLVM switched
3563
+ * coroutines instead of the native stack-switching implementations. The
3564
+ * first two adapters are emitted into the program module; the remaining
3565
+ * helpers let scr_async.c register, queue, and finish those coroutine
3566
+ * frames through the same ScrFiber scheduler. These declarations are part
3567
+ * of the LLVM/runtime ABI even though native targets never call them. */
3568
+ void scr_wasi_coro_resume(void *handle);
3569
+ void scr_wasi_coro_destroy(void *handle);
3570
+ void scr_wasi_coro_started(void *handle);
3571
+ void scr_wasi_await_prepare(ScrFiber *self, ScrPromise *p);
3572
+ void scr_wasi_await_hop_prepare(ScrFiber *self);
3573
+ bool scr_wasi_module_await_prepare(ScrFiber *self, ScrPromise *p);
3574
+ void scr_wasi_async_finish(ScrFiber *self);
3575
+ void scr_wasi_gen_finish(ScrFiber *self);
3551
3576
 
3552
3577
  double scr_await_f64(ScrPromise *p); /* rejected promises re-throw */
3553
3578
  bool scr_await_bool(ScrPromise *p);
@@ -5113,6 +5138,20 @@ void scr_net_listen(ScrNetServer *s, double port, ScrClosure *cb /*moves, nullab
5113
5138
  void scr_net_listen_opts(ScrNetServer *s, double port, ScrStr *host /*borrowed*/,
5114
5139
  bool ipv6_only, ScrClosure *cb /*moves, nullable*/);
5115
5140
  double scr_net_server_port(ScrNetServer *s); /* address().port */
5141
+ /* Writable http.Server timeout property storage. `field` is the compiler
5142
+ * ABI selector: timeout, keepAliveTimeout, headersTimeout, requestTimeout,
5143
+ * keepAliveTimeoutBuffer. Typed reads validate that no dynamic write left
5144
+ * a non-number in the ordinary JS property slot. */
5145
+ double scr_net_server_timeout_get(ScrNetServer *s, double field);
5146
+ void scr_net_server_timeout_set(ScrNetServer *s, double field, double value);
5147
+ /* Marks the shared net-server handle as an HTTP/1 or HTTPS server. The
5148
+ * dynamic handle uses this to keep HTTP-only fields off net/TLS/H2. */
5149
+ void scr_net_server_enable_http_timeout_surface(ScrNetServer *s);
5150
+ /* Constructor-option twin: undefined is absent; otherwise validates type
5151
+ * and a non-negative safe integer before storing, matching Node's option
5152
+ * ladder (plain property writes do not validate). */
5153
+ bool scr_net_server_timeout_option_check(double field, double value);
5154
+ void scr_net_server_timeout_option_set(ScrNetServer *s, double field, const struct ScrDyn *value);
5116
5155
  ScrStr *scr_net_server_addr_ip(ScrNetServer *s); /* +1 — address().address */
5117
5156
  ScrStr *scr_net_server_addr_family(ScrNetServer *s); /* +1 — address().family */
5118
5157
  void scr_net_server_close(ScrNetServer *s, ScrClosure *cb /*moves, nullable*/);
package/src/scr_tls.c CHANGED
@@ -1415,6 +1415,27 @@ ScrNetServer *scr_tls_create_server_dyn(const ScrDyn *opts /*borrowed*/,
1415
1415
  ScrNetServer *scr_https_create_server_dyn(const ScrDyn *opts /*borrowed*/,
1416
1416
  ScrClosure *handler /*moves, nullable*/,
1417
1417
  ScrHttpReqFn fn) {
1418
+ /* HTTPS ServerOptions extends http.ServerOptions. Consume the one HTTP
1419
+ * constructor field this runtime models before the shared TLS walker;
1420
+ * that walker deliberately owns only the TLS-side option surface. */
1421
+ bool has_timeout_buffer = false;
1422
+ double timeout_buffer = 0;
1423
+ if (opts != NULL && opts->kind == SCR_DYN_OBJ) {
1424
+ const ScrDyn *v = scr_dyn_obj_get(opts, "keepAliveTimeoutBuffer", 22);
1425
+ if (v != NULL && v->kind != SCR_DYN_UNDEF) {
1426
+ if (v->kind != SCR_DYN_NUM) {
1427
+ scr_dyn_arg_type_fail("keepAliveTimeoutBuffer", "of type number", v);
1428
+ scr_closure_release(handler);
1429
+ return NULL;
1430
+ }
1431
+ timeout_buffer = v->v.num;
1432
+ if (!scr_net_server_timeout_option_check(4, timeout_buffer)) {
1433
+ scr_closure_release(handler);
1434
+ return NULL;
1435
+ }
1436
+ has_timeout_buffer = true;
1437
+ }
1438
+ }
1418
1439
  ScrBytes *cert, *key;
1419
1440
  if (!scr_tls_srv_opts_walk(opts, "https.createServer", &cert, &key)) {
1420
1441
  scr_closure_release(handler);
@@ -1422,6 +1443,7 @@ ScrNetServer *scr_https_create_server_dyn(const ScrDyn *opts /*borrowed*/,
1422
1443
  }
1423
1444
  ScrNetServer *s = scr_https_create_server((const char *)cert->data, cert->len,
1424
1445
  (const char *)key->data, key->len, handler, fn);
1446
+ if (has_timeout_buffer) scr_net_server_timeout_set(s, 4, timeout_buffer);
1425
1447
  scr_bytes_release(cert);
1426
1448
  scr_bytes_release(key);
1427
1449
  return s;
package/vendor/README.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Vendored third-party code
2
2
 
3
+ ## libucontext (derived source)
4
+
5
+ - Project: https://github.com/kaniini/libucontext
6
+ - Commit: 49e671dd52ff6791295d8161ad3b6da7dc5f6f9d
7
+ - License: ISC (copyright and permission notice reproduced in `src/scr_musl.c`)
8
+
9
+ The x86_64 register-save/restore and `makecontext` logic is adapted into `src/scr_musl.c`, rather than carried as a separate library, to supply the legacy `ucontext` functions that musl declares but does not implement. It is compiled only for the explicit `x86_64-linux-musl` target and uses musl's public `ucontext_t` layout. The signal-mask compatibility wrapper is deliberately not included: scriptc fibers perform user-space register swaps and do not change a per-fiber signal mask.
10
+
3
11
  ## ryu/
4
12
 
5
13
  - Project: https://github.com/ulfjack/ryu