IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
ExceptionHandler.cs
Go to the documentation of this file.
1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3
4// Copied from .NET Core RuntimeMethodBuilder as of 1/24/2024.
5
6using System;
7using System.Diagnostics;
8using System.Runtime.InteropServices;
9
11{
12
13
17 [StructLayout(LayoutKind.Sequential)]
18 internal readonly struct ExceptionHandler : IEquatable<ExceptionHandler>
19 {
20 // Keep in sync with unmanged structure.
21 internal readonly int m_exceptionClass;
22 internal readonly int m_tryStartOffset;
23 internal readonly int m_tryEndOffset;
24 internal readonly int m_filterOffset;
25 internal readonly int m_handlerStartOffset;
26 internal readonly int m_handlerEndOffset;
27 internal readonly ExceptionHandlingClauseOptions m_kind;
28
29 public int ExceptionTypeToken
30 {
31 get { return m_exceptionClass; }
32 }
33
34 public int TryOffset
35 {
36 get { return m_tryStartOffset; }
37 }
38
39 public int TryLength
40 {
41 get { return m_tryEndOffset - m_tryStartOffset; }
42 }
43
44 public int FilterOffset
45 {
46 get { return m_filterOffset; }
47 }
48
49 public int HandlerOffset
50 {
51 get { return m_handlerStartOffset; }
52 }
53
54 public int HandlerLength
55 {
56 get { return m_handlerEndOffset - m_handlerStartOffset; }
57 }
58
59 public ExceptionHandlingClauseOptions Kind
60 {
61 get { return m_kind; }
62 }
63
64 #region Constructors
65
81 public ExceptionHandler(int tryOffset, int tryLength, int filterOffset, int handlerOffset, int handlerLength,
82 ExceptionHandlingClauseOptions kind, int exceptionTypeToken)
83 {
84 if (tryOffset < 0)
85 {
86 throw new ArgumentOutOfRangeException("tryOffset", string.Format("Non-negative number required."));
87 }
88
89 if (tryLength < 0)
90 {
91 throw new ArgumentOutOfRangeException("tryLength", string.Format("Non-negative number required."));
92 }
93
94 if (filterOffset < 0)
95 {
96 throw new ArgumentOutOfRangeException("filterOffset", string.Format("Non-negative number required."));
97 }
98
99 if (handlerOffset < 0)
100 {
101 throw new ArgumentOutOfRangeException("handlerOffset", string.Format("Non-negative number required."));
102 }
103
104 if (handlerLength < 0)
105 {
106 throw new ArgumentOutOfRangeException("handlerLength", string.Format("Non-negative number required."));
107 }
108
109 if ((long)tryOffset + tryLength > Int32.MaxValue)
110 {
111 throw new ArgumentOutOfRangeException("tryLength", string.Format("Valid values are between {0} and {1}, inclusive.", 0, Int32.MaxValue - tryOffset));
112 }
113
114 if ((long)handlerOffset + handlerLength > Int32.MaxValue)
115 {
116 throw new ArgumentOutOfRangeException("handlerLength", string.Format("Valid values are between {0} and {1}, inclusive.", 0, Int32.MaxValue - handlerOffset));
117 }
118
119 // Other tokens migth also be invalid. We only check nil tokens as the implementation (SectEH_Emit in corhlpr.cpp) requires it,
120 // and we can't check for valid tokens until the module is baked.
121 if (kind == ExceptionHandlingClauseOptions.Clause && (exceptionTypeToken & 0x00FFFFFF) == 0)
122 {
123 throw new ArgumentException(string.Format("Token {0:x} is not a valid Type token.", exceptionTypeToken), "exceptionTypeToken");
124 }
125
126 if (!IsValidKind(kind))
127 {
128 throw new ArgumentOutOfRangeException("kind", string.Format("Enum value was out of legal range."));
129 }
130
131 m_tryStartOffset = tryOffset;
132 m_tryEndOffset = tryOffset + tryLength;
133 m_filterOffset = filterOffset;
134 m_handlerStartOffset = handlerOffset;
135 m_handlerEndOffset = handlerOffset + handlerLength;
136 m_kind = kind;
137 m_exceptionClass = exceptionTypeToken;
138 }
139
140 internal ExceptionHandler(int tryStartOffset, int tryEndOffset, int filterOffset, int handlerStartOffset, int handlerEndOffset,
141 int kind, int exceptionTypeToken)
142 {
143 Debug.Assert(tryStartOffset >= 0);
144 Debug.Assert(tryEndOffset >= 0);
145 Debug.Assert(filterOffset >= 0);
146 Debug.Assert(handlerStartOffset >= 0);
147 Debug.Assert(handlerEndOffset >= 0);
148 Debug.Assert(IsValidKind((ExceptionHandlingClauseOptions)kind));
149 Debug.Assert(kind != (int)ExceptionHandlingClauseOptions.Clause || (exceptionTypeToken & 0x00FFFFFF) != 0);
150
151 m_tryStartOffset = tryStartOffset;
152 m_tryEndOffset = tryEndOffset;
153 m_filterOffset = filterOffset;
154 m_handlerStartOffset = handlerStartOffset;
155 m_handlerEndOffset = handlerEndOffset;
156 m_kind = (ExceptionHandlingClauseOptions)kind;
157 m_exceptionClass = exceptionTypeToken;
158 }
159
160 private static bool IsValidKind(ExceptionHandlingClauseOptions kind)
161 {
162 switch (kind)
163 {
164 case ExceptionHandlingClauseOptions.Clause:
165 case ExceptionHandlingClauseOptions.Filter:
166 case ExceptionHandlingClauseOptions.Finally:
167 case ExceptionHandlingClauseOptions.Fault:
168 return true;
169
170 default:
171 return false;
172 }
173 }
174
175 #endregion
176
177 #region Equality
178
179 public override int GetHashCode()
180 {
181 return m_exceptionClass ^ m_tryStartOffset ^ m_tryEndOffset ^ m_filterOffset ^ m_handlerStartOffset ^ m_handlerEndOffset ^ (int)m_kind;
182 }
183
184 public override bool Equals(Object obj)
185 {
186 return obj is ExceptionHandler && Equals((ExceptionHandler)obj);
187 }
188
189 public bool Equals(ExceptionHandler other)
190 {
191 return
192 other.m_exceptionClass == m_exceptionClass &&
193 other.m_tryStartOffset == m_tryStartOffset &&
194 other.m_tryEndOffset == m_tryEndOffset &&
195 other.m_filterOffset == m_filterOffset &&
196 other.m_handlerStartOffset == m_handlerStartOffset &&
197 other.m_handlerEndOffset == m_handlerEndOffset &&
198 other.m_kind == m_kind;
199 }
200
201 public static bool operator ==(ExceptionHandler left, ExceptionHandler right)
202 {
203 return left.Equals(right);
204 }
205
206 public static bool operator !=(ExceptionHandler left, ExceptionHandler right)
207 {
208 return !left.Equals(right);
209 }
210
211 #endregion
212
213 }
214
215}