Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
InstructionEncoder.cs
Go to the documentation of this file.
2
3public readonly struct InstructionEncoder
4{
5 public BlobBuilder CodeBuilder { get; }
6
8
9 public int Offset => CodeBuilder.Count;
10
11 public InstructionEncoder(BlobBuilder codeBuilder, ControlFlowBuilder? controlFlowBuilder = null)
12 {
13 if (codeBuilder == null)
14 {
16 }
17 CodeBuilder = codeBuilder;
18 ControlFlowBuilder = controlFlowBuilder;
19 }
20
21 public void OpCode(ILOpCode code)
22 {
23 if ((uint)(byte)code == (uint)code)
24 {
25 CodeBuilder.WriteByte((byte)code);
26 }
27 else
28 {
29 CodeBuilder.WriteUInt16BE((ushort)code);
30 }
31 }
32
37
38 public void Token(int token)
39 {
41 }
42
48
49 public void Call(EntityHandle methodHandle)
50 {
51 if (methodHandle.Kind != HandleKind.MethodDefinition && methodHandle.Kind != HandleKind.MethodSpecification && methodHandle.Kind != HandleKind.MemberReference)
52 {
53 Throw.InvalidArgument_Handle("methodHandle");
54 }
55 OpCode(ILOpCode.Call);
56 Token(methodHandle);
57 }
58
59 public void Call(MethodDefinitionHandle methodHandle)
60 {
61 OpCode(ILOpCode.Call);
62 Token(methodHandle);
63 }
64
65 public void Call(MethodSpecificationHandle methodHandle)
66 {
67 OpCode(ILOpCode.Call);
68 Token(methodHandle);
69 }
70
71 public void Call(MemberReferenceHandle methodHandle)
72 {
73 OpCode(ILOpCode.Call);
74 Token(methodHandle);
75 }
76
78 {
79 OpCode(ILOpCode.Calli);
80 Token(signature);
81 }
82
83 public void LoadConstantI4(int value)
84 {
85 ILOpCode code;
86 switch (value)
87 {
88 case -1:
89 code = ILOpCode.Ldc_i4_m1;
90 break;
91 case 0:
92 code = ILOpCode.Ldc_i4_0;
93 break;
94 case 1:
95 code = ILOpCode.Ldc_i4_1;
96 break;
97 case 2:
98 code = ILOpCode.Ldc_i4_2;
99 break;
100 case 3:
101 code = ILOpCode.Ldc_i4_3;
102 break;
103 case 4:
104 code = ILOpCode.Ldc_i4_4;
105 break;
106 case 5:
107 code = ILOpCode.Ldc_i4_5;
108 break;
109 case 6:
110 code = ILOpCode.Ldc_i4_6;
111 break;
112 case 7:
113 code = ILOpCode.Ldc_i4_7;
114 break;
115 case 8:
116 code = ILOpCode.Ldc_i4_8;
117 break;
118 default:
119 if ((sbyte)value == value)
120 {
121 OpCode(ILOpCode.Ldc_i4_s);
123 }
124 else
125 {
126 OpCode(ILOpCode.Ldc_i4);
128 }
129 return;
130 }
131 OpCode(code);
132 }
133
134 public void LoadConstantI8(long value)
135 {
136 OpCode(ILOpCode.Ldc_i8);
138 }
139
140 public void LoadConstantR4(float value)
141 {
142 OpCode(ILOpCode.Ldc_r4);
144 }
145
146 public void LoadConstantR8(double value)
147 {
148 OpCode(ILOpCode.Ldc_r8);
150 }
151
152 public void LoadLocal(int slotIndex)
153 {
154 switch (slotIndex)
155 {
156 case 0:
157 OpCode(ILOpCode.Ldloc_0);
158 return;
159 case 1:
160 OpCode(ILOpCode.Ldloc_1);
161 return;
162 case 2:
163 OpCode(ILOpCode.Ldloc_2);
164 return;
165 case 3:
166 OpCode(ILOpCode.Ldloc_3);
167 return;
168 }
169 if ((uint)slotIndex <= 255u)
170 {
171 OpCode(ILOpCode.Ldloc_s);
172 CodeBuilder.WriteByte((byte)slotIndex);
173 }
174 else if (slotIndex > 0)
175 {
176 OpCode(ILOpCode.Ldloc);
177 CodeBuilder.WriteInt32(slotIndex);
178 }
179 else
180 {
181 Throw.ArgumentOutOfRange("slotIndex");
182 }
183 }
184
185 public void StoreLocal(int slotIndex)
186 {
187 switch (slotIndex)
188 {
189 case 0:
190 OpCode(ILOpCode.Stloc_0);
191 return;
192 case 1:
193 OpCode(ILOpCode.Stloc_1);
194 return;
195 case 2:
196 OpCode(ILOpCode.Stloc_2);
197 return;
198 case 3:
199 OpCode(ILOpCode.Stloc_3);
200 return;
201 }
202 if ((uint)slotIndex <= 255u)
203 {
204 OpCode(ILOpCode.Stloc_s);
205 CodeBuilder.WriteByte((byte)slotIndex);
206 }
207 else if (slotIndex > 0)
208 {
209 OpCode(ILOpCode.Stloc);
210 CodeBuilder.WriteInt32(slotIndex);
211 }
212 else
213 {
214 Throw.ArgumentOutOfRange("slotIndex");
215 }
216 }
217
218 public void LoadLocalAddress(int slotIndex)
219 {
220 if ((uint)slotIndex <= 255u)
221 {
222 OpCode(ILOpCode.Ldloca_s);
223 CodeBuilder.WriteByte((byte)slotIndex);
224 }
225 else if (slotIndex > 0)
226 {
227 OpCode(ILOpCode.Ldloca);
228 CodeBuilder.WriteInt32(slotIndex);
229 }
230 else
231 {
232 Throw.ArgumentOutOfRange("slotIndex");
233 }
234 }
235
236 public void LoadArgument(int argumentIndex)
237 {
238 switch (argumentIndex)
239 {
240 case 0:
241 OpCode(ILOpCode.Ldarg_0);
242 return;
243 case 1:
244 OpCode(ILOpCode.Ldarg_1);
245 return;
246 case 2:
247 OpCode(ILOpCode.Ldarg_2);
248 return;
249 case 3:
250 OpCode(ILOpCode.Ldarg_3);
251 return;
252 }
253 if ((uint)argumentIndex <= 255u)
254 {
255 OpCode(ILOpCode.Ldarg_s);
256 CodeBuilder.WriteByte((byte)argumentIndex);
257 }
258 else if (argumentIndex > 0)
259 {
260 OpCode(ILOpCode.Ldarg);
261 CodeBuilder.WriteInt32(argumentIndex);
262 }
263 else
264 {
265 Throw.ArgumentOutOfRange("argumentIndex");
266 }
267 }
268
269 public void LoadArgumentAddress(int argumentIndex)
270 {
271 if ((uint)argumentIndex <= 255u)
272 {
273 OpCode(ILOpCode.Ldarga_s);
274 CodeBuilder.WriteByte((byte)argumentIndex);
275 }
276 else if (argumentIndex > 0)
277 {
278 OpCode(ILOpCode.Ldarga);
279 CodeBuilder.WriteInt32(argumentIndex);
280 }
281 else
282 {
283 Throw.ArgumentOutOfRange("argumentIndex");
284 }
285 }
286
287 public void StoreArgument(int argumentIndex)
288 {
289 if ((uint)argumentIndex <= 255u)
290 {
291 OpCode(ILOpCode.Starg_s);
292 CodeBuilder.WriteByte((byte)argumentIndex);
293 }
294 else if (argumentIndex > 0)
295 {
296 OpCode(ILOpCode.Starg);
297 CodeBuilder.WriteInt32(argumentIndex);
298 }
299 else
300 {
301 Throw.ArgumentOutOfRange("argumentIndex");
302 }
303 }
304
306 {
307 return GetBranchBuilder().AddLabel();
308 }
309
310 public void Branch(ILOpCode code, LabelHandle label)
311 {
312 int branchOperandSize = code.GetBranchOperandSize();
313 GetBranchBuilder().AddBranch(Offset, label, code);
314 OpCode(code);
315 if (branchOperandSize == 1)
316 {
318 }
319 else
320 {
322 }
323 }
324
325 public void MarkLabel(LabelHandle label)
326 {
328 }
329
331 {
332 if (ControlFlowBuilder == null)
333 {
335 }
336 return ControlFlowBuilder;
337 }
338}
void AddBranch(int ilOffset, LabelHandle label, ILOpCode opCode)
static int GetToken(this MetadataReader reader, EntityHandle handle)
static void ArgumentOutOfRange(string parameterName)
Definition Throw.cs:145
static void BuilderArgumentNull()
Definition Throw.cs:138
static Exception InvalidArgument_Handle(string parameterName)
Definition Throw.cs:40
static void ControlFlowBuilderNotAvailable()
Definition Throw.cs:54
void Call(MethodDefinitionHandle methodHandle)
void CallIndirect(StandaloneSignatureHandle signature)
void Call(MethodSpecificationHandle methodHandle)
void Call(MemberReferenceHandle methodHandle)
InstructionEncoder(BlobBuilder codeBuilder, ControlFlowBuilder? controlFlowBuilder=null)