using System; using System.Collections.Generic; using System.Runtime.CompilerServices; namespace System.Linq.Expressions { // Token: 0x02000019 RID: 25 internal class CompilationContext { // Token: 0x06000167 RID: 359 RVA: 0x000091AC File Offset: 0x000073AC public int AddGlobal(object global) { return CompilationContext.AddItemToList(global, this.globals); } // Token: 0x06000168 RID: 360 RVA: 0x000091BC File Offset: 0x000073BC public object[] GetGlobals() { return this.globals.ToArray(); } // Token: 0x06000169 RID: 361 RVA: 0x000091CC File Offset: 0x000073CC private static int AddItemToList(T item, IList list) { list.Add(item); return list.Count - 1; } // Token: 0x0600016A RID: 362 RVA: 0x000091E0 File Offset: 0x000073E0 public int AddCompilationUnit(LambdaExpression lambda) { this.DetectHoistedVariables(lambda); return this.AddCompilationUnit(null, lambda); } // Token: 0x0600016B RID: 363 RVA: 0x000091F4 File Offset: 0x000073F4 public int AddCompilationUnit(EmitContext parent, LambdaExpression lambda) { EmitContext emitContext = new EmitContext(this, parent, lambda); int num = CompilationContext.AddItemToList(emitContext, this.units); emitContext.Emit(); return num; } // Token: 0x0600016C RID: 364 RVA: 0x00009220 File Offset: 0x00007420 private void DetectHoistedVariables(LambdaExpression lambda) { this.hoisted_map = new CompilationContext.HoistedVariableDetector().Process(lambda); } // Token: 0x0600016D RID: 365 RVA: 0x00009234 File Offset: 0x00007434 public List GetHoistedLocals(LambdaExpression lambda) { if (this.hoisted_map == null) { return null; } List list; this.hoisted_map.TryGetValue(lambda, out list); return list; } // Token: 0x0600016E RID: 366 RVA: 0x00009260 File Offset: 0x00007460 public object[] CreateHoistedLocals(int unit) { List hoistedLocals = this.GetHoistedLocals(this.units[unit].Lambda); return new object[(hoistedLocals != null) ? hoistedLocals.Count : 0]; } // Token: 0x0600016F RID: 367 RVA: 0x0000929C File Offset: 0x0000749C public Expression IsolateExpression(ExecutionScope scope, object[] locals, Expression expression) { return new CompilationContext.ParameterReplacer(this, scope, locals).Transform(expression); } // Token: 0x06000170 RID: 368 RVA: 0x000092AC File Offset: 0x000074AC public Delegate CreateDelegate() { return this.CreateDelegate(0, new ExecutionScope(this)); } // Token: 0x06000171 RID: 369 RVA: 0x000092BC File Offset: 0x000074BC public Delegate CreateDelegate(int unit, ExecutionScope scope) { return this.units[unit].CreateDelegate(scope); } // Token: 0x04000064 RID: 100 private List globals = new List(); // Token: 0x04000065 RID: 101 private List units = new List(); // Token: 0x04000066 RID: 102 private Dictionary> hoisted_map; // Token: 0x0200001A RID: 26 private class ParameterReplacer : ExpressionTransformer { // Token: 0x06000172 RID: 370 RVA: 0x000092D0 File Offset: 0x000074D0 public ParameterReplacer(CompilationContext context, ExecutionScope scope, object[] locals) { this.context = context; this.scope = scope; this.locals = locals; } // Token: 0x06000173 RID: 371 RVA: 0x000092F0 File Offset: 0x000074F0 protected override Expression VisitParameter(ParameterExpression parameter) { ExecutionScope parent = this.scope; object[] array = this.locals; while (parent != null) { int num = this.IndexOfHoistedLocal(parent, parameter); if (num != -1) { return this.ReadHoistedLocalFromArray(array, num); } array = parent.Locals; parent = parent.Parent; } return parameter; } // Token: 0x06000174 RID: 372 RVA: 0x00009340 File Offset: 0x00007540 private Expression ReadHoistedLocalFromArray(object[] locals, int position) { return Expression.Field(Expression.Convert(Expression.ArrayIndex(Expression.Constant(locals), Expression.Constant(position)), locals[position].GetType()), "Value"); } // Token: 0x06000175 RID: 373 RVA: 0x0000937C File Offset: 0x0000757C private int IndexOfHoistedLocal(ExecutionScope scope, ParameterExpression parameter) { return this.context.units[scope.compilation_unit].IndexOfHoistedLocal(parameter); } // Token: 0x04000067 RID: 103 private CompilationContext context; // Token: 0x04000068 RID: 104 private ExecutionScope scope; // Token: 0x04000069 RID: 105 private object[] locals; } // Token: 0x0200001B RID: 27 private class HoistedVariableDetector : ExpressionVisitor { // Token: 0x06000177 RID: 375 RVA: 0x000093B0 File Offset: 0x000075B0 public Dictionary> Process(LambdaExpression lambda) { this.Visit(lambda); return this.hoisted_map; } // Token: 0x06000178 RID: 376 RVA: 0x000093C0 File Offset: 0x000075C0 protected override void VisitLambda(LambdaExpression lambda) { this.lambda = lambda; foreach (ParameterExpression parameterExpression in lambda.Parameters) { this.parameter_to_lambda[parameterExpression] = lambda; } base.VisitLambda(lambda); } // Token: 0x06000179 RID: 377 RVA: 0x00009438 File Offset: 0x00007638 protected override void VisitParameter(ParameterExpression parameter) { if (this.lambda.Parameters.Contains(parameter)) { return; } this.Hoist(parameter); } // Token: 0x0600017A RID: 378 RVA: 0x00009458 File Offset: 0x00007658 private void Hoist(ParameterExpression parameter) { LambdaExpression lambdaExpression; if (!this.parameter_to_lambda.TryGetValue(parameter, out lambdaExpression)) { return; } if (this.hoisted_map == null) { this.hoisted_map = new Dictionary>(); } List list; if (!this.hoisted_map.TryGetValue(lambdaExpression, out list)) { list = new List(); this.hoisted_map[lambdaExpression] = list; } list.Add(parameter); } // Token: 0x0400006A RID: 106 private Dictionary parameter_to_lambda = new Dictionary(); // Token: 0x0400006B RID: 107 private Dictionary> hoisted_map; // Token: 0x0400006C RID: 108 private LambdaExpression lambda; } } }