private static bool ImplicitConvertToSingle(TypeCode sourceTypeCode, FleeILGenerator ilg) { switch (sourceTypeCode) { case TypeCode.Char: case TypeCode.Byte: case TypeCode.SByte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.Int64: EmitConvert(ilg, OpCodes.Conv_R4); break; case TypeCode.UInt32: case TypeCode.UInt64: EmitConvert(ilg, OpCodes.Conv_R_Un); EmitConvert(ilg, OpCodes.Conv_R4); break; case TypeCode.Single: break; default: return(false); } return(true); }
/// <summary> /// Add a branch from a location to a target label /// </summary> /// <param name="ilg"></param> /// <param name="target"></param> /// <remarks></remarks> public void AddBranch(FleeILGenerator ilg, Label target) { ILLocation startLoc = new ILLocation(ilg.Length); BranchInfo bi = new BranchInfo(startLoc, target); MyBranchInfos.Add(bi); }
/// <summary> /// Set the position for a label /// </summary> /// <param name="ilg"></param> /// <param name="target"></param> /// <remarks></remarks> public void MarkLabel(FleeILGenerator ilg, Label target) { int pos = ilg.Length; foreach (BranchInfo bi in MyBranchInfos) { bi.Mark(target, pos); } }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { base.Emit(ilg, services); MyElement.Emit(ilg, services); if (MyElement.ResultType.IsValueType == true) { EmitValueTypeLoadAddress(ilg, this.ResultType); } }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { MyCastExpression.Emit(ilg, services); Type sourceType = MyCastExpression.ResultType; Type destType = MyDestType; this.EmitCast(ilg, sourceType, destType, services); }
public static void EmitArrayLoad(FleeILGenerator ilg, Type elementType) { TypeCode tc = Type.GetTypeCode(elementType); switch (tc) { case TypeCode.Byte: ilg.Emit(OpCodes.Ldelem_U1); break; case TypeCode.SByte: case TypeCode.Boolean: ilg.Emit(OpCodes.Ldelem_I1); break; case TypeCode.Int16: ilg.Emit(OpCodes.Ldelem_I2); break; case TypeCode.UInt16: ilg.Emit(OpCodes.Ldelem_U2); break; case TypeCode.Int32: ilg.Emit(OpCodes.Ldelem_I4); break; case TypeCode.UInt32: ilg.Emit(OpCodes.Ldelem_U4); break; case TypeCode.Int64: case TypeCode.UInt64: ilg.Emit(OpCodes.Ldelem_I8); break; case TypeCode.Single: ilg.Emit(OpCodes.Ldelem_R4); break; case TypeCode.Double: ilg.Emit(OpCodes.Ldelem_R8); break; case TypeCode.Object: case TypeCode.String: ilg.Emit(OpCodes.Ldelem_Ref); break; default: // Must be a non-primitive value type ilg.Emit(OpCodes.Ldelema, elementType); ilg.Emit(OpCodes.Ldobj, elementType); return; } }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { Type resultType = this.ResultType; MyLeftChild.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyLeftChild.ResultType, resultType, ilg); MyRightChild.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyRightChild.ResultType, resultType, ilg); ilg.Emit(OpCodes.Xor); }
protected void EmitOverloadedOperatorCall(MethodInfo method, FleeILGenerator ilg, IServiceProvider services) { ParameterInfo[] parameters = method.GetParameters(); ParameterInfo pLeft = parameters[0]; ParameterInfo pRight = parameters[1]; EmitChildWithConvert(MyLeftChild, pLeft.ParameterType, ilg, services); EmitChildWithConvert(MyRightChild, pRight.ParameterType, ilg, services); ilg.Emit(OpCodes.Call, method); }
/// <summary> /// Determine if a branch from a point to a label will be long /// </summary> /// <param name="ilg"></param> /// <param name="target"></param> /// <returns></returns> /// <remarks></remarks> public bool IsLongBranch(FleeILGenerator ilg, Label target) { ILLocation startLoc = new ILLocation(ilg.Length); BranchInfo bi = new BranchInfo(startLoc, target); int index = MyBranchInfos.IndexOf(bi); bi = MyBranchInfos[index]; return(bi.IsLongBranch); }
private void EmitValueTypeArrayLoad(FleeILGenerator ilg, Type elementType) { if (this.NextRequiresAddress == true) { ilg.Emit(OpCodes.Ldelema, elementType); } else { Utility.EmitArrayLoad(ilg, elementType); } }
// Emit the load of a constant field. We can't emit a ldsfld/ldfld of a constant so we have to get its value // and then emit a ldc. private static void EmitLiteral(FieldInfo fi, FleeILGenerator ilg, IServiceProvider services) { object value = fi.GetValue(null); Type t = value.GetType(); TypeCode code = Type.GetTypeCode(t); LiteralElement elem = default(LiteralElement); switch (code) { case TypeCode.Char: case TypeCode.Byte: case TypeCode.SByte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: elem = new Int32LiteralElement(System.Convert.ToInt32(value)); break; case TypeCode.UInt32: elem = new UInt32LiteralElement((UInt32)value); break; case TypeCode.Int64: elem = new Int64LiteralElement((Int64)value); break; case TypeCode.UInt64: elem = new UInt64LiteralElement((UInt64)value); break; case TypeCode.Double: elem = new DoubleLiteralElement((double)value); break; case TypeCode.Single: elem = new SingleLiteralElement((float)value); break; case TypeCode.Boolean: elem = new BooleanLiteralElement((bool)value); break; case TypeCode.String: elem = new StringLiteralElement((string)value); break; default: elem = null; Debug.Fail("Unsupported constant type"); break; } elem.Emit(ilg, services); }
private static void EmitReferenceTypeMethodCall(MethodInfo mi, FleeILGenerator ilg) { if (mi.IsStatic == true) { ilg.Emit(OpCodes.Call, mi); } else { ilg.Emit(OpCodes.Callvirt, mi); } }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { if (MyValue == true) { ilg.Emit(OpCodes.Ldc_I4_1); } else { ilg.Emit(OpCodes.Ldc_I4_0); } }
/// <summary> /// Get a label by a key. Create the label if it is not present. /// </summary> /// <param name="key"></param> /// <param name="ilg"></param> /// <returns></returns> /// <remarks></remarks> public Label GetLabel(object key, FleeILGenerator ilg) { Label lbl = default(Label); if (MyKeyLabelMap.TryGetValue(key, out lbl) == false) { lbl = ilg.DefineLabel(); MyKeyLabelMap.Add(key, lbl); } return(lbl); }
private static void EmitSuperShort(Int32 value, FleeILGenerator ilg) { OpCode ldcOpcode = default(OpCode); switch (value) { case 0: ldcOpcode = OpCodes.Ldc_I4_0; break; case 1: ldcOpcode = OpCodes.Ldc_I4_1; break; case 2: ldcOpcode = OpCodes.Ldc_I4_2; break; case 3: ldcOpcode = OpCodes.Ldc_I4_3; break; case 4: ldcOpcode = OpCodes.Ldc_I4_4; break; case 5: ldcOpcode = OpCodes.Ldc_I4_5; break; case 6: ldcOpcode = OpCodes.Ldc_I4_6; break; case 7: ldcOpcode = OpCodes.Ldc_I4_7; break; case 8: ldcOpcode = OpCodes.Ldc_I4_8; break; case -1: ldcOpcode = OpCodes.Ldc_I4_M1; break; default: Debug.Assert(false, "value out of range"); break; } ilg.Emit(ldcOpcode); }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { if (object.ReferenceEquals(MyChild.ResultType, typeof(bool))) { this.EmitLogical(ilg, services); } else { MyChild.Emit(ilg, services); ilg.Emit(OpCodes.Not); } }
private void EmitConditional(FleeILGenerator ilg, IServiceProvider services, BranchManager bm) { Label falseLabel = bm.FindLabel("falseLabel"); Label endLabel = bm.FindLabel("endLabel"); // Emit the condition MyCondition.Emit(ilg, services); // On false go to the false operand if (ilg.IsTemp == true) { bm.AddBranch(ilg, falseLabel); ilg.Emit(OpCodes.Brfalse_S, falseLabel); } else if (bm.IsLongBranch(ilg, falseLabel) == false) { ilg.Emit(OpCodes.Brfalse_S, falseLabel); } else { ilg.Emit(OpCodes.Brfalse, falseLabel); } // Emit the true operand MyWhenTrue.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyWhenTrue.ResultType, MyResultType, ilg); // Jump to end if (ilg.IsTemp == true) { bm.AddBranch(ilg, endLabel); ilg.Emit(OpCodes.Br_S, endLabel); } else if (bm.IsLongBranch(ilg, endLabel) == false) { ilg.Emit(OpCodes.Br_S, endLabel); } else { ilg.Emit(OpCodes.Br, endLabel); } bm.MarkLabel(ilg, falseLabel); ilg.MarkLabel(falseLabel); // Emit the false operand MyWhenFalse.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyWhenFalse.ResultType, MyResultType, ilg); // Fall through to end bm.MarkLabel(ilg, endLabel); ilg.MarkLabel(endLabel); }
public static void EmitLoadLocalAddress(FleeILGenerator ilg, int index) { Debug.Assert(index >= 0, "Invalid index"); if (index <= byte.MaxValue) { ilg.Emit(OpCodes.Ldloca_S, (byte)index); } else { ilg.Emit(OpCodes.Ldloca, index); } }
private static bool ImplicitConvertToUInt16(TypeCode sourceTypeCode, FleeILGenerator ilg) { switch (sourceTypeCode) { case TypeCode.Char: case TypeCode.Byte: case TypeCode.UInt16: return(true); default: return(false); } }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { base.Emit(ilg, services); if (this.IsArray == true) { this.EmitArrayLoad(ilg, services); } else { this.EmitIndexer(ilg, services); } }
private void EmitCast(FleeILGenerator ilg, Type sourceType, Type destType, IServiceProvider services) { MethodInfo explicitOperator = this.GetExplictOverloadedOperator(sourceType, destType); if (object.ReferenceEquals(sourceType, destType)) { // Identity cast; do nothing return; } else if ((explicitOperator != null)) { ilg.Emit(OpCodes.Call, explicitOperator); } else if (sourceType.IsEnum == true | destType.IsEnum == true) { this.EmitEnumCast(ilg, sourceType, destType, services); } else if (ImplicitConverter.EmitImplicitConvert(sourceType, destType, ilg) == true) { // Implicit numeric cast; do nothing return; } else if (IsCastableNumericType(sourceType) & IsCastableNumericType(destType)) { // Explicit numeric cast EmitExplicitNumericCast(ilg, sourceType, destType, services); } else if (sourceType.IsValueType == true) { Debug.Assert(destType.IsValueType == false, "expecting reference type"); ilg.Emit(OpCodes.Box, sourceType); } else { if (destType.IsValueType == true) { // Reference type to value type ilg.Emit(OpCodes.Unbox_Any, destType); } else { // Reference type to reference type if (destType.IsAssignableFrom(sourceType) == false) { // Only emit cast if it is an explicit cast ilg.Emit(OpCodes.Castclass, destType); } } } }
private void EmitOnDemandFunction(ExpressionElement[] elements, FleeILGenerator ilg, IServiceProvider services) { // Load the variable collection EmitLoadVariables(ilg); // Load the function name ilg.Emit(OpCodes.Ldstr, MyName); // Load the arguments array EmitElementArrayLoad(elements, typeof(object), ilg, services); // Call the function to get the result MethodInfo mi = VariableCollection.GetFunctionInvokeMethod(MyOnDemandFunctionReturnType); this.EmitMethodCall(mi, ilg); }
public override void Emit(FleeILGenerator ilg, System.IServiceProvider services) { int index = ilg.GetTempLocalIndex(typeof(TimeSpan)); Utility.EmitLoadLocalAddress(ilg, index); LiteralElement.EmitInt64Load(MyValue.Ticks, ilg); ConstructorInfo ci = typeof(TimeSpan).GetConstructor(new Type[] { typeof(long) }); ilg.Emit(OpCodes.Call, ci); Utility.EmitLoadLocal(ilg, index); }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { MyChild.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyChild.ResultType, MyResultType, ilg); ExpressionOptions options = services.GetService(typeof(ExpressionOptions)) as ExpressionOptions; if (options.IsGeneric == false) { ImplicitConverter.EmitImplicitConvert(MyResultType, typeof(object), ilg); } ilg.Emit(OpCodes.Ret); }
private void EmitFieldLoad(FieldInfo fi, FleeILGenerator ilg, IServiceProvider services) { if (fi.IsLiteral == true) { EmitLiteral(fi, ilg, services); } else if (this.ResultType.IsValueType == true & this.NextRequiresAddress == true) { EmitLdfld(fi, true, ilg); } else { EmitLdfld(fi, false, ilg); } }
private void EmitCollectionIn(FleeILGenerator ilg, IServiceProvider services) { // Get the contains method MethodInfo mi = this.GetCollectionContainsMethod(); ParameterInfo p1 = mi.GetParameters()[0]; // Load the collection MyTargetCollectionElement.Emit(ilg, services); // Load the argument MyOperand.Emit(ilg, services); // Do an implicit convert if necessary ImplicitConverter.EmitImplicitConvert(MyOperand.ResultType, p1.ParameterType, ilg); // Call the contains method ilg.Emit(OpCodes.Callvirt, mi); }
public static void EmitInt32Load(Int32 value, FleeILGenerator ilg) { if (value >= -1 & value <= 8) { EmitSuperShort(value, ilg); } else if (value >= sbyte.MinValue & value <= sbyte.MaxValue) { ilg.Emit(OpCodes.Ldc_I4_S, (sbyte)value); } else { ilg.Emit(OpCodes.Ldc_I4, value); } }
private static void EmitBranchToTrueTerminal(FleeILGenerator ilg, Label trueTerminal, BranchManager bm) { if (ilg.IsTemp == true) { bm.AddBranch(ilg, trueTerminal); ilg.Emit(OpCodes.Brtrue_S, trueTerminal); } else if (bm.IsLongBranch(ilg, trueTerminal) == false) { ilg.Emit(OpCodes.Brtrue_S, trueTerminal); } else { ilg.Emit(OpCodes.Brtrue, trueTerminal); } }
private void EmitEnumCast(FleeILGenerator ilg, Type sourceType, Type destType, IServiceProvider services) { if (destType.IsValueType == false) { ilg.Emit(OpCodes.Box, sourceType); } else if (sourceType.IsValueType == false) { ilg.Emit(OpCodes.Unbox_Any, destType); } else { sourceType = GetUnderlyingEnumType(sourceType); destType = GetUnderlyingEnumType(destType); this.EmitCast(ilg, sourceType, destType, services); } }
private void EmitArrayLoad(FleeILGenerator ilg, IServiceProvider services) { MyIndexerElement.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyIndexerElement.ResultType, typeof(Int32), ilg); Type elementType = this.ResultType; if (elementType.IsValueType == false) { // Simple reference load ilg.Emit(OpCodes.Ldelem_Ref); } else { this.EmitValueTypeArrayLoad(ilg, elementType); } }