Esempio n. 1
0
        /// <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;
            }
        }
Esempio n. 2
0
        /// <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);
        }