Merge branch 'master' into r2r-merge
This commit is contained in:
Коммит
82351cc766
|
@ -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>
|
||||
|
|
15
dir.targets
15
dir.targets
|
@ -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>"$(NativeObject)" -o "$(NativeBinary)" -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 --emrun </EmccArgs>
|
||||
<EmccArgs Condition="'$(Platform)'=='wasm'">$(EmccArgs) "$(IlcPath)/sdk/libPortableRuntime.bc" "$(IlcPath)/sdk/libbootstrappercpp.bc" "$(IlcPath)/sdk/libSystem.Private.CoreLib.Native.bc" </EmccArgs>
|
||||
<EmccArgs Condition="'$(Platform)'=='wasm'">$(EmccArgs) "$(IlcPath)/sdk/libPortableRuntime.bc" "$(IlcPath)/sdk/libbootstrappercpp.bc" "$(IlcPath)/sdk/libSystem.Private.CoreLib.Native.bc" </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;
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче