Skip to content

Commit 4de3e24

Browse files
Don't use ref assemblies for NETCoreApp runtime libraries
Solves an issue with structs not being recognized. This is not a great fix but it should be enough for now.
1 parent c055ac5 commit 4de3e24

File tree

3 files changed

+31
-4
lines changed

3 files changed

+31
-4
lines changed

src/DistIL.Cli/Program.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,12 @@ static void RunOptimizer(OptimizerOptions options)
3131
var logger = new ConsoleLogger() { MinLevel = options.Verbosity };
3232

3333
var resolver = new ModuleResolver(logger);
34+
resolver.AddSearchPaths(new[] { Path.GetDirectoryName(Path.GetFullPath(options.InputPath))! });
3435
resolver.AddSearchPaths(options.ResolverPaths);
35-
resolver.AddSearchPaths(new[] { Path.GetDirectoryName(options.InputPath)!, Environment.CurrentDirectory });
36-
resolver.AddTrustedSearchPaths();
36+
37+
if (!options.NoResolverFallback) {
38+
resolver.AddTrustedSearchPaths();
39+
}
3740

3841
var module = resolver.Load(options.InputPath);
3942

@@ -136,6 +139,9 @@ class OptimizerOptions
136139
[Option('r', HelpText = "Module resolver search paths.")]
137140
public IEnumerable<string> ResolverPaths { get; set; } = null!;
138141

142+
[Option("no-resolver-fallback", HelpText = "Don't use fallback search paths for module resolution.")]
143+
public bool NoResolverFallback { get; set; } = false;
144+
139145
[Option("filter-unmarked", HelpText = "Only transform methods and classes marked with `OptimizeAttribute`.")]
140146
public bool FilterUnmarked { get; set; } = false;
141147

src/DistIL.OptimizerTask/DistIL.OptimizerTask.targets

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<PropertyGroup>
1515
<!-- Trailing slashes are removed to prevent issues with argument splitting. -->
1616
<JoinedAsmRefPaths>@(AsmRefPaths -> '"%(Identity)"', ' ')</JoinedAsmRefPaths>
17-
<ResolverPathsArg>-r $(JoinedAsmRefPaths.Replace('\"', '"'))</ResolverPathsArg>
17+
<ResolverPathsArg>-r $(JoinedAsmRefPaths.Replace('\"', '"')) --no-resolver-fallback</ResolverPathsArg>
1818

1919
<FilterUnmarkedArg Condition="'$(DistilAllMethods)' != 'true'">--filter-unmarked</FilterUnmarkedArg>
2020
</PropertyGroup>

src/DistIL/AsmIO/ModuleResolver.cs

+22-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ namespace DistIL.AsmIO;
33
using System.IO;
44
using System.Reflection;
55
using System.Reflection.PortableExecutable;
6+
using System.Text.RegularExpressions;
67

78
public class ModuleResolver
89
{
@@ -25,7 +26,27 @@ public ModuleResolver(ICompilationLogger? logger = null)
2526

2627
public void AddSearchPaths(IEnumerable<string> paths)
2728
{
28-
_searchPaths = _searchPaths.Concat(paths).Distinct(StringComparer.OrdinalIgnoreCase).ToArray();
29+
_searchPaths = _searchPaths
30+
.Concat(paths)
31+
.Select(FixRuntimePackRefPath)
32+
.Distinct(StringComparer.OrdinalIgnoreCase)
33+
.ToArray();
34+
35+
//Try to change search path for the `NETCore.App.Ref` pack to the actual implementation path.
36+
//This is done for a couple reasons:
37+
// - We make the assumption that "System.Private.CoreLib" always exist, but it doesn't in ref packs.
38+
// This would lead to multiple defs for e.g. "System.ValueType", which would cause issues.
39+
// - We want to depend on _some_ private impl details which are not shipped in ref asms.
40+
// Notably accessing private `List<T>` fields.
41+
static string FixRuntimePackRefPath(string path)
42+
{
43+
//e.g. "C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\7.0.3\ref\net7.0"
44+
// shared **** ***********
45+
//(I guess this piece will be in the top 3 reasons why I'll be sent to code hell.)
46+
string normPath = Path.GetFullPath(path).Replace('\\', '/');
47+
string implPath = Regex.Replace(normPath, @"(.+?\/)packs(\/Microsoft\.NETCore\.App)\.Ref(\/.+?)\/.+", "$1shared$2$3");
48+
return implPath != normPath && Directory.Exists(implPath) ? implPath : path;
49+
}
2950
}
3051

3152
public void AddTrustedSearchPaths()

0 commit comments

Comments
 (0)