/// <summary> /// Lowers leae nodes to linear <see cref="LoadElementAddress"/> values. /// </summary> private static void Lower( RewriterContext context, TypeLowering <ArrayType> typeLowering, LoadArrayElementAddress value) { var builder = context.Builder; var location = value.Location; Value array = value.ArrayValue; // Get and validate the array type var structureType = array.Type.As <StructureType>(location); // Compute linear address based on the .Net array layouts Value elementIndex = builder.CreatePrimitiveValue(location, 0L); // (((0 * Width + x) * Height) + y) * Depth + z... for (int i = 0, e = structureType.NumFields - 1; i < e; ++i) { Value length = builder.CreateGetField( location, array, new FieldAccess(1 + i)); // Create a debug assertion to check for out-of-bounds accesses builder.CreateDebugAssert( location, builder.CreateCompare( location, value.Dimensions[i], length, CompareKind.LessThan), builder.CreatePrimitiveValue( location, $"{i}-th array index out of range")); // Update index computation elementIndex = builder.CreateArithmetic( location, elementIndex, length, BinaryArithmeticKind.Mul); elementIndex = builder.CreateArithmetic( location, elementIndex, value.Dimensions[i], BinaryArithmeticKind.Add); } // Extract the actual view field from the structure and compute the // appropriate target element address. var view = GetViewFromArray(builder, location, array); var lea = builder.CreateLoadElementAddress( location, view, elementIndex); context.ReplaceAndRemove(value, lea); }
/// <summary cref="IValueVisitor.Visit(LoadArrayElementAddress)"/> public void Visit(LoadArrayElementAddress value) => throw new InvalidCodeGenerationException();