예제 #1
0
        /// <summary>
        /// Computes a linear array address.
        /// </summary>
        /// <param name="location">The current location.</param>
        /// <param name="arrayIndex">The array index.</param>
        /// <param name="arrayExtent">The array extent.</param>
        /// <param name="arrayExtentOffset">The extent offset.</param>
        /// <returns>The linear array address.</returns>
        internal ValueReference ComputeArrayAddress(
            Location location,
            Value arrayIndex,
            Value arrayExtent,
            int arrayExtentOffset)
        {
            int   dimensions  = StructureType.GetNumFields(arrayExtent.Type);
            Value linearIndex = CreateGetField(
                location,
                arrayIndex,
                new FieldSpan(dimensions - 1));

            for (int i = dimensions - 2; i >= 0; --i)
            {
                var extent = CreateGetField(
                    location,
                    arrayExtent,
                    new FieldSpan(i + arrayExtentOffset));
                var index = CreateGetField(
                    location,
                    arrayIndex,
                    new FieldSpan(i));
                linearIndex = CreateArithmetic(
                    location,
                    linearIndex,
                    extent,
                    index,
                    TernaryArithmeticKind.MultiplyAdd);
            }
            return(linearIndex);
        }
예제 #2
0
        /// <summary>
        /// Computes a linear array length based on an array extent.
        /// </summary>
        /// <param name="location">The current location.</param>
        /// <param name="arrayExtent">The array extent.</param>
        /// <returns>The linear array length.</returns>
        internal ValueReference ComputeArrayLength(
            Location location,
            Value arrayExtent)
        {
            // Compute total number of elements
            var size = CreateGetField(
                location,
                arrayExtent,
                new FieldSpan(0));
            int dimensions = StructureType.GetNumFields(arrayExtent.Type);

            for (int i = 1; i < dimensions; ++i)
            {
                var element = CreateGetField(
                    location,
                    arrayExtent,
                    new FieldSpan(i));
                size = CreateArithmetic(
                    location,
                    size,
                    element,
                    BinaryArithmeticKind.Mul);
            }
            return(size);
        }
예제 #3
0
        /// <summary>
        /// Lowers array extent values.
        /// </summary>
        private static void Lower(
            RewriterContext context,
            TypeLowering <ArrayType> typeLowering,
            GetArrayExtent value)
        {
            var builder = context.Builder;

            // Create new extent structure based on all dimension entries
            int dimensions = StructureType.GetNumFields(typeLowering[value]);
            var instance   = builder.CreateDynamicStructure(value.Location, dimensions);

            // Insert all dimension values
            for (int i = 0; i < dimensions; ++i)
            {
                instance.Add(builder.CreateGetField(
                                 value.Location,
                                 value.ObjectValue,
                                 new FieldSpan(i + ArrayTypeLowering.DimensionOffset)));
            }

            var newStructure = instance.Seal();

            context.ReplaceAndRemove(value, newStructure);
        }