/// <summary> /// </summary> /// <param name="virtualTable"> /// </param> /// <param name="thisType"> /// </param> /// <param name="llvmWriter"> /// </param> public static void BuildVirtualTable(this List<LlvmWriter.Pair<IMethod, IMethod>> virtualTable, IType thisType, LlvmWriter llvmWriter) { if (thisType.BaseType != null) { virtualTable.BuildVirtualTable(thisType.BaseType, llvmWriter); } // get all virtual methods in current type and replace or append foreach (var virtualOrAbstractMethod in IlReader.Methods(thisType).Where(m => m.IsVirtual || m.IsAbstract || m.IsOverride)) { if (virtualOrAbstractMethod.IsAbstract && virtualOrAbstractMethod.DeclaringType.Equals(thisType)) { virtualTable.Add(new LlvmWriter.Pair<IMethod, IMethod> { Key = virtualOrAbstractMethod, Value = virtualOrAbstractMethod }); continue; } // find method in virtual table var baseMethod = virtualOrAbstractMethod.IsOverride ? virtualTable.First(m => m.Key.IsMatchingOverride(virtualOrAbstractMethod)) : virtualTable.FirstOrDefault(m => m.Key.IsMatchingOverride(virtualOrAbstractMethod)); if (baseMethod == null) { virtualTable.Add(new LlvmWriter.Pair<IMethod, IMethod> { Key = virtualOrAbstractMethod, Value = virtualOrAbstractMethod }); continue; } baseMethod.Value = virtualOrAbstractMethod; } // append custom methods // custom GetHashCode for Enums if (thisType.ToNormal().IsEnum) { var getHashCodeMethod = new SynthesizedGetHashCodeMethod(thisType, llvmWriter); var baseMethod = virtualTable.First(m => m.Key.IsMatchingOverride(getHashCodeMethod)); baseMethod.Value = getHashCodeMethod; } // custom GetType // TODO: you need to append it before processing custom methods var getTypeMethod = new SynthesizedGetTypeMethod(thisType, llvmWriter); var baseGetTypeMethod = virtualTable.FirstOrDefault(m => m.Key.IsMatchingOverride(getTypeMethod)); #if !FOR_MSCORLIBTEST Debug.Assert(baseGetTypeMethod != null, "Could not find virtual method GetType (adjust source code and make GetType a virtual method"); #endif if (baseGetTypeMethod != null) { baseGetTypeMethod.Value = getTypeMethod; } }
/// <summary> /// </summary> /// <param name="type"> /// </param> /// <param name="llvmWriter"> /// </param> public static void WriteGetHashCodeMethodForEnum(this IType type, LlvmWriter llvmWriter) { var writer = llvmWriter.Output; var method = new SynthesizedGetHashCodeMethod(type, llvmWriter); writer.WriteLine("; default GetHashCode method"); var opCode = OpCodePart.CreateNop; llvmWriter.WriteMethodStart(method, null); llvmWriter.WriteLlvmLoad(opCode, type.ToClass(), new FullyDefinedReference(llvmWriter.GetThisName(), llvmWriter.ThisType), true, true); writer.WriteLine(string.Empty); var normalType = type.ToNormal(); llvmWriter.WriteGetHashCodeObjectForEnum(opCode, normalType); writer.Write("ret i32"); writer.Write(" "); llvmWriter.WriteResult(opCode.Result); llvmWriter.WriteMethodEnd(method, null); llvmWriter.methodsHaveDefinition.Add(method); }