Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
ExceptionRegionEncoder.cs
Go to the documentation of this file.
2
3public readonly struct ExceptionRegionEncoder
4{
5 internal const int MaxSmallExceptionRegions = 20;
6
7 internal const int MaxExceptionRegions = 699050;
8
9 public BlobBuilder Builder { get; }
10
11 public bool HasSmallFormat { get; }
12
13 internal ExceptionRegionEncoder(BlobBuilder builder, bool hasSmallFormat)
14 {
15 Builder = builder;
16 HasSmallFormat = hasSmallFormat;
17 }
18
19 public static bool IsSmallRegionCount(int exceptionRegionCount)
20 {
21 return (uint)exceptionRegionCount <= 20u;
22 }
23
24 public static bool IsSmallExceptionRegion(int startOffset, int length)
25 {
26 if ((uint)startOffset <= 65535u)
27 {
28 return (uint)length <= 255u;
29 }
30 return false;
31 }
32
33 internal static bool IsSmallExceptionRegionFromBounds(int startOffset, int endOffset)
34 {
35 return IsSmallExceptionRegion(startOffset, endOffset - startOffset);
36 }
37
38 internal static int GetExceptionTableSize(int exceptionRegionCount, bool isSmallFormat)
39 {
40 return 4 + exceptionRegionCount * (isSmallFormat ? 12 : 24);
41 }
42
43 internal static bool IsExceptionRegionCountInBounds(int exceptionRegionCount)
44 {
45 return (uint)exceptionRegionCount <= 699050u;
46 }
47
48 internal static bool IsValidCatchTypeHandle(EntityHandle catchType)
49 {
50 if (!catchType.IsNil)
51 {
52 if (catchType.Kind != HandleKind.TypeDefinition && catchType.Kind != HandleKind.TypeSpecification)
53 {
54 return catchType.Kind == HandleKind.TypeReference;
55 }
56 return true;
57 }
58 return false;
59 }
60
61 internal static ExceptionRegionEncoder SerializeTableHeader(BlobBuilder builder, int exceptionRegionCount, bool hasSmallRegions)
62 {
63 bool flag = hasSmallRegions && IsSmallRegionCount(exceptionRegionCount);
64 int exceptionTableSize = GetExceptionTableSize(exceptionRegionCount, flag);
65 builder.Align(4);
66 if (flag)
67 {
68 builder.WriteByte(1);
69 builder.WriteByte((byte)exceptionTableSize);
70 builder.WriteInt16(0);
71 }
72 else
73 {
74 builder.WriteByte(65);
75 builder.WriteByte((byte)exceptionTableSize);
76 builder.WriteUInt16((ushort)(exceptionTableSize >> 8));
77 }
78 return new ExceptionRegionEncoder(builder, flag);
79 }
80
81 public ExceptionRegionEncoder AddFinally(int tryOffset, int tryLength, int handlerOffset, int handlerLength)
82 {
83 return Add(ExceptionRegionKind.Finally, tryOffset, tryLength, handlerOffset, handlerLength);
84 }
85
86 public ExceptionRegionEncoder AddFault(int tryOffset, int tryLength, int handlerOffset, int handlerLength)
87 {
88 return Add(ExceptionRegionKind.Fault, tryOffset, tryLength, handlerOffset, handlerLength);
89 }
90
91 public ExceptionRegionEncoder AddCatch(int tryOffset, int tryLength, int handlerOffset, int handlerLength, EntityHandle catchType)
92 {
93 return Add(ExceptionRegionKind.Catch, tryOffset, tryLength, handlerOffset, handlerLength, catchType);
94 }
95
96 public ExceptionRegionEncoder AddFilter(int tryOffset, int tryLength, int handlerOffset, int handlerLength, int filterOffset)
97 {
98 return Add(ExceptionRegionKind.Filter, tryOffset, tryLength, handlerOffset, handlerLength, default(EntityHandle), filterOffset);
99 }
100
101 public ExceptionRegionEncoder Add(ExceptionRegionKind kind, int tryOffset, int tryLength, int handlerOffset, int handlerLength, EntityHandle catchType = default(EntityHandle), int filterOffset = 0)
102 {
103 if (Builder == null)
104 {
106 }
107 if (HasSmallFormat)
108 {
109 if ((ushort)tryOffset != tryOffset)
110 {
111 Throw.ArgumentOutOfRange("tryOffset");
112 }
113 if ((byte)tryLength != tryLength)
114 {
115 Throw.ArgumentOutOfRange("tryLength");
116 }
117 if ((ushort)handlerOffset != handlerOffset)
118 {
119 Throw.ArgumentOutOfRange("handlerOffset");
120 }
121 if ((byte)handlerLength != handlerLength)
122 {
123 Throw.ArgumentOutOfRange("handlerLength");
124 }
125 }
126 else
127 {
128 if (tryOffset < 0)
129 {
130 Throw.ArgumentOutOfRange("tryOffset");
131 }
132 if (tryLength < 0)
133 {
134 Throw.ArgumentOutOfRange("tryLength");
135 }
136 if (handlerOffset < 0)
137 {
138 Throw.ArgumentOutOfRange("handlerOffset");
139 }
140 if (handlerLength < 0)
141 {
142 Throw.ArgumentOutOfRange("handlerLength");
143 }
144 }
145 int catchTokenOrOffset;
146 switch (kind)
147 {
148 case ExceptionRegionKind.Catch:
149 if (!IsValidCatchTypeHandle(catchType))
150 {
151 Throw.InvalidArgument_Handle("catchType");
152 }
153 catchTokenOrOffset = MetadataTokens.GetToken(catchType);
154 break;
155 case ExceptionRegionKind.Filter:
156 if (filterOffset < 0)
157 {
158 Throw.ArgumentOutOfRange("filterOffset");
159 }
160 catchTokenOrOffset = filterOffset;
161 break;
162 case ExceptionRegionKind.Finally:
163 case ExceptionRegionKind.Fault:
164 catchTokenOrOffset = 0;
165 break;
166 default:
167 throw new ArgumentOutOfRangeException("kind");
168 }
169 AddUnchecked(kind, tryOffset, tryLength, handlerOffset, handlerLength, catchTokenOrOffset);
170 return this;
171 }
172
173 internal void AddUnchecked(ExceptionRegionKind kind, int tryOffset, int tryLength, int handlerOffset, int handlerLength, int catchTokenOrOffset)
174 {
175 if (HasSmallFormat)
176 {
177 Builder.WriteUInt16((ushort)kind);
178 Builder.WriteUInt16((ushort)tryOffset);
179 Builder.WriteByte((byte)tryLength);
180 Builder.WriteUInt16((ushort)handlerOffset);
181 Builder.WriteByte((byte)handlerLength);
182 }
183 else
184 {
185 Builder.WriteInt32((int)kind);
186 Builder.WriteInt32(tryOffset);
187 Builder.WriteInt32(tryLength);
188 Builder.WriteInt32(handlerOffset);
189 Builder.WriteInt32(handlerLength);
190 }
191 Builder.WriteInt32(catchTokenOrOffset);
192 }
193}
static int GetToken(this MetadataReader reader, EntityHandle handle)
static void InvalidOperation(string message)
Definition Throw.cs:68
static void ArgumentOutOfRange(string parameterName)
Definition Throw.cs:145
static Exception InvalidArgument_Handle(string parameterName)
Definition Throw.cs:40
static string MethodHasNoExceptionRegions
Definition SR.cs:238
Definition SR.cs:7
ExceptionRegionEncoder AddFinally(int tryOffset, int tryLength, int handlerOffset, int handlerLength)
ExceptionRegionEncoder(BlobBuilder builder, bool hasSmallFormat)
static bool IsSmallExceptionRegionFromBounds(int startOffset, int endOffset)
static bool IsExceptionRegionCountInBounds(int exceptionRegionCount)
void AddUnchecked(ExceptionRegionKind kind, int tryOffset, int tryLength, int handlerOffset, int handlerLength, int catchTokenOrOffset)
ExceptionRegionEncoder AddCatch(int tryOffset, int tryLength, int handlerOffset, int handlerLength, EntityHandle catchType)
static ExceptionRegionEncoder SerializeTableHeader(BlobBuilder builder, int exceptionRegionCount, bool hasSmallRegions)
ExceptionRegionEncoder AddFilter(int tryOffset, int tryLength, int handlerOffset, int handlerLength, int filterOffset)
ExceptionRegionEncoder AddFault(int tryOffset, int tryLength, int handlerOffset, int handlerLength)
static bool IsSmallExceptionRegion(int startOffset, int length)
ExceptionRegionEncoder Add(ExceptionRegionKind kind, int tryOffset, int tryLength, int handlerOffset, int handlerLength, EntityHandle catchType=default(EntityHandle), int filterOffset=0)
static int GetExceptionTableSize(int exceptionRegionCount, bool isSmallFormat)