예제 #1
0
        protected static void ConvertAlloca <TConstructionData>(
            SSARewriterContext <Value> context,
            TConstructionData data,
            Alloca alloca,
            Value initValue)
            where TConstructionData : IConstructionData
        {
            alloca.Assert(data.ContainsAlloca(alloca));

            // Bind the init value and remove the allocation from the block
            context.SetValue(context.Block, alloca, initValue);
            data.AddConverted(alloca, new FieldRef(alloca));
            context.Remove(alloca);
        }
예제 #2
0
        /// <summary>
        /// Converts an alloca node to its initial SSA value.
        /// </summary>
        private static void Convert <TConstructionData>(
            SSARewriterContext <Value> context,
            TConstructionData data,
            Alloca alloca)
            where TConstructionData : IConstructionData
        {
            if (!data.ContainsAlloca(alloca))
            {
                return;
            }
            alloca.Assert(!alloca.IsSimpleAllocation);

            // Get the builder and the associated array length value
            var builder          = context.Builder;
            var arrayLengthValue = alloca.ArrayLength.ResolveAs <PrimitiveValue>();

            alloca.AssertNotNull(arrayLengthValue);
            int arrayLength = arrayLengthValue.Int32Value;

            // Create a structure with the appropriate number of fields that correspond
            // to the current array length
            var allocaTypeBuilder = builder.CreateStructureType(arrayLength + 1);

            // Append array length
            allocaTypeBuilder.Add(builder.GetPrimitiveType(BasicValueType.Int32));
            // Append all virtual fields
            for (int i = 0; i < arrayLength; ++i)
            {
                allocaTypeBuilder.Add(alloca.AllocaType);
            }
            var allocationType = allocaTypeBuilder.Seal();

            // Initialize the structure value
            var initValue = builder.CreateNull(alloca.Location, allocationType);

            // ... and set the array length
            initValue = builder.CreateSetField(
                alloca.Location,
                initValue,
                new FieldSpan(new FieldAccess(0)),
                builder.CreateConvertToInt32(alloca.Location, arrayLengthValue));
            ConvertAlloca(context, data, alloca, initValue);
        }