With #11556 applied, claude-code 2.1.112 starts (--help works) but -p "say hi" fails immediately:
This blocks every cc runtime measurement that needs a turn, including the four-turn tenuring rows for #9949 — those drive cc through -p, so they cannot run until this is fixed.
Caught in gdb on a symbolized build, breaking on every copy of the throw:
#0 js_throw_type_error_not_a_function
#1 js_native_call_method
#2 js_typed_feedback_native_call_method_by_id
#3 perry_fn_cli_2_1_112_js__aMA
#4 … cli_2_1_112_js closures …
#7 perry_runtime::promise::microtasks::pump_protected
#10 perry_runtime::promise::microtasks::run_microtasks
#11 main
So a typed-feedback native method call by id for the method prompt found a receiver that does not carry it, during microtask drain (hence no Uncaught prefix difference — it is thrown inside a promise job).
What prompt is in this bundle
Not a global. grep finds 48 object-literal method definitions of the form
{ …, async description(){ return … }, async prompt(){ return … }, get inputSchema(){ … }, … }
i.e. each tool descriptor carries its own async prompt(). There is no globalThis.prompt, no window.prompt, and no typeof prompt guard anywhere in the bundle, and perry defines no global prompt either. So the failing call is someToolDescriptor.prompt(), and the defect is that a user-defined async method on a plain object literal is not found by the typed-feedback native-method dispatch.
Reproduce
PERRY_RUNTIME_DIR=$PWD/target/release \
./target/release/perry compile --no-auto-optimize --enable-wasm-runtime cli_2.1.112.js -o cc
HOME=/tmp/cc_home ./cc -p "say hi" # prompt is not a function
HOME=/tmp/cc_home ./cc --help # works
Verified on fix/11499-static-write-instance-accessor (main d57f5139f6 + that fix).
One thing I deliberately did NOT conclude
I read xmm0 at the breakpoint and the runtime's printer dumped what looks like the global object (PerformanceResourceTiming, crypto, navigator, a signal-exit emitter). I am not claiming that is the receiver. I broke on js_throw_type_error_not_a_function, which does not take the receiver in xmm0, so that value may well be a leftover register — the same over-reading that produced a wrong first-bad attribution on #11301. The correct next step is to break on js_native_call_method with the method name filtered to prompt and read its actual receiver argument. I have not done that yet.
If it does turn out to be the global object, this is a receiver-resolution bug rather than a missing-method bug, which would point somewhere quite different — worth establishing before anyone starts on a fix.
Related
Possibly the same family as #10893 (a static accessor reached through the class-id chain was invisible to the native-call tower) and #10848 (patching a built-in method), both of which were dispatch-tower gaps rather than missing implementations.
With #11556 applied,
claude-code2.1.112 starts (--helpworks) but-p "say hi"fails immediately:This blocks every cc runtime measurement that needs a turn, including the four-turn tenuring rows for #9949 — those drive cc through
-p, so they cannot run until this is fixed.Caught in gdb on a symbolized build, breaking on every copy of the throw:
So a typed-feedback native method call by id for the method
promptfound a receiver that does not carry it, during microtask drain (hence noUncaughtprefix difference — it is thrown inside a promise job).What
promptis in this bundleNot a global.
grepfinds 48 object-literal method definitions of the formi.e. each tool descriptor carries its own
async prompt(). There is noglobalThis.prompt, nowindow.prompt, and notypeof promptguard anywhere in the bundle, and perry defines no globalprompteither. So the failing call issomeToolDescriptor.prompt(), and the defect is that a user-defined async method on a plain object literal is not found by the typed-feedback native-method dispatch.Reproduce
Verified on
fix/11499-static-write-instance-accessor(maind57f5139f6+ that fix).One thing I deliberately did NOT conclude
I read
xmm0at the breakpoint and the runtime's printer dumped what looks like the global object (PerformanceResourceTiming,crypto,navigator, a signal-exit emitter). I am not claiming that is the receiver. I broke onjs_throw_type_error_not_a_function, which does not take the receiver inxmm0, so that value may well be a leftover register — the same over-reading that produced a wrong first-bad attribution on #11301. The correct next step is to break onjs_native_call_methodwith the method name filtered topromptand read its actual receiver argument. I have not done that yet.If it does turn out to be the global object, this is a receiver-resolution bug rather than a missing-method bug, which would point somewhere quite different — worth establishing before anyone starts on a fix.
Related
Possibly the same family as #10893 (a static accessor reached through the class-id chain was invisible to the native-call tower) and #10848 (patching a built-in method), both of which were dispatch-tower gaps rather than missing implementations.