Summary
Perry compiles the marked npm package natively ("2 native, 0 JavaScript") but the
result is functionally broken: any parse throws
TypeError: Cannot read properties of undefined (reading 'pedantic')
at <anonymous>
Minimal repro — three lines:
import { marked } from "marked";
const out = marked.parse("# hi") as string;
console.log(out.length);
| runtime |
result |
node --experimental-strip-types |
12 |
scriptc 0.0.22 --dynamic (QuickJS island) |
correct on the full workload |
perry 0.5.1389 (f3e14a61e) |
TypeError |
Reproduces both with perry.compilePackages: ["marked"] and without it — Perry
compiles the package natively on either path, so there is no working fallback.
Repro
cd gc-handoff/apps/mdapp # marked is vendored under ./node_modules
export PERRY_RUNTIME_DIR=<repo>/target/release
<repo>/target/release/perry mdmin.ts -o p_mdmin
./p_mdmin # TypeError
node --experimental-strip-types mdmin.ts # 12
mdapp.ts in the same directory is the fuller workload (300 generated markdown
documents through marked.parse, counting <h2> tags): Node and scriptc
--dynamic both print 612040 1800; Perry throws the same TypeError.
Where to look
pedantic is a marked option flag. In node_modules/marked/lib/marked.cjs it
appears both in the defaults object (pedantic: false, ~line 63) and as a key in
the rules tables (pedantic: blockPedantic / pedantic: inlinePedantic, ~lines
285/291). The message says the container is undefined at the read, so the
suspect is a module-level object literal or rules table that did not initialize —
i.e. module init ordering, or an object-literal construction form that lowers
incorrectly.
Possibly related to the known object-literal computed-key / cross-module spread
issue (#809), but that is a guess — the container has not been identified.
Note the compile also reports:
perry: module IR is 11.9 MB (> 6.0 MB), 347 functions (~35 KB/fn); compiling at
-Os instead of -O3 ... (#4880)
so this module takes the oversized-IR path; worth checking whether the failure is
sensitive to that (try PERRY_LL_SIZE_OPT / PERRY_LL_O0_THRESHOLD_BYTES).
Why it matters
This is the axis where Perry's architecture is supposed to win outright: scriptc
must run npm dependencies inside an embedded QuickJS engine (it refuses statically
with SC2013: values from the 'marked' package run in the embedded dynamic engine), while Perry compiles the same package to native code. Today scriptb
produces the right answer through its interpreter and Perry produces a TypeError,
so the comparison cannot even be run.
marked is a pure-JS, dependency-free, widely used package — a reasonable
regression target for native npm compilation.
Summary
Perry compiles the
markednpm package natively ("2 native, 0 JavaScript") but theresult is functionally broken: any parse throws
Minimal repro — three lines:
node --experimental-strip-types12--dynamic(QuickJS island)f3e14a61e)Reproduces both with
perry.compilePackages: ["marked"]and without it — Perrycompiles the package natively on either path, so there is no working fallback.
Repro
mdapp.tsin the same directory is the fuller workload (300 generated markdowndocuments through
marked.parse, counting<h2>tags): Node and scriptc--dynamicboth print612040 1800; Perry throws the same TypeError.Where to look
pedanticis amarkedoption flag. Innode_modules/marked/lib/marked.cjsitappears both in the defaults object (
pedantic: false, ~line 63) and as a key inthe rules tables (
pedantic: blockPedantic/pedantic: inlinePedantic, ~lines285/291). The message says the container is
undefinedat the read, so thesuspect is a module-level object literal or rules table that did not initialize —
i.e. module init ordering, or an object-literal construction form that lowers
incorrectly.
Possibly related to the known object-literal computed-key / cross-module spread
issue (#809), but that is a guess — the container has not been identified.
Note the compile also reports:
so this module takes the oversized-IR path; worth checking whether the failure is
sensitive to that (try
PERRY_LL_SIZE_OPT/PERRY_LL_O0_THRESHOLD_BYTES).Why it matters
This is the axis where Perry's architecture is supposed to win outright: scriptc
must run npm dependencies inside an embedded QuickJS engine (it refuses statically
with
SC2013: values from the 'marked' package run in the embedded dynamic engine), while Perry compiles the same package to native code. Today scriptbproduces the right answer through its interpreter and Perry produces a TypeError,
so the comparison cannot even be run.
markedis a pure-JS, dependency-free, widely used package — a reasonableregression target for native npm compilation.