Merge branch 'master' into r2r-merge

This commit is contained in:
Michal Strehovský 2018-09-25 14:20:55 +02:00
Родитель bc456a0091 52ec9ae468
Коммит 82351cc766
211 изменённых файлов: 6923 добавлений и 4655 удалений

Просмотреть файл

@ -1 +1 @@
2.2.0-preview1-02908-01
3.0.0-preview1-03205-01

Просмотреть файл

@ -1 +1 @@
2.1.301
2.1.401

Просмотреть файл

@ -2,6 +2,7 @@
<configuration>
<packageSources>
<clear/>
<add key="dotnetfeed" value="https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json" />
<add key="myget.org dotnet-buildtools" value="https://dotnet.myget.org/F/dotnet-buildtools/api/v3/index.json" />
<add key="myget.org dotnet-core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />
<add key="myget.org dotnet-corefxlab" value="https://dotnet.myget.org/F/dotnet-corefxlab/api/v3/index.json" />

Просмотреть файл

@ -55,7 +55,7 @@ IF ERRORLEVEL 1 exit /b %ERRORLEVEL%
call "!VS%__VSProductVersion%COMNTOOLS!\VsDevCmd.bat"
echo Commencing build of managed components for %__BuildOS%.%__BuildArch%.%__BuildType%
echo.
%_msbuildexe% /ConsoleLoggerParameters:ForceNoAlign "%__ProjectDir%\build.proj" %__ExtraMsBuildParams% /p:RepoPath="%__ProjectDir%" /p:RepoLocalBuild="true" /p:NuPkgRid=%__NugetRuntimeId% /nologo /maxcpucount /verbosity:minimal /nodeReuse:false /fileloggerparameters:Verbosity=normal;LogFile="%__BuildLog%"
"%__DotNetCliPath%\dotnet.exe" msbuild /ConsoleLoggerParameters:ForceNoAlign "%__ProjectDir%\build.proj" %__ExtraMsBuildParams% /p:RepoPath="%__ProjectDir%" /p:RepoLocalBuild="true" /p:NuPkgRid=%__NugetRuntimeId% /nologo /maxcpucount /verbosity:minimal /nodeReuse:false /fileloggerparameters:Verbosity=normal;LogFile="%__BuildLog%"
IF NOT ERRORLEVEL 1 (
findstr /ir /c:".*Warning(s)" /c:".*Error(s)" /c:"Time Elapsed.*" "%__BuildLog%"
goto AfterILCompilerBuild
@ -71,14 +71,14 @@ set __GenRespFiles=0
if not exist "%__ObjDir%\ryujit.rsp" set __GenRespFiles=1
if not exist "%__ObjDir%\cpp.rsp" set __GenRespFiles=1
if "%__GenRespFiles%"=="1" (
%_msbuildexe% /ConsoleLoggerParameters:ForceNoAlign "/p:IlcPath=%__BinDir%" /p:Configuration=%__BuildType% /t:Clean,IlcCompile "%__ProjectDir%\src\ILCompiler\repro\repro.csproj"
"%__DotNetCliPath%\dotnet.exe" msbuild /ConsoleLoggerParameters:ForceNoAlign "/p:IlcPath=%__BinDir%" /p:Configuration=%__BuildType% /t:Clean,IlcCompile "%__ProjectDir%\src\ILCompiler\repro\repro.csproj"
call :CopyResponseFile "%__ObjDir%\repro\native\repro.ilc.rsp" "%__ObjDir%\ryujit.rsp"
set __ExtraArgs=/p:NativeCodeGen=cpp
if /i "%__BuildType%"=="debug" (
set __ExtraArgs=!__ExtraArgs! "/p:AdditionalCppCompilerFlags=/MTd"
)
%_msbuildexe% /ConsoleLoggerParameters:ForceNoAlign "/p:IlcPath=%__BinDir%" /p:Configuration=%__BuildType% /t:Clean,IlcCompile "%__ProjectDir%\src\ILCompiler\repro\repro.csproj" !__ExtraArgs!
"%__DotNetCliPath%\dotnet.exe" msbuild /ConsoleLoggerParameters:ForceNoAlign "/p:IlcPath=%__BinDir%" /p:Configuration=%__BuildType% /t:Clean,IlcCompile "%__ProjectDir%\src\ILCompiler\repro\repro.csproj" !__ExtraArgs!
call :CopyResponseFile "%__ObjDir%\repro\native\repro.ilc.rsp" "%__ObjDir%\cpp.rsp"
)
:AfterVsDevGenerateRespFiles

Просмотреть файл

@ -27,5 +27,5 @@ exit /b %ERRORLEVEL%
:AfterVarSetup
%_msbuildexe% "%__ProjectDir%\pkg\packages.proj" /m /nologo /flp:v=diag;LogFile=build-packages.log /p:NuPkgRid=%__NugetRuntimeId% /p:OSGroup=%__BuildOS% /p:Configuration=%__BuildType% /p:Platform=%__BuildArch% %__ExtraMsBuildParams%
"%__DotNetCliPath%\dotnet.exe" msbuild "%__ProjectDir%\pkg\packages.proj" /m /nologo /flp:v=diag;LogFile=build-packages.log /p:NuPkgRid=%__NugetRuntimeId% /p:OSGroup=%__BuildOS% /p:Configuration=%__BuildType% /p:Platform=%__BuildArch% %__ExtraMsBuildParams%
exit /b %ERRORLEVEL%

Просмотреть файл

@ -6,6 +6,8 @@
<CoreFxUapVersion>4.7.0-preview1-26831-01</CoreFxUapVersion>
<MicrosoftNETCoreNativeVersion>3.0.0-preview1-26831-01</MicrosoftNETCoreNativeVersion>
<MicrosoftNETCoreAppPackageVersion>2.1.0</MicrosoftNETCoreAppPackageVersion>
<XunitNetcoreExtensionsVersion>1.0.1-prerelease-02104-02</XunitNetcoreExtensionsVersion>
<MicrosoftDotNetTestSdkVersion>15.8.0</MicrosoftDotNetTestSdkVersion>
<XUnitPackageVersion>2.4.1-pre.build.4059</XUnitPackageVersion>
<MicrosoftDotNetXUnitExtensionsVersion>2.4.0-beta.18420.3</MicrosoftDotNetXUnitExtensionsVersion>
</PropertyGroup>
</Project>

Просмотреть файл

@ -149,7 +149,7 @@
</PropertyGroup>
<ItemGroup>
<SupplementalTestData Include="$(RuntimePath)*.dll" />
<SupplementalTestData Include="$(RuntimePath)*" />
</ItemGroup>
<!-- initialize all the targets variables to false as they should only be set below -->
@ -263,6 +263,11 @@
<SkipTests Condition="'$(SkipTests)'=='' and ('$(OsEnvironment)'=='Windows_NT' and '$(TargetsWindows)'!='true')">true</SkipTests>
</PropertyGroup>
<PropertyGroup>
<!-- On Windows fallback to ILAsm from the framework for now -->
<IlasmToolPath Condition="'$(OSEnvironment)'=='Windows_NT'">%WINDIR%\Microsoft.NET\Framework\v4.0.30319\ilasm.exe</IlasmToolPath>
</PropertyGroup>
<!-- Use Roslyn Compilers to build -->
<Import Project="$(RoslynPropsFile)" Condition="Exists('$(RoslynPropsFile)')" />
</Project>

Просмотреть файл

@ -36,6 +36,21 @@
</PackageReference>
</ItemGroup>
<!-- Set default references for netstandard2.0 -->
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<NuGetTargetMoniker>.NETStandard,Version=v2.0</NuGetTargetMoniker>
<TargetFrameworkIdentifier>.NETStandard</TargetFrameworkIdentifier>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="NETStandard.Library">
<Version>2.0.3</Version>
</PackageReference>
</ItemGroup>
<ImportGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<Import Project="$(PackagesDir)netstandard.library\2.0.3\build\netstandard2.0\NETStandard.Library.targets" Condition="Exists('$(PackagesDir)netstandard.library\2.0.3\build\netstandard2.0\NETStandard.Library.targets')" />
</ImportGroup>
<!-- Set non-empty TargetFrameworkIdentifier to avoid defaulting to .NETPortable -->
<PropertyGroup Condition="'$(TargetFrameworkIdentifier)' == ''">
<TargetFrameworkIdentifier>.NETStandard</TargetFrameworkIdentifier>

Просмотреть файл

@ -2,20 +2,21 @@
setlocal
set INIT_TOOLS_LOG=%~dp0init-tools.log
if [%PACKAGES_DIR%]==[] set PACKAGES_DIR=%~dp0packages\
if [%PACKAGES_DIR%]==[] set PACKAGES_DIR=%~dp0packages
if [%TOOLRUNTIME_DIR%]==[] set TOOLRUNTIME_DIR=%~dp0Tools
set DOTNET_PATH=%TOOLRUNTIME_DIR%\dotnetcli\
if [%DOTNET_CMD%]==[] set DOTNET_CMD=%DOTNET_PATH%dotnet.exe
if [%BUILDTOOLS_SOURCE%]==[] set BUILDTOOLS_SOURCE=https://dotnet.myget.org/F/dotnet-buildtools/api/v3/index.json
set /P BUILDTOOLS_VERSION=< "%~dp0BuildToolsVersion.txt"
set BUILD_TOOLS_PATH=%PACKAGES_DIR%Microsoft.DotNet.BuildTools\%BUILDTOOLS_VERSION%\lib\
set BUILD_TOOLS_PATH=%PACKAGES_DIR%\Microsoft.DotNet.BuildTools\%BUILDTOOLS_VERSION%\lib
set INIT_TOOLS_RESTORE_PROJECT=%~dp0init-tools.msbuild
set BUILD_TOOLS_SEMAPHORE=%TOOLRUNTIME_DIR%\%BUILDTOOLS_VERSION%\init-tools.completed
set BUILD_TOOLS_SEMAPHORE_DIR=%TOOLRUNTIME_DIR%\%BUILDTOOLS_VERSION%
set BUILD_TOOLS_SEMAPHORE=%BUILD_TOOLS_SEMAPHORE_DIR%\init-tools.completed
:: if force option is specified then clean the tool runtime and build tools package directory to force it to get recreated
if [%1]==[force] (
if exist "%TOOLRUNTIME_DIR%" rmdir /S /Q "%TOOLRUNTIME_DIR%"
if exist "%PACKAGES_DIR%Microsoft.DotNet.BuildTools" rmdir /S /Q "%PACKAGES_DIR%Microsoft.DotNet.BuildTools"
if exist "%PACKAGES_DIR%\Microsoft.DotNet.BuildTools" rmdir /S /Q "%PACKAGES_DIR%\Microsoft.DotNet.BuildTools"
)
:: If semaphore exists do nothing
@ -26,6 +27,21 @@ if exist "%BUILD_TOOLS_SEMAPHORE%" (
if exist "%TOOLRUNTIME_DIR%" rmdir /S /Q "%TOOLRUNTIME_DIR%"
if exist "%DotNetBuildToolsDir%" (
echo Using tools from '%DotNetBuildToolsDir%'.
mklink /j "%TOOLRUNTIME_DIR%" "%DotNetBuildToolsDir%"
if not exist "%DOTNET_CMD%" (
echo ERROR: Ensure that '%DotNetBuildToolsDir%' contains the .NET Core SDK at '%DOTNET_PATH%'
exit /b 1
)
echo Done initializing tools.
if NOT exist "%BUILD_TOOLS_SEMAPHORE_DIR%" mkdir "%BUILD_TOOLS_SEMAPHORE_DIR%"
echo Using tools from '%DotNetBuildToolsDir%'. > "%BUILD_TOOLS_SEMAPHORE%"
exit /b 0
)
echo Running %0 > "%INIT_TOOLS_LOG%"
set /p DOTNET_VERSION=< "%~dp0DotnetCLIVersion.txt"
@ -37,7 +53,7 @@ set DOTNET_ZIP_NAME=dotnet-sdk-%DOTNET_VERSION%-win-x64.zip
set DOTNET_REMOTE_PATH=https://dotnetcli.azureedge.net/dotnet/Sdk/%DOTNET_VERSION%/%DOTNET_ZIP_NAME%
set DOTNET_LOCAL_PATH=%DOTNET_PATH%%DOTNET_ZIP_NAME%
echo Installing '%DOTNET_REMOTE_PATH%' to '%DOTNET_LOCAL_PATH%' >> "%INIT_TOOLS_LOG%"
powershell -NoProfile -ExecutionPolicy unrestricted -Command "$retryCount = 0; $success = $false; do { try { (New-Object Net.WebClient).DownloadFile('%DOTNET_REMOTE_PATH%', '%DOTNET_LOCAL_PATH%'); $success = $true; } catch { if ($retryCount -ge 6) { throw; } else { $retryCount++; Start-Sleep -Seconds (5 * $retryCount); } } } while ($success -eq $false); Add-Type -Assembly 'System.IO.Compression.FileSystem' -ErrorVariable AddTypeErrors; if ($AddTypeErrors.Count -eq 0) { [System.IO.Compression.ZipFile]::ExtractToDirectory('%DOTNET_LOCAL_PATH%', '%DOTNET_PATH%') } else { (New-Object -com shell.application).namespace('%DOTNET_PATH%').CopyHere((new-object -com shell.application).namespace('%DOTNET_LOCAL_PATH%').Items(),16) }" >> "%INIT_TOOLS_LOG%"
powershell -NoProfile -ExecutionPolicy unrestricted -Command "$retryCount = 0; $success = $false; $proxyCredentialsRequired = $false; do { try { $wc = New-Object Net.WebClient; if ($proxyCredentialsRequired) { [Net.WebRequest]::DefaultWebProxy.Credentials = [Net.CredentialCache]::DefaultNetworkCredentials; } $wc.DownloadFile('%DOTNET_REMOTE_PATH%', '%DOTNET_LOCAL_PATH%'); $success = $true; } catch { if ($retryCount -ge 6) { throw; } else { $we = $_.Exception.InnerException -as [Net.WebException]; $proxyCredentialsRequired = ($we -ne $null -and ([Net.HttpWebResponse]$we.Response).StatusCode -eq [Net.HttpStatusCode]::ProxyAuthenticationRequired); Start-Sleep -Seconds (5 * $retryCount); $retryCount++; } } } while ($success -eq $false); Add-Type -Assembly 'System.IO.Compression.FileSystem' -ErrorVariable AddTypeErrors; if ($AddTypeErrors.Count -eq 0) { [System.IO.Compression.ZipFile]::ExtractToDirectory('%DOTNET_LOCAL_PATH%', '%DOTNET_PATH%') } else { (New-Object -com shell.application).namespace('%DOTNET_PATH%').CopyHere((new-object -com shell.application).namespace('%DOTNET_LOCAL_PATH%').Items(),16) }" >> "%INIT_TOOLS_LOG%"
if NOT exist "%DOTNET_LOCAL_PATH%" (
echo ERROR: Could not install dotnet cli correctly. 1>&2
goto :error
@ -47,9 +63,9 @@ if NOT exist "%DOTNET_LOCAL_PATH%" (
if exist "%BUILD_TOOLS_PATH%" goto :afterbuildtoolsrestore
echo Restoring BuildTools version %BUILDTOOLS_VERSION%...
echo Running: "%DOTNET_CMD%" restore "%INIT_TOOLS_RESTORE_PROJECT%" --no-cache --packages %PACKAGES_DIR% --source "%BUILDTOOLS_SOURCE%" /p:BuildToolsPackageVersion=%BUILDTOOLS_VERSION% >> "%INIT_TOOLS_LOG%"
call "%DOTNET_CMD%" restore "%INIT_TOOLS_RESTORE_PROJECT%" --no-cache --packages %PACKAGES_DIR% --source "%BUILDTOOLS_SOURCE%" /p:BuildToolsPackageVersion=%BUILDTOOLS_VERSION% >> "%INIT_TOOLS_LOG%"
if NOT exist "%BUILD_TOOLS_PATH%init-tools.cmd" (
echo Running: "%DOTNET_CMD%" restore "%INIT_TOOLS_RESTORE_PROJECT%" --no-cache --packages "%PACKAGES_DIR%" --source "%BUILDTOOLS_SOURCE%" /p:BuildToolsPackageVersion=%BUILDTOOLS_VERSION% /p:ToolsDir=%TOOLRUNTIME_DIR% >> "%INIT_TOOLS_LOG%"
call "%DOTNET_CMD%" restore "%INIT_TOOLS_RESTORE_PROJECT%" --no-cache --packages "%PACKAGES_DIR%" --source "%BUILDTOOLS_SOURCE%" /p:BuildToolsPackageVersion=%BUILDTOOLS_VERSION% /p:ToolsDir=%TOOLRUNTIME_DIR% >> "%INIT_TOOLS_LOG%"
if NOT exist "%BUILD_TOOLS_PATH%\init-tools.cmd" (
echo ERROR: Could not restore build tools correctly. 1>&2
goto :error
)
@ -57,19 +73,17 @@ if NOT exist "%BUILD_TOOLS_PATH%init-tools.cmd" (
:afterbuildtoolsrestore
echo Initializing BuildTools...
echo Running: "%BUILD_TOOLS_PATH%init-tools.cmd" "%~dp0" "%DOTNET_CMD%" "%TOOLRUNTIME_DIR%" >> "%INIT_TOOLS_LOG%"
call "%BUILD_TOOLS_PATH%init-tools.cmd" "%~dp0" "%DOTNET_CMD%" "%TOOLRUNTIME_DIR%" >> "%INIT_TOOLS_LOG%"
echo Running: "%BUILD_TOOLS_PATH%\init-tools.cmd" "%~dp0" "%DOTNET_CMD%" "%TOOLRUNTIME_DIR%" >> "%INIT_TOOLS_LOG%"
call "%BUILD_TOOLS_PATH%\init-tools.cmd" "%~dp0" "%DOTNET_CMD%" "%TOOLRUNTIME_DIR%" "%PACKAGES_DIR%" >> "%INIT_TOOLS_LOG%"
set INIT_TOOLS_ERRORLEVEL=%ERRORLEVEL%
if not [%INIT_TOOLS_ERRORLEVEL%]==[0] (
echo ERROR: An error occured when trying to initialize the tools. 1>&2
goto :error
)
rem CoreRT does not use special copy of the shared runtime for testing
copy /Y %TOOLRUNTIME_DIR%\csc.runtimeconfig.json %TOOLRUNTIME_DIR%\xunit.console.netcore.runtimeconfig.json
:: Create semaphore file
echo Done initializing tools.
if NOT exist "%BUILD_TOOLS_SEMAPHORE_DIR%" mkdir "%BUILD_TOOLS_SEMAPHORE_DIR%"
echo Init-Tools.cmd completed for BuildTools Version: %BUILDTOOLS_VERSION% > "%BUILD_TOOLS_SEMAPHORE%"
exit /b 0

Просмотреть файл

@ -148,9 +148,6 @@ if [ ! -e $__INIT_TOOLS_DONE_MARKER ]; then
Tools/crossgen.sh $__scriptpath/Tools $__PKG_RID
# CoreRT does not use special copy of the shared runtime for testing
cp $__TOOLRUNTIME_DIR/csc.runtimeconfig.json $__TOOLRUNTIME_DIR/xunit.console.netcore.runtimeconfig.json
mkdir -p $__INIT_TOOLS_DONE_MARKER_DIR
touch $__INIT_TOOLS_DONE_MARKER

Просмотреть файл

@ -40,6 +40,7 @@ See the LICENSE file in the project root for more information.
<NativeLibrary Condition="$(NativeCodeGen) == '' and $(NativeLib) != ''" Include="$(IlcPath)\sdk\bootstrapperdll.lib" />
<NativeLibrary Condition="$(NativeCodeGen) == ''" Include="$(IlcPath)\sdk\$(FullRuntimeName).lib" />
<NativeLibrary Condition="$(NativeCodeGen) == ''" Include="$(IlcPath)\sdk\System.Private.TypeLoader.Native.lib" />
<NativeLibrary Condition="$(NativeCodeGen) == '' and '$(ExperimentalJitSupport)' == 'true'" Include="$(IlcPath)\sdk\System.Private.Jit.Native.lib" />
<NativeLibrary Condition="$(NativeCodeGen) == 'cpp'" Include="$(IlcPath)\sdk\bootstrappercpp.lib" />
<NativeLibrary Condition="$(NativeCodeGen) == 'cpp'" Include="$(IlcPath)\sdk\PortableRuntime.lib" />
<NativeLibrary Condition="$(NativeCodeGen) == 'wasm'" Include="$(IlcPath)\sdk\bootstrappercpp.lib" />

Просмотреть файл

@ -71,6 +71,8 @@ See the LICENSE file in the project root for more information.
<FrameworkLibPath Condition="'$(FrameworkLibPath)' == ''">$(NativeOutputPath)</FrameworkLibPath>
<FrameworkObjPath Condition="'$(FrameworkObjPath)' == ''">$(NativeIntermediateOutputPath)</FrameworkObjPath>
<ExperimentalDynamicCodeSupport Condition="'$(ExperimentalInterpreterSupport)' == 'true' or '$(ExperimentalJitSupport)' == 'true'">true</ExperimentalDynamicCodeSupport>
<SharedLibrary Condition="'$(OS)' == 'Windows_NT'">$(FrameworkLibPath)\Framework$(LibFileExt)</SharedLibrary>
<SharedLibrary Condition="'$(OS)' != 'Windows_NT'">$(FrameworkLibPath)\libframework$(LibFileExt)</SharedLibrary>
<IlcDynamicBuildPropertyDependencies Condition="'$(IlcCalledViaPackage)' == 'true'">SetupProperties</IlcDynamicBuildPropertyDependencies>
@ -85,17 +87,19 @@ See the LICENSE file in the project root for more information.
<ItemGroup>
<AutoInitializedAssemblies Include="System.Private.CoreLib" />
<AutoInitializedAssemblies Include="System.Private.DeveloperExperience.Console" />
<AutoInitializedAssemblies Include="System.Private.StackTraceMetadata" />
<AutoInitializedAssemblies Condition="'$(ExperimentalInterpreterSupport)' == 'true'" Include="System.Private.Interpreter" />
<AutoInitializedAssemblies Condition="'$(ExperimentalJitSupport)' == 'true'" Include="System.Private.Jit" />
</ItemGroup>
<ItemGroup Condition="'$(ExperimentalInterpreterSupport)' != 'true'">
<ItemGroup Condition="'$(ExperimentalDynamicCodeSupport)' != 'true'">
<AutoInitializedAssemblies Include="System.Private.StackTraceMetadata" />
<AutoInitializedAssemblies Include="System.Private.TypeLoader" />
<AutoInitializedAssemblies Include="System.Private.Reflection.Execution" />
<AutoInitializedAssemblies Include="System.Private.Interop" />
</ItemGroup>
<ItemGroup Condition="'$(ExperimentalInterpreterSupport)' == 'true'">
<AutoInitializedAssemblies Include="System.Private.Interpreter" />
<ItemGroup Condition="'$(ExperimentalDynamicCodeSupport)' == 'true'">
<AutoInitializedAssemblies Include="System.Private.StackTraceMetadata.Experimental" />
<AutoInitializedAssemblies Include="System.Private.TypeLoader.Experimental" />
<AutoInitializedAssemblies Include="System.Private.Reflection.Execution.Experimental" />
<AutoInitializedAssemblies Include="System.Private.Interop.Experimental" />
@ -184,7 +188,7 @@ See the LICENSE file in the project root for more information.
<IlcArg Condition="$(OutputType) == 'Library' and $(NativeLib) != ''" Include="--nativelib" />
<IlcArg Condition="$(ExportsFile) != ''" Include="--exportsfile:$(ExportsFile)" />
<ILcArg Condition="'$(Platform)' == 'wasm'" Include="--wasm" />
<ILcArg Condition="'$(ExperimentalInterpreterSupport)' == 'true'" Include="--nometadatablocking" />
<ILcArg Condition="'$(ExperimentalDynamicCodeSupport)' == 'true'" Include="--nometadatablocking" />
<IlcArg Include="@(AutoInitializedAssemblies->'--initassembly:%(Identity)')" />
<IlcArg Include="@(AppContextSwitchOverrides->'--appcontextswitch:%(Identity)')" />
<IlcArg Condition="$(ServerGarbageCollection) != ''" Include="--runtimeopt:RH_UseServerGC=1" />
@ -280,7 +284,7 @@ See the LICENSE file in the project root for more information.
<PropertyGroup>
<EmccArgs>&quot;$(NativeObject)&quot; -o &quot;$(NativeBinary)&quot; -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 --emrun </EmccArgs>
<EmccArgs Condition="'$(Platform)'=='wasm'">$(EmccArgs) &quot;$(IlcPath)/sdk/libPortableRuntime.bc&quot; &quot;$(IlcPath)/sdk/libbootstrappercpp.bc&quot; &quot;$(IlcPath)/sdk/libSystem.Private.CoreLib.Native.bc&quot; </EmccArgs>
<EmccArgs Condition="'$(Platform)'=='wasm'">$(EmccArgs) &quot;$(IlcPath)/sdk/libPortableRuntime.bc&quot; &quot;$(IlcPath)/sdk/libbootstrappercpp.bc&quot; &quot;$(IlcPath)/sdk/libSystem.Private.CoreLib.Native.bc&quot; </EmccArgs>
<EmccArgs Condition="'$(Configuration)'=='Release'">$(EmccArgs) -O2 --llvm-lto 2</EmccArgs>
<EmccArgs Condition="'$(Configuration)'=='Debug'">$(EmccArgs) -g3</EmccArgs>
</PropertyGroup>

Просмотреть файл

@ -1,16 +0,0 @@
// 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.
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
internal static partial class Interop
{
internal unsafe partial class Sys
{
[DllImport(Interop.Libraries.CoreLibNative, EntryPoint = "CoreLibNative_DoubleToString")]
internal static extern unsafe int DoubleToString(double value, byte* format, byte* buffer, int bufferLength);
}
}

Просмотреть файл

@ -6,9 +6,6 @@ internal static partial class Interop
{
internal static partial class Libraries
{
internal const string CoreFile_L1 = "api-ms-win-core-file-l1-1-0.dll";
internal const string CoreFile_L1_2 = "api-ms-win-core-file-l1-2-0.dll";
internal const string CoreFile_L2 = "api-ms-win-core-file-l2-1-0.dll";
internal const string ErrorHandling = "api-ms-win-core-errorhandling-l1-1-0.dll";
internal const string Handle = "api-ms-win-core-handle-l1-1-0.dll";
internal const string IO = "api-ms-win-core-io-l1-1-0.dll";
@ -17,7 +14,6 @@ internal static partial class Interop
internal const string ProcessThreads = "api-ms-win-core-processthreads-l1-1-0.dll";
internal const string RealTime = "api-ms-win-core-realtime-l1-1-0.dll";
internal const string SysInfo = "api-ms-win-core-sysinfo-l1-2-0.dll";
internal const string Registry_L1 = "api-ms-win-core-registry-l1-1-0.dll";
internal const string ThreadPool = "api-ms-win-core-threadpool-l1-2-0.dll";
internal const string Localization = "api-ms-win-core-localization-l1-2-1.dll";
}

Просмотреть файл

@ -1,44 +0,0 @@
// 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.
internal partial class Interop
{
internal partial class mincore
{
internal partial class RegistryOptions
{
internal const int REG_OPTION_NON_VOLATILE = 0x0000; // (default) keys are persisted beyond reboot/unload
internal const int REG_OPTION_VOLATILE = 0x0001; // All keys created by the function are volatile
internal const int REG_OPTION_CREATE_LINK = 0x0002; // They key is a symbolic link
internal const int REG_OPTION_BACKUP_RESTORE = 0x0004; // Use SE_BACKUP_NAME process special privileges
}
internal partial class RegistryOperations
{
internal const int KEY_QUERY_VALUE = 0x0001;
internal const int KEY_SET_VALUE = 0x0002;
internal const int KEY_CREATE_SUB_KEY = 0x0004;
internal const int KEY_ENUMERATE_SUB_KEYS = 0x0008;
internal const int KEY_NOTIFY = 0x0010;
internal const int KEY_CREATE_LINK = 0x0020;
internal const int KEY_READ = ((STANDARD_RIGHTS_READ |
KEY_QUERY_VALUE |
KEY_ENUMERATE_SUB_KEYS |
KEY_NOTIFY)
&
(~SYNCHRONIZE));
internal const int KEY_WRITE = ((STANDARD_RIGHTS_WRITE |
KEY_SET_VALUE |
KEY_CREATE_SUB_KEY)
&
(~SYNCHRONIZE));
internal const int SYNCHRONIZE = 0x00100000;
internal const int READ_CONTROL = 0x00020000;
internal const int STANDARD_RIGHTS_READ = READ_CONTROL;
internal const int STANDARD_RIGHTS_WRITE = READ_CONTROL;
}
}
}

Просмотреть файл

@ -0,0 +1,19 @@
// 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.
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
internal static partial class Interop
{
internal static partial class Ole32
{
internal const uint COINIT_APARTMENTTHREADED = 2;
internal const uint COINIT_MULTITHREADED = 0;
[DllImport(Interop.Libraries.Ole32, ExactSpelling = true)]
internal extern static int CoInitializeEx(IntPtr reserved, uint dwCoInit);
}
}

Просмотреть файл

@ -0,0 +1,16 @@
// 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.
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
internal static partial class Interop
{
internal static partial class Ole32
{
[DllImport(Interop.Libraries.Ole32, ExactSpelling = true)]
internal extern static int CoUninitialize();
}
}

Просмотреть файл

@ -0,0 +1,317 @@
// 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.
using System;
using Internal.TypeSystem;
using Internal.TypeSystem.Ecma;
using Internal.IL.Stubs;
using Debug = System.Diagnostics.Debug;
namespace Internal.IL
{
public sealed class CoreRTILProvider : ILProvider
{
private MethodIL TryGetRuntimeImplementedMethodIL(MethodDesc method)
{
// Provides method bodies for runtime implemented methods. It can return null for
// methods that are treated specially by the codegen.
Debug.Assert(method.IsRuntimeImplemented);
TypeDesc owningType = method.OwningType;
if (owningType.IsDelegate)
{
return DelegateMethodILEmitter.EmitIL(method);
}
return null;
}
/// <summary>
/// Provides method bodies for intrinsics recognized by the compiler.
/// It can return null if it's not an intrinsic recognized by the compiler,
/// but an intrinsic e.g. recognized by codegen.
/// </summary>
private MethodIL TryGetIntrinsicMethodIL(MethodDesc method)
{
Debug.Assert(method.IsIntrinsic);
MetadataType owningType = method.OwningType as MetadataType;
if (owningType == null)
return null;
switch (owningType.Name)
{
case "Unsafe":
{
if (owningType.Namespace == "Internal.Runtime.CompilerServices")
return UnsafeIntrinsics.EmitIL(method);
}
break;
case "Debug":
{
if (owningType.Namespace == "System.Diagnostics" && method.Name == "DebugBreak")
return new ILStubMethodIL(method, new byte[] { (byte)ILOpcode.break_, (byte)ILOpcode.ret }, Array.Empty<LocalVariableDefinition>(), null);
}
break;
case "EETypePtr":
{
if (owningType.Namespace == "System" && method.Name == "EETypePtrOf")
return EETypePtrOfIntrinsic.EmitIL(method);
}
break;
case "RuntimeAugments":
{
if (owningType.Namespace == "Internal.Runtime.Augments" && method.Name == "GetCanonType")
return GetCanonTypeIntrinsic.EmitIL(method);
}
break;
case "EEType":
{
if (owningType.Namespace == "Internal.Runtime" && method.Name == "get_SupportsRelativePointers")
{
ILOpcode value = method.Context.Target.SupportsRelativePointers ?
ILOpcode.ldc_i4_1 : ILOpcode.ldc_i4_0;
return new ILStubMethodIL(method, new byte[] { (byte)value, (byte)ILOpcode.ret }, Array.Empty<LocalVariableDefinition>(), null);
}
}
break;
}
return null;
}
/// <summary>
/// Provides method bodies for intrinsics recognized by the compiler that
/// are specialized per instantiation. It can return null if the intrinsic
/// is not recognized.
/// </summary>
private MethodIL TryGetPerInstantiationIntrinsicMethodIL(MethodDesc method)
{
Debug.Assert(method.IsIntrinsic);
MetadataType owningType = method.OwningType.GetTypeDefinition() as MetadataType;
if (owningType == null)
return null;
string methodName = method.Name;
switch (owningType.Name)
{
case "RuntimeHelpers":
{
if ((methodName == "IsReferenceOrContainsReferences" || methodName == "IsReference")
&& owningType.Namespace == "System.Runtime.CompilerServices")
{
TypeDesc elementType = method.Instantiation[0];
// Fallback to non-intrinsic implementation for universal generics
if (elementType.IsCanonicalSubtype(CanonicalFormKind.Universal))
return null;
bool result = elementType.IsGCPointer;
if (methodName == "IsReferenceOrContainsReferences")
{
result |= (elementType.IsDefType ? ((DefType)elementType).ContainsGCPointers : false);
}
return new ILStubMethodIL(method, new byte[] {
result ? (byte)ILOpcode.ldc_i4_1 : (byte)ILOpcode.ldc_i4_0,
(byte)ILOpcode.ret },
Array.Empty<LocalVariableDefinition>(), null);
}
}
break;
case "Comparer`1":
{
if (methodName == "Create" && owningType.Namespace == "System.Collections.Generic")
return ComparerIntrinsics.EmitComparerCreate(method);
}
break;
case "EqualityComparer`1":
{
if (methodName == "Create" && owningType.Namespace == "System.Collections.Generic")
return ComparerIntrinsics.EmitEqualityComparerCreate(method);
}
break;
case "EqualityComparerHelpers":
{
if (owningType.Namespace != "Internal.IntrinsicSupport")
return null;
if (methodName == "EnumOnlyEquals")
{
// EnumOnlyEquals would basically like to do this:
// static bool EnumOnlyEquals<T>(T x, T y) where T: struct => x == y;
// This is not legal though.
// We don't want to do this:
// static bool EnumOnlyEquals<T>(T x, T y) where T: struct => x.Equals(y);
// Because it would box y.
// So we resort to some per-instantiation magic.
TypeDesc elementType = method.Instantiation[0];
if (!elementType.IsEnum)
return null;
ILOpcode convInstruction;
if (((DefType)elementType).InstanceFieldSize.AsInt <= 4)
{
convInstruction = ILOpcode.conv_i4;
}
else
{
Debug.Assert(((DefType)elementType).InstanceFieldSize.AsInt == 8);
convInstruction = ILOpcode.conv_i8;
}
return new ILStubMethodIL(method, new byte[] {
(byte)ILOpcode.ldarg_0,
(byte)convInstruction,
(byte)ILOpcode.ldarg_1,
(byte)convInstruction,
(byte)ILOpcode.prefix1, unchecked((byte)ILOpcode.ceq),
(byte)ILOpcode.ret,
},
Array.Empty<LocalVariableDefinition>(), null);
}
else if (methodName == "GetComparerForReferenceTypesOnly")
{
TypeDesc elementType = method.Instantiation[0];
if (!elementType.IsRuntimeDeterminedSubtype
&& !elementType.IsCanonicalSubtype(CanonicalFormKind.Any)
&& !elementType.IsGCPointer)
{
return new ILStubMethodIL(method, new byte[] {
(byte)ILOpcode.ldnull,
(byte)ILOpcode.ret
},
Array.Empty<LocalVariableDefinition>(), null);
}
}
else if (methodName == "StructOnlyEquals")
{
TypeDesc elementType = method.Instantiation[0];
if (!elementType.IsRuntimeDeterminedSubtype
&& !elementType.IsCanonicalSubtype(CanonicalFormKind.Any)
&& !elementType.IsGCPointer)
{
Debug.Assert(elementType.IsValueType);
TypeSystemContext context = elementType.Context;
MetadataType helperType = context.SystemModule.GetKnownType("Internal.IntrinsicSupport", "EqualityComparerHelpers");
MethodDesc methodToCall;
if (elementType.IsEnum)
{
methodToCall = helperType.GetKnownMethod("EnumOnlyEquals", null).MakeInstantiatedMethod(elementType);
}
else if (elementType.IsNullable && ComparerIntrinsics.ImplementsIEquatable(elementType.Instantiation[0]))
{
methodToCall = helperType.GetKnownMethod("StructOnlyEqualsNullable", null).MakeInstantiatedMethod(elementType.Instantiation[0]);
}
else if (ComparerIntrinsics.ImplementsIEquatable(elementType))
{
methodToCall = helperType.GetKnownMethod("StructOnlyEqualsIEquatable", null).MakeInstantiatedMethod(elementType);
}
else
{
methodToCall = helperType.GetKnownMethod("StructOnlyNormalEquals", null).MakeInstantiatedMethod(elementType);
}
return new ILStubMethodIL(method, new byte[]
{
(byte)ILOpcode.ldarg_0,
(byte)ILOpcode.ldarg_1,
(byte)ILOpcode.call, 1, 0, 0, 0,
(byte)ILOpcode.ret
},
Array.Empty<LocalVariableDefinition>(), new object[] { methodToCall });
}
}
}
break;
}
return null;
}
public override MethodIL GetMethodIL(MethodDesc method)
{
if (method is EcmaMethod)
{
// TODO: Workaround: we should special case methods with Intrinsic attribute, but since
// CoreLib source is still not in the repo, we have to work with what we have, which is
// an MCG attribute on the type itself...
if (((MetadataType)method.OwningType).HasCustomAttribute("System.Runtime.InteropServices", "McgIntrinsicsAttribute"))
{
var name = method.Name;
if (name == "Call" || name.StartsWith("StdCall"))
{
return CalliIntrinsic.EmitIL(method);
}
else
if (name == "AddrOf")
{
return AddrOfIntrinsic.EmitIL(method);
}
}
if (method.IsIntrinsic)
{
MethodIL result = TryGetIntrinsicMethodIL(method);
if (result != null)
return result;
}
if (method.IsRuntimeImplemented)
{
MethodIL result = TryGetRuntimeImplementedMethodIL(method);
if (result != null)
return result;
}
MethodIL methodIL = EcmaMethodIL.Create((EcmaMethod)method);
if (methodIL != null)
return methodIL;
return null;
}
else
if (method is MethodForInstantiatedType || method is InstantiatedMethod)
{
// Intrinsics specialized per instantiation
if (method.IsIntrinsic)
{
MethodIL methodIL = TryGetPerInstantiationIntrinsicMethodIL(method);
if (methodIL != null)
return methodIL;
}
var methodDefinitionIL = GetMethodIL(method.GetTypicalMethodDefinition());
if (methodDefinitionIL == null)
return null;
return new InstantiatedMethodIL(method, methodDefinitionIL);
}
else
if (method is ILStubMethod)
{
return ((ILStubMethod)method).EmitIL();
}
else
if (method is ArrayMethod)
{
return ArrayMethodILEmitter.EmitIL((ArrayMethod)method);
}
else
{
Debug.Assert(!(method is PInvokeTargetNativeMethod), "Who is asking for IL of PInvokeTargetNativeMethod?");
return null;
}
}
}
}

Просмотреть файл

@ -2,362 +2,16 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using Internal.TypeSystem;
using Internal.TypeSystem.Ecma;
using Internal.IL.Stubs;
using Debug = System.Diagnostics.Debug;
namespace Internal.IL
{
internal sealed class ILProvider : LockFreeReaderHashtable<MethodDesc, ILProvider.MethodILData>
/// <summary>
/// Provides IL for <see cref="MethodDesc"/> method bodies either by reading
/// the IL bytes from the source ECMA-335 assemblies, or through other means.
/// </summary>
public abstract class ILProvider
{
private PInvokeILProvider _pinvokeILProvider;
public ILProvider(PInvokeILProvider pinvokeILProvider)
{
_pinvokeILProvider = pinvokeILProvider;
}
private MethodIL TryGetRuntimeImplementedMethodIL(MethodDesc method)
{
// Provides method bodies for runtime implemented methods. It can return null for
// methods that are treated specially by the codegen.
Debug.Assert(method.IsRuntimeImplemented);
TypeDesc owningType = method.OwningType;
if (owningType.IsDelegate)
{
return DelegateMethodILEmitter.EmitIL(method);
}
return null;
}
/// <summary>
/// Provides method bodies for intrinsics recognized by the compiler.
/// It can return null if it's not an intrinsic recognized by the compiler,
/// but an intrinsic e.g. recognized by codegen.
/// </summary>
private MethodIL TryGetIntrinsicMethodIL(MethodDesc method)
{
Debug.Assert(method.IsIntrinsic);
MetadataType owningType = method.OwningType as MetadataType;
if (owningType == null)
return null;
switch (owningType.Name)
{
case "Unsafe":
{
if (owningType.Namespace == "Internal.Runtime.CompilerServices")
return UnsafeIntrinsics.EmitIL(method);
}
break;
case "Debug":
{
if (owningType.Namespace == "System.Diagnostics" && method.Name == "DebugBreak")
return new ILStubMethodIL(method, new byte[] { (byte)ILOpcode.break_, (byte)ILOpcode.ret }, Array.Empty<LocalVariableDefinition>(), null);
}
break;
case "EETypePtr":
{
if (owningType.Namespace == "System" && method.Name == "EETypePtrOf")
return EETypePtrOfIntrinsic.EmitIL(method);
}
break;
case "RuntimeAugments":
{
if (owningType.Namespace == "Internal.Runtime.Augments" && method.Name == "GetCanonType")
return GetCanonTypeIntrinsic.EmitIL(method);
}
break;
case "EEType":
{
if (owningType.Namespace == "Internal.Runtime" && method.Name == "get_SupportsRelativePointers")
{
ILOpcode value = method.Context.Target.SupportsRelativePointers ?
ILOpcode.ldc_i4_1 : ILOpcode.ldc_i4_0;
return new ILStubMethodIL(method, new byte[] { (byte)value, (byte)ILOpcode.ret }, Array.Empty<LocalVariableDefinition>(), null);
}
}
break;
}
return null;
}
/// <summary>
/// Provides method bodies for intrinsics recognized by the compiler that
/// are specialized per instantiation. It can return null if the intrinsic
/// is not recognized.
/// </summary>
private MethodIL TryGetPerInstantiationIntrinsicMethodIL(MethodDesc method)
{
Debug.Assert(method.IsIntrinsic);
MetadataType owningType = method.OwningType.GetTypeDefinition() as MetadataType;
if (owningType == null)
return null;
string methodName = method.Name;
switch (owningType.Name)
{
case "RuntimeHelpers":
{
if ((methodName == "IsReferenceOrContainsReferences" || methodName == "IsReference")
&& owningType.Namespace == "System.Runtime.CompilerServices")
{
TypeDesc elementType = method.Instantiation[0];
// Fallback to non-intrinsic implementation for universal generics
if (elementType.IsCanonicalSubtype(CanonicalFormKind.Universal))
return null;
bool result = elementType.IsGCPointer;
if (methodName == "IsReferenceOrContainsReferences")
{
result |= (elementType.IsDefType ? ((DefType)elementType).ContainsGCPointers : false);
}
return new ILStubMethodIL(method, new byte[] {
result ? (byte)ILOpcode.ldc_i4_1 : (byte)ILOpcode.ldc_i4_0,
(byte)ILOpcode.ret },
Array.Empty<LocalVariableDefinition>(), null);
}
}
break;
case "Comparer`1":
{
if (methodName == "Create" && owningType.Namespace == "System.Collections.Generic")
return ComparerIntrinsics.EmitComparerCreate(method);
}
break;
case "EqualityComparer`1":
{
if (methodName == "Create" && owningType.Namespace == "System.Collections.Generic")
return ComparerIntrinsics.EmitEqualityComparerCreate(method);
}
break;
case "EqualityComparerHelpers":
{
if (owningType.Namespace != "Internal.IntrinsicSupport")
return null;
if (methodName == "EnumOnlyEquals")
{
// EnumOnlyEquals would basically like to do this:
// static bool EnumOnlyEquals<T>(T x, T y) where T: struct => x == y;
// This is not legal though.
// We don't want to do this:
// static bool EnumOnlyEquals<T>(T x, T y) where T: struct => x.Equals(y);
// Because it would box y.
// So we resort to some per-instantiation magic.
TypeDesc elementType = method.Instantiation[0];
if (!elementType.IsEnum)
return null;
ILOpcode convInstruction;
if (((DefType)elementType).InstanceFieldSize.AsInt <= 4)
{
convInstruction = ILOpcode.conv_i4;
}
else
{
Debug.Assert(((DefType)elementType).InstanceFieldSize.AsInt == 8);
convInstruction = ILOpcode.conv_i8;
}
return new ILStubMethodIL(method, new byte[] {
(byte)ILOpcode.ldarg_0,
(byte)convInstruction,
(byte)ILOpcode.ldarg_1,
(byte)convInstruction,
(byte)ILOpcode.prefix1, unchecked((byte)ILOpcode.ceq),
(byte)ILOpcode.ret,
},
Array.Empty<LocalVariableDefinition>(), null);
}
else if (methodName == "GetComparerForReferenceTypesOnly")
{
TypeDesc elementType = method.Instantiation[0];
if (!elementType.IsRuntimeDeterminedSubtype
&& !elementType.IsCanonicalSubtype(CanonicalFormKind.Any)
&& !elementType.IsGCPointer)
{
return new ILStubMethodIL(method, new byte[] {
(byte)ILOpcode.ldnull,
(byte)ILOpcode.ret
},
Array.Empty<LocalVariableDefinition>(), null);
}
}
else if (methodName == "StructOnlyEquals")
{
TypeDesc elementType = method.Instantiation[0];
if (!elementType.IsRuntimeDeterminedSubtype
&& !elementType.IsCanonicalSubtype(CanonicalFormKind.Any)
&& !elementType.IsGCPointer)
{
Debug.Assert(elementType.IsValueType);
TypeSystemContext context = elementType.Context;
MetadataType helperType = context.SystemModule.GetKnownType("Internal.IntrinsicSupport", "EqualityComparerHelpers");
MethodDesc methodToCall;
if (elementType.IsEnum)
{
methodToCall = helperType.GetKnownMethod("EnumOnlyEquals", null).MakeInstantiatedMethod(elementType);
}
else if (elementType.IsNullable && ComparerIntrinsics.ImplementsIEquatable(elementType.Instantiation[0]))
{
methodToCall = helperType.GetKnownMethod("StructOnlyEqualsNullable", null).MakeInstantiatedMethod(elementType.Instantiation[0]);
}
else if (ComparerIntrinsics.ImplementsIEquatable(elementType))
{
methodToCall = helperType.GetKnownMethod("StructOnlyEqualsIEquatable", null).MakeInstantiatedMethod(elementType);
}
else
{
methodToCall = helperType.GetKnownMethod("StructOnlyNormalEquals", null).MakeInstantiatedMethod(elementType);
}
return new ILStubMethodIL(method, new byte[]
{
(byte)ILOpcode.ldarg_0,
(byte)ILOpcode.ldarg_1,
(byte)ILOpcode.call, 1, 0, 0, 0,
(byte)ILOpcode.ret
},
Array.Empty<LocalVariableDefinition>(), new object[] { methodToCall });
}
}
}
break;
}
return null;
}
private MethodIL CreateMethodIL(MethodDesc method)
{
if (method is EcmaMethod)
{
// TODO: Workaround: we should special case methods with Intrinsic attribute, but since
// CoreLib source is still not in the repo, we have to work with what we have, which is
// an MCG attribute on the type itself...
if (((MetadataType)method.OwningType).HasCustomAttribute("System.Runtime.InteropServices", "McgIntrinsicsAttribute"))
{
var name = method.Name;
if (name == "Call" || name.StartsWith("StdCall"))
{
return CalliIntrinsic.EmitIL(method);
}
else
if (name == "AddrOf")
{
return AddrOfIntrinsic.EmitIL(method);
}
}
if (method.IsIntrinsic)
{
MethodIL result = TryGetIntrinsicMethodIL(method);
if (result != null)
return result;
}
if (method.IsPInvoke)
{
var pregenerated = McgInteropSupport.TryGetPregeneratedPInvoke(method);
if (pregenerated == null)
return _pinvokeILProvider.EmitIL(method);
method = pregenerated;
}
if (method.IsRuntimeImplemented)
{
MethodIL result = TryGetRuntimeImplementedMethodIL(method);
if (result != null)
return result;
}
MethodIL methodIL = EcmaMethodIL.Create((EcmaMethod)method);
if (methodIL != null)
return methodIL;
return null;
}
else
if (method is MethodForInstantiatedType || method is InstantiatedMethod)
{
// Intrinsics specialized per instantiation
if (method.IsIntrinsic)
{
MethodIL methodIL = TryGetPerInstantiationIntrinsicMethodIL(method);
if (methodIL != null)
return methodIL;
}
var methodDefinitionIL = GetMethodIL(method.GetTypicalMethodDefinition());
if (methodDefinitionIL == null)
return null;
return new InstantiatedMethodIL(method, methodDefinitionIL);
}
else
if (method is ILStubMethod)
{
return ((ILStubMethod)method).EmitIL();
}
else
if (method is ArrayMethod)
{
return ArrayMethodILEmitter.EmitIL((ArrayMethod)method);
}
else
{
Debug.Assert(!(method is PInvokeTargetNativeMethod), "Who is asking for IL of PInvokeTargetNativeMethod?");
return null;
}
}
internal class MethodILData
{
public MethodDesc Method;
public MethodIL MethodIL;
}
protected override int GetKeyHashCode(MethodDesc key)
{
return key.GetHashCode();
}
protected override int GetValueHashCode(MethodILData value)
{
return value.Method.GetHashCode();
}
protected override bool CompareKeyToValue(MethodDesc key, MethodILData value)
{
return Object.ReferenceEquals(key, value.Method);
}
protected override bool CompareValueToValue(MethodILData value1, MethodILData value2)
{
return Object.ReferenceEquals(value1.Method, value2.Method);
}
protected override MethodILData CreateValueFromKey(MethodDesc key)
{
return new MethodILData() { Method = key, MethodIL = CreateMethodIL(key) };
}
public MethodIL GetMethodIL(MethodDesc method)
{
return GetOrCreateValue(method).MethodIL;
}
public abstract MethodIL GetMethodIL(MethodDesc method);
}
}

Просмотреть файл

@ -1,111 +0,0 @@
// 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.
using System;
using System.Reflection;
using Internal.TypeSystem;
using Debug = System.Diagnostics.Debug;
namespace Internal.IL
{
/// <summary>
/// Provides compilation hooks for interop code generated by tool
/// </summary>
public static class McgInteropSupport
{
/// <summary>
/// Assembly name suffix for pregenerated interop code.
/// </summary>
private const string AssemblyNameSuffix = ".McgInterop";
private const string PInvokeContainerTypeNS = "McgInterop";
private const string PInvokeMethodContainerType = "McgPInvokeMarshaller";
/// <summary>
/// Returns true if <paramref name="method"/> is pregenerated interop code
/// </summary>
public static bool IsPregeneratedInterop(MethodDesc method)
{
var metadataType = (MetadataType)method.OwningType;
var module = metadataType.Module;
var assemblyName = ((IAssemblyDesc)module).GetName();
var simpleName = assemblyName.Name;
return simpleName.EndsWith(AssemblyNameSuffix);
}
/// <summary>
/// Returns pregenerated interop code for given PInvoke method if one exist
/// </summary>
public static MethodDesc TryGetPregeneratedPInvoke(MethodDesc method)
{
Debug.Assert(method.IsPInvoke);
var metadataType = (MetadataType)method.OwningType;
var module = metadataType.Module;
var assemblyName = ((IAssemblyDesc)module).GetName();
var interopAssemblyName = new AssemblyName();
interopAssemblyName.Name = assemblyName.Name + AssemblyNameSuffix;
interopAssemblyName.Version = assemblyName.Version;
interopAssemblyName.SetPublicKeyToken(interopAssemblyName.GetPublicKeyToken());
interopAssemblyName.CultureName = assemblyName.CultureName;
interopAssemblyName.ContentType = assemblyName.ContentType;
var interopModule = module.Context.ResolveAssembly(interopAssemblyName, false);
if (interopModule == null)
return null;
var pregeneratedMethod = GetMatchingMethod(interopModule, method);
if (pregeneratedMethod == null)
{
// TODO: Better error message
throw new MissingMemberException("Missing method in " + interopAssemblyName.Name + ":" + method.ToString());
}
return pregeneratedMethod;
}
// Returns null if no matching method is found
private static MethodDesc GetMatchingMethod(ModuleDesc module, MethodDesc method)
{
// TODO:Enable this once mcg generated code match GetMatchingType
// type lookup.
// var matchingType = GetMatchingType(module, method.OwningType);
var matchingType = TryGetMcgGeneratedType(module);
if (matchingType == null)
return null;
return matchingType.GetMethod(method.Name, method.Signature);
}
// Returns null if no matching type is found
private static TypeDesc GetMatchingType(ModuleDesc module, TypeDesc type)
{
var metadataType = (MetadataType)type;
var containingType = metadataType.ContainingType;
if (containingType != null)
{
var matchingContainingType = (MetadataType)GetMatchingType(module, containingType);
if (matchingContainingType == null)
return null;
return matchingContainingType.GetNestedType(metadataType.Name);
}
else
{
return module.GetType(metadataType.Namespace, metadataType.Name, false);
}
}
// TODO: This's to work-around the limitation of mcg code generation.Mcg currently
// do not preserve user pinvoke defining type hierarchy,but dump all pinvoke stub methods
// to a type named McgPInvokeMarshaller
private static TypeDesc TryGetMcgGeneratedType(ModuleDesc module)
{
// this should not fail since we are looking for a well known type.
return module.GetType(PInvokeContainerTypeNS, PInvokeMethodContainerType, true);
}
}
}

Просмотреть файл

@ -8,29 +8,90 @@
<TargetFramework>netcoreapp2.1</TargetFramework>
<RidSpecificAssets>true</RidSpecificAssets>
<OutputPath>$(RuntimePath)</OutputPath>
<XUnitRunnerPackageId>xunit.runner.console</XUnitRunnerPackageId>
<XUnitRunner>xunit.console</XUnitRunner>
<XUnitTestAdapterPackageId>xunit.runner.visualstudio</XUnitTestAdapterPackageId>
<XUnitAdapter>xunit.runner.visualstudio.dotnetcore.testadapter</XUnitAdapter>
<TestPlatformHostPackageId>microsoft.testplatform.testhost</TestPlatformHostPackageId>
<TestPlatformHost>testhost</TestPlatformHost>
<!-- In case the project language is not set -->
<Language Condition="'$(Language)' == ''">unknown</Language>
<!-- Don't warn if some dependencies were rolled forward -->
<NoWarn>$(NoWarn);NU1603</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="xunit.console.netcore">
<Version>1.0.3-prerelease-00921-01</Version>
<PackageReference Include="xunit">
<Version>$(XUnitPackageVersion)</Version>
</PackageReference>
<PackageReference Include="Microsoft.DotNet.BuildTools.TestSuite">
<Version>$(XunitNetcoreExtensionsVersion)</Version>
<PackageReference Include="$(XUnitRunnerPackageId)">
<Version>$(XUnitPackageVersion)</Version>
</PackageReference>
<PackageReference Include="Microsoft.xunit.netcore.extensions">
<Version>$(XunitNetcoreExtensionsVersion)</Version>
<PackageReference Include="Microsoft.DotNet.XUnitExtensions">
<Version>$(MicrosoftDotNetXUnitExtensionsVersion)</Version>
</PackageReference>
<PackageReference Include="$(XUnitTestAdapterPackageId)">
<Version>$(XUnitPackageVersion)</Version>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk">
<Version>$(MicrosoftDotNetTestSdkVersion)</Version>
</PackageReference>
<PackageReference Include="Microsoft.TestPlatform.ObjectModel">
<Version>$(MicrosoftDotNetTestSdkVersion)</Version>
</PackageReference>
<PackageReference Include="$(TestPlatformHostPackageId)">
<Version>$(MicrosoftDotNetTestSdkVersion)</Version>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.DependencyModel">
<Version>2.0.4</Version>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
<Version>9.0.1</Version>
</PackageReference>
</ItemGroup>
<Target Name="AddTestPlatformDependenciesNetCore" BeforeTargets="ResolveReferences">
<Error Condition="!Exists('$(PackagesDir)$(XUnitRunnerPackageId)\$(XUnitPackageVersion)\tools\netcoreapp2.0\$(XUnitRunner).dll')"
Text="Error: looks the package $(PackagesDir)$(XUnitRunnerPackageId)\$(XUnitPackageVersion) not restored or missing $(XUnitRunner).dll."
/>
<Error Condition="!Exists('$(PackagesDir)$(XUnitTestAdapterPackageId)\$(XUnitPackageVersion)\build\netcoreapp1.0\$(XUnitAdapter).dll')"
Text="Error: looks the package $(PackagesDir)$(XUnitTestAdapterPackageId)\$(XUnitPackageVersion) not restored or missing $(XUnitAdapter).dll."
/>
<Error Condition="!Exists('$(PackagesDir)$(TestPlatformHostPackageId)\$(MicrosoftDotNetTestSdkVersion)\lib\netstandard1.5\$(TestPlatformHost).dll')"
Text="Error: looks the package $(PackagesDir)$(TestPlatformHostPackageId)\$(MicrosoftDotNetTestSdkVersion) not restored or missing $(TestPlatformHost).dll."
/>
<ItemGroup>
<ReferenceCopyLocalPaths Include="$(PackagesDir)$(XUnitRunnerPackageId)\$(XUnitPackageVersion)\tools\netcoreapp2.0\*.*">
<Private>false</Private>
<NuGetPackageId>$(XUnitRunnerPackageId)</NuGetPackageId>
<NuGetPackageVersion>$(XUnitPackageVersion)</NuGetPackageVersion>
</ReferenceCopyLocalPaths>
<ReferenceCopyLocalPaths Include="$(PackagesDir)$(XUnitTestAdapterPackageId)\$(XUnitPackageVersion)\build\netcoreapp1.0\*.*">
<Private>false</Private>
<NuGetPackageId>$(XUnitTestAdapterPackageId)</NuGetPackageId>
<NuGetPackageVersion>$(XUnitPackageVersion)</NuGetPackageVersion>
</ReferenceCopyLocalPaths>
<ReferenceCopyLocalPaths Include="$(PackagesDir)$(TestPlatformHostPackageId)\$(MicrosoftDotNetTestSdkVersion)\lib\netstandard1.5\$(TestPlatformHost).dll">
<Private>false</Private>
<NuGetPackageId>$(TestPlatformHostPackageId)</NuGetPackageId>
<NuGetPackageVersion>$(MicrosoftDotNetTestSdkVersion)</NuGetPackageVersion>
</ReferenceCopyLocalPaths>
</ItemGroup>
</Target>
<ItemGroup>
<PackageToInclude Include="xunit.abstractions"/>
<PackageToInclude Include="xunit.assert"/>
<PackageToInclude Include="xunit.extensibility.core"/>
<PackageToInclude Include="xunit.extensibility.execution"/>
<PackageToInclude Include="xunit.runner.utility"/>
<PackageToInclude Include="Microsoft.xunit.netcore.extensions"/>
<PackageToInclude Include="xunit.console.netcore" />
</ItemGroup>
<!-- xunit core -->
<PackageToInclude Include="xunit.abstractions" />
<PackageToInclude Include="xunit.assert" />
<PackageToInclude Include="xunit.extensibility.core" />
<PackageToInclude Include="xunit.extensibility.execution" />
<PackageToInclude Include="xunit.runner.utility" />
<PackageToInclude Include="Microsoft.DotNet.XUnitExtensions" />
<!-- test sdk -->
<PackageToInclude Include="Microsoft.NET.Test.Sdk" />
<PackageToInclude Include="Microsoft.TestPlatform.TestHost" />
<PackageToInclude Include="Microsoft.TestPlatform.ObjectModel" />
<PackageToInclude Include="Microsoft.Extensions.DependencyModel" />
<PackageToInclude Include="Newtonsoft.Json" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>

Просмотреть файл

@ -41,6 +41,7 @@ namespace ILCompiler
DependencyAnalyzerBase<NodeFactory> dependencyGraph,
NodeFactory nodeFactory,
IEnumerable<ICompilationRootProvider> compilationRoots,
ILProvider ilProvider,
DebugInformationProvider debugInformationProvider,
DevirtualizationManager devirtualizationManager,
Logger logger)
@ -63,25 +64,30 @@ namespace ILCompiler
_assemblyGetExecutingAssemblyMethodThunks = new AssemblyGetExecutingAssemblyMethodThunkCache(globalModuleGeneratedType);
_methodBaseGetCurrentMethodThunks = new MethodBaseGetCurrentMethodThunkCache();
bool? forceLazyPInvokeResolution = null;
// TODO: Workaround lazy PInvoke resolution not working with CppCodeGen yet
// https://github.com/dotnet/corert/issues/2454
// https://github.com/dotnet/corert/issues/2149
if (nodeFactory.IsCppCodegenTemporaryWorkaround) forceLazyPInvokeResolution = false;
PInvokeILProvider = new PInvokeILProvider(new PInvokeILEmitterConfiguration(forceLazyPInvokeResolution), nodeFactory.InteropStubManager.InteropStateManager);
if (!(nodeFactory.InteropStubManager is EmptyInteropStubManager))
{
bool? forceLazyPInvokeResolution = null;
// TODO: Workaround lazy PInvoke resolution not working with CppCodeGen yet
// https://github.com/dotnet/corert/issues/2454
// https://github.com/dotnet/corert/issues/2149
if (nodeFactory.IsCppCodegenTemporaryWorkaround) forceLazyPInvokeResolution = false;
PInvokeILProvider = new PInvokeILProvider(new PInvokeILEmitterConfiguration(forceLazyPInvokeResolution), nodeFactory.InteropStubManager.InteropStateManager);
_methodILCache = new ILProvider(PInvokeILProvider);
ilProvider = new CombinedILProvider(ilProvider, PInvokeILProvider);
}
_methodILCache = new ILCache(ilProvider);
}
private ILProvider _methodILCache;
private ILCache _methodILCache;
public MethodIL GetMethodIL(MethodDesc method)
{
// Flush the cache when it grows too big
if (_methodILCache.Count > 1000)
_methodILCache = new ILProvider(PInvokeILProvider);
_methodILCache = new ILCache(_methodILCache.ILProvider);
return _methodILCache.GetMethodIL(method);
return _methodILCache.GetOrCreateValue(method).MethodIL;
}
protected abstract void ComputeDependencyNodeDependencies(List<DependencyNodeCore<NodeFactory>> obj);
@ -437,6 +443,64 @@ namespace ILCompiler
_graph.AddRoot(_factory.ReadOnlyDataBlob(exportName, data, alignment), reason);
}
}
private sealed class ILCache : LockFreeReaderHashtable<MethodDesc, ILCache.MethodILData>
{
public ILProvider ILProvider { get; }
public ILCache(ILProvider provider)
{
ILProvider = provider;
}
protected override int GetKeyHashCode(MethodDesc key)
{
return key.GetHashCode();
}
protected override int GetValueHashCode(MethodILData value)
{
return value.Method.GetHashCode();
}
protected override bool CompareKeyToValue(MethodDesc key, MethodILData value)
{
return Object.ReferenceEquals(key, value.Method);
}
protected override bool CompareValueToValue(MethodILData value1, MethodILData value2)
{
return Object.ReferenceEquals(value1.Method, value2.Method);
}
protected override MethodILData CreateValueFromKey(MethodDesc key)
{
return new MethodILData() { Method = key, MethodIL = ILProvider.GetMethodIL(key) };
}
internal class MethodILData
{
public MethodDesc Method;
public MethodIL MethodIL;
}
}
private sealed class CombinedILProvider : ILProvider
{
private readonly ILProvider _primaryILProvider;
private readonly PInvokeILProvider _pinvokeProvider;
public CombinedILProvider(ILProvider primaryILProvider, PInvokeILProvider pinvokeILProvider)
{
_primaryILProvider = primaryILProvider;
_pinvokeProvider = pinvokeILProvider;
}
public override MethodIL GetMethodIL(MethodDesc method)
{
MethodIL result = _primaryILProvider.GetMethodIL(method);
if (result == null && method.IsPInvoke)
result = _pinvokeProvider.GetMethodIL(method);
return result;
}
}
}
// Interface under which Compilation is exposed externally.

Просмотреть файл

@ -8,6 +8,8 @@ using System.Collections.Generic;
using ILCompiler.DependencyAnalysis;
using ILCompiler.DependencyAnalysisFramework;
using Internal.IL;
namespace ILCompiler
{
public abstract class CompilationBuilder
@ -92,6 +94,10 @@ namespace ILCompiler
public abstract CompilationBuilder UseBackendOptions(IEnumerable<string> options);
public abstract CompilationBuilder UseILProvider(ILProvider ilProvider);
protected abstract ILProvider GetILProvider();
protected DependencyAnalyzerBase<NodeFactory> CreateDependencyGraph(NodeFactory factory, IComparer<DependencyNodeCore<NodeFactory>> comparer = null)
{
return _dependencyTrackingLevel.CreateDependencyGraph(factory, comparer);
@ -99,7 +105,7 @@ namespace ILCompiler
public ILScannerBuilder GetILScannerBuilder(CompilationModuleGroup compilationGroup = null)
{
return new ILScannerBuilder(_context, compilationGroup ?? _compilationGroup, _nameMangler);
return new ILScannerBuilder(_context, compilationGroup ?? _compilationGroup, _nameMangler, GetILProvider());
}
public abstract ICompilation ToCompilation();

Просмотреть файл

@ -38,6 +38,10 @@ namespace ILCompiler
/// </summary>
public abstract bool ContainsMethodDictionary(MethodDesc method);
/// <summary>
/// If true, "method" is imported from the set of reference assemblies
/// </summary>
public abstract bool ImportsMethod(MethodDesc method, bool unboxingStub);
/// <summary>
/// If true, "type" is exported by the set of input assemblies being compiled
/// </summary>
public abstract ExportForm GetExportTypeForm(TypeDesc type);

Просмотреть файл

@ -426,6 +426,13 @@ namespace ILCompiler.DependencyAnalysis
}
}
if (!ConstructedEETypeNode.CreationAllowed(_type))
{
// If necessary EEType is the highest load level for this type, ask the metadata manager
// if we have any dependencies due to reflectability.
factory.MetadataManager.GetDependenciesDueToReflectability(ref dependencies, factory, _type);
}
return dependencies;
}

Просмотреть файл

@ -37,10 +37,6 @@ namespace ILCompiler.DependencyAnalysis
{
return new RuntimeImportMethodNode(method);
}
// On CLR this would throw a SecurityException with "ECall methods must be packaged into a system module."
// This is a corner case that nobody is likely to care about.
ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramSpecific, method);
}
if (CompilationModuleGroup.ContainsMethodBody(method, false))

Просмотреть файл

@ -10,7 +10,7 @@ namespace ILCompiler.DependencyAnalysis
/// <summary>
/// Represents a method that is imported from the runtime library.
/// </summary>
public class RuntimeImportMethodNode : ExternSymbolNode, IMethodNode
public class RuntimeImportMethodNode : ExternSymbolNode, IMethodNode, IExportableSymbolNode
{
private MethodDesc _method;
@ -28,6 +28,21 @@ namespace ILCompiler.DependencyAnalysis
}
}
public ExportForm GetExportForm(NodeFactory factory)
{
// Force non-fake exports for RuntimeImportMethods that have '*' as their module. ('*' means the method is
// REALLY a reference to the linked in native code)
if (((EcmaMethod)_method).GetRuntimeImportDllName() == "*")
{
ExportForm exportForm = factory.CompilationModuleGroup.GetExportMethodForm(_method, false);
if (exportForm == ExportForm.ByName)
return ExportForm.None; // Method symbols exported by name are naturally handled by the linker
return exportForm;
}
return ExportForm.None;
}
public override int ClassCode => -1173492615;
public override int CompareToImpl(ISortableNode other, CompilerComparer comparer)

Просмотреть файл

@ -237,12 +237,21 @@ namespace ILCompiler
{
if (method.HasCustomAttribute("System.Runtime", "RuntimeImportAttribute"))
{
return new RuntimeImportMethodNode(method);
RuntimeImportMethodNode runtimeImportMethod = new RuntimeImportMethodNode(method);
// If the method is imported from either the current module or the runtime, reference it directly
if (CompilationModuleGroup.ContainsMethodBody(method, false))
return runtimeImportMethod;
// If the method is imported from the runtime but not a managed assembly, reference it directly
else if (!CompilationModuleGroup.ImportsMethod(method, false))
return runtimeImportMethod;
// If the method is imported from a managed assembly, reference it via an import cell
}
if (CompilationModuleGroup.ContainsMethodBody(method, false))
else
{
return NonExternMethodSymbol(method, false);
if (CompilationModuleGroup.ContainsMethodBody(method, false))
return NonExternMethodSymbol(method, false);
}
return _importedNodeProvider.ImportedMethodCodeNode(this, method, false);

Просмотреть файл

@ -28,9 +28,10 @@ namespace ILCompiler
DependencyAnalyzerBase<NodeFactory> dependencyGraph,
ILScanNodeFactory nodeFactory,
IEnumerable<ICompilationRootProvider> roots,
ILProvider ilProvider,
DebugInformationProvider debugInformationProvider,
Logger logger)
: base(dependencyGraph, nodeFactory, roots, debugInformationProvider, null, logger)
: base(dependencyGraph, nodeFactory, roots, ilProvider, debugInformationProvider, null, logger)
{
}

Просмотреть файл

@ -9,6 +9,7 @@ using ILCompiler.DependencyAnalysis;
using ILCompiler.DependencyAnalysisFramework;
using Internal.TypeSystem;
using Internal.IL;
namespace ILCompiler
{
@ -17,6 +18,7 @@ namespace ILCompiler
private readonly CompilerTypeSystemContext _context;
private readonly CompilationModuleGroup _compilationGroup;
private readonly NameMangler _nameMangler;
private readonly ILProvider _ilProvider;
// These need to provide reasonable defaults so that the user can optionally skip
// calling the Use/Configure methods and still get something reasonable back.
@ -25,12 +27,13 @@ namespace ILCompiler
private IEnumerable<ICompilationRootProvider> _compilationRoots = Array.Empty<ICompilationRootProvider>();
private MetadataManager _metadataManager;
internal ILScannerBuilder(CompilerTypeSystemContext context, CompilationModuleGroup compilationGroup, NameMangler mangler)
internal ILScannerBuilder(CompilerTypeSystemContext context, CompilationModuleGroup compilationGroup, NameMangler mangler, ILProvider ilProvider)
{
_context = context;
_compilationGroup = compilationGroup;
_nameMangler = mangler;
_metadataManager = new EmptyMetadataManager(context);
_ilProvider = ilProvider;
}
public ILScannerBuilder UseDependencyTracking(DependencyTrackingLevel trackingLevel)
@ -57,7 +60,7 @@ namespace ILCompiler
var nodeFactory = new ILScanNodeFactory(_context, _compilationGroup, _metadataManager, interopStubManager, _nameMangler);
DependencyAnalyzerBase<NodeFactory> graph = _dependencyTrackingLevel.CreateDependencyGraph(nodeFactory);
return new ILScanner(graph, nodeFactory, _compilationRoots, new NullDebugInformationProvider(), _logger);
return new ILScanner(graph, nodeFactory, _compilationRoots, _ilProvider, new NullDebugInformationProvider(), _logger);
}
}
}

Просмотреть файл

@ -30,6 +30,26 @@ namespace ILCompiler
return null;
}
public static string GetRuntimeImportDllName(this EcmaMethod This)
{
var decoded = This.GetDecodedCustomAttribute("System.Runtime", "RuntimeImportAttribute");
if (decoded == null)
return null;
var decodedValue = decoded.Value;
if (decodedValue.FixedArguments.Length == 2)
return (string)decodedValue.FixedArguments[0].Value;
foreach (var argument in decodedValue.NamedArguments)
{
if (argument.Name == "DllName")
return (string)argument.Value;
}
return null;
}
public static string GetRuntimeExportName(this EcmaMethod This)
{
var decoded = This.GetDecodedCustomAttribute("System.Runtime", "RuntimeExportAttribute");
@ -75,7 +95,7 @@ namespace ILCompiler
/// </summary>
public static bool IsRawPInvoke(this MethodDesc method)
{
return method.IsPInvoke && ((method is Internal.IL.Stubs.PInvokeTargetNativeMethod) || Internal.IL.McgInteropSupport.IsPregeneratedInterop(method));
return method.IsPInvoke && (method is Internal.IL.Stubs.PInvokeTargetNativeMethod);
}
/// <summary>

Просмотреть файл

@ -58,6 +58,11 @@ namespace ILCompiler
return ContainsMethodBody(method, false);
}
public sealed override bool ImportsMethod(MethodDesc method, bool unboxingStub)
{
return false;
}
public sealed override ExportForm GetExportTypeForm(TypeDesc type)
{
return ExportForm.None;

Просмотреть файл

@ -388,13 +388,11 @@ namespace ILCompiler
MethodDesc requiredGenericFieldsMethod = typeWithMetadataMappings.GetMethod("RequiredGenericFields", null);
MethodDesc requiredTemplatesMethod = typeWithMetadataMappings.GetMethod("CompilerDeterminedInstantiations", null);
ILProvider ilProvider = new ILProvider(null);
MetadataLoadedInfo result = new MetadataLoadedInfo();
if (fullMetadataMethod != null)
{
MethodIL fullMethodIL = ilProvider.GetMethodIL(fullMetadataMethod);
MethodIL fullMethodIL = EcmaMethodIL.Create((EcmaMethod)fullMetadataMethod);
ReadMetadataMethod(fullMethodIL, result.AllTypeMappings, result.MethodMappings, result.FieldMappings, metadataModules);
foreach (var mapping in result.AllTypeMappings)
{
@ -404,7 +402,7 @@ namespace ILCompiler
if (weakMetadataMethod != null)
{
MethodIL weakMethodIL = ilProvider.GetMethodIL(weakMetadataMethod);
MethodIL weakMethodIL = EcmaMethodIL.Create((EcmaMethod)weakMetadataMethod);
Dictionary<MethodDesc, int> weakMethodMappings = new Dictionary<MethodDesc, int>();
Dictionary<FieldDesc, int> weakFieldMappings = new Dictionary<FieldDesc, int>();
ReadMetadataMethod(weakMethodIL, result.WeakReflectedTypeMappings, weakMethodMappings, weakFieldMappings, metadataModules);
@ -417,7 +415,7 @@ namespace ILCompiler
if (requiredGenericTypesMethod != null)
{
foreach (var type in ReadRequiredGenericsEntities(ilProvider.GetMethodIL(requiredGenericTypesMethod)))
foreach (var type in ReadRequiredGenericsEntities(EcmaMethodIL.Create((EcmaMethod)requiredGenericTypesMethod)))
{
Debug.Assert(type is DefType);
result.RequiredGenericTypes.Add((TypeDesc)type);
@ -426,19 +424,19 @@ namespace ILCompiler
if (requiredGenericMethodsMethod != null)
{
foreach (var method in ReadRequiredGenericsEntities(ilProvider.GetMethodIL(requiredGenericMethodsMethod)))
foreach (var method in ReadRequiredGenericsEntities(EcmaMethodIL.Create((EcmaMethod)requiredGenericMethodsMethod)))
result.RequiredGenericMethods.Add((MethodDesc)method);
}
if (requiredGenericFieldsMethod != null)
{
foreach (var field in ReadRequiredGenericsEntities(ilProvider.GetMethodIL(requiredGenericFieldsMethod)))
foreach (var field in ReadRequiredGenericsEntities(EcmaMethodIL.Create((EcmaMethod)requiredGenericFieldsMethod)))
result.RequiredGenericFields.Add((FieldDesc)field);
}
if (requiredTemplatesMethod != null)
{
ReadRequiredTemplates(ilProvider.GetMethodIL(requiredTemplatesMethod),
ReadRequiredTemplates(EcmaMethodIL.Create((EcmaMethod)requiredTemplatesMethod),
result.RequiredTemplateTypes,
result.RequiredTemplateMethods,
result.RequiredTemplateFields);
@ -877,8 +875,7 @@ namespace ILCompiler
if (dynamicInvokeStubDescriptorMethod == null)
return dynamicInvokeMapTable;
ILProvider ilProvider = new ILProvider(null);
ILStreamReader il = new ILStreamReader(ilProvider.GetMethodIL(dynamicInvokeStubDescriptorMethod));
ILStreamReader il = new ILStreamReader(EcmaMethodIL.Create((EcmaMethod)dynamicInvokeStubDescriptorMethod));
// structure is
// REPEAT N TIMES
//ldtoken method

Просмотреть файл

@ -31,6 +31,11 @@ namespace ILCompiler
return ContainsMethodBody(method, false);
}
public override bool ImportsMethod(MethodDesc method, bool unboxingStub)
{
return false;
}
public override ExportForm GetExportTypeForm(TypeDesc type)
{
return ExportForm.None;

Просмотреть файл

@ -50,6 +50,11 @@ namespace ILCompiler
return false;
}
public override bool ImportsMethod(MethodDesc method, bool unboxingStub)
{
return false;
}
public override ExportForm GetExportTypeForm(TypeDesc type)
{
return ExportForm.None;

Просмотреть файл

@ -276,17 +276,14 @@ namespace ILCompiler
foreach (var constructedType in GetTypesWithRuntimeMapping())
{
if (!IsReflectionBlocked(constructedType))
{
reflectableTypes[constructedType] |= MetadataCategory.RuntimeMapping;
reflectableTypes[constructedType] |= MetadataCategory.RuntimeMapping;
// Also set the description bit if the definition is getting metadata.
TypeDesc constructedTypeDefinition = constructedType.GetTypeDefinition();
if (constructedType != constructedTypeDefinition &&
(reflectableTypes[constructedTypeDefinition] & MetadataCategory.Description) != 0)
{
reflectableTypes[constructedType] |= MetadataCategory.Description;
}
// Also set the description bit if the definition is getting metadata.
TypeDesc constructedTypeDefinition = constructedType.GetTypeDefinition();
if (constructedType != constructedTypeDefinition &&
(reflectableTypes[constructedTypeDefinition] & MetadataCategory.Description) != 0)
{
reflectableTypes[constructedType] |= MetadataCategory.Description;
}
}

Просмотреть файл

@ -14,7 +14,7 @@ namespace Internal.IL
/// Wraps the API and configuration for a particular PInvoke IL emitter. Eventually this will
/// allow ILProvider to switch out its PInvoke IL generator with another, such as MCG.
/// </summary>
public class PInvokeILProvider
public class PInvokeILProvider : ILProvider
{
private readonly PInvokeILEmitterConfiguration _pInvokeILEmitterConfiguration;
private readonly InteropStateManager _interopStateManager;
@ -25,7 +25,7 @@ namespace Internal.IL
_interopStateManager = interopStateManager;
}
public MethodIL EmitIL(MethodDesc method)
public override MethodIL GetMethodIL(MethodDesc method)
{
return PInvokeILEmitter.EmitIL(method, _pInvokeILEmitterConfiguration, _interopStateManager);
}

Просмотреть файл

@ -46,6 +46,9 @@
<Compile Include="..\..\Common\src\TypeSystem\Ecma\EcmaSignatureEncoder.cs">
<Link>Ecma\EcmaSignatureEncoder.cs</Link>
</Compile>
<Compile Include="..\..\Common\src\TypeSystem\IL\CoreRTILProvider.cs">
<Link>IL\CoreRTILProvider.cs</Link>
</Compile>
<Compile Include="..\..\Common\src\TypeSystem\IL\ILImporter.cs">
<Link>IL\ILImporter.cs</Link>
</Compile>
@ -394,9 +397,6 @@
<Compile Include="..\..\Common\src\TypeSystem\IL\ILProvider.cs">
<Link>IL\ILProvider.cs</Link>
</Compile>
<Compile Include="..\..\Common\src\TypeSystem\IL\McgInteropSupport.cs">
<Link>IL\McgInteropSupport.cs</Link>
</Compile>
<Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\AddrOfIntrinsic.cs">
<Link>IL\Stubs\AddrOfIntrinsic.cs</Link>
</Compile>

Просмотреть файл

@ -4,7 +4,7 @@
<OutputType>Library</OutputType>
<AssemblyName>ILCompiler.Compiler.Tests.Assets</AssemblyName>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RunTestsForProject>false</RunTestsForProject>
<SkipTestRun>true</SkipTestRun>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -4,11 +4,14 @@
<OutputType>Library</OutputType>
<AssemblyName>ILCompiler.Compiler.Tests</AssemblyName>
<RootNamespace>ILCompiler.Compiler.Tests</RootNamespace>
<TargetFramework>netstandard1.3</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.DotNet.BuildTools.TestSuite">
<Version>$(XunitNetcoreExtensionsVersion)</Version>
<PackageReference Include="xunit">
<Version>$(XUnitPackageVersion)</Version>
</PackageReference>
<PackageReference Include="Microsoft.DotNet.XUnitExtensions">
<Version>$(MicrosoftDotNetXUnitExtensionsVersion)</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>

Просмотреть файл

@ -4,6 +4,7 @@
using System.Collections.Generic;
using Internal.IL;
using Internal.TypeSystem;
using ILCompiler.DependencyAnalysis;
@ -22,10 +23,11 @@ namespace ILCompiler
DependencyAnalyzerBase<NodeFactory> dependencyGraph,
NodeFactory nodeFactory,
IEnumerable<ICompilationRootProvider> roots,
ILProvider ilProvider,
DebugInformationProvider debugInformationProvider,
Logger logger,
CppCodegenConfigProvider options)
: base(dependencyGraph, nodeFactory, GetCompilationRoots(roots, nodeFactory), debugInformationProvider, null, logger)
: base(dependencyGraph, nodeFactory, GetCompilationRoots(roots, nodeFactory), ilProvider, debugInformationProvider, null, logger)
{
Options = options;
}

Просмотреть файл

@ -8,6 +8,7 @@ using System.Collections.Generic;
using ILCompiler.DependencyAnalysis;
using ILCompiler.DependencyAnalysisFramework;
using Internal.IL;
using Internal.TypeSystem;
namespace ILCompiler
@ -17,6 +18,7 @@ namespace ILCompiler
// These need to provide reasonable defaults so that the user can optionally skip
// calling the Use/Configure methods and still get something reasonable back.
CppCodegenConfigProvider _config = new CppCodegenConfigProvider(Array.Empty<string>());
private ILProvider _ilProvider = new CoreRTILProvider();
public CppCodegenCompilationBuilder(CompilerTypeSystemContext context, CompilationModuleGroup group)
: base(context, group, new CoreRTNameMangler(new CppNodeMangler(), true))
@ -29,13 +31,24 @@ namespace ILCompiler
return this;
}
public override CompilationBuilder UseILProvider(ILProvider ilProvider)
{
_ilProvider = ilProvider;
return this;
}
protected override ILProvider GetILProvider()
{
return _ilProvider;
}
public override ICompilation ToCompilation()
{
var interopStubManager = new CompilerGeneratedInteropStubManager(_compilationGroup, _context, new InteropStateManager(_context.GeneratedAssembly));
CppCodegenNodeFactory factory = new CppCodegenNodeFactory(_context, _compilationGroup, _metadataManager, interopStubManager, _nameMangler, _vtableSliceProvider, _dictionaryLayoutProvider);
DependencyAnalyzerBase<NodeFactory> graph = CreateDependencyGraph(factory);
return new CppCodegenCompilation(graph, factory, _compilationRoots, _debugInformationProvider, _logger, _config);
return new CppCodegenCompilation(graph, factory, _compilationRoots, _ilProvider, _debugInformationProvider, _logger, _config);
}
}

Просмотреть файл

@ -425,10 +425,6 @@ namespace ILCompiler.CppCodeGen
try
{
// TODO: hacky special-case
if (method.Name == "_ecvt_s")
throw new NotImplementedException();
var ilImporter = new ILImporter(_compilation, this, method, methodIL);
CompilerTypeSystemContext typeSystemContext = _compilation.TypeSystemContext;
@ -1349,7 +1345,7 @@ namespace ILCompiler.CppCodeGen
{
string importName = externC.Key;
// TODO: hacky special-case
if (importName != "memmove" && importName != "malloc") // some methods are already declared by the CRT headers
if (importName != "memmove" && importName != "memset" && importName != "malloc") // some methods are already declared by the CRT headers
{
sb.AppendLine();
AppendCppMethodDeclaration(sb, null, false, importName, externC.Value);

Просмотреть файл

@ -694,7 +694,7 @@ namespace Internal.IL
{
AppendSemicolon();
AppendLine();
Append("memset(&");
Append("::memset(&");
Append(GetVarName(i, false));
Append(",0,sizeof(");
Append(_writer.GetCppSignatureTypeName(localType));
@ -2130,7 +2130,7 @@ namespace Internal.IL
TypeDesc type = (TypeDesc)_methodIL.GetObject(token);
var addr = _stack.Pop();
AppendLine();
Append("memset((void*)");
Append("::memset((void*)");
Append(addr);
Append(",0,sizeof(");
Append(GetSignatureTypeNameAndAddReference(type));
@ -2562,7 +2562,7 @@ namespace Internal.IL
if (_methodIL.IsInitLocals)
{
AppendLine();
Append("memset(");
Append("::memset(");
Append(bufferName);
Append(", 0, ");
Append(count);

Просмотреть файл

@ -50,8 +50,8 @@ namespace ILCompiler.DependencyAnalysisFramework.Tests
testGraph.AddRoot("A", "A is root");
List<string> results = testGraph.AnalysisResults;
Assert.True(results.Contains("A"));
Assert.True(results.Contains("B"));
Assert.Contains("A", results);
Assert.Contains("B", results);
});
}
@ -64,9 +64,9 @@ namespace ILCompiler.DependencyAnalysisFramework.Tests
testGraph.AddRoot("A", "A is root");
List<string> results = testGraph.AnalysisResults;
Assert.True(results.Contains("A"));
Assert.False(results.Contains("B"));
Assert.False(results.Contains("C"));
Assert.Contains("A", results);
Assert.DoesNotContain("B", results);
Assert.DoesNotContain("C", results);
Assert.True(results.Count == 1);
});
}
@ -81,9 +81,9 @@ namespace ILCompiler.DependencyAnalysisFramework.Tests
testGraph.AddRoot("C", "C is root");
List<string> results = testGraph.AnalysisResults;
Assert.True(results.Contains("A"));
Assert.True(results.Contains("B"));
Assert.True(results.Contains("C"));
Assert.Contains("A", results);
Assert.Contains("B", results);
Assert.Contains("C", results);
Assert.True(results.Count == 3);
});
}

Просмотреть файл

@ -4,7 +4,7 @@
<OutputType>Library</OutputType>
<AssemblyName>ILCompiler.DependencyAnalysisFramework.Tests</AssemblyName>
<RootNamespace>ILCompiler.DependencyAnalysisFramework.Tests</RootNamespace>
<TargetFramework>netstandard1.3</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\src\ILCompiler.DependencyAnalysisFramework.csproj" />
@ -13,8 +13,11 @@
<PackageReference Include="System.Collections.Immutable">
<Version>1.3.1</Version>
</PackageReference>
<PackageReference Include="Microsoft.DotNet.BuildTools.TestSuite">
<Version>$(XunitNetcoreExtensionsVersion)</Version>
<PackageReference Include="xunit">
<Version>$(XUnitPackageVersion)</Version>
</PackageReference>
<PackageReference Include="Microsoft.DotNet.XUnitExtensions">
<Version>$(MicrosoftDotNetXUnitExtensionsVersion)</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>

Просмотреть файл

@ -57,7 +57,7 @@ namespace MetadataTransformTests
return scope;
}
public void CheckTypeDefinitionForProperWinRTHome(TypeDefinition typeDefinition, string module)
private void CheckTypeDefinitionForProperWinRTHome(TypeDefinition typeDefinition, string module)
{
ScopeDefinition scope = GetScopeDefinitionOfType(typeDefinition);
Assert.Equal(module, scope.Name.Value);
@ -66,7 +66,7 @@ namespace MetadataTransformTests
}
public void CheckTypeReferenceForProperWinRTHome(TypeReference typeReference, string module)
private void CheckTypeReferenceForProperWinRTHome(TypeReference typeReference, string module)
{
ScopeReference scope = GetScopeReferenceOfType(typeReference);
Assert.Equal(module, scope.Name.Value);

Просмотреть файл

@ -4,11 +4,14 @@
<OutputType>Library</OutputType>
<AssemblyName>ILCompiler.MetadataTransform.Tests</AssemblyName>
<RootNamespace>MetadataTransformTests</RootNamespace>
<TargetFramework>netstandard1.3</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.DotNet.BuildTools.TestSuite">
<Version>$(XunitNetcoreExtensionsVersion)</Version>
<PackageReference Include="xunit">
<Version>$(XUnitPackageVersion)</Version>
</PackageReference>
<PackageReference Include="Microsoft.DotNet.XUnitExtensions">
<Version>$(MicrosoftDotNetXUnitExtensionsVersion)</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>

Просмотреть файл

@ -5,7 +5,7 @@
<PropertyGroup>
<OutputType>Library</OutputType>
<AssemblyName>ILMetadataAssembly</AssemblyName>
<RunTestsForProject>false</RunTestsForProject>
<SkipTestRun>true</SkipTestRun>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -5,7 +5,7 @@
<AssemblyName>PrimaryMetadataAssembly</AssemblyName>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<IsCoreAssembly>true</IsCoreAssembly>
<RunTestsForProject>false</RunTestsForProject>
<SkipTestRun>true</SkipTestRun>
</PropertyGroup>
<ItemGroup>
<Compile Include="Platform.cs" />

Просмотреть файл

@ -4,7 +4,7 @@
<OutputType>Library</OutputType>
<AssemblyName>SampleMetadataAssembly</AssemblyName>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RunTestsForProject>false</RunTestsForProject>
<SkipTestRun>true</SkipTestRun>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -4,7 +4,7 @@
<OutputType>Library</OutputType>
<AssemblyName>SampleWinRTMetadataAssembly</AssemblyName>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RunTestsForProject>false</RunTestsForProject>
<SkipTestRun>true</SkipTestRun>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -10,6 +10,8 @@ using Cts = Internal.TypeSystem;
using Xunit;
#pragma warning disable xUnit2013 // Do not use Assert.Equal() to check for collection size
namespace MetadataTransformTests
{
public class SimpleTests

Просмотреть файл

@ -4,7 +4,7 @@
<OutputType>Library</OutputType>
<AssemblyName>WindowsWinRTMetadataAssembly</AssemblyName>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RunTestsForProject>false</RunTestsForProject>
<SkipTestRun>true</SkipTestRun>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -34,10 +34,6 @@ namespace ILCompiler.DependencyAnalysis
{
return new RuntimeImportMethodNode(method);
}
// On CLR this would throw a SecurityException with "ECall methods must be packaged into a system module."
// This is a corner case that nobody is likely to care about.
ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramSpecific, method);
}
if (CompilationModuleGroup.ContainsMethodBody(method, false))

Просмотреть файл

@ -23,11 +23,12 @@ namespace ILCompiler
DependencyAnalyzerBase<NodeFactory> dependencyGraph,
NodeFactory nodeFactory,
IEnumerable<ICompilationRootProvider> roots,
ILProvider ilProvider,
DebugInformationProvider debugInformationProvider,
Logger logger,
DevirtualizationManager devirtualizationManager,
JitConfigProvider configProvider)
: base(dependencyGraph, nodeFactory, roots, debugInformationProvider, devirtualizationManager, logger)
: base(dependencyGraph, nodeFactory, roots, ilProvider, debugInformationProvider, devirtualizationManager, logger)
{
_jitConfigProvider = configProvider;
}

Просмотреть файл

@ -8,6 +8,7 @@ using System.Collections.Generic;
using ILCompiler.DependencyAnalysis;
using ILCompiler.DependencyAnalysisFramework;
using Internal.IL;
using Internal.JitInterface;
using Internal.TypeSystem;
@ -20,6 +21,7 @@ namespace ILCompiler
// These need to provide reasonable defaults so that the user can optionally skip
// calling the Use/Configure methods and still get something reasonable back.
private KeyValuePair<string, string>[] _ryujitOptions = Array.Empty<KeyValuePair<string, string>>();
private ILProvider _ilProvider = new CoreRTILProvider();
public RyuJitCompilationBuilder(CompilerTypeSystemContext context, CompilationModuleGroup group)
: base(context, group,
@ -52,6 +54,17 @@ namespace ILCompiler
return this;
}
public override CompilationBuilder UseILProvider(ILProvider ilProvider)
{
_ilProvider = ilProvider;
return this;
}
protected override ILProvider GetILProvider()
{
return _ilProvider;
}
public override ICompilation ToCompilation()
{
ArrayBuilder<CorJitFlag> jitFlagBuilder = new ArrayBuilder<CorJitFlag>();
@ -91,7 +104,7 @@ namespace ILCompiler
var jitConfig = new JitConfigProvider(jitFlagBuilder.ToArray(), _ryujitOptions);
DependencyAnalyzerBase<NodeFactory> graph = CreateDependencyGraph(factory, new ObjectNode.ObjectNodeComparer(new CompilerComparer()));
return new RyuJitCompilation(graph, factory, _compilationRoots, _debugInformationProvider, _logger, _devirtualizationManager, jitConfig);
return new RyuJitCompilation(graph, factory, _compilationRoots, _ilProvider, _debugInformationProvider, _logger, _devirtualizationManager, jitConfig);
}
}
}

Просмотреть файл

@ -5,7 +5,7 @@
<AssemblyName>CoreTestAssembly</AssemblyName>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<IsCoreAssembly>true</IsCoreAssembly>
<RunTestsForProject>false</RunTestsForProject>
<SkipTestRun>true</SkipTestRun>
</PropertyGroup>
<ItemGroup>
<Compile Include="Canonicalization.cs" />

Просмотреть файл

@ -35,19 +35,19 @@ namespace TypeSystemTests
{
var map = GCPointerMap.FromInstanceLayout(classWithArrayFields);
Assert.Equal(map.Size, 3);
Assert.Equal(3, map.Size);
Assert.Equal("011", map.ToString());
}
{
var map = GCPointerMap.FromInstanceLayout(classWithStringField);
Assert.Equal(map.Size, 4);
Assert.Equal(4, map.Size);
Assert.Equal("0010", map.ToString());
}
{
var map = GCPointerMap.FromInstanceLayout(mixedStruct);
Assert.Equal(map.Size, 5);
Assert.Equal(5, map.Size);
Assert.Equal("01001", map.ToString());
}
@ -60,19 +60,19 @@ namespace TypeSystemTests
{
var map = GCPointerMap.FromInstanceLayout(doubleMixedStructLayout);
Assert.Equal(map.Size, 10);
Assert.Equal(10, map.Size);
Assert.Equal("0100101001", map.ToString());
}
{
var map = GCPointerMap.FromInstanceLayout(explicitlyFarPointer);
Assert.Equal(map.Size, 117);
Assert.Equal(117, map.Size);
Assert.Equal("100000000000000000000000000000000000000000000000000000000000000010000000000000001000000000000000000000000000000001001", map.ToString());
}
{
var map = GCPointerMap.FromInstanceLayout(struct32GcPointers);
Assert.Equal(map.Size, 32);
Assert.Equal(32, map.Size);
Assert.Equal("11111111111111111111111111111111", map.ToString());
}
}
@ -82,7 +82,7 @@ namespace TypeSystemTests
{
MetadataType mixedStaticClass = _testModule.GetType("GCPointerMap", "MixedStaticClass");
var map = GCPointerMap.FromStaticLayout(mixedStaticClass);
Assert.Equal(map.Size, 12);
Assert.Equal(12, map.Size);
Assert.Equal("010100101001", map.ToString());
}
@ -91,7 +91,7 @@ namespace TypeSystemTests
{
MetadataType mixedThreadStaticClass = _testModule.GetType("GCPointerMap", "MixedThreadStaticClass");
var map = GCPointerMap.FromThreadStaticLayout(mixedThreadStaticClass);
Assert.Equal(map.Size, 14);
Assert.Equal(14, map.Size);
Assert.Equal("00010010100110", map.ToString());
}
}

Просмотреть файл

@ -33,8 +33,7 @@ namespace TypeSystemTests
// Verify that we get just type definitions.
Assert.NotNull(t);
Assert.True(t.IsTypeDefinition);
Assert.NotNull(t.Instantiation);
Assert.Equal(t.Instantiation.Length, 1);
Assert.Equal(1, t.Instantiation.Length);
Assert.True(t.Instantiation[0].IsTypeDefinition);
// Verify that we got a method definition
@ -50,14 +49,13 @@ namespace TypeSystemTests
// Verify properties of the instantiated type
Assert.NotNull(instantiatedType);
Assert.False(instantiatedType.IsTypeDefinition);
Assert.NotNull(instantiatedType.Instantiation);
Assert.Equal(instantiatedType.Instantiation.Length, 1);
Assert.Equal(instantiatedType.Instantiation[0], _context.GetWellKnownType(WellKnownType.Int32));
Assert.Equal(1, instantiatedType.Instantiation.Length);
Assert.Equal(_context.GetWellKnownType(WellKnownType.Int32), instantiatedType.Instantiation[0]);
// Verify that we get an instantiated method with the proper signature
MethodDesc fooInstantiatedMethod = instantiatedType.GetMethods().First(m => m.Name == "Foo");
Assert.False(fooInstantiatedMethod.IsTypicalMethodDefinition);
Assert.Equal(fooInstantiatedMethod.Signature.ReturnType, _context.GetWellKnownType(WellKnownType.Int32));
Assert.Equal(_context.GetWellKnownType(WellKnownType.Int32), fooInstantiatedMethod.Signature.ReturnType);
Assert.Same(fooInstantiatedMethod.GetTypicalMethodDefinition(), fooMethod);
// This is not a generic method, so they should be the same
Assert.Same(fooInstantiatedMethod.GetMethodDefinition(), fooInstantiatedMethod);
@ -137,16 +135,16 @@ namespace TypeSystemTests
InstantiatedType genericOfIntString = genericOpenType.MakeInstantiatedType(intType, stringType);
InstantiatedType genericOfIntObject = genericOpenType.MakeInstantiatedType(intType, objectType);
Assert.Equal(true, genericOfCharObject.IsConstructedOverType(new TypeDesc[] { charType }));
Assert.Equal(true, genericOfCharObject.IsConstructedOverType(new TypeDesc[] { objectType }));
Assert.Equal(false, genericOfCharObject.IsConstructedOverType(new TypeDesc[] { intType }));
Assert.Equal(false, genericOfCharObject.IsConstructedOverType(new TypeDesc[] { stringType }));
Assert.Equal(false, genericOfCharObject.IsConstructedOverType(new TypeDesc[] { genericOpenType }));
Assert.True(genericOfCharObject.IsConstructedOverType(new TypeDesc[] { charType }));
Assert.True(genericOfCharObject.IsConstructedOverType(new TypeDesc[] { objectType }));
Assert.False(genericOfCharObject.IsConstructedOverType(new TypeDesc[] { intType }));
Assert.False(genericOfCharObject.IsConstructedOverType(new TypeDesc[] { stringType }));
Assert.False(genericOfCharObject.IsConstructedOverType(new TypeDesc[] { genericOpenType }));
Assert.Equal(true, genericOfCharString.IsConstructedOverType(new TypeDesc[] { charType }));
Assert.Equal(false, genericOfCharString.IsConstructedOverType(new TypeDesc[] { objectType }));
Assert.Equal(false, genericOfCharString.IsConstructedOverType(new TypeDesc[] { intType }));
Assert.Equal(true, genericOfCharString.IsConstructedOverType(new TypeDesc[] { stringType }));
Assert.True(genericOfCharString.IsConstructedOverType(new TypeDesc[] { charType }));
Assert.False(genericOfCharString.IsConstructedOverType(new TypeDesc[] { objectType }));
Assert.False(genericOfCharString.IsConstructedOverType(new TypeDesc[] { intType }));
Assert.True(genericOfCharString.IsConstructedOverType(new TypeDesc[] { stringType }));
// Test direct replacement
TypeDesc testDirectReplaceAllTypes = genericOfCharObject.ReplaceTypesInConstructionOfType(new TypeDesc[] { charType, objectType }, new TypeDesc[] { intType, stringType });
@ -197,8 +195,8 @@ namespace TypeSystemTests
TypeDesc testReplaceTypeInPointer = charPointer.ReplaceTypesInConstructionOfType(new TypeDesc[] { charType }, new TypeDesc[] { intType });
Assert.Equal(intPointer, testReplaceTypeInPointer);
Assert.Equal(true, charPointer.IsConstructedOverType(new TypeDesc[] { charType }));
Assert.Equal(false, charPointer.IsConstructedOverType(new TypeDesc[] { intType }));
Assert.True(charPointer.IsConstructedOverType(new TypeDesc[] { charType }));
Assert.False(charPointer.IsConstructedOverType(new TypeDesc[] { intType }));
// Test byref
TypeDesc charByRef = _context.GetByRefType(charType);
@ -206,13 +204,13 @@ namespace TypeSystemTests
TypeDesc testReplaceTypeInByRef = charByRef.ReplaceTypesInConstructionOfType(new TypeDesc[] { charType }, new TypeDesc[] { intType });
Assert.Equal(intByRef, testReplaceTypeInByRef);
Assert.Equal(true, charByRef.IsConstructedOverType(new TypeDesc[] { charType }));
Assert.Equal(false, charByRef.IsConstructedOverType(new TypeDesc[] { intType }));
Assert.True(charByRef.IsConstructedOverType(new TypeDesc[] { charType }));
Assert.False(charByRef.IsConstructedOverType(new TypeDesc[] { intType }));
// Test replace type entirely
TypeDesc testReplaceTypeEntirely = charByRef.ReplaceTypesInConstructionOfType(new TypeDesc[] { charByRef }, new TypeDesc[] { intByRef });
Assert.Equal(intByRef, testReplaceTypeEntirely);
Assert.Equal(true, charByRef.IsConstructedOverType(new TypeDesc[] { charByRef }));
Assert.True(charByRef.IsConstructedOverType(new TypeDesc[] { charByRef }));
}
[Fact]
@ -273,4 +271,4 @@ namespace TypeSystemTests
Assert.Equal(getMethodOnMDCharArray, testArrayMethodCase);
}
}
}
}

Просмотреть файл

@ -4,7 +4,7 @@
<PropertyGroup>
<OutputType>Library</OutputType>
<AssemblyName>ILTestAssembly</AssemblyName>
<RunTestsForProject>false</RunTestsForProject>
<SkipTestRun>true</SkipTestRun>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -4,16 +4,16 @@
<OutputType>Library</OutputType>
<AssemblyName>TypeSystem.Tests</AssemblyName>
<RootNamespace>TypeSystem.Tests</RootNamespace>
<TargetFramework>netstandard1.3</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
<!-- Don't warn if some dependencies were rolled forward -->
<NoWarn>$(NoWarn);NU1603</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.DotNet.BuildTools.TestSuite">
<Version>$(XunitNetcoreExtensionsVersion)</Version>
<PackageReference Include="xunit">
<Version>$(XUnitPackageVersion)</Version>
</PackageReference>
<PackageReference Include="Microsoft.xunit.netcore.extensions">
<Version>$(XunitNetcoreExtensionsVersion)</Version>
<PackageReference Include="Microsoft.DotNet.XUnitExtensions">
<Version>$(MicrosoftDotNetXUnitExtensionsVersion)</Version>
</PackageReference>
<PackageReference Include="System.Reflection.Metadata">
<Version>1.4.2</Version>

Просмотреть файл

@ -268,7 +268,7 @@ namespace TypeSystemTests
Assert.Equal(LayoutInt.Indeterminate, genOfUUU.GetFields().ElementAt(2).Offset);
}
public void TestIndeterminatedNestedStructFieldPerContext(TypeSystemContext context, ModuleDesc testModule, out InstantiatedType genOfIntNestedInt, out InstantiatedType genOfLongNestedInt)
private void TestIndeterminatedNestedStructFieldPerContext(TypeSystemContext context, ModuleDesc testModule, out InstantiatedType genOfIntNestedInt, out InstantiatedType genOfLongNestedInt)
{
// Given a struct with all field universal, what is the layout?
MetadataType tGen = testModule.GetType("GenericTypes", "GenStruct`3");
@ -310,7 +310,7 @@ namespace TypeSystemTests
Assert.Equal(LayoutInt.Indeterminate, genOfLongNestedInt.InstanceByteAlignment);
}
public void AssertClassIndeterminateSize(TypeSystemContext context, MetadataType type, LayoutInt expectedIndeterminateByteAlignment)
private void AssertClassIndeterminateSize(TypeSystemContext context, MetadataType type, LayoutInt expectedIndeterminateByteAlignment)
{
Assert.Equal(context.Target.LayoutPointerSize, type.InstanceFieldAlignment);
Assert.Equal(context.Target.LayoutPointerSize, type.InstanceFieldSize);

Просмотреть файл

@ -54,6 +54,7 @@ namespace Internal.IL
private readonly byte[] _ilBytes;
private MethodDebugInformation _debugInformation;
private LLVMMetadataRef _debugFunction;
private TypeDesc _constrainedType = null;
/// <summary>
/// Stack of values pushed onto the IL stack: locals, arguments, values, function pointer, ...
@ -503,6 +504,10 @@ namespace Internal.IL
private void EndImportingInstruction()
{
// If this was constrained used in a call, it's already been cleared,
// but if it was on some other instruction, it shoudln't carry forward
_constrainedType = null;
// Reset the debug position so it doesn't end up applying to the wrong instructions
LLVM.SetCurrentDebugLocation(_builder, default(LLVMValueRef));
}
@ -1198,7 +1203,7 @@ namespace Internal.IL
}
}
if (callee.IsPInvoke || (callee.IsInternalCall && callee.HasCustomAttribute("System.Runtime", "RuntimeImportAttribute")))
if (callee.IsRawPInvoke() || (callee.IsInternalCall && callee.HasCustomAttribute("System.Runtime", "RuntimeImportAttribute")))
{
ImportRawPInvoke(callee);
return;
@ -1267,12 +1272,6 @@ namespace Internal.IL
}
}
// we don't really have virtual call support, but we'll treat it as direct for now
if (opcode != ILOpcode.call && opcode != ILOpcode.callvirt && opcode != ILOpcode.newobj)
{
throw new NotImplementedException();
}
if (opcode == ILOpcode.newobj && callee.OwningType.IsDelegate)
{
FunctionPointerEntry functionPointer = ((FunctionPointerEntry)_stack.Peek());
@ -1284,10 +1283,12 @@ namespace Internal.IL
}
}
HandleCall(callee, callee.Signature, opcode);
TypeDesc localConstrainedType = _constrainedType;
_constrainedType = null;
HandleCall(callee, callee.Signature, opcode, localConstrainedType);
}
private LLVMValueRef LLVMFunctionForMethod(MethodDesc callee, StackEntry thisPointer, bool isCallVirt)
private LLVMValueRef LLVMFunctionForMethod(MethodDesc callee, StackEntry thisPointer, bool isCallVirt, TypeDesc constrainedType)
{
string calleeName = _compilation.NameMangler.GetMangledMethodName(callee).ToString();
@ -1321,17 +1322,23 @@ namespace Internal.IL
isValueTypeCall = true;
}
}
if (callee.OwningType.IsInterface)
if(constrainedType != null && constrainedType.IsValueType)
{
// For value types, devirtualize the call
if (isValueTypeCall)
isValueTypeCall = true;
}
if (isValueTypeCall)
{
if (constrainedType != null)
{
targetMethod = constrainedType.TryResolveConstraintMethodApprox(callee.OwningType, callee, out _);
}
else if (callee.OwningType.IsInterface)
{
targetMethod = parameterType.ResolveInterfaceMethodTarget(callee);
}
}
else
{
if (isValueTypeCall)
else
{
targetMethod = parameterType.FindVirtualFunctionTargetMethodOnObjectType(callee);
}
@ -1584,7 +1591,7 @@ namespace Internal.IL
return false;
}
private void HandleCall(MethodDesc callee, MethodSignature signature, ILOpcode opcode = ILOpcode.call, LLVMValueRef calliTarget = default(LLVMValueRef))
private void HandleCall(MethodDesc callee, MethodSignature signature, ILOpcode opcode = ILOpcode.call, TypeDesc constrainedType = null, LLVMValueRef calliTarget = default(LLVMValueRef))
{
var parameterCount = signature.Length + (signature.IsStatic ? 0 : 1);
// The last argument is the top of the stack. We need to reverse them and store starting at the first argument
@ -1593,10 +1600,34 @@ namespace Internal.IL
{
argumentValues[argumentValues.Length - i - 1] = _stack.Pop();
}
PushNonNull(HandleCall(callee, signature, argumentValues, opcode, calliTarget));
if (constrainedType != null)
{
if (signature.IsStatic)
{
// Constrained call on static method
ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramSpecific, _method);
}
StackEntry thisByRef = argumentValues[0];
if (thisByRef.Kind != StackValueKind.ByRef)
{
// Constrained call without byref
ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramSpecific, _method);
}
// If this is a constrained call and the 'this' pointer is a reference type, it's a byref,
// dereference it before calling.
if (!constrainedType.IsValueType)
{
TypeDesc objectType = thisByRef.Type.GetParameterType();
argumentValues[0] = new LoadExpressionEntry(StackValueKind.ObjRef, "thisPtr", thisByRef.ValueAsType(objectType, _builder), objectType);
}
}
PushNonNull(HandleCall(callee, signature, argumentValues, opcode, constrainedType, calliTarget));
}
private ExpressionEntry HandleCall(MethodDesc callee, MethodSignature signature, StackEntry[] argumentValues, ILOpcode opcode = ILOpcode.call, LLVMValueRef calliTarget = default(LLVMValueRef), TypeDesc forcedReturnType = null)
private ExpressionEntry HandleCall(MethodDesc callee, MethodSignature signature, StackEntry[] argumentValues, ILOpcode opcode = ILOpcode.call, TypeDesc constrainedType = null, LLVMValueRef calliTarget = default(LLVMValueRef), TypeDesc forcedReturnType = null)
{
if (opcode == ILOpcode.callvirt && callee.IsVirtual)
{
@ -1687,7 +1718,7 @@ namespace Internal.IL
}
else
{
fn = LLVMFunctionForMethod(callee, signature.IsStatic ? null : argumentValues[0], opcode == ILOpcode.callvirt);
fn = LLVMFunctionForMethod(callee, signature.IsStatic ? null : argumentValues[0], opcode == ILOpcode.callvirt, constrainedType);
}
LLVMValueRef llvmReturn = LLVM.BuildCall(_builder, fn, llvmArgs.ToArray(), string.Empty);
@ -1955,7 +1986,7 @@ namespace Internal.IL
private void ImportCalli(int token)
{
MethodSignature methodSignature = (MethodSignature)_methodIL.GetObject(token);
HandleCall(null, methodSignature, ILOpcode.calli, ((ExpressionEntry)_stack.Pop()).ValueAsType(LLVM.PointerType(GetLLVMSignatureForMethod(methodSignature), 0), _builder));
HandleCall(null, methodSignature, ILOpcode.calli, calliTarget: ((ExpressionEntry)_stack.Pop()).ValueAsType(LLVM.PointerType(GetLLVMSignatureForMethod(methodSignature), 0), _builder));
}
private void ImportLdFtn(int token, ILOpcode opCode)
@ -1967,7 +1998,7 @@ namespace Internal.IL
StackEntry thisPointer = _stack.Pop();
if (method.IsVirtual)
{
targetLLVMFunction = LLVMFunctionForMethod(method, thisPointer, true);
targetLLVMFunction = LLVMFunctionForMethod(method, thisPointer, true, null);
AddVirtualMethodReference(method);
}
}
@ -2652,6 +2683,7 @@ namespace Internal.IL
private void ImportConstrainedPrefix(int token)
{
_constrainedType = (TypeDesc)_methodIL.GetObject(token);
}
private void ImportNoPrefix(byte mask)

Просмотреть файл

@ -5,6 +5,7 @@
using System.Collections.Generic;
using Internal.TypeSystem;
using Internal.IL;
using ILCompiler.DependencyAnalysis;
using ILCompiler.DependencyAnalysisFramework;
@ -24,10 +25,11 @@ namespace ILCompiler
DependencyAnalyzerBase<NodeFactory> dependencyGraph,
WebAssemblyCodegenNodeFactory nodeFactory,
IEnumerable<ICompilationRootProvider> roots,
ILProvider ilProvider,
DebugInformationProvider debugInformationProvider,
Logger logger,
WebAssemblyCodegenConfigProvider options)
: base(dependencyGraph, nodeFactory, GetCompilationRoots(roots, nodeFactory), debugInformationProvider, null, logger)
: base(dependencyGraph, nodeFactory, GetCompilationRoots(roots, nodeFactory), ilProvider, debugInformationProvider, null, logger)
{
NodeFactory = nodeFactory;
Module = LLVM.ModuleCreateWithName("netscripten");
@ -56,7 +58,7 @@ namespace ILCompiler
{
foreach (WebAssemblyMethodCodeNode methodCodeNodeNeedingCode in obj)
{
Internal.IL.ILImporter.CompileMethod(this, methodCodeNodeNeedingCode);
ILImporter.CompileMethod(this, methodCodeNodeNeedingCode);
}
}
}

Просмотреть файл

@ -8,6 +8,7 @@ using System.Collections.Generic;
using ILCompiler.DependencyAnalysis;
using ILCompiler.DependencyAnalysisFramework;
using Internal.IL;
using Internal.TypeSystem;
namespace ILCompiler
@ -17,6 +18,7 @@ namespace ILCompiler
// These need to provide reasonable defaults so that the user can optionally skip
// calling the Use/Configure methods and still get something reasonable back.
WebAssemblyCodegenConfigProvider _config = new WebAssemblyCodegenConfigProvider(Array.Empty<string>());
private ILProvider _ilProvider = new CoreRTILProvider();
public WebAssemblyCodegenCompilationBuilder(CompilerTypeSystemContext context, CompilationModuleGroup group)
: base(context, group, new CoreRTNameMangler(new WebAssemblyNodeMangler(), false))
@ -29,12 +31,23 @@ namespace ILCompiler
return this;
}
public override CompilationBuilder UseILProvider(ILProvider ilProvider)
{
_ilProvider = ilProvider;
return this;
}
protected override ILProvider GetILProvider()
{
return _ilProvider;
}
public override ICompilation ToCompilation()
{
var interopStubManager = new CompilerGeneratedInteropStubManager(_compilationGroup, _context, new InteropStateManager(_context.GeneratedAssembly));
WebAssemblyCodegenNodeFactory factory = new WebAssemblyCodegenNodeFactory(_context, _compilationGroup, _metadataManager, interopStubManager, _nameMangler, _vtableSliceProvider, _dictionaryLayoutProvider);
DependencyAnalyzerBase<NodeFactory> graph = CreateDependencyGraph(factory, new ObjectNode.ObjectNodeComparer(new CompilerComparer()));
return new WebAssemblyCodegenCompilation(graph, factory, _compilationRoots, _debugInformationProvider, _logger, _config);
return new WebAssemblyCodegenCompilation(graph, factory, _compilationRoots, _ilProvider, _debugInformationProvider, _logger, _config);
}
}

Просмотреть файл

@ -34,7 +34,12 @@ namespace ILVerify
public void SetSystemModuleName(AssemblyName name)
{
_typeSystemContext.SetSystemModule(_typeSystemContext.GetModule(_typeSystemContext._resolver.Resolve(name.Name)));
PEReader peReader = _typeSystemContext._resolver.Resolve(name.Name);
if (peReader is null)
{
throw new VerifierException("Assembly or module not found: " + name.FullName);
}
_typeSystemContext.SetSystemModule(_typeSystemContext.GetModule(peReader));
}
internal EcmaModule GetModule(PEReader peReader)
@ -161,7 +166,7 @@ namespace ILVerify
private IEnumerable<VerificationResult> VerifyMethod(EcmaModule module, MethodIL methodIL, MethodDefinitionHandle methodHandle)
{
var builder = new ArrayBuilder<VerificationResult>();
MethodDesc method = methodIL.OwningMethod;
MethodDesc method = methodIL.OwningMethod;
try
{

Просмотреть файл

@ -20,7 +20,7 @@ namespace ILVerification.Tests
void TestMethodsWithValidIL(ValidILTestCase validIL)
{
var results = Verify(validIL);
Assert.Equal(0, results.Count());
Assert.Empty(results);
}
[Theory(DisplayName = "")]

Просмотреть файл

@ -0,0 +1,3 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="ILTests.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="ILTests.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="ILTests.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="ILTests.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="ILTests.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="ILTests.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="ILTests.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="ILTests.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="ILTests.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="ILTests.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="ILTests.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="ILTests.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="ILTests.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,17 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<OutputType>Library</OutputType>
<AssemblyName>$(MSBuildProjectName)</AssemblyName>
<OutputPath>$(BaseOutputPath)$(OSPlatformConfig)/ILVerification.Tests/Tests</OutputPath>
<SkipTestRun>true</SkipTestRun>
<SkipSigning>true</SkipSigning>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).il" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="ILTests.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="ILTests.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="ILTests.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="ILTests.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="ILTests.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="ILTests.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="ILTests.targets" />
</Project>

Просмотреть файл

@ -3,7 +3,7 @@
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>netstandard1.5</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
@ -14,16 +14,21 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0-preview-20170427-09" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
<PackageReference Include="xunit" Version="$(XUnitPackageVersion)" />
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\src\ILVerification.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="ILTests\*.ilproj">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<OutputItemType>Content</OutputItemType>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>

Просмотреть файл

@ -20,19 +20,17 @@ namespace ILVerification.Tests
{
/// <summary>
/// Parses the methods in the test assemblies.
/// It loads all assemblies from the test folder defined in <code>TestDataLoader.TESTASSEMBLYPATH</code>
/// It loads all assemblies from the test folder defined in <code>TestDataLoader.TestAssemblyPath</code>
/// This class feeds the xunit Theories
/// </summary>
class TestDataLoader
{
/// <summary>
/// The folder with the binaries which are compiled from the test driver IL Code
/// Currently the test .il code is built manually, but the plan is to have a ProjectReference and automatically build the .il files.
/// See: https://github.com/dotnet/corert/pull/3725#discussion_r118820770
/// The folder with the test binaries
/// </summary>
public static string TESTASSEMBLYPATH = @"..\..\..\ILTests\";
private const string TestAssemblyPath = @"Tests\";
private const string SPECIALTEST_PREFIX = "special.";
private const string SpecialTestPrefix = "special.";
/// <summary>
/// Returns all methods that contain valid IL code based on the following naming convention:
@ -129,11 +127,11 @@ namespace ILVerification.Tests
private static MethodDefinitionHandle HandleSpecialTests(string[] methodParams, EcmaMethod method)
{
if (!methodParams[0].StartsWith(SPECIALTEST_PREFIX))
if (!methodParams[0].StartsWith(SpecialTestPrefix))
return method.Handle;
// Cut off special prefix
var specialParams = methodParams[0].Substring(SPECIALTEST_PREFIX.Length);
var specialParams = methodParams[0].Substring(SpecialTestPrefix.Length);
// Get friendly name / special name
int delimiter = specialParams.IndexOf('.');
@ -152,7 +150,7 @@ namespace ILVerification.Tests
private static IEnumerable<string> GetAllTestDlls()
{
foreach (var item in Directory.GetFiles(TESTASSEMBLYPATH))
foreach (var item in Directory.GetFiles(TestAssemblyPath))
{
if (item.ToLower().EndsWith(".dll"))
{
@ -167,7 +165,7 @@ namespace ILVerification.Tests
foreach (var fileName in GetAllTestDlls())
{
simpleNameToPathMap.Add(Path.GetFileNameWithoutExtension(fileName), TESTASSEMBLYPATH + fileName);
simpleNameToPathMap.Add(Path.GetFileNameWithoutExtension(fileName), TestAssemblyPath + fileName);
}
Assembly coreAssembly = typeof(object).GetTypeInfo().Assembly;

Просмотреть файл

@ -27,18 +27,6 @@ The code is split into three projects:
To test the ILVerification library we have small methods checked in as .il files testing specific verification scenarios. These tests live under [src/ILVerification/tests/ILTests](../ILVerification/tests/ILTests). Tests are grouped into .il files based on functionalities they test. There is no strict policy here, the goal is to have a few dozen .il files instead of thousands containing each only a single method.
Currently the IL files are NOT compiled automatically. You have to compile manually (We want to automate this step later):
```
ilasm [filename.il] /dll /ERROR
```
Note: if you run the tests and get an error similar to this then it means that the .il files were not compiled, or none of them contained methods that follow the naming convention described below:
```
Result Message: System.InvalidOperationException : No data found for ILVerify.Tests.ILMethodTester.TestMethodsWithInvalidIL
```
The test project itself is under [src/ILVerification/tests](../ILVerification/tests)
Method names in the .il files must follow the following naming convention:

Просмотреть файл

@ -45,6 +45,12 @@ namespace Internal.JitInterface
ARM = 0x01c4,
}
#if SUPPORT_JIT
private const string JitSupportLibrary = "*";
#else
private const string JitSupportLibrary = "jitinterface";
#endif
private IntPtr _jit;
private IntPtr _unmanagedCallbacks; // array of pointers to JIT-EE interface callbacks
@ -58,7 +64,7 @@ namespace Internal.JitInterface
[DllImport("clrjitilc", CallingConvention=CallingConvention.StdCall)]
private extern static IntPtr getJit();
[DllImport("jitinterface")]
[DllImport(JitSupportLibrary)]
private extern static IntPtr GetJitHost(IntPtr configProvider);
//
@ -71,15 +77,15 @@ namespace Internal.JitInterface
return _this;
}
[DllImport("jitinterface")]
[DllImport(JitSupportLibrary)]
private extern static CorJitResult JitCompileMethod(out IntPtr exception,
IntPtr jit, IntPtr thisHandle, IntPtr callbacks,
ref CORINFO_METHOD_INFO info, uint flags, out IntPtr nativeEntry, out uint codeSize);
[DllImport("jitinterface")]
[DllImport(JitSupportLibrary)]
private extern static uint GetMaxIntrinsicSIMDVectorLength(IntPtr jit, CORJIT_FLAGS* flags);
[DllImport("jitinterface")]
[DllImport(JitSupportLibrary)]
private extern static IntPtr AllocException([MarshalAs(UnmanagedType.LPWStr)]string message, int messageLength);
private IntPtr AllocException(Exception ex)
@ -96,10 +102,10 @@ namespace Internal.JitInterface
return nativeException;
}
[DllImport("jitinterface")]
[DllImport(JitSupportLibrary)]
private extern static void FreeException(IntPtr obj);
[DllImport("jitinterface")]
[DllImport(JitSupportLibrary)]
private extern static char* GetExceptionMessage(IntPtr obj);
private JitConfigProvider _jitConfig;

Просмотреть файл

@ -294,15 +294,15 @@ public:
union
{
vlReg vlReg;
vlStk vlStk;
vlRegReg vlRegReg;
vlRegStk vlRegStk;
vlStkReg vlStkReg;
vlStk2 vlStk2;
vlFPstk vlFPstk;
vlFixedVarArg vlFixedVarArg;
vlMemory vlMemory;
ICorDebugInfo::vlReg vlReg;
ICorDebugInfo::vlStk vlStk;
ICorDebugInfo::vlRegReg vlRegReg;
ICorDebugInfo::vlRegStk vlRegStk;
ICorDebugInfo::vlStkReg vlStkReg;
ICorDebugInfo::vlStk2 vlStk2;
ICorDebugInfo::vlFPstk vlFPstk;
ICorDebugInfo::vlFixedVarArg vlFixedVarArg;
ICorDebugInfo::vlMemory vlMemory;
};
};

Просмотреть файл

@ -1,7 +1,6 @@
project(System.Private.CoreLib.Native)
set(NATIVE_SOURCES
pal_cruntime.cpp
pal_datetime.cpp
pal_dynamicload.cpp
pal_environment.cpp

Просмотреть файл

@ -1,17 +0,0 @@
// 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.
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
extern "C" int CoreLibNative_DoubleToString(double value, char *format, char *buffer, int bufferLength)
{
assert(buffer != NULL && format != NULL);
// return number of characters written to the buffer. if the return value greater than bufferLength
// means the number of characters would be written to the buffer if there is enough space
return snprintf(buffer, bufferLength, format, value);
}

Просмотреть файл

@ -7,15 +7,23 @@ set(NATIVE_SOURCES
corinfoexception.cpp
)
set (JIT_SOURCES
CodeHeap.cpp
JITCodeManager.cpp
../Runtime/coreclr/GCInfoDecoder.cpp
)
if(WIN32 AND CLR_CMAKE_PLATFORM_ARCH_AMD64)
set(NATIVE_SOURCES ${NATIVE_SOURCES}
CodeHeap.cpp
JITCodeManager.cpp
../Runtime/coreclr/GCInfoDecoder.cpp
)
add_definitions(-DGCINFODECODER_NO_EE)
add_definitions(-DFEATURE_REDHAWK)
add_definitions(-DFEATURE_SINGLE_MODULE_RUNTIME)
add_library(System.Private.Jit.Native
STATIC
${NATIVE_SOURCES}
${JIT_SOURCES}
)
endif(WIN32 AND CLR_CMAKE_PLATFORM_ARCH_AMD64)
add_library(jitinterface
@ -27,4 +35,5 @@ install (TARGETS jitinterface DESTINATION tools)
if(WIN32)
target_link_libraries(jitinterface ntdll.lib)
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/jitinterface.pdb DESTINATION tools)
install (TARGETS System.Private.Jit.Native DESTINATION sdk)
endif(WIN32)

Просмотреть файл

@ -18,13 +18,23 @@ static void *s_topAddress = nullptr;
static DWORD s_pageSize = 0;
extern HMODULE s_hRuntime;
#if FEATURE_SINGLE_MODULE_RUNTIME
extern "C" void RhpNewArray();
#endif
void InitMemoryStatics()
{
std::call_once(s_staticInit, []()
{
HMODULE module = s_hRuntime;
if (module != NULL)
{
#if FEATURE_SINGLE_MODULE_RUNTIME
s_mrtAddr = &RhpNewArray;
#else
s_mrtAddr = GetProcAddress(module, "RhpNewArray");
#endif
}
assert(s_mrtAddr != nullptr);

Просмотреть файл

@ -46,14 +46,24 @@ HMODULE s_hRuntime = NULL;
pfnRegisterCodeManager s_pfnRegisterCodeManager;
pfnUnregisterCodeManager s_pfnUnregisterCodeManager;
#if FEATURE_SINGLE_MODULE_RUNTIME
extern "C" bool RegisterCodeManager(ICodeManager * pCodeManager, PTR_VOID pvStartRange, UInt32 cbRange);
extern "C" void UnregisterCodeManager(ICodeManager * pCodeManager);
#endif
bool InitializeCodeManagerRuntime()
{
std::call_once(s_RuntimeInit, []()
{
if (s_hRuntime != NULL)
{
#if FEATURE_SINGLE_MODULE_RUNTIME
s_pfnRegisterCodeManager = &RegisterCodeManager;
s_pfnUnregisterCodeManager = &UnregisterCodeManager;
#else
s_pfnRegisterCodeManager = (pfnRegisterCodeManager)GetProcAddress(s_hRuntime, "RegisterCodeManager");
s_pfnUnregisterCodeManager = (pfnUnregisterCodeManager)GetProcAddress(s_hRuntime, "UnregisterCodeManager");
#endif
}
});
@ -259,7 +269,7 @@ bool JITCodeManager::Initialize()
// Note that main method bodies will not have an entry in the map.
PTR_RUNTIME_FUNCTION JITCodeManager::AllocRuntimeFunction(PTR_RUNTIME_FUNCTION mainMethod, DWORD beginAddr, DWORD endAddr, DWORD unwindData)
{
ReaderWriterLock::WriteHolder lh(&m_lock);
SlimReaderWriterLock::WriteHolder lh(&m_lock);
m_runtimeFunctions.push_back(RUNTIME_FUNCTION());
PTR_RUNTIME_FUNCTION method = &m_runtimeFunctions.back();
@ -278,7 +288,7 @@ PTR_RUNTIME_FUNCTION JITCodeManager::AllocRuntimeFunction(PTR_RUNTIME_FUNCTION m
void JITCodeManager::UpdateRuntimeFunctionTable()
{
ReaderWriterLock::WriteHolder lh(&m_lock);
SlimReaderWriterLock::WriteHolder lh(&m_lock);
PTR_RUNTIME_FUNCTION pFunctionTable = &m_runtimeFunctions[0];
DWORD nEntryCount = (DWORD)m_runtimeFunctions.size();
@ -381,7 +391,7 @@ bool JITCodeManager::FindMethodInfo(PTR_VOID ControlPC,
if (RelativePC >= m_cbRange)
return false;
ReaderWriterLock::ReadHolder lh(&m_lock);
SlimReaderWriterLock::ReadHolder lh(&m_lock);
int MethodIndex = LookupUnwindInfoForMethod((UInt32)RelativePC, m_pRuntimeFunctionTable,
0, m_nRuntimeFunctionTable - 1);
@ -420,7 +430,7 @@ bool JITCodeManager::IsFunclet(MethodInfo * pMethInfo)
JITMethodInfo * pMethodInfo = (JITMethodInfo *)pMethInfo;
// A funclet will have an entry in funclet to main method map
ReaderWriterLock::ReadHolder lh(&m_lock);
SlimReaderWriterLock::ReadHolder lh(&m_lock);
return m_FuncletToMainMethodMap.find(pMethodInfo->runtimeFunction.BeginAddress) != m_FuncletToMainMethodMap.end();
}

Просмотреть файл

@ -51,19 +51,19 @@ typedef DPTR(struct _UNWIND_INFO) PTR_UNWIND_INFO;
typedef DPTR(union _UNWIND_CODE) PTR_UNWIND_CODE;
#endif // target_amd64
class ReaderWriterLock : private SRWLOCK
class SlimReaderWriterLock : private SRWLOCK
{
public:
ReaderWriterLock()
SlimReaderWriterLock()
{
::InitializeSRWLock(this);
}
class ReadHolder
{
ReaderWriterLock * m_pLock;
SlimReaderWriterLock * m_pLock;
public:
ReadHolder(ReaderWriterLock * pLock)
ReadHolder(SlimReaderWriterLock * pLock)
: m_pLock(pLock)
{
::AcquireSRWLockShared(m_pLock);
@ -77,10 +77,10 @@ public:
class WriteHolder
{
ReaderWriterLock * m_pLock;
SlimReaderWriterLock * m_pLock;
public:
WriteHolder(ReaderWriterLock * pLock)
WriteHolder(SlimReaderWriterLock * pLock)
: m_pLock(pLock)
{
::AcquireSRWLockExclusive(m_pLock);
@ -167,7 +167,7 @@ class JITCodeManager : ICodeManager
UInt32 m_cbRange;
// lock to protect m_runtimeFunctions and m_FuncletToMainMethodMap
ReaderWriterLock m_lock;
SlimReaderWriterLock m_lock;
std::vector<RUNTIME_FUNCTION> m_runtimeFunctions;
PTR_RUNTIME_FUNCTION m_pRuntimeFunctionTable;

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше