scripts
This commit is contained in:
@@ -0,0 +1,460 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
|
||||
namespace System.Linq.Expressions
|
||||
{
|
||||
/// <summary>Represents an expression that has a unary operator.</summary>
|
||||
// Token: 0x02000030 RID: 48
|
||||
public sealed class UnaryExpression : Expression
|
||||
{
|
||||
// Token: 0x06000251 RID: 593 RVA: 0x0000C180 File Offset: 0x0000A380
|
||||
internal UnaryExpression(ExpressionType node_type, Expression operand, Type type)
|
||||
: base(node_type, type)
|
||||
{
|
||||
this.operand = operand;
|
||||
}
|
||||
|
||||
// Token: 0x06000252 RID: 594 RVA: 0x0000C194 File Offset: 0x0000A394
|
||||
internal UnaryExpression(ExpressionType node_type, Expression operand, Type type, MethodInfo method, bool is_lifted)
|
||||
: base(node_type, type)
|
||||
{
|
||||
this.operand = operand;
|
||||
this.method = method;
|
||||
this.is_lifted = is_lifted;
|
||||
}
|
||||
|
||||
/// <summary>Gets the operand of the unary operation.</summary>
|
||||
/// <returns>An <see cref="T:System.Linq.Expressions.Expression" /> that represents the operand of the unary operation.</returns>
|
||||
// Token: 0x17000036 RID: 54
|
||||
// (get) Token: 0x06000253 RID: 595 RVA: 0x0000C1B8 File Offset: 0x0000A3B8
|
||||
public Expression Operand
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.operand;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets the implementing method for the unary operation.</summary>
|
||||
/// <returns>The <see cref="T:System.Reflection.MethodInfo" /> that represents the implementing method.</returns>
|
||||
// Token: 0x17000037 RID: 55
|
||||
// (get) Token: 0x06000254 RID: 596 RVA: 0x0000C1C0 File Offset: 0x0000A3C0
|
||||
public MethodInfo Method
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.method;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets a value that indicates whether the expression tree node represents a lifted call to an operator.</summary>
|
||||
/// <returns>true if the node represents a lifted call; otherwise, false.</returns>
|
||||
// Token: 0x17000038 RID: 56
|
||||
// (get) Token: 0x06000255 RID: 597 RVA: 0x0000C1C8 File Offset: 0x0000A3C8
|
||||
public bool IsLifted
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.is_lifted;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets a value that indicates whether the expression tree node represents a lifted call to an operator whose return type is lifted to a nullable type.</summary>
|
||||
/// <returns>true if the operator's return type is lifted to a nullable type; otherwise, false.</returns>
|
||||
// Token: 0x17000039 RID: 57
|
||||
// (get) Token: 0x06000256 RID: 598 RVA: 0x0000C1D0 File Offset: 0x0000A3D0
|
||||
public bool IsLiftedToNull
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.is_lifted && base.Type.IsNullable();
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x06000257 RID: 599 RVA: 0x0000C1EC File Offset: 0x0000A3EC
|
||||
private void EmitArrayLength(EmitContext ec)
|
||||
{
|
||||
this.operand.Emit(ec);
|
||||
ec.ig.Emit(OpCodes.Ldlen);
|
||||
}
|
||||
|
||||
// Token: 0x06000258 RID: 600 RVA: 0x0000C20C File Offset: 0x0000A40C
|
||||
private void EmitTypeAs(EmitContext ec)
|
||||
{
|
||||
Type type = base.Type;
|
||||
ec.EmitIsInst(this.operand, type);
|
||||
if (type.IsNullable())
|
||||
{
|
||||
ec.ig.Emit(OpCodes.Unbox_Any, type);
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x06000259 RID: 601 RVA: 0x0000C24C File Offset: 0x0000A44C
|
||||
private void EmitLiftedUnary(EmitContext ec)
|
||||
{
|
||||
ILGenerator ig = ec.ig;
|
||||
LocalBuilder localBuilder = ec.EmitStored(this.operand);
|
||||
LocalBuilder localBuilder2 = ig.DeclareLocal(base.Type);
|
||||
Label label = ig.DefineLabel();
|
||||
Label label2 = ig.DefineLabel();
|
||||
ec.EmitNullableHasValue(localBuilder);
|
||||
ig.Emit(OpCodes.Brtrue, label);
|
||||
ec.EmitNullableInitialize(localBuilder2);
|
||||
ig.Emit(OpCodes.Br, label2);
|
||||
ig.MarkLabel(label);
|
||||
ec.EmitNullableGetValueOrDefault(localBuilder);
|
||||
this.EmitUnaryOperator(ec);
|
||||
ec.EmitNullableNew(base.Type);
|
||||
ig.MarkLabel(label2);
|
||||
}
|
||||
|
||||
// Token: 0x0600025A RID: 602 RVA: 0x0000C2DC File Offset: 0x0000A4DC
|
||||
private void EmitUnaryOperator(EmitContext ec)
|
||||
{
|
||||
ILGenerator ig = ec.ig;
|
||||
ExpressionType nodeType = base.NodeType;
|
||||
switch (nodeType)
|
||||
{
|
||||
case ExpressionType.Negate:
|
||||
ig.Emit(OpCodes.Neg);
|
||||
break;
|
||||
default:
|
||||
if (nodeType != ExpressionType.Convert && nodeType != ExpressionType.ConvertChecked)
|
||||
{
|
||||
if (nodeType == ExpressionType.Not)
|
||||
{
|
||||
if (this.operand.Type.GetNotNullableType() == typeof(bool))
|
||||
{
|
||||
ig.Emit(OpCodes.Ldc_I4_0);
|
||||
ig.Emit(OpCodes.Ceq);
|
||||
}
|
||||
else
|
||||
{
|
||||
ig.Emit(OpCodes.Not);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.EmitPrimitiveConversion(ec, this.operand.Type.GetNotNullableType(), base.Type.GetNotNullableType());
|
||||
}
|
||||
break;
|
||||
case ExpressionType.NegateChecked:
|
||||
ig.Emit(OpCodes.Ldc_I4_M1);
|
||||
ig.Emit((!Expression.IsUnsigned(this.operand.Type)) ? OpCodes.Mul_Ovf : OpCodes.Mul_Ovf_Un);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x0600025B RID: 603 RVA: 0x0000C3E4 File Offset: 0x0000A5E4
|
||||
private void EmitConvert(EmitContext ec)
|
||||
{
|
||||
Type type = this.operand.Type;
|
||||
Type type2 = base.Type;
|
||||
if (type == type2)
|
||||
{
|
||||
this.operand.Emit(ec);
|
||||
}
|
||||
else if (type.IsNullable() && !type2.IsNullable())
|
||||
{
|
||||
this.EmitConvertFromNullable(ec);
|
||||
}
|
||||
else if (!type.IsNullable() && type2.IsNullable())
|
||||
{
|
||||
this.EmitConvertToNullable(ec);
|
||||
}
|
||||
else if (type.IsNullable() && type2.IsNullable())
|
||||
{
|
||||
this.EmitConvertFromNullableToNullable(ec);
|
||||
}
|
||||
else if (Expression.IsReferenceConversion(type, type2))
|
||||
{
|
||||
this.EmitCast(ec);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Expression.IsPrimitiveConversion(type, type2))
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
this.EmitPrimitiveConversion(ec);
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x0600025C RID: 604 RVA: 0x0000C4B8 File Offset: 0x0000A6B8
|
||||
private void EmitConvertFromNullableToNullable(EmitContext ec)
|
||||
{
|
||||
this.EmitLiftedUnary(ec);
|
||||
}
|
||||
|
||||
// Token: 0x0600025D RID: 605 RVA: 0x0000C4C4 File Offset: 0x0000A6C4
|
||||
private void EmitConvertToNullable(EmitContext ec)
|
||||
{
|
||||
ec.Emit(this.operand);
|
||||
if (this.IsUnBoxing())
|
||||
{
|
||||
this.EmitUnbox(ec);
|
||||
return;
|
||||
}
|
||||
if (this.operand.Type != base.Type.GetNotNullableType())
|
||||
{
|
||||
this.EmitPrimitiveConversion(ec, this.operand.Type, base.Type.GetNotNullableType());
|
||||
}
|
||||
ec.EmitNullableNew(base.Type);
|
||||
}
|
||||
|
||||
// Token: 0x0600025E RID: 606 RVA: 0x0000C534 File Offset: 0x0000A734
|
||||
private void EmitConvertFromNullable(EmitContext ec)
|
||||
{
|
||||
if (this.IsBoxing())
|
||||
{
|
||||
ec.Emit(this.operand);
|
||||
this.EmitBox(ec);
|
||||
return;
|
||||
}
|
||||
ec.EmitCall(this.operand, this.operand.Type.GetMethod("get_Value"));
|
||||
if (this.operand.Type.GetNotNullableType() != base.Type)
|
||||
{
|
||||
this.EmitPrimitiveConversion(ec, this.operand.Type.GetNotNullableType(), base.Type);
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x0600025F RID: 607 RVA: 0x0000C5BC File Offset: 0x0000A7BC
|
||||
private bool IsBoxing()
|
||||
{
|
||||
return this.operand.Type.IsValueType && !base.Type.IsValueType;
|
||||
}
|
||||
|
||||
// Token: 0x06000260 RID: 608 RVA: 0x0000C5F0 File Offset: 0x0000A7F0
|
||||
private void EmitBox(EmitContext ec)
|
||||
{
|
||||
ec.ig.Emit(OpCodes.Box, this.operand.Type);
|
||||
}
|
||||
|
||||
// Token: 0x06000261 RID: 609 RVA: 0x0000C610 File Offset: 0x0000A810
|
||||
private bool IsUnBoxing()
|
||||
{
|
||||
return !this.operand.Type.IsValueType && base.Type.IsValueType;
|
||||
}
|
||||
|
||||
// Token: 0x06000262 RID: 610 RVA: 0x0000C640 File Offset: 0x0000A840
|
||||
private void EmitUnbox(EmitContext ec)
|
||||
{
|
||||
ec.ig.Emit(OpCodes.Unbox_Any, base.Type);
|
||||
}
|
||||
|
||||
// Token: 0x06000263 RID: 611 RVA: 0x0000C658 File Offset: 0x0000A858
|
||||
private void EmitCast(EmitContext ec)
|
||||
{
|
||||
this.operand.Emit(ec);
|
||||
if (this.IsBoxing())
|
||||
{
|
||||
this.EmitBox(ec);
|
||||
}
|
||||
else if (this.IsUnBoxing())
|
||||
{
|
||||
this.EmitUnbox(ec);
|
||||
}
|
||||
else
|
||||
{
|
||||
ec.ig.Emit(OpCodes.Castclass, base.Type);
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x06000264 RID: 612 RVA: 0x0000C6B8 File Offset: 0x0000A8B8
|
||||
private void EmitPrimitiveConversion(EmitContext ec, bool is_unsigned, OpCode signed, OpCode unsigned, OpCode signed_checked, OpCode unsigned_checked)
|
||||
{
|
||||
if (base.NodeType != ExpressionType.ConvertChecked)
|
||||
{
|
||||
ec.ig.Emit((!is_unsigned) ? signed : unsigned);
|
||||
}
|
||||
else
|
||||
{
|
||||
ec.ig.Emit((!is_unsigned) ? signed_checked : unsigned_checked);
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x06000265 RID: 613 RVA: 0x0000C70C File Offset: 0x0000A90C
|
||||
private void EmitPrimitiveConversion(EmitContext ec)
|
||||
{
|
||||
this.operand.Emit(ec);
|
||||
this.EmitPrimitiveConversion(ec, this.operand.Type, base.Type);
|
||||
}
|
||||
|
||||
// Token: 0x06000266 RID: 614 RVA: 0x0000C740 File Offset: 0x0000A940
|
||||
private void EmitPrimitiveConversion(EmitContext ec, Type from, Type to)
|
||||
{
|
||||
bool flag = Expression.IsUnsigned(from);
|
||||
switch (Type.GetTypeCode(to))
|
||||
{
|
||||
case TypeCode.SByte:
|
||||
this.EmitPrimitiveConversion(ec, flag, OpCodes.Conv_I1, OpCodes.Conv_U1, OpCodes.Conv_Ovf_I1, OpCodes.Conv_Ovf_I1_Un);
|
||||
return;
|
||||
case TypeCode.Byte:
|
||||
this.EmitPrimitiveConversion(ec, flag, OpCodes.Conv_I1, OpCodes.Conv_U1, OpCodes.Conv_Ovf_U1, OpCodes.Conv_Ovf_U1_Un);
|
||||
return;
|
||||
case TypeCode.Int16:
|
||||
this.EmitPrimitiveConversion(ec, flag, OpCodes.Conv_I2, OpCodes.Conv_U2, OpCodes.Conv_Ovf_I2, OpCodes.Conv_Ovf_I2_Un);
|
||||
return;
|
||||
case TypeCode.UInt16:
|
||||
this.EmitPrimitiveConversion(ec, flag, OpCodes.Conv_I2, OpCodes.Conv_U2, OpCodes.Conv_Ovf_U2, OpCodes.Conv_Ovf_U2_Un);
|
||||
return;
|
||||
case TypeCode.Int32:
|
||||
this.EmitPrimitiveConversion(ec, flag, OpCodes.Conv_I4, OpCodes.Conv_U4, OpCodes.Conv_Ovf_I4, OpCodes.Conv_Ovf_I4_Un);
|
||||
return;
|
||||
case TypeCode.UInt32:
|
||||
this.EmitPrimitiveConversion(ec, flag, OpCodes.Conv_I4, OpCodes.Conv_U4, OpCodes.Conv_Ovf_U4, OpCodes.Conv_Ovf_U4_Un);
|
||||
return;
|
||||
case TypeCode.Int64:
|
||||
this.EmitPrimitiveConversion(ec, flag, OpCodes.Conv_I8, OpCodes.Conv_U8, OpCodes.Conv_Ovf_I8, OpCodes.Conv_Ovf_I8_Un);
|
||||
return;
|
||||
case TypeCode.UInt64:
|
||||
this.EmitPrimitiveConversion(ec, flag, OpCodes.Conv_I8, OpCodes.Conv_U8, OpCodes.Conv_Ovf_U8, OpCodes.Conv_Ovf_U8_Un);
|
||||
return;
|
||||
case TypeCode.Single:
|
||||
if (flag)
|
||||
{
|
||||
ec.ig.Emit(OpCodes.Conv_R_Un);
|
||||
}
|
||||
ec.ig.Emit(OpCodes.Conv_R4);
|
||||
return;
|
||||
case TypeCode.Double:
|
||||
if (flag)
|
||||
{
|
||||
ec.ig.Emit(OpCodes.Conv_R_Un);
|
||||
}
|
||||
ec.ig.Emit(OpCodes.Conv_R8);
|
||||
return;
|
||||
default:
|
||||
throw new NotImplementedException(base.Type.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x06000267 RID: 615 RVA: 0x0000C8D8 File Offset: 0x0000AAD8
|
||||
private void EmitArithmeticUnary(EmitContext ec)
|
||||
{
|
||||
if (!this.IsLifted)
|
||||
{
|
||||
this.operand.Emit(ec);
|
||||
this.EmitUnaryOperator(ec);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.EmitLiftedUnary(ec);
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x06000268 RID: 616 RVA: 0x0000C910 File Offset: 0x0000AB10
|
||||
private void EmitUserDefinedLiftedToNullOperator(EmitContext ec)
|
||||
{
|
||||
ILGenerator ig = ec.ig;
|
||||
LocalBuilder localBuilder = ec.EmitStored(this.operand);
|
||||
Label label = ig.DefineLabel();
|
||||
Label label2 = ig.DefineLabel();
|
||||
ec.EmitNullableHasValue(localBuilder);
|
||||
ig.Emit(OpCodes.Brfalse, label);
|
||||
ec.EmitNullableGetValueOrDefault(localBuilder);
|
||||
ec.EmitCall(this.method);
|
||||
ec.EmitNullableNew(base.Type);
|
||||
ig.Emit(OpCodes.Br, label2);
|
||||
ig.MarkLabel(label);
|
||||
LocalBuilder localBuilder2 = ig.DeclareLocal(base.Type);
|
||||
ec.EmitNullableInitialize(localBuilder2);
|
||||
ig.MarkLabel(label2);
|
||||
}
|
||||
|
||||
// Token: 0x06000269 RID: 617 RVA: 0x0000C9A4 File Offset: 0x0000ABA4
|
||||
private void EmitUserDefinedLiftedOperator(EmitContext ec)
|
||||
{
|
||||
LocalBuilder localBuilder = ec.EmitStored(this.operand);
|
||||
ec.EmitNullableGetValue(localBuilder);
|
||||
ec.EmitCall(this.method);
|
||||
}
|
||||
|
||||
// Token: 0x0600026A RID: 618 RVA: 0x0000C9D4 File Offset: 0x0000ABD4
|
||||
private void EmitUserDefinedOperator(EmitContext ec)
|
||||
{
|
||||
if (!this.IsLifted)
|
||||
{
|
||||
ec.Emit(this.operand);
|
||||
ec.EmitCall(this.method);
|
||||
}
|
||||
else if (this.IsLiftedToNull)
|
||||
{
|
||||
this.EmitUserDefinedLiftedToNullOperator(ec);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.EmitUserDefinedLiftedOperator(ec);
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x0600026B RID: 619 RVA: 0x0000CA28 File Offset: 0x0000AC28
|
||||
private void EmitQuote(EmitContext ec)
|
||||
{
|
||||
ec.EmitScope();
|
||||
ec.EmitReadGlobal(this.operand, typeof(Expression));
|
||||
if (ec.HasHoistedLocals)
|
||||
{
|
||||
ec.EmitLoadHoistedLocalsStore();
|
||||
}
|
||||
else
|
||||
{
|
||||
ec.ig.Emit(OpCodes.Ldnull);
|
||||
}
|
||||
ec.EmitIsolateExpression();
|
||||
}
|
||||
|
||||
// Token: 0x0600026C RID: 620 RVA: 0x0000CA80 File Offset: 0x0000AC80
|
||||
internal override void Emit(EmitContext ec)
|
||||
{
|
||||
if (this.method != null)
|
||||
{
|
||||
this.EmitUserDefinedOperator(ec);
|
||||
return;
|
||||
}
|
||||
ExpressionType nodeType = base.NodeType;
|
||||
switch (nodeType)
|
||||
{
|
||||
case ExpressionType.Negate:
|
||||
case ExpressionType.UnaryPlus:
|
||||
case ExpressionType.NegateChecked:
|
||||
case ExpressionType.Not:
|
||||
this.EmitArithmeticUnary(ec);
|
||||
return;
|
||||
default:
|
||||
if (nodeType == ExpressionType.Convert || nodeType == ExpressionType.ConvertChecked)
|
||||
{
|
||||
this.EmitConvert(ec);
|
||||
return;
|
||||
}
|
||||
if (nodeType == ExpressionType.ArrayLength)
|
||||
{
|
||||
this.EmitArrayLength(ec);
|
||||
return;
|
||||
}
|
||||
if (nodeType == ExpressionType.Quote)
|
||||
{
|
||||
this.EmitQuote(ec);
|
||||
return;
|
||||
}
|
||||
if (nodeType != ExpressionType.TypeAs)
|
||||
{
|
||||
throw new NotImplementedException(base.NodeType.ToString());
|
||||
}
|
||||
this.EmitTypeAs(ec);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x040000C0 RID: 192
|
||||
private Expression operand;
|
||||
|
||||
// Token: 0x040000C1 RID: 193
|
||||
private MethodInfo method;
|
||||
|
||||
// Token: 0x040000C2 RID: 194
|
||||
private bool is_lifted;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user