diff options
author | Marek Safar <marek.safar@gmail.com> | 2017-12-14 19:34:06 +0300 |
---|---|---|
committer | Marek Safar <marek.safar@gmail.com> | 2017-12-14 19:34:06 +0300 |
commit | 76ffcdabae660e9586273c9b40db180a0dc8d4c8 (patch) | |
tree | 1a0b35f500240bd4ee56051bd5513a41b91993fe | |
parent | eea46c1a1357010bdc10adbd9d9b49106aa1f4c8 (diff) | |
parent | 1afa0668b38603cdb7197653d73194df749c2d0d (diff) |
Merge commit '1afa0668b38603cdb7197653d73194df749c2d0d' into mono-2017-10mono-2017-10
48 files changed, 691 insertions, 329 deletions
diff --git a/Mono.Cecil.Cil/CodeReader.cs b/Mono.Cecil.Cil/CodeReader.cs index 17376d4..f7f11d5 100644 --- a/Mono.Cecil.Cil/CodeReader.cs +++ b/Mono.Cecil.Cil/CodeReader.cs @@ -45,7 +45,7 @@ namespace Mono.Cecil.Cil { return position; } - void MoveBackTo (int position) + public void MoveBackTo (int position) { this.reader.context = null; this.Position = position; @@ -62,6 +62,30 @@ namespace Mono.Cecil.Cil { return this.body; } + public int ReadCodeSize (MethodDefinition method) + { + var position = MoveTo (method); + + var code_size = ReadCodeSize (); + + MoveBackTo (position); + return code_size; + } + + int ReadCodeSize () + { + var flags = ReadByte (); + switch (flags & 0x3) { + case 0x2: // tiny + return flags >> 2; + case 0x3: // fat + Advance (-1 + 2 + 2); // go back, 2 bytes flags, 2 bytes stack size + return (int) ReadUInt32 (); + default: + throw new InvalidOperationException (); + } + } + void ReadMethodBody () { var flags = ReadByte (); @@ -88,99 +112,6 @@ namespace Mono.Cecil.Cil { ReadDebugInfo (); } - void ReadDebugInfo () - { - if (method.debug_info.sequence_points != null) - ReadSequencePoints (); - - if (method.debug_info.scope != null) - ReadScope (method.debug_info.scope); - - if (method.custom_infos != null) - ReadCustomDebugInformations (method); - } - - void ReadCustomDebugInformations (MethodDefinition method) - { - var custom_infos = method.custom_infos; - - for (int i = 0; i < custom_infos.Count; i++) { - var state_machine_scope = custom_infos [i] as StateMachineScopeDebugInformation; - if (state_machine_scope != null) - ReadStateMachineScope (state_machine_scope); - - var async_method = custom_infos [i] as AsyncMethodBodyDebugInformation; - if (async_method != null) - ReadAsyncMethodBody (async_method); - } - } - - void ReadAsyncMethodBody (AsyncMethodBodyDebugInformation async_method) - { - if (async_method.catch_handler.Offset > -1) - async_method.catch_handler = new InstructionOffset (GetInstruction (async_method.catch_handler.Offset)); - - if (!async_method.yields.IsNullOrEmpty ()) - for (int i = 0; i < async_method.yields.Count; i++) - async_method.yields [i] = new InstructionOffset (GetInstruction (async_method.yields [i].Offset)); - - if (!async_method.resumes.IsNullOrEmpty ()) - for (int i = 0; i < async_method.resumes.Count; i++) - async_method.resumes [i] = new InstructionOffset (GetInstruction (async_method.resumes [i].Offset)); - } - - void ReadStateMachineScope (StateMachineScopeDebugInformation state_machine_scope) - { - state_machine_scope.start = new InstructionOffset (GetInstruction (state_machine_scope.start.Offset)); - - var end_instruction = GetInstruction (state_machine_scope.end.Offset); - state_machine_scope.end = end_instruction == null - ? new InstructionOffset () - : new InstructionOffset (end_instruction); - } - - void ReadSequencePoints () - { - var symbol = method.debug_info; - - for (int i = 0; i < symbol.sequence_points.Count; i++) { - var sequence_point = symbol.sequence_points [i]; - var instruction = GetInstruction (sequence_point.Offset); - if (instruction != null) - sequence_point.offset = new InstructionOffset (instruction); - } - } - - void ReadScopes (Collection<ScopeDebugInformation> scopes) - { - for (int i = 0; i < scopes.Count; i++) - ReadScope (scopes [i]); - } - - void ReadScope (ScopeDebugInformation scope) - { - var start_instruction = GetInstruction (scope.Start.Offset); - if (start_instruction != null) - scope.Start = new InstructionOffset (start_instruction); - - var end_instruction = GetInstruction (scope.End.Offset); - scope.End = end_instruction != null - ? new InstructionOffset (end_instruction) - : new InstructionOffset (); - - if (!scope.variables.IsNullOrEmpty ()) { - for (int i = 0; i < scope.variables.Count; i++) { - var variable_info = scope.variables [i]; - var variable = GetVariable (variable_info.Index); - if (variable != null) - variable_info.index = new VariableIndex (variable); - } - } - - if (!scope.scopes.IsNullOrEmpty ()) - ReadScopes (scope.scopes); - } - void ReadFatMethod () { var flags = ReadUInt16 (); @@ -442,6 +373,104 @@ namespace Mono.Cecil.Cil { return new MetadataToken (ReadUInt32 ()); } + void ReadDebugInfo () + { + if (method.debug_info.sequence_points != null) + ReadSequencePoints (); + + if (method.debug_info.scope != null) + ReadScope (method.debug_info.scope); + + if (method.custom_infos != null) + ReadCustomDebugInformations (method); + } + + void ReadCustomDebugInformations (MethodDefinition method) + { + var custom_infos = method.custom_infos; + + for (int i = 0; i < custom_infos.Count; i++) { + var state_machine_scope = custom_infos [i] as StateMachineScopeDebugInformation; + if (state_machine_scope != null) + ReadStateMachineScope (state_machine_scope); + + var async_method = custom_infos [i] as AsyncMethodBodyDebugInformation; + if (async_method != null) + ReadAsyncMethodBody (async_method); + } + } + + void ReadAsyncMethodBody (AsyncMethodBodyDebugInformation async_method) + { + if (async_method.catch_handler.Offset > -1) + async_method.catch_handler = new InstructionOffset (GetInstruction (async_method.catch_handler.Offset)); + + if (!async_method.yields.IsNullOrEmpty ()) + for (int i = 0; i < async_method.yields.Count; i++) + async_method.yields [i] = new InstructionOffset (GetInstruction (async_method.yields [i].Offset)); + + if (!async_method.resumes.IsNullOrEmpty ()) + for (int i = 0; i < async_method.resumes.Count; i++) + async_method.resumes [i] = new InstructionOffset (GetInstruction (async_method.resumes [i].Offset)); + } + + void ReadStateMachineScope (StateMachineScopeDebugInformation state_machine_scope) + { + if (state_machine_scope.scopes.IsNullOrEmpty ()) + return; + + foreach (var scope in state_machine_scope.scopes) { + scope.start = new InstructionOffset (GetInstruction (scope.start.Offset)); + + var end_instruction = GetInstruction (scope.end.Offset); + scope.end = end_instruction == null + ? new InstructionOffset () + : new InstructionOffset (end_instruction); + } + } + + void ReadSequencePoints () + { + var symbol = method.debug_info; + + for (int i = 0; i < symbol.sequence_points.Count; i++) { + var sequence_point = symbol.sequence_points [i]; + var instruction = GetInstruction (sequence_point.Offset); + if (instruction != null) + sequence_point.offset = new InstructionOffset (instruction); + } + } + + void ReadScopes (Collection<ScopeDebugInformation> scopes) + { + for (int i = 0; i < scopes.Count; i++) + ReadScope (scopes [i]); + } + + void ReadScope (ScopeDebugInformation scope) + { + var start_instruction = GetInstruction (scope.Start.Offset); + if (start_instruction != null) + scope.Start = new InstructionOffset (start_instruction); + + var end_instruction = GetInstruction (scope.End.Offset); + scope.End = end_instruction != null + ? new InstructionOffset (end_instruction) + : new InstructionOffset (); + + if (!scope.variables.IsNullOrEmpty ()) { + for (int i = 0; i < scope.variables.Count; i++) { + var variable_info = scope.variables [i]; + var variable = GetVariable (variable_info.Index); + if (variable != null) + variable_info.index = new VariableIndex (variable); + } + } + + if (!scope.scopes.IsNullOrEmpty ()) + ReadScopes (scope.scopes); + } + #if !READ_ONLY public ByteBuffer PatchRawMethodBody (MethodDefinition method, CodeWriter writer, out int code_size, out MetadataToken local_var_token) diff --git a/Mono.Cecil.Cil/Symbols.cs b/Mono.Cecil.Cil/Symbols.cs index b0ada58..4c4a8b0 100644 --- a/Mono.Cecil.Cil/Symbols.cs +++ b/Mono.Cecil.Cil/Symbols.cs @@ -479,7 +479,7 @@ namespace Mono.Cecil.Cil { internal InstructionOffset catch_handler; internal Collection<InstructionOffset> yields; internal Collection<InstructionOffset> resumes; - internal MethodDefinition move_next; + internal Collection<MethodDefinition> resume_methods; public InstructionOffset CatchHandler { get { return catch_handler; } @@ -494,9 +494,8 @@ namespace Mono.Cecil.Cil { get { return resumes ?? (resumes = new Collection<InstructionOffset> ()); } } - public MethodDefinition MoveNextMethod { - get { return move_next; } - set { move_next = value; } + public Collection<MethodDefinition> ResumeMethods { + get { return resume_methods ?? (resume_methods = new Collection<MethodDefinition> ()); } } public override CustomDebugInformationKind Kind { @@ -524,7 +523,7 @@ namespace Mono.Cecil.Cil { } } - public sealed class StateMachineScopeDebugInformation : CustomDebugInformation { + public sealed class StateMachineScope { internal InstructionOffset start; internal InstructionOffset end; @@ -539,27 +538,39 @@ namespace Mono.Cecil.Cil { set { end = value; } } - public override CustomDebugInformationKind Kind { - get { return CustomDebugInformationKind.StateMachineScope; } - } - - public static Guid KindIdentifier = new Guid ("{6DA9A61E-F8C7-4874-BE62-68BC5630DF71}"); - - internal StateMachineScopeDebugInformation (int start, int end) - : base (KindIdentifier) + internal StateMachineScope (int start, int end) { this.start = new InstructionOffset (start); this.end = new InstructionOffset (end); } - public StateMachineScopeDebugInformation (Instruction start, Instruction end) - : base (KindIdentifier) + public StateMachineScope (Instruction start, Instruction end) { this.start = new InstructionOffset (start); this.end = end != null ? new InstructionOffset (end) : new InstructionOffset (); } } + public sealed class StateMachineScopeDebugInformation : CustomDebugInformation { + + internal Collection<StateMachineScope> scopes; + + public Collection<StateMachineScope> Scopes { + get { return scopes ?? (scopes = new Collection<StateMachineScope> ()); } + } + + public override CustomDebugInformationKind Kind { + get { return CustomDebugInformationKind.StateMachineScope; } + } + + public static Guid KindIdentifier = new Guid ("{6DA9A61E-F8C7-4874-BE62-68BC5630DF71}"); + + public StateMachineScopeDebugInformation () + : base (KindIdentifier) + { + } + } + public sealed class EmbeddedSourceDebugInformation : CustomDebugInformation { internal byte [] content; @@ -671,8 +682,10 @@ namespace Mono.Cecil.Cil { var offset_mapping = new Dictionary<int, SequencePoint> (sequence_points.Count); - for (int i = 0; i < sequence_points.Count; i++) - offset_mapping.Add (sequence_points [i].Offset, sequence_points [i]); + for (int i = 0; i < sequence_points.Count; i++) { + if (!offset_mapping.ContainsKey (sequence_points [i].Offset)) + offset_mapping.Add (sequence_points [i].Offset, sequence_points [i]); + } var instructions = method.Body.Instructions; diff --git a/Mono.Cecil.PE/Image.cs b/Mono.Cecil.PE/Image.cs index 8160f94..d9d182a 100644 --- a/Mono.Cecil.PE/Image.cs +++ b/Mono.Cecil.PE/Image.cs @@ -39,6 +39,7 @@ namespace Mono.Cecil.PE { public uint Timestamp; public ModuleAttributes Attributes; + public DataDirectory Win32Resources; public DataDirectory Debug; public DataDirectory Resources; public DataDirectory StrongName; diff --git a/Mono.Cecil.PE/ImageReader.cs b/Mono.Cecil.PE/ImageReader.cs index f36d2e5..63213f3 100644 --- a/Mono.Cecil.PE/ImageReader.cs +++ b/Mono.Cecil.PE/ImageReader.cs @@ -160,12 +160,18 @@ namespace Mono.Cecil.PE { // ExportTable 8 // ImportTable 8 + + Advance (pe64 ? 56 : 40); + // ResourceTable 8 + + image.Win32Resources = ReadDataDirectory (); + // ExceptionTable 8 // CertificateTable 8 // BaseRelocationTable 8 - Advance (pe64 ? 88 : 72); + Advance (24); // Debug 8 image.Debug = ReadDataDirectory (); diff --git a/Mono.Cecil.PE/ImageWriter.cs b/Mono.Cecil.PE/ImageWriter.cs index 3fc689d..f69e134 100644 --- a/Mono.Cecil.PE/ImageWriter.cs +++ b/Mono.Cecil.PE/ImageWriter.cs @@ -87,21 +87,15 @@ namespace Mono.Cecil.PE { void GetWin32Resources () { - var rsrc = GetImageResourceSection (); - if (rsrc == null) - return; - - win32_resources = module.Image.GetReaderAt (rsrc.VirtualAddress, rsrc.SizeOfRawData, (s, reader) => new ByteBuffer (reader.ReadBytes ((int) s))); - } - - Section GetImageResourceSection () - { if (!module.HasImage) - return null; + return; - const string rsrc_section = ".rsrc"; + DataDirectory win32_resources_directory = module.Image.Win32Resources; + var size = win32_resources_directory.Size; - return module.Image.GetSection (rsrc_section); + if (size > 0) { + win32_resources = module.Image.GetReaderAt (win32_resources_directory.VirtualAddress, size, (s, reader) => new ByteBuffer (reader.ReadBytes ((int) s))); + } } public static ImageWriter CreateWriter (ModuleDefinition module, MetadataBuilder metadata, Disposable<Stream> stream) @@ -846,10 +840,10 @@ namespace Mono.Cecil.PE { void PatchResourceDataEntry (ByteBuffer resources) { - var old_rsrc = GetImageResourceSection (); var rva = resources.ReadUInt32 (); resources.position -= 4; - resources.WriteUInt32 (rva - old_rsrc.VirtualAddress + rsrc.VirtualAddress); + + resources.WriteUInt32 (rva - module.Image.Win32Resources.VirtualAddress + rsrc.VirtualAddress); } } } diff --git a/Mono.Cecil.Tests.props b/Mono.Cecil.Tests.props index e129090..e4a4031 100644 --- a/Mono.Cecil.Tests.props +++ b/Mono.Cecil.Tests.props @@ -2,9 +2,24 @@ <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <BuildDirectory>$(MSBuildProjectDirectory)</BuildDirectory> + <IsTestProject>true</IsTestProject> </PropertyGroup> <Import Project="Mono.Cecil.props" /> - <ItemGroup> + <PropertyGroup Condition="'$(NetStandard)' == 'true'"> + <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> + </PropertyGroup> + <ItemGroup Condition="'$(NetStandard)' == 'true'"> + <PackageReference Include="NUnit"> + <Version>3.7.1</Version> + </PackageReference> + <PackageReference Include="Microsoft.NET.Test.Sdk"> + <Version>15.3.0</Version> + </PackageReference> + <PackageReference Include="NUnit3TestAdapter"> + <Version>3.8.0</Version> + </PackageReference> + </ItemGroup> + <ItemGroup Condition="'$(NetStandard)' != 'true'"> <Reference Include="nunit.core"> <SpecificVersion>False</SpecificVersion> <HintPath>$(MSBuildThisFileDirectory)\Test\libs\nunit-2.6.2\nunit.core.dll</HintPath> @@ -18,4 +33,14 @@ <HintPath>$(MSBuildThisFileDirectory)\Test\libs\nunit-2.6.2\nunit.framework.dll</HintPath> </Reference> </ItemGroup> + <!-- Workaround for https://github.com/Microsoft/msbuild/issues/1310 --> + <Target Name="ForceGenerationOfBindingRedirects" + AfterTargets="ResolveAssemblyReferences" + BeforeTargets="GenerateBindingRedirects" + Condition="'$(AutoGenerateBindingRedirects)' == 'true'"> + <PropertyGroup> + <!-- Needs to be set in a target because it has to be set after the initial evaluation in the common targets --> + <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType> + </PropertyGroup> + </Target> </Project> diff --git a/Mono.Cecil.nuspec b/Mono.Cecil.nuspec index 95ef8b4..4fc12bc 100644 --- a/Mono.Cecil.nuspec +++ b/Mono.Cecil.nuspec @@ -2,7 +2,7 @@ <package xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <metadata xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <id>Mono.Cecil</id> - <version>0.10.0.0-beta6</version> + <version>0.10.0.0-beta7</version> <title>Mono.Cecil</title> <authors>Jb Evain</authors> <owners>Jb Evain</owners> diff --git a/Mono.Cecil.props b/Mono.Cecil.props index da63a2f..366603e 100644 --- a/Mono.Cecil.props +++ b/Mono.Cecil.props @@ -36,18 +36,19 @@ </PropertyGroup> <PropertyGroup Condition=" $(Configuration.StartsWith('net_3_5')) "> <TargetFrameworkVersion>v3.5</TargetFrameworkVersion> - <DefineConstants>$(DefineConstants);</DefineConstants> + <DefineConstants>$(DefineConstants);NET_3_5;</DefineConstants> </PropertyGroup> <PropertyGroup Condition=" $(Configuration.StartsWith('net_4_0')) "> <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> <DefineConstants>$(DefineConstants);NET_4_0;</DefineConstants> </PropertyGroup> - <PropertyGroup Condition=" $(NetStandard) "> - <TargetFramework>netstandard1.3</TargetFramework> + <PropertyGroup Condition="'$(NetStandard)' == 'true'"> + <TargetFramework Condition="'$(IsTestProject)' == 'true'">netcoreapp2.0</TargetFramework> + <TargetFramework Condition="'$(IsTestProject)' != 'true'">netstandard1.3</TargetFramework> </PropertyGroup> - <Import Project="NetStandard.props" Condition=" $(NetStandard) " /> + <Import Project="NetStandard.props" Condition="'$(NetStandard)' == 'true'" /> <!-- Shared References --> - <ItemGroup Condition=" ! $(NetStandard) "> + <ItemGroup Condition="'$(NetStandard)' != 'true'"> <Reference Include="System.Core" /> <Reference Include="System" /> </ItemGroup> diff --git a/Mono.Cecil.sln b/Mono.Cecil.sln index f7ce9ef..a8c436f 100644 --- a/Mono.Cecil.sln +++ b/Mono.Cecil.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio 15 +VisualStudioVersion = 15.0.26927.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{74E5ECE0-06B4-401C-AEBA-E8DD53E17943}" EndProject @@ -22,6 +22,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil.Rocks.Tests", "r EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil.Rocks", "rocks\Mono.Cecil.Rocks.csproj", "{FBC6DD59-D09D-499C-B03C-99C1C78FF2AC}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E0893F44-CB9F-49C5-B38C-70082EFC5072}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution net_3_5_Debug_ReadOnly|Any CPU = net_3_5_Debug_ReadOnly|Any CPU @@ -81,9 +86,11 @@ Global {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Debug_ReadOnly|Any CPU.ActiveCfg = netstandard_Debug_ReadOnly|Any CPU {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Debug_ReadOnly|Any CPU.Build.0 = netstandard_Debug_ReadOnly|Any CPU {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Debug|Any CPU.ActiveCfg = netstandard_Debug|Any CPU + {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Debug|Any CPU.Build.0 = netstandard_Debug|Any CPU {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Release_ReadOnly|Any CPU.ActiveCfg = netstandard_Release_ReadOnly|Any CPU {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Release_ReadOnly|Any CPU.Build.0 = netstandard_Release_ReadOnly|Any CPU {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Release|Any CPU.ActiveCfg = netstandard_Release|Any CPU + {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Release|Any CPU.Build.0 = netstandard_Release|Any CPU {8559DD7F-A16F-46D0-A05A-9139FAEBA8FD}.net_3_5_Debug_ReadOnly|Any CPU.ActiveCfg = net_3_5_Debug_ReadOnly|Any CPU {8559DD7F-A16F-46D0-A05A-9139FAEBA8FD}.net_3_5_Debug_ReadOnly|Any CPU.Build.0 = net_3_5_Debug_ReadOnly|Any CPU {8559DD7F-A16F-46D0-A05A-9139FAEBA8FD}.net_3_5_Debug|Any CPU.ActiveCfg = net_3_5_Debug|Any CPU @@ -125,10 +132,8 @@ Global {AC71DF9C-99FA-4A63-990A-66C8010355A6}.net_4_0_Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU {AC71DF9C-99FA-4A63-990A-66C8010355A6}.net_4_0_Release|Any CPU.Build.0 = net_4_0_Release|Any CPU {AC71DF9C-99FA-4A63-990A-66C8010355A6}.netstandard_Debug_ReadOnly|Any CPU.ActiveCfg = netstandard_Debug_ReadOnly|Any CPU - {AC71DF9C-99FA-4A63-990A-66C8010355A6}.netstandard_Debug_ReadOnly|Any CPU.Build.0 = netstandard_Debug_ReadOnly|Any CPU {AC71DF9C-99FA-4A63-990A-66C8010355A6}.netstandard_Debug|Any CPU.ActiveCfg = netstandard_Debug|Any CPU {AC71DF9C-99FA-4A63-990A-66C8010355A6}.netstandard_Release_ReadOnly|Any CPU.ActiveCfg = netstandard_Release_ReadOnly|Any CPU - {AC71DF9C-99FA-4A63-990A-66C8010355A6}.netstandard_Release_ReadOnly|Any CPU.Build.0 = netstandard_Release_ReadOnly|Any CPU {AC71DF9C-99FA-4A63-990A-66C8010355A6}.netstandard_Release|Any CPU.ActiveCfg = netstandard_Release|Any CPU {63E6915C-7EA4-4D76-AB28-0D7191EEA626}.net_3_5_Debug_ReadOnly|Any CPU.ActiveCfg = net_3_5_Debug_ReadOnly|Any CPU {63E6915C-7EA4-4D76-AB28-0D7191EEA626}.net_3_5_Debug_ReadOnly|Any CPU.Build.0 = net_3_5_Debug_ReadOnly|Any CPU @@ -171,10 +176,8 @@ Global {29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.net_4_0_Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU {29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.net_4_0_Release|Any CPU.Build.0 = net_4_0_Release|Any CPU {29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.netstandard_Debug_ReadOnly|Any CPU.ActiveCfg = netstandard_Debug_ReadOnly|Any CPU - {29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.netstandard_Debug_ReadOnly|Any CPU.Build.0 = netstandard_Debug_ReadOnly|Any CPU {29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.netstandard_Debug|Any CPU.ActiveCfg = netstandard_Debug|Any CPU {29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.netstandard_Release_ReadOnly|Any CPU.ActiveCfg = netstandard_Release_ReadOnly|Any CPU - {29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.netstandard_Release_ReadOnly|Any CPU.Build.0 = netstandard_Release_ReadOnly|Any CPU {29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.netstandard_Release|Any CPU.ActiveCfg = netstandard_Release|Any CPU {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.net_3_5_Debug_ReadOnly|Any CPU.ActiveCfg = net_3_5_Debug_ReadOnly|Any CPU {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.net_3_5_Debug_ReadOnly|Any CPU.Build.0 = net_3_5_Debug_ReadOnly|Any CPU @@ -193,10 +196,8 @@ Global {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.net_4_0_Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.net_4_0_Release|Any CPU.Build.0 = net_4_0_Release|Any CPU {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.netstandard_Debug_ReadOnly|Any CPU.ActiveCfg = netstandard_Debug_ReadOnly|Any CPU - {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.netstandard_Debug_ReadOnly|Any CPU.Build.0 = netstandard_Debug_ReadOnly|Any CPU {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.netstandard_Debug|Any CPU.ActiveCfg = netstandard_Debug|Any CPU {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.netstandard_Release_ReadOnly|Any CPU.ActiveCfg = netstandard_Release_ReadOnly|Any CPU - {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.netstandard_Release_ReadOnly|Any CPU.Build.0 = netstandard_Release_ReadOnly|Any CPU {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.netstandard_Release|Any CPU.ActiveCfg = netstandard_Release|Any CPU {FBC6DD59-D09D-499C-B03C-99C1C78FF2AC}.net_3_5_Debug_ReadOnly|Any CPU.ActiveCfg = net_3_5_Debug_ReadOnly|Any CPU {FBC6DD59-D09D-499C-B03C-99C1C78FF2AC}.net_3_5_Debug_ReadOnly|Any CPU.Build.0 = net_3_5_Debug_ReadOnly|Any CPU @@ -234,4 +235,7 @@ Global {29300103-CB76-4A1D-B6FD-FFD91C1EC8AA} = {74E5ECE0-06B4-401C-AEBA-E8DD53E17943} {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52} = {74E5ECE0-06B4-401C-AEBA-E8DD53E17943} EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D75C0801-AFCB-4B1F-90AD-2B7852A74E6A} + EndGlobalSection EndGlobal diff --git a/Mono.Cecil/AssemblyReader.cs b/Mono.Cecil/AssemblyReader.cs index 02d7787..0be4404 100644 --- a/Mono.Cecil/AssemblyReader.cs +++ b/Mono.Cecil/AssemblyReader.cs @@ -156,7 +156,6 @@ namespace Mono.Cecil { this.module.Read (this.module, (module, reader) => { ReadModuleManifest (reader); ReadModule (module, resolve_attributes: true); - return module; }); } @@ -422,10 +421,7 @@ namespace Mono.Cecil { protected override void ReadModule () { - this.module.Read (this.module, (module, reader) => { - ReadModuleManifest (reader); - return module; - }); + this.module.Read (this.module, (_, reader) => ReadModuleManifest (reader)); } public override void ReadSymbols (ModuleDefinition module) @@ -943,8 +939,8 @@ namespace Mono.Cecil { type.BaseType = GetTypeDefOrRef (ReadMetadataToken (CodedIndex.TypeDefOrRef)); - type.fields_range = ReadFieldsRange (rid); - type.methods_range = ReadMethodsRange (rid); + type.fields_range = ReadListRange (rid, Table.TypeDef, Table.Field); + type.methods_range = ReadListRange (rid, Table.TypeDef, Table.Method); if (IsNested (attributes)) type.DeclaringType = GetNestedTypeDeclaringType (type); @@ -965,21 +961,13 @@ namespace Mono.Cecil { return GetTypeDefinition (declaring_rid); } - Range ReadFieldsRange (uint type_index) - { - return ReadListRange (type_index, Table.TypeDef, Table.Field); - } - - Range ReadMethodsRange (uint type_index) - { - return ReadListRange (type_index, Table.TypeDef, Table.Method); - } - Range ReadListRange (uint current_index, Table current, Table target) { var list = new Range (); - list.Start = ReadTableIndex (target); + var start = ReadTableIndex (target); + if (start == 0) + return list; uint next_index; var current_table = image.TableHeap [current]; @@ -993,7 +981,8 @@ namespace Mono.Cecil { this.position = position; } - list.Length = next_index - list.Start; + list.Start = start; + list.Length = next_index - start; return list; } @@ -1496,16 +1485,11 @@ namespace Mono.Cecil { for (uint i = 1; i <= length; i++) { var type_rid = ReadTableIndex (Table.TypeDef); - Range events_range = ReadEventsRange (i); + Range events_range = ReadListRange (i, Table.EventMap, Table.Event); metadata.AddEventsRange (type_rid, events_range); } } - Range ReadEventsRange (uint rid) - { - return ReadListRange (rid, Table.EventMap, Table.Event); - } - public bool HasProperties (TypeDefinition type) { InitializeProperties (); @@ -1585,16 +1569,11 @@ namespace Mono.Cecil { for (uint i = 1; i <= length; i++) { var type_rid = ReadTableIndex (Table.TypeDef); - var properties_range = ReadPropertiesRange (i); + var properties_range = ReadListRange (i, Table.PropertyMap, Table.Property); metadata.AddPropertiesRange (type_rid, properties_range); } } - Range ReadPropertiesRange (uint rid) - { - return ReadListRange (rid, Table.PropertyMap, Table.Property); - } - MethodSemanticsAttributes ReadMethodSemantics (MethodDefinition method) { InitializeMethodSemantics (); @@ -1697,23 +1676,19 @@ namespace Mono.Cecil { } } - public PropertyDefinition ReadMethods (PropertyDefinition property) + public void ReadMethods (PropertyDefinition property) { ReadAllSemantics (property.DeclaringType); - return property; } - public EventDefinition ReadMethods (EventDefinition @event) + public void ReadMethods (EventDefinition @event) { ReadAllSemantics (@event.DeclaringType); - return @event; } - public MethodSemanticsAttributes ReadAllSemantics (MethodDefinition method) + public void ReadAllSemantics (MethodDefinition method) { ReadAllSemantics (method.DeclaringType); - - return method.SemanticsAttributes; } void ReadAllSemantics (TypeDefinition type) @@ -1729,11 +1704,6 @@ namespace Mono.Cecil { } } - Range ReadParametersRange (uint method_rid) - { - return ReadListRange (method_rid, Table.Method, Table.Param); - } - public Collection<MethodDefinition> ReadMethods (TypeDefinition type) { var methods_range = type.methods_range; @@ -1794,7 +1764,7 @@ namespace Mono.Cecil { methods.Add (method); // attach method var signature = ReadBlobIndex (); - var param_range = ReadParametersRange (method_rid); + var param_range = ReadListRange (method_rid, Table.Method, Table.Param); this.context = method; @@ -2121,6 +2091,11 @@ namespace Mono.Cecil { return code.ReadMethodBody (method); } + public int ReadCodeSize (MethodDefinition method) + { + return code.ReadCodeSize (method); + } + public CallSite ReadCallSite (MetadataToken token) { if (!MoveTo (Table.StandAloneSig, token.RID)) @@ -2387,8 +2362,8 @@ namespace Mono.Cecil { var type_system = module.TypeSystem; - var context = new MethodReference (string.Empty, type_system.Void); - context.DeclaringType = new TypeReference (string.Empty, string.Empty, module, type_system.CoreLibrary); + var context = new MethodDefinition (string.Empty, MethodAttributes.Static, type_system.Void); + context.DeclaringType = new TypeDefinition (string.Empty, string.Empty, TypeAttributes.Public); var member_references = new MemberReference [length]; @@ -3183,25 +3158,36 @@ namespace Mono.Cecil { for (int i = 0; i < rows.Length; i++) { if (rows [i].Col1 == StateMachineScopeDebugInformation.KindIdentifier) { var signature = ReadSignature (rows [i].Col2); - infos.Add (new StateMachineScopeDebugInformation (signature.ReadInt32 (), signature.ReadInt32 ())); + var scopes = new Collection<StateMachineScope> (); + + while (signature.CanReadMore ()) { + var start = signature.ReadInt32 (); + var end = start + signature.ReadInt32 (); + scopes.Add (new StateMachineScope (start, end)); + } + + var state_machine = new StateMachineScopeDebugInformation (); + state_machine.scopes = scopes; + + infos.Add (state_machine); } else if (rows [i].Col1 == AsyncMethodBodyDebugInformation.KindIdentifier) { var signature = ReadSignature (rows [i].Col2); var catch_offset = signature.ReadInt32 () - 1; var yields = new Collection<InstructionOffset> (); var resumes = new Collection<InstructionOffset> (); - uint move_next_rid = 0; + var resume_methods = new Collection<MethodDefinition> (); while (signature.CanReadMore ()) { yields.Add (new InstructionOffset (signature.ReadInt32 ())); resumes.Add (new InstructionOffset (signature.ReadInt32 ())); - move_next_rid = signature.ReadCompressedUInt32 (); + resume_methods.Add (GetMethodDefinition (signature.ReadCompressedUInt32 ())); } var async_body = new AsyncMethodBodyDebugInformation (catch_offset); async_body.yields = yields; async_body.resumes = resumes; - async_body.move_next = GetMethodDefinition (move_next_rid); + async_body.resume_methods = resume_methods; infos.Add (async_body); } else if (rows [i].Col1 == EmbeddedSourceDebugInformation.KindIdentifier) { @@ -3370,7 +3356,7 @@ namespace Mono.Cecil { switch (etype) { case ElementType.ValueType: { var value_type = GetTypeDefOrRef (ReadTypeTokenSignature ()); - value_type.IsValueType = true; + value_type.KnownValueType (); return value_type; } case ElementType.Class: @@ -3410,8 +3396,8 @@ namespace Mono.Cecil { ReadGenericInstanceSignature (element_type, generic_instance); if (is_value_type) { - generic_instance.IsValueType = true; - element_type.GetElementType ().IsValueType = true; + generic_instance.KnownValueType (); + element_type.GetElementType ().KnownValueType (); } return generic_instance; diff --git a/Mono.Cecil/AssemblyWriter.cs b/Mono.Cecil/AssemblyWriter.cs index 5496cac..52c601c 100644 --- a/Mono.Cecil/AssemblyWriter.cs +++ b/Mono.Cecil/AssemblyWriter.cs @@ -2392,13 +2392,19 @@ namespace Mono.Cecil { var method_info = ((MethodDefinition) provider).DebugInformation; var signature = CreateSignatureWriter (); - signature.WriteUInt32 ((uint) state_machine_scope.Start.Offset); - var end_offset = state_machine_scope.End.IsEndOfMethod - ? method_info.code_size - : state_machine_scope.End.Offset; + var scopes = state_machine_scope.Scopes; - signature.WriteUInt32 ((uint) (end_offset - state_machine_scope.Start.Offset)); + for (int i = 0; i < scopes.Count; i++) { + var scope = scopes [i]; + signature.WriteUInt32 ((uint) scope.Start.Offset); + + var end_offset = scope.End.IsEndOfMethod + ? method_info.code_size + : scope.End.Offset; + + signature.WriteUInt32 ((uint) (end_offset - scope.Start.Offset)); + } AddCustomDebugInformation (provider, state_machine_scope, signature); } @@ -2411,7 +2417,7 @@ namespace Mono.Cecil { for (int i = 0; i < async_method.yields.Count; i++) { signature.WriteUInt32 ((uint) async_method.yields [i].Offset); signature.WriteUInt32 ((uint) async_method.resumes [i].Offset); - signature.WriteCompressedUInt32 (async_method.move_next.MetadataToken.RID); + signature.WriteCompressedUInt32 (async_method.resume_methods [i].MetadataToken.RID); } AddCustomDebugInformation (provider, async_method, signature); diff --git a/Mono.Cecil/BaseAssemblyResolver.cs b/Mono.Cecil/BaseAssemblyResolver.cs index ade0102..cf6a3a3 100644 --- a/Mono.Cecil/BaseAssemblyResolver.cs +++ b/Mono.Cecil/BaseAssemblyResolver.cs @@ -11,6 +11,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Reflection; using System.Text; using Mono.Collections.Generic; @@ -65,14 +66,19 @@ namespace Mono.Cecil { #endif } -#if !NET_CORE public abstract class BaseAssemblyResolver : IAssemblyResolver { static readonly bool on_mono = Type.GetType ("Mono.Runtime") != null; readonly Collection<string> directories; +#if NET_CORE + // Maps file names of available trusted platform assemblies to their full paths. + // Internal for testing. + internal static readonly Lazy<Dictionary<string, string>> TrustedPlatformAssemblies = new Lazy<Dictionary<string, string>> (CreateTrustedPlatformAssemblyMap); +#else Collection<string> gac_paths; +#endif public void AddSearchDirectory (string directory) { @@ -127,6 +133,11 @@ namespace Mono.Cecil { }; } +#if NET_CORE + assembly = SearchTrustedPlatformAssemblies (name, parameters); + if (assembly != null) + return assembly; +#else var framework_dir = Path.GetDirectoryName (typeof (object).Module.FullyQualifiedName); var framework_dirs = on_mono ? new [] { framework_dir, Path.Combine (framework_dir, "Facades") } @@ -151,7 +162,7 @@ namespace Mono.Cecil { assembly = SearchDirectory (name, framework_dirs, parameters); if (assembly != null) return assembly; - +#endif if (ResolveFailure != null) { assembly = ResolveFailure (this, name); if (assembly != null) @@ -161,7 +172,45 @@ namespace Mono.Cecil { throw new AssemblyResolutionException (name); } - AssemblyDefinition SearchDirectory (AssemblyNameReference name, IEnumerable<string> directories, ReaderParameters parameters) +#if NET_CORE + AssemblyDefinition SearchTrustedPlatformAssemblies (AssemblyNameReference name, ReaderParameters parameters) + { + if (name.IsWindowsRuntime) + return null; + + if (TrustedPlatformAssemblies.Value.TryGetValue (name.Name, out string path)) + return GetAssembly (path, parameters); + + return null; + } + + static Dictionary<string, string> CreateTrustedPlatformAssemblyMap () + { + var result = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase); + + string paths; + + try { + // AppContext is only available on platforms that implement .NET Standard 1.6 + var appContextType = Type.GetType ("System.AppContext, System.AppContext, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false); + var getData = appContextType?.GetTypeInfo ().GetDeclaredMethod ("GetData"); + paths = (string) getData?.Invoke (null, new [] { "TRUSTED_PLATFORM_ASSEMBLIES" }); + } catch { + paths = null; + } + + if (paths == null) + return result; + + foreach (var path in paths.Split (Path.PathSeparator)) + if (string.Equals (Path.GetExtension (path), ".dll", StringComparison.OrdinalIgnoreCase)) + result [Path.GetFileNameWithoutExtension (path)] = path; + + return result; + } +#endif + + protected virtual AssemblyDefinition SearchDirectory (AssemblyNameReference name, IEnumerable<string> directories, ReaderParameters parameters) { var extensions = name.IsWindowsRuntime ? new [] { ".winmd", ".dll" } : new [] { ".exe", ".dll" }; foreach (var directory in directories) { @@ -185,11 +234,11 @@ namespace Mono.Cecil { return version.Major == 0 && version.Minor == 0 && version.Build == 0 && version.Revision == 0; } +#if !NET_CORE AssemblyDefinition GetCorlib (AssemblyNameReference reference, ReaderParameters parameters) { var version = reference.Version; var corlib = typeof (object).Assembly.GetName (); - if (corlib.Version == version || IsZero (version)) return GetAssembly (typeof (object).Module.FullyQualifiedName, parameters); @@ -325,7 +374,7 @@ namespace Mono.Cecil { return null; } - +#endif static string GetAssemblyFile (AssemblyNameReference reference, string prefix, string gac) { var gac_folder = new StringBuilder () @@ -352,5 +401,4 @@ namespace Mono.Cecil { { } } -#endif } diff --git a/Mono.Cecil/CustomAttribute.cs b/Mono.Cecil/CustomAttribute.cs index 5e33667..135f8b7 100644 --- a/Mono.Cecil/CustomAttribute.cs +++ b/Mono.Cecil/CustomAttribute.cs @@ -62,8 +62,10 @@ namespace Mono.Cecil { bool HasFields { get; } bool HasProperties { get; } + bool HasConstructorArguments { get; } Collection<CustomAttributeNamedArgument> Fields { get; } Collection<CustomAttributeNamedArgument> Properties { get; } + Collection<CustomAttributeArgument> ConstructorArguments { get; } } public sealed class CustomAttribute : ICustomAttribute { @@ -196,7 +198,6 @@ namespace Mono.Cecil { resolved = false; } - return this; }); } } diff --git a/Mono.Cecil/DefaultAssemblyResolver.cs b/Mono.Cecil/DefaultAssemblyResolver.cs index 197aaa0..755071e 100644 --- a/Mono.Cecil/DefaultAssemblyResolver.cs +++ b/Mono.Cecil/DefaultAssemblyResolver.cs @@ -8,8 +8,6 @@ // Licensed under the MIT/X11 license. // -#if !NET_CORE - using System; using System.Collections.Generic; @@ -61,5 +59,3 @@ namespace Mono.Cecil { } } } - -#endif diff --git a/Mono.Cecil/MethodDefinition.cs b/Mono.Cecil/MethodDefinition.cs index 71de613..5dda999 100644 --- a/Mono.Cecil/MethodDefinition.cs +++ b/Mono.Cecil/MethodDefinition.cs @@ -143,9 +143,9 @@ namespace Mono.Cecil { public MethodBody Body { get { - MethodBody localBody = this.body; - if (localBody != null) - return localBody; + var local = this.body; + if (local != null) + return local; if (!HasBody) return null; diff --git a/Mono.Cecil/ModuleDefinition.cs b/Mono.Cecil/ModuleDefinition.cs index 137691c..d82db4e 100644 --- a/Mono.Cecil/ModuleDefinition.cs +++ b/Mono.Cecil/ModuleDefinition.cs @@ -418,13 +418,11 @@ namespace Mono.Cecil { public IAssemblyResolver AssemblyResolver { get { -#if !NET_CORE if (assembly_resolver.value == null) { lock (module_lock) { assembly_resolver = Disposable.Owned (new DefaultAssemblyResolver () as IAssemblyResolver); } } -#endif return assembly_resolver.value; } @@ -754,28 +752,16 @@ namespace Mono.Cecil { internal FieldDefinition Resolve (FieldReference field) { -#if NET_CORE - if (MetadataResolver == null) - throw new NotSupportedException (); -#endif return MetadataResolver.Resolve (field); } internal MethodDefinition Resolve (MethodReference method) { -#if NET_CORE - if (MetadataResolver == null) - throw new NotSupportedException (); -#endif return MetadataResolver.Resolve (method); } internal TypeDefinition Resolve (TypeReference type) { -#if NET_CORE - if (MetadataResolver == null) - throw new NotSupportedException (); -#endif return MetadataResolver.Resolve (type); } @@ -970,6 +956,19 @@ namespace Mono.Cecil { get { return module_lock; } } + internal void Read<TItem> (TItem item, Action<TItem, MetadataReader> read) + { + lock (module_lock) { + var position = reader.position; + var context = reader.context; + + read (item, reader); + + reader.position = position; + reader.context = context; + } + } + internal TRet Read<TItem, TRet> (TItem item, Func<TItem, MetadataReader, TRet> read) { lock (module_lock) { @@ -1321,6 +1320,9 @@ namespace Mono.Cecil { public static TargetRuntime ParseRuntime (this string self) { + if (string.IsNullOrEmpty (self)) + return TargetRuntime.Net_4_0; + switch (self [1]) { case '1': return self [3] == '0' diff --git a/Mono.Cecil/SecurityDeclaration.cs b/Mono.Cecil/SecurityDeclaration.cs index 309f7d2..2762d08 100644 --- a/Mono.Cecil/SecurityDeclaration.cs +++ b/Mono.Cecil/SecurityDeclaration.cs @@ -70,6 +70,14 @@ namespace Mono.Cecil { { this.attribute_type = attributeType; } + + bool ICustomAttribute.HasConstructorArguments { + get { return false; } + } + + Collection<CustomAttributeArgument> ICustomAttribute.ConstructorArguments { + get { throw new NotSupportedException (); } + } } public sealed class SecurityDeclaration { @@ -143,11 +151,7 @@ namespace Mono.Cecil { if (resolved || !HasImage) return; - module.Read (this, (declaration, reader) => { - reader.ReadSecurityDeclarationSignature (declaration); - return this; - }); - + module.Read (this, (declaration, reader) => reader.ReadSecurityDeclarationSignature (declaration)); resolved = true; } } diff --git a/Mono.Cecil/TypeDefinition.cs b/Mono.Cecil/TypeDefinition.cs index 3e4928c..6b6558c 100644 --- a/Mono.Cecil/TypeDefinition.cs +++ b/Mono.Cecil/TypeDefinition.cs @@ -416,6 +416,9 @@ namespace Mono.Cecil { return base_type.IsTypeOf ("System", "Enum") || (base_type.IsTypeOf ("System", "ValueType") && !this.IsTypeOf ("System", "Enum")); } + set { + throw new NotSupportedException (); + } } public override bool IsPrimitive { diff --git a/Mono.Cecil/TypeSystem.cs b/Mono.Cecil/TypeSystem.cs index 3b5202c..e16ec6f 100644 --- a/Mono.Cecil/TypeSystem.cs +++ b/Mono.Cecil/TypeSystem.cs @@ -184,7 +184,7 @@ namespace Mono.Cecil { return typeRef; var type = LookupType ("System", name); type.etype = element_type; - type.IsValueType = true; + type.KnownValueType (); return typeRef = type; } } @@ -313,6 +313,12 @@ namespace Mono.Cecil { return true; } + public static void KnownValueType (this TypeReference type) + { + if (!type.IsDefinition) + type.IsValueType = true; + } + static bool IsCoreLibrary (AssemblyNameReference reference) { var name = reference.Name; diff --git a/Mono/Type.cs b/Mono/Type.cs index 4ff2048..fd53f81 100644 --- a/Mono/Type.cs +++ b/Mono/Type.cs @@ -100,7 +100,8 @@ namespace Mono { public static Type [] GetGenericArguments (this Type type) { #if NET_CORE - return type.GetTypeInfo ().GenericTypeArguments; + var info = type.GetTypeInfo (); + return info.IsGenericTypeDefinition ? info.GenericTypeParameters : info.GenericTypeArguments; #else return type.GetGenericArguments (); #endif diff --git a/NetStandard.props b/NetStandard.props index d5f4196..bc0bacc 100644 --- a/NetStandard.props +++ b/NetStandard.props @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <DefineConstants>$(DefineConstants);NET_4_0;NET_CORE;</DefineConstants> + <DefineConstants>$(DefineConstants);NET_CORE;</DefineConstants> <EnableDefaultCompileItems>false</EnableDefaultCompileItems> <GenerateAssemblyInfo>false</GenerateAssemblyInfo> <PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign> diff --git a/ProjectInfo.cs b/ProjectInfo.cs index 4d9e922..0b94141 100644 --- a/ProjectInfo.cs +++ b/ProjectInfo.cs @@ -17,4 +17,4 @@ using System.Runtime.InteropServices; [assembly: AssemblyVersion ("0.10.0.0")] [assembly: AssemblyFileVersion ("0.10.0.0")] -[assembly: AssemblyInformationalVersion ("0.10.0.0-beta6")] +[assembly: AssemblyInformationalVersion ("0.10.0.0-beta7")] diff --git a/Test/Mono.Cecil.Tests.csproj b/Test/Mono.Cecil.Tests.csproj index 9277d6a..a8c4d0e 100644 --- a/Test/Mono.Cecil.Tests.csproj +++ b/Test/Mono.Cecil.Tests.csproj @@ -1,10 +1,34 @@ <?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\Mono.Cecil.Tests.props" /> <PropertyGroup> <ProjectGuid>{A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}</ProjectGuid> <RootNamespace>Mono.Cecil.Tests</RootNamespace> <AssemblyName>Mono.Cecil.Tests</AssemblyName> </PropertyGroup> + <ItemGroup Condition="'$(NetStandard)' == 'true'"> + <PackageReference Include="System.Reflection.TypeExtensions"> + <Version>4.3.0</Version> + </PackageReference> + <PackageReference Include="System.Diagnostics.Process"> + <Version>4.3.0</Version> + </PackageReference> + <PackageReference Include="System.Diagnostics.StackTrace"> + <Version>4.3.0</Version> + </PackageReference> + <PackageReference Include="System.Diagnostics.FileVersionInfo"> + <Version>4.3.0</Version> + </PackageReference> + <PackageReference Include="System.Runtime.Loader"> + <Version>4.3.0</Version> + </PackageReference> + <PackageReference Include="Microsoft.CodeAnalysis.CSharp"> + <Version>2.3.2</Version> + </PackageReference> + <PackageReference Include="Microsoft.CodeAnalysis.VisualBasic"> + <Version>2.3.2</Version> + </PackageReference> + </ItemGroup> <ItemGroup> <ProjectReference Include="..\Mono.Cecil.csproj"> <Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project> @@ -26,6 +50,5 @@ <ItemGroup> <None Include="Resources\**\*" /> </ItemGroup> - <Import Project="..\Mono.Cecil.Tests.props" /> - <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" Condition="'$(NetStandard)' != 'true'" /> </Project>
\ No newline at end of file diff --git a/Test/Mono.Cecil.Tests/AssemblyTests.cs b/Test/Mono.Cecil.Tests/AssemblyTests.cs index 0d484de..af45a3c 100644 --- a/Test/Mono.Cecil.Tests/AssemblyTests.cs +++ b/Test/Mono.Cecil.Tests/AssemblyTests.cs @@ -59,6 +59,9 @@ namespace Mono.Cecil.Tests { [Test] public void Retargetable () { + if (Platform.OnCoreClr) + return; + TestModule ("RetargetableExample.dll", module => { var type = module.Types [1]; var property = type.Properties [0]; @@ -76,6 +79,9 @@ namespace Mono.Cecil.Tests { [Test] public void SystemRuntime () { + if (Platform.OnCoreClr) + return; + TestModule ("System.Runtime.dll", module => { Assert.AreEqual ("System.Runtime", module.Assembly.Name.Name); Assert.AreEqual (1, module.AssemblyReferences.Count); diff --git a/Test/Mono.Cecil.Tests/CallerMemberNameAttribute.cs b/Test/Mono.Cecil.Tests/CallerMemberNameAttribute.cs new file mode 100644 index 0000000..63bd9b8 --- /dev/null +++ b/Test/Mono.Cecil.Tests/CallerMemberNameAttribute.cs @@ -0,0 +1,10 @@ +#if NET_3_5 || NET_4_0 +namespace System.Runtime.CompilerServices { + [AttributeUsage (AttributeTargets.Parameter, Inherited = false)] + public sealed class CallerMemberNameAttribute : Attribute { + public CallerMemberNameAttribute () + { + } + } +} +#endif
\ No newline at end of file diff --git a/Test/Mono.Cecil.Tests/CompilationService.cs b/Test/Mono.Cecil.Tests/CompilationService.cs index 877ed24..5501d57 100644 --- a/Test/Mono.Cecil.Tests/CompilationService.cs +++ b/Test/Mono.Cecil.Tests/CompilationService.cs @@ -4,9 +4,16 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; - +using System.Reflection; using NUnit.Framework; +#if NET_CORE +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Emit; +using CS = Microsoft.CodeAnalysis.CSharp; +using VB = Microsoft.CodeAnalysis.VisualBasic; +#endif + namespace Mono.Cecil.Tests { struct CompilationResult { @@ -22,7 +29,23 @@ namespace Mono.Cecil.Tests { public static class Platform { - public static bool OnMono { get { return typeof (object).Assembly.GetType ("Mono.Runtime") != null; } } + public static bool OnMono { + get { return TryGetType ("Mono.Runtime") != null; } + } + + public static bool OnCoreClr { + get { return TryGetType ("System.Runtime.Loader.AssemblyLoadContext, System.Runtime.Loader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") != null; } + } + + static Type TryGetType (string assemblyQualifiedName) + { + try { + // Note that throwOnError=false only suppresses some exceptions, not all. + return Type.GetType(assemblyQualifiedName, throwOnError: false); + } catch { + return null; + } + } } abstract class CompilationService { @@ -68,8 +91,11 @@ namespace Mono.Cecil.Tests { return IlasmCompilationService.Instance.Compile (name); if (extension == ".cs" || extension == ".vb") +#if NET_CORE + return RoslynCompilationService.Instance.Compile (name); +#else return CodeDomCompilationService.Instance.Compile (name); - +#endif throw new NotSupportedException (extension); } @@ -84,9 +110,11 @@ namespace Mono.Cecil.Tests { public static void Verify (string name) { +#if !NET_CORE var output = Platform.OnMono ? ShellService.PEDump (name) : ShellService.PEVerify (name); if (output.ExitCode != 0) Assert.Fail (output.ToString ()); +#endif } } @@ -112,6 +140,76 @@ namespace Mono.Cecil.Tests { } } +#if NET_CORE + + class RoslynCompilationService : CompilationService { + + public static readonly RoslynCompilationService Instance = new RoslynCompilationService (); + + protected override string CompileFile (string name) + { + var compilation = GetCompilation (name); + var outputName = GetCompiledFilePath (name); + + var result = compilation.Emit (outputName); + Assert.IsTrue (result.Success, GetErrorMessage (result)); + + return outputName; + } + + static Compilation GetCompilation (string name) + { + var assemblyName = Path.GetFileNameWithoutExtension (name); + var source = File.ReadAllText (name); + + var tpa = BaseAssemblyResolver.TrustedPlatformAssemblies.Value; + + var references = new [] + { + MetadataReference.CreateFromFile (tpa ["netstandard"]), + MetadataReference.CreateFromFile (tpa ["mscorlib"]), + MetadataReference.CreateFromFile (tpa ["System.Private.CoreLib"]), + MetadataReference.CreateFromFile (tpa ["System.Runtime"]), + MetadataReference.CreateFromFile (tpa ["System.Console"]), + MetadataReference.CreateFromFile (tpa ["System.Security.AccessControl"]), + }; + + var extension = Path.GetExtension (name); + switch (extension) { + case ".cs": + return CS.CSharpCompilation.Create ( + assemblyName, + new [] { CS.SyntaxFactory.ParseSyntaxTree (source) }, + references, + new CS.CSharpCompilationOptions (OutputKind.DynamicallyLinkedLibrary, optimizationLevel: OptimizationLevel.Release)); + + case ".vb": + return VB.VisualBasicCompilation.Create ( + assemblyName, + new [] { VB.SyntaxFactory.ParseSyntaxTree (source) }, + references, + new VB.VisualBasicCompilationOptions (OutputKind.DynamicallyLinkedLibrary, optimizationLevel: OptimizationLevel.Release)); + + default: + throw new NotSupportedException (); + } + } + + static string GetErrorMessage (EmitResult result) + { + if (result.Success) + return string.Empty; + + var builder = new StringBuilder (); + foreach (var diagnostic in result.Diagnostics) + builder.AppendLine (diagnostic.ToString ()); + + return builder.ToString (); + } + } + +#else + class CodeDomCompilationService : CompilationService { public static readonly CodeDomCompilationService Instance = new CodeDomCompilationService (); @@ -166,6 +264,8 @@ namespace Mono.Cecil.Tests { } } +#endif + class ShellService { public class ProcessOutput { @@ -243,9 +343,13 @@ namespace Mono.Cecil.Tests { static string NetFrameworkTool (string tool) { +#if NET_CORE + return Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.Windows), "Microsoft.NET", "Framework", "v4.0.30319", tool + ".exe"); +#else return Path.Combine ( Path.GetDirectoryName (typeof (object).Assembly.Location), tool + ".exe"); +#endif } static string WinSdkTool (string tool) diff --git a/Test/Mono.Cecil.Tests/CustomAttributesTests.cs b/Test/Mono.Cecil.Tests/CustomAttributesTests.cs index a89fcfd..8ec0270 100644 --- a/Test/Mono.Cecil.Tests/CustomAttributesTests.cs +++ b/Test/Mono.Cecil.Tests/CustomAttributesTests.cs @@ -21,15 +21,15 @@ namespace Mono.Cecil.Tests { TestCSharp ("CustomAttributes.cs", module => { var hamster = module.GetType ("Hamster"); - Assert.IsTrue (hamster.HasCustomAttributes); - Assert.AreEqual (1, hamster.CustomAttributes.Count); + Assert.IsTrue (hamster.HasCustomAttributes); + Assert.AreEqual (1, hamster.CustomAttributes.Count); - var attribute = hamster.CustomAttributes [0]; - Assert.AreEqual ("System.Void FooAttribute::.ctor(System.String)", - attribute.Constructor.FullName); + var attribute = hamster.CustomAttributes [0]; + Assert.AreEqual ("System.Void FooAttribute::.ctor(System.String)", + attribute.Constructor.FullName); - Assert.IsTrue (attribute.HasConstructorArguments); - Assert.AreEqual (1, attribute.ConstructorArguments.Count); + Assert.IsTrue (attribute.HasConstructorArguments); + Assert.AreEqual (1, attribute.ConstructorArguments.Count); AssertArgument ("bar", attribute.ConstructorArguments [0]); }); @@ -559,10 +559,10 @@ namespace Mono.Cecil.Tests { } switch (Type.GetTypeCode (value.GetType ())) { - case TypeCode.String: + case System.TypeCode.String: signature.AppendFormat ("\"{0}\"", value); break; - case TypeCode.Char: + case System.TypeCode.Char: signature.AppendFormat ("'{0}'", (char) value); break; default: diff --git a/Test/Mono.Cecil.Tests/ImageReadTests.cs b/Test/Mono.Cecil.Tests/ImageReadTests.cs index 16f89d2..16b8a7b 100644 --- a/Test/Mono.Cecil.Tests/ImageReadTests.cs +++ b/Test/Mono.Cecil.Tests/ImageReadTests.cs @@ -170,6 +170,7 @@ namespace Mono.Cecil.Tests { }, verify: false); } +#if !NET_CORE [Test] public void WindowsRuntimeComponentAssembly () { @@ -181,7 +182,7 @@ namespace Mono.Cecil.Tests { Assert.IsTrue (module.Assembly.Name.IsWindowsRuntime); }, verify: false, assemblyResolver: resolver); } - +#endif [Test] public void DeterministicAssembly () { diff --git a/Test/Mono.Cecil.Tests/ImportCecilTests.cs b/Test/Mono.Cecil.Tests/ImportCecilTests.cs index a28b093..bc12f5e 100644 --- a/Test/Mono.Cecil.Tests/ImportCecilTests.cs +++ b/Test/Mono.Cecil.Tests/ImportCecilTests.cs @@ -1,7 +1,6 @@ #if !READ_ONLY using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; using SR = System.Reflection; @@ -255,6 +254,9 @@ namespace Mono.Cecil.Tests { [Test] public void ContextGenericTest () { + if (Platform.OnCoreClr) + return; + var module = ModuleDefinition.ReadModule (typeof (ContextGeneric1Method2<>).Module.FullyQualifiedName); // by mixing open generics with 2 & 1 parameters, we make sure the right context is used (because otherwise, an exception will be thrown) var type = typeof (ContextGeneric1Method2<>).MakeGenericType (typeof (ContextGeneric2Method1<,>)); @@ -287,11 +289,10 @@ namespace Mono.Cecil.Tests { delegate void Emitter (ModuleDefinition module, MethodBody body); - [MethodImpl (MethodImplOptions.NoInlining)] - static TDelegate Compile<TDelegate> (Emitter emitter) + static TDelegate Compile<TDelegate> (Emitter emitter, [CallerMemberName] string testMethodName = null) where TDelegate : class { - var name = GetTestCaseName (); + var name = "ImportCecil_" + testMethodName; var module = CreateTestModule<TDelegate> (name, emitter); var assembly = LoadTestModule (module); @@ -362,15 +363,6 @@ namespace Mono.Cecil.Tests { { return ModuleDefinition.CreateModule (name, ModuleKind.Dll); } - - [MethodImpl (MethodImplOptions.NoInlining)] - static string GetTestCaseName () - { - var stack_trace = new StackTrace (); - var stack_frame = stack_trace.GetFrame (2); - - return "ImportCecil_" + stack_frame.GetMethod ().Name; - } } } -#endif
\ No newline at end of file +#endif diff --git a/Test/Mono.Cecil.Tests/ImportReflectionTests.cs b/Test/Mono.Cecil.Tests/ImportReflectionTests.cs index 0476861..c99ca4f 100644 --- a/Test/Mono.Cecil.Tests/ImportReflectionTests.cs +++ b/Test/Mono.Cecil.Tests/ImportReflectionTests.cs @@ -1,7 +1,6 @@ #if !READ_ONLY using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using SR = System.Reflection; using System.Runtime.CompilerServices; @@ -156,6 +155,9 @@ namespace Mono.Cecil.Tests { [Test] public void ImportGenericField () { + if (Platform.OnCoreClr) + return; + var get_field = Compile<Func<Generic<string>, string>> ((module, body) => { var il = body.GetILProcessor (); il.Emit (OpCodes.Ldarg_0); @@ -173,6 +175,9 @@ namespace Mono.Cecil.Tests { [Test] public void ImportGenericMethod () { + if (Platform.OnCoreClr) + return; + var generic_identity = Compile<Func<Generic<int>, int, int>> ((module, body) => { var il = body.GetILProcessor (); il.Emit (OpCodes.Ldarg_0); @@ -187,6 +192,9 @@ namespace Mono.Cecil.Tests { [Test] public void ImportGenericMethodSpec () { + if (Platform.OnCoreClr) + return; + var gen_spec_id = Compile<Func<Generic<string>, int, int>> ((module, body) => { var il = body.GetILProcessor (); il.Emit (OpCodes.Ldarg_0); @@ -202,6 +210,9 @@ namespace Mono.Cecil.Tests { [Test] public void ImportComplexGenericMethodSpec () { + if (Platform.OnCoreClr) + return; + var gen_spec_id = Compile<Func<Generic<string>, int, int>> ((module, body) => { var il = body.GetILProcessor (); il.Emit (OpCodes.Ldarg_0); @@ -279,6 +290,9 @@ namespace Mono.Cecil.Tests { [Test] public void ImportGenericFieldFromContext () { + if (Platform.OnCoreClr) + return; + var list_foo = typeof (Foo<>).GetField ("list").FieldType; var generic_list_foo_open = typeof (Generic<>).MakeGenericType (list_foo); var generic_list_foo_open_field = generic_list_foo_open.GetField ("Field"); @@ -295,6 +309,9 @@ namespace Mono.Cecil.Tests { [Test] public void ImportGenericMethodFromContext () { + if (Platform.OnCoreClr) + return; + var list_foo = typeof (Foo<>).GetField ("list").FieldType; var generic_list_foo_open = typeof (Generic<>).MakeGenericType (list_foo); var generic_list_foo_open_method = generic_list_foo_open.GetMethod ("Method"); @@ -334,11 +351,10 @@ namespace Mono.Cecil.Tests { delegate void Emitter (ModuleDefinition module, MethodBody body); - [MethodImpl (MethodImplOptions.NoInlining)] - static TDelegate Compile<TDelegate> (Emitter emitter) + static TDelegate Compile<TDelegate> (Emitter emitter, [CallerMemberName] string testMethodName = null) where TDelegate : class { - var name = GetTestCaseName (); + var name = "ImportReflection_" + testMethodName; var module = CreateTestModule<TDelegate> (name, emitter); var assembly = LoadTestModule (module); @@ -409,15 +425,6 @@ namespace Mono.Cecil.Tests { { return ModuleDefinition.CreateModule (name, ModuleKind.Dll); } - - [MethodImpl (MethodImplOptions.NoInlining)] - static string GetTestCaseName () - { - var stack_trace = new StackTrace (); - var stack_frame = stack_trace.GetFrame (2); - - return "ImportReflection_" + stack_frame.GetMethod ().Name; - } } } -#endif
\ No newline at end of file +#endif diff --git a/Test/Mono.Cecil.Tests/MethodTests.cs b/Test/Mono.Cecil.Tests/MethodTests.cs index bbf1742..b878613 100644 --- a/Test/Mono.Cecil.Tests/MethodTests.cs +++ b/Test/Mono.Cecil.Tests/MethodTests.cs @@ -204,6 +204,8 @@ namespace Mono.Cecil.Tests { var beta = type.GetMethod ("Beta"); var charlie = type.GetMethod ("Charlie"); + // Note that the test depends on the C# compiler emitting the constructor call instruction as + // the first instruction of the method body. This requires optimizations to be enabled. var new_list_beta = (MethodReference) beta.Body.Instructions [0].Operand; var new_list_charlie = (MethodReference) charlie.Body.Instructions [0].Operand; diff --git a/Test/Mono.Cecil.Tests/ModuleTests.cs b/Test/Mono.Cecil.Tests/ModuleTests.cs index 476b8ff..2b8eda1 100644 --- a/Test/Mono.Cecil.Tests/ModuleTests.cs +++ b/Test/Mono.Cecil.Tests/ModuleTests.cs @@ -49,7 +49,10 @@ namespace Mono.Cecil.Tests { [Test] public void MultiModules () { - TestModule ("mma.exe", module => { + if (Platform.OnCoreClr) + return; + + TestModule("mma.exe", module => { var assembly = module.Assembly; Assert.AreEqual (3, assembly.Modules.Count); @@ -157,6 +160,9 @@ namespace Mono.Cecil.Tests { [Test] public void ExportedTypeFromNetModule () { + if (Platform.OnCoreClr) + return; + TestModule ("mma.exe", module => { Assert.IsTrue (module.HasExportedTypes); Assert.AreEqual (2, module.ExportedTypes.Count); @@ -183,14 +189,14 @@ namespace Mono.Cecil.Tests { var exported_type = module.ExportedTypes [0]; Assert.AreEqual ("System.Diagnostics.DebuggableAttribute", exported_type.FullName); - Assert.AreEqual ("mscorlib", exported_type.Scope.Name); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", exported_type.Scope.Name); Assert.IsTrue (exported_type.IsForwarder); var nested_exported_type = module.ExportedTypes [1]; Assert.AreEqual ("System.Diagnostics.DebuggableAttribute/DebuggingModes", nested_exported_type.FullName); Assert.AreEqual (exported_type, nested_exported_type.DeclaringType); - Assert.AreEqual ("mscorlib", nested_exported_type.Scope.Name); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", nested_exported_type.Scope.Name); }); } @@ -199,7 +205,7 @@ namespace Mono.Cecil.Tests { { TestCSharp ("CustomAttributes.cs", module => { Assert.IsTrue (module.HasTypeReference ("System.Attribute")); - Assert.IsTrue (module.HasTypeReference ("mscorlib", "System.Attribute")); + Assert.IsTrue (module.HasTypeReference (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", "System.Attribute")); Assert.IsFalse (module.HasTypeReference ("System.Core", "System.Attribute")); Assert.IsFalse (module.HasTypeReference ("System.Linq.Enumerable")); @@ -234,10 +240,9 @@ namespace Mono.Cecil.Tests { } [Test] - [ExpectedException (typeof (BadImageFormatException))] public void OpenIrrelevantFile () { - GetResourceModule ("text_file.txt"); + Assert.Throws<BadImageFormatException> (() => GetResourceModule ("text_file.txt")); } [Test] @@ -273,7 +278,8 @@ namespace Mono.Cecil.Tests { { using (var module = ModuleDefinition.ReadModule (file)) { - Assert.IsNotNullOrEmpty (module.FileName); + Assert.IsNotNull (module.FileName); + Assert.IsNotEmpty (module.FileName); Assert.AreEqual (path, module.FileName); } } diff --git a/Test/Mono.Cecil.Tests/PortablePdbTests.cs b/Test/Mono.Cecil.Tests/PortablePdbTests.cs index 2e73eec..25ee2d1 100644 --- a/Test/Mono.Cecil.Tests/PortablePdbTests.cs +++ b/Test/Mono.Cecil.Tests/PortablePdbTests.cs @@ -320,8 +320,15 @@ namespace Mono.Cecil.Tests { var state_machine_scope = move_next.CustomDebugInformations.OfType<StateMachineScopeDebugInformation> ().FirstOrDefault (); Assert.IsNotNull (state_machine_scope); - Assert.AreEqual (0, state_machine_scope.Start.Offset); - Assert.IsTrue (state_machine_scope.End.IsEndOfMethod); + Assert.AreEqual (3, state_machine_scope.Scopes.Count); + Assert.AreEqual (0, state_machine_scope.Scopes [0].Start.Offset); + Assert.IsTrue (state_machine_scope.Scopes [0].End.IsEndOfMethod); + + Assert.AreEqual (0, state_machine_scope.Scopes [1].Start.Offset); + Assert.AreEqual (0, state_machine_scope.Scopes [1].End.Offset); + + Assert.AreEqual (184, state_machine_scope.Scopes [2].Start.Offset); + Assert.AreEqual (343, state_machine_scope.Scopes [2].End.Offset); var async_body = move_next.CustomDebugInformations.OfType<AsyncMethodBodyDebugInformation> ().FirstOrDefault (); Assert.IsNotNull (async_body); @@ -335,7 +342,8 @@ namespace Mono.Cecil.Tests { Assert.AreEqual (91, async_body.Resumes [0].Offset); Assert.AreEqual (252, async_body.Resumes [1].Offset); - Assert.AreEqual (move_next, async_body.MoveNextMethod); + Assert.AreEqual (move_next, async_body.ResumeMethods [0]); + Assert.AreEqual (move_next, async_body.ResumeMethods [1]); }); } diff --git a/Test/Mono.Cecil.Tests/ResolveTests.cs b/Test/Mono.Cecil.Tests/ResolveTests.cs index aab7d0c..f65b889 100644 --- a/Test/Mono.Cecil.Tests/ResolveTests.cs +++ b/Test/Mono.Cecil.Tests/ResolveTests.cs @@ -26,7 +26,8 @@ namespace Mono.Cecil.Tests { Assert.IsNotNull (definition); Assert.AreEqual ("System.String System.String::Empty", definition.FullName); - Assert.AreEqual ("mscorlib", definition.Module.Assembly.Name.Name); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", + definition.Module.Assembly.Name.Name); } delegate string GetSubstring (string str, int start, int length); @@ -42,7 +43,8 @@ namespace Mono.Cecil.Tests { Assert.IsNotNull (definition); Assert.AreEqual ("System.String System.String::Substring(System.Int32,System.Int32)", definition.FullName); - Assert.AreEqual ("mscorlib", definition.Module.Assembly.Name.Name); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", + definition.Module.Assembly.Name.Name); } [Test] @@ -56,7 +58,8 @@ namespace Mono.Cecil.Tests { Assert.AreEqual ("get_Length", definition.Name); Assert.AreEqual ("System.String", definition.DeclaringType.FullName); - Assert.AreEqual ("mscorlib", definition.Module.Assembly.Name.Name); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", + definition.Module.Assembly.Name.Name); } [Test] @@ -72,7 +75,8 @@ namespace Mono.Cecil.Tests { Assert.IsNotNull (definition); Assert.AreEqual ("System.Void System.Collections.Generic.List`1::Add(T)", definition.FullName); - Assert.AreEqual ("mscorlib", definition.Module.Assembly.Name.Name); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", + definition.Module.Assembly.Name.Name); } [Test] @@ -92,7 +96,8 @@ namespace Mono.Cecil.Tests { Assert.IsNotNull (definition); Assert.AreEqual ("System.Boolean System.Collections.Generic.Dictionary`2::TryGetValue(TKey,TValue&)", definition.FullName); - Assert.AreEqual ("mscorlib", definition.Module.Assembly.Name.Name); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", + definition.Module.Assembly.Name.Name); } class CustomResolver : DefaultAssemblyResolver { @@ -140,7 +145,7 @@ namespace Mono.Cecil.Tests { var definition = reference.Resolve (); Assert.IsNotNull (definition); Assert.AreEqual ("System.Diagnostics.DebuggableAttribute", definition.FullName); - Assert.AreEqual ("mscorlib", definition.Module.Assembly.Name.Name); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", definition.Module.Assembly.Name.Name); } [Test] @@ -162,7 +167,7 @@ namespace Mono.Cecil.Tests { var definition = reference.Resolve (); Assert.IsNotNull (definition); Assert.AreEqual ("System.Diagnostics.DebuggableAttribute/DebuggingModes", definition.FullName); - Assert.AreEqual ("mscorlib", definition.Module.Assembly.Name.Name); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", definition.Module.Assembly.Name.Name); } [Test] @@ -176,6 +181,19 @@ namespace Mono.Cecil.Tests { } [Test] + public void GenericRectangularArrayGetMethodInMemberReferences () + { + using (var module = GetResourceModule ("FSharp.Core.dll")) { + foreach (var member in module.GetMemberReferences ()) { + if (!member.DeclaringType.IsArray) + continue; + + Assert.IsNull (member.Resolve ()); + } + } + } + + [Test] public void ResolveFunctionPointer () { var module = GetResourceModule ("cppcli.dll"); @@ -223,7 +241,9 @@ namespace Mono.Cecil.Tests { Assert.IsTrue (reference.IsRetargetable); var assembly = resolver.Resolve (reference); Assert.IsNotNull (assembly); - Assert.AreEqual (typeof (object).Assembly.GetName ().Version, assembly.Name.Version); + + if (!Platform.OnCoreClr) + Assert.AreEqual (typeof (object).Assembly.GetName ().Version, assembly.Name.Version); } } diff --git a/Test/Mono.Cecil.Tests/SecurityDeclarationTests.cs b/Test/Mono.Cecil.Tests/SecurityDeclarationTests.cs index 3b59e6f..c3106f4 100644 --- a/Test/Mono.Cecil.Tests/SecurityDeclarationTests.cs +++ b/Test/Mono.Cecil.Tests/SecurityDeclarationTests.cs @@ -249,10 +249,10 @@ namespace Mono.Cecil.Tests { } switch (Type.GetTypeCode (value.GetType ())) { - case TypeCode.String: + case System.TypeCode.String: signature.AppendFormat ("\"{0}\"", value); break; - case TypeCode.Char: + case System.TypeCode.Char: signature.AppendFormat ("'{0}'", (char) value); break; default: diff --git a/Test/Mono.Cecil.Tests/TypeParserTests.cs b/Test/Mono.Cecil.Tests/TypeParserTests.cs index 603b7f4..a838c07 100644 --- a/Test/Mono.Cecil.Tests/TypeParserTests.cs +++ b/Test/Mono.Cecil.Tests/TypeParserTests.cs @@ -233,6 +233,9 @@ namespace Mono.Cecil.Tests { [Test] public void GenericInstanceExternArguments () { + if (Platform.OnCoreClr) + return; + var module = GetCurrentModule (); var fullname = string.Format ("System.Collections.Generic.Dictionary`2[[System.Int32, {0}],[System.String, {0}]]", @@ -280,7 +283,7 @@ namespace Mono.Cecil.Tests { var instance = type as GenericInstanceType; Assert.IsNotNull (instance); Assert.AreEqual (2, instance.GenericArguments.Count); - Assert.AreEqual ("mscorlib", type.Scope.Name); + Assert.AreEqual (Platform.OnCoreClr ? "System.Runtime" : "mscorlib", type.Scope.Name); Assert.AreEqual (module, type.Module); Assert.AreEqual ("System.Collections.Generic", type.Namespace); Assert.AreEqual ("Dictionary`2", type.Name); @@ -296,7 +299,7 @@ namespace Mono.Cecil.Tests { Assert.AreEqual ("TypeParserTests", argument.Name); argument = instance.GenericArguments [1]; - Assert.AreEqual ("mscorlib", argument.Scope.Name); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", argument.Scope.Name); Assert.AreEqual (module, argument.Module); Assert.AreEqual ("System", argument.Namespace); Assert.AreEqual ("String", argument.Name); @@ -319,7 +322,7 @@ namespace Mono.Cecil.Tests { var instance = type as GenericInstanceType; Assert.IsNotNull (instance); Assert.AreEqual (2, instance.GenericArguments.Count); - Assert.AreEqual ("mscorlib", type.Scope.Name); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", type.Scope.Name); Assert.AreEqual (module, type.Module); Assert.AreEqual ("System.Collections.Generic", type.Namespace); Assert.AreEqual ("Dictionary`2", type.Name); @@ -354,7 +357,7 @@ namespace Mono.Cecil.Tests { var instance = type as GenericInstanceType; Assert.IsNotNull (instance); Assert.AreEqual (2, instance.GenericArguments.Count); - Assert.AreEqual ("mscorlib", type.Scope.Name); + Assert.AreEqual (Platform.OnCoreClr ? "System.Runtime" : "mscorlib", type.Scope.Name); Assert.AreEqual (module, type.Module); Assert.AreEqual ("System.Collections.Generic", type.Namespace); Assert.AreEqual ("Dictionary`2", type.Name); @@ -364,7 +367,7 @@ namespace Mono.Cecil.Tests { Assert.AreEqual (2, type.GenericParameters.Count); var argument = instance.GenericArguments [0]; - Assert.AreEqual ("mscorlib", argument.Scope.Name); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", argument.Scope.Name); Assert.AreEqual (module, argument.Module); Assert.AreEqual ("System", argument.Namespace); Assert.AreEqual ("String", argument.Name); @@ -385,7 +388,7 @@ namespace Mono.Cecil.Tests { Assert.IsInstanceOf (typeof (TypeDefinition), argument); argument = instance.GenericArguments [1]; - Assert.AreEqual ("mscorlib", argument.Scope.Name); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", argument.Scope.Name); Assert.AreEqual (module, argument.Module); Assert.AreEqual ("System", argument.Namespace); Assert.AreEqual ("Int32", argument.Name); diff --git a/Test/Mono.Cecil.Tests/WindowsRuntimeAssemblyResolver.cs b/Test/Mono.Cecil.Tests/WindowsRuntimeAssemblyResolver.cs index 1e3a90b..fb39e33 100644 --- a/Test/Mono.Cecil.Tests/WindowsRuntimeAssemblyResolver.cs +++ b/Test/Mono.Cecil.Tests/WindowsRuntimeAssemblyResolver.cs @@ -1,4 +1,6 @@ -using System; +#if !NET_CORE + +using System; using System.Collections.Generic; using System.IO; using Microsoft.Win32; @@ -91,3 +93,4 @@ namespace Mono.Cecil.Tests { } } } +#endif
\ No newline at end of file diff --git a/Test/Mono.Cecil.Tests/WindowsRuntimeProjectionsTests.cs b/Test/Mono.Cecil.Tests/WindowsRuntimeProjectionsTests.cs index 166f4d9..d5ed3b0 100644 --- a/Test/Mono.Cecil.Tests/WindowsRuntimeProjectionsTests.cs +++ b/Test/Mono.Cecil.Tests/WindowsRuntimeProjectionsTests.cs @@ -1,4 +1,6 @@ -using NUnit.Framework; +#if !NET_CORE + +using NUnit.Framework; using System; using System.Collections.Generic; using System.IO; @@ -141,3 +143,4 @@ namespace Mono.Cecil.Tests { protected override string [] CustomListTypeNames { get { return new [] { "CustomList" }; } } } } +#endif diff --git a/Test/Resources/assemblies/FSharp.Core.dll b/Test/Resources/assemblies/FSharp.Core.dll Binary files differnew file mode 100644 index 0000000..02d0786 --- /dev/null +++ b/Test/Resources/assemblies/FSharp.Core.dll diff --git a/rocks/Mono.Cecil.Rocks/ILParser.cs b/rocks/Mono.Cecil.Rocks/ILParser.cs index 8d119eb..e05068f 100644 --- a/rocks/Mono.Cecil.Rocks/ILParser.cs +++ b/rocks/Mono.Cecil.Rocks/ILParser.cs @@ -44,6 +44,7 @@ namespace Mono.Cecil.Rocks { class ParseContext { public CodeReader Code { get; set; } + public int Position { get; set; } public MetadataReader Metadata { get; set; } public Collection<VariableDefinition> Variables { get; set; } public IILVisitor Visitor { get; set; } @@ -58,6 +59,14 @@ namespace Mono.Cecil.Rocks { if (!method.HasBody || !method.HasImage) throw new ArgumentException (); + method.Module.Read (method, (m, _) => { + ParseMethod (m, visitor); + return true; + }); + } + + static void ParseMethod (MethodDefinition method, IILVisitor visitor) + { var context = CreateContext (method, visitor); var code = context.Code; @@ -75,15 +84,18 @@ namespace Mono.Cecil.Rocks { default: throw new NotSupportedException (); } + + code.MoveBackTo (context.Position); } static ParseContext CreateContext (MethodDefinition method, IILVisitor visitor) { var code = method.Module.Read (method, (_, reader) => reader.code); - code.MoveTo (method); + var position = code.MoveTo (method); return new ParseContext { Code = code, + Position = position, Metadata = code.reader, Visitor = visitor, }; diff --git a/rocks/Mono.Cecil.Rocks/MethodBodyRocks.cs b/rocks/Mono.Cecil.Rocks/MethodBodyRocks.cs index dfdaece..c627d2f 100644 --- a/rocks/Mono.Cecil.Rocks/MethodBodyRocks.cs +++ b/rocks/Mono.Cecil.Rocks/MethodBodyRocks.cs @@ -189,10 +189,10 @@ namespace Mono.Cecil.Rocks { var instruction = self.Instructions [i]; if (instruction.OpCode.Code != Code.Ldc_I8) continue; - var l = (long)instruction.Operand; - if (l >= uint.MaxValue) + var l = (long) instruction.Operand; + if (l >= int.MaxValue || l <= int.MinValue) continue; - ExpandMacro (instruction, OpCodes.Ldc_I4, (uint)l); + ExpandMacro (instruction, OpCodes.Ldc_I4, (int) l); self.Instructions.Insert (++i, Instruction.Create (OpCodes.Conv_I8)); } } diff --git a/symbols/mdb/Mono.Cecil.Mdb/MdbReader.cs b/symbols/mdb/Mono.Cecil.Mdb/MdbReader.cs index 66a7225..59e933a 100644 --- a/symbols/mdb/Mono.Cecil.Mdb/MdbReader.cs +++ b/symbols/mdb/Mono.Cecil.Mdb/MdbReader.cs @@ -78,6 +78,7 @@ namespace Mono.Cecil.Mdb { return null; var info = new MethodDebugInformation (method); + info.code_size = ReadCodeSize (method); var scopes = ReadScopes (entry, info); ReadLineNumbers (entry, info); @@ -86,6 +87,11 @@ namespace Mono.Cecil.Mdb { return info; } + static int ReadCodeSize (MethodDefinition method) + { + return method.Module.Read (method, (m, reader) => reader.ReadCodeSize (m)); + } + static void ReadLocalVariables (MethodEntry entry, ScopeDebugInformation [] scopes) { var locals = entry.GetLocals (); diff --git a/symbols/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs b/symbols/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs index 0eec10f..e151c75 100644 --- a/symbols/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs +++ b/symbols/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs @@ -234,7 +234,7 @@ namespace Mono.CompilerServices.SymbolWriter public override string ToString () { - return String.Format ("[Line {0}:{1,2}-{3,4}:{5}]", File, Row, Column, EndRow, EndColumn, Offset); + return String.Format ("[Line {0}:{1},{2}-{3},{4}:{5}]", File, Row, Column, EndRow, EndColumn, Offset); } } diff --git a/symbols/pdb/Mono.Cecil.Pdb/NativePdbReader.cs b/symbols/pdb/Mono.Cecil.Pdb/NativePdbReader.cs index b07191d..964f4ad 100644 --- a/symbols/pdb/Mono.Cecil.Pdb/NativePdbReader.cs +++ b/symbols/pdb/Mono.Cecil.Pdb/NativePdbReader.cs @@ -137,9 +137,15 @@ namespace Mono.Cecil.Pdb { } } - if (function.iteratorScopes != null) - foreach (var iterator_scope in function.iteratorScopes) - symbol.CustomDebugInformations.Add (new StateMachineScopeDebugInformation ((int) iterator_scope.Offset, (int) (iterator_scope.Offset + iterator_scope.Length + 1))); + if (function.iteratorScopes != null) { + var state_machine = new StateMachineScopeDebugInformation (); + + foreach (var iterator_scope in function.iteratorScopes) { + state_machine.Scopes.Add (new StateMachineScope ((int) iterator_scope.Offset, (int) (iterator_scope.Offset + iterator_scope.Length + 1))); + } + + symbol.CustomDebugInformations.Add (state_machine); + } if (function.synchronizationInformation != null) { var async_debug_info = new AsyncMethodBodyDebugInformation ((int) function.synchronizationInformation.GeneratedCatchHandlerOffset); @@ -147,11 +153,11 @@ namespace Mono.Cecil.Pdb { foreach (var synchronization_point in function.synchronizationInformation.synchronizationPoints) { async_debug_info.Yields.Add (new InstructionOffset ((int) synchronization_point.SynchronizeOffset)); async_debug_info.Resumes.Add (new InstructionOffset ((int) synchronization_point.ContinuationOffset)); + async_debug_info.ResumeMethods.Add (method); } symbol.CustomDebugInformations.Add (async_debug_info); - async_debug_info.MoveNextMethod = method; symbol.StateMachineKickOffMethod = (MethodDefinition) method.Module.LookupToken ((int) function.synchronizationInformation.kickoffMethodToken); } @@ -280,7 +286,11 @@ namespace Mono.Cecil.Pdb { break; } case 'A': - var index = used_namespace.IndexOf(' '); + var index = used_namespace.IndexOf (' '); + if (index < 0) { + target = new ImportTarget (ImportTargetKind.ImportNamespace) { @namespace = used_namespace }; + break; + } var alias_value = used_namespace.Substring (1, index - 1); var alias_target_value = used_namespace.Substring (index + 2); switch (used_namespace [index + 1]) { @@ -294,6 +304,15 @@ namespace Mono.Cecil.Pdb { break; } break; + case '*': + target = new ImportTarget (ImportTargetKind.ImportNamespace) { @namespace = value }; + break; + case '@': + if (!value.StartsWith ("P:")) + continue; + + target = new ImportTarget (ImportTargetKind.ImportNamespace) { @namespace = value.Substring (2) }; + break; } if (target != null) diff --git a/symbols/pdb/Mono.Cecil.Pdb/NativePdbWriter.cs b/symbols/pdb/Mono.Cecil.Pdb/NativePdbWriter.cs index e3d6d17..be871ac 100644 --- a/symbols/pdb/Mono.Cecil.Pdb/NativePdbWriter.cs +++ b/symbols/pdb/Mono.Cecil.Pdb/NativePdbWriter.cs @@ -111,10 +111,10 @@ namespace Mono.Cecil.Pdb { } if (info.HasCustomDebugInformations) { - var scopes = info.CustomDebugInformations.OfType<StateMachineScopeDebugInformation> ().ToArray (); + var state_machine = info.CustomDebugInformations.FirstOrDefault (cdi => cdi.Kind == CustomDebugInformationKind.StateMachineScope) as StateMachineScopeDebugInformation; - if (scopes.Length > 0) - metadata.WriteIteratorScopes (scopes, info); + if (state_machine != null) + metadata.WriteIteratorScopes (state_machine, info); } metadata.WriteCustomMetadata (); @@ -139,7 +139,7 @@ namespace Mono.Cecil.Pdb { async_metadata.WriteUInt32 ((uint) async_debug_info.Resumes.Count); for (int i = 0; i < async_debug_info.Resumes.Count; ++i) { async_metadata.WriteUInt32 ((uint) async_debug_info.Yields [i].Offset); - async_metadata.WriteUInt32 (async_debug_info.MoveNextMethod != null ? async_debug_info.MoveNextMethod.MetadataToken.ToUInt32 () : 0); + async_metadata.WriteUInt32 (async_debug_info.resume_methods [i].MetadataToken.ToUInt32 ()); async_metadata.WriteUInt32 ((uint) async_debug_info.Resumes [i].Offset); } @@ -312,10 +312,11 @@ namespace Mono.Cecil.Pdb { Write (CustomMetadataType.ForwardInfo, () => writer.WriteUInt32 (import_parent.ToUInt32 ())); } - public void WriteIteratorScopes (StateMachineScopeDebugInformation [] scopes, MethodDebugInformation debug_info) + public void WriteIteratorScopes (StateMachineScopeDebugInformation state_machine, MethodDebugInformation debug_info) { Write (CustomMetadataType.IteratorScopes, () => { - writer.WriteInt32 (scopes.Length); + var scopes = state_machine.Scopes; + writer.WriteInt32 (scopes.Count); foreach (var scope in scopes) { var start = scope.Start.Offset; var end = scope.End.IsEndOfMethod ? debug_info.code_size : scope.End.Offset; diff --git a/symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs b/symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs index 054f1f8..b6fdcdf 100644 --- a/symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs +++ b/symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs @@ -143,7 +143,7 @@ namespace Mono.Cecil.Tests { Assert.AreEqual (DocumentHashAlgorithm.None, document.HashAlgorithm); Assert.AreEqual (DocumentLanguage.FSharp, document.Language); Assert.AreEqual (DocumentLanguageVendor.Microsoft, document.LanguageVendor); - }, readOnly: Platform.OnMono, symbolReaderProvider: typeof(PdbReaderProvider), symbolWriterProvider: typeof(PdbWriterProvider)); + }, readOnly: Platform.OnMono, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider)); } [Test] @@ -157,7 +157,15 @@ namespace Mono.Cecil.Tests { public void EmptyRootNamespace () { TestModule ("EmptyRootNamespace.dll", module => { - }, readOnly: Platform.OnMono, symbolReaderProvider: typeof(PdbReaderProvider), symbolWriterProvider: typeof(PdbWriterProvider)); + }, readOnly: Platform.OnMono, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider)); + } + + [Test] + public void VisualBasicNamespace () + { + TestModule ("AVbTest.exe", module => { + }, readOnly: Platform.OnMono, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider)); + } [Test] @@ -346,8 +354,9 @@ namespace Mono.Cecil.Tests { var state_machine_scope = move_next.DebugInformation.CustomDebugInformations [0] as StateMachineScopeDebugInformation; Assert.IsNotNull (state_machine_scope); - Assert.AreEqual (142, state_machine_scope.Start.Offset); - Assert.AreEqual (319, state_machine_scope.End.Offset); + Assert.AreEqual (1, state_machine_scope.Scopes.Count); + Assert.AreEqual (142, state_machine_scope.Scopes [0].Start.Offset); + Assert.AreEqual (319, state_machine_scope.Scopes [0].End.Offset); var async_body = move_next.DebugInformation.CustomDebugInformations [1] as AsyncMethodBodyDebugInformation; Assert.IsNotNull (async_body); @@ -361,7 +370,8 @@ namespace Mono.Cecil.Tests { Assert.AreEqual (98, async_body.Resumes [0].Offset); Assert.AreEqual (227, async_body.Resumes [1].Offset); - Assert.AreEqual (move_next, async_body.MoveNextMethod); + Assert.AreEqual (move_next, async_body.ResumeMethods [0]); + Assert.AreEqual (move_next, async_body.ResumeMethods [1]); }, readOnly: Platform.OnMono, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider)); } diff --git a/symbols/pdb/Test/Resources/assemblies/AVbTest.exe b/symbols/pdb/Test/Resources/assemblies/AVbTest.exe Binary files differnew file mode 100644 index 0000000..54dcdf6 --- /dev/null +++ b/symbols/pdb/Test/Resources/assemblies/AVbTest.exe diff --git a/symbols/pdb/Test/Resources/assemblies/AVbTest.pdb b/symbols/pdb/Test/Resources/assemblies/AVbTest.pdb Binary files differnew file mode 100644 index 0000000..c46ce47 --- /dev/null +++ b/symbols/pdb/Test/Resources/assemblies/AVbTest.pdb |