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" }],