Terraria v1.4.4.9
Terraria source code documentation
All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Events Macros
CompilerScope.cs
Go to the documentation of this file.
7
9
10internal sealed class CompilerScope
11{
12 private abstract class Storage
13 {
14 internal readonly LambdaCompiler Compiler;
15
16 internal readonly ParameterExpression Variable;
17
23
24 internal abstract void EmitLoad();
25
26 internal abstract void EmitAddress();
27
28 internal abstract void EmitStore();
29
30 internal virtual void EmitStore(Storage value)
31 {
32 value.EmitLoad();
33 EmitStore();
34 }
35
36 internal virtual void FreeLocal()
37 {
38 }
39 }
40
41 private sealed class LocalStorage : Storage
42 {
43 private readonly LocalBuilder _local;
44
47 {
48 _local = compiler.GetLocal(variable.IsByRef ? variable.Type.MakeByRefType() : variable.Type);
49 }
50
51 internal override void EmitLoad()
52 {
53 Compiler.IL.Emit(OpCodes.Ldloc, _local);
54 }
55
56 internal override void EmitStore()
57 {
58 Compiler.IL.Emit(OpCodes.Stloc, _local);
59 }
60
61 internal override void EmitAddress()
62 {
63 Compiler.IL.Emit(OpCodes.Ldloca, _local);
64 }
65
66 internal override void FreeLocal()
67 {
68 Compiler.FreeLocal(_local);
69 }
70 }
71
72 private sealed class ArgumentStorage : Storage
73 {
74 private readonly int _argument;
75
77 : base(compiler, p)
78 {
79 _argument = compiler.GetLambdaArgument(compiler.Parameters.IndexOf(p));
80 }
81
82 internal override void EmitLoad()
83 {
84 Compiler.IL.EmitLoadArg(_argument);
85 }
86
87 internal override void EmitStore()
88 {
89 Compiler.IL.EmitStoreArg(_argument);
90 }
91
92 internal override void EmitAddress()
93 {
94 Compiler.IL.EmitLoadArgAddress(_argument);
95 }
96 }
97
98 private sealed class ElementBoxStorage : Storage
99 {
100 private readonly int _index;
101
102 private readonly Storage _array;
103
104 private readonly Type _boxType;
105
106 private readonly FieldInfo _boxValueField;
107
109 : base(array.Compiler, variable)
110 {
111 _array = array;
112 _index = index;
113 Type type = typeof(StrongBox<>).MakeGenericType(variable.Type);
114 _boxValueField = type.GetField("Value");
115 _boxType = type;
116 }
117
118 internal override void EmitLoad()
119 {
120 EmitLoadBox();
121 Compiler.IL.Emit(OpCodes.Ldfld, _boxValueField);
122 }
123
124 internal override void EmitStore()
125 {
126 LocalBuilder local = Compiler.GetLocal(Variable.Type);
127 Compiler.IL.Emit(OpCodes.Stloc, local);
128 EmitLoadBox();
129 Compiler.IL.Emit(OpCodes.Ldloc, local);
130 Compiler.FreeLocal(local);
131 Compiler.IL.Emit(OpCodes.Stfld, _boxValueField);
132 }
133
134 internal override void EmitStore(Storage value)
135 {
136 EmitLoadBox();
137 value.EmitLoad();
138 Compiler.IL.Emit(OpCodes.Stfld, _boxValueField);
139 }
140
141 internal override void EmitAddress()
142 {
143 EmitLoadBox();
144 Compiler.IL.Emit(OpCodes.Ldflda, _boxValueField);
145 }
146
147 internal void EmitLoadBox()
148 {
150 Compiler.IL.EmitPrimitive(_index);
151 Compiler.IL.Emit(OpCodes.Ldelem_Ref);
152 Compiler.IL.Emit(OpCodes.Castclass, _boxType);
153 }
154 }
155
156 private sealed class LocalBoxStorage : Storage
157 {
158 private readonly LocalBuilder _boxLocal;
159
160 private readonly FieldInfo _boxValueField;
161
164 {
165 Type type = typeof(StrongBox<>).MakeGenericType(variable.Type);
166 _boxValueField = type.GetField("Value");
167 _boxLocal = compiler.GetLocal(type);
168 }
169
170 internal override void EmitLoad()
171 {
172 Compiler.IL.Emit(OpCodes.Ldloc, _boxLocal);
173 Compiler.IL.Emit(OpCodes.Ldfld, _boxValueField);
174 }
175
176 internal override void EmitAddress()
177 {
178 Compiler.IL.Emit(OpCodes.Ldloc, _boxLocal);
179 Compiler.IL.Emit(OpCodes.Ldflda, _boxValueField);
180 }
181
182 internal override void EmitStore()
183 {
184 LocalBuilder local = Compiler.GetLocal(Variable.Type);
185 Compiler.IL.Emit(OpCodes.Stloc, local);
186 Compiler.IL.Emit(OpCodes.Ldloc, _boxLocal);
187 Compiler.IL.Emit(OpCodes.Ldloc, local);
188 Compiler.FreeLocal(local);
189 Compiler.IL.Emit(OpCodes.Stfld, _boxValueField);
190 }
191
192 internal override void EmitStore(Storage value)
193 {
194 Compiler.IL.Emit(OpCodes.Ldloc, _boxLocal);
195 value.EmitLoad();
196 Compiler.IL.Emit(OpCodes.Stfld, _boxValueField);
197 }
198
199 internal void EmitStoreBox()
200 {
201 Compiler.IL.Emit(OpCodes.Stloc, _boxLocal);
202 }
203
204 internal override void FreeLocal()
205 {
206 Compiler.FreeLocal(_boxLocal);
207 }
208 }
209
211
212 internal readonly object Node;
213
214 internal readonly bool IsMethod;
215
216 internal bool NeedsClosure;
217
219
221
223
225
227
229
231
232 private string CurrentLambdaName
233 {
234 get
235 {
237 {
239 {
240 return lambdaExpression.Name;
241 }
242 }
244 }
245 }
246
258
260 {
261 SetParent(lc, parent);
263 if (IsMethod && _closureHoistedLocals != null)
264 {
266 }
268 if (IsMethod)
269 {
271 }
272 return this;
273 }
274
276 {
277 if (!IsMethod)
278 {
279 foreach (Storage value in _locals.Values)
280 {
281 value.FreeLocal();
282 }
283 }
284 CompilerScope parent = _parent;
285 _parent = null;
286 _hoistedLocals = null;
288 _locals.Clear();
289 return parent;
290 }
291
293 {
294 if (NearestHoistedLocals != null && vars.Count > 0)
295 {
297 foreach (ParameterExpression var in vars)
298 {
299 ulong num = 0uL;
301 while (!hoistedLocals.Indexes.ContainsKey(var))
302 {
303 num++;
305 }
306 ulong item = (num << 32) | (uint)hoistedLocals.Indexes[var];
307 arrayBuilder.UncheckedAdd((long)item);
308 }
310 lc.EmitConstantArray(arrayBuilder.ToArray());
312 }
313 else
314 {
316 }
317 }
318
323
328
333
338
343
345 {
347 {
349 {
350 return value;
351 }
352 if (compilerScope.IsMethod)
353 {
354 break;
355 }
356 }
358 {
360 {
362 }
363 }
365 }
366
383
385 {
386 if (_hoistedLocals == null)
387 {
388 return;
389 }
390 lc.IL.EmitPrimitive(_hoistedLocals.Variables.Count);
391 lc.IL.Emit(OpCodes.Newarr, typeof(object));
392 int num = 0;
394 {
395 lc.IL.Emit(OpCodes.Dup);
396 lc.IL.EmitPrimitive(num++);
397 Type type = typeof(StrongBox<>).MakeGenericType(variable.Type);
398 int index;
399 if (IsMethod && (index = lc.Parameters.IndexOf(variable)) >= 0)
400 {
401 lc.EmitLambdaArgument(index);
402 lc.IL.Emit(OpCodes.Newobj, type.GetConstructor(new Type[1] { variable.Type }));
403 }
405 {
407 lc.IL.Emit(OpCodes.Newobj, type.GetConstructor(new Type[1] { variable.Type }));
408 }
409 else
410 {
411 lc.IL.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes));
412 }
414 {
415 lc.IL.Emit(OpCodes.Dup);
417 }
418 lc.IL.Emit(OpCodes.Stelem_Ref);
419 }
421 }
422
423 private void EmitCachedVariables()
424 {
425 if (ReferenceCount == null)
426 {
427 return;
428 }
430 {
432 {
433 elementBoxStorage.EmitLoadBox();
435 }
436 }
437 }
438
440 {
441 if (refCount > 2)
442 {
443 return !_locals.ContainsKey(v);
444 }
445 return false;
446 }
447
449 {
450 if (ReferenceCount == null)
451 {
452 return false;
453 }
455 {
456 return ShouldCache(v, value);
457 }
458 return false;
459 }
460
467
469 {
470 if (locals != null)
471 {
473 while ((locals = locals.Parent) != null)
474 {
479 }
480 }
481 }
482
484 {
485 lc.EmitClosureArgument();
487 AddLocal(lc, locals.SelfVariable);
488 EmitSet(locals.SelfVariable);
489 }
490
492 {
494 {
496 {
499 }
500 }
501 }
502
504 {
505 if (MergedScopes != null)
506 {
508 }
509 return GetVariables(Node);
510 }
511
513 {
515 {
516 yield return variable;
517 }
519 {
520 foreach (ParameterExpression variable2 in mergedScope.Variables)
521 {
522 yield return variable2;
523 }
524 }
525 }
526
528 {
529 if (scope is LambdaExpression provider)
530 {
531 return new ParameterList(provider);
532 }
534 {
535 return new ParameterExpression[1] { ((CatchBlock)scope).Variable };
536 }
537 return blockExpression.Variables;
538 }
539}
bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
bool ICollection< KeyValuePair< TKey, TValue > >. Contains(KeyValuePair< TKey, TValue > keyValuePair)
void Add(TKey key, TValue value)
ArgumentStorage(LambdaCompiler compiler, ParameterExpression p)
ElementBoxStorage(Storage array, int index, ParameterExpression variable)
LocalBoxStorage(LambdaCompiler compiler, ParameterExpression variable)
LocalStorage(LambdaCompiler compiler, ParameterExpression variable)
Storage(LambdaCompiler compiler, ParameterExpression variable)
IEnumerable< ParameterExpression > GetVariables()
void SetParent(LambdaCompiler lc, CompilerScope parent)
void EmitSet(ParameterExpression variable)
void EmitGet(ParameterExpression variable)
static IReadOnlyList< ParameterExpression > GetVariables(object scope)
CompilerScope Enter(LambdaCompiler lc, CompilerScope parent)
Storage ResolveVariable(ParameterExpression variable)
void EmitAddressOf(ParameterExpression variable)
void CacheBoxToLocal(LambdaCompiler lc, ParameterExpression v)
void EmitVariableAccess(LambdaCompiler lc, ReadOnlyCollection< ParameterExpression > vars)
void EmitClosureToVariable(LambdaCompiler lc, HoistedLocals locals)
void EmitClosureAccess(LambdaCompiler lc, HoistedLocals locals)
IEnumerable< ParameterExpression > GetVariablesIncludingMerged()
readonly Dictionary< ParameterExpression, VariableStorageKind > Definitions
Dictionary< ParameterExpression, int > ReferenceCount
bool ShouldCache(ParameterExpression v, int refCount)
Storage ResolveVariable(ParameterExpression variable, HoistedLocals hoistedLocals)
void AddLocal(LambdaCompiler gen, ParameterExpression variable)
readonly Dictionary< ParameterExpression, Storage > _locals
readonly ParameterExpression SelfVariable
readonly ReadOnlyCollection< ParameterExpression > Variables
static Exception UndefinedVariable(object p0, object p1, object p2)
Definition Error.cs:758
static ParameterExpression Variable(Type type)
static readonly OpCode Castclass
Definition OpCodes.cs:235
static readonly OpCode Ldloca
Definition OpCodes.cs:427
static readonly OpCode Stloc
Definition OpCodes.cs:429
static readonly OpCode Newobj
Definition OpCodes.cs:233
static readonly OpCode Ldflda
Definition OpCodes.cs:247
static readonly OpCode Stelem_Ref
Definition OpCodes.cs:323
static readonly OpCode Ldfld
Definition OpCodes.cs:245
static readonly OpCode Ldelem_Ref
Definition OpCodes.cs:307
static readonly OpCode Call
Definition OpCodes.cs:83
static readonly OpCode Ldloc
Definition OpCodes.cs:425
static readonly OpCode Dup
Definition OpCodes.cs:77
static readonly OpCode Stfld
Definition OpCodes.cs:249
static readonly OpCode Newarr
Definition OpCodes.cs:281
static readonly Type[] EmptyTypes
Definition Type.cs:19