diff options
author | Michal Strehovský <MichalStrehovsky@users.noreply.github.com> | 2016-09-27 19:56:43 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-09-27 19:56:43 +0300 |
commit | a05f4934a88a17288799bc996f8fcd744b414909 (patch) | |
tree | c8115df708b228be37ae58b52feffe2d4d1df38b /src/ILCompiler.MetadataTransform | |
parent | 93e735a43817022df8dcd0b6570a89bfc253f70e (diff) |
Extend metadata schema to support function pointers (#1928)
Also:
* update `MetadataTransform` to emit the new metadata
* a simple unit test
Diffstat (limited to 'src/ILCompiler.MetadataTransform')
7 files changed, 99 insertions, 1 deletions
diff --git a/src/ILCompiler.MetadataTransform/MetadataTransform.sln b/src/ILCompiler.MetadataTransform/MetadataTransform.sln index 3294ea789..760eba095 100644 --- a/src/ILCompiler.MetadataTransform/MetadataTransform.sln +++ b/src/ILCompiler.MetadataTransform/MetadataTransform.sln @@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILCompiler.TypeSystem", ".. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILCompiler.MetadataTransform.Tests", "tests\ILCompiler.MetadataTransform.Tests.csproj", "{B4B713D9-68A1-4EB3-8164-4DC8BE69BCBC}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILMetadataAssembly", "tests\ILMetadataAssembly\ILMetadataAssembly.ilproj", "{347E2A5A-54E5-4482-9723-ED460DE79CE8}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PrimaryMetadataAssembly", "tests\PrimaryMetadataAssembly\PrimaryMetadataAssembly.csproj", "{C29B7395-F925-4B0E-972D-187D2D4BFEC7}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleMetadataAssembly", "tests\SampleMetadataAssembly\SampleMetadataAssembly.csproj", "{D29B7395-A925-5B0E-972D-387D2D4BFEC8}" @@ -41,6 +43,10 @@ Global {B4B713D9-68A1-4EB3-8164-4DC8BE69BCBC}.Debug|Any CPU.Build.0 = Debug|Any CPU {B4B713D9-68A1-4EB3-8164-4DC8BE69BCBC}.Release|Any CPU.ActiveCfg = Release|Any CPU {B4B713D9-68A1-4EB3-8164-4DC8BE69BCBC}.Release|Any CPU.Build.0 = Release|Any CPU + {347E2A5A-54E5-4482-9723-ED460DE79CE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {347E2A5A-54E5-4482-9723-ED460DE79CE8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {347E2A5A-54E5-4482-9723-ED460DE79CE8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {347E2A5A-54E5-4482-9723-ED460DE79CE8}.Release|Any CPU.Build.0 = Release|Any CPU {C29B7395-F925-4B0E-972D-187D2D4BFEC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C29B7395-F925-4B0E-972D-187D2D4BFEC7}.Debug|Any CPU.Build.0 = Debug|Any CPU {C29B7395-F925-4B0E-972D-187D2D4BFEC7}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/src/ILCompiler.MetadataTransform/src/ILCompiler/Metadata/Transform.Type.cs b/src/ILCompiler.MetadataTransform/src/ILCompiler/Metadata/Transform.Type.cs index 4178a4d60..326cda3b0 100644 --- a/src/ILCompiler.MetadataTransform/src/ILCompiler/Metadata/Transform.Type.cs +++ b/src/ILCompiler.MetadataTransform/src/ILCompiler/Metadata/Transform.Type.cs @@ -25,6 +25,7 @@ namespace ILCompiler.Metadata private Action<Cts.ArrayType, TypeSpecification> _initArray; private Action<Cts.ByRefType, TypeSpecification> _initByRef; private Action<Cts.PointerType, TypeSpecification> _initPointer; + private Action<Cts.FunctionPointerType, TypeSpecification> _initFunctionPointer; private Action<Cts.TypeDesc, TypeSpecification> _initTypeInst; private Action<Cts.SignatureTypeVariable, TypeSpecification> _initTypeVar; private Action<Cts.SignatureMethodVariable, TypeSpecification> _initMethodVar; @@ -54,7 +55,8 @@ namespace ILCompiler.Metadata rec = _types.Create((Cts.PointerType)type, _initPointer ?? (_initPointer = InitializePointer)); break; case Cts.TypeFlags.FunctionPointer: - throw new NotImplementedException(); + rec = _types.Create((Cts.FunctionPointerType)type, _initFunctionPointer ?? (_initFunctionPointer = InitializeFunctionPointer)); + break; case Cts.TypeFlags.SignatureTypeVariable: rec = _types.Create((Cts.SignatureTypeVariable)type, _initTypeVar ?? (_initTypeVar = InitializeTypeVariable)); break; @@ -128,6 +130,14 @@ namespace ILCompiler.Metadata }; } + private void InitializeFunctionPointer(Cts.FunctionPointerType entity, TypeSpecification record) + { + record.Signature = new FunctionPointerSignature + { + Signature = HandleMethodSignature(entity.Signature) + }; + } + private void InitializeTypeVariable(Cts.SignatureTypeVariable entity, TypeSpecification record) { record.Signature = new TypeVariableSignature diff --git a/src/ILCompiler.MetadataTransform/tests/ILCompiler.MetadataTransform.Tests.csproj b/src/ILCompiler.MetadataTransform/tests/ILCompiler.MetadataTransform.Tests.csproj index c7212126e..ef9e29a0e 100644 --- a/src/ILCompiler.MetadataTransform/tests/ILCompiler.MetadataTransform.Tests.csproj +++ b/src/ILCompiler.MetadataTransform/tests/ILCompiler.MetadataTransform.Tests.csproj @@ -35,6 +35,12 @@ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <Targets>Build;DebugSymbolsProjectOutputGroup</Targets> </ProjectReference> + <ProjectReference Include="ILMetadataAssembly\ILMetadataAssembly.ilproj"> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + <OutputItemType>Content</OutputItemType> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + <Targets>Build</Targets> + </ProjectReference> <ProjectReference Include="SampleMetadataAssembly\SampleMetadataAssembly.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <OutputItemType>Content</OutputItemType> diff --git a/src/ILCompiler.MetadataTransform/tests/ILMetadataAssembly/ILMetadataAssembly.ilproj b/src/ILCompiler.MetadataTransform/tests/ILMetadataAssembly/ILMetadataAssembly.ilproj new file mode 100644 index 000000000..f1001ee6a --- /dev/null +++ b/src/ILCompiler.MetadataTransform/tests/ILMetadataAssembly/ILMetadataAssembly.ilproj @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <OutputType>Library</OutputType> + <AssemblyName>ILMetadataAssembly</AssemblyName> + <ProjectGuid>{347E2A5A-54E5-4482-9723-ED460DE79CE8}</ProjectGuid> + </PropertyGroup> + + <!-- Default configurations to help VS understand the configurations --> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + </PropertyGroup> + + <ItemGroup> + <!-- Main has to be the first file. Do not put anything before Main.il --> + <Compile Include="Main.il" /> + + <Compile Include="TypeWithFunctionPointers.il" /> + </ItemGroup> + + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/src/ILCompiler.MetadataTransform/tests/ILMetadataAssembly/Main.il b/src/ILCompiler.MetadataTransform/tests/ILMetadataAssembly/Main.il new file mode 100644 index 000000000..fda344290 --- /dev/null +++ b/src/ILCompiler.MetadataTransform/tests/ILMetadataAssembly/Main.il @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern PrimaryMetadataAssembly +{ +} + +.assembly ILMetadataAssembly +{ +} + +// Mark this as core library so that ILASM doesn't take the code paths that +// 'fix' all the references to e.g. System.Object to be mscorlib. +.mscorlib diff --git a/src/ILCompiler.MetadataTransform/tests/ILMetadataAssembly/TypeWithFunctionPointers.il b/src/ILCompiler.MetadataTransform/tests/ILMetadataAssembly/TypeWithFunctionPointers.il new file mode 100644 index 000000000..16acdddcf --- /dev/null +++ b/src/ILCompiler.MetadataTransform/tests/ILMetadataAssembly/TypeWithFunctionPointers.il @@ -0,0 +1,9 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.class public auto ansi beforefieldinit SampleMetadata.TypeWithFunctionPointers + extends [PrimaryMetadataAssembly]System.Object +{ + .field private static method object *(object) TheField; +} diff --git a/src/ILCompiler.MetadataTransform/tests/SimpleTests.cs b/src/ILCompiler.MetadataTransform/tests/SimpleTests.cs index 900488123..b1d6d06a6 100644 --- a/src/ILCompiler.MetadataTransform/tests/SimpleTests.cs +++ b/src/ILCompiler.MetadataTransform/tests/SimpleTests.cs @@ -254,5 +254,30 @@ namespace MetadataTransformTests Assert.Equal(iCloneableGenericImplementationMethod, methodImplGenericMethodBody.Method); Assert.Equal(implementsICloneableType, methodImplGenericMethodBody.EnclosingType); } + + [Fact] + public void TestFunctionPointerSignatures() + { + var ilModule = _context.GetModuleForSimpleName("ILMetadataAssembly"); + Cts.MetadataType typeWithFunctionPointers = ilModule.GetType("SampleMetadata", "TypeWithFunctionPointers"); + + var policy = new SingleFileMetadataPolicy(); + var transformResult = MetadataTransform.Run(policy, + new[] { _systemModule, ilModule }); + + var typeWithFunctionPointersType = transformResult.GetTransformedTypeDefinition(typeWithFunctionPointers); + var objectType = transformResult.GetTransformedTypeDefinition((Cts.MetadataType)_context.GetWellKnownType(Cts.WellKnownType.Object)); + + Assert.Equal(1, typeWithFunctionPointersType.Fields.Count); + + var theField = typeWithFunctionPointersType.Fields[0]; + Assert.IsType<TypeSpecification>(theField.Signature.Type); + var theFieldSignature = (TypeSpecification)theField.Signature.Type; + Assert.IsType<FunctionPointerSignature>(theFieldSignature.Signature); + var theFieldPointerSignature = (FunctionPointerSignature)theFieldSignature.Signature; + Assert.Equal(objectType, theFieldPointerSignature.Signature.ReturnType); + Assert.Equal(1, theFieldPointerSignature.Signature.Parameters.Count); + Assert.Equal(objectType, theFieldPointerSignature.Signature.Parameters[0]); + } } }
\ No newline at end of file |