public void Execute(LlvmWriter writer, OpCodePart opCode)
 {
     if (this.action != null)
     {
         this.action.Invoke(writer, opCode);
     }
 }
Esempio n. 2
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++;
            }
        }
Esempio n. 3
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <returns>
        /// </returns>
        public static IncrementalResult WriteAllocateException(this LlvmWriter llvmWriter, OpCodePart opCode)
        {
            var writer = llvmWriter.Output;

            writer.WriteLine("; Allocate exception");
            var errorAllocationResultNumber = llvmWriter.WriteSetResultNumber(opCode, llvmWriter.ResolveType("System.Byte").ToPointerType());
            writer.Write("call i8* @__cxa_allocate_exception(i32 {0})", LlvmWriter.PointerSize);
            writer.WriteLine(string.Empty);

            var newExceptionResult = opCode.OpCodeOperands[0].Result;

            opCode.OpCodeOperands[0].Result = opCode.Result;

            llvmWriter.WriteBitcast(opCode, opCode.Result, newExceptionResult.Type);
            writer.WriteLine("*");

            opCode.OpCodeOperands[0].Result = newExceptionResult;

            llvmWriter.UnaryOper(writer, opCode, "store");
            writer.Write(", ");
            opCode.OpCodeOperands[0].Result.Type.WriteTypePrefix(writer);
            writer.Write("* ");
            llvmWriter.WriteResult(opCode.Result);
            writer.WriteLine(string.Empty);

            return errorAllocationResultNumber;
        }
Esempio n. 4
0
        public static void WriteCreateInstanceFunction(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();
            }
        }
Esempio n. 5
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="elementType">
        /// </param>
        /// <param name="length">
        /// </param>
        public static FullyDefinedReference WriteStringAllocationSize(
            this LlvmWriter llvmWriter,
            OpCodePart opCode,
            IType stringType,
            IType charType)
        {
            Debug.Assert(stringType.IsString, "This is for string only");

            var writer = llvmWriter.Output;

            writer.WriteLine("; Calculate String allocation size");

            object[] code;
            IList<object> tokenResolutions;
            IList<IType> locals;
            IList<IParameter> parameters;
            GetCalculationPartOfStringAllocationSizeMethodBody(
                llvmWriter,
                stringType,
                charType,
                out code,
                out tokenResolutions,
                out locals,
                out parameters);

            var constructedMethod = MethodBodyBank.GetMethodDecorator(null, code, tokenResolutions, locals, parameters);

            // actual write
            var opCodes = llvmWriter.WriteCustomMethodPart(constructedMethod, null);
            return opCodes.Last().Result;
        }
Esempio n. 6
0
        public void ProcessAlternativeValues(OpCodePart opCodePart)
        {
            // read all alternative values from other branches
            if (opCodePart.JumpDestination == null)
            {
                return;
            }

            var previousFlow = opCodePart.Previous != null ? opCodePart.Previous.OpCode.FlowControl : FlowControl.Break;
            var noMainEntry = previousFlow == FlowControl.Branch || previousFlow == FlowControl.Return || previousFlow == FlowControl.Throw || previousFlow == FlowControl.Break;
            var entires = opCodePart.JumpDestination.Where(opCode => opCode.IsJumpForward());
            var entriesList = entires as IList<OpCodePart> ?? entires.ToList();
            //if (entriesList.Count() <= (noMainEntry ? 1 : 0))
            if (!entriesList.Any())
            {
                return;
            }

            var values = entriesList.Where(opCode => opCode.BranchStackValue != null).Select(opCode => opCode.BranchStackValue);
            if (!values.Any())
            {
                return;
            }

            var alternativeValues = GetPhiValues(values, !noMainEntry ? this.main.Peek() : null);
            if (alternativeValues == null)
            {
                return;
            }

            var firstValue = alternativeValues.Values.OrderByDescending(v => v.AddressStart).First();
            if (alternativeValues.Values.Count() == 1)
            {
                // it just one value, we can push it back to stack
                if (!this.main.Any() || this.main.All(op => op.AddressStart != firstValue.AddressStart))
                {
                    this.main.Push(firstValue);
                }

                return;
            }

            opCodePart.AlternativeValues = alternativeValues;

            if (noMainEntry)
            {
                return;
            }

            while (this.main.Any() && alternativeValues.Values.Contains(this.main.Peek()))
            {
                this.main.Pop();
            }

            this.main.Push(firstValue);
        }
Esempio n. 7
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();
     }
 }
Esempio n. 8
0
        public void SaveBranchStackValue(OpCodePart opCode, BaseWriter baseWriter)
        {
            switch (opCode.ToCode())
            {
                case Code.Br:
                case Code.Br_S:
                case Code.Beq:
                case Code.Beq_S:
                case Code.Blt:
                case Code.Blt_S:
                case Code.Bgt:
                case Code.Bgt_S:
                case Code.Ble:
                case Code.Ble_S:
                case Code.Bge:
                case Code.Bge_S:
                case Code.Blt_Un:
                case Code.Blt_Un_S:
                case Code.Bgt_Un:
                case Code.Bgt_Un_S:
                case Code.Ble_Un:
                case Code.Ble_Un_S:
                case Code.Bge_Un:
                case Code.Bge_Un_S:
                case Code.Bne_Un:
                case Code.Bne_Un_S:
                case Code.Brtrue:
                case Code.Brtrue_S:
                case Code.Brfalse:
                case Code.Brfalse_S:
                    if (opCode.IsJumpForward() && this.main.Any())
                    {
                        opCode.BranchStackValue = this.main.Peek();
                    }

                    break;
            }
        }
Esempio n. 9
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;
            }
        }
Esempio n. 10
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;
        }
Esempio n. 11
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;
        }
Esempio n. 12
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="exceptionHandlingClause">
        /// </param>
        public static void WriteThrow(this LlvmWriter llvmWriter, OpCodePart opCode, CatchOfFinallyClause exceptionHandlingClause)
        {
            var writer = llvmWriter.Output;

            writer.WriteLine("; Throw");

            var exceptionPointerType = exceptionHandlingClause != null
                                           ? WriteThrowInvoke(llvmWriter, opCode, exceptionHandlingClause)
                                           : WriteThrowCall(llvmWriter, opCode);

            llvmWriter.typeRttiPointerDeclRequired.Add(exceptionPointerType);
            llvmWriter.CheckIfExternalDeclarationIsRequired(exceptionPointerType);
        }
Esempio n. 13
0
        /// <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);
        }
Esempio n. 14
0
 /// <summary>
 /// </summary>
 /// <param name="llvmWriter">
 /// </param>
 /// <param name="opCode">
 /// </param>
 /// <param name="typeToLoad">
 /// </param>
 /// <param name="source">
 /// </param>
 /// <param name="appendReference">
 /// </param>
 /// <param name="structAsRef">
 /// </param>
 public static void WriteLlvmLoad(
     this LlvmWriter llvmWriter, OpCodePart opCode, IType typeToLoad, IncrementalResult source, bool appendReference = true, bool structAsRef = false)
 {
     llvmWriter.WriteLlvmLoad(opCode, typeToLoad, new FullyDefinedReference(source.ToString(), source.Type), appendReference, structAsRef);
 }
Esempio n. 15
0
 /// <summary>
 /// </summary>
 /// <param name="opCode">
 /// </param>
 public UsedByInfo(OpCodePart opCode)
 {
     this.OpCode = opCode;
 }
Esempio n. 16
0
 /// <summary>
 /// </summary>
 /// <param name="opCodes">
 /// </param>
 public OpCodeBlock(OpCodePart[] opCodes)
     : base(OpCodesEmit.Nop, 0, 0)
 {
     this.OpCodes = opCodes;
 }
Esempio n. 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() : llvmWriter.ResolveType("System.Array");
            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 || toType.IsArray || toType.IsPointer || toType.IsByRef || bareType.IsDerivedFrom(toType) || (fromResult is ConstValue))
            {
                llvmWriter.WriteSetResultNumber(opCode, toType, true);
                writer.Write("bitcast ");
                fromResult.Type.WriteTypePrefix(writer, true);
                writer.Write(' ');
                llvmWriter.WriteResult(fromResult);
                writer.Write(" to ");
                toType.WriteTypePrefix(writer, true);
            }
            else
            {
                Debug.Assert(fromResult.Type.IntTypeBitSize() == 0);
                llvmWriter.WriteDynamicCast(writer, opCode, fromResult, toType, true, throwExceptionIfNull);
            }

            writer.WriteLine(string.Empty);

            return true;
        }
Esempio n. 18
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="typeToSave">
        /// </param>
        /// <param name="operandIndex">
        /// </param>
        /// <param name="destination">
        /// </param>
        public static void WriteLlvmSave(this LlvmWriter llvmWriter, OpCodePart opCode, IType typeToSave, int operandIndex, FullyDefinedReference destination)
        {
            var writer = llvmWriter.Output;

            llvmWriter.ProcessOperator(
                writer,
                opCode,
                "store",
                typeToSave,
                options: LlvmWriter.OperandOptions.CastPointersToBytePointer | LlvmWriter.OperandOptions.AdjustIntTypes,
                operand1: operandIndex,
                operand2: -1);
            llvmWriter.WriteOperandResult(writer, opCode, operandIndex);
            writer.Write(", ");
            typeToSave.WriteTypePrefix(writer);
            writer.Write("* ");
            writer.Write(destination);
        }
Esempio n. 19
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);
        }
Esempio n. 20
0
        public static void WriteLlvmLoadPrimitiveFromStructure(this LlvmWriter llvmWriter, OpCodePart opCode, FullyDefinedReference source)
        {
            var writer = llvmWriter.Output;

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

            writer.WriteLine(string.Empty);

            llvmWriter.WriteLlvmLoad(opCode, opCode.Result.Type, opCode.Result);

            writer.WriteLine(string.Empty);
        }
Esempio n. 21
0
        public static void WriteLlvmSavePrimitiveIntoStructure(this LlvmWriter llvmWriter, OpCodePart opCode, FullyDefinedReference source, FullyDefinedReference destination)
        {
            var writer = llvmWriter.Output;

            writer.WriteLine("; Copy primitive data into a structure");

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

            writer.WriteLine(string.Empty);

            llvmWriter.SaveToField(opCode, opCode.Result.Type, 0);

            writer.WriteLine(string.Empty);
            writer.WriteLine("; End of Copy primitive data");
        }
Esempio n. 22
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="typeToLoad">
        /// </param>
        /// <param name="source">
        /// </param>
        /// <param name="appendReference">
        /// </param>
        /// <param name="structAsRef">
        /// </param>
        /// <param name="indirect">
        /// </param>
        public static void WriteLlvmLoad(
            this LlvmWriter llvmWriter,
            OpCodePart opCode,
            IType typeToLoad,
            FullyDefinedReference source,
            bool appendReference = true,
            bool structAsRef = false,
            bool indirect = false)
        {
            // TODO: improve it, by checking if Source is Reference or Pointer
            var writer = llvmWriter.Output;

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

            Debug.Assert(structAsRef || !isStruct || typeToLoad.IsByRef || isStruct && !typeToLoad.IsByRef && opCode.HasResult);

            if (!isStruct || typeToLoad.IsByRef || structAsRef || !opCode.HasResult || (indirect && !isStruct))
            {
                ////Debug.Assert(source.Type.IsPointer);
                var dereferencedType = source.Type.IsPointer ? source.Type.GetElementType() : null;

                var effectiveSource = source;

                // check if you need bitcast pointer type
                if (!typeToLoad.IsPointer && dereferencedType != null && typeToLoad.TypeNotEquals(dereferencedType))
                {
                    // check if you need cast here
                    llvmWriter.WriteBitcast(opCode, source, typeToLoad);
                    writer.WriteLine(string.Empty);
                    effectiveSource = opCode.Result;
                }

                if (indirect && !source.Type.IsPointer && !source.Type.IsByRef && source.Type.IntTypeBitSize() > 0)
                {
                    // check if you need cast here
                    llvmWriter.WriteIntToPtr(opCode, source, typeToLoad);
                    writer.WriteLine(string.Empty);
                    effectiveSource = opCode.Result;
                }

                llvmWriter.WriteSetResultNumber(opCode, typeToLoad);

                // last part
                writer.Write("load ");
                typeToLoad.WriteTypePrefix(writer, structAsRef);
                if (appendReference)
                {
                    // add reference to type
                    writer.Write('*');
                }

                writer.Write(' ');
                writer.Write(effectiveSource.ToString());

                // TODO: optional do we need to calculate it propertly?
                writer.Write(", align " + LlvmWriter.PointerSize);
            }
            else
            {
                llvmWriter.WriteCopyStruct(writer, opCode, typeToLoad, source, opCode.Result);
            }
        }
Esempio n. 23
0
 /// <summary>
 /// </summary>
 /// <param name="opCode">
 /// </param>
 public UsedByInfo(OpCodePart opCode)
 {
     this.OpCode = opCode;
 }
Esempio n. 24
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        public static void WriteCatchProlog(this LlvmWriter llvmWriter, OpCodePart opCode)
        {
            var writer = llvmWriter.Output;

            writer.WriteLine("; Cacth Clauses - Prolog");

            var handlerOffset = opCode.ExceptionHandlers.First().Offset;
            writer.Indent--;
            writer.WriteLine(".catch{0}:", handlerOffset);
            writer.Indent++;

            var catchTypes = opCode.ExceptionHandlers.Where(eh => eh.Flags == ExceptionHandlingClauseOptions.Clause).Select(eh => eh.Catch).ToArray();
            var finallyOrFault =
                opCode.ExceptionHandlers.FirstOrDefault(
                    eh => eh.Flags.HasFlag(ExceptionHandlingClauseOptions.Finally) || eh.Flags.HasFlag(ExceptionHandlingClauseOptions.Fault));
            llvmWriter.WriteLandingPad(opCode, finallyOrFault != null ? LandingPadOptions.Cleanup : LandingPadOptions.None, finallyOrFault, catchTypes);

            writer.WriteLine(string.Empty);
        }
Esempio n. 25
0
 /// <summary>
 /// </summary>
 /// <param name="opCode">
 /// </param>
 /// <param name="operandPosition">
 /// </param>
 public UsedByInfo(OpCodePart opCode, int operandPosition)
 {
     this.OpCode = opCode;
     this.OperandPosition = operandPosition;
 }
Esempio n. 26
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="options">
        /// </param>
        /// <param name="finallyOrFaultClause">
        /// </param>
        /// <param name="catch">
        /// </param>
        /// <param name="filter">
        /// </param>
        /// <param name="exceptionAllocationResultNumber">
        /// </param>
        public static void WriteLandingPad(
            this LlvmWriter llvmWriter,
            OpCodePart opCode,
            LandingPadOptions options,
            CatchOfFinallyClause finallyOrFaultClause,
            IType[] @catch = null,
            int[] filter = null,
            int? exceptionAllocationResultNumber = null)
        {
            var writer = llvmWriter.Output;

            llvmWriter.WriteLandingPadVariables();

            var landingPadResult = llvmWriter.WriteSetResultNumber(opCode, llvmWriter.ResolveType("System.Byte").ToPointerType());

            writer.WriteLine("landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)");
            if (options.HasFlag(LandingPadOptions.Cleanup))
            {
                writer.Indent++;
                writer.WriteLine("cleanup");
                writer.Indent--;
            }

            if (options.HasFlag(LandingPadOptions.EmptyFilter))
            {
                writer.Indent++;
                writer.WriteLine("filter [0 x i8*] zeroinitializer");
                writer.Indent--;
            }

            if (@catch != null && @catch.Any())
            {
                foreach (var catchType in @catch)
                {
                    writer.Indent++;

                    if (catchType != null)
                    {
                        writer.Write("catch i8* bitcast (");
                        catchType.WriteRttiPointerClassInfoDeclaration(writer);
                        writer.WriteLine("* @\"{0}\" to i8*)", catchType.GetRttiPointerInfoName());

                        llvmWriter.typeRttiPointerDeclRequired.Add(catchType);
                        llvmWriter.CheckIfExternalDeclarationIsRequired(catchType);
                    }
                    else
                    {
                        writer.Write("catch i8* null");
                    }

                    writer.Indent--;
                }
            }
            else if (finallyOrFaultClause != null)
            {
                // default catch with rethrowing it
                writer.Indent++;
                writer.WriteLine("catch i8* null");
                writer.Indent--;

                finallyOrFaultClause.EmptyFinallyRethrowRequired = true;
            }

            var getErrorObjectResultNumber = llvmWriter.WriteSetResultNumber(opCode, llvmWriter.ResolveType("System.Byte").ToPointerType());
            writer.WriteLine("extractvalue {1} {0}, 0", landingPadResult, "{ i8*, i32 }");
            writer.WriteLine("store i8* {0}, i8** %.error_object", getErrorObjectResultNumber);
            var getErrorTypeIdResultNumber = llvmWriter.WriteSetResultNumber(opCode, llvmWriter.ResolveType("System.Int32"));
            writer.WriteLine("extractvalue {1} {0}, 1", landingPadResult, "{ i8*, i32 }");
            writer.Write("store i32 {0}, i32* %.error_typeid", getErrorTypeIdResultNumber);

            if (exceptionAllocationResultNumber.HasValue)
            {
                writer.WriteLine(string.Empty);
                writer.Write("call void @__cxa_free_exception(i8* {0})", exceptionAllocationResultNumber.Value);
            }

            opCode.Result = landingPadResult;
        }
Esempio n. 27
0
        private static bool JumpOrLabelPoint(OpCodePart current, out bool startOrEnd)
        {
            if ((current.OpCode.FlowControl == FlowControl.Cond_Branch || current.OpCode.FlowControl == FlowControl.Branch)
                && !current.Any(Code.Leave, Code.Leave_S))
            {
                startOrEnd = false;
                return true;
            }

            if (current.JumpDestination != null && current.JumpDestination.Any())
            {
                startOrEnd = true;
                return true;
            }

            startOrEnd = false;
            return false;
        }
Esempio n. 28
0
 /// <summary>
 /// </summary>
 /// <param name="opCode">
 /// </param>
 /// <param name="operandPosition">
 /// </param>
 public UsedByInfo(OpCodePart opCode, int operandPosition)
 {
     this.OpCode          = opCode;
     this.OperandPosition = operandPosition;
 }
Esempio n. 29
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;
        }
Esempio n. 30
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="fromType">
        /// </param>
        /// <param name="custromName">
        /// </param>
        /// <param name="toType">
        /// </param>
        /// <param name="appendReference">
        /// </param>
        /// <param name="doNotConvert">
        /// </param>
        /// <exception cref="NotImplementedException">
        /// </exception>
        public static void WriteCast(
            this LlvmWriter llvmWriter,
            OpCodePart opCode,
            IType fromType,
            string custromName,
            IType toType,
            bool appendReference = false,
            bool doNotConvert = false)
        {
            // TODO: remove this one. use anather one
            var writer = llvmWriter.Output;

            if (!fromType.IsInterface && toType.IsInterface)
            {
                throw new NotImplementedException();

                ////opCode.Result = res;
                ////this.WriteInterfaceAccess(writer, opCode, fromType, toType);
            }
            else
            {
                llvmWriter.WriteSetResultNumber(opCode, toType);
                writer.Write("bitcast ");
                fromType.WriteTypePrefix(writer, true);
                writer.Write(' ');
                writer.Write(custromName);
                writer.Write(" to ");
                toType.WriteTypePrefix(writer, true);
                if (appendReference)
                {
                    // result should be array
                    writer.Write('*');
                }
            }

            writer.WriteLine(string.Empty);
        }
Esempio n. 31
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="method">
        /// </param>
        private static void WriteDelegateInvoke(this LlvmWriter llvmWriter, IMethod method)
        {
            var writer = llvmWriter.Output;

            writer.WriteLine(" {");
            writer.Indent++;

            var opCode = OpCodePart.CreateNop;

            // create this variable
            llvmWriter.WriteArgumentCopyDeclaration(null, 0, method.DeclaringType, true);
            for (var i = 1; i <= llvmWriter.GetArgCount() + 1; i++)
            {
                llvmWriter.WriteArgumentCopyDeclaration(llvmWriter.GetArgName(i), i, llvmWriter.GetArgType(i));
            }

            // load 'this' variable
            llvmWriter.WriteLlvmLoad(opCode, method.DeclaringType, new FullyDefinedReference(llvmWriter.GetThisName(), method.DeclaringType));
            writer.WriteLine(string.Empty);

            var thisResult = opCode.Result;

            // write access to a field 1
            llvmWriter.WriteFieldAccess(writer, opCode, method.DeclaringType, method.DeclaringType.BaseType.BaseType, 0, thisResult);
            writer.WriteLine(string.Empty);

            var objectMemberAccessResultNumber = opCode.Result;

            // load value 1
            opCode.Result = null;
            llvmWriter.WriteLlvmLoad(opCode, objectMemberAccessResultNumber.Type, objectMemberAccessResultNumber);
            writer.WriteLine(string.Empty);

            var objectResultNumber = opCode.Result;

            // write access to a field 2
            llvmWriter.WriteFieldAccess(writer, opCode, method.DeclaringType, method.DeclaringType.BaseType.BaseType, 1, thisResult);
            writer.WriteLine(string.Empty);

            // additional step to extract value from IntPtr structure
            llvmWriter.WriteFieldAccess(writer, opCode, opCode.Result.Type, opCode.Result.Type, 0, opCode.Result);
            writer.WriteLine(string.Empty);

            // load value 2
            var methodMemberAccessResultNumber = opCode.Result;

            // load value 1
            opCode.Result = null;
            llvmWriter.WriteLlvmLoad(opCode, methodMemberAccessResultNumber.Type, methodMemberAccessResultNumber);
            writer.WriteLine(string.Empty);

            var methodResultNumber = opCode.Result;

            // switch code if method is static
            var compareResult = llvmWriter.WriteSetResultNumber(opCode, llvmWriter.ResolveType("System.Boolean"));
            writer.Write("icmp ne ");
            objectResultNumber.Type.WriteTypePrefix(writer);
            writer.Write(" ");
            writer.Write(objectResultNumber);
            writer.WriteLine(", null");
            llvmWriter.WriteCondBranch(writer, compareResult, "normal", "static");

            // normal brunch
            var callResult = llvmWriter.WriteCallInvokeMethod(objectResultNumber, methodResultNumber, method, false);

            var returnNormal = new OpCodePart(OpCodesEmit.Ret, 0, 0);
            returnNormal.OpCodeOperands = new[] { OpCodePart.CreateNop };
            returnNormal.OpCodeOperands[0].Result = callResult;
            llvmWriter.WriteReturn(writer, returnNormal, method.ReturnType);
            writer.WriteLine(string.Empty);

            // static brunch
            llvmWriter.WriteLabel(writer, "static");

            var callStaticResult = llvmWriter.WriteCallInvokeMethod(objectResultNumber, methodResultNumber, method, true);

            var returnStatic = new OpCodePart(OpCodesEmit.Ret, 0, 0);
            returnStatic.OpCodeOperands = new[] { OpCodePart.CreateNop };
            returnStatic.OpCodeOperands[0].Result = callStaticResult;
            llvmWriter.WriteReturn(writer, returnStatic, method.ReturnType);
            writer.WriteLine(string.Empty);

            writer.Indent--;
            writer.WriteLine("}");
        }
Esempio n. 32
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="exceptionHandlingClause">
        /// </param>
        /// <param name="upperLevelExceptionHandlingClause">
        /// </param>
        public static void WriteCatchEnd(
            this LlvmWriter llvmWriter, OpCodePart opCode, CatchOfFinallyClause exceptionHandlingClause, CatchOfFinallyClause upperLevelExceptionHandlingClause)
        {
            var writer = llvmWriter.Output;

            var isFinally = exceptionHandlingClause.Flags.HasFlag(ExceptionHandlingClauseOptions.Finally);
            if (isFinally)
            {
                writer.WriteLine("; End of Finally Handler Body");
            }
            else
            {
                writer.WriteLine("; End of Catch Handler Body");
            }

            if (isFinally)
            {
                // process Leave jumps
                var index = 0;
                var opCodeNope = OpCodePart.CreateNop;

                var fullyDefinedRef = new FullyDefinedReference(
                    string.Concat("%.finally_jump", exceptionHandlingClause.Offset), llvmWriter.ResolveType("System.Int32"));

                llvmWriter.WriteLlvmLoad(opCodeNope, llvmWriter.ResolveType("System.Int32"), fullyDefinedRef);
                writer.WriteLine(string.Empty);
                writer.WriteLine("switch i32 {1}, label %.finally_exit{0} [", exceptionHandlingClause.Offset, opCodeNope.Result);
                writer.Indent++;
                writer.WriteLine("i32 {0}, label %.finally_exit{1}", index++, exceptionHandlingClause.Offset);
                foreach (var leave in exceptionHandlingClause.FinallyJumps)
                {
                    writer.WriteLine("i32 {0}, label %{1}", index++, leave);
                }

                writer.Indent--;
                writer.WriteLine("]");

                llvmWriter.WriteLabel(writer, string.Concat(".finally_exit", exceptionHandlingClause.Offset));

                if (exceptionHandlingClause.EmptyFinallyRethrowRequired)
                {
                    // rethrow exception in empty finally block
                    var opCodeNop = OpCodePart.CreateNop;
                    llvmWriter.WriteRethrow(
                        opCodeNop,
                        llvmWriter.catchScopes.Count > 0 ? llvmWriter.catchScopes.Peek() : null,
                        llvmWriter.tryScopes.Count > 0 ? llvmWriter.tryScopes.Peek().Catches.First() : null);
                }
            }

            var startOfHandlerAddress = exceptionHandlingClause.Offset;
            var endOfHandlerAddress = exceptionHandlingClause.Offset + exceptionHandlingClause.Length;

            if (exceptionHandlingClause.RethrowCatchWithCleanUpRequired)
            {
                llvmWriter.WriteLabel(writer, string.Format(".catch_with_cleanup_{0}_{1}", startOfHandlerAddress, endOfHandlerAddress));

                var opCodeNop = OpCodePart.CreateNop;
                llvmWriter.WriteLandingPad(
                    opCodeNop,
                    LandingPadOptions.Cleanup,
                    null,
                    new[] { upperLevelExceptionHandlingClause != null ? upperLevelExceptionHandlingClause.Catch : llvmWriter.ResolveType("System.Exception") });
                writer.WriteLine(string.Empty);
            }
            else
            {
                writer.WriteLine("store i32 0, i32* %.error_typeid");
            }

            writer.WriteLine("call void @__cxa_end_catch()");

            if (!exceptionHandlingClause.RethrowCatchWithCleanUpRequired || upperLevelExceptionHandlingClause == null)
            {
                var isLeave = opCode.Any(Code.Leave, Code.Leave_S);
                var nextOp = opCode.Next;
                if (!isLeave &&
                    (nextOp == null || nextOp.JumpDestination == null || !nextOp.JumpDestination.Any() || nextOp.GroupAddressStart != endOfHandlerAddress))
                {
                    if (nextOp != null && nextOp.CatchOrFinallyBegin == null || opCode.Any(Code.Leave, Code.Leave_S)
                        || llvmWriter.OpsByAddressStart.Values.Any(op => op.ToCode() == Code.Ret))
                    {
                        writer.WriteLine("br label %.exit{0}", endOfHandlerAddress);
                        llvmWriter.WriteLabel(writer, string.Concat(".exit", endOfHandlerAddress));
                        writer.WriteLine(string.Empty);
                    }
                    else
                    {
                        writer.WriteLine("unreachable");
                    }
                }
                else
                {
                    if (isLeave)
                    {
                        writer.WriteLine("br label %.a{0}", opCode.JumpAddress());
                    }
                    else
                    {
                        writer.WriteLine("br label %.a{0}", nextOp.GroupAddressStart);
                    }
                }
            }
            else
            {
                if (!upperLevelExceptionHandlingClause.Flags.HasFlag(ExceptionHandlingClauseOptions.Finally))
                {
                    writer.WriteLine("br label %.exception_switch{0}", upperLevelExceptionHandlingClause.Offset);
                }
                else
                {
                    writer.WriteLine("br label %.finally_no_error_entry{0}", upperLevelExceptionHandlingClause.Offset);
                }
            }

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