29 Commits
Author SHA1 Message Date
Daniel Grunwald 790f4f60ee Second round of fixes. 2026-09-05 22:11:12 +02:00
Daniel Grunwald 4b040c1bb2 First round of bugfixes. 2026-09-05 22:11:12 +02:00
Daniel Grunwald c4e181505c Prepare for a split of StackType.O into StackType.Obj and StackType.VT: the easy cases 2026-09-05 22:11:12 +02:00
Daniel Grunwald 5526400b17 Extend InferType() to every ILInstruction
Change InferType() to an abstract method and implement for every ILInstruction.
With this change, we now always have enough information to create a variable of an appropriate type to store the result of evaluating the instruction.
This previously was not the case for instructions producing "other value type", for which the stacktype-based fallback incorrectly produced `object`.
2026-08-30 21:25:45 +02:00
Siegfried Pammer cd212ea05f Pass the compilation to ILInstruction.CheckInvariant
Invariants that involve types (stack type of a variable against its IType,
the element type of an array access, the operand types of a comparison)
need a type system to resolve them against, and the only correct one is the
type system the instruction tree was decoded with. Until now CheckInvariant
took only the phase, so such a check had no compilation to use:
DeconstructInstruction.CheckInvariant called IsAssignment with a null type
system, which only held up because the targets it sees are ldloc, whose
InferType never touches the compilation; a ldflda-wrapped or pointer target
would have failed inside the invariant instead of reporting a violation.

Every call site already has that type system in scope: the ILReader's
compilation, the ILTransformContext of the running transform, or the
decompiler's own IDecompilerTypeSystem. It is now passed explicitly and the
base implementation asserts it is present, so a future invariant can rely
on it without re-plumbing the callers.

Assisted-by: Claude:claude-fable-5:Claude Code
2026-08-30 12:43:40 +02:00
Siegfried Pammer 468e3da92c Bracket ILAst WriteTo in one place via WriteToCore
The debug-step node bracket (MarkNodeStart/try/finally/MarkNodeEnd) was copied
into every hand-written WriteTo override and re-emitted by the T4 generator, so
a newly added instruction could silently omit it and lose step highlighting with
no compile error or test failure. Seal WriteTo on ILInstruction to apply the
bracket once and delegate to a new abstract WriteToCore; move every override
(hand-written and generated) to WriteToCore without the wrapper. Rendered output
is unchanged -- the marks are no-ops unless the output tracks nodes.

Assisted-by: Claude:claude-opus-4-8:Claude Code
2026-07-02 01:08:51 +02:00
Siegfried Pammer 04505bbdf2 Highlight and scroll to the changed instruction in the ILAst view
The C# debug-steps view highlights and centers the exact AST node a
transform changed; the ILAst view already had the step tree and
replay-at-step but produced no highlight. Bring it to parity.

IL rendering has no token-writer seam like the C# output visitor, so
per-instruction text spans are recorded by bracketing
ILInstruction.WriteTo via a new INodeTrackingOutput. The dominant
inst.ReplaceWith(newInst) transform pattern detaches the instruction
passed to Step, so ILTransformContext gains EndStep to record the
produced instruction; Stepper additionally records the position's
ancestor chain as fallback candidates before the step-limit throw, so
the "show state before" view -- which halts at the selected step --
still resolves to a surviving ancestor (ultimately the ILFunction).
The highlight-range resolver is shared with the C# language.

Assisted-by: Claude:claude-opus-4-8:Claude Code
2026-07-02 01:08:51 +02:00
Siegfried Pammer 1cc8a62f95 Delete TokenRole; carry token text as constants
TokenRole was a printer-side descriptor whose only jobs were holding a token's
text and giving the writers an identity to single out specific tokens. The text
becomes plain const strings on the nodes, and the few identity checks are
reexpressed as node-stack context: interpolation braces are recognized by an
Interpolation on the writer's stack, record class versus struct coloring keys
off TypeDeclaration.ClassType, and the accessor/this/base/override cases fall
out of the surrounding node. WriteKeyword/WriteToken drop the descriptor
parameter. The constants are named for what the token is: a keyword, a symbol
token, or a modifier.
Assisted-by: Claude:claude-opus-4-8:Claude Code
2026-06-23 07:43:42 +02:00
Peter Crabtree e1e16b64f5 dev: Strip BOM mark from text files 2025-08-28 20:56:19 -04:00
Daniel Grunwald ec58d57875 #3465: Fix bugs in comp.o handling. 2025-08-23 17:55:37 +02:00
Siegfried Pammer 6c00c138eb Fix #3465: Translate comp.o(a op b) if op not in (==, !=) into Unsafe.As<object, UIntPtr>(ref a) op Unsafe.As<object, UIntPtr>(ref b) 2025-08-14 23:26:45 +02:00
Siegfried Pammer cb62cac9d3 Add support for nullable int const patterns 2023-08-05 14:33:47 +02:00
Daniel Grunwald 5fb2f7a22f #nullable enable for ILAst (except for generated code) 2021-06-03 21:36:12 +02:00
Siegfried Pammer ba39dd5c55 Fix #2354: decompilation of unary and binary operators with nullable value types. 2021-05-26 23:42:51 +02:00
dotnet format 0d9f871a4f #2128: Reformat the whole code base. 2020-08-28 01:05:38 +02:00
Siegfried Pammer c1fca21e8a Make ILRange field private - introduce public API for IL range manipulation. 2019-02-16 20:36:17 +01:00
Daniel Grunwald 0a9df3d373 Fix #1252: Incorrect comparison type for lifted comparisons in expression trees. 2018-11-14 14:00:46 +01:00
Siegfried Pammer 4540b93e19 Use ArgumentOutOfRangeException or BadImageFormatException in switch-default sections. 2018-07-11 17:18:08 +02:00
Siegfried Pammer 5fec6bd7f7 Implement Interval.WriteTo extension method on ILAst 2017-10-14 16:00:01 +02:00
Daniel Grunwald 53a050552b Add support for syntax sugar when writing out the ILAst. 2017-09-23 15:38:19 +02:00
Daniel Grunwald 66d1b744c3 Add ILAstWritingOptions parameter to ILInstruction.WriteTo(). 2017-09-23 14:54:18 +02:00
Daniel Grunwald 96c6b03d9b [nullables] operator! on bool? 2017-09-23 14:23:20 +02:00
Daniel Grunwald 919219524b Eliminate the dedicated logic.not instruction, and treat it as syntax sugar similar to logic.and/logic.or.
'logic.not(arg)' is now represented using 'comp(arg == ldc.i4 0)'.
2017-09-23 00:27:47 +02:00
Daniel Grunwald 21ef967d4d [nullables] Lifting for non-equality comparisons. 2017-09-21 00:22:24 +02:00
Siegfried Pammer 840ec04fde Namespace adjustments for Syntax classes 2016-11-26 12:06:58 +01:00
Christoph Wille 1ce8349dd9 Adjust namespaces 2016-11-26 11:12:53 +01:00
Daniel Grunwald 14815abd7c Initial version of IL pattern matching. 2016-07-25 18:23:24 +02:00
Daniel Grunwald ae318eca02 Make implicit I4->I conversions explicit in ILAst. 2016-07-02 11:29:35 +02:00
Daniel Grunwald f1021d18af Make comparisons in the ILAst more similar to C# comparisons.
Add some logic.not simplification to ExpressionTransforms.
2016-06-20 01:09:40 +02:00