25using System.Collections.Generic;
33 internal sealed class MethodBody
36 readonly IList<ExceptionHandlingClause> exceptionClauses;
37 readonly IList<LocalVariableInfo> locals;
38 readonly
bool initLocals;
39 readonly
int maxStack;
40 readonly
int localVarSigTok;
53 const byte CorILMethod_TinyFormat = 0x02;
54 const byte CorILMethod_FatFormat = 0x03;
55 const byte CorILMethod_MoreSects = 0x08;
56 const byte CorILMethod_InitLocals = 0x10;
57 const byte CorILMethod_Sect_EHTable = 0x01;
58 const byte CorILMethod_Sect_FatFormat = 0x40;
59 const byte CorILMethod_Sect_MoreSects = 0x80;
61 var exceptionClauses =
new List<ExceptionHandlingClause>();
62 var locals =
new List<LocalVariableInfo>();
63 var stream = module.GetStream();
65 var br =
new BinaryReader(stream);
67 var b = br.ReadByte();
68 if ((b & 3) == CorILMethod_TinyFormat)
71 body = br.ReadBytes(b >> 2);
74 else if ((b & 3) == CorILMethod_FatFormat)
76 initLocals = (b & CorILMethod_InitLocals) != 0;
77 var flagsAndSize = (short)(b | (br.ReadByte() << 8));
78 if ((flagsAndSize >> 12) != 3)
79 throw new BadImageFormatException(
"Fat format method header size should be 3");
81 maxStack = br.ReadUInt16();
82 var codeLength = br.ReadInt32();
83 localVarSigTok = br.ReadInt32();
84 body = br.ReadBytes(codeLength);
85 if ((b & CorILMethod_MoreSects) != 0)
87 stream.Position = (stream.Position + 3) & ~3;
88 var hdr = br.ReadInt32();
89 if ((hdr & CorILMethod_Sect_MoreSects) != 0 || (hdr & CorILMethod_Sect_EHTable) == 0)
91 throw new NotImplementedException();
93 else if ((hdr & CorILMethod_Sect_FatFormat) != 0)
95 var count = ComputeExceptionCount((hdr >> 8) & 0xFFFFFF, 24);
96 for (
int i = 0; i < count; i++)
98 var flags = br.ReadInt32();
99 var tryOffset = br.ReadInt32();
100 var tryLength = br.ReadInt32();
101 var handlerOffset = br.ReadInt32();
102 var handlerLength = br.ReadInt32();
103 var classTokenOrFilterOffset = br.ReadInt32();
104 exceptionClauses.Add(
new ExceptionHandlingClause(module, flags, tryOffset, tryLength, handlerOffset, handlerLength, classTokenOrFilterOffset, context));
109 var count = ComputeExceptionCount((hdr >> 8) & 0xFF, 12);
110 for (
int i = 0; i < count; i++)
112 var flags = br.ReadUInt16();
113 var tryOffset = br.ReadUInt16();
114 var tryLength = br.ReadByte();
115 var handlerOffset = br.ReadUInt16();
116 var handlerLength = br.ReadByte();
117 var classTokenOrFilterOffset = br.ReadInt32();
118 exceptionClauses.Add(
new ExceptionHandlingClause(module, flags, tryOffset, tryLength, handlerOffset, handlerLength, classTokenOrFilterOffset, context));
123 if (localVarSigTok != 0)
125 var sig = module.GetStandAloneSig((localVarSigTok & 0xFFFFFF) - 1);
126 Signature.ReadLocalVarSig(module, sig, context, locals);
131 throw new BadImageFormatException();
134 this.exceptionClauses = exceptionClauses.AsReadOnly();
135 this.locals = locals.AsReadOnly();
138 static int ComputeExceptionCount(
int size,
int itemLength)
143 return size / itemLength;
146 public IList<ExceptionHandlingClause> ExceptionHandlingClauses
148 get {
return exceptionClauses; }
151 public bool InitLocals
153 get {
return initLocals; }
156 public IList<LocalVariableInfo> LocalVariables
158 get {
return locals; }
161 public byte[] GetILAsByteArray()
166 public int LocalSignatureMetadataToken
168 get {
return localVarSigTok; }
171 public int MaxStackSize
173 get {
return maxStack; }