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 <unsigned int8>, 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 <noreply@anthropic.com>
This commit is contained in:
parent
ece15ed6a1
commit
e46bed73f1
|
|
@ -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 }],
|
||||
[
|
||||
|
|
|
|||
|
|
@ -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" }],
|
||||
|
|
|
|||
Loading…
Reference in New Issue