Skip to content

node:perf_hooks — typeof PerformanceObserver instance methods reports wrong type (native-class member read lowers as a call) #1320

@proggeramlug

Description

@proggeramlug

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_hooksobserver/entry-types FAIL; all 19 others PASS. Tracked as a known failure in test-parity/known_failures.json.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions