From b6f80073aa8d4a9fcb936280baddbeff8930dcfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Thu, 14 Oct 2021 22:24:48 +0900 Subject: [PATCH] Implement function pointer signatures (#57) * Implement function pointer signatures Will be needed to trim anything touching corelib. Fixes #35. * Fix modifiers rewrite Co-authored-by: vitek-karas --- .../ILTrim.Tests.Cases.Expectations.csproj | 1 - .../Basic/FunctionPointer.cs | 27 +++++++++++++++++++ .../ILTrim.Tests.Cases.csproj | 1 + .../EcmaSignatureAnalyzer.cs | 7 +++-- .../EcmaSignatureRewriter.cs | 19 +++++++++++-- 5 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/Basic/FunctionPointer.cs diff --git a/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases.Expectations/ILTrim.Tests.Cases.Expectations.csproj b/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases.Expectations/ILTrim.Tests.Cases.Expectations.csproj index 8b526db9b74..72f2e53fa75 100644 --- a/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases.Expectations/ILTrim.Tests.Cases.Expectations.csproj +++ b/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases.Expectations/ILTrim.Tests.Cases.Expectations.csproj @@ -2,7 +2,6 @@ net6.0 - enable enable x64;x86 diff --git a/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/Basic/FunctionPointer.cs b/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/Basic/FunctionPointer.cs new file mode 100644 index 00000000000..608e0ab8110 --- /dev/null +++ b/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/Basic/FunctionPointer.cs @@ -0,0 +1,27 @@ +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +[module:KeptAttributeAttribute(typeof(System.Security.UnverifiableCodeAttribute))] + +namespace Mono.Linker.Tests.Cases.Basic +{ + [Kept] + [SetupCompileArgument("/unsafe")] + unsafe class FunctionPointer + { + [Kept] + static void Main() + { + MethodTakingFunctionPointer(null); + } + + [Kept] + static void MethodTakingFunctionPointer(delegate* del) { } + + [Kept] + class OneType { } + + [Kept] + class OtherType { } + } +} diff --git a/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/ILTrim.Tests.Cases.csproj b/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/ILTrim.Tests.Cases.csproj index 1f0a194fe4b..da3847d6585 100644 --- a/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/ILTrim.Tests.Cases.csproj +++ b/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/ILTrim.Tests.Cases.csproj @@ -3,6 +3,7 @@ net6.0 x64;x86 + true $(DefineConstants);INCLUDE_EXPECTATIONS diff --git a/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/EcmaSignatureAnalyzer.cs b/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/EcmaSignatureAnalyzer.cs index f9cbaa76010..75f9a67cbef 100644 --- a/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/EcmaSignatureAnalyzer.cs +++ b/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/EcmaSignatureAnalyzer.cs @@ -46,6 +46,7 @@ private void AnalyzeType() private void AnalyzeType(SignatureTypeCode typeCode) { + again: switch (typeCode) { case SignatureTypeCode.Void: @@ -85,7 +86,8 @@ private void AnalyzeType(SignatureTypeCode typeCode) case SignatureTypeCode.RequiredModifier: case SignatureTypeCode.OptionalModifier: AnalyzeCustomModifier(typeCode); - break; + typeCode = _blobReader.ReadSignatureTypeCode(); + goto again; case SignatureTypeCode.GenericTypeInstance: _blobReader.ReadCompressedInteger(); Dependencies.Add(_factory.GetNodeForToken(_module, _blobReader.ReadTypeHandle()), "Signature reference"); @@ -96,7 +98,8 @@ private void AnalyzeType(SignatureTypeCode typeCode) } break; case SignatureTypeCode.FunctionPointer: - throw new NotImplementedException(); + AnalyzeMethodSignature(); + break; default: throw new BadImageFormatException(); } diff --git a/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/EcmaSignatureRewriter.cs b/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/EcmaSignatureRewriter.cs index 28b158c5372..d952e04f248 100644 --- a/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/EcmaSignatureRewriter.cs +++ b/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/EcmaSignatureRewriter.cs @@ -32,6 +32,7 @@ private void RewriteType(SignatureTypeEncoder encoder) private void RewriteType(SignatureTypeCode typeCode, SignatureTypeEncoder encoder) { + again: switch (typeCode) { case SignatureTypeCode.Boolean: @@ -96,7 +97,8 @@ private void RewriteType(SignatureTypeCode typeCode, SignatureTypeEncoder encode case SignatureTypeCode.RequiredModifier: case SignatureTypeCode.OptionalModifier: RewriteCustomModifier(typeCode, encoder.CustomModifiers()); - break; + typeCode = _blobReader.ReadSignatureTypeCode(); + goto again; case SignatureTypeCode.GenericTypeInstance: { int classOrValueType = _blobReader.ReadCompressedInteger(); @@ -119,7 +121,15 @@ private void RewriteType(SignatureTypeCode typeCode, SignatureTypeEncoder encode case SignatureTypeCode.TypedReference: encoder.PrimitiveType(PrimitiveTypeCode.TypedReference); break; case SignatureTypeCode.FunctionPointer: - throw new NotImplementedException(); + { + SignatureHeader header = _blobReader.ReadSignatureHeader(); + int arity = header.IsGeneric ? _blobReader.ReadCompressedInteger() : 0; + MethodSignatureEncoder sigEncoder = encoder.FunctionPointer(header.CallingConvention, 0, arity); + int count = _blobReader.ReadCompressedInteger(); + sigEncoder.Parameters(count, out ReturnTypeEncoder retTypeEncoder, out ParametersEncoder paramEncoder); + RewriteMethodSignature(count, retTypeEncoder, paramEncoder); + } + break; default: throw new BadImageFormatException(); } @@ -185,6 +195,11 @@ private void RewriteMethodSignature(BlobBuilder blobBuilder, SignatureHeader hea sigEncoder.Parameters(count, out ReturnTypeEncoder returnTypeEncoder, out ParametersEncoder paramsEncoder); + RewriteMethodSignature(count, returnTypeEncoder, paramsEncoder); + } + + private void RewriteMethodSignature(int count, ReturnTypeEncoder returnTypeEncoder, ParametersEncoder paramsEncoder) + { bool isByRef = false; againReturnType: SignatureTypeCode typeCode = _blobReader.ReadSignatureTypeCode();