From e46bed73f190484984c42efcb6fae0ccc42da4ee Mon Sep 17 00:00:00 2001 From: Angelo Perez <102934797+Angelopgit@users.noreply.github.com> Date: Tue, 13 Oct 2026 09:16:00 -0400 Subject: [PATCH] fix(managed): decode the CIL no. prefix (#2241) The CIL opcode table held five of the six ECMA-335 prefix opcodes and omitted no. (FE 19 , III.2.2). A method body using it was reported as malformed with "Unsupported CIL opcode 0xfe19", losing its instruction counts and normalized IL digest. Decode it with its one-byte check mask and treat it as a prefix, so it shares an instruction boundary with the opcode it modifies. Claude-Session: https://claude.ai/code/session_012pRGskbPGjT444CgJfuhhj Co-authored-by: Claude Fable 5.1 --- src/dotnet/ManagedCilDecoding.test.ts | 25 +++++++++++++++++++ src/dotnet/ManagedMemberInstructionDecoder.ts | 2 ++ 2 files changed, 27 insertions(+) diff --git a/src/dotnet/ManagedCilDecoding.test.ts b/src/dotnet/ManagedCilDecoding.test.ts index 55a008b72..4ba33f4c9 100644 --- a/src/dotnet/ManagedCilDecoding.test.ts +++ b/src/dotnet/ManagedCilDecoding.test.ts @@ -345,6 +345,31 @@ describe("managed exception region prefix boundaries", () => { }); }); + it("decodes the no. prefix and keeps it with its opcode", () => { + // ldarg.0; no. nullcheck; ldfld 0x04000001; pop; ret + const il = Buffer.from([2, 0xfe, 0x19, 4, 0x7b, 1, 0, 0, 4, 0x26, 0x2a]); + expect( + managedBodyWithRegion({ il, tryLength: 10, handlerOffset: 10 }), + ).toMatchObject({ + status: "present", + issue: null, + decoded_instruction_count: 5, + opcode_counts: { "ldarg.0": 1, "no.": 1, ldfld: 1, pop: 1, ret: 1 }, + }); + expect( + managedBodyWithRegion({ + il, + tryOffset: 4, + tryLength: 5, + handlerOffset: 10, + }), + ).toMatchObject({ + status: "malformed", + issue: + "Exception clause try range does not align with CIL instruction boundaries", + }); + }); + it.each([ ["start", { tryOffset: 5, tryLength: 1, handlerOffset: 6 }], [ diff --git a/src/dotnet/ManagedMemberInstructionDecoder.ts b/src/dotnet/ManagedMemberInstructionDecoder.ts index b05dd083f..01c2b7814 100644 --- a/src/dotnet/ManagedMemberInstructionDecoder.ts +++ b/src/dotnet/ManagedMemberInstructionDecoder.ts @@ -12,6 +12,7 @@ const PREFIX_OPCODES = new Set([ "tail.", "constrained.", "readonly.", + "no.", ]); const OPCODES = new Map< @@ -232,6 +233,7 @@ const OPCODES = new Map< [0xfe16, { name: "constrained.", operand: "type" }], [0xfe17, { name: "cpblk", operand: "none" }], [0xfe18, { name: "initblk", operand: "none" }], + [0xfe19, { name: "no.", operand: "short-i" }], [0xfe1a, { name: "rethrow", operand: "none" }], [0xfe1c, { name: "sizeof", operand: "type" }], [0xfe1d, { name: "refanytype", operand: "none" }],