using System; using System.Collections.Generic; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; namespace System.Linq.Expressions { // Token: 0x0200001C RID: 28 internal class EmitContext { // Token: 0x0600017B RID: 379 RVA: 0x000094BC File Offset: 0x000076BC public EmitContext(CompilationContext context, EmitContext parent, LambdaExpression lambda) { this.context = context; this.parent = parent; this.lambda = lambda; this.hoisted = context.GetHoistedLocals(lambda); this.method = new DynamicMethod("lambda_method", lambda.GetReturnType(), EmitContext.CreateParameterTypes(lambda.Parameters), typeof(ExecutionScope), true); this.ig = this.method.GetILGenerator(); } // Token: 0x1700001D RID: 29 // (get) Token: 0x0600017C RID: 380 RVA: 0x00009530 File Offset: 0x00007730 public bool HasHoistedLocals { get { return this.hoisted != null && this.hoisted.Count > 0; } } // Token: 0x1700001E RID: 30 // (get) Token: 0x0600017D RID: 381 RVA: 0x00009550 File Offset: 0x00007750 public LambdaExpression Lambda { get { return this.lambda; } } // Token: 0x0600017E RID: 382 RVA: 0x00009558 File Offset: 0x00007758 public void Emit() { if (this.HasHoistedLocals) { this.EmitStoreHoistedLocals(); } this.lambda.EmitBody(this); } // Token: 0x0600017F RID: 383 RVA: 0x00009578 File Offset: 0x00007778 private static Type[] CreateParameterTypes(IList parameters) { Type[] array = new Type[parameters.Count + 1]; array[0] = typeof(ExecutionScope); for (int i = 0; i < parameters.Count; i++) { array[i + 1] = parameters[i].Type; } return array; } // Token: 0x06000180 RID: 384 RVA: 0x000095CC File Offset: 0x000077CC public bool IsLocalParameter(ParameterExpression parameter, ref int position) { position = this.lambda.Parameters.IndexOf(parameter); if (position > -1) { position++; return true; } return false; } // Token: 0x06000181 RID: 385 RVA: 0x00009600 File Offset: 0x00007800 public Delegate CreateDelegate(ExecutionScope scope) { return this.method.CreateDelegate(this.lambda.Type, scope); } // Token: 0x06000182 RID: 386 RVA: 0x0000961C File Offset: 0x0000781C public void Emit(Expression expression) { expression.Emit(this); } // Token: 0x06000183 RID: 387 RVA: 0x00009628 File Offset: 0x00007828 public LocalBuilder EmitStored(Expression expression) { LocalBuilder localBuilder = this.ig.DeclareLocal(expression.Type); expression.Emit(this); this.ig.Emit(OpCodes.Stloc, localBuilder); return localBuilder; } // Token: 0x06000184 RID: 388 RVA: 0x00009660 File Offset: 0x00007860 public void EmitLoadAddress(Expression expression) { this.ig.Emit(OpCodes.Ldloca, this.EmitStored(expression)); } // Token: 0x06000185 RID: 389 RVA: 0x0000967C File Offset: 0x0000787C public void EmitLoadSubject(Expression expression) { if (expression.Type.IsValueType) { this.EmitLoadAddress(expression); return; } this.Emit(expression); } // Token: 0x06000186 RID: 390 RVA: 0x000096A8 File Offset: 0x000078A8 public void EmitLoadSubject(LocalBuilder local) { if (local.LocalType.IsValueType) { this.EmitLoadAddress(local); return; } this.EmitLoad(local); } // Token: 0x06000187 RID: 391 RVA: 0x000096D4 File Offset: 0x000078D4 public void EmitLoadAddress(LocalBuilder local) { this.ig.Emit(OpCodes.Ldloca, local); } // Token: 0x06000188 RID: 392 RVA: 0x000096E8 File Offset: 0x000078E8 public void EmitLoad(LocalBuilder local) { this.ig.Emit(OpCodes.Ldloc, local); } // Token: 0x06000189 RID: 393 RVA: 0x000096FC File Offset: 0x000078FC public void EmitCall(LocalBuilder local, IList arguments, MethodInfo method) { this.EmitLoadSubject(local); this.EmitArguments(method, arguments); this.EmitCall(method); } // Token: 0x0600018A RID: 394 RVA: 0x00009714 File Offset: 0x00007914 public void EmitCall(LocalBuilder local, MethodInfo method) { this.EmitLoadSubject(local); this.EmitCall(method); } // Token: 0x0600018B RID: 395 RVA: 0x00009724 File Offset: 0x00007924 public void EmitCall(Expression expression, MethodInfo method) { if (!method.IsStatic) { this.EmitLoadSubject(expression); } this.EmitCall(method); } // Token: 0x0600018C RID: 396 RVA: 0x00009740 File Offset: 0x00007940 public void EmitCall(Expression expression, IList arguments, MethodInfo method) { if (!method.IsStatic) { this.EmitLoadSubject(expression); } this.EmitArguments(method, arguments); this.EmitCall(method); } // Token: 0x0600018D RID: 397 RVA: 0x00009770 File Offset: 0x00007970 private void EmitArguments(MethodInfo method, IList arguments) { ParameterInfo[] parameters = method.GetParameters(); for (int i = 0; i < parameters.Length; i++) { ParameterInfo parameterInfo = parameters[i]; Expression expression = arguments[i]; if (parameterInfo.ParameterType.IsByRef) { this.ig.Emit(OpCodes.Ldloca, this.EmitStored(expression)); } else { this.Emit(arguments[i]); } } } // Token: 0x0600018E RID: 398 RVA: 0x000097E0 File Offset: 0x000079E0 public void EmitCall(MethodInfo method) { this.ig.Emit((!method.IsVirtual) ? OpCodes.Call : OpCodes.Callvirt, method); } // Token: 0x0600018F RID: 399 RVA: 0x00009814 File Offset: 0x00007A14 public void EmitNullableHasValue(LocalBuilder local) { this.EmitCall(local, "get_HasValue"); } // Token: 0x06000190 RID: 400 RVA: 0x00009824 File Offset: 0x00007A24 public void EmitNullableInitialize(LocalBuilder local) { this.ig.Emit(OpCodes.Ldloca, local); this.ig.Emit(OpCodes.Initobj, local.LocalType); this.ig.Emit(OpCodes.Ldloc, local); } // Token: 0x06000191 RID: 401 RVA: 0x0000986C File Offset: 0x00007A6C public void EmitNullableGetValue(LocalBuilder local) { this.EmitCall(local, "get_Value"); } // Token: 0x06000192 RID: 402 RVA: 0x0000987C File Offset: 0x00007A7C public void EmitNullableGetValueOrDefault(LocalBuilder local) { this.EmitCall(local, "GetValueOrDefault"); } // Token: 0x06000193 RID: 403 RVA: 0x0000988C File Offset: 0x00007A8C private void EmitCall(LocalBuilder local, string method_name) { this.EmitCall(local, local.LocalType.GetMethod(method_name, Type.EmptyTypes)); } // Token: 0x06000194 RID: 404 RVA: 0x000098A8 File Offset: 0x00007AA8 public void EmitNullableNew(Type of) { this.ig.Emit(OpCodes.Newobj, of.GetConstructor(new Type[] { of.GetFirstGenericArgument() })); } // Token: 0x06000195 RID: 405 RVA: 0x000098D0 File Offset: 0x00007AD0 public void EmitCollection(IEnumerable collection) where T : Expression { foreach (T t in collection) { t.Emit(this); } } // Token: 0x06000196 RID: 406 RVA: 0x00009938 File Offset: 0x00007B38 public void EmitCollection(IEnumerable initializers, LocalBuilder local) { foreach (ElementInit elementInit in initializers) { elementInit.Emit(this, local); } } // Token: 0x06000197 RID: 407 RVA: 0x00009998 File Offset: 0x00007B98 public void EmitCollection(IEnumerable bindings, LocalBuilder local) { foreach (MemberBinding memberBinding in bindings) { memberBinding.Emit(this, local); } } // Token: 0x06000198 RID: 408 RVA: 0x000099F8 File Offset: 0x00007BF8 public void EmitIsInst(Expression expression, Type candidate) { expression.Emit(this); Type type = expression.Type; if (type.IsValueType) { this.ig.Emit(OpCodes.Box, type); } this.ig.Emit(OpCodes.Isinst, candidate); } // Token: 0x06000199 RID: 409 RVA: 0x00009A40 File Offset: 0x00007C40 public void EmitScope() { this.ig.Emit(OpCodes.Ldarg_0); } // Token: 0x0600019A RID: 410 RVA: 0x00009A54 File Offset: 0x00007C54 public void EmitReadGlobal(object global) { this.EmitReadGlobal(global, global.GetType()); } // Token: 0x0600019B RID: 411 RVA: 0x00009A64 File Offset: 0x00007C64 public void EmitLoadGlobals() { this.EmitScope(); this.ig.Emit(OpCodes.Ldfld, typeof(ExecutionScope).GetField("Globals")); } // Token: 0x0600019C RID: 412 RVA: 0x00009A9C File Offset: 0x00007C9C public void EmitReadGlobal(object global, Type type) { this.EmitLoadGlobals(); this.ig.Emit(OpCodes.Ldc_I4, this.AddGlobal(global, type)); this.ig.Emit(OpCodes.Ldelem, typeof(object)); this.EmitLoadStrongBoxValue(type); } // Token: 0x0600019D RID: 413 RVA: 0x00009AE8 File Offset: 0x00007CE8 public void EmitLoadStrongBoxValue(Type type) { Type type2 = type.MakeStrongBoxType(); this.ig.Emit(OpCodes.Isinst, type2); this.ig.Emit(OpCodes.Ldfld, type2.GetField("Value")); } // Token: 0x0600019E RID: 414 RVA: 0x00009B28 File Offset: 0x00007D28 private int AddGlobal(object value, Type type) { return this.context.AddGlobal(EmitContext.CreateStrongBox(value, type)); } // Token: 0x0600019F RID: 415 RVA: 0x00009B3C File Offset: 0x00007D3C public void EmitCreateDelegate(LambdaExpression lambda) { this.EmitScope(); this.ig.Emit(OpCodes.Ldc_I4, this.AddChildContext(lambda)); if (this.hoisted_store != null) { this.ig.Emit(OpCodes.Ldloc, this.hoisted_store); } else { this.ig.Emit(OpCodes.Ldnull); } this.ig.Emit(OpCodes.Callvirt, typeof(ExecutionScope).GetMethod("CreateDelegate")); this.ig.Emit(OpCodes.Castclass, lambda.Type); } // Token: 0x060001A0 RID: 416 RVA: 0x00009BD8 File Offset: 0x00007DD8 private void EmitStoreHoistedLocals() { this.EmitHoistedLocalsStore(); for (int i = 0; i < this.hoisted.Count; i++) { this.EmitStoreHoistedLocal(i, this.hoisted[i]); } } // Token: 0x060001A1 RID: 417 RVA: 0x00009C1C File Offset: 0x00007E1C private void EmitStoreHoistedLocal(int position, ParameterExpression parameter) { this.ig.Emit(OpCodes.Ldloc, this.hoisted_store); this.ig.Emit(OpCodes.Ldc_I4, position); parameter.Emit(this); this.EmitCreateStrongBox(parameter.Type); this.ig.Emit(OpCodes.Stelem, typeof(object)); } // Token: 0x060001A2 RID: 418 RVA: 0x00009C80 File Offset: 0x00007E80 public void EmitLoadHoistedLocalsStore() { this.ig.Emit(OpCodes.Ldloc, this.hoisted_store); } // Token: 0x060001A3 RID: 419 RVA: 0x00009C98 File Offset: 0x00007E98 private void EmitCreateStrongBox(Type type) { this.ig.Emit(OpCodes.Newobj, type.MakeStrongBoxType().GetConstructor(new Type[] { type })); } // Token: 0x060001A4 RID: 420 RVA: 0x00009CC0 File Offset: 0x00007EC0 private void EmitHoistedLocalsStore() { this.EmitScope(); this.hoisted_store = this.ig.DeclareLocal(typeof(object[])); this.ig.Emit(OpCodes.Callvirt, typeof(ExecutionScope).GetMethod("CreateHoistedLocals")); this.ig.Emit(OpCodes.Stloc, this.hoisted_store); } // Token: 0x060001A5 RID: 421 RVA: 0x00009D28 File Offset: 0x00007F28 public void EmitLoadLocals() { this.ig.Emit(OpCodes.Ldfld, typeof(ExecutionScope).GetField("Locals")); } // Token: 0x060001A6 RID: 422 RVA: 0x00009D5C File Offset: 0x00007F5C public void EmitParentScope() { this.ig.Emit(OpCodes.Ldfld, typeof(ExecutionScope).GetField("Parent")); } // Token: 0x060001A7 RID: 423 RVA: 0x00009D90 File Offset: 0x00007F90 public void EmitIsolateExpression() { this.ig.Emit(OpCodes.Callvirt, typeof(ExecutionScope).GetMethod("IsolateExpression")); } // Token: 0x060001A8 RID: 424 RVA: 0x00009DC4 File Offset: 0x00007FC4 public int IndexOfHoistedLocal(ParameterExpression parameter) { if (!this.HasHoistedLocals) { return -1; } return this.hoisted.IndexOf(parameter); } // Token: 0x060001A9 RID: 425 RVA: 0x00009DE0 File Offset: 0x00007FE0 public bool IsHoistedLocal(ParameterExpression parameter, ref int level, ref int position) { if (this.parent == null) { return false; } if (this.parent.hoisted != null) { position = this.parent.hoisted.IndexOf(parameter); if (position > -1) { return true; } } level++; return this.parent.IsHoistedLocal(parameter, ref level, ref position); } // Token: 0x060001AA RID: 426 RVA: 0x00009E3C File Offset: 0x0000803C private int AddChildContext(LambdaExpression lambda) { return this.context.AddCompilationUnit(this, lambda); } // Token: 0x060001AB RID: 427 RVA: 0x00009E4C File Offset: 0x0000804C private static object CreateStrongBox(object value, Type type) { return Activator.CreateInstance(type.MakeStrongBoxType(), new object[] { value }); } // Token: 0x0400006D RID: 109 private CompilationContext context; // Token: 0x0400006E RID: 110 private EmitContext parent; // Token: 0x0400006F RID: 111 private LambdaExpression lambda; // Token: 0x04000070 RID: 112 private DynamicMethod method; // Token: 0x04000071 RID: 113 private LocalBuilder hoisted_store; // Token: 0x04000072 RID: 114 private List hoisted; // Token: 0x04000073 RID: 115 public readonly ILGenerator ig; } }