Skip to content

Compiled: direct call to an instance/static method or constructor pads an omitted optional (no-default) param with null, not the undefined sentinel #739

@nickna

Description

@nickna

Summary

In compiled mode, calling a class instance or static method (or a constructor) directly with fewer arguments than parameters pads a missing trailing optional, no-default parameter (x?: T) with CLR null instead of the undefined sentinel. Observable through typeof, === undefined, === null. The interpreter is correct, and free functions are correct.

This is the direct-call analogue of #640 (which fixed the value-call / $TSFunction.Invoke path) and #703 (class methods invoked as values). The direct-call path for class methods was not covered.

Repro

class C {
  m(x?: any): string { return typeof x; }
  static s(x?: any): string { return typeof x; }
}
console.log(new C().m());   // interp: "undefined"   compiled: "object"  (BUG)
console.log(C.s());         // interp: "undefined"   compiled: "object"  (BUG)

typeof null === "object", so the missing optional reads as null. Free functions are fine (function h(x?: any) { return typeof x; } h()"undefined" in both modes). Class expressions are also fine (they use all-object param slots).

Cause / fix sketch

The direct method-call emitter pads missing trailing args with the slot's CLR default (null for object slots) rather than the $Undefined singleton. For object-typed params it should pad with the sentinel (cf. the private-method call padding added in #705, ILEmitter.Properties.Private.cs EmitPrivateCallArgsPadded, which pads with $Undefined). Mirror that for the instance/static method and constructor direct-call sites. Note this is distinct from default-parameter firing — these params have no default; the value should simply be undefined.

Discovered

While implementing #703/#705.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions