Skip to content

refactor(compile): extract per-receiver branches from EmitGetProperty (#1242)#1244

Merged
nickna merged 1 commit into
mainfrom
tech-debt-1242-getproperty-branches
Jul 4, 2026
Merged

refactor(compile): extract per-receiver branches from EmitGetProperty (#1242)#1244
nickna merged 1 commit into
mainfrom
tech-debt-1242-getproperty-branches

Conversation

@nickna

@nickna nickna commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Closes #1242. Part of #1094.

What

Follow-up to #1141 / PR #1241, which split RuntimeEmitter.Objects.Properties.cs at the file level but deliberately left the 2,028-line EmitGetProperty god-method intact. This PR extracts the per-receiver branches inside that method into Emit<Receiver>GetBranch(il, …) helpers, the original #1141 ask.

15 self-contained, disjoint receiver arms move into a new sibling partial Compilation/RuntimeEmitter.Objects.GetPropertyBranches.cs. Each helper mirrors the already-factored EmitProxyGetPropertyCheck/EmitProxyDeleteCheck shape:

  • emits the receiver-type test itself,
  • runs the branch body + ret on a match,
  • otherwise falls through to a caller-supplied notMatch label.

The dispatch table in EmitGetProperty now reads as a flat sequence of EmitXGetBranch(il, …, notX); MarkLabel(notX) arms sitting right beside the existing proxy-check call.

Extracted arms: namespace, $Object, Map, Set, Dictionary, $Array, List, object[], String, $Buffer, $Stats, $TSFunction, $BoundTSFunction, $CJSModule, $RegExp.

EmitGetProperty drops from ~2,028 → ~960 lines.

What was left inline (deferred, per the incremental plan)

The genuinely interdependent arms #1242 flagged as risky stay inline:

  • the System.Type / class-instance pair (they share the base-walk-loop jump target classInstanceLabel),
  • the three-way Promise dispatch (Task / $Promise subclass / $Promise),
  • the typed-array family ($ArrayBuffer/$SharedArrayBuffer/$DataView/TypedArray share a gated block),
  • the bound-callable multi-check ($BoundArrayMethod/$BoundMapMethod/$BoundSetMethod/$BoundAnyFunction),
  • the primitive-prototype fall-throughs (bool/double).

These remain candidates for later increments.

Safety

Pure mechanical move — no behaviour change. The larger arms ($Object, $RegExp, Dictionary) were relocated with a line-preserving script rather than retyped, so their local functions and comments carry over verbatim. Each arm was extracted incrementally, one receiver type at a time, and verified with --compile … --verify (IL validation) plus an output diff against a pre-refactor compiled baseline; every increment matched.

No new metadata-token references are introduced — the moved IL keeps its existing Ldtoken/GetMethodFromHandle late-binding, so compiled standalone DLLs gain no SharpTS.dll dependency.

Gate

  • dotnet test (xUnit): 15404 / 0 failed / 0 skipped
  • Test262 (interpreter + compiled): 22 / 0 / 4 skipped — no baseline regression
  • TypeScriptConformance: 31 / 0
  • IL --verify: clean on the emitted GetProperty

…#1242)

Slice 15 self-contained, disjoint receiver arms out of the 2,028-line
EmitGetProperty god-method into named Emit<Receiver>GetBranch helpers in a
new sibling partial (RuntimeEmitter.Objects.GetPropertyBranches.cs). Each
helper mirrors the already-factored EmitProxyGetPropertyCheck shape: it emits
the receiver-type test itself, runs the branch body + `ret` on a match, and
otherwise falls through to a caller-supplied `notMatch` label. The dispatch
table in EmitGetProperty now reads as a flat sequence of
`EmitXGetBranch(il, …, notX); MarkLabel(notX)` arms.

Extracted arms: namespace, $Object, Map, Set, Dictionary, $Array, List,
object[], String, $Buffer, $Stats, $TSFunction, $BoundTSFunction, $CJSModule,
$RegExp. EmitGetProperty drops from ~2,028 to ~960 lines.

The interdependent arms deferred in #1141/#1242 stay inline: the
System.Type/class-instance pair (shared base-walk jump target), the three-way
Promise dispatch, the typed-array family, the bound-callable multi-check, and
the primitive-prototype fall-throughs.

Pure mechanical move — no behaviour change. Each arm was extracted
incrementally and verified with `--compile … --verify` plus an output diff
against a pre-refactor compiled baseline.

Gate: xUnit 15404/0, Test262 22/0/4skip (interp + compiled), TSConformance
31/0, IL --verify clean. Standalone constraint preserved (no new metadata
tokens; existing Ldtoken/GetMethodFromHandle late-binding retained).

Part of #1094.
@nickna nickna merged commit ecda7a5 into main Jul 4, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extract per-receiver branches from EmitGetProperty (follow-up to #1141)

1 participant