public override void Compile(EmitCompilerContext context, EmitIl il) { Initializer?.Compile(context, il); var start = il.DefineLabel(); var end = il.DefineLabel(); il.MarkLabel(start); if (Predicate != null) { Predicate.Compile(context, il); } else { il.Emit(EmitOpCodes.Ldc_I4_1); } il.Emit(EmitOpCodes.Brfalse, end); Body.Compile(context, il); Incrementor?.Compile(context, il); il.Emit(EmitOpCodes.Br, start); il.MarkLabel(end); }
public override void Compile(EmitCompilerContext context, EmitIl il) { Expression.Compile(context, il); var expressionType = Expression.GetExpressionType(); EmitType voidType = typeof(void); if (expressionType.IsValueType && !context.Method.ReturnType.IsValueType && !Equals(expressionType, voidType)) { il.Emit(EmitOpCodes.Box, Expression.GetExpressionType()); } // else if (!Expression.GetType(context.TypeSystem).IsValueType && !context.Method.ReturnType.IsValueType) // { // // } il.Emit(EmitOpCodes.Ret); }
public override void Compile(EmitCompilerContext context, EmitIl il) { Expression.Compile(context, il); il.Emit(EmitOpCodes.Pop); }
public abstract void Compile(EmitCompilerContext context, EmitIl il);
public override void Compile(EmitCompilerContext context, EmitIl il) { Operand.Compile(context, il); var operandType = Operand.GetExpressionType(); EmitType typeInt = typeof(int); EmitType typeUint = typeof(uint); EmitType typeShort = typeof(short); EmitType typeUshort = typeof(ushort); EmitType typeByte = typeof(byte); EmitType typeSbyte = typeof(sbyte); EmitType typeLong = typeof(long); EmitType typeUlong = typeof(ulong); EmitType typeDouble = typeof(double); EmitType typeFloat = typeof(float); EmitType typeDecimal = typeof(decimal); EmitType typeBool = typeof(bool); var typeIs32Bit = Equals(Type, typeByte) || Equals(Type, typeShort) || Equals(Type, typeInt) || Equals(Type, typeSbyte) || Equals(Type, typeUshort) || Equals(Type, typeUint); var operandIs32Bit = Equals(operandType, typeByte) || Equals(operandType, typeShort) || Equals(operandType, typeInt) || Equals(operandType, typeSbyte) || Equals(operandType, typeUshort) || Equals(operandType, typeUint); var typeIsFloatingPoint = Equals(Type, typeFloat) || Equals(Type, typeDouble); var operandIsFloatingPoint = Equals(operandType, typeFloat) || Equals(operandType, typeDouble); if (operandIs32Bit || operandIsFloatingPoint || Equals(operandType, typeLong)) { if (Equals(Type, operandType)) { return; } if (Equals(Type, typeFloat)) { il.Emit(EmitOpCodes.Conv_R4); return; } if (Equals(Type, typeDouble)) { il.Emit(EmitOpCodes.Conv_R8); return; } if (Equals(Type, typeByte)) { il.Emit(EmitOpCodes.Conv_U1); return; } if (Equals(Type, typeSbyte)) { il.Emit(EmitOpCodes.Conv_I1); return; } if (Equals(Type, typeShort)) { il.Emit(EmitOpCodes.Conv_I2); return; } if (Equals(Type, typeUshort)) { il.Emit(EmitOpCodes.Conv_U2); return; } if (Equals(Type, typeInt)) { il.Emit(EmitOpCodes.Conv_I4); return; } if (Equals(Type, typeUint)) { il.Emit(EmitOpCodes.Conv_U4); return; } if (Equals(Type, typeLong)) { il.Emit(EmitOpCodes.Conv_I8); return; } if (Equals(Type, typeUlong)) { il.Emit(EmitOpCodes.Conv_U8); return; } } // All else fails, then: il.Emit(EmitOpCodes.Castclass, Type); }
public void SetData(EmitCompilerContext context, EmitLocal local) { context.Data[this] = local; }
public EmitLocal GetData(EmitCompilerContext context) { return (EmitLocal)context.Data[this]; }
public override void Compile(EmitCompilerContext context, EmitIl il) { switch (Operator) { case EmitUnaryOperator.BooleanNot: Operand.Compile(context, il); il.Emit(EmitOpCodes.Ldc_I4_0); il.Emit(EmitOpCodes.Ceq); break; case EmitUnaryOperator.BitwiseNot: Operand.Compile(context, il); il.Emit(EmitOpCodes.Not); break; case EmitUnaryOperator.Minus: Operand.Compile(context, il); il.Emit(EmitOpCodes.Neg); break; case EmitUnaryOperator.Plus: Operand.Compile(context, il); break; case EmitUnaryOperator.PostfixDecrement: { Operand.Compile(context, il); var local = il.DeclareLocal(Operand.GetExpressionType()); il.Emit(EmitOpCodes.Stloc, local); ((IEmitReferenceExpression)Operand).CompileAssignment(context, il, () => { il.Emit(EmitOpCodes.Ldloc, local); il.Emit(EmitOpCodes.Ldc_I4_1); il.Emit(EmitOpCodes.Sub); }); il.Emit(EmitOpCodes.Pop); il.Emit(EmitOpCodes.Ldloc, local); break; } case EmitUnaryOperator.PostfixIncrement: { Operand.Compile(context, il); var local = il.DeclareLocal(Operand.GetExpressionType()); il.Emit(EmitOpCodes.Stloc, local); ((IEmitReferenceExpression)Operand).CompileAssignment(context, il, () => { il.Emit(EmitOpCodes.Ldloc, local); il.Emit(EmitOpCodes.Ldc_I4_1); il.Emit(EmitOpCodes.Add); }); il.Emit(EmitOpCodes.Pop); il.Emit(EmitOpCodes.Ldloc, local); break; } case EmitUnaryOperator.PrefixDecrement: { Operand.Compile(context, il); il.Emit(EmitOpCodes.Ldc_I4_1); il.Emit(EmitOpCodes.Sub); var local = il.DeclareLocal(Operand.GetExpressionType()); il.Emit(EmitOpCodes.Stloc, local); ((IEmitReferenceExpression)Operand).CompileAssignment(context, il, () => { il.Emit(EmitOpCodes.Ldloc, local); }); break; } case EmitUnaryOperator.PrefixIncrement: { Operand.Compile(context, il); il.Emit(EmitOpCodes.Ldc_I4_1); il.Emit(EmitOpCodes.Add); var local = il.DeclareLocal(Operand.GetExpressionType()); il.Emit(EmitOpCodes.Stloc, local); ((IEmitReferenceExpression)Operand).CompileAssignment(context, il, () => { il.Emit(EmitOpCodes.Ldloc, local); }); break; } } }
public EmitLocal GetData(EmitCompilerContext context) { return((EmitLocal)context.Data[this]); }