Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions src/coreclr/jit/lowerxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8202,18 +8202,20 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre
case NI_AVX2_BroadcastScalarToVector256:
case NI_AVX512F_BroadcastScalarToVector512:
{
var_types baseType = hwintrinsic->GetSimdBaseType();
if (varTypeIsSmall(baseType))
var_types parentBaseType = parentNode->GetSimdBaseType();
var_types childBaseType = hwintrinsic->GetSimdBaseType();

if (varTypeIsSmall(parentBaseType) || (genTypeSize(parentBaseType) != genTypeSize(childBaseType)))
{
// early return if the base type is not embedded broadcast compatible.
// early return if either base type is not embedded broadcast compatible.
return false;
}

// make the broadcast node containable when embedded broadcast can be enabled.
if (intrinsicId == NI_SSE3_MoveAndDuplicate)
{
// NI_SSE3_MoveAndDuplicate is for Vector128<double> only.
assert(baseType == TYP_DOUBLE);
assert(childBaseType == TYP_DOUBLE);
}

if (comp->compOpportunisticallyDependsOn(InstructionSet_AVX512F_VL) &&
Expand Down Expand Up @@ -8246,6 +8248,15 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre
case NI_AVX_BroadcastScalarToVector128:
case NI_AVX_BroadcastScalarToVector256:
{
var_types parentBaseType = parentNode->GetSimdBaseType();
var_types childBaseType = hwintrinsic->GetSimdBaseType();

if (varTypeIsSmall(parentBaseType) || (genTypeSize(parentBaseType) != genTypeSize(childBaseType)))
{
// early return if either base type is not embedded broadcast compatible.
return false;
}

return parentNode->OperIsEmbBroadcastCompatible();
}

Expand Down
121 changes: 39 additions & 82 deletions src/installer/managed/Microsoft.NET.HostModel/AppHost/PEUtils.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Buffers.Binary;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Reflection.PortableExecutable;

namespace Microsoft.NET.HostModel.AppHost
{
Expand All @@ -15,29 +18,13 @@ public static class PEUtils
/// <returns>true if the accessor represents a PE image, false otherwise.</returns>
internal static unsafe bool IsPEImage(MemoryMappedViewAccessor accessor)
{
byte* pointer = null;
if (accessor.Capacity < PEOffsets.DosStub.PESignatureOffset + sizeof(uint))
return false;

try
{
accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref pointer);
byte* bytes = pointer + accessor.PointerOffset;

// https://en.wikipedia.org/wiki/Portable_Executable
// Validate that we're looking at Windows PE file
if (((ushort*)bytes)[0] != PEOffsets.DosImageSignature
|| accessor.Capacity < PEOffsets.DosStub.PESignatureOffset + sizeof(uint))
{
return false;
}
return true;
}
finally
{
if (pointer != null)
{
accessor.SafeMemoryMappedViewHandle.ReleasePointer();
}
}
// https://en.wikipedia.org/wiki/Portable_Executable
// Validate that we're looking at Windows PE file
ushort signature = AsLittleEndian(accessor.ReadUInt16(0));
return signature == PEOffsets.DosImageSignature;
}

public static bool IsPEImage(string filePath)
Expand All @@ -60,40 +47,15 @@ public static bool IsPEImage(string filePath)
/// <param name="accessor">The memory accessor which has the apphost file opened.</param>
internal static unsafe void SetWindowsGraphicalUserInterfaceBit(MemoryMappedViewAccessor accessor)
{
byte* pointer = null;

try
{
accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref pointer);
byte* bytes = pointer + accessor.PointerOffset;

// https://en.wikipedia.org/wiki/Portable_Executable
uint peHeaderOffset = ((uint*)(bytes + PEOffsets.DosStub.PESignatureOffset))[0];

if (accessor.Capacity < peHeaderOffset + PEOffsets.PEHeader.Subsystem + sizeof(ushort))
{
throw new AppHostNotPEFileException("Subsystem offset out of file range.");
}

ushort* subsystem = ((ushort*)(bytes + peHeaderOffset + PEOffsets.PEHeader.Subsystem));

// https://docs.microsoft.com/en-us/windows/desktop/Debug/pe-format#windows-subsystem
// The subsystem of the prebuilt apphost should be set to CUI
if (subsystem[0] != (ushort)PEOffsets.Subsystem.WindowsCui)
{
throw new AppHostNotCUIException(subsystem[0]);
}

// Set the subsystem to GUI
subsystem[0] = (ushort)PEOffsets.Subsystem.WindowsGui;
}
finally
{
if (pointer != null)
{
accessor.SafeMemoryMappedViewHandle.ReleasePointer();
}
}
// https://learn.microsoft.com/windows/win32/debug/pe-format#windows-subsystem
// The subsystem of the prebuilt apphost should be set to CUI
uint peHeaderOffset;
ushort subsystem = GetWindowsSubsystem(accessor, out peHeaderOffset);
if (subsystem != (ushort)Subsystem.WindowsCui)
throw new AppHostNotCUIException(subsystem);

// Set the subsystem to GUI
accessor.Write(peHeaderOffset + PEOffsets.PEHeader.Subsystem, AsLittleEndian((ushort)Subsystem.WindowsGui));
}

public static unsafe void SetWindowsGraphicalUserInterfaceBit(string filePath)
Expand All @@ -113,32 +75,7 @@ public static unsafe void SetWindowsGraphicalUserInterfaceBit(string filePath)
/// <param name="accessor">The memory accessor which has the apphost file opened.</param>
internal static unsafe ushort GetWindowsGraphicalUserInterfaceBit(MemoryMappedViewAccessor accessor)
{
byte* pointer = null;

try
{
accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref pointer);
byte* bytes = pointer + accessor.PointerOffset;

// https://en.wikipedia.org/wiki/Portable_Executable
uint peHeaderOffset = ((uint*)(bytes + PEOffsets.DosStub.PESignatureOffset))[0];

if (accessor.Capacity < peHeaderOffset + PEOffsets.PEHeader.Subsystem + sizeof(ushort))
{
throw new AppHostNotPEFileException("Subsystem offset out of file range.");
}

ushort* subsystem = ((ushort*)(bytes + peHeaderOffset + PEOffsets.PEHeader.Subsystem));

return subsystem[0];
}
finally
{
if (pointer != null)
{
accessor.SafeMemoryMappedViewHandle.ReleasePointer();
}
}
return GetWindowsSubsystem(accessor, out _);
}

public static unsafe ushort GetWindowsGraphicalUserInterfaceBit(string filePath)
Expand All @@ -151,5 +88,25 @@ public static unsafe ushort GetWindowsGraphicalUserInterfaceBit(string filePath)
}
}
}

private static ushort GetWindowsSubsystem(MemoryMappedViewAccessor accessor, out uint peHeaderOffset)
{
// https://en.wikipedia.org/wiki/Portable_Executable
if (accessor.Capacity < PEOffsets.DosStub.PESignatureOffset + sizeof(uint))
throw new AppHostNotPEFileException("PESignature offset out of file range.");

peHeaderOffset = AsLittleEndian(accessor.ReadUInt32(PEOffsets.DosStub.PESignatureOffset));
if (accessor.Capacity < peHeaderOffset + PEOffsets.PEHeader.Subsystem + sizeof(ushort))
throw new AppHostNotPEFileException("Subsystem offset out of file range.");

// https://learn.microsoft.com/windows/win32/debug/pe-format#windows-subsystem
return AsLittleEndian(accessor.ReadUInt16(peHeaderOffset + PEOffsets.PEHeader.Subsystem));
}

private static ushort AsLittleEndian(ushort value)
=> BitConverter.IsLittleEndian ? value : BinaryPrimitives.ReverseEndianness(value);

private static uint AsLittleEndian(uint value)
=> BitConverter.IsLittleEndian ? value : BinaryPrimitives.ReverseEndianness(value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Microsoft.NET.HostModel.AppHost;
using Microsoft.DotNet.CoreSetup.Test;
using System.Diagnostics;
using System.Reflection.PortableExecutable;

namespace Microsoft.NET.HostModel.Tests
{
Expand Down Expand Up @@ -111,7 +112,9 @@ public void ItCanSetWindowsGUISubsystem()
BitConverter
.ToUInt16(File.ReadAllBytes(destinationFilePath), SubsystemOffset)
.Should()
.Be(2);
.Be((ushort)Subsystem.WindowsGui);

Assert.Equal((ushort)Subsystem.WindowsGui, PEUtils.GetWindowsGraphicalUserInterfaceBit(destinationFilePath));
}
}

Expand Down Expand Up @@ -153,6 +156,7 @@ public void ItFailsToSetGUISubsystemWithWrongDefault()
string destinationFilePath = Path.Combine(testDirectory.Path, "DestinationAppHost.exe.mock");
string appBinaryFilePath = "Test/App/Binary/Path.dll";

Assert.Equal(42, PEUtils.GetWindowsGraphicalUserInterfaceBit(sourceAppHostMock));
Assert.Throws<AppHostNotCUIException>(() =>
HostWriter.CreateAppHost(
sourceAppHostMock,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,11 @@ private static void BindInstance(
return;
}

if (config is null)
{
return;
}

var section = config as IConfigurationSection;
string? configValue = section?.Value;
if (configValue != null && TryConvertValue(type, configValue, section?.Path, out object? convertedValue, out Exception? error))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -888,5 +888,11 @@ public int MyIntProperty
}
}

public class SimplePoco
{
public string A { get; set; }
public string B { get; set; }
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#if BUILDING_SOURCE_GENERATOR_TESTS
using Microsoft.Extensions.Configuration;
#endif
using Microsoft.Extensions.Configuration.Memory;
using Microsoft.Extensions.Configuration.Test;
using Xunit;

Expand Down Expand Up @@ -1767,7 +1768,7 @@ public void EnsureCallingThePropertySetter()
Assert.Equal(0, options.OtherCodeNullable);
Assert.Equal("default", options.OtherCodeString);
Assert.Null(options.OtherCodeNull);
Assert.Null(options.OtherCodeUri);
Assert.Null(options.OtherCodeUri);
}

[Fact]
Expand Down Expand Up @@ -2238,7 +2239,7 @@ void TestUntypedOverloads(IConfiguration? configuration, string? key)
Assert.Throws<ArgumentNullException>(() => configuration.GetValue(typeof(GeolocationClass), key, new GeolocationClass()));
Assert.Throws<ArgumentNullException>(() => configuration.GetValue(typeof(Geolocation), key));
Assert.Throws<ArgumentNullException>(() => configuration.GetValue(typeof(Geolocation), key, defaultValue: null));
Assert.Throws<ArgumentNullException>(() => configuration.GetValue(typeof(Geolocation), key, default(Geolocation)));
Assert.Throws<ArgumentNullException>(() => configuration.GetValue(typeof(Geolocation), key, default(Geolocation)));
}
}

Expand Down Expand Up @@ -2404,5 +2405,38 @@ public void SharedChildInstance()
config.GetSection("A").Bind(instance);
Assert.Equal("localhost", instance.ConnectionString);
}

[Fact]
public void CanBindToMockConfigurationSection()
{
const string expectedA = "hello";

var configSource = new MemoryConfigurationSource()
{
InitialData = new Dictionary<string, string?>()
{
[$":{nameof(SimplePoco.A)}"] = expectedA,
}
};
var configRoot = new MockConfigurationRoot(new[] { configSource.Build(null) });
var configSection = new ConfigurationSection(configRoot, string.Empty);

SimplePoco result = new();
configSection.Bind(result);

Assert.Equal(expectedA, result.A);
Assert.Equal(default(string), result.B);
}

// a mock configuration root that will return null for undefined Sections,
// as is common when Configuration interfaces are mocked
class MockConfigurationRoot : ConfigurationRoot, IConfigurationRoot
{
public MockConfigurationRoot(IList<IConfigurationProvider> providers) : base(providers)
{ }

IConfigurationSection IConfiguration.GetSection(string key) =>
this[key] is null ? null : new ConfigurationSection(this, key);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace System.Numerics.Tensors
{
public static partial class TensorPrimitives
{
public static void Abs(System.ReadOnlySpan<float> x, System.Span<float> destination) { }
public static void Add(System.ReadOnlySpan<float> x, System.ReadOnlySpan<float> y, System.Span<float> destination) { }
public static void Add(System.ReadOnlySpan<float> x, float y, System.Span<float> destination) { }
public static void AddMultiply(System.ReadOnlySpan<float> x, System.ReadOnlySpan<float> y, System.ReadOnlySpan<float> multiplier, System.Span<float> destination) { }
Expand All @@ -24,12 +25,17 @@ public static void Exp(System.ReadOnlySpan<float> x, System.Span<float> destinat
public static int IndexOfMaxMagnitude(System.ReadOnlySpan<float> x) { throw null; }
public static int IndexOfMin(System.ReadOnlySpan<float> x) { throw null; }
public static int IndexOfMinMagnitude(System.ReadOnlySpan<float> x) { throw null; }
public static float L2Normalize(System.ReadOnlySpan<float> x) { throw null; }
public static float Norm(System.ReadOnlySpan<float> x) { throw null; }
public static void Log(System.ReadOnlySpan<float> x, System.Span<float> destination) { }
public static void Log2(System.ReadOnlySpan<float> x, System.Span<float> destination) { }
public static float Max(System.ReadOnlySpan<float> x) { throw null; }
public static void Max(System.ReadOnlySpan<float> x, System.ReadOnlySpan<float> y, System.Span<float> destination) { throw null; }
public static float MaxMagnitude(System.ReadOnlySpan<float> x) { throw null; }
public static void MaxMagnitude(System.ReadOnlySpan<float> x, System.ReadOnlySpan<float> y, System.Span<float> destination) { throw null; }
public static float Min(System.ReadOnlySpan<float> x) { throw null; }
public static void Min(System.ReadOnlySpan<float> x, System.ReadOnlySpan<float> y, System.Span<float> destination) { throw null; }
public static float MinMagnitude(System.ReadOnlySpan<float> x) { throw null; }
public static void MinMagnitude(System.ReadOnlySpan<float> x, System.ReadOnlySpan<float> y, System.Span<float> destination) { throw null; }
public static void Multiply(System.ReadOnlySpan<float> x, System.ReadOnlySpan<float> y, System.Span<float> destination) { }
public static void Multiply(System.ReadOnlySpan<float> x, float y, System.Span<float> destination) { }
public static void MultiplyAdd(System.ReadOnlySpan<float> x, System.ReadOnlySpan<float> y, System.ReadOnlySpan<float> addend, System.Span<float> destination) { }
Expand Down
Loading