IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
MethodBody.cs
Go to the documentation of this file.
1/*
2 Copyright (C) 2009 Jeroen Frijters
3
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
7
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
19
20 Jeroen Frijters
21 jeroen@frijters.net
22
23*/
24using System;
25using System.Collections.Generic;
26using System.IO;
27
29
30namespace IKVM.Reflection
31{
32
33 internal sealed class MethodBody
34 {
35
36 readonly IList<ExceptionHandlingClause> exceptionClauses;
37 readonly IList<LocalVariableInfo> locals;
38 readonly bool initLocals;
39 readonly int maxStack;
40 readonly int localVarSigTok;
41 readonly byte[] body;
42
51 internal MethodBody(ModuleReader module, int rva, IGenericContext context)
52 {
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;
60
61 var exceptionClauses = new List<ExceptionHandlingClause>();
62 var locals = new List<LocalVariableInfo>();
63 var stream = module.GetStream();
64 module.SeekRVA(rva);
65 var br = new BinaryReader(stream);
66
67 var b = br.ReadByte();
68 if ((b & 3) == CorILMethod_TinyFormat)
69 {
70 initLocals = true;
71 body = br.ReadBytes(b >> 2);
72 maxStack = 8;
73 }
74 else if ((b & 3) == CorILMethod_FatFormat)
75 {
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");
80
81 maxStack = br.ReadUInt16();
82 var codeLength = br.ReadInt32();
83 localVarSigTok = br.ReadInt32();
84 body = br.ReadBytes(codeLength);
85 if ((b & CorILMethod_MoreSects) != 0)
86 {
87 stream.Position = (stream.Position + 3) & ~3;
88 var hdr = br.ReadInt32();
89 if ((hdr & CorILMethod_Sect_MoreSects) != 0 || (hdr & CorILMethod_Sect_EHTable) == 0)
90 {
91 throw new NotImplementedException();
92 }
93 else if ((hdr & CorILMethod_Sect_FatFormat) != 0)
94 {
95 var count = ComputeExceptionCount((hdr >> 8) & 0xFFFFFF, 24);
96 for (int i = 0; i < count; i++)
97 {
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));
105 }
106 }
107 else
108 {
109 var count = ComputeExceptionCount((hdr >> 8) & 0xFF, 12);
110 for (int i = 0; i < count; i++)
111 {
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));
119 }
120 }
121 }
122
123 if (localVarSigTok != 0)
124 {
125 var sig = module.GetStandAloneSig((localVarSigTok & 0xFFFFFF) - 1);
126 Signature.ReadLocalVarSig(module, sig, context, locals);
127 }
128 }
129 else
130 {
131 throw new BadImageFormatException();
132 }
133
134 this.exceptionClauses = exceptionClauses.AsReadOnly();
135 this.locals = locals.AsReadOnly();
136 }
137
138 static int ComputeExceptionCount(int size, int itemLength)
139 {
140 // LAMESPEC according to the spec, the count should be calculated as "(size - 4) / itemLength",
141 // FXBUG but to workaround a VB compiler bug that specifies the size incorrectly,
142 // we do a truncating division instead.
143 return size / itemLength;
144 }
145
146 public IList<ExceptionHandlingClause> ExceptionHandlingClauses
147 {
148 get { return exceptionClauses; }
149 }
150
151 public bool InitLocals
152 {
153 get { return initLocals; }
154 }
155
156 public IList<LocalVariableInfo> LocalVariables
157 {
158 get { return locals; }
159 }
160
161 public byte[] GetILAsByteArray()
162 {
163 return body;
164 }
165
166 public int LocalSignatureMetadataToken
167 {
168 get { return localVarSigTok; }
169 }
170
171 public int MaxStackSize
172 {
173 get { return maxStack; }
174 }
175
176 }
177
178}