Summary
Part of the node:perf_hooks granular parity work (umbrella #793). The new test-parity/node-suite/perf_hooks/ suite is 19/20; the lone failure is observer/entry-types, which asserts:
const obs = new PerformanceObserver(() => {});
console.log(typeof obs.observe); // Node: "function" — Perry: "undefined"
console.log(typeof obs.disconnect); // Node: "function"
console.log(typeof obs.takeRecords); // Node: "function"
obs.observe(...) / .disconnect() / .takeRecords() calls work correctly (the observer/observe-marks test, which exercises the full async-delivery path, passes). Only the bare-property-read form (typeof obs.observe) is wrong.
Root cause
obs is typed Named("PerformanceObserver") (an imported native class), so HIR lowering rewrites any member access on it — including a bare read in typeof position — into a NativeMethodCall (a method invocation), not a PropertyGet. So typeof obs.observe evaluates a 0-arg observe() call and typeofs the result instead of yielding the method as a function value.
HIR (from --print-hir):
TypeOf(NativeMethodCall { module: "perf_hooks", method: "observe", object: Some(LocalGet(0)), args: [] })
This is not perf_hooks-specific — it affects typeof <instance>.<method> for any native-class instance that isn't wired through HANDLE_PROPERTY_DISPATCH (e.g. EventEmitter, StringDecoder would show the same if probed this way).
Possible fixes
- Route native-class instance property reads (member access not in call position) through
HANDLE_PROPERTY_DISPATCH so typeof inst.method yields a bound-method function value, or
- Make the HIR distinguish a member read from a 0-arg call so
typeof obs.observe lowers to a PropertyGet.
Repro
./run_parity_tests.sh --suite node-suite --module perf_hooks → observer/entry-types FAIL; all 19 others PASS. Tracked as a known failure in test-parity/known_failures.json.
Summary
Part of the
node:perf_hooksgranular parity work (umbrella #793). The newtest-parity/node-suite/perf_hooks/suite is 19/20; the lone failure isobserver/entry-types, which asserts:obs.observe(...)/.disconnect()/.takeRecords()calls work correctly (theobserver/observe-markstest, which exercises the full async-delivery path, passes). Only the bare-property-read form (typeof obs.observe) is wrong.Root cause
obsis typedNamed("PerformanceObserver")(an imported native class), so HIR lowering rewrites any member access on it — including a bare read intypeofposition — into aNativeMethodCall(a method invocation), not aPropertyGet. Sotypeof obs.observeevaluates a 0-argobserve()call andtypeofs the result instead of yielding the method as a function value.HIR (from
--print-hir):This is not perf_hooks-specific — it affects
typeof <instance>.<method>for any native-class instance that isn't wired throughHANDLE_PROPERTY_DISPATCH(e.g. EventEmitter, StringDecoder would show the same if probed this way).Possible fixes
HANDLE_PROPERTY_DISPATCHsotypeof inst.methodyields a bound-method function value, ortypeof obs.observelowers to aPropertyGet.Repro
./run_parity_tests.sh --suite node-suite --module perf_hooks→observer/entry-typesFAIL; all 19 others PASS. Tracked as a known failure intest-parity/known_failures.json.