@sproutboat/toolchain 0.4.14 → 0.4.15

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @sproutboat/toolchain
2
2
 
3
+ ## 0.4.15
4
+
5
+ ### Patch Changes
6
+
7
+ - c9f84ac: Raise Porffor's per-coroutine fiber stack from 256 KiB to 8 MiB. A large async handler compiled at -O0 (`sproutboat dev`) overflowed it within a few nested awaits and died with SIGBUS on its first request (baronunread/sproutboat#178). Only touched pages cost memory.
8
+
3
9
  ## 0.4.14
4
10
 
5
11
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sproutboat/toolchain",
3
- "version": "0.4.14",
3
+ "version": "0.4.15",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {
@@ -27,7 +27,8 @@ async function fixture(): Promise<{ archive: string; sha256: string }> {
27
27
  " return 0;\n" +
28
28
  " }\n" +
29
29
  " return -1;\n" +
30
- "}\n",
30
+ "}\n" +
31
+ "#define PORF_CORO_STACK_SIZE (256u * 1024u)\n",
31
32
  "compiler/index.js": " ...darwinReleaseCompileArgs,\n uSocketsArchive,\n '-lm'\n",
32
33
  "compiler/precompile.js":
33
34
  "const fs = require('node:fs');\n" +
package/src/patch.test.ts CHANGED
@@ -35,6 +35,9 @@ int porf_native_fetch_read_value(jsval value, const char** out_buf, size_t* out_
35
35
 
36
36
  return -1;
37
37
  }
38
+
39
+ #define PORF_CORO_STACK_SIZE (256u * 1024u)
40
+ #define PORF_CORO_MAX 16384
38
41
  `;
39
42
 
40
43
  // Porffor's compiler/uwebsockets.js, trimmed to the parts the patch touches:
@@ -289,6 +292,10 @@ test("#165: render.js routes console output to stderr, unbuffered, idempotently"
289
292
  "int porf_native_fetch_read_value(jsval value, const char** out_buf, size_t* out_len, char** out_owned) {",
290
293
  );
291
294
 
295
+ // #178: fiber stacks big enough for -O0 frames in a few nested awaits.
296
+ expect(once).toContain("#define PORF_CORO_STACK_SIZE (8u * 1024u * 1024u)");
297
+ expect(once).not.toContain("(256u * 1024u)");
298
+
292
299
  await patchRenderJs(root);
293
300
  expect(await readFile(join(root, "compiler/render.js"), "utf8")).toBe(once);
294
301
  } finally {
package/src/patch.ts CHANGED
@@ -131,6 +131,24 @@ const READ_RAW_INJECT =
131
131
  READ_RAW_ANCHOR;
132
132
  const READ_RAW_MARKER = "porf_native_fetch_read_raw_bytes(jsval value";
133
133
 
134
+ /**
135
+ * baronunread/sproutboat#178: every async function runs on its own fiber
136
+ * stack, and alpha-10 fixes those at 256 KiB. A large handler compiled at -O0
137
+ * (what `sproutboat dev` builds) spends ~40 KiB of stack per call into the
138
+ * biggest generated functions, so a few nested awaits run off the end into
139
+ * the guard page and the sprout dies with SIGBUS on its first request, no log.
140
+ * -O3 frames are smaller, which only raises the threshold: a deep enough
141
+ * async chain hits it in a release build too.
142
+ *
143
+ * Match a thread's usual 8 MiB. The reservation is MAP_NORESERVE with a guard
144
+ * page, so only touched pages cost memory and a shallow handler pays nothing.
145
+ */
146
+ const CORO_STACK_ANCHOR = "#define PORF_CORO_STACK_SIZE (256u * 1024u)";
147
+ const CORO_STACK_INJECT =
148
+ "// sproutboat #178: 256 KiB overflows -O0 frames in a few nested awaits.\n" +
149
+ "#define PORF_CORO_STACK_SIZE (8u * 1024u * 1024u)";
150
+ const CORO_STACK_MARKER = "sproutboat #178";
151
+
134
152
  /**
135
153
  * render.js full-block replacements: `[marker, anchor, inject, what]`, each a
136
154
  * complete swap of the matched region (unlike `RENDER_EDITS`, which only ever
@@ -139,6 +157,7 @@ const READ_RAW_MARKER = "porf_native_fetch_read_raw_bytes(jsval value";
139
157
  const RENDER_REPLACEMENTS = [
140
158
  [BYTESTRING_MARKER, BYTESTRING_ANCHOR, BYTESTRING_INJECT, "bytestring UTF-8 encoding (#172)"],
141
159
  [READ_RAW_MARKER, READ_RAW_ANCHOR, READ_RAW_INJECT, "raw bytestring passthrough function (#176)"],
160
+ [CORO_STACK_MARKER, CORO_STACK_ANCHOR, CORO_STACK_INJECT, "coroutine stack size (#178)"],
142
161
  ] as const;
143
162
 
144
163
  // #15 — no `--port` flag: Porffor's native-fetch entry point calls