Files
2026-06-04 11:42:34 +02:00

211 lines
6.5 KiB
C#

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<object>(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>(T item, IList<T> 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>(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<ParameterExpression> GetHoistedLocals(LambdaExpression lambda)
{
if (this.hoisted_map == null)
{
return null;
}
List<ParameterExpression> 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<ParameterExpression> 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<object> globals = new List<object>();
// Token: 0x04000065 RID: 101
private List<EmitContext> units = new List<EmitContext>();
// Token: 0x04000066 RID: 102
private Dictionary<LambdaExpression, List<ParameterExpression>> 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<LambdaExpression, List<ParameterExpression>> 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<LambdaExpression, List<ParameterExpression>>();
}
List<ParameterExpression> list;
if (!this.hoisted_map.TryGetValue(lambdaExpression, out list))
{
list = new List<ParameterExpression>();
this.hoisted_map[lambdaExpression] = list;
}
list.Add(parameter);
}
// Token: 0x0400006A RID: 106
private Dictionary<ParameterExpression, LambdaExpression> parameter_to_lambda = new Dictionary<ParameterExpression, LambdaExpression>();
// Token: 0x0400006B RID: 107
private Dictionary<LambdaExpression, List<ParameterExpression>> hoisted_map;
// Token: 0x0400006C RID: 108
private LambdaExpression lambda;
}
}
}