Exemplo n.º 1
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();
            }
        }
Exemplo n.º 2
0
 public void Execute(LlvmWriter writer, OpCodePart opCode)
 {
     if (this.action != null)
     {
         this.action.Invoke(writer, opCode);
     }
 }
Exemplo n.º 3
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);
            }
            llvmWriter.WriteSetResultNumber(opCode, toType);
            writer.Write("bitcast ");
            fromType.WriteTypePrefix(llvmWriter, true);
            writer.Write(' ');
            writer.Write(custromName);
            writer.Write(" to ");
            toType.WriteTypePrefix(llvmWriter, true);
            if (appendReference)
            {
                // result should be array
                writer.Write('*');
            }

            writer.WriteLine(string.Empty);
        }
Exemplo n.º 4
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++;
            }
        }
Exemplo n.º 5
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);
        }
Exemplo n.º 6
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="intConvert">
        /// </param>
        /// <param name="toType">
        /// </param>
        public static void LlvmIntConvert(
            this LlvmWriter llvmWriter,
            OpCodePart opCode,
            string intConvert,
            IType toType)
        {
            var writer = llvmWriter.Output;

            var incomingResult = opCode.Result;

            llvmWriter.ProcessOperator(
                writer,
                opCode,
                intConvert,
                opCode.Result.Type,
                toType,
                LlvmWriter.OperandOptions.GenerateResult);

            var returnResult = opCode.Result;

            opCode.Result = incomingResult;

            llvmWriter.WriteOperandResult(writer, opCode);

            writer.Write(" to ");
            toType.WriteTypePrefix(llvmWriter);

            opCode.Result = returnResult;
        }
Exemplo n.º 7
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(
                    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");
        }
Exemplo n.º 8
0
        private static void AddPhiValue(PhiNodes phiNodes, OpCodePart value)
        {
            var currentLabel = value.FindBeginOfBasicBlock();

            phiNodes.Values.Add(value);
            if (currentLabel.HasValue)
            {
                phiNodes.Labels.Add(currentLabel.Value);
            }
            else
            {
                // we need to create a label
                var opCode = value.OpCodeOperands != null && value.OpCodeOperands.Length > 0
                    ? value.OpCodeOperands[0]
                    : value;
                if (opCode.JumpDestination == null)
                {
                    opCode.JumpDestination = new List <OpCodePart>();
                }

                opCode.JumpDestination.Add(value);

                phiNodes.Labels.Add(opCode.AddressStart);
            }
        }
Exemplo n.º 9
0
        public static void WriteAllocateMemory(
            this LlvmWriter llvmWriter,
            OpCodePart opCodePart,
            FullyDefinedReference size,
            bool doNotTestNullValue)
        {
            var writer = llvmWriter.Output;

            var mallocResult = llvmWriter.WriteSetResultNumber(
                opCodePart,
                llvmWriter.System.System_Byte.ToPointerType());

            writer.Write("call i8* @{0}(", llvmWriter.GetAllocator());
            size.Type.WriteTypePrefix(llvmWriter);
            writer.Write(" ");
            llvmWriter.WriteResult(size);
            writer.WriteLine(")");

            if (!doNotTestNullValue)
            {
                llvmWriter.WriteTestNullValueAndThrowException(
                    writer,
                    opCodePart,
                    mallocResult,
                    "System.OutOfMemoryException",
                    "new_obj");
            }

            if (!llvmWriter.Gc)
            {
                llvmWriter.WriteMemSet(mallocResult, size);
                writer.WriteLine(string.Empty);
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// </summary>
        /// <param name="requiredType">
        /// </param>
        /// <param name="opCodePart">
        /// </param>
        /// <param name="dynamicCastRequired">
        /// </param>
        /// <returns>
        /// </returns>
        public static bool IsClassCastRequired(
            this IType requiredType,
            OpCodePart opCodePart,
            out bool dynamicCastRequired)
        {
            dynamicCastRequired = false;

            var resultType = opCodePart.Result.Type;
            var other      = resultType.IsPointer || resultType.IsByRef ? resultType.GetElementType() : resultType;
            var constValue = opCodePart.Result as ConstValue;

            if (constValue != null && constValue.IsNull)
            {
                return(false);
            }

            if ((resultType.IsClass || resultType.IsPointer || resultType.IsByRef) && requiredType.IsByRef)
            {
                return(requiredType.GetElementType().TypeNotEquals(other));
            }

            if (requiredType.TypeNotEquals(other))
            {
                if (requiredType.IsAssignableFrom(other) || other.IsArray && requiredType.FullName == "System.Array")
                {
                    return(true);
                }

                dynamicCastRequired = true;
            }

            return(false);
        }
Exemplo n.º 11
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="elementType">
        /// </param>
        /// <param name="length">
        /// </param>
        public static FullyDefinedReference WriteSingleDimArrayAllocationSize(
            this LlvmWriter llvmWriter,
            OpCodePart opCode,
            IType arrayType)
        {
            Debug.Assert(arrayType.IsArray && !arrayType.IsMultiArray, "This is for single dim arrays only");

            var writer = llvmWriter.Output;

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

            object[] code;
            IList<object> tokenResolutions;
            IList<IType> locals;
            IList<IParameter> parameters;
            GetCalculationPartOfSingleDimArrayAllocationSizeMethodBody(
                llvmWriter,
                arrayType,
                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;
        }
Exemplo n.º 12
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);
        }
Exemplo n.º 13
0
        public static int?FindBeginOfBasicBlock(this OpCodePart popCodePart)
        {
            // add alternative stack value to and address
            // 1) find jump address
            var current = popCodePart;

            // Varpop can pop 0
            var jumpOrLabel = false;

            while (current != null && !(JumpOrLabelPoint(current, out jumpOrLabel)))
            {
                current = current.Previous;
            }

            if (current != null && JumpOrLabelPoint(current, out jumpOrLabel))
            {
                var nextAlternateValues = current.Next != null ? current.Next.AlternativeValues : null;
                if (nextAlternateValues != null && nextAlternateValues.Values.Any(v => v.AddressStart == current.AddressStart))
                {
                    return(current.Next.AddressStart);
                }

                var address = jumpOrLabel ? current.AddressStart : current.AddressEnd;
                return(address);
            }

            return(null);
        }
Exemplo n.º 14
0
 public void Execute(LlvmWriter writer, OpCodePart opCode)
 {
     if (this.action != null)
     {
         this.action.Invoke(writer, opCode);
     }
 }
Exemplo n.º 15
0
        /// <summary>
        /// </summary>
        /// <param name="opCode">
        /// </param>
        /// <param name="baseWriter">
        /// </param>
        /// <returns>
        /// </returns>
        public static OpCodePart PreviousOpCodeGroup(this OpCodePart opCode, BaseWriter baseWriter)
        {
            OpCodePart ret = null;

            baseWriter.OpsByGroupAddressEnd.TryGetValue(opCode.GroupAddressStart, out ret);
            return(ret);
        }
Exemplo n.º 16
0
        /// <summary>
        /// </summary>
        /// <param name="methodInfo">
        /// </param>
        /// <param name="opCodeMethodInfo">
        /// </param>
        /// <param name="thisType">
        /// </param>
        /// <param name="methodAddressResultNumber">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        public static void WriteFunctionCallLoadFunctionAddress(
            this IMethod methodInfo,
            OpCodePart opCodeMethodInfo,
            IType thisType,
            ref FullyDefinedReference methodAddressResultNumber,
            LlvmWriter llvmWriter)
        {
            if (!methodInfo.IsUnmanagedMethodReference)
            {
                return;
            }

            var writer = llvmWriter.Output;

            // if this is external method reference we need to load reference first
            // %4 = load i32 ()** @__glewCreateProgram, align 4
            // load pointer
            llvmWriter.WriteSetResultNumber(
                opCodeMethodInfo,
                llvmWriter.System.System_Byte.ToPointerType().ToPointerType());
            writer.Write("load ");
            llvmWriter.WriteMethodPointerType(writer, methodInfo, thisType);
            writer.Write("* ");
            llvmWriter.WriteMethodDefinitionName(writer, methodInfo);
            writer.Write(", align {0}", LlvmWriter.PointerSize);
            writer.WriteLine(string.Empty);
            methodAddressResultNumber = opCodeMethodInfo.Result;
        }
Exemplo n.º 17
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="elementType">
        /// </param>
        /// <param name="length">
        /// </param>
        public static FullyDefinedReference WriteMultiDimArrayAllocationSize(
            this LlvmWriter llvmWriter,
            OpCodePart opCode,
            IType arrayType)
        {
            Debug.Assert(arrayType.IsMultiArray, "This is for multi arrays only");

            var writer = llvmWriter.Output;

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

            object[]           code;
            IList <object>     tokenResolutions;
            IList <IType>      locals;
            IList <IParameter> parameters;

            GetCalculationPartOfMultiDimArrayAllocationSizeMethodBody(
                llvmWriter,
                arrayType,
                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);
        }
Exemplo n.º 18
0
        private static PhiNodes GetPhiValues(IEnumerable <OpCodePart> values, OpCodePart currentValue)
        {
            var phiNodes = new PhiNodes();
            var any      = false;

            foreach (var alternateValue in values.Where(alternateValue => currentValue == null || !alternateValue.Equals(currentValue)))
            {
                AddPhiValue(phiNodes, alternateValue);
                any = true;
            }

            if (any)
            {
                if (currentValue != null)
                {
                    AddPhiValue(phiNodes, currentValue);
                }

                // all values the same - return null
                var firstValueAddressStart = phiNodes.Values.First().AddressStart;
                if (phiNodes.Values.Count() > 1 && phiNodes.Values.All(v => v.AddressStart == firstValueAddressStart))
                {
                    return(null);
                }

                return(phiNodes);
            }

            return(null);
        }
Exemplo n.º 19
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++;
            }
        }
Exemplo n.º 20
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();
            }
        }
Exemplo n.º 21
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);
        }
Exemplo n.º 22
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCodePart">
        /// </param>
        /// <param name="declaringTypeIn">
        /// </param>
        /// <param name="doNotCallInit">
        /// </param>
        /// <param name="doNotTestNullValue">
        /// </param>
        public static void WriteNewMethodBody(
            this LlvmWriter llvmWriter,
            OpCodePart opCodePart,
            IType declaringTypeIn,
            bool doNotCallInit              = false,
            bool doNotTestNullValue         = false,
            bool enableStringFastAllocation = false)
        {
            var declaringClassType = declaringTypeIn.ToClass();

            var writer = llvmWriter.Output;

            writer.WriteLine("; New obj");

            llvmWriter.WriteAllocateMemoryForObject(opCodePart, declaringClassType, doNotTestNullValue, enableStringFastAllocation);

            var castResult = opCodePart.Result;

            if (!doNotCallInit)
            {
                // typeResolver.WriteInitObject(writer, opCode, declaringType);
                declaringClassType.WriteCallInitObjectMethod(llvmWriter, opCodePart);
            }

            // restore result and type
            opCodePart.Result = castResult;

            writer.WriteLine(string.Empty);
            writer.WriteLine("; end of new obj");
        }
Exemplo n.º 23
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.System.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(llvmWriter);
            writer.Write("* ");
            llvmWriter.WriteResult(opCode.Result);
            writer.WriteLine(string.Empty);

            return errorAllocationResultNumber;
        }
Exemplo n.º 24
0
        public static void WriteLlvmLoadPrimitiveFromStructure(
            this LlvmWriter llvmWriter,
            OpCodePart opCode,
            FullyDefinedReference source)
        {
            var writer = llvmWriter.Output;

            // write access to a field
            if (!llvmWriter.WriteFieldAccess(
                    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);
        }
Exemplo n.º 25
0
        /// <summary>
        /// </summary>
        /// <param name="tryClause">
        /// </param>
        /// <param name="opCodeMethodInfo">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        public static void WriteFunctionCallUnwind(
            this TryClause tryClause,
            OpCodePart opCodeMethodInfo,
            LlvmWriter llvmWriter)
        {
            if (tryClause == null)
            {
                llvmWriter.WriteDbgLine(opCodeMethodInfo);
                return;
            }

            var writer = llvmWriter.Output;

            var nextAddress = llvmWriter.GetBlockJumpAddress();

            var label = string.Concat("next", nextAddress);

            writer.WriteLine(string.Empty);
            writer.Indent++;
            writer.Write("to label %.{0} unwind label %.catch{1}", label, tryClause.Catches.First().Offset);
            writer.Indent--;

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

            writer.Indent--;
            writer.WriteLine(".{0}:", label);
            writer.Indent++;

            LlvmHelpersGen.SetCustomLabel(opCodeMethodInfo, label);
        }
Exemplo n.º 26
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);
        }
Exemplo n.º 27
0
        /// <summary>
        /// </summary>
        /// <param name="method">
        /// </param>
        /// <param name="opCodeMethodInfo">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        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, new[] { 0, 1 });
                break;

            case "CompareExchange`1":
            case "CompareExchange":
                opCodeMethodInfo.InterlockBase(
                    "cmpxchg ",
                    llvmWriter.IsLlvm34OrLower ? " acq_rel" : " acq_rel monotonic",
                    !llvmWriter.IsLlvm35 && !llvmWriter.IsLlvm34OrLower,
                    llvmWriter,
                    new[] { 0, 2, 1 });
                break;
            }
        }
Exemplo n.º 28
0
        /// <summary>
        /// </summary>
        /// <param name="methodInfo">
        /// </param>
        /// <param name="opCodeMethodInfo">
        /// </param>
        /// <param name="llvmWriter">
        /// </param>
        /// <returns>
        /// </returns>
        public static FullyDefinedReference WriteFunctionCallResult(
            this IMethod methodInfo,
            OpCodePart opCodeMethodInfo,
            LlvmWriter llvmWriter)
        {
            var writer = llvmWriter.Output;

            var isReturnStructType = methodInfo != null && methodInfo.ReturnType.IsStructureType();
            var isReturnVoidType   = methodInfo != null && methodInfo.ReturnType.IsVoid();

            // allocate space for structure if return type is structure
            if (isReturnStructType)
            {
                // TODO: for optimization, when it is used by Code.Stfld etc you can optimaze sending reference to a structure without allocating it in stack
                // todo so you need to request a destination reference as you did before

                // we need to store temp result of struct in stack to be used by "Ldfld, Ldflda"
                llvmWriter.WriteSetResultNumber(opCodeMethodInfo, methodInfo.ReturnType);
                llvmWriter.WriteAlloca(methodInfo.ReturnType);
                writer.WriteLine(string.Empty);
            }
            else if (!isReturnVoidType)
            {
                llvmWriter.WriteSetResultNumber(opCodeMethodInfo, methodInfo.ReturnType);
            }

            return(opCodeMethodInfo.Result);
        }
Exemplo n.º 29
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);
        }
Exemplo n.º 30
0
        public static void WriteAllocateMemoryForObject(
            this LlvmWriter llvmWriter,
            OpCodePart opCodePart,
            IType declaringClassType,
            bool doNotTestNullValue,
            bool enableStringFastAllocation = false)
        {
            var writer = llvmWriter.Output;

            var size = declaringClassType.GetTypeSize(llvmWriter);

            FullyDefinedReference allocResult;

            if (declaringClassType.IsMultiArray)
            {
                allocResult = llvmWriter.WriteMultiDimArrayAllocationSize(opCodePart, declaringClassType);
            }
            else if (declaringClassType.IsArray)
            {
                allocResult = llvmWriter.WriteSingleDimArrayAllocationSize(opCodePart, declaringClassType);
            }
            else if (enableStringFastAllocation && declaringClassType.IsString)
            {
                allocResult = llvmWriter.WriteStringAllocationSize(opCodePart, declaringClassType, llvmWriter.System.System_Char);
            }
            else
            {
                allocResult = new ConstValue(size, llvmWriter.System.System_Int32);
            }

            var mallocResult = llvmWriter.WriteSetResultNumber(
                opCodePart,
                llvmWriter.System.System_Byte.ToPointerType());

            writer.Write("call i8* @{0}(", llvmWriter.GetAllocator());
            allocResult.Type.WriteTypePrefix(llvmWriter);
            writer.Write(" {0}", allocResult);
            writer.WriteLine(")");

            if (!doNotTestNullValue)
            {
                llvmWriter.WriteTestNullValueAndThrowException(
                    writer,
                    opCodePart,
                    mallocResult,
                    "System.OutOfMemoryException",
                    "new_obj");
            }

            if (!llvmWriter.Gc)
            {
                llvmWriter.WriteMemSet(declaringClassType, mallocResult);
                writer.WriteLine(string.Empty);
            }

            llvmWriter.WriteBitcast(opCodePart, mallocResult, declaringClassType);
            writer.WriteLine(string.Empty);
        }
Exemplo n.º 31
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;
        }
Exemplo n.º 32
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);
        }
Exemplo n.º 33
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);
        }
Exemplo n.º 34
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);
        }
Exemplo n.º 35
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;
            }
        }
Exemplo n.º 36
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;
            }
        }
Exemplo n.º 37
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="source">
        /// </param>
        /// <param name="toType">
        /// </param>
        public static void WriteBitcast(
            this LlvmWriter llvmWriter,
            OpCodePart opCode,
            FullyDefinedReference source,
            IType toType,
            bool asReference = true)
        {
            var writer = llvmWriter.Output;

            llvmWriter.WriteSetResultNumber(opCode, toType);
            writer.Write("bitcast ");
            source.Type.WriteTypePrefix(llvmWriter, asReference);
            writer.Write(" ");
            llvmWriter.WriteResult(source);
            writer.Write(" to ");
            toType.WriteTypePrefix(llvmWriter, asReference);
        }
Exemplo n.º 38
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="fromType">
        /// </param>
        /// <param name="result">
        /// </param>
        /// <param name="custom">
        /// </param>
        public static void WriteBitcast(
            this LlvmWriter llvmWriter,
            OpCodePart opCode,
            IType fromType,
            IncrementalResult result,
            string custom)
        {
            var writer = llvmWriter.Output;

            llvmWriter.WriteSetResultNumber(opCode, null);
            writer.Write("bitcast ");
            fromType.WriteTypePrefix(llvmWriter, true);
            writer.Write(' ');
            llvmWriter.WriteResult(result);
            writer.Write(" to ");
            writer.Write(custom);

            writer.WriteLine(string.Empty);
        }
Exemplo n.º 39
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*");
        }
Exemplo n.º 40
0
        private static PhiNodes GetPhiValues(IEnumerable<OpCodePart> values, OpCodePart currentValue)
        {
            var phiNodes = new PhiNodes();
            var any = false;
            foreach (
                var alternateValue in
                    values.Where(alternateValue => currentValue == null || !alternateValue.Equals(currentValue)))
            {
                AddPhiValue(phiNodes, alternateValue);
                any = true;
            }

            if (any)
            {
                if (currentValue != null)
                {
                    AddPhiValue(phiNodes, currentValue);
                }

                // all values the same - return null
                var firstValueAddressStart = phiNodes.Values.First().AddressStart;
                if (phiNodes.Values.Count() > 1 && phiNodes.Values.All(v => v.AddressStart == firstValueAddressStart))
                {
                    return null;
                }

                return phiNodes;
            }

            return null;
        }
Exemplo n.º 41
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;
            }

            // TODO: check if alternative stack has the same values then ignore alternative stack
            var valueNumber = 0;
            while (true)
            {
                var values =
                    entriesList.Where(opCode => opCode.BranchStackValue != null && opCode.BranchStackValue.Count > 0)
                        .Select(opCode => opCode.BranchStackValue.Peek());
                if (!values.Any())
                {
                    return;
                }

                var currentStackValue = valueNumber >= this.main.Count ? null : this.main.Skip(valueNumber).First();
                var alternativeValues = GetPhiValues(values, !noMainEntry ? currentStackValue : 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;
                }

                if (opCodePart.AlternativeValues == null)
                {
                    opCodePart.AlternativeValues = new Queue<PhiNodes>();
                }
                else
                {
                    // if labels are different it means that values belong to other PHI Nodes
                    var firstAlternativeValues = opCodePart.AlternativeValues.First();
                    if (firstAlternativeValues.Labels.Count != alternativeValues.Labels.Count ||
                        alternativeValues.Labels.Where((t, i) => t != firstAlternativeValues.Labels[i]).Any())
                    {
                        return;
                    }
                }

                opCodePart.AlternativeValues.Enqueue(alternativeValues);

                // remove values from branchstack
                foreach (
                    var branchStack in
                        entriesList.Where(
                            opCode => opCode.BranchStackValue != null && opCode.BranchStackValue.Count > 0)
                            .Select(opCode => opCode.BranchStackValue))
                {
                    branchStack.Pop();
                }

                if (noMainEntry)
                {
                    return;
                }

                // we remove all previously added values at line this.main.Push(firstValue); to reinsert it after removing alternative values from cache which is not at top level
                var top = new Stack<OpCodePart>();
                for (var i = 0; i < valueNumber; i++)
                {
                    top.Push(this.main.Pop());
                }

                // we remove all alternative values from cache, they not needed anymore
                while (this.main.Any() && alternativeValues.Values.Contains(this.main.Peek()))
                {
                    this.main.Pop();
                }

                // this is new value
                this.main.Push(firstValue);

                // we insert top back
                for (var i = 0; i < valueNumber; i++)
                {
                    this.main.Push(top.Pop());
                }

                valueNumber++;

                // set UsedByAlternativeValues
                foreach (var value in alternativeValues.Values)
                {
                    value.UsedByAlternativeValues = alternativeValues;
                }
            }
        }
Exemplo n.º 42
0
 /// <summary>
 /// </summary>
 /// <param name="opCodePart">
 /// </param>
 /// <param name="label">
 /// </param>
 public static void SetCustomLabel(OpCodePart opCodePart, string label)
 {
     if (opCodePart.AddressStart == 0 && opCodePart.UsedBy != null)
     {
         opCodePart.UsedBy.OpCode.CreatedLabel = label;
     }
     else
     {
         opCodePart.CreatedLabel = label;
     }
 }
Exemplo n.º 43
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);
        }
Exemplo n.º 44
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCodeMethodInfo">
        /// </param>
        /// <param name="methodInfo">
        /// </param>
        /// <param name="isVirtual">
        /// </param>
        /// <param name="hasThis">
        /// </param>
        /// <param name="isCtor">
        /// </param>
        /// <param name="thisResultNumber">
        /// </param>
        /// <param name="tryClause">
        /// </param>
        public static void WriteCall(
            this LlvmWriter llvmWriter,
            OpCodePart opCodeMethodInfo,
            IMethod methodInfo,
            bool isVirtual,
            bool hasThis,
            bool isCtor,
            FullyDefinedReference thisResultNumber,
            TryClause tryClause)
        {
            var writer = llvmWriter.Output;

            IType thisType;
            bool hasThisArgument;
            OpCodePart opCodeFirstOperand;
            BaseWriter.ReturnResult resultOfFirstOperand;
            bool isIndirectMethodCall;
            IType ownerOfExplicitInterface;
            IType requiredType;
            methodInfo.WriteFunctionCallProlog(
                opCodeMethodInfo,
                isVirtual,
                hasThis,
                llvmWriter,
                out thisType,
                out hasThisArgument,
                out opCodeFirstOperand,
                out resultOfFirstOperand,
                out isIndirectMethodCall,
                out ownerOfExplicitInterface,
                out requiredType);

            llvmWriter.CheckIfMethodExternalDeclarationIsRequired(methodInfo, ownerOfExplicitInterface);
            llvmWriter.CheckIfExternalDeclarationIsRequired(methodInfo.DeclaringType);

            if (hasThisArgument)
            {
                opCodeMethodInfo.WriteFunctionCallPrepareThisExpression(
                    thisType,
                    opCodeFirstOperand,
                    resultOfFirstOperand,
                    llvmWriter);
            }

            FullyDefinedReference methodAddressResultNumber = null;
            if (isIndirectMethodCall)
            {
                methodAddressResultNumber = llvmWriter.GenerateVirtualCall(
                    opCodeMethodInfo,
                    methodInfo,
                    thisType,
                    opCodeFirstOperand,
                    resultOfFirstOperand,
                    ref requiredType);
            }

            methodInfo.WriteFunctionCallLoadFunctionAddress(
                opCodeMethodInfo,
                thisType,
                ref methodAddressResultNumber,
                llvmWriter);

            methodInfo.PreProcessCallParameters(opCodeMethodInfo, llvmWriter);

            if (llvmWriter.ProcessPluggableMethodCall(opCodeMethodInfo, methodInfo))
            {
                return;
            }

            var returnFullyDefinedReference = methodInfo.WriteFunctionCallResult(opCodeMethodInfo, llvmWriter);

            writer.WriteFunctionCall(tryClause);

            methodInfo.WriteFunctionCallAttributes(writer);

            if (methodInfo.CallingConvention.HasFlag(CallingConventions.VarArgs))
            {
                llvmWriter.WriteMethodPointerType(writer, methodInfo);
                writer.Write(" ");
            }
            else
            {
                methodInfo.WriteFunctionCallReturnType(llvmWriter);

                writer.Write(' ');

                // extra support
                if (methodInfo.IsExternalLibraryMethod())
                {
                    writer.Write("(...)* ");
                }
            }

            methodInfo.WriteFunctionNameExpression(methodAddressResultNumber, ownerOfExplicitInterface, llvmWriter);

            methodInfo.GetParameters()
                .WriteFunctionCallArguments(
                    opCodeMethodInfo.OpCodeOperands,
                    isVirtual,
                    hasThis,
                    isCtor,
                    thisResultNumber,
                    thisType,
                    returnFullyDefinedReference,
                    methodInfo != null ? methodInfo.ReturnType : null,
                    llvmWriter,
                    methodInfo.CallingConvention.HasFlag(CallingConventions.VarArgs));

            tryClause.WriteFunctionCallUnwind(opCodeMethodInfo, llvmWriter);
        }
Exemplo n.º 45
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.System.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.System.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.System.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;
        }
Exemplo n.º 46
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);
            }
            llvmWriter.WriteSetResultNumber(opCode, toType);
            writer.Write("bitcast ");
            fromType.WriteTypePrefix(llvmWriter, true);
            writer.Write(' ');
            writer.Write(custromName);
            writer.Write(" to ");
            toType.WriteTypePrefix(llvmWriter, true);
            if (appendReference)
            {
                // result should be array
                writer.Write('*');
            }

            writer.WriteLine(string.Empty);
        }
Exemplo n.º 47
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;
        }
Exemplo n.º 48
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;
        }
Exemplo n.º 49
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;
        }
Exemplo n.º 50
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);
        }
Exemplo n.º 51
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;

            var result = opCode.Result;

            llvmWriter.WriteSetResultNumber(opCode, toType);
            writer.Write("bitcast ");
            result.Type.WriteTypePrefix(llvmWriter, true);
            writer.Write(" ");
            llvmWriter.WriteResult(result);
            writer.Write(" to ");
            toType.WriteTypePrefix(llvmWriter, true);
        }
Exemplo n.º 52
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.System.System_Int32);

                llvmWriter.WriteLlvmLoad(opCodeNope, llvmWriter.System.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,
                        upperLevelExceptionHandlingClause,
                        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.System.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))
                {
                    var noNext = nextOp == null;
                    var isNextCatchBlock = nextOp != null && nextOp.CatchOrFinallyBegin != null;
                    var hasExit = llvmWriter.OpsByAddressStart.Values.Any(op => op.ToCode() == Code.Ret);
                    if (!isNextCatchBlock && !noNext && (isLeave || hasExit))
                    {
                        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");
            }
        }
Exemplo n.º 53
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);
        }
Exemplo n.º 54
0
        private static void AddPhiValue(PhiNodes phiNodes, OpCodePart value)
        {
            var currentLabel = value.FindBeginOfBasicBlock();
            phiNodes.Values.Add(value);
            if (currentLabel.HasValue)
            {
                phiNodes.Labels.Add(currentLabel.Value);
            }
            else
            {
                // we need to create a label
                var opCode = value.OpCodeOperands != null && value.OpCodeOperands.Length > 0
                    ? value.OpCodeOperands[0]
                    : value;
                if (opCode.JumpDestination == null)
                {
                    opCode.JumpDestination = new List<OpCodePart>();
                }

                opCode.JumpDestination.Add(value);

                phiNodes.Labels.Add(opCode.AddressStart);
            }
        }
Exemplo n.º 55
0
 public void Push(OpCodePart opCodePart)
 {
     this.main.Push(opCodePart);
 }
Exemplo n.º 56
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="source">
        /// </param>
        /// <param name="toType">
        /// </param>
        public static void WriteIntToPtr(
            this LlvmWriter llvmWriter,
            OpCodePart opCode,
            FullyDefinedReference source,
            IType toType)
        {
            var writer = llvmWriter.Output;

            Debug.Assert(!source.Type.IsPointer && !source.Type.IsByRef);

            llvmWriter.WriteSetResultNumber(opCode, toType);
            writer.Write("inttoptr ");
            source.Type.WriteTypePrefix(llvmWriter);
            writer.Write(" ");
            llvmWriter.WriteResult(source);
            writer.Write(" to ");
            toType.WriteTypePrefix(llvmWriter, true);
        }
Exemplo n.º 57
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())
                    {
                        // to clone whole stack
                        var clonedStack = this.main.ToList();
                        clonedStack.Reverse();
                        opCode.BranchStackValue = new Stack<OpCodePart>(clonedStack);
                    }

                    break;
            }
        }
Exemplo n.º 58
0
        public static void WriteLlvmLoadPrimitiveFromStructure(
            this LlvmWriter llvmWriter,
            OpCodePart opCode,
            FullyDefinedReference source)
        {
            var writer = llvmWriter.Output;

            // write access to a field
            if (!llvmWriter.WriteFieldAccess(
                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);
        }
Exemplo n.º 59
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);
 }
Exemplo n.º 60
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: review the whole proc.
            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(llvmWriter, 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);
            }
        }