Skip to content

npm: marked compiles natively but throws at runtime — "Cannot read properties of undefined (reading 'pedantic')" #7689

Description

@proggeramlug

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugConfirmed defect or regression

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions