Example #1
0
        /// <summary>
        /// </summary>
        /// <param name="methodBase">
        /// </param>
        /// <param name="opCodeMethodInfo">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        public static void PreProcessCallParameters(
            this IMethod methodBase,
            OpCodePart opCodeMethodInfo,
            LlvmWriter llvmWriter)
        {
            // check if you need to cast parameter
            if (opCodeMethodInfo.OpCodeOperands == null)
            {
                return;
            }

            var writer = llvmWriter.Output;

            var parameters = methodBase.GetParameters();
            var index = opCodeMethodInfo.OpCodeOperands.Count() - parameters.Count();
            foreach (var parameter in parameters)
            {
                var operand = opCodeMethodInfo.OpCodeOperands[index];

                var dynamicCastRequired = false;
                if (parameter.ParameterType.IsClassCastRequired(operand, out dynamicCastRequired))
                {
                    writer.WriteLine("; Cast of '{0}' parameter", parameter.Name);
                    llvmWriter.WriteCast(operand, operand.Result, parameter.ParameterType);
                }

                operand.RequiredIncomingType = parameter.ParameterType;
                llvmWriter.AdjustOperandResultTypeToIncomingType(operand);

                index++;
            }
        }
 public void Execute(LlvmWriter writer, OpCodePart opCode)
 {
     if (this.action != null)
     {
         this.action.Invoke(writer, opCode);
     }
 }
        /// <summary>
        /// </summary>
        /// <param name="typeIn">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        public static void WriteBoxMethod(this IType typeIn, LlvmWriter llvmWriter)
        {
            var writer = llvmWriter.Output;

            var classType = typeIn.ToClass();
            var normalType = typeIn.ToNormal();

            var method = new SynthesizedBoxMethod(classType);
            writer.WriteLine("; Box method");

            var isStruct = classType.ToNormal().IsStructureType();

            var opCode = OpCodePart.CreateNop;

            llvmWriter.WriteMethodStart(method, null);

            llvmWriter.WriteNewMethodBody(opCode, normalType, true);
            var newObjectResult = opCode.Result;
            opCode.Result = null;

            if (!isStruct)
            {
                llvmWriter.WriteLlvmLoad(opCode, normalType, new FullyDefinedReference(llvmWriter.GetArgVarName("value", 0), normalType));
                writer.WriteLine(string.Empty);
            }

            llvmWriter.WriteBoxObject(opCode, classType, newObjectResult, true);

            writer.Write("ret ");
            classType.WriteTypePrefix(writer);
            writer.Write(" ");
            llvmWriter.WriteResult(opCode.Result);

            llvmWriter.WriteMethodEnd(method, null);
        }
Example #4
0
        public static void IncDecInterlockBase(this OpCodePart opCodeMethodInfo, string oper, string attribs, LlvmWriter llvmWriter)
        {
            var writer = llvmWriter.Output;

            var first = opCodeMethodInfo.OpCodeOperands.First();
            var resultType = first.Result.Type.ToDereferencedType();

            llvmWriter.WriteSetResultNumber(opCodeMethodInfo, resultType);

            writer.Write(oper);
            //i32* %ptr, i32 %cmp, i32 %squared 

            var index = 0;
            foreach (var operand in opCodeMethodInfo.OpCodeOperands)
            {
                if (index++ > 0)
                {
                    writer.Write(", ");
                }

                operand.Result.Type.WriteTypePrefix(writer);
                writer.Write(' ');
                llvmWriter.WriteResult(operand.Result);
            }

            writer.Write(", ");
            resultType.WriteTypePrefix(writer);
            writer.Write(" 1");

            writer.WriteLine(attribs);
        }
Example #5
0
        /// <summary>
        /// </summary>
        /// <param name="method">
        /// </param>
        /// <param name="opCodeMethodInfo">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        /// <exception cref="NotImplementedException">
        /// </exception>
        public static void WriteActivatorFunction(
            this IMethod method,
            OpCodePart opCodeMethodInfo,
            LlvmWriter llvmWriter)
        {
            switch (method.MetadataName)
            {
                case "CreateInstance`1":

                    // this is dummy function which is not used now as using Boxing before calling CreateInstance is enough for us
                    var type = method.GetGenericArguments().First();

                    ////if (!type.IsStructureType())
                    ////{
                    ////    opCodeMethodInfo.Result = llvmWriter.WriteNewCallingDefaultConstructor(llvmWriter.Output, type);
                    ////}
                    ////else
                    ////{
                    ////    llvmWriter.WriteInit(opCodeMethodInfo, type, opCodeMethodInfo.Destination);
                    ////}
                    opCodeMethodInfo.Result = new ConstValue(null, type);

                    break;

                default:
                    throw new NotImplementedException();
            }
        }
Example #6
0
        /// <summary>
        /// </summary>
        /// <param name="type">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        public static void WriteRttiClassDefinition(this IType type, LlvmWriter llvmWriter)
        {
            var writer = llvmWriter.Output;

            type.WriteRttiClassName(writer);
            type.WriteRttiClassInfo(llvmWriter);
        }
Example #7
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="type">
        /// </param>
        public static void WriteAlloca(this LlvmWriter llvmWriter, IType type)
        {
            var writer = llvmWriter.Output;

            // for value types
            writer.Write("alloca ");
            type.WriteTypePrefix(llvmWriter);
            writer.Write(", align " + LlvmWriter.PointerSize);
        }
Example #8
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="type">
        /// </param>
        /// <param name="operandType">
        /// </param>
        public static void WriteGetTypeStaticObject(this LlvmWriter llvmWriter, OpCodePart opCode, IType type, IType operandType)
        {
            var writer = llvmWriter.Output;

            llvmWriter.WriteLlvmLoad(opCode, operandType, new FullyDefinedReference(type.GetTypeStaticFieldName(), operandType));
            writer.WriteLine(string.Empty);

            var result = opCode.Result;

            var testNullResultNumber = llvmWriter.WriteTestNull(writer, opCode, opCode.Result);

            llvmWriter.WriteBranchSwitchToExecute(
                writer,
                opCode,
                testNullResultNumber,
                operandType.FullName,
                "gettype",
                "new",
                () =>
            {
                // TODO: here send predifined byte array data with info for Type
                var runtimeType         = llvmWriter.ResolveType("System.RuntimeType");
                var byteType            = llvmWriter.ResolveType("System.Byte");
                var byteArrayType       = byteType.ToArrayType(1);
                var bytes               = type.GenerateTypeInfoBytes();
                var bytesIndex          = llvmWriter.GetBytesIndex(bytes);
                var firstParameterValue =
                    new FullyDefinedReference(
                        llvmWriter.GetArrayTypeReference(string.Format("@.bytes{0}", bytesIndex), byteType, bytes.Length), byteArrayType);

                opCode.Result       = null;
                var newObjectResult = llvmWriter.WriteNewWithCallingConstructor(opCode, runtimeType, byteArrayType, firstParameterValue);
                writer.WriteLine(string.Empty);

                // call cmp exchnage
                var noOpCmpXchg                      = OpCodePart.CreateNop;
                noOpCmpXchg.OpCodeOperands           = new[] { OpCodePart.CreateNop, OpCodePart.CreateNop, OpCodePart.CreateNop };
                noOpCmpXchg.OpCodeOperands[0].Result = new FullyDefinedReference(type.GetTypeStaticFieldName(), operandType.ToPointerType());
                noOpCmpXchg.OpCodeOperands[1].Result = new ConstValue(null, operandType);
                noOpCmpXchg.OpCodeOperands[2].Result = newObjectResult;
                noOpCmpXchg.InterlockBase("cmpxchg ", llvmWriter.IsLlvm34OrLower ? " acq_rel" : " acq_rel monotonic", !llvmWriter.IsLlvm35 && !llvmWriter.IsLlvm34OrLower, llvmWriter);
                writer.WriteLine(string.Empty);

                // load again
                opCode.Result = null;
                llvmWriter.WriteLlvmLoad(opCode, operandType, new FullyDefinedReference(type.GetTypeStaticFieldName(), operandType));
                writer.WriteLine(string.Empty);

                writer.Write("ret ");
                opCode.Result.Type.WriteTypePrefix(writer);
                writer.Write(" ");
                llvmWriter.WriteResult(opCode.Result);
                writer.WriteLine(string.Empty);
            });

            opCode.Result = result;
        }
Example #9
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        public static void WriteArrayGetLength(this LlvmWriter llvmWriter, OpCodePart opCode)
        {
            var intType = llvmWriter.ResolveType("System.Int32");

            var lengthResult = GetArrayDataAddressHelper(llvmWriter, opCode, intType, ArrayDataLength);

            opCode.Result = null;
            llvmWriter.WriteLlvmLoad(opCode, intType, lengthResult);
        }
Example #10
0
        public static void WriteArrayGetElementSize(this LlvmWriter llvmWriter, OpCodePart opCode)
        {
            var intType = llvmWriter.ResolveType("System.Int32");

            var elementSizeResult = GetArrayDataAddressHelper(llvmWriter, opCode, intType, ArrayDataElementSize);

            opCode.Result = null;
            llvmWriter.WriteLlvmLoad(opCode, intType, elementSizeResult);
        }
Example #11
0
        /// <summary>
        /// </summary>
        /// <param name="type">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        public static void WriteRttiClassInfo(this IType type, LlvmWriter llvmWriter)
        {
            var writer = llvmWriter.Output;

            writer.Write("@\"{0}\" = linkonce_odr constant ", type.GetRttiInfoName());
            type.WriteRttiClassInfoDeclaration(writer);
            writer.Write(' ');
            type.WriteRttiClassInfoDefinition(llvmWriter);
        }
Example #12
0
        /// <summary>
        /// </summary>
        /// <param name="type">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        public static void WriteRtti(this IType type, LlvmWriter llvmWriter)
        {
            var writer = llvmWriter.Output;

            writer.WriteLine("; RTTI class");
            type.WriteRttiClassDefinition(llvmWriter);
            writer.WriteLine("; RTTI pointer");
            type.WriteRttiPointerClassDefinition(writer);
        }
Example #13
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="finallyClause">
        /// </param>
        public static void WriteFinallyLeave(this LlvmWriter llvmWriter, CatchOfFinallyClause finallyClause)
        {
            var writer = llvmWriter.Output;

            llvmWriter.WriteFinallyVariables(finallyClause);

            writer.WriteLine("store i32 {0}, i32* %.finally_jump{1}", finallyClause.FinallyJumps.Count, finallyClause.Offset);
            writer.WriteLine("br label %.finally_no_error_entry{0}", finallyClause.Offset);
        }
Example #14
0
        /// <summary>
        /// </summary>
        /// <param name="type">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        public static void WriteRtti(this IType type, LlvmWriter llvmWriter)
        {
            var writer = llvmWriter.Output;

            writer.WriteLine("; RTTI class");
            type.WriteRttiClassDefinition(llvmWriter);
            writer.WriteLine("; RTTI pointer");
            type.WriteRttiPointerClassDefinition(writer);
        }
Example #15
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        public static void WriteUnreachable(this LlvmWriter llvmWriter)
        {
            var writer = llvmWriter.Output;

            writer.Indent--;
            writer.WriteLine(".unreachable:");
            writer.Indent++;
            writer.WriteLine("unreachable");
        }
Example #16
0
        /// <summary>
        /// </summary>
        /// <param name="virtualTable">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="type">
        /// </param>
        /// <param name="interfaceIndex">
        /// </param>
        /// <param name="baseTypeFieldsOffset">
        /// </param>
        public static void WriteTableOfMethods(
            this List <LlvmWriter.Pair <IMethod, IMethod> > virtualTable,
            LlvmWriter llvmWriter,
            IType type,
            int interfaceIndex,
            int baseTypeFieldsOffset)
        {
            var writer = llvmWriter.Output;

            writer.WriteLine(" = linkonce_odr constant [{0} x i8*] [", virtualTable.GetVirtualTableSize());

            writer.Indent++;
            writer.WriteLine(
                "i8* {0},",
                interfaceIndex == 0
                    ? "null"
                    : string.Format(
                    "inttoptr (i32 -{0} to i8*)",
                    baseTypeFieldsOffset + ((interfaceIndex - 1) * LlvmWriter.PointerSize)));

            // RTTI info class
            writer.Write("i8* bitcast (");
            type.WriteRttiClassInfoDeclaration(writer);
            writer.Write("* @\"{0}\" to i8*)", type.GetRttiInfoName());

            // define virtual table
            foreach (var virtualMethod in virtualTable)
            {
                var method = virtualMethod.Value;

                // write method pointer
                writer.WriteLine(",");

                writer.Write("i8* bitcast (");
                if (virtualMethod.Value == null || virtualMethod.Value.IsAbstract)
                {
                    writer.Write("void ()* @__cxa_pure_virtual");
                }
                else
                {
                    // write pointer to method
                    llvmWriter.WriteMethodReturnType(writer, method);
                    llvmWriter.WriteMethodParamsDef(writer, method, true, method.DeclaringType, method.ReturnType, true);
                    writer.Write("* ");
                    llvmWriter.WriteMethodDefinitionName(writer, method);

                    llvmWriter.CheckIfMethodExternalDeclarationIsRequired(method);
                }

                writer.Write(" to i8*)");
            }

            writer.WriteLine(string.Empty);
            writer.Indent--;
            writer.WriteLine("]");
        }
Example #17
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="fromResult">
        /// </param>
        /// <param name="toType">
        /// </param>
        /// <param name="throwExceptionIfNull">
        /// </param>
        /// <returns>
        /// </returns>
        public static bool WriteCast(
            this LlvmWriter llvmWriter,
            OpCodePart opCode,
            FullyDefinedReference fromResult,
            IType toType,
            bool throwExceptionIfNull = false)
        {
            var writer = llvmWriter.Output;

            var bareType = !fromResult.Type.IsArray
                ? fromResult.Type.ToBareType()
                : fromResult.Type;

            if (toType.IsInterface && !(fromResult is ConstValue))
            {
                if (bareType.GetAllInterfaces().Contains(toType))
                {
                    opCode.Result = fromResult;
                    llvmWriter.WriteInterfaceAccess(writer, opCode, bareType, toType);
                }
                else
                {
                    llvmWriter.WriteDynamicCast(writer, opCode, fromResult, toType, true, throwExceptionIfNull);
                }
            }
            else if (fromResult.Type.IntTypeBitSize() == LlvmWriter.PointerSize * 8 &&
                     (toType.IsPointer || toType.IsByRef))
            {
                LlvmConvert(llvmWriter, opCode, string.Empty, string.Empty, toType, true);
            }
            else if (fromResult.Type.IsArray ||
                     (fromResult.Type.IsPointer && bareType.TypeEquals(llvmWriter.System.System_Void)) ||
                     toType.IsArray ||
                     toType.IsPointer ||
                     toType.IsByRef ||
                     bareType.IsDerivedFrom(toType) ||
                     (fromResult is ConstValue))
            {
                llvmWriter.WriteSetResultNumber(opCode, toType);
                writer.Write("bitcast ");
                fromResult.Type.WriteTypePrefix(llvmWriter);
                writer.Write(' ');
                llvmWriter.WriteResult(fromResult);
                writer.Write(" to ");
                toType.WriteTypePrefix(llvmWriter, toType.IsStructureType());
            }
            else
            {
                Debug.Assert(fromResult.Type.IntTypeBitSize() == 0);
                llvmWriter.WriteDynamicCast(writer, opCode, fromResult, toType, true, throwExceptionIfNull);
            }

            writer.WriteLine(string.Empty);

            return(true);
        }
Example #18
0
        public static void WriteMemSet(this LlvmWriter llvmWriter, FullyDefinedReference op1, FullyDefinedReference size)
        {
            var writer = llvmWriter.Output;

            writer.Write("call void @llvm.memset.p0i8.i32(i8* {0}, i8 0, ", op1);
            size.Type.WriteTypePrefix(writer);
            writer.Write(" ");
            llvmWriter.WriteResult(size);
            writer.Write(", i32 {0}, i1 false)", LlvmWriter.PointerSize /*Align*/);
        }
Example #19
0
        /// <summary>
        /// </summary>
        /// <param name="type">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        public static void WriteCallUnboxObjectMethod(this IType type, LlvmWriter llvmWriter, OpCodePart opCode)
        {
            var writer = llvmWriter.Output;

            var method = new SynthesizedUnboxMethod(type);

            writer.WriteLine(string.Empty);
            writer.WriteLine("; call Unbox Object method");
            llvmWriter.WriteCall(opCode, method, false, true, false, null, llvmWriter.tryScopes.Count > 0 ? llvmWriter.tryScopes.Peek() : null);
        }
Example #20
0
        /// <summary>
        /// </summary>
        /// <param name="declaringType">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        /// <returns>
        /// </returns>
        public static string GetVirtualTableReference(this IType declaringType, LlvmWriter llvmWriter)
        {
            var virtualTable = declaringType.GetVirtualTable(llvmWriter);

            return(string.Format(
                       "getelementptr inbounds ([{0} x i8*]* {1}, i32 0, i32 {2})",
                       virtualTable.GetVirtualTableSize(),
                       declaringType.GetVirtualTableName(),
                       FunctionsOffsetInVirtualTable));
        }
Example #21
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="elementType">
        /// </param>
        /// <param name="length">
        /// </param>
        /// <returns>
        /// </returns>
        public static string GetArrayTypeHeader(this LlvmWriter llvmWriter, IType elementType, int length)
        {
            var typeString = llvmWriter.WriteToString(
                () =>
            {
                elementType.WriteTypePrefix(llvmWriter);
            });

            return("{ " + GetSingleDimArrayPrefixDataType(llvmWriter) + ", [" + length + " x " + typeString + "] }");
        }
Example #22
0
        /// <summary>
        /// </summary>
        /// <param name="declaringType">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        /// <returns>
        /// </returns>
        public static string GetVirtualTableReference(this IType declaringType, LlvmWriter llvmWriter)
        {
            var virtualTable = declaringType.GetVirtualTable(llvmWriter);

            return string.Format(
                "getelementptr inbounds ([{0} x i8*]* {1}, i32 0, i32 {2})", 
                virtualTable.GetVirtualTableSize(), 
                declaringType.GetVirtualTableName(), 
                FunctionsOffsetInVirtualTable);
        }
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="declaringType">
        /// </param>
        public static void WriteGetHashCodeObjectForEnum(
            this LlvmWriter llvmWriter,
            OpCodePart opCode,
            IType declaringType)
        {
            var writer = llvmWriter.Output;

            var isStruct = declaringType.IsStructureType();

            writer.WriteLine("; Returning Hash Code");
            writer.WriteLine(string.Empty);

            llvmWriter.CheckIfExternalDeclarationIsRequired(declaringType);

            writer.WriteLine("; Get data");

            if (!isStruct)
            {
                // write access to a field
                if (
                    !llvmWriter.WriteFieldAccess(
                        opCode,
                        declaringType.ToClass(),
                        declaringType.ToClass(),
                        0,
                        opCode.Result))
                {
                    writer.WriteLine("; No data");
                    return;
                }

                writer.WriteLine(string.Empty);
            }
            else
            {
                Debug.Fail("Not implemented yet");
                throw new NotImplementedException();
            }

            // load value from field
            var memberAccessResultNumber = opCode.Result;

            opCode.Result = null;
            llvmWriter.WriteLlvmLoad(opCode, memberAccessResultNumber.Type.ToNormal(), memberAccessResultNumber);
            writer.WriteLine(string.Empty);

            if (opCode.Result.Type.IntTypeBitSize() != llvmWriter.System.System_Int32.IntTypeBitSize())
            {
                llvmWriter.AdjustIntConvertableTypes(writer, opCode, llvmWriter.System.System_Int32);
                writer.WriteLine(string.Empty);
            }

            writer.WriteLine("; End of Getting data");
        }
Example #24
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="result">
        /// </param>
        public static void WriteBitcast(this LlvmWriter llvmWriter, OpCodePart opCode, FullyDefinedReference result)
        {
            var writer = llvmWriter.Output;

            llvmWriter.WriteSetResultNumber(opCode, llvmWriter.System.System_Byte.ToPointerType());
            writer.Write("bitcast ");
            result.Type.WriteTypePrefix(llvmWriter, !result.Type.IsByRef && result.Type.IsValueType());
            writer.Write(" ");
            llvmWriter.WriteResult(result);
            writer.Write(" to i8*");
        }
Example #25
0
        /// <summary>
        /// </summary>
        /// <param name="type">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        public static void WriteUnboxMethod(this IType type, LlvmWriter llvmWriter)
        {
            var writer = llvmWriter.Output;

            var method = new SynthesizedUnboxMethod(type);

            writer.WriteLine("; Unbox method");

            var opCode = OpCodePart.CreateNop;

            var normalType = type.ToNormal();
            var isStruct   = normalType.IsStructureType();

            if (isStruct)
            {
                opCode.Result = new FullyDefinedReference("%agg.result", normalType);
            }

            llvmWriter.WriteMethodStart(method, null);
            llvmWriter.WriteLlvmLoad(opCode, type.ToClass(), new FullyDefinedReference(llvmWriter.GetThisName(), llvmWriter.ThisType), true, true);
            writer.WriteLine(string.Empty);

            var resultPresents = llvmWriter.WriteUnboxObject(opCode, normalType);

            writer.Write("ret ");
            if (!isStruct)
            {
                if (normalType.IsEnum)
                {
                    normalType.GetEnumUnderlyingType().WriteTypePrefix(writer);
                }
                else
                {
                    normalType.WriteTypePrefix(writer);
                }

                writer.Write(" ");

                if (resultPresents)
                {
                    llvmWriter.WriteResult(opCode.Result);
                }
                else
                {
                    writer.WriteLine(" undef");
                }
            }
            else
            {
                writer.WriteLine(" void");
            }

            llvmWriter.WriteMethodEnd(method, null);
        }
        /// <summary>
        /// </summary>
        /// <param name="type">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        public static void WriteRttiClassInfoDefinition(IType type, LlvmWriter llvmWriter)
        {
            var writer = llvmWriter.Output;

            writer.WriteLine("{");
            writer.Indent++;
            writer.WriteLine("i8* bitcast (i8** getelementptr inbounds (i8** @_ZTVN10__cxxabiv117__class_type_infoE, i32 2) to i8*),");
            writer.WriteLine("i8* getelementptr inbounds ([{1} x i8]* @\"{0}\", i32 0, i32 0)", type.GetRttiStringName(), type.StringLength());
            writer.Indent--;
            writer.WriteLine("}");
        }
Example #27
0
        /// <summary>
        /// </summary>
        /// <param name="methodInfo">
        /// </param>
        /// <param name="opCodeMethodInfo">
        /// </param>
        /// <param name="isVirtual">
        /// </param>
        /// <param name="hasThis">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="thisType">
        /// </param>
        /// <param name="hasThisArgument">
        /// </param>
        /// <param name="opCodeFirstOperand">
        /// </param>
        /// <param name="resultOfFirstOperand">
        /// </param>
        /// <param name="isIndirectMethodCall">
        /// </param>
        /// <param name="ownerOfExplicitInterface">
        /// </param>
        /// <param name="requiredType">
        /// </param>
        public static void WriteFunctionCallProlog(
            this IMethod methodInfo,
            OpCodePart opCodeMethodInfo,
            bool isVirtual,
            bool hasThis,
            LlvmWriter llvmWriter,
            out IType thisType,
            out bool hasThisArgument,
            out OpCodePart opCodeFirstOperand,
            out BaseWriter.ReturnResult resultOfFirstOperand,
            out bool isIndirectMethodCall,
            out IType ownerOfExplicitInterface,
            out IType requiredType)
        {
            thisType = methodInfo.DeclaringType.ToClass();

            hasThisArgument = hasThis && opCodeMethodInfo.OpCodeOperands != null &&
                              opCodeMethodInfo.OpCodeOperands.Length - methodInfo.GetParameters().Count() > 0;
            opCodeFirstOperand = opCodeMethodInfo.OpCodeOperands != null && opCodeMethodInfo.OpCodeOperands.Length > 0
                ? opCodeMethodInfo.OpCodeOperands[0]
                : null;
            resultOfFirstOperand = opCodeFirstOperand != null?llvmWriter.ResultOf(opCodeFirstOperand) : null;

            isIndirectMethodCall = isVirtual
                                   &&
                                   (methodInfo.IsAbstract || methodInfo.IsVirtual ||
                                    (thisType.IsInterface && thisType.TypeEquals(resultOfFirstOperand.Type)));

            ownerOfExplicitInterface = isVirtual && thisType.IsInterface &&
                                       thisType.TypeNotEquals(resultOfFirstOperand.Type)
                ? resultOfFirstOperand.Type
                : null;

            var rollbackType = false;

            requiredType = ownerOfExplicitInterface != null ? resultOfFirstOperand.Type : null;
            if (requiredType != null)
            {
                thisType     = requiredType;
                rollbackType = true;
            }

            if (isIndirectMethodCall && methodInfo.DeclaringType.TypeNotEquals(thisType) &&
                methodInfo.DeclaringType.IsInterface && !thisType.IsInterface &&
                thisType.HasExplicitInterfaceMethodOverride(methodInfo))
            {
                // this is explicit call of interface
                isIndirectMethodCall = false;
            }
            else if (rollbackType)
            {
                thisType = methodInfo.DeclaringType;
            }
        }
Example #28
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="charType">
        /// </param>
        /// <param name="length">
        /// </param>
        /// <returns>
        /// </returns>
        public static string GetStringTypeHeader(this LlvmWriter llvmWriter, int length)
        {
            var charType   = llvmWriter.System.System_Char;
            var typeString = llvmWriter.WriteToString(
                () =>
            {
                charType.WriteTypePrefix(llvmWriter);
            });

            return("{ " + GetStringPrefixDataType(llvmWriter) + ", [" + length + " x " + typeString + "] }");
        }
Example #29
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="result">
        /// </param>
        public static void WriteBitcast(this LlvmWriter llvmWriter, OpCodePart opCode, FullyDefinedReference result)
        {
            var writer = llvmWriter.Output;

            llvmWriter.WriteSetResultNumber(opCode, llvmWriter.ResolveType("System.Byte").ToPointerType());
            writer.Write("bitcast ");
            result.Type.WriteTypePrefix(writer, true);
            writer.Write(" ");
            llvmWriter.WriteResult(result);
            writer.Write(" to i8*");
        }
Example #30
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="realConvert">
        /// </param>
        /// <param name="intConvert">
        /// </param>
        /// <param name="toType">
        /// </param>
        /// <param name="toAddress">
        /// </param>
        /// <param name="typesToExclude">
        /// </param>
        public static void LlvmConvert(
            this LlvmWriter llvmWriter, OpCodePart opCode, string realConvert, string intConvert, IType toType, bool toAddress, params IType[] typesToExclude)
        {
            var writer = llvmWriter.Output;

            var resultOf        = llvmWriter.ResultOf(opCode.OpCodeOperands[0]);
            var areBothPointers = (resultOf.Type.IsPointer || resultOf.Type.IsByRef) && toAddress;
            var typeToTest      = resultOf.Type.IsEnum ? resultOf.Type.GetEnumUnderlyingType() : resultOf.Type;

            if (!typesToExclude.Any(typeToTest.TypeEquals) && !areBothPointers)
            {
                if (resultOf.Type.IsReal())
                {
                    llvmWriter.UnaryOper(writer, opCode, realConvert, resultType: toType, options: LlvmWriter.OperandOptions.GenerateResult);
                }
                else if (resultOf.Type.IsPointer || resultOf.Type.IsByRef)
                {
                    llvmWriter.UnaryOper(writer, opCode, "ptrtoint", resultType: toType, options: LlvmWriter.OperandOptions.GenerateResult);
                }
                else if (toType.IsPointer || toType.IsByRef)
                {
                    llvmWriter.UnaryOper(writer, opCode, "inttoptr", resultType: toType, options: LlvmWriter.OperandOptions.GenerateResult);
                }
                else
                {
                    var intSize = toType.IntTypeBitSize();
                    if (intSize > 0)
                    {
                        var toIntType = llvmWriter.GetIntTypeByByteSize(intSize / 8);
                        if (llvmWriter.AdjustIntConvertableTypes(writer, opCode.OpCodeOperands[0], toIntType))
                        {
                            opCode.Result = opCode.OpCodeOperands[0].Result;
                            return;
                        }
                    }

                    // if types are equals then
                    if (opCode.OpCodeOperands[0].Result.Type.TypeEquals(toType))
                    {
                        opCode.Result = opCode.OpCodeOperands[0].Result;
                        return;
                    }

                    llvmWriter.UnaryOper(writer, opCode, intConvert, resultType: toType, options: LlvmWriter.OperandOptions.GenerateResult);
                }

                writer.Write(" to ");
                toType.WriteTypePrefix(writer);
            }
            else
            {
                opCode.Result = opCode.OpCodeOperands[0].Result;
            }
        }
        /// <summary>
        /// </summary>
        /// <param name="type">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        public static void WriteRttiClassInfoDefinition(IType type, LlvmWriter llvmWriter)
        {
            var writer = llvmWriter.Output;

            writer.WriteLine("{");
            writer.Indent++;
            writer.WriteLine("i8* bitcast (i8** getelementptr inbounds (i8** @_ZTVN10__cxxabiv117__class_type_infoE, i32 2) to i8*),");
            writer.WriteLine("i8* getelementptr inbounds ([{1} x i8]* @\"{0}\", i32 0, i32 0)", type.GetRttiStringName(), type.StringLength());
            writer.Indent--;
            writer.WriteLine("}");
        }
Example #32
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="objectResult">
        /// </param>
        /// <param name="methodResult">
        /// </param>
        /// <param name="invokeMethod">
        /// </param>
        /// <param name="isStatic">
        /// </param>
        /// <returns>
        /// </returns>
        public static FullyDefinedReference WriteCallInvokeMethod(
            this LlvmWriter llvmWriter,
            FullyDefinedReference objectResult,
            FullyDefinedReference methodResult,
            IMethod invokeMethod,
            bool isStatic)
        {
            var writer = llvmWriter.Output;

            var method     = new SynthesizedInvokeMethod(llvmWriter, objectResult, methodResult, invokeMethod, isStatic);
            var opCodeNope = OpCodePart.CreateNop;

            opCodeNope.OpCodeOperands =
                Enumerable.Range(0, invokeMethod.GetParameters().Count())
                .Select(p => new OpCodeInt32Part(OpCodesEmit.Ldarg, 0, 0, p + 1))
                .ToArray();

            foreach (var generatedOperand in opCodeNope.OpCodeOperands)
            {
                llvmWriter.ActualWrite(writer, generatedOperand);
            }

            writer.WriteLine(string.Empty);

            // bitcast object to method
            var opCodeNopeForBitCast = OpCodePart.CreateNop;

            opCodeNopeForBitCast.OpCodeOperands           = new[] { OpCodePart.CreateNop };
            opCodeNopeForBitCast.OpCodeOperands[0].Result = methodResult;
            llvmWriter.UnaryOper(
                writer,
                opCodeNopeForBitCast,
                "bitcast",
                methodResult.Type,
                options: LlvmWriter.OperandOptions.GenerateResult);
            writer.Write(" to ");
            llvmWriter.WriteMethodPointerType(writer, method);
            writer.WriteLine(string.Empty);

            method.MethodResult = opCodeNopeForBitCast.Result;

            // actual call
            llvmWriter.WriteCall(
                opCodeNope,
                method,
                false,
                !isStatic,
                false,
                objectResult,
                llvmWriter.tryScopes.Count > 0 ? llvmWriter.tryScopes.Peek() : null);
            writer.WriteLine(string.Empty);

            return(opCodeNope.Result);
        }
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="exceptionHandlingClause">
        /// </param>
        /// <param name="upperLevelExceptionHandlingClause">
        /// </param>
        public static void WriteRethrow(
            this LlvmWriter llvmWriter,
            OpCodePart opCode,
            CatchOfFinallyClause exceptionHandlingClause,
            CatchOfFinallyClause upperLevelExceptionHandlingClause)
        {
            var writer = llvmWriter.Output;

            writer.WriteLine("; Rethrow");
            WriteRethrowInvoke(llvmWriter, exceptionHandlingClause);
        }
        /// <summary>
        /// </summary>
        /// <param name="type">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        public static void WriteTypeStorageStaticField(this IType type, LlvmWriter llvmWriter)
        {
            var writer = llvmWriter.Output;

            writer.Write(
                "{0} = {1}global ",
                type.GetTypeStaticFieldName(),
                "linkonce_odr ");
            llvmWriter.System.System_Type.WriteTypePrefix(llvmWriter);
            writer.WriteLine(" null");
        }
Example #35
0
 /// <summary>
 /// </summary>
 /// <param name="method">
 /// </param>
 /// <param name="opCodeMethodInfo">
 /// </param>
 /// <param name="llvmWriter">
 /// </param>
 /// <exception cref="NotImplementedException">
 /// </exception>
 public static void WriteArrayFunction(this IMethod method, OpCodePart opCodeMethodInfo, LlvmWriter llvmWriter)
 {
     switch (method.Name)
     {
         case "get_Length":
             llvmWriter.WriteArrayGetLength(opCodeMethodInfo);
             break;
         default:
             throw new NotImplementedException();
     }
 }
Example #36
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="type">
        /// </param>
        /// <param name="op1">
        /// </param>
        public static void WriteMemSet(this LlvmWriter llvmWriter, IType type, FullyDefinedReference op1)
        {
            var writer = llvmWriter.Output;

            writer.Write(
                "call void @llvm.memset.p0i8.i32(i8* {0}, i8 0, i32 {1}, i32 {2}, i1 false)",
                op1,
                type.GetTypeSize(type.IsPrimitiveType() && !type.UseAsClass),
                LlvmWriter.PointerSize

                /*Align*/);
        }
Example #37
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="toType">
        /// </param>
        public static void WriteBitcast(this LlvmWriter llvmWriter, OpCodePart opCode, IType toType)
        {
            var writer = llvmWriter.Output;

            llvmWriter.WriteSetResultNumber(opCode, toType);
            writer.Write("bitcast ");
            opCode.Result.Type.WriteTypePrefix(writer, true);
            writer.Write(" ");
            llvmWriter.WriteResult(opCode.Result);
            writer.Write(" to ");
            toType.WriteTypePrefix(writer, true);
        }
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        public static void WriteUnwindException(this LlvmWriter llvmWriter)
        {
            var writer = llvmWriter.Output;

            writer.Indent--;
            writer.WriteLine(".unwind_exception:");
            writer.Indent++;
            llvmWriter.WriteLandingPad(OpCodePart.CreateNop, LandingPadOptions.EmptyFilter, null);
            writer.WriteLine(string.Empty);
            writer.WriteLine("br label %.unexpected");
            llvmWriter.WriteUnexpectedCall();
        }
Example #39
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="source">
        /// </param>
        /// <param name="toType">
        /// </param>
        public static void WritePtrToInt(this LlvmWriter llvmWriter, OpCodePart opCode, FullyDefinedReference source, IType toType)
        {
            var writer = llvmWriter.Output;

            llvmWriter.WriteSetResultNumber(opCode, toType);
            writer.Write("ptrtoint ");
            source.Type.WriteTypePrefix(writer, true);
            writer.Write(" ");
            llvmWriter.WriteResult(source);
            writer.Write(" to ");
            toType.WriteTypePrefix(writer);
        }
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="exceptionHandlingClause">
        /// </param>
        public static void WriteCatchBegin(this LlvmWriter llvmWriter, CatchOfFinallyClause exceptionHandlingClause)
        {
            var writer = llvmWriter.Output;

            var isFinally = exceptionHandlingClause.Flags.HasFlag(ExceptionHandlingClauseOptions.Finally);

            if (isFinally)
            {
                writer.WriteLine("; Begin of Finally");
            }
            else
            {
                writer.WriteLine("; Begin of Catch");
            }

            var catchType = exceptionHandlingClause.Catch;

            var opCodeNone      = OpCodePart.CreateNop;
            var bytePointerType = llvmWriter.System.System_Byte.ToPointerType();
            var errorObjectOfCatchResultNumber = llvmWriter.WriteSetResultNumber(opCodeNone, bytePointerType);

            writer.WriteLine("load i8** %.error_object");
            var beginCatchResultNumber = llvmWriter.WriteSetResultNumber(opCodeNone, bytePointerType);

            writer.WriteLine("call i8* @__cxa_begin_catch(i8* {0})", errorObjectOfCatchResultNumber);
            if (catchType != null)
            {
                llvmWriter.WriteBitcast(opCodeNone, beginCatchResultNumber, catchType);
                writer.WriteLine(string.Empty);

                exceptionHandlingClause.ExceptionResult = opCodeNone.Result;
            }

            if (isFinally)
            {
                // set default error handler jump to carry on try/catch execution
                writer.WriteLine("store i32 0, i32* %.finally_jump{0}", exceptionHandlingClause.Offset);
                writer.WriteLine("br label %.finally_no_error_entry{0}", exceptionHandlingClause.Offset);
                writer.Indent--;
                writer.WriteLine(".finally_no_error_entry{0}:", exceptionHandlingClause.Offset);
                writer.Indent++;
            }

            if (isFinally)
            {
                writer.WriteLine("; Begin of Finally Handler Body");
            }
            else
            {
                writer.WriteLine("; Begin of Catch Handler Body");
            }
        }
Example #41
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;
            }
        }
Example #42
0
        /// <summary>
        /// </summary>
        /// <param name="method">
        /// </param>
        /// <param name="opCodeMethodInfo">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        public static void WriteThreadingFunction(
            this IMethod method,
            OpCodePart opCodeMethodInfo,
            LlvmWriter llvmWriter)
        {
            var writer = llvmWriter.Output;

            switch (method.MetadataName)
            {
                case "MemoryBarrier":
                    writer.WriteLine("fence acquire");
                    break;
            }
        }
        /// <summary>
        /// </summary>
        /// <param name="type">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        public static void WriteRttiClassInfoDefinition(IType type, LlvmWriter llvmWriter)
        {
            var writer = llvmWriter.Output;

            writer.WriteLine("{");
            writer.Indent++;
            writer.WriteLine("i8* bitcast (i8** getelementptr inbounds (i8** @_ZTVN10__cxxabiv120__si_class_type_infoE, i32 2) to i8*),");
            writer.WriteLine("i8* getelementptr inbounds ([{1} x i8]* @\"{0}\", i32 0, i32 0),", type.GetRttiStringName(), type.StringLength());
            writer.Write("i8* bitcast (");

            var singleInheritanceType = type.GetInterfaces().First();

            singleInheritanceType.WriteRttiClassInfoDeclaration(writer);
            writer.WriteLine("* @\"{0}\" to i8*)", singleInheritanceType.GetRttiInfoName());
            writer.Indent--;
            writer.WriteLine("}");
        }
        /// <summary>
        /// </summary>
        /// <param name="type">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        public static void WriteRttiClassInfoDefinition(IType type, LlvmWriter llvmWriter)
        {
            var writer = llvmWriter.Output;

            var @interfaces = type.GetInterfaces();

            writer.WriteLine("{");
            writer.Indent++;
            writer.WriteLine(
                "i8* bitcast (i8** getelementptr inbounds (i8** @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i32 2) to i8*),");
            writer.WriteLine(
                "i8* getelementptr inbounds ([{1} x i8]* @\"{0}\", i32 0, i32 0),",
                type.GetRttiStringName(),
                type.StringLength());
            writer.WriteLine("i32 0,");
            writer.WriteLine("i32 {0}", @interfaces.Count() + (type.BaseType != null ? 1 : 0));

            var nextFlag = 2;

            if (type.BaseType != null)
            {
                writer.Write(",i8* bitcast (");
                type.BaseType.WriteRttiClassInfoDeclaration(writer);
                writer.WriteLine("* @\"{0}\" to i8*),", type.BaseType.GetRttiInfoName());

                // if class does not have any virtual method then next value should be 0, else 2 (and next class should be +1024)
                writer.WriteLine("i32 {0}", nextFlag);

                // apply fields shift + base item
                // nextFlag += 1024 * (type.BaseType.GetFieldsShift() + 1);
                nextFlag += 1024 * (type.BaseType.GetTypeSize(llvmWriter) / LlvmWriter.PointerSize);
            }

            foreach (var @interface in type.GetInterfaces())
            {
                writer.Write(",i8* bitcast (");
                @interface.WriteRttiClassInfoDeclaration(writer);
                writer.WriteLine("* @\"{0}\" to i8*),", @interface.GetRttiInfoName());
                writer.WriteLine("i32 {0}", nextFlag);
                nextFlag += 1024;
            }

            writer.Indent--;
            writer.WriteLine("}");
        }
Example #45
0
        /// <summary>
        /// </summary>
        /// <param name="typeIn">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        public static void WriteGetTypeStaticMethod(this IType typeIn, LlvmWriter llvmWriter)
        {
            var writer = llvmWriter.Output;

            var classType = typeIn.ToClass();

            var systemType = llvmWriter.ResolveType("System.Type");
            var method = new SynthesizedGetTypeStaticMethod(classType, llvmWriter);
            writer.WriteLine("; Get Type Object method");

            var opCode = OpCodePart.CreateNop;
            llvmWriter.WriteMethodStart(method, null);
            llvmWriter.WriteGetTypeStaticObject(opCode, classType, systemType);

            writer.Write("ret ");
            systemType.WriteTypePrefix(writer);
            writer.Write(" ");
            llvmWriter.WriteResult(opCode.Result);

            llvmWriter.WriteMethodEnd(method, null);
        }
Example #46
0
        public static void WriteInterlockedFunction(this IMethod method, OpCodePart opCodeMethodInfo, LlvmWriter llvmWriter)
        {
            switch (method.MetadataName)
            {
                case "Increment":
                    opCodeMethodInfo.IncDecInterlockBase("atomicrmw add ", " acquire", llvmWriter);
                    break;

                case "Decrement":
                    opCodeMethodInfo.IncDecInterlockBase("atomicrmw sub ", " acquire", llvmWriter);
                    break;

                case "Exchange`1":
                case "Exchange":
                    opCodeMethodInfo.InterlockBase("atomicrmw xchg ", " acquire", false, llvmWriter);
                    break;

                case "CompareExchange`1":
                case "CompareExchange":
                    opCodeMethodInfo.InterlockBase("cmpxchg ", " acq_rel monotonic", llvmWriter.IsLlvm36OrHigher, llvmWriter);
                    break;
            }
        }
Example #47
0
        /// <summary>
        /// </summary>
        /// <param name="thisType">
        /// </param>
        /// <param name="methodInfo">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="requiredInterface">
        /// </param>
        /// <returns>
        /// </returns>
        /// <exception cref="KeyNotFoundException">
        /// </exception>
        public static int GetVirtualMethodIndex(this IType thisType, IMethod methodInfo, LlvmWriter llvmWriter, out IType requiredInterface)
        {
            requiredInterface = null;

            if (!thisType.IsInterface)
            {
                var virtualTable = thisType.GetVirtualTable(llvmWriter);

                var index = 0;
                foreach (var virtualMethod in virtualTable.Select(v => v.Value))
                {
                    if (virtualMethod.IsMatchingOverride(methodInfo))
                    {
                        // + RTTI info shift
                        return index;
                    }

                    index++;
                }

                throw new KeyNotFoundException("virtual method could not be found");
            }
            else
            {
                var virtualTable = thisType.GetVirtualInterfaceTableLayout();

                var index = 0;
                foreach (var virtualMethod in virtualTable)
                {
                    if (virtualMethod.IsMatchingOverride(methodInfo))
                    {
                        // + RTTI info shift
                        return index;
                    }

                    index++;
                }

                // try to find a method in all interfaces
                foreach (var @interface in thisType.SelectAllTopAndAllNotFirstChildrenInterfaces().Skip(1))
                {
                    var virtualTableOfSecondaryInterface = @interface.GetVirtualInterfaceTableLayout();

                    index = 0;
                    foreach (var virtualMethod in virtualTableOfSecondaryInterface)
                    {
                        if (virtualMethod.IsMatchingOverride(methodInfo))
                        {
                            requiredInterface = @interface;

                            // + RTTI info shift
                            return index;
                        }

                        index++;
                    }
                }

                throw new KeyNotFoundException("virtual method could not be found");
            }
        }
Example #48
0
        /// <summary>
        /// </summary>
        /// <param name="type">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        public static void WriteRttiClassInfo(this IType type, LlvmWriter llvmWriter)
        {
            var writer = llvmWriter.Output;

            writer.Write("@\"{0}\" = linkonce_odr constant ", type.GetRttiInfoName());
            type.WriteRttiClassInfoDeclaration(writer);
            writer.Write(' ');
            type.WriteRttiClassInfoDefinition(llvmWriter);
        }
 /// <summary>
 /// </summary>
 /// <param name="type">
 /// </param>
 /// <param name="llvmWriter">
 /// </param>
 public SynthesizedGetTypeStaticMethod(IType type, LlvmWriter llvmWriter)
     : base(type, ".getType")
 {
     this.systemType = llvmWriter.ResolveType("System.Type");
 }
Example #50
0
        private static void CompileExeTarget(string[] sources, string[] processedArgs)
        {
            var corelibSwitch = "corelib:";
            var findCoreLibSwitch = processedArgs.FirstOrDefault(arg => arg.StartsWith(corelibSwitch));
            if (findCoreLibSwitch == null)
            {
                Console.WriteLine("It is needed to provide CoreLib using /corelib:<file.dll> switch");
                return;
            }

            Console.Write("Generating LLVM IR file for CoreLib...");
            var coreLib = findCoreLibSwitch.Substring(corelibSwitch.Length);
            Il2Converter.Convert(
                new[] { coreLib },
                Environment.CurrentDirectory,
                processedArgs.Where(p => !p.StartsWith(corelibSwitch)).ToArray());
            Console.WriteLine("Done.");

            // you need to get target
            var llvmDummyWriter = new LlvmWriter(string.Empty, string.Empty, string.Empty, processedArgs);
            var target = llvmDummyWriter.Target;

            // next step compile CoreLib
            Console.Write("Compiling LLVM IR file for CoreLib...");
            var coreLibNameNoExt = Path.GetFileNameWithoutExtension(coreLib);
            ExecCmd("llc", string.Format("-filetype=obj -mtriple={1} {0}.ll", coreLibNameNoExt, target));
            Console.WriteLine("Done.");
            
            // compile generated dll
            Console.Write("Compiling LLVM IR file...");
            var targetFileNameNoExt = Path.GetFileNameWithoutExtension(sources.First());
            ExecCmd("llc", string.Format("-filetype=obj -mtriple={1} {0}.ll", targetFileNameNoExt, target));
            Console.WriteLine("Done.");

            // detect OBJ extention
            var objExt = ".obj";
            var targetObjFile = Directory.GetFiles(Environment.CurrentDirectory, targetFileNameNoExt + ".o*").FirstOrDefault();
            if (targetObjFile != null)
            {
                objExt = Path.GetExtension(targetObjFile);
            }

            Console.Write("Compiling target exe. file...");
            // finally generate EXE output
            ExecCmd("g++", string.Format("-o {0}.exe {0}{2} {1}{2} -lstdc++ -lgc-lib -march=i686 -L .", targetFileNameNoExt, coreLibNameNoExt, objExt));
            Console.WriteLine("Done.");
        }
Example #51
0
        /// <summary>
        /// </summary>
        /// <param name="virtualTable">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="type">
        /// </param>
        /// <param name="interfaceIndex">
        /// </param>
        /// <param name="baseTypeFieldsOffset">
        /// </param>
        public static void WriteTableOfMethods(
            this List<LlvmWriter.Pair<IMethod, IMethod>> virtualTable, LlvmWriter llvmWriter, IType type, int interfaceIndex, int baseTypeFieldsOffset)
        {
            var writer = llvmWriter.Output;

            writer.WriteLine(" = linkonce_odr unnamed_addr constant [{0} x i8*] [", virtualTable.GetVirtualTableSize());

            writer.Indent++;
            writer.WriteLine(
                "i8* {0},",
                interfaceIndex == 0
                    ? "null"
                    : string.Format("inttoptr (i32 -{0} to i8*)", baseTypeFieldsOffset + ((interfaceIndex - 1) * LlvmWriter.PointerSize)));

            // RTTI info class
            writer.Write("i8* bitcast (");
            type.WriteRttiClassInfoDeclaration(writer);
            writer.Write("* @\"{0}\" to i8*)", type.GetRttiInfoName());

            // define virtual table
            foreach (var virtualMethod in virtualTable)
            {
                var method = virtualMethod.Value;

                // write method pointer
                writer.WriteLine(",");

                writer.Write("i8* bitcast (");
                if (virtualMethod.Value == null || virtualMethod.Value.IsAbstract)
                {
                    writer.Write("void ()* @__cxa_pure_virtual");
                }
                else
                {
                    // write pointer to method
                    llvmWriter.WriteMethodReturnType(writer, method);
                    llvmWriter.WriteMethodParamsDef(writer, method, true, method.DeclaringType, method.ReturnType, true);
                    writer.Write("* ");
                    llvmWriter.WriteMethodDefinitionName(writer, method);

                    llvmWriter.CheckIfExternalDeclarationIsRequired(method);
                }

                writer.Write(" to i8*)");
            }

            writer.WriteLine(string.Empty);
            writer.Indent--;
            writer.WriteLine("]");
        }
Example #52
0
 /// <summary>
 /// </summary>
 /// <param name="thisType">
 /// </param>
 /// <param name="methodInfo">
 /// </param>
 /// <param name="llvmWriter">
 /// </param>
 /// <returns>
 /// </returns>
 public static bool HasVirtualMethod(this IType thisType, IMethod methodInfo, LlvmWriter llvmWriter)
 {
     return thisType.GetVirtualTable(llvmWriter).Select(v => v.Value).Any(virtualMethod => virtualMethod.IsMatchingOverride(methodInfo));
 }
Example #53
0
        /// <summary>
        /// </summary>
        /// <param name="type">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        public static void WriteRttiClassInfoDefinition(this IType type, LlvmWriter llvmWriter)
        {
            var interfaces = type.GetInterfaces();
            var anyInterface = interfaces.Any();
            var onlyInterface = interfaces.Count() == 1;
            if (type.BaseType == null && !anyInterface)
            {
                RttiClassWithNoBaseAndNoInterfaces.WriteRttiClassInfoDefinition(type, llvmWriter);
                return;
            }

            if (type.BaseType != null)
            {
                llvmWriter.AddRequiredRttiDeclaration(type.BaseType);
            }

            if (anyInterface)
            {
                foreach (var @interface in type.GetInterfaces())
                {
                    llvmWriter.AddRequiredRttiDeclaration(@interface);
                }

                if (type.BaseType == null && onlyInterface)
                {
                    RttiClassWithNoBaseAndSingleInterface.WriteRttiClassInfoDefinition(type, llvmWriter);
                    return;
                }

                RttiClassWithBaseAndInterfaces.WriteRttiClassInfoDefinition(type, llvmWriter);
                return;
            }

            RttiClassWithBaseAndNoInterfaces.WriteRttiClassInfoDefinition(type, llvmWriter);
        }
Example #54
0
        /// <summary>
        /// </summary>
        /// <param name="thisType">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        /// <returns>
        /// </returns>
        public static List<LlvmWriter.Pair<IMethod, IMethod>> GetVirtualTable(this IType thisType, LlvmWriter llvmWriter)
        {
            List<LlvmWriter.Pair<IMethod, IMethod>> virtualTable;

            if (virtualTableByType.TryGetValue(thisType.FullName, out virtualTable))
            {
                return virtualTable;
            }

            virtualTable = new List<LlvmWriter.Pair<IMethod, IMethod>>();
            virtualTable.BuildVirtualTable(thisType, llvmWriter);

            virtualTableByType[thisType.FullName] = virtualTable;

            return virtualTable;
        }
Example #55
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="exceptionHandlingClause">
        /// </param>
        private static void WriteRethrowInvoke(LlvmWriter llvmWriter, CatchOfFinallyClause exceptionHandlingClause)
        {
            var writer = llvmWriter.Output;

            writer.WriteLine("invoke void @__cxa_rethrow()");
            if (exceptionHandlingClause != null)
            {
                writer.Indent++;
                writer.WriteLine(
                    "to label %.unreachable unwind label %.catch_with_cleanup_{0}_{1}",
                    exceptionHandlingClause.Offset,
                    exceptionHandlingClause.Offset + exceptionHandlingClause.Length);
                writer.Indent--;
                exceptionHandlingClause.RethrowCatchWithCleanUpRequired = true;
            }
            else
            {
                writer.Indent++;
                writer.WriteLine("to label %.unreachable unwind label %.unwind_exception");
                writer.Indent--;
                llvmWriter.needToWriteUnwindException = true;
            }

            llvmWriter.needToWriteUnreachable = true;
        }
 public static int GetDataFieldIndex(IType arrayType, LlvmWriter llvmWriter)
 {
     return llvmWriter.GetFieldIndex(arrayType, "data");
 }
Example #57
0
        /// <summary>
        /// </summary>
        /// <returns>
        /// </returns>
        public static string GetStringPrefixConstData(LlvmWriter llvmWriter)
        {
            if (_stringPrefixConstData != null)
            {
                return _stringPrefixConstData;
            }

            ITypeResolver typeResolver = llvmWriter;

            var stringSystemType = typeResolver.System.System_String;

            llvmWriter.AddRequiredVirtualTablesDeclaration(stringSystemType);
            llvmWriter.AddRequiredRttiDeclaration(stringSystemType);

            var sb = new StringBuilder();

            sb.Append("i8* bitcast (i8** ");
            sb.Append(stringSystemType.GetVirtualTableReference(typeResolver));
            sb.AppendLine(" to i8*)");

            foreach (var @interface in stringSystemType.SelectAllTopAndAllNotFirstChildrenInterfaces().Distinct())
            {
                if (sb.Length > 0)
                {
                    sb.Append(", ");
                }

                sb.Append("i8* bitcast (i8** ");
                sb.Append(stringSystemType.GetVirtualTableReference(@interface, typeResolver));
                sb.AppendLine(" to i8*)");                
            }

            _stringPrefixConstData = sb.ToString();
            return _stringPrefixConstData;
        }
Example #58
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <returns>
        /// </returns>
        private static IType WriteThrowCall(LlvmWriter llvmWriter, OpCodePart opCode)
        {
            var writer = llvmWriter.Output;

            var errorAllocationResultNumber = llvmWriter.WriteAllocateException(opCode);

            var exceptionPointerType = opCode.OpCodeOperands[0].Result.Type;
            writer.Write("call void @__cxa_throw(i8* {0}, i8* bitcast (", errorAllocationResultNumber);
            exceptionPointerType.WriteRttiPointerClassInfoDeclaration(writer);
            writer.Write("* @\"{0}\" to i8*), i8* null)", exceptionPointerType.GetRttiPointerInfoName());

            llvmWriter.WriteDbgLine(opCode);
            writer.WriteLine(string.Empty);

            writer.WriteLine("unreachable");

            return exceptionPointerType;
        }
Example #59
0
 /// <summary>
 /// </summary>
 /// <param name="writer">
 /// </param>
 /// <param name="objectResult">
 /// </param>
 /// <param name="methodResult">
 /// </param>
 /// <param name="invokeMethod">
 /// </param>
 /// <param name="isStatic">
 /// </param>
 public SynthesizedInvokeMethod(
     LlvmWriter writer, FullyDefinedReference objectResult, FullyDefinedReference methodResult, IMethod invokeMethod, bool isStatic)
 {
     this.writer = writer;
     this.objectResult = objectResult;
     this.MethodResult = methodResult;
     this.invokeMethod = invokeMethod;
     this.isStatic = isStatic;
 }
Example #60
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="exceptionHandlingClause">
        /// </param>
        /// <returns>
        /// </returns>
        private static IType WriteThrowInvoke(
            LlvmWriter llvmWriter,
            OpCodePart opCode,
            CatchOfFinallyClause exceptionHandlingClause)
        {
            var writer = llvmWriter.Output;

            var errorAllocationResultNumber = llvmWriter.WriteAllocateException(opCode);

            var exceptionPointerType = opCode.OpCodeOperands[0].Result.Type;
            writer.Write("invoke void @__cxa_throw(i8* {0}, i8* bitcast (", errorAllocationResultNumber);
            exceptionPointerType.WriteRttiPointerClassInfoDeclaration(writer);
            writer.WriteLine("* @\"{0}\" to i8*), i8* null)", exceptionPointerType.GetRttiPointerInfoName());
            writer.Indent++;
            if (exceptionHandlingClause != null)
            {
                writer.Write("to label %.unreachable unwind label %.catch{0}", exceptionHandlingClause.Offset);
            }
            else
            {
                writer.Write("to label %.unreachable unwind label %.unwind_exception");
                llvmWriter.needToWriteUnwindException = true;
            }

            llvmWriter.WriteDbgLine(opCode);
            writer.WriteLine(string.Empty);

            writer.Indent--;
            llvmWriter.needToWriteUnreachable = true;

            return exceptionPointerType;
        }