public static void EmitLoadLocal(YaleIlGenerator ilg, int index) { Debug.Assert(index >= 0, "Invalid index"); if (index >= 0 & index <= 3) { switch (index) { case 0: ilg.Emit(OpCodes.Ldloc_0); break; case 1: ilg.Emit(OpCodes.Ldloc_1); break; case 2: ilg.Emit(OpCodes.Ldloc_2); break; case 3: ilg.Emit(OpCodes.Ldloc_3); break; } } else { Debug.Assert(index < 256, "local index too large"); ilg.Emit(OpCodes.Ldloc_S, Convert.ToByte(index)); } }
private static bool ImplicitConvertToInt64(TypeCode sourceTypeCode, YaleIlGenerator ilGenerator) { switch (sourceTypeCode) { case TypeCode.SByte: case TypeCode.Int16: case TypeCode.Int32: EmitConvert(ilGenerator, OpCodes.Conv_I8); break; case TypeCode.Char: case TypeCode.Byte: case TypeCode.UInt16: case TypeCode.UInt32: EmitConvert(ilGenerator, OpCodes.Conv_U8); break; case TypeCode.Int64: break; default: return(false); } return(true); }
public static void SyncFleeIlGeneratorLabels(YaleIlGenerator source, YaleIlGenerator target) { while (source.LabelCount != target.LabelCount) { target.DefineLabel(); } }
/// <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(YaleIlGenerator ilg, Label target) { var startLoc = new ILLocation(ilg.Length); var branchInfo = new BranchInfo(startLoc, target); branchInfos.Add(branchInfo); }
/// <summary> /// Set the position for a label /// </summary> /// <param name="ilg"></param> /// <param name="target"></param> /// <remarks></remarks> public void MarkLabel(YaleIlGenerator ilg, Label target) { var pos = ilg.Length; foreach (var branchInfo in branchInfos) { branchInfo.Mark(target, pos); } }
/// <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, YaleIlGenerator ilg) { if (keyLabelMap.TryGetValue(key, out var lbl) == false) { lbl = ilg.DefineLabel(); keyLabelMap.Add(key, lbl); } return(lbl); }
public static void EmitArrayLoad(YaleIlGenerator ilg, Type elementType) { var typeCode = Type.GetTypeCode(elementType); switch (typeCode) { 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; } }
/// <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(YaleIlGenerator ilg, Label target) { var startLoc = new ILLocation(ilg.Length); var branchInfo = new BranchInfo(startLoc, target); var index = branchInfos.IndexOf(branchInfo); branchInfo = branchInfos[index]; return(branchInfo.IsLongBranch); }
public static void EmitLoadLocalAddress(YaleIlGenerator ilg, int index) { Debug.Assert(index >= 0, "Invalid index"); if (index <= byte.MaxValue) { ilg.Emit(OpCodes.Ldloca_S, Convert.ToByte(index)); } else { ilg.Emit(OpCodes.Ldloca, index); } }
private static void EmitConvert(YaleIlGenerator ilg, OpCode convertOpcode) { ilg?.Emit(convertOpcode); }
/// <summary> ///Emit an implicit conversion (if the ilg is not null) and returns a value that determines whether the implicit conversion /// succeeded /// </summary> /// <param name="sourceType"></param> /// <param name="destinationType"></param> /// <param name="ilGenerator"></param> /// <returns></returns> public static bool EmitImplicitNumericConvert(Type sourceType, Type destinationType, YaleIlGenerator ilGenerator) { var sourceTypeCode = Type.GetTypeCode(sourceType); var destTypeCode = Type.GetTypeCode(destinationType); switch (destTypeCode) { case TypeCode.Int16: return(ImplicitConvertToInt16(sourceTypeCode)); case TypeCode.UInt16: return(ImplicitConvertToUInt16(sourceTypeCode)); case TypeCode.Int32: return(ImplicitConvertToInt32(sourceTypeCode)); case TypeCode.UInt32: return(ImplicitConvertToUInt32(sourceTypeCode)); case TypeCode.Double: return(ImplicitConvertToDouble(sourceTypeCode, ilGenerator)); case TypeCode.Single: return(ImplicitConvertToSingle(sourceTypeCode, ilGenerator)); case TypeCode.Int64: return(ImplicitConvertToInt64(sourceTypeCode, ilGenerator)); case TypeCode.UInt64: return(ImplicitConvertToUInt64(sourceTypeCode, ilGenerator)); default: return(false); } }
private static bool ImplicitConvertToValueType(Type sourceType, Type destinationType, YaleIlGenerator ilGenerator) { // We only handle value types if (sourceType.IsValueType == false && destinationType.IsValueType == false) { return(false); } // No implicit conversion to enum. Have to do this check here since calling GetTypeCode on an enum will return the typecode // of the underlying type which screws us up. if (sourceType.IsEnum || destinationType.IsEnum) { return(false); } return(EmitImplicitNumericConvert(sourceType, destinationType, ilGenerator)); }
private static bool ImplicitConvertToReferenceType(Type sourceType, Type destinationType, YaleIlGenerator ilGenerator) { if (destinationType.IsValueType) { return(false); } if (ReferenceEquals(sourceType, typeof(Null))) { // Null is always convertible to a reference type return(true); } if (destinationType.IsAssignableFrom(sourceType) == false) { return(false); } if (sourceType.IsValueType) { ilGenerator?.Emit(OpCodes.Box, sourceType); } return(true); }
private static bool EmitOverloadedImplicitConvert(Type sourceType, Type destinationType, YaleIlGenerator ilGenerator) { // Look for an implicit operator on the destination type var methodInfo = Utility.GetSimpleOverloadedOperator("Implicit", sourceType, destinationType); if (methodInfo == null) { return(false); } ilGenerator?.Emit(OpCodes.Call, methodInfo); return(true); }
public static bool EmitImplicitConvert(Type sourceType, Type destinationType, YaleIlGenerator ilGenerator) { if (ReferenceEquals(sourceType, destinationType)) { return(true); } if (EmitOverloadedImplicitConvert(sourceType, destinationType, ilGenerator)) { return(true); } if (ImplicitConvertToReferenceType(sourceType, destinationType, ilGenerator)) { return(true); } return(ImplicitConvertToValueType(sourceType, destinationType, ilGenerator)); }
public override void Emit(YaleIlGenerator ilGenerator, ExpressionContext context) { Utility.EmitLoadLocal(ilGenerator, _index); }